[U-Boot] [PATCH] sh: Add support pin function control using GPIO

Renesas SH and R-Mobile set up device using PFC. This provide the framework. Most codes were brought from linux kernel.
Signed-off-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com --- drivers/gpio/Makefile | 1 + drivers/gpio/sh_pfc.c | 629 +++++++++++++++++++++++++++++++++++++++++++++++++ include/sh_pfc.h | 192 +++++++++++++++ 3 files changed, 822 insertions(+) create mode 100644 drivers/gpio/sh_pfc.c create mode 100644 include/sh_pfc.h
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fb3b09a..9192582 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -39,6 +39,7 @@ COBJS-$(CONFIG_TEGRA2_GPIO) += tegra2_gpio.o COBJS-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o COBJS-$(CONFIG_ALTERA_PIO) += altera_pio.o COBJS-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o +COBJS-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/gpio/sh_pfc.c b/drivers/gpio/sh_pfc.c new file mode 100644 index 0000000..7a5af20 --- /dev/null +++ b/drivers/gpio/sh_pfc.c @@ -0,0 +1,629 @@ +/* + * Pinmuxed GPIO support for SuperH. + * Copy from linux kernel driver/sh/pfc.c + * + * Copyright (C) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <common.h> +#include <asm/bitops.h> +#include <asm/io.h> +#include <sh_pfc.h> + +static struct pinmux_info *gpioc; + +#define pfc_phys_to_virt(p, a) ((void *)a) + +static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) +{ + if (enum_id < r->begin) + return 0; + + if (enum_id > r->end) + return 0; + + return 1; +} + +static unsigned long gpio_read_raw_reg(void *mapped_reg, + unsigned long reg_width) +{ + switch (reg_width) { + + case 8: + return readb(mapped_reg); + case 16: + return readw(mapped_reg); + case 32: + return readl(mapped_reg); + } + + BUG(); + return 0; +} + +static void gpio_write_raw_reg(void *mapped_reg, + unsigned long reg_width, + unsigned long data) +{ + switch (reg_width) { + case 8: + writeb(data, mapped_reg); + return; + case 16: + writew(data, mapped_reg); + return; + case 32: + writel(data, mapped_reg); + return; + } + + BUG(); +} + +static int gpio_read_bit(struct pinmux_data_reg *dr, + unsigned long in_pos) +{ + unsigned long pos; + + pos = dr->reg_width - (in_pos + 1); + + debug("read_bit: addr = %lx, pos = %ld, " + "r_width = %ld\n", dr->reg, pos, dr->reg_width); + + return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; +} + +static void gpio_write_bit(struct pinmux_data_reg *dr, + unsigned long in_pos, unsigned long value) +{ + unsigned long pos; + + pos = dr->reg_width - (in_pos + 1); + + debug("write_bit addr = %lx, value = %d, pos = %ld, " + "r_width = %ld\n", + dr->reg, !!value, pos, dr->reg_width); + + if (value) + __set_bit(pos, &dr->reg_shadow); + else + __clear_bit(pos, &dr->reg_shadow); + + gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); +} + +static void config_reg_helper(struct pinmux_info *gpioc, + struct pinmux_cfg_reg *crp, + unsigned long in_pos, +#if 0 + void __iomem **mapped_regp, +#else + void **mapped_regp, +#endif + unsigned long *maskp, + unsigned long *posp) +{ + int k; + + *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg); + + if (crp->field_width) { + *maskp = (1 << crp->field_width) - 1; + *posp = crp->reg_width - ((in_pos + 1) * crp->field_width); + } else { + *maskp = (1 << crp->var_field_width[in_pos]) - 1; + *posp = crp->reg_width; + for (k = 0; k <= in_pos; k++) + *posp -= crp->var_field_width[k]; + } +} + +static int read_config_reg(struct pinmux_info *gpioc, + struct pinmux_cfg_reg *crp, + unsigned long field) +{ + void *mapped_reg; + + unsigned long mask, pos; + + config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos); + + debug("read_reg: addr = %lx, field = %ld, " + "r_width = %ld, f_width = %ld\n", + crp->reg, field, crp->reg_width, crp->field_width); + + return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask; +} + +static void write_config_reg(struct pinmux_info *gpioc, + struct pinmux_cfg_reg *crp, + unsigned long field, unsigned long value) +{ + void *mapped_reg; + unsigned long mask, pos, data; + + config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos); + + debug("write_reg addr = %lx, value = %ld, field = %ld, " + "r_width = %ld, f_width = %ld\n", + crp->reg, value, field, crp->reg_width, crp->field_width); + + mask = ~(mask << pos); + value = value << pos; + + data = gpio_read_raw_reg(mapped_reg, crp->reg_width); + data &= mask; + data |= value; + + if (gpioc->unlock_reg) + gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg), + 32, ~data); + + gpio_write_raw_reg(mapped_reg, crp->reg_width, data); +} + +static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) +{ + struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; + struct pinmux_data_reg *data_reg; + int k, n; + + if (!enum_in_range(gpiop->enum_id, &gpioc->data)) + return -1; + + k = 0; + while (1) { + data_reg = gpioc->data_regs + k; + + if (!data_reg->reg_width) + break; + + data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg); + + for (n = 0; n < data_reg->reg_width; n++) { + if (data_reg->enum_ids[n] == gpiop->enum_id) { + gpiop->flags &= ~PINMUX_FLAG_DREG; + gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); + gpiop->flags &= ~PINMUX_FLAG_DBIT; + gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); + return 0; + } + } + k++; + } + + BUG(); + + return -1; +} + +static void setup_data_regs(struct pinmux_info *gpioc) +{ + struct pinmux_data_reg *drp; + int k; + + for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++) + setup_data_reg(gpioc, k); + + k = 0; + while (1) { + drp = gpioc->data_regs + k; + + if (!drp->reg_width) + break; + + drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg, + drp->reg_width); + k++; + } +} + +static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio, + struct pinmux_data_reg **drp, int *bitp) +{ + struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; + int k, n; + + if (!enum_in_range(gpiop->enum_id, &gpioc->data)) + return -1; + + k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; + n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; + *drp = gpioc->data_regs + k; + *bitp = n; + return 0; +} + +static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, + struct pinmux_cfg_reg **crp, + int *fieldp, int *valuep, + unsigned long **cntp) +{ + struct pinmux_cfg_reg *config_reg; + unsigned long r_width, f_width, curr_width, ncomb; + int k, m, n, pos, bit_pos; + + k = 0; + while (1) { + config_reg = gpioc->cfg_regs + k; + + r_width = config_reg->reg_width; + f_width = config_reg->field_width; + + if (!r_width) + break; + + pos = 0; + m = 0; + for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) { + if (f_width) + curr_width = f_width; + else + curr_width = config_reg->var_field_width[m]; + + ncomb = 1 << curr_width; + for (n = 0; n < ncomb; n++) { + if (config_reg->enum_ids[pos + n] == enum_id) { + *crp = config_reg; + *fieldp = m; + *valuep = n; + *cntp = &config_reg->cnt[m]; + return 0; + } + } + pos += ncomb; + m++; + } + k++; + } + + return -1; +} + +static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio, + int pos, pinmux_enum_t *enum_idp) +{ + pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id; + pinmux_enum_t *data = gpioc->gpio_data; + int k; + + if (!enum_in_range(enum_id, &gpioc->data)) { + if (!enum_in_range(enum_id, &gpioc->mark)) { + debug("non data/mark enum_id for gpio %d\n", gpio); + return -1; + } + } + + if (pos) { + *enum_idp = data[pos + 1]; + return pos + 1; + } + + for (k = 0; k < gpioc->gpio_data_size; k++) { + if (data[k] == enum_id) { + *enum_idp = data[k + 1]; + return k + 1; + } + } + + debug("cannot locate data/mark enum_id for gpio %d\n", gpio); + return -1; +} + +enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; + +static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, + int pinmux_type, int cfg_mode) +{ + struct pinmux_cfg_reg *cr = NULL; + pinmux_enum_t enum_id; + struct pinmux_range *range; + int in_range, pos, field, value; + unsigned long *cntp; + + switch (pinmux_type) { + + case PINMUX_TYPE_FUNCTION: + range = NULL; + break; + + case PINMUX_TYPE_OUTPUT: + range = &gpioc->output; + break; + + case PINMUX_TYPE_INPUT: + range = &gpioc->input; + break; + + case PINMUX_TYPE_INPUT_PULLUP: + range = &gpioc->input_pu; + break; + + case PINMUX_TYPE_INPUT_PULLDOWN: + range = &gpioc->input_pd; + break; + + default: + goto out_err; + } + + pos = 0; + enum_id = 0; + field = 0; + value = 0; + while (1) { + pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id); + if (pos <= 0) + goto out_err; + + if (!enum_id) + break; + + /* first check if this is a function enum */ + in_range = enum_in_range(enum_id, &gpioc->function); + if (!in_range) { + /* not a function enum */ + if (range) { + /* + * other range exists, so this pin is + * a regular GPIO pin that now is being + * bound to a specific direction. + * + * for this case we only allow function enums + * and the enums that match the other range. + */ + in_range = enum_in_range(enum_id, range); + + /* + * special case pass through for fixed + * input-only or output-only pins without + * function enum register association. + */ + if (in_range && enum_id == range->force) + continue; + } else { + /* + * no other range exists, so this pin + * must then be of the function type. + * + * allow function type pins to select + * any combination of function/in/out + * in their MARK lists. + */ + in_range = 1; + } + } + + if (!in_range) + continue; + + if (get_config_reg(gpioc, enum_id, &cr, + &field, &value, &cntp) != 0) + goto out_err; + + switch (cfg_mode) { + case GPIO_CFG_DRYRUN: + if (!*cntp || + (read_config_reg(gpioc, cr, field) != value)) + continue; + break; + + case GPIO_CFG_REQ: + write_config_reg(gpioc, cr, field, value); + *cntp = *cntp + 1; + break; + + case GPIO_CFG_FREE: + *cntp = *cntp - 1; + break; + } + } + + return 0; + out_err: + return -1; +} + +#if 0 +static DEFINE_SPINLOCK(gpio_lock); +static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip) +{ + return container_of(chip, struct pinmux_info, chip); +} +#endif + +static int sh_gpio_request(unsigned offset) +{ + struct pinmux_data_reg *dummy; + int i, ret, pinmux_type; + + ret = -1; + + if (!gpioc) + goto err_out; + + if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) + goto err_out; + + /* setup pin function here if no data is associated with pin */ + + if (get_data_reg(gpioc, offset, &dummy, &i) != 0) + pinmux_type = PINMUX_TYPE_FUNCTION; + else + pinmux_type = PINMUX_TYPE_GPIO; + + if (pinmux_type == PINMUX_TYPE_FUNCTION) { + if (pinmux_config_gpio(gpioc, offset, + pinmux_type, + GPIO_CFG_DRYRUN) != 0) + goto err_out; + + if (pinmux_config_gpio(gpioc, offset, + pinmux_type, + GPIO_CFG_REQ) != 0) + BUG(); + } + + gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; + gpioc->gpios[offset].flags |= pinmux_type; + + ret = 0; +err_out: + return ret; +} + +static void sh_gpio_free(unsigned offset) +{ + int pinmux_type; + + if (!gpioc) + return; + + pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE; + pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE); + gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; + gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE; +} + +static int pinmux_direction(struct pinmux_info *gpioc, + unsigned gpio, int new_pinmux_type) +{ + int pinmux_type; + int ret = -1; + + if (!gpioc) + goto err_out; + + pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE; + + switch (pinmux_type) { + case PINMUX_TYPE_GPIO: + break; + case PINMUX_TYPE_OUTPUT: + case PINMUX_TYPE_INPUT: + case PINMUX_TYPE_INPUT_PULLUP: + case PINMUX_TYPE_INPUT_PULLDOWN: + pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE); + break; + default: + goto err_out; + } + + if (pinmux_config_gpio(gpioc, gpio, + new_pinmux_type, + GPIO_CFG_DRYRUN) != 0) + goto err_out; + + if (pinmux_config_gpio(gpioc, gpio, + new_pinmux_type, + GPIO_CFG_REQ) != 0) + BUG(); + + gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; + gpioc->gpios[gpio].flags |= new_pinmux_type; + + ret = 0; + err_out: + return ret; +} + +static int sh_gpio_direction_input(unsigned offset) +{ + return pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT); +} + +static void sh_gpio_set_value(struct pinmux_info *gpioc, + unsigned gpio, int value) +{ + struct pinmux_data_reg *dr = NULL; + int bit = 0; + + if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) + BUG(); + else + gpio_write_bit(dr, bit, value); +} + +static int sh_gpio_direction_output(unsigned offset, int value) +{ + sh_gpio_set_value(gpioc, offset, value); + return pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT); +} + +static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio) +{ + struct pinmux_data_reg *dr = NULL; + int bit = 0; + + if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) + return -1; + + return gpio_read_bit(dr, bit); +} + +static int sh_gpio_get(unsigned offset) +{ + return sh_gpio_get_value(gpioc, offset); +} + +static void sh_gpio_set(unsigned offset, int value) +{ + sh_gpio_set_value(gpioc, offset, value); +} + +int register_pinmux(struct pinmux_info *pip) +{ + if (pip != NULL) { + gpioc = pip; + debug("%s deregistering\n", pip->name); + setup_data_regs(gpioc); + } + return 0; +} + +int unregister_pinmux(struct pinmux_info *pip) +{ + debug("%s deregistering\n", pip->name); + if (gpioc != pip) + return -1; + + gpioc = NULL; + return 0; +} + +int gpio_request(unsigned gpio, const char *label) +{ + sh_gpio_request(gpio); + return 0; +} + +int gpio_free(unsigned gpio) +{ + sh_gpio_free(gpio); + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + return sh_gpio_direction_input(gpio); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + return sh_gpio_direction_output(gpio, value); +} + +void gpio_set_value(unsigned gpio, int value) +{ + sh_gpio_set(gpio, value); +} + +int gpio_get_value(unsigned gpio) +{ + return sh_gpio_get(gpio); +} diff --git a/include/sh_pfc.h b/include/sh_pfc.h new file mode 100644 index 0000000..4e0dc71 --- /dev/null +++ b/include/sh_pfc.h @@ -0,0 +1,192 @@ +/* + * SuperH Pin Function Controller Support + * Copy from Linux kernel. (include/linux/sh_pfc.h) + * + * Copyright (c) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef __SH_PFC_H +#define __SH_PFC_H + +typedef unsigned short pinmux_enum_t; +typedef unsigned short pinmux_flag_t; + +#define PINMUX_TYPE_NONE 0 +#define PINMUX_TYPE_FUNCTION 1 +#define PINMUX_TYPE_GPIO 2 +#define PINMUX_TYPE_OUTPUT 3 +#define PINMUX_TYPE_INPUT 4 +#define PINMUX_TYPE_INPUT_PULLUP 5 +#define PINMUX_TYPE_INPUT_PULLDOWN 6 + +#define PINMUX_FLAG_TYPE (0x7) +#define PINMUX_FLAG_WANT_PULLUP (1 << 3) +#define PINMUX_FLAG_WANT_PULLDOWN (1 << 4) + +#define PINMUX_FLAG_DBIT_SHIFT 5 +#define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT) +#define PINMUX_FLAG_DREG_SHIFT 10 +#define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) + +struct pinmux_gpio { + pinmux_enum_t enum_id; + pinmux_flag_t flags; +}; + +#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark } +#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0 + +struct pinmux_cfg_reg { + unsigned long reg, reg_width, field_width; + unsigned long *cnt; + pinmux_enum_t *enum_ids; + unsigned long *var_field_width; +}; + +#define PINMUX_CFG_REG(name, r, r_width, f_width) \ + .reg = r, .reg_width = r_width, .field_width = f_width, \ + .cnt = (unsigned long [r_width / f_width]) {}, \ + .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) + +#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \ + .reg = r, .reg_width = r_width, \ + .cnt = (unsigned long [r_width]) {}, \ + .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \ + .enum_ids = (pinmux_enum_t []) + +struct pinmux_data_reg { + unsigned long reg, reg_width, reg_shadow; + pinmux_enum_t *enum_ids; + void *mapped_reg; +}; + +#define PINMUX_DATA_REG(name, r, r_width) \ + .reg = r, .reg_width = r_width, \ + .enum_ids = (pinmux_enum_t [r_width]) \ + +struct pinmux_irq { + int irq; + pinmux_enum_t *enum_ids; +}; + +#define PINMUX_IRQ(irq_nr, ids...) \ + { .irq = irq_nr, .enum_ids = (pinmux_enum_t []) { ids, 0 } } \ + +struct pinmux_range { + pinmux_enum_t begin; + pinmux_enum_t end; + pinmux_enum_t force; +}; + +struct pinmux_info { + char *name; + pinmux_enum_t reserved_id; + struct pinmux_range data; + struct pinmux_range input; + struct pinmux_range input_pd; + struct pinmux_range input_pu; + struct pinmux_range output; + struct pinmux_range mark; + struct pinmux_range function; + + unsigned first_gpio, last_gpio; + + struct pinmux_gpio *gpios; + struct pinmux_cfg_reg *cfg_regs; + struct pinmux_data_reg *data_regs; + + pinmux_enum_t *gpio_data; + unsigned int gpio_data_size; + + struct pinmux_irq *gpio_irq; + unsigned int gpio_irq_size; + + struct resource *resource; + unsigned int num_resources; + unsigned long unlock_reg; +}; + +int register_pinmux(struct pinmux_info *pip); +int unregister_pinmux(struct pinmux_info *pip); + +/* helper macro for port */ +#define PORT_1(fn, pfx, sfx) fn(pfx, sfx) + +#define PORT_10(fn, pfx, sfx) \ + PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx), \ + PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx), \ + PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx), \ + PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx), \ + PORT_1(fn, pfx##8, sfx), PORT_1(fn, pfx##9, sfx) + +#define PORT_90(fn, pfx, sfx) \ + PORT_10(fn, pfx##1, sfx), PORT_10(fn, pfx##2, sfx), \ + PORT_10(fn, pfx##3, sfx), PORT_10(fn, pfx##4, sfx), \ + PORT_10(fn, pfx##5, sfx), PORT_10(fn, pfx##6, sfx), \ + PORT_10(fn, pfx##7, sfx), PORT_10(fn, pfx##8, sfx), \ + PORT_10(fn, pfx##9, sfx) + +#define _PORT_ALL(pfx, sfx) pfx##_##sfx +#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA) +#define PORT_ALL(str) CPU_ALL_PORT(_PORT_ALL, PORT, str) +#define GPIO_PORT_ALL() CPU_ALL_PORT(_GPIO_PORT, , unused) +#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK) + +/* helper macro for pinmux_enum_t */ +#define PORT_DATA_I(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN) + +#define PORT_DATA_I_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \ + PORT##nr##_IN, PORT##nr##_IN_PD) + +#define PORT_DATA_I_PU(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \ + PORT##nr##_IN, PORT##nr##_IN_PU) + +#define PORT_DATA_I_PU_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \ + PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU) + +#define PORT_DATA_O(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT) + +#define PORT_DATA_IO(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN) + +#define PORT_DATA_IO_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN, PORT##nr##_IN_PD) + +#define PORT_DATA_IO_PU(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN, PORT##nr##_IN_PU) + +#define PORT_DATA_IO_PU_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU) + +/* helper macro for top 4 bits in PORTnCR */ +#define _PCRH(in, in_pd, in_pu, out) \ + 0, (out), (in), 0, \ + 0, 0, 0, 0, \ + 0, 0, (in_pd), 0, \ + 0, 0, (in_pu), 0 + +#define PORTCR(nr, reg) \ + { \ + PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \ + _PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \ + PORT##nr##_IN_PU, PORT##nr##_OUT), \ + PORT##nr##_FN0, PORT##nr##_FN1, \ + PORT##nr##_FN2, PORT##nr##_FN3, \ + PORT##nr##_FN4, PORT##nr##_FN5, \ + PORT##nr##_FN6, PORT##nr##_FN7 } \ + } + +#endif /* __SH_PFC_H */

Renesas SH and R-Mobile set up device using PFC. This provide the framework. Most codes were brought from linux kernel.
Signed-off-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com --- drivers/gpio/Makefile | 1 + drivers/gpio/sh_pfc.c | 629 +++++++++++++++++++++++++++++++++++++++++++++++++ include/sh_pfc.h | 192 +++++++++++++++ 3 files changed, 822 insertions(+) create mode 100644 drivers/gpio/sh_pfc.c create mode 100644 include/sh_pfc.h
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fb3b09a..9192582 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -39,6 +39,7 @@ COBJS-$(CONFIG_TEGRA2_GPIO) += tegra2_gpio.o COBJS-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o COBJS-$(CONFIG_ALTERA_PIO) += altera_pio.o COBJS-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o +COBJS-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/gpio/sh_pfc.c b/drivers/gpio/sh_pfc.c new file mode 100644 index 0000000..7a5af20 --- /dev/null +++ b/drivers/gpio/sh_pfc.c @@ -0,0 +1,629 @@ +/* + * Pinmuxed GPIO support for SuperH. + * Copy from linux kernel driver/sh/pfc.c + * + * Copyright (C) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <common.h> +#include <asm/bitops.h> +#include <asm/io.h> +#include <sh_pfc.h> + +static struct pinmux_info *gpioc; + +#define pfc_phys_to_virt(p, a) ((void *)a) + +static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r) +{ + if (enum_id < r->begin) + return 0; + + if (enum_id > r->end) + return 0; + + return 1; +} + +static unsigned long gpio_read_raw_reg(void *mapped_reg, + unsigned long reg_width) +{ + switch (reg_width) { + + case 8: + return readb(mapped_reg); + case 16: + return readw(mapped_reg); + case 32: + return readl(mapped_reg); + } + + BUG(); + return 0; +} + +static void gpio_write_raw_reg(void *mapped_reg, + unsigned long reg_width, + unsigned long data) +{ + switch (reg_width) { + case 8: + writeb(data, mapped_reg); + return; + case 16: + writew(data, mapped_reg); + return; + case 32: + writel(data, mapped_reg); + return; + } + + BUG(); +} + +static int gpio_read_bit(struct pinmux_data_reg *dr, + unsigned long in_pos) +{ + unsigned long pos; + + pos = dr->reg_width - (in_pos + 1); + + debug("read_bit: addr = %lx, pos = %ld, " + "r_width = %ld\n", dr->reg, pos, dr->reg_width); + + return (gpio_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; +} + +static void gpio_write_bit(struct pinmux_data_reg *dr, + unsigned long in_pos, unsigned long value) +{ + unsigned long pos; + + pos = dr->reg_width - (in_pos + 1); + + debug("write_bit addr = %lx, value = %d, pos = %ld, " + "r_width = %ld\n", + dr->reg, !!value, pos, dr->reg_width); + + if (value) + __set_bit(pos, &dr->reg_shadow); + else + __clear_bit(pos, &dr->reg_shadow); + + gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); +} + +static void config_reg_helper(struct pinmux_info *gpioc, + struct pinmux_cfg_reg *crp, + unsigned long in_pos, +#if 0 + void __iomem **mapped_regp, +#else + void **mapped_regp, +#endif + unsigned long *maskp, + unsigned long *posp) +{ + int k; + + *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg); + + if (crp->field_width) { + *maskp = (1 << crp->field_width) - 1; + *posp = crp->reg_width - ((in_pos + 1) * crp->field_width); + } else { + *maskp = (1 << crp->var_field_width[in_pos]) - 1; + *posp = crp->reg_width; + for (k = 0; k <= in_pos; k++) + *posp -= crp->var_field_width[k]; + } +} + +static int read_config_reg(struct pinmux_info *gpioc, + struct pinmux_cfg_reg *crp, + unsigned long field) +{ + void *mapped_reg; + + unsigned long mask, pos; + + config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos); + + debug("read_reg: addr = %lx, field = %ld, " + "r_width = %ld, f_width = %ld\n", + crp->reg, field, crp->reg_width, crp->field_width); + + return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask; +} + +static void write_config_reg(struct pinmux_info *gpioc, + struct pinmux_cfg_reg *crp, + unsigned long field, unsigned long value) +{ + void *mapped_reg; + unsigned long mask, pos, data; + + config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos); + + debug("write_reg addr = %lx, value = %ld, field = %ld, " + "r_width = %ld, f_width = %ld\n", + crp->reg, value, field, crp->reg_width, crp->field_width); + + mask = ~(mask << pos); + value = value << pos; + + data = gpio_read_raw_reg(mapped_reg, crp->reg_width); + data &= mask; + data |= value; + + if (gpioc->unlock_reg) + gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg), + 32, ~data); + + gpio_write_raw_reg(mapped_reg, crp->reg_width, data); +} + +static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio) +{ + struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; + struct pinmux_data_reg *data_reg; + int k, n; + + if (!enum_in_range(gpiop->enum_id, &gpioc->data)) + return -1; + + k = 0; + while (1) { + data_reg = gpioc->data_regs + k; + + if (!data_reg->reg_width) + break; + + data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg); + + for (n = 0; n < data_reg->reg_width; n++) { + if (data_reg->enum_ids[n] == gpiop->enum_id) { + gpiop->flags &= ~PINMUX_FLAG_DREG; + gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); + gpiop->flags &= ~PINMUX_FLAG_DBIT; + gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); + return 0; + } + } + k++; + } + + BUG(); + + return -1; +} + +static void setup_data_regs(struct pinmux_info *gpioc) +{ + struct pinmux_data_reg *drp; + int k; + + for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++) + setup_data_reg(gpioc, k); + + k = 0; + while (1) { + drp = gpioc->data_regs + k; + + if (!drp->reg_width) + break; + + drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg, + drp->reg_width); + k++; + } +} + +static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio, + struct pinmux_data_reg **drp, int *bitp) +{ + struct pinmux_gpio *gpiop = &gpioc->gpios[gpio]; + int k, n; + + if (!enum_in_range(gpiop->enum_id, &gpioc->data)) + return -1; + + k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; + n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; + *drp = gpioc->data_regs + k; + *bitp = n; + return 0; +} + +static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id, + struct pinmux_cfg_reg **crp, + int *fieldp, int *valuep, + unsigned long **cntp) +{ + struct pinmux_cfg_reg *config_reg; + unsigned long r_width, f_width, curr_width, ncomb; + int k, m, n, pos, bit_pos; + + k = 0; + while (1) { + config_reg = gpioc->cfg_regs + k; + + r_width = config_reg->reg_width; + f_width = config_reg->field_width; + + if (!r_width) + break; + + pos = 0; + m = 0; + for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) { + if (f_width) + curr_width = f_width; + else + curr_width = config_reg->var_field_width[m]; + + ncomb = 1 << curr_width; + for (n = 0; n < ncomb; n++) { + if (config_reg->enum_ids[pos + n] == enum_id) { + *crp = config_reg; + *fieldp = m; + *valuep = n; + *cntp = &config_reg->cnt[m]; + return 0; + } + } + pos += ncomb; + m++; + } + k++; + } + + return -1; +} + +static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio, + int pos, pinmux_enum_t *enum_idp) +{ + pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id; + pinmux_enum_t *data = gpioc->gpio_data; + int k; + + if (!enum_in_range(enum_id, &gpioc->data)) { + if (!enum_in_range(enum_id, &gpioc->mark)) { + debug("non data/mark enum_id for gpio %d\n", gpio); + return -1; + } + } + + if (pos) { + *enum_idp = data[pos + 1]; + return pos + 1; + } + + for (k = 0; k < gpioc->gpio_data_size; k++) { + if (data[k] == enum_id) { + *enum_idp = data[k + 1]; + return k + 1; + } + } + + debug("cannot locate data/mark enum_id for gpio %d\n", gpio); + return -1; +} + +enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE }; + +static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio, + int pinmux_type, int cfg_mode) +{ + struct pinmux_cfg_reg *cr = NULL; + pinmux_enum_t enum_id; + struct pinmux_range *range; + int in_range, pos, field, value; + unsigned long *cntp; + + switch (pinmux_type) { + + case PINMUX_TYPE_FUNCTION: + range = NULL; + break; + + case PINMUX_TYPE_OUTPUT: + range = &gpioc->output; + break; + + case PINMUX_TYPE_INPUT: + range = &gpioc->input; + break; + + case PINMUX_TYPE_INPUT_PULLUP: + range = &gpioc->input_pu; + break; + + case PINMUX_TYPE_INPUT_PULLDOWN: + range = &gpioc->input_pd; + break; + + default: + goto out_err; + } + + pos = 0; + enum_id = 0; + field = 0; + value = 0; + while (1) { + pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id); + if (pos <= 0) + goto out_err; + + if (!enum_id) + break; + + /* first check if this is a function enum */ + in_range = enum_in_range(enum_id, &gpioc->function); + if (!in_range) { + /* not a function enum */ + if (range) { + /* + * other range exists, so this pin is + * a regular GPIO pin that now is being + * bound to a specific direction. + * + * for this case we only allow function enums + * and the enums that match the other range. + */ + in_range = enum_in_range(enum_id, range); + + /* + * special case pass through for fixed + * input-only or output-only pins without + * function enum register association. + */ + if (in_range && enum_id == range->force) + continue; + } else { + /* + * no other range exists, so this pin + * must then be of the function type. + * + * allow function type pins to select + * any combination of function/in/out + * in their MARK lists. + */ + in_range = 1; + } + } + + if (!in_range) + continue; + + if (get_config_reg(gpioc, enum_id, &cr, + &field, &value, &cntp) != 0) + goto out_err; + + switch (cfg_mode) { + case GPIO_CFG_DRYRUN: + if (!*cntp || + (read_config_reg(gpioc, cr, field) != value)) + continue; + break; + + case GPIO_CFG_REQ: + write_config_reg(gpioc, cr, field, value); + *cntp = *cntp + 1; + break; + + case GPIO_CFG_FREE: + *cntp = *cntp - 1; + break; + } + } + + return 0; + out_err: + return -1; +} + +#if 0 +static DEFINE_SPINLOCK(gpio_lock); +static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip) +{ + return container_of(chip, struct pinmux_info, chip); +} +#endif + +static int sh_gpio_request(unsigned offset) +{ + struct pinmux_data_reg *dummy; + int i, ret, pinmux_type; + + ret = -1; + + if (!gpioc) + goto err_out; + + if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE) + goto err_out; + + /* setup pin function here if no data is associated with pin */ + + if (get_data_reg(gpioc, offset, &dummy, &i) != 0) + pinmux_type = PINMUX_TYPE_FUNCTION; + else + pinmux_type = PINMUX_TYPE_GPIO; + + if (pinmux_type == PINMUX_TYPE_FUNCTION) { + if (pinmux_config_gpio(gpioc, offset, + pinmux_type, + GPIO_CFG_DRYRUN) != 0) + goto err_out; + + if (pinmux_config_gpio(gpioc, offset, + pinmux_type, + GPIO_CFG_REQ) != 0) + BUG(); + } + + gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; + gpioc->gpios[offset].flags |= pinmux_type; + + ret = 0; +err_out: + return ret; +} + +static void sh_gpio_free(unsigned offset) +{ + int pinmux_type; + + if (!gpioc) + return; + + pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE; + pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE); + gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE; + gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE; +} + +static int pinmux_direction(struct pinmux_info *gpioc, + unsigned gpio, int new_pinmux_type) +{ + int pinmux_type; + int ret = -1; + + if (!gpioc) + goto err_out; + + pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE; + + switch (pinmux_type) { + case PINMUX_TYPE_GPIO: + break; + case PINMUX_TYPE_OUTPUT: + case PINMUX_TYPE_INPUT: + case PINMUX_TYPE_INPUT_PULLUP: + case PINMUX_TYPE_INPUT_PULLDOWN: + pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE); + break; + default: + goto err_out; + } + + if (pinmux_config_gpio(gpioc, gpio, + new_pinmux_type, + GPIO_CFG_DRYRUN) != 0) + goto err_out; + + if (pinmux_config_gpio(gpioc, gpio, + new_pinmux_type, + GPIO_CFG_REQ) != 0) + BUG(); + + gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE; + gpioc->gpios[gpio].flags |= new_pinmux_type; + + ret = 0; + err_out: + return ret; +} + +static int sh_gpio_direction_input(unsigned offset) +{ + return pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT); +} + +static void sh_gpio_set_value(struct pinmux_info *gpioc, + unsigned gpio, int value) +{ + struct pinmux_data_reg *dr = NULL; + int bit = 0; + + if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) + BUG(); + else + gpio_write_bit(dr, bit, value); +} + +static int sh_gpio_direction_output(unsigned offset, int value) +{ + sh_gpio_set_value(gpioc, offset, value); + return pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT); +} + +static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio) +{ + struct pinmux_data_reg *dr = NULL; + int bit = 0; + + if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) + return -1; + + return gpio_read_bit(dr, bit); +} + +static int sh_gpio_get(unsigned offset) +{ + return sh_gpio_get_value(gpioc, offset); +} + +static void sh_gpio_set(unsigned offset, int value) +{ + sh_gpio_set_value(gpioc, offset, value); +} + +int register_pinmux(struct pinmux_info *pip) +{ + if (pip != NULL) { + gpioc = pip; + debug("%s deregistering\n", pip->name); + setup_data_regs(gpioc); + } + return 0; +} + +int unregister_pinmux(struct pinmux_info *pip) +{ + debug("%s deregistering\n", pip->name); + if (gpioc != pip) + return -1; + + gpioc = NULL; + return 0; +} + +int gpio_request(unsigned gpio, const char *label) +{ + sh_gpio_request(gpio); + return 0; +} + +int gpio_free(unsigned gpio) +{ + sh_gpio_free(gpio); + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + return sh_gpio_direction_input(gpio); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + return sh_gpio_direction_output(gpio, value); +} + +void gpio_set_value(unsigned gpio, int value) +{ + sh_gpio_set(gpio, value); +} + +int gpio_get_value(unsigned gpio) +{ + return sh_gpio_get(gpio); +} diff --git a/include/sh_pfc.h b/include/sh_pfc.h new file mode 100644 index 0000000..4e0dc71 --- /dev/null +++ b/include/sh_pfc.h @@ -0,0 +1,192 @@ +/* + * SuperH Pin Function Controller Support + * Copy from Linux kernel. (include/linux/sh_pfc.h) + * + * Copyright (c) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef __SH_PFC_H +#define __SH_PFC_H + +typedef unsigned short pinmux_enum_t; +typedef unsigned short pinmux_flag_t; + +#define PINMUX_TYPE_NONE 0 +#define PINMUX_TYPE_FUNCTION 1 +#define PINMUX_TYPE_GPIO 2 +#define PINMUX_TYPE_OUTPUT 3 +#define PINMUX_TYPE_INPUT 4 +#define PINMUX_TYPE_INPUT_PULLUP 5 +#define PINMUX_TYPE_INPUT_PULLDOWN 6 + +#define PINMUX_FLAG_TYPE (0x7) +#define PINMUX_FLAG_WANT_PULLUP (1 << 3) +#define PINMUX_FLAG_WANT_PULLDOWN (1 << 4) + +#define PINMUX_FLAG_DBIT_SHIFT 5 +#define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT) +#define PINMUX_FLAG_DREG_SHIFT 10 +#define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT) + +struct pinmux_gpio { + pinmux_enum_t enum_id; + pinmux_flag_t flags; +}; + +#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark } +#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0 + +struct pinmux_cfg_reg { + unsigned long reg, reg_width, field_width; + unsigned long *cnt; + pinmux_enum_t *enum_ids; + unsigned long *var_field_width; +}; + +#define PINMUX_CFG_REG(name, r, r_width, f_width) \ + .reg = r, .reg_width = r_width, .field_width = f_width, \ + .cnt = (unsigned long [r_width / f_width]) {}, \ + .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) + +#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \ + .reg = r, .reg_width = r_width, \ + .cnt = (unsigned long [r_width]) {}, \ + .var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \ + .enum_ids = (pinmux_enum_t []) + +struct pinmux_data_reg { + unsigned long reg, reg_width, reg_shadow; + pinmux_enum_t *enum_ids; + void *mapped_reg; +}; + +#define PINMUX_DATA_REG(name, r, r_width) \ + .reg = r, .reg_width = r_width, \ + .enum_ids = (pinmux_enum_t [r_width]) \ + +struct pinmux_irq { + int irq; + pinmux_enum_t *enum_ids; +}; + +#define PINMUX_IRQ(irq_nr, ids...) \ + { .irq = irq_nr, .enum_ids = (pinmux_enum_t []) { ids, 0 } } \ + +struct pinmux_range { + pinmux_enum_t begin; + pinmux_enum_t end; + pinmux_enum_t force; +}; + +struct pinmux_info { + char *name; + pinmux_enum_t reserved_id; + struct pinmux_range data; + struct pinmux_range input; + struct pinmux_range input_pd; + struct pinmux_range input_pu; + struct pinmux_range output; + struct pinmux_range mark; + struct pinmux_range function; + + unsigned first_gpio, last_gpio; + + struct pinmux_gpio *gpios; + struct pinmux_cfg_reg *cfg_regs; + struct pinmux_data_reg *data_regs; + + pinmux_enum_t *gpio_data; + unsigned int gpio_data_size; + + struct pinmux_irq *gpio_irq; + unsigned int gpio_irq_size; + + struct resource *resource; + unsigned int num_resources; + unsigned long unlock_reg; +}; + +int register_pinmux(struct pinmux_info *pip); +int unregister_pinmux(struct pinmux_info *pip); + +/* helper macro for port */ +#define PORT_1(fn, pfx, sfx) fn(pfx, sfx) + +#define PORT_10(fn, pfx, sfx) \ + PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx), \ + PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx), \ + PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx), \ + PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx), \ + PORT_1(fn, pfx##8, sfx), PORT_1(fn, pfx##9, sfx) + +#define PORT_90(fn, pfx, sfx) \ + PORT_10(fn, pfx##1, sfx), PORT_10(fn, pfx##2, sfx), \ + PORT_10(fn, pfx##3, sfx), PORT_10(fn, pfx##4, sfx), \ + PORT_10(fn, pfx##5, sfx), PORT_10(fn, pfx##6, sfx), \ + PORT_10(fn, pfx##7, sfx), PORT_10(fn, pfx##8, sfx), \ + PORT_10(fn, pfx##9, sfx) + +#define _PORT_ALL(pfx, sfx) pfx##_##sfx +#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA) +#define PORT_ALL(str) CPU_ALL_PORT(_PORT_ALL, PORT, str) +#define GPIO_PORT_ALL() CPU_ALL_PORT(_GPIO_PORT, , unused) +#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK) + +/* helper macro for pinmux_enum_t */ +#define PORT_DATA_I(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN) + +#define PORT_DATA_I_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \ + PORT##nr##_IN, PORT##nr##_IN_PD) + +#define PORT_DATA_I_PU(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \ + PORT##nr##_IN, PORT##nr##_IN_PU) + +#define PORT_DATA_I_PU_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \ + PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU) + +#define PORT_DATA_O(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT) + +#define PORT_DATA_IO(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN) + +#define PORT_DATA_IO_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN, PORT##nr##_IN_PD) + +#define PORT_DATA_IO_PU(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN, PORT##nr##_IN_PU) + +#define PORT_DATA_IO_PU_PD(nr) \ + PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \ + PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU) + +/* helper macro for top 4 bits in PORTnCR */ +#define _PCRH(in, in_pd, in_pu, out) \ + 0, (out), (in), 0, \ + 0, 0, 0, 0, \ + 0, 0, (in_pd), 0, \ + 0, 0, (in_pu), 0 + +#define PORTCR(nr, reg) \ + { \ + PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \ + _PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \ + PORT##nr##_IN_PU, PORT##nr##_OUT), \ + PORT##nr##_FN0, PORT##nr##_FN1, \ + PORT##nr##_FN2, PORT##nr##_FN3, \ + PORT##nr##_FN4, PORT##nr##_FN5, \ + PORT##nr##_FN6, PORT##nr##_FN7 } \ + } + +#endif /* __SH_PFC_H */

The KZM-A9-GT board has Renesas R-Mobile SH73A0, 512MB DDR2-SDRAM, USB, Ethernet, and more.
This patch supports the following functions: - 512MB DDR2-SDRAM - 16MB NOR Flash memory - Serial console (SCIF) - Ethernet (SMSC) - I2C
Signed-off-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com --- arch/arm/include/asm/mach-types.h | 2 + board/kmc/kzm/Makefile | 51 ++++++ board/kmc/kzm/kzm.c | 142 +++++++++++++++++ board/kmc/kzm/lowlevel_init.S | 308 +++++++++++++++++++++++++++++++++++++ boards.cfg | 1 + include/configs/kzm_a9_gt.h | 164 ++++++++++++++++++++ 6 files changed, 668 insertions(+) create mode 100644 board/kmc/kzm/Makefile create mode 100644 board/kmc/kzm/kzm.c create mode 100644 board/kmc/kzm/lowlevel_init.S create mode 100644 include/configs/kzm_a9_gt.h
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index 2d5c3bc..98c992c 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -1106,6 +1106,8 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_ATDGP318 3494 #define MACH_TYPE_OMAP5_SEVM 3777
+#define MACH_TYPE_KZM9G 4140 + #ifdef CONFIG_ARCH_EBSA110 # ifdef machine_arch_type # undef machine_arch_type diff --git a/board/kmc/kzm/Makefile b/board/kmc/kzm/Makefile new file mode 100644 index 0000000..8601230 --- /dev/null +++ b/board/kmc/kzm/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com +# (C) Copyright 2012 Renesas Solutions Corp. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +COBJS := kzm.o +SOBJS := lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(call cmd_link_o_target, $(OBJS) $(SOBJS)) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj) .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/kmc/kzm/kzm.c b/board/kmc/kzm/kzm.c new file mode 100644 index 0000000..ae0868e --- /dev/null +++ b/board/kmc/kzm/kzm.c @@ -0,0 +1,142 @@ +/* + * (C) Copyright 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com + * (C) Copyright 2012 Renesas Solutions Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <netdev.h> +#include <i2c.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define CS0BCR_D (0x06C00400) +#define CS4BCR_D (0x06C00400) +#define CS0WCR_D (0x55062C42) +#define CS4WCR_D (0x19051443) +#define CMNCR_BROMMD0 (1 << 21) +#define CMNCR_BROMMD1 (1 << 22) +#define CMNCR_BROMMD (CMNCR_BROMMD0|CMNCR_BROMMD1) +#define VCLKCR1_D (0x27) + +#define SMSTPCR1_CMT0 (1 << 24) +#define SMSTPCR1_I2C0 (1 << 16) +#define SMSTPCR3_USB (1 << 22) + +#define PORT32CR (0xE6051020) +#define PORT33CR (0xE6051021) +#define PORT34CR (0xE6051022) +#define PORT35CR (0xE6051023) + +int board_early_init_f(void) +{ + writel(CS0BCR_D, CS0BCR); + writel(CS4BCR_D, CS4BCR); + writel(CS0WCR_D, CS0WCR); + writel(CS4WCR_D, CS4WCR); + + clrsetbits_le32(CMNCR, ~CMNCR_BROMMD, CMNCR_BROMMD); + + clrbits_le32(SMSTPCR1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); + clrbits_le32(SRCR1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0)); + clrbits_le32(SMSTPCR3, SMSTPCR3_USB); + clrbits_le32(SRCR3, SMSTPCR3_USB); + writel(VCLKCR1_D, VCLKCR1); + + /* Setup SCIF4 / workaround */ + writeb(0x12, PORT32CR); + writeb(0x22, PORT33CR); + writeb(0x12, PORT34CR); + writeb(0x22, PORT35CR); + + return 0; +} + +int board_init(void) +{ + sh73a0_pinmux_init(); + + /* SCIFA 4 */ + gpio_request(GPIO_FN_SCIFA4_TXD, NULL); + gpio_request(GPIO_FN_SCIFA4_RXD, NULL); + gpio_request(GPIO_FN_SCIFA4_RTS_, NULL); + gpio_request(GPIO_FN_SCIFA4_CTS_, NULL); + + /* Ethernet/SMSC */ + gpio_request(GPIO_PORT224, NULL); + gpio_direction_input(GPIO_PORT224); + + /* SMSC/USB */ + gpio_request(GPIO_FN_CS4_, NULL); + + /* MMCIF */ + gpio_request(GPIO_FN_MMCCLK0, NULL); + gpio_request(GPIO_FN_MMCCMD0_PU, NULL); + gpio_request(GPIO_FN_MMCD0_0_PU, NULL); + gpio_request(GPIO_FN_MMCD0_1_PU, NULL); + gpio_request(GPIO_FN_MMCD0_2_PU, NULL); + gpio_request(GPIO_FN_MMCD0_3_PU, NULL); + gpio_request(GPIO_FN_MMCD0_4_PU, NULL); + gpio_request(GPIO_FN_MMCD0_5_PU, NULL); + gpio_request(GPIO_FN_MMCD0_6_PU, NULL); + gpio_request(GPIO_FN_MMCD0_7_PU, NULL); + + /* SDHI */ + gpio_request(GPIO_FN_SDHIWP0, NULL); + gpio_request(GPIO_FN_SDHICD0, NULL); + gpio_request(GPIO_FN_SDHICMD0, NULL); + gpio_request(GPIO_FN_SDHICLK0, NULL); + gpio_request(GPIO_FN_SDHID0_3, NULL); + gpio_request(GPIO_FN_SDHID0_2, NULL); + gpio_request(GPIO_FN_SDHID0_1, NULL); + gpio_request(GPIO_FN_SDHID0_0, NULL); + gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON, NULL); + gpio_request(GPIO_PORT15, NULL); + gpio_direction_output(GPIO_PORT15, 1); + + /* I2C */ + gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL); + gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL); + + gd->bd->bi_boot_params = (CONFIG_SYS_SDRAM_BASE + 0x100); + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + return 0; +} + +int board_eth_init(bd_t *bis) +{ + int ret = 0; +#ifdef CONFIG_SMC911X + ret = smc911x_initialize(0, CONFIG_SMC911X_BASE); +#endif + return ret; +} + +void reset_cpu(ulong addr) +{ +} diff --git a/board/kmc/kzm/lowlevel_init.S b/board/kmc/kzm/lowlevel_init.S new file mode 100644 index 0000000..5221611 --- /dev/null +++ b/board/kmc/kzm/lowlevel_init.S @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2012 Nobuhiro Iwamatsu nobuhiro.Iwamatsu.yj@renesas.com + * Copyright (C) 2012 Renesas Solutions Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/macro.h> + +/* loop until a value was compare */ +.macro cmp_loop, addr, data, cmp + ldr r0, =\addr + ldr r1, =\data + ldr r2, =\cmp +2: + ldr r3, [r0, #0] + and r3, r1, r3 + cmp r2, r3 + bne 2b +.endm + +/* read value from addr, and calc OR with data */ +.macro or_write32, addr, data + ldr r4, =\addr + ldr r5, =\data + ldr r6, [r4] + orr r5, r6, r5 + str r5, [r4] +.endm + +/* read value from addr, and calc AND with data */ +.macro and_write32, addr, data + ldr r4, =\addr + ldr r5, =\data + ldr r6, [r4] + and r5, r6, r5 + str r5, [r4] +.endm + +.globl lowlevel_init + +lowlevel_init: + + ldr r0, =MERAM_BASE + mov r1, #0x0 + str r1, [r0] + + mrc p15, 0, r0, c0, c0, 5 + ands r0, r0, #0xF + beq lowlevel_init__ + b wait_interrupt + + .pool + .align 4 + +wait_interrupt: + ldr r1, =ICCICR + mov r2, #0x0 + str r2, [r1] + mov r2, #0xF0 + ldr r1, =ICCPMR + str r2, [r1] + ldr r1, =ICCICR + mov r2, #0x1 + str r2, [r1] + +wait_loop: + wfi + + ldr r2, [r1, #0xC] + str r2, [r1, #0x10] + + ldr r0, =MERAM_BASE + ldr r2, [r0] + cmp r2, #0 + movne pc, r2 + + b wait_loop + +wait_loop_end: + .pool + .align 4 + +lowlevel_init__: + + mov r0, #0x200000 + +loop0: + subs r0, r0, #1 + bne loop0 + + write16 RWTCSRA0, 0xA507 + .pool + + and_write32 LIFEC_SEC_SRC, 0xFFFFFFE7 + + and_write32 SRCR3, 0xFFFF7FFF + and_write32 SMSTPCR2,0xFFFBFFFF + and_write32 SRCR2, 0xFFFBFFFF + write32 PLLECR, 0x00000000 + + cmp_loop PLLECR, 0x00000F00, 0x00000000 + cmp_loop FRQCRB, 0x80000000, 0x00000000 + + write32 PLL0CR, 0x2D000000 + write32 PLL1CR, 0x17100000 + write32 FRQCRB, 0x96235880 + cmp_loop FRQCRB, 0x80000000, 0x00000000 + + write32 FLCKCR, 0x0000000B + and_write32 SMSTPCR0, 0xFFFFFFFD + + and_write32 SRCR0, 0xFFFFFFFD + write32 SMGPIOTIME, 0x00000514 + write32 SMCMT2TIME, 0x00000514 + write32 SMCPGTIME, 0x00000514 + write32 SMSYSCTIME, 0x00000514 + + write32 DVFSCR4, 0x00092000 + write32 DVFSCR5, 0x000000DC + write32 PLLECR, 0x00000000 + cmp_loop PLLECR, 0x00000F00, 0x00000000 + + write32 FRQCRA, 0x0012453C + write32 FRQCRB, 0x80331350 + cmp_loop FRQCRB, 0x80000000, 0x00000000 + write32 FRQCRD, 0x00000B0B + cmp_loop FRQCRD, 0x80000000, 0x00000000 + + write32 PCLKCR, 0x00000003 + write32 VCLKCR1, 0x0000012F + write32 VCLKCR2, 0x00000119 + write32 VCLKCR3, 0x00000119 + write32 ZBCKCR, 0x00000002 + write32 FLCKCR, 0x00000005 + write32 SD0CKCR, 0x00000080 + write32 SD1CKCR, 0x00000080 + write32 SD2CKCR, 0x00000080 + write32 FSIACKCR, 0x0000003F + write32 FSIBCKCR, 0x0000003F + write32 SUBCKCR, 0x00000080 + write32 SPUACKCR, 0x0000000B + write32 SPUVCKCR, 0x0000000B + write32 MSUCKCR, 0x0000013F + write32 HSICKCR, 0x00000080 + write32 MFCK1CR, 0x0000003F + write32 MFCK2CR, 0x0000003F + write32 DSITCKCR, 0x00000107 + write32 DSI0PCKCR, 0x00000313 + write32 DSI1PCKCR, 0x0000130D + write32 DSI0PHYCR, 0x2A800E0E + write32 PLL0CR, 0x1E000000 + write32 PLL0CR, 0x2D000000 + write32 PLL1CR, 0x17100000 + write32 PLL2CR, 0x27000080 + write32 PLL3CR, 0x1D000000 + write32 PLL0STPCR, 0x00080000 + write32 PLL1STPCR, 0x000120C0 + write32 PLL2STPCR, 0x00012000 + write32 PLL3STPCR, 0x00000030 + write32 PLLECR, 0x0000000B + cmp_loop PLLECR, 0x00000B00, 0x00000B00 + + write32 DVFSCR3, 0x000120F0 + write32 MPMODE, 0x00000020 + write32 VREFCR, 0x0000028A + write32 RMSTPCR0, 0xE4628087 + write32 RMSTPCR1, 0xFFFFFFFF + write32 RMSTPCR2, 0x53FFFFFF + write32 RMSTPCR3, 0xFFFFFFFF + write32 RMSTPCR4, 0x00800D3D + write32 RMSTPCR5, 0xFFFFF3FF + write32 SMSTPCR2, 0x00000000 + write32 SRCR2, 0x00040000 + and_write32 PLLECR, 0xFFFFFFF7 + cmp_loop PLLECR, 0x00000800, 0x00000000 + + write32 HPBCTRL6, 0x00000001 + cmp_loop HPBCTRL6, 0x00000001, 0x00000001 + + write32 FRQCRD, 0x00001414 + cmp_loop FRQCRD, 0x80000000, 0x00000000 + + write32 PLL3CR, 0x1D000000 + or_write32 PLLECR, 0x00000008 + cmp_loop PLLECR, 0x00000800, 0x00000800 + + or_write32 DLLCNT0A, 0x00000002 + write32 SDGENCNTA, 0x00000005 + cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000 + + write32 SDCR0A, 0xACC90159 + write32 SDCR1A, 0x00010059 + write32 SDWCRC0A, 0x50874114 + write32 SDWCRC1A, 0x33199B37 + write32 SDWCRC2A, 0x008F2313 + write32 SDWCR00A, 0x31020707 + write32 SDWCR01A, 0x0017040A + write32 SDWCR10A, 0x31020707 + write32 SDWCR11A, 0x0017040A + write32 SDDRVCR0A, 0x05555555 + write32 SDWCR2A, 0x30000000 + or_write32 SDPCRA, 0x00000080 + cmp_loop SDPCRA, 0x00000080, 0x00000080 + write32 SDGENCNTA, 0x00002710 + cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000 + write32 SDMRACR0A, 0x0000003F + write32 SDMRA1, 0x00000000 + write32 SDGENCNTA, 0x000001F4 + cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000 + write32 SDMRACR0A, 0x0000FF0A + write32 SDMRA3, 0x00000000 + write32 SDGENCNTA, 0x00000032 + cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000 + write32 SDMRACR0A, 0x00002201 + write32 SDMRA1, 0x00000000 + write32 SDMRACR0A, 0x00000402 + write32 SDMRA1, 0x00000000 + write32 SDMRACR0A, 0x00000403 + write32 SDMRA1, 0x00000000 + write32 SDMRA2, 0x00000000 + write32 SDMRTMPCRA, 0x88800004 + write32 SDMRTMPMSKA,0x00000004 + write32 RTCORA, 0xA55A0032 + write32 RTCORHA, 0xA55A000C + write32 RTCSRA, 0xA55A2048 + or_write32 SDCR0A, 0x00000800 + or_write32 SDCR1A, 0x00000400 + write32 ZQCCRA, 0xFFF20000 + + or_write32 DLLCNT0B, 0x00000002 + write32 SDGENCNTB, 0x00000005 + cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000 + + write32 SDCR0B, 0xACC90159 + write32 SDCR1B, 0x00010059 + write32 SDWCRC0B, 0x50874114 + write32 SDWCRC1B, 0x33199B37 + write32 SDWCRC2B, 0x008F2313 + write32 SDWCR00B, 0x31020707 + write32 SDWCR01B, 0x0017040A + write32 SDWCR10B, 0x31020707 + write32 SDWCR11B, 0x0017040A + write32 SDDRVCR0B, 0x05555555 + write32 SDWCR2B, 0x30000000 + or_write32 SDPCRB, 0x00000080 + cmp_loop SDPCRB, 0x00000080, 0x00000080 + + write32 SDGENCNTB, 0x00002710 + cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000 + write32 SDMRACR0B, 0x0000003F + write32 SDMRB1, 0x00000000 + write32 SDGENCNTB, 0x000001F4 + cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000 + + write32 SDMRACR0B, 0x0000FF0A + write32 SDMRB3, 0x00000000 + write32 SDGENCNTB, 0x00000032 + cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000 + + write32 SDMRACR0B, 0x00002201 + write32 SDMRB1, 0x00000000 + write32 SDMRACR0B, 0x00000402 + write32 SDMRB1, 0x00000000 + write32 SDMRACR0B, 0x00000403 + write32 SDMRB1, 0x00000000 + write32 SDMRB2, 0x00000000 + write32 SDMRTMPCRB, 0x88800004 + write32 SDMRTMPMSKB, 0x00000004 + write32 RTCORB, 0xA55A0032 + write32 RTCORHB, 0xA55A000C + write32 RTCSRB, 0xA55A2048 + or_write32 SDCR0B, 0x00000800 + or_write32 SDCR1B, 0x00000400 + write32 ZQCCRB, 0xFFF20000 + or_write32 SDPDCR0B, 0x00030000 + write32 DPHYCNT1B, 0xA5390000 + write32 DPHYCNT0B, 0x00001200 + write32 DPHYCNT1B, 0x07CE0000 + write32 DPHYCNT0B, 0x00001247 + cmp_loop DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000 + + and_write32 SDPDCR0B, 0xFFFCFFFF + + write32 FRQCRD, 0x00000B0B + cmp_loop FRQCRD, 0x80000000, 0x00000000 + + bx lr + + .pool + .align 4 diff --git a/boards.cfg b/boards.cfg index 9ef903a..dfd9908 100644 --- a/boards.cfg +++ b/boards.cfg @@ -232,6 +232,7 @@ harmony arm armv7 harmony nvidia seaboard arm armv7 seaboard nvidia tegra2 ventana arm armv7 ventana nvidia tegra2 u8500_href arm armv7 u8500 st-ericsson u8500 +kzm_a9_gt arm armv7 kzm kmc rmobile actux1_4_16 arm ixp actux1 - - actux1:FLASH2X2 actux1_4_32 arm ixp actux1 - - actux1:FLASH2X2,RAM_32MB actux1_8_16 arm ixp actux1 - - actux1:FLASH1X8 diff --git a/include/configs/kzm_a9_gt.h b/include/configs/kzm_a9_gt.h new file mode 100644 index 0000000..48b7afa --- /dev/null +++ b/include/configs/kzm_a9_gt.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com + * Copyright (C) 2012 Renesas Solutions Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __KZM_A9_GT_H +#define __KZM_A9_GT_H + +#undef DEBUG + +#define CONFIG_ARM_CORTEXA9 1 +#define CONFIG_RMOBILE 1 +#define CONFIG_SH73A0 1 +#define CONFIG_KZM_A9_GT 1 +#define CONFIG_MACH_TYPE MACH_TYPE_KZM9G + +#include <asm/arch/rmobile.h> + +#define CONFIG_ARCH_CPU_INIT 1 +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_BOARD_EARLY_INIT_F 1 +#define CONFIG_L2_OFF 1 + +#include <config_cmd_default.h> +#define CONFIG_CMDLINE_TAG 1 +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_DOS_PARTITION 1 +#define CONFIG_CMD_FAT 1 + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTARGS "root=/dev/null console=ttySC4,115200" +#define CONFIG_INTEGRATOR 1 +#define CONFIG_ARCH_CINTEGRATOR 1 +#define CONFIG_BOOTDELAY 3 + +#define CONFIG_VERSION_VARIABLE +#undef CONFIG_SHOW_BOOT_PROGRESS + +/* MEMORY */ +#define KZM_SDRAM_BASE (0x40000000) +#define PHYS_SDRAM KZM_SDRAM_BASE +#define PHYS_SDRAM_SIZE (512 * 1024 * 1024) +#define CONFIG_NR_DRAM_BANKS (1) + +/* NOR Flash */ +#define KZM_FLASH_BASE (0x00000000) +#define CONFIG_SYS_FLASH_BASE (KZM_FLASH_BASE) +#define CONFIG_SYS_FLASH_CFI_WIDTH (FLASH_CFI_16BIT) +#define CONFIG_SYS_MAX_FLASH_BANKS (1) +#define CONFIG_SYS_MAX_FLASH_SECT (512) + +/* prompt */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT "> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_PBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_BARGSIZE 512 +#define CONFIG_SYS_BAUDRATE_TABLE { 115200 } + +/* SCIF */ +#define CONFIG_SCIF_CONSOLE 1 +#define CONFIG_CONS_SCIF4 1 +#undef CONFIG_SYS_CONSOLE_INFO_QUIET +#undef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE +#undef CONFIG_SYS_CONSOLE_ENV_OVERWRITE + +#define CONFIG_SYS_MEMTEST_START (KZM_SDRAM_BASE) +#define CONFIG_SYS_MEMTEST_END \ + (CONFIG_SYS_MEMTEST_START + (60 * 1024 * 1024)) +#undef CONFIG_SYS_ALT_MEMTEST +#undef CONFIG_SYS_MEMTEST_SCRATCH +#undef CONFIG_SYS_LOADS_BAUD_CHANGE + +#define CONFIG_SYS_INIT_RAM_ADDR (0xE5600000) /* MERAM */ +#define CONFIG_SYS_INIT_RAM_SIZE (0x00010000) +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_SDRAM_BASE KZM_SDRAM_BASE +#define CONFIG_SYS_SDRAM_SIZE PHYS_SDRAM_SIZE +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 32 * 1024 * 1024) + +#define CONFIG_SYS_MONITOR_BASE (KZM_FLASH_BASE) +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024) +#define CONFIG_SYS_GBL_DATA_SIZE (256) +#define CONFIG_SYS_BOOTMAPSZ (8 * 1024 * 1024) + +#define CONFIG_SYS_TEXT_BASE 0x00000000 +#define CONFIG_STANDALONE_LOAD_ADDR 0x41000000 + +/* FLASH */ +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#undef CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define FLASH_SECTOR_SIZE (256 * 1024) /* 256 KB sectors */ +#define CONFIG_ENV_SIZE FLASH_SECTOR_SIZE +#define CONFIG_ENV_OFFSET FLASH_SECTOR_SIZE +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET) + +/* Timeout for Flash erase operations (in ms) */ +#define CONFIG_SYS_FLASH_ERASE_TOUT (3 * 1000) +/* Timeout for Flash write operations (in ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT (3 * 1000) +/* Timeout for Flash set sector lock bit operations (in ms) */ +#define CONFIG_SYS_FLASH_LOCK_TOUT (3 * 1000) +/* Timeout for Flash clear lock bit operations (in ms) */ +#define CONFIG_SYS_FLASH_UNLOCK_TOUT (3 * 1000) + +#undef CONFIG_SYS_FLASH_PROTECTION +#undef CONFIG_SYS_DIRECT_FLASH_TFTP +#define CONFIG_ENV_IS_IN_FLASH + +/* GPIO / PFC */ +#define CONFIG_SH_GPIO_PFC 1 + +/* Clock */ +#define CONFIG_SYS_CLK_FREQ 48000000 +#define CONFIG_SYS_CPU_CLK (1196000000) +#define TMU_CLK_DIVIDER (4) /* 4 (default), 16, 64, 256 or 1024 */ +#define CFG_HZ (1000) +#define CONFIG_SYS_HZ CFG_HZ + +/* Ether */ +#define CONFIG_NET_MULTI 1 +#define CONFIG_CMD_PING 1 +#define CONFIG_CMD_DHCP 1 +#define CONFIG_SMC911X 1 +#define CONFIG_SMC911X_BASE (0x10000000) +#define CONFIG_SMC911X_32_BIT 1 + +/* I2C */ +#define CONFIG_CMD_I2C 1 +#define CONFIG_SH_I2C 1 +#define CONFIG_HARD_I2C 1 +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_SYS_MAX_I2C_BUS 2 +#define CONFIG_SYS_I2C_MODULE 1 +#define CONFIG_SYS_I2C_SPEED 100000 /* 100 kHz */ +#define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SH_I2C_DATA_HIGH 4 +#define CONFIG_SH_I2C_DATA_LOW 5 +#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_BASE0 (0xE6820000) +#define CONFIG_SH_I2C_BASE1 (0xE6822000) + +#endif /* __KZM_A9_GT_H */

Hi Nobuhiro,
On Thu, 21 Jun 2012 15:23:39 +0900, Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com wrote :
The KZM-A9-GT board has Renesas R-Mobile SH73A0, 512MB DDR2-SDRAM, USB, Ethernet, and more.
This patch supports the following functions:
- 512MB DDR2-SDRAM
- 16MB NOR Flash memory
- Serial console (SCIF)
- Ethernet (SMSC)
- I2C
Signed-off-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
arch/arm/include/asm/mach-types.h | 2 + board/kmc/kzm/Makefile | 51 ++++++ board/kmc/kzm/kzm.c | 142 +++++++++++++++++ board/kmc/kzm/lowlevel_init.S | 308 +++++++++++++++++++++++++++++++++++++ boards.cfg | 1 + include/configs/kzm_a9_gt.h | 164 ++++++++++++++++++++ 6 files changed, 668 insertions(+) create mode 100644 board/kmc/kzm/Makefile create mode 100644 board/kmc/kzm/kzm.c create mode 100644 board/kmc/kzm/lowlevel_init.S create mode 100644 include/configs/kzm_a9_gt.h
Board should be also added to MAINTAINERS
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index 2d5c3bc..98c992c 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -1106,6 +1106,8 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_ATDGP318 3494 #define MACH_TYPE_OMAP5_SEVM 3777
+#define MACH_TYPE_KZM9G 4140
#ifdef CONFIG_ARCH_EBSA110 # ifdef machine_arch_type # undef machine_arch_type diff --git a/board/kmc/kzm/Makefile b/board/kmc/kzm/Makefile new file mode 100644 index 0000000..8601230 --- /dev/null +++ b/board/kmc/kzm/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com +# (C) Copyright 2012 Renesas Solutions Corp. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +#
+include $(TOPDIR)/config.mk
+LIB = $(obj)lib$(BOARD).o
+COBJS := kzm.o +SOBJS := lowlevel_init.o
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS))
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
- $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+clean:
- rm -f $(SOBJS) $(OBJS)
+distclean: clean
- rm -f $(LIB) core *.bak $(obj) .depend
+#########################################################################
+# defines $(obj).depend target +include $(SRCTREE)/rules.mk
+sinclude $(obj).depend
+######################################################################### diff --git a/board/kmc/kzm/kzm.c b/board/kmc/kzm/kzm.c new file mode 100644 index 0000000..ae0868e --- /dev/null +++ b/board/kmc/kzm/kzm.c @@ -0,0 +1,142 @@ +/*
- (C) Copyright 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
- (C) Copyright 2012 Renesas Solutions Corp.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <netdev.h> +#include <i2c.h>
+DECLARE_GLOBAL_DATA_PTR;
+#define CS0BCR_D (0x06C00400) +#define CS4BCR_D (0x06C00400) +#define CS0WCR_D (0x55062C42) +#define CS4WCR_D (0x19051443) +#define CMNCR_BROMMD0 (1 << 21) +#define CMNCR_BROMMD1 (1 << 22) +#define CMNCR_BROMMD (CMNCR_BROMMD0|CMNCR_BROMMD1) +#define VCLKCR1_D (0x27)
+#define SMSTPCR1_CMT0 (1 << 24) +#define SMSTPCR1_I2C0 (1 << 16) +#define SMSTPCR3_USB (1 << 22)
+#define PORT32CR (0xE6051020) +#define PORT33CR (0xE6051021) +#define PORT34CR (0xE6051022) +#define PORT35CR (0xE6051023)
+int board_early_init_f(void) +{
- writel(CS0BCR_D, CS0BCR);
- writel(CS4BCR_D, CS4BCR);
- writel(CS0WCR_D, CS0WCR);
- writel(CS4WCR_D, CS4WCR);
- clrsetbits_le32(CMNCR, ~CMNCR_BROMMD, CMNCR_BROMMD);
- clrbits_le32(SMSTPCR1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0));
- clrbits_le32(SRCR1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0));
- clrbits_le32(SMSTPCR3, SMSTPCR3_USB);
- clrbits_le32(SRCR3, SMSTPCR3_USB);
- writel(VCLKCR1_D, VCLKCR1);
- /* Setup SCIF4 / workaround */
- writeb(0x12, PORT32CR);
- writeb(0x22, PORT33CR);
- writeb(0x12, PORT34CR);
- writeb(0x22, PORT35CR);
- return 0;
+}
+int board_init(void) +{
- sh73a0_pinmux_init();
- /* SCIFA 4 */
- gpio_request(GPIO_FN_SCIFA4_TXD, NULL);
- gpio_request(GPIO_FN_SCIFA4_RXD, NULL);
- gpio_request(GPIO_FN_SCIFA4_RTS_, NULL);
- gpio_request(GPIO_FN_SCIFA4_CTS_, NULL);
- /* Ethernet/SMSC */
- gpio_request(GPIO_PORT224, NULL);
- gpio_direction_input(GPIO_PORT224);
- /* SMSC/USB */
- gpio_request(GPIO_FN_CS4_, NULL);
- /* MMCIF */
- gpio_request(GPIO_FN_MMCCLK0, NULL);
- gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
- /* SDHI */
- gpio_request(GPIO_FN_SDHIWP0, NULL);
- gpio_request(GPIO_FN_SDHICD0, NULL);
- gpio_request(GPIO_FN_SDHICMD0, NULL);
- gpio_request(GPIO_FN_SDHICLK0, NULL);
- gpio_request(GPIO_FN_SDHID0_3, NULL);
- gpio_request(GPIO_FN_SDHID0_2, NULL);
- gpio_request(GPIO_FN_SDHID0_1, NULL);
- gpio_request(GPIO_FN_SDHID0_0, NULL);
- gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON, NULL);
- gpio_request(GPIO_PORT15, NULL);
- gpio_direction_output(GPIO_PORT15, 1);
- /* I2C */
- gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL);
- gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);
- gd->bd->bi_boot_params = (CONFIG_SYS_SDRAM_BASE + 0x100);
- return 0;
+}
+int dram_init(void) +{
- gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
- return 0;
+}
+int board_eth_init(bd_t *bis) +{
- int ret = 0;
+#ifdef CONFIG_SMC911X
- ret = smc911x_initialize(0, CONFIG_SMC911X_BASE);
+#endif
- return ret;
+}
+void reset_cpu(ulong addr) +{ +} diff --git a/board/kmc/kzm/lowlevel_init.S b/board/kmc/kzm/lowlevel_init.S new file mode 100644 index 0000000..5221611 --- /dev/null +++ b/board/kmc/kzm/lowlevel_init.S @@ -0,0 +1,308 @@ +/*
- Copyright (C) 2012 Nobuhiro Iwamatsu nobuhiro.Iwamatsu.yj@renesas.com
- Copyright (C) 2012 Renesas Solutions Corp.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <config.h> +#include <asm/macro.h>
+/* loop until a value was compare */ +.macro cmp_loop, addr, data, cmp
- ldr r0, =\addr
- ldr r1, =\data
- ldr r2, =\cmp
+2:
- ldr r3, [r0, #0]
- and r3, r1, r3
- cmp r2, r3
- bne 2b
+.endm
+/* read value from addr, and calc OR with data */ +.macro or_write32, addr, data
- ldr r4, =\addr
- ldr r5, =\data
- ldr r6, [r4]
- orr r5, r6, r5
- str r5, [r4]
+.endm
+/* read value from addr, and calc AND with data */ +.macro and_write32, addr, data
- ldr r4, =\addr
- ldr r5, =\data
- ldr r6, [r4]
- and r5, r6, r5
- str r5, [r4]
+.endm
+.globl lowlevel_init
+lowlevel_init:
- ldr r0, =MERAM_BASE
- mov r1, #0x0
- str r1, [r0]
- mrc p15, 0, r0, c0, c0, 5
- ands r0, r0, #0xF
- beq lowlevel_init__
- b wait_interrupt
- .pool
- .align 4
+wait_interrupt:
- ldr r1, =ICCICR
- mov r2, #0x0
- str r2, [r1]
- mov r2, #0xF0
- ldr r1, =ICCPMR
- str r2, [r1]
- ldr r1, =ICCICR
- mov r2, #0x1
- str r2, [r1]
+wait_loop:
- wfi
- ldr r2, [r1, #0xC]
- str r2, [r1, #0x10]
- ldr r0, =MERAM_BASE
- ldr r2, [r0]
- cmp r2, #0
- movne pc, r2
- b wait_loop
+wait_loop_end:
- .pool
- .align 4
+lowlevel_init__:
- mov r0, #0x200000
+loop0:
- subs r0, r0, #1
- bne loop0
- write16 RWTCSRA0, 0xA507
- .pool
- and_write32 LIFEC_SEC_SRC, 0xFFFFFFE7
- and_write32 SRCR3, 0xFFFF7FFF
- and_write32 SMSTPCR2,0xFFFBFFFF
- and_write32 SRCR2, 0xFFFBFFFF
- write32 PLLECR, 0x00000000
- cmp_loop PLLECR, 0x00000F00, 0x00000000
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 PLL0CR, 0x2D000000
- write32 PLL1CR, 0x17100000
- write32 FRQCRB, 0x96235880
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 FLCKCR, 0x0000000B
- and_write32 SMSTPCR0, 0xFFFFFFFD
- and_write32 SRCR0, 0xFFFFFFFD
- write32 SMGPIOTIME, 0x00000514
- write32 SMCMT2TIME, 0x00000514
- write32 SMCPGTIME, 0x00000514
- write32 SMSYSCTIME, 0x00000514
- write32 DVFSCR4, 0x00092000
- write32 DVFSCR5, 0x000000DC
- write32 PLLECR, 0x00000000
- cmp_loop PLLECR, 0x00000F00, 0x00000000
- write32 FRQCRA, 0x0012453C
- write32 FRQCRB, 0x80331350
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 FRQCRD, 0x00000B0B
- cmp_loop FRQCRD, 0x80000000, 0x00000000
- write32 PCLKCR, 0x00000003
- write32 VCLKCR1, 0x0000012F
- write32 VCLKCR2, 0x00000119
- write32 VCLKCR3, 0x00000119
- write32 ZBCKCR, 0x00000002
- write32 FLCKCR, 0x00000005
- write32 SD0CKCR, 0x00000080
- write32 SD1CKCR, 0x00000080
- write32 SD2CKCR, 0x00000080
- write32 FSIACKCR, 0x0000003F
- write32 FSIBCKCR, 0x0000003F
- write32 SUBCKCR, 0x00000080
- write32 SPUACKCR, 0x0000000B
- write32 SPUVCKCR, 0x0000000B
- write32 MSUCKCR, 0x0000013F
- write32 HSICKCR, 0x00000080
- write32 MFCK1CR, 0x0000003F
- write32 MFCK2CR, 0x0000003F
- write32 DSITCKCR, 0x00000107
- write32 DSI0PCKCR, 0x00000313
- write32 DSI1PCKCR, 0x0000130D
- write32 DSI0PHYCR, 0x2A800E0E
- write32 PLL0CR, 0x1E000000
- write32 PLL0CR, 0x2D000000
- write32 PLL1CR, 0x17100000
- write32 PLL2CR, 0x27000080
- write32 PLL3CR, 0x1D000000
- write32 PLL0STPCR, 0x00080000
- write32 PLL1STPCR, 0x000120C0
- write32 PLL2STPCR, 0x00012000
- write32 PLL3STPCR, 0x00000030
- write32 PLLECR, 0x0000000B
- cmp_loop PLLECR, 0x00000B00, 0x00000B00
- write32 DVFSCR3, 0x000120F0
- write32 MPMODE, 0x00000020
- write32 VREFCR, 0x0000028A
- write32 RMSTPCR0, 0xE4628087
- write32 RMSTPCR1, 0xFFFFFFFF
- write32 RMSTPCR2, 0x53FFFFFF
- write32 RMSTPCR3, 0xFFFFFFFF
- write32 RMSTPCR4, 0x00800D3D
- write32 RMSTPCR5, 0xFFFFF3FF
- write32 SMSTPCR2, 0x00000000
- write32 SRCR2, 0x00040000
- and_write32 PLLECR, 0xFFFFFFF7
- cmp_loop PLLECR, 0x00000800, 0x00000000
- write32 HPBCTRL6, 0x00000001
- cmp_loop HPBCTRL6, 0x00000001, 0x00000001
- write32 FRQCRD, 0x00001414
- cmp_loop FRQCRD, 0x80000000, 0x00000000
- write32 PLL3CR, 0x1D000000
- or_write32 PLLECR, 0x00000008
- cmp_loop PLLECR, 0x00000800, 0x00000800
- or_write32 DLLCNT0A, 0x00000002
- write32 SDGENCNTA, 0x00000005
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDCR0A, 0xACC90159
- write32 SDCR1A, 0x00010059
- write32 SDWCRC0A, 0x50874114
- write32 SDWCRC1A, 0x33199B37
- write32 SDWCRC2A, 0x008F2313
- write32 SDWCR00A, 0x31020707
- write32 SDWCR01A, 0x0017040A
- write32 SDWCR10A, 0x31020707
- write32 SDWCR11A, 0x0017040A
- write32 SDDRVCR0A, 0x05555555
- write32 SDWCR2A, 0x30000000
- or_write32 SDPCRA, 0x00000080
- cmp_loop SDPCRA, 0x00000080, 0x00000080
- write32 SDGENCNTA, 0x00002710
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x0000003F
- write32 SDMRA1, 0x00000000
- write32 SDGENCNTA, 0x000001F4
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x0000FF0A
- write32 SDMRA3, 0x00000000
- write32 SDGENCNTA, 0x00000032
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x00002201
- write32 SDMRA1, 0x00000000
- write32 SDMRACR0A, 0x00000402
- write32 SDMRA1, 0x00000000
- write32 SDMRACR0A, 0x00000403
- write32 SDMRA1, 0x00000000
- write32 SDMRA2, 0x00000000
- write32 SDMRTMPCRA, 0x88800004
- write32 SDMRTMPMSKA,0x00000004
- write32 RTCORA, 0xA55A0032
- write32 RTCORHA, 0xA55A000C
- write32 RTCSRA, 0xA55A2048
- or_write32 SDCR0A, 0x00000800
- or_write32 SDCR1A, 0x00000400
- write32 ZQCCRA, 0xFFF20000
- or_write32 DLLCNT0B, 0x00000002
- write32 SDGENCNTB, 0x00000005
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDCR0B, 0xACC90159
- write32 SDCR1B, 0x00010059
- write32 SDWCRC0B, 0x50874114
- write32 SDWCRC1B, 0x33199B37
- write32 SDWCRC2B, 0x008F2313
- write32 SDWCR00B, 0x31020707
- write32 SDWCR01B, 0x0017040A
- write32 SDWCR10B, 0x31020707
- write32 SDWCR11B, 0x0017040A
- write32 SDDRVCR0B, 0x05555555
- write32 SDWCR2B, 0x30000000
- or_write32 SDPCRB, 0x00000080
- cmp_loop SDPCRB, 0x00000080, 0x00000080
- write32 SDGENCNTB, 0x00002710
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x0000003F
- write32 SDMRB1, 0x00000000
- write32 SDGENCNTB, 0x000001F4
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x0000FF0A
- write32 SDMRB3, 0x00000000
- write32 SDGENCNTB, 0x00000032
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x00002201
- write32 SDMRB1, 0x00000000
- write32 SDMRACR0B, 0x00000402
- write32 SDMRB1, 0x00000000
- write32 SDMRACR0B, 0x00000403
- write32 SDMRB1, 0x00000000
- write32 SDMRB2, 0x00000000
- write32 SDMRTMPCRB, 0x88800004
- write32 SDMRTMPMSKB, 0x00000004
- write32 RTCORB, 0xA55A0032
- write32 RTCORHB, 0xA55A000C
- write32 RTCSRB, 0xA55A2048
- or_write32 SDCR0B, 0x00000800
- or_write32 SDCR1B, 0x00000400
- write32 ZQCCRB, 0xFFF20000
- or_write32 SDPDCR0B, 0x00030000
- write32 DPHYCNT1B, 0xA5390000
- write32 DPHYCNT0B, 0x00001200
- write32 DPHYCNT1B, 0x07CE0000
- write32 DPHYCNT0B, 0x00001247
- cmp_loop DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000
- and_write32 SDPDCR0B, 0xFFFCFFFF
- write32 FRQCRD, 0x00000B0B
- cmp_loop FRQCRD, 0x80000000, 0x00000000
Can't all this be simplified by using tables?
- bx lr
- .pool
- .align 4
diff --git a/boards.cfg b/boards.cfg index 9ef903a..dfd9908 100644 --- a/boards.cfg +++ b/boards.cfg @@ -232,6 +232,7 @@ harmony arm armv7 harmony nvidia seaboard arm armv7 seaboard nvidia tegra2 ventana arm armv7 ventana nvidia tegra2 u8500_href arm armv7 u8500 st-ericsson u8500 +kzm_a9_gt arm armv7 kzm kmc rmobile actux1_4_16 arm ixp actux1 - - actux1:FLASH2X2 actux1_4_32 arm ixp actux1 - - actux1:FLASH2X2,RAM_32MB actux1_8_16 arm ixp actux1 - - actux1:FLASH1X8 diff --git a/include/configs/kzm_a9_gt.h b/include/configs/kzm_a9_gt.h new file mode 100644 index 0000000..48b7afa --- /dev/null +++ b/include/configs/kzm_a9_gt.h @@ -0,0 +1,164 @@ +/*
- Copyright (C) 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
- Copyright (C) 2012 Renesas Solutions Corp.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#ifndef __KZM_A9_GT_H +#define __KZM_A9_GT_H
+#undef DEBUG
+#define CONFIG_ARM_CORTEXA9 1
I think the "1" is unneeded; dito below.
+#define CONFIG_RMOBILE 1 +#define CONFIG_SH73A0 1 +#define CONFIG_KZM_A9_GT 1 +#define CONFIG_MACH_TYPE MACH_TYPE_KZM9G
+#include <asm/arch/rmobile.h>
+#define CONFIG_ARCH_CPU_INIT 1 +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_BOARD_EARLY_INIT_F 1 +#define CONFIG_L2_OFF 1
+#include <config_cmd_default.h> +#define CONFIG_CMDLINE_TAG 1 +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_DOS_PARTITION 1 +#define CONFIG_CMD_FAT 1
+#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTARGS "root=/dev/null console=ttySC4,115200" +#define CONFIG_INTEGRATOR 1 +#define CONFIG_ARCH_CINTEGRATOR 1 +#define CONFIG_BOOTDELAY 3
+#define CONFIG_VERSION_VARIABLE +#undef CONFIG_SHOW_BOOT_PROGRESS
+/* MEMORY */ +#define KZM_SDRAM_BASE (0x40000000) +#define PHYS_SDRAM KZM_SDRAM_BASE +#define PHYS_SDRAM_SIZE (512 * 1024 * 1024) +#define CONFIG_NR_DRAM_BANKS (1)
+/* NOR Flash */ +#define KZM_FLASH_BASE (0x00000000) +#define CONFIG_SYS_FLASH_BASE (KZM_FLASH_BASE) +#define CONFIG_SYS_FLASH_CFI_WIDTH (FLASH_CFI_16BIT) +#define CONFIG_SYS_MAX_FLASH_BANKS (1) +#define CONFIG_SYS_MAX_FLASH_SECT (512)
+/* prompt */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT "> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_PBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_BARGSIZE 512 +#define CONFIG_SYS_BAUDRATE_TABLE { 115200 }
+/* SCIF */ +#define CONFIG_SCIF_CONSOLE 1 +#define CONFIG_CONS_SCIF4 1 +#undef CONFIG_SYS_CONSOLE_INFO_QUIET +#undef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE +#undef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
+#define CONFIG_SYS_MEMTEST_START (KZM_SDRAM_BASE) +#define CONFIG_SYS_MEMTEST_END \
- (CONFIG_SYS_MEMTEST_START + (60 * 1024 * 1024))
+#undef CONFIG_SYS_ALT_MEMTEST +#undef CONFIG_SYS_MEMTEST_SCRATCH +#undef CONFIG_SYS_LOADS_BAUD_CHANGE
+#define CONFIG_SYS_INIT_RAM_ADDR (0xE5600000) /* MERAM */ +#define CONFIG_SYS_INIT_RAM_SIZE (0x00010000) +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
CONFIG_SYS_INIT_RAM_SIZE - \
GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_SDRAM_BASE KZM_SDRAM_BASE +#define CONFIG_SYS_SDRAM_SIZE PHYS_SDRAM_SIZE +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 32 * 1024 * 1024)
+#define CONFIG_SYS_MONITOR_BASE (KZM_FLASH_BASE) +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024) +#define CONFIG_SYS_GBL_DATA_SIZE (256) +#define CONFIG_SYS_BOOTMAPSZ (8 * 1024 * 1024)
+#define CONFIG_SYS_TEXT_BASE 0x00000000 +#define CONFIG_STANDALONE_LOAD_ADDR 0x41000000
+/* FLASH */ +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#undef CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define FLASH_SECTOR_SIZE (256 * 1024) /* 256 KB sectors */ +#define CONFIG_ENV_SIZE FLASH_SECTOR_SIZE +#define CONFIG_ENV_OFFSET FLASH_SECTOR_SIZE +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
+/* Timeout for Flash erase operations (in ms) */ +#define CONFIG_SYS_FLASH_ERASE_TOUT (3 * 1000) +/* Timeout for Flash write operations (in ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT (3 * 1000) +/* Timeout for Flash set sector lock bit operations (in ms) */ +#define CONFIG_SYS_FLASH_LOCK_TOUT (3 * 1000) +/* Timeout for Flash clear lock bit operations (in ms) */ +#define CONFIG_SYS_FLASH_UNLOCK_TOUT (3 * 1000)
+#undef CONFIG_SYS_FLASH_PROTECTION +#undef CONFIG_SYS_DIRECT_FLASH_TFTP +#define CONFIG_ENV_IS_IN_FLASH
+/* GPIO / PFC */ +#define CONFIG_SH_GPIO_PFC 1
+/* Clock */ +#define CONFIG_SYS_CLK_FREQ 48000000 +#define CONFIG_SYS_CPU_CLK (1196000000) +#define TMU_CLK_DIVIDER (4) /* 4 (default), 16, 64, 256 or 1024 */ +#define CFG_HZ (1000) +#define CONFIG_SYS_HZ CFG_HZ
+/* Ether */ +#define CONFIG_NET_MULTI 1 +#define CONFIG_CMD_PING 1 +#define CONFIG_CMD_DHCP 1 +#define CONFIG_SMC911X 1 +#define CONFIG_SMC911X_BASE (0x10000000) +#define CONFIG_SMC911X_32_BIT 1
+/* I2C */ +#define CONFIG_CMD_I2C 1 +#define CONFIG_SH_I2C 1 +#define CONFIG_HARD_I2C 1 +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_SYS_MAX_I2C_BUS 2 +#define CONFIG_SYS_I2C_MODULE 1 +#define CONFIG_SYS_I2C_SPEED 100000 /* 100 kHz */ +#define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SH_I2C_DATA_HIGH 4 +#define CONFIG_SH_I2C_DATA_LOW 5 +#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_BASE0 (0xE6820000) +#define CONFIG_SH_I2C_BASE1 (0xE6822000)
+#endif /* __KZM_A9_GT_H */
Amicalement,

Hi, Albert.
Thank you for your review.
2012/6/26 Albert ARIBAUD albert.u.boot@aribaud.net:
Hi Nobuhiro,
On Thu, 21 Jun 2012 15:23:39 +0900, Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com wrote :
The KZM-A9-GT board has Renesas R-Mobile SH73A0, 512MB DDR2-SDRAM, USB, Ethernet, and more.
This patch supports the following functions: - 512MB DDR2-SDRAM - 16MB NOR Flash memory - Serial console (SCIF) - Ethernet (SMSC) - I2C
Signed-off-by: Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
arch/arm/include/asm/mach-types.h | 2 + board/kmc/kzm/Makefile | 51 ++++++ board/kmc/kzm/kzm.c | 142 +++++++++++++++++ board/kmc/kzm/lowlevel_init.S | 308 +++++++++++++++++++++++++++++++++++++ boards.cfg | 1 + include/configs/kzm_a9_gt.h | 164 ++++++++++++++++++++ 6 files changed, 668 insertions(+) create mode 100644 board/kmc/kzm/Makefile create mode 100644 board/kmc/kzm/kzm.c create mode 100644 board/kmc/kzm/lowlevel_init.S create mode 100644 include/configs/kzm_a9_gt.h
Board should be also added to MAINTAINERS
Oh, I will add .
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index 2d5c3bc..98c992c 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -1106,6 +1106,8 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_ATDGP318 3494 #define MACH_TYPE_OMAP5_SEVM 3777
+#define MACH_TYPE_KZM9G 4140
#ifdef CONFIG_ARCH_EBSA110 # ifdef machine_arch_type # undef machine_arch_type diff --git a/board/kmc/kzm/Makefile b/board/kmc/kzm/Makefile new file mode 100644 index 0000000..8601230 --- /dev/null +++ b/board/kmc/kzm/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com +# (C) Copyright 2012 Renesas Solutions Corp. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +#
+include $(TOPDIR)/config.mk
+LIB = $(obj)lib$(BOARD).o
+COBJS := kzm.o +SOBJS := lowlevel_init.o
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS))
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
- $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+clean:
- rm -f $(SOBJS) $(OBJS)
+distclean: clean
- rm -f $(LIB) core *.bak $(obj) .depend
+#########################################################################
+# defines $(obj).depend target +include $(SRCTREE)/rules.mk
+sinclude $(obj).depend
+######################################################################### diff --git a/board/kmc/kzm/kzm.c b/board/kmc/kzm/kzm.c new file mode 100644 index 0000000..ae0868e --- /dev/null +++ b/board/kmc/kzm/kzm.c @@ -0,0 +1,142 @@ +/*
- (C) Copyright 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
- (C) Copyright 2012 Renesas Solutions Corp.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <netdev.h> +#include <i2c.h>
+DECLARE_GLOBAL_DATA_PTR;
+#define CS0BCR_D (0x06C00400) +#define CS4BCR_D (0x06C00400) +#define CS0WCR_D (0x55062C42) +#define CS4WCR_D (0x19051443) +#define CMNCR_BROMMD0 (1 << 21) +#define CMNCR_BROMMD1 (1 << 22) +#define CMNCR_BROMMD (CMNCR_BROMMD0|CMNCR_BROMMD1) +#define VCLKCR1_D (0x27)
+#define SMSTPCR1_CMT0 (1 << 24) +#define SMSTPCR1_I2C0 (1 << 16) +#define SMSTPCR3_USB (1 << 22)
+#define PORT32CR (0xE6051020) +#define PORT33CR (0xE6051021) +#define PORT34CR (0xE6051022) +#define PORT35CR (0xE6051023)
+int board_early_init_f(void) +{
- writel(CS0BCR_D, CS0BCR);
- writel(CS4BCR_D, CS4BCR);
- writel(CS0WCR_D, CS0WCR);
- writel(CS4WCR_D, CS4WCR);
- clrsetbits_le32(CMNCR, ~CMNCR_BROMMD, CMNCR_BROMMD);
- clrbits_le32(SMSTPCR1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0));
- clrbits_le32(SRCR1, (SMSTPCR1_CMT0|SMSTPCR1_I2C0));
- clrbits_le32(SMSTPCR3, SMSTPCR3_USB);
- clrbits_le32(SRCR3, SMSTPCR3_USB);
- writel(VCLKCR1_D, VCLKCR1);
- /* Setup SCIF4 / workaround */
- writeb(0x12, PORT32CR);
- writeb(0x22, PORT33CR);
- writeb(0x12, PORT34CR);
- writeb(0x22, PORT35CR);
- return 0;
+}
+int board_init(void) +{
- sh73a0_pinmux_init();
- /* SCIFA 4 */
- gpio_request(GPIO_FN_SCIFA4_TXD, NULL);
- gpio_request(GPIO_FN_SCIFA4_RXD, NULL);
- gpio_request(GPIO_FN_SCIFA4_RTS_, NULL);
- gpio_request(GPIO_FN_SCIFA4_CTS_, NULL);
- /* Ethernet/SMSC */
- gpio_request(GPIO_PORT224, NULL);
- gpio_direction_input(GPIO_PORT224);
- /* SMSC/USB */
- gpio_request(GPIO_FN_CS4_, NULL);
- /* MMCIF */
- gpio_request(GPIO_FN_MMCCLK0, NULL);
- gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
- gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
- /* SDHI */
- gpio_request(GPIO_FN_SDHIWP0, NULL);
- gpio_request(GPIO_FN_SDHICD0, NULL);
- gpio_request(GPIO_FN_SDHICMD0, NULL);
- gpio_request(GPIO_FN_SDHICLK0, NULL);
- gpio_request(GPIO_FN_SDHID0_3, NULL);
- gpio_request(GPIO_FN_SDHID0_2, NULL);
- gpio_request(GPIO_FN_SDHID0_1, NULL);
- gpio_request(GPIO_FN_SDHID0_0, NULL);
- gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON, NULL);
- gpio_request(GPIO_PORT15, NULL);
- gpio_direction_output(GPIO_PORT15, 1);
- /* I2C */
- gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL);
- gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);
- gd->bd->bi_boot_params = (CONFIG_SYS_SDRAM_BASE + 0x100);
- return 0;
+}
+int dram_init(void) +{
- gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
- return 0;
+}
+int board_eth_init(bd_t *bis) +{
- int ret = 0;
+#ifdef CONFIG_SMC911X
- ret = smc911x_initialize(0, CONFIG_SMC911X_BASE);
+#endif
- return ret;
+}
+void reset_cpu(ulong addr) +{ +} diff --git a/board/kmc/kzm/lowlevel_init.S b/board/kmc/kzm/lowlevel_init.S new file mode 100644 index 0000000..5221611 --- /dev/null +++ b/board/kmc/kzm/lowlevel_init.S @@ -0,0 +1,308 @@ +/*
- Copyright (C) 2012 Nobuhiro Iwamatsu nobuhiro.Iwamatsu.yj@renesas.com
- Copyright (C) 2012 Renesas Solutions Corp.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <config.h> +#include <asm/macro.h>
+/* loop until a value was compare */ +.macro cmp_loop, addr, data, cmp
- ldr r0, =\addr
- ldr r1, =\data
- ldr r2, =\cmp
+2:
- ldr r3, [r0, #0]
- and r3, r1, r3
- cmp r2, r3
- bne 2b
+.endm
+/* read value from addr, and calc OR with data */ +.macro or_write32, addr, data
- ldr r4, =\addr
- ldr r5, =\data
- ldr r6, [r4]
- orr r5, r6, r5
- str r5, [r4]
+.endm
+/* read value from addr, and calc AND with data */ +.macro and_write32, addr, data
- ldr r4, =\addr
- ldr r5, =\data
- ldr r6, [r4]
- and r5, r6, r5
- str r5, [r4]
+.endm
+.globl lowlevel_init
+lowlevel_init:
- ldr r0, =MERAM_BASE
- mov r1, #0x0
- str r1, [r0]
- mrc p15, 0, r0, c0, c0, 5
- ands r0, r0, #0xF
- beq lowlevel_init__
- b wait_interrupt
- .pool
- .align 4
+wait_interrupt:
- ldr r1, =ICCICR
- mov r2, #0x0
- str r2, [r1]
- mov r2, #0xF0
- ldr r1, =ICCPMR
- str r2, [r1]
- ldr r1, =ICCICR
- mov r2, #0x1
- str r2, [r1]
+wait_loop:
- wfi
- ldr r2, [r1, #0xC]
- str r2, [r1, #0x10]
- ldr r0, =MERAM_BASE
- ldr r2, [r0]
- cmp r2, #0
- movne pc, r2
- b wait_loop
+wait_loop_end:
- .pool
- .align 4
+lowlevel_init__:
- mov r0, #0x200000
+loop0:
- subs r0, r0, #1
- bne loop0
- write16 RWTCSRA0, 0xA507
- .pool
- and_write32 LIFEC_SEC_SRC, 0xFFFFFFE7
- and_write32 SRCR3, 0xFFFF7FFF
- and_write32 SMSTPCR2,0xFFFBFFFF
- and_write32 SRCR2, 0xFFFBFFFF
- write32 PLLECR, 0x00000000
- cmp_loop PLLECR, 0x00000F00, 0x00000000
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 PLL0CR, 0x2D000000
- write32 PLL1CR, 0x17100000
- write32 FRQCRB, 0x96235880
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 FLCKCR, 0x0000000B
- and_write32 SMSTPCR0, 0xFFFFFFFD
- and_write32 SRCR0, 0xFFFFFFFD
- write32 SMGPIOTIME, 0x00000514
- write32 SMCMT2TIME, 0x00000514
- write32 SMCPGTIME, 0x00000514
- write32 SMSYSCTIME, 0x00000514
- write32 DVFSCR4, 0x00092000
- write32 DVFSCR5, 0x000000DC
- write32 PLLECR, 0x00000000
- cmp_loop PLLECR, 0x00000F00, 0x00000000
- write32 FRQCRA, 0x0012453C
- write32 FRQCRB, 0x80331350
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 FRQCRD, 0x00000B0B
- cmp_loop FRQCRD, 0x80000000, 0x00000000
- write32 PCLKCR, 0x00000003
- write32 VCLKCR1, 0x0000012F
- write32 VCLKCR2, 0x00000119
- write32 VCLKCR3, 0x00000119
- write32 ZBCKCR, 0x00000002
- write32 FLCKCR, 0x00000005
- write32 SD0CKCR, 0x00000080
- write32 SD1CKCR, 0x00000080
- write32 SD2CKCR, 0x00000080
- write32 FSIACKCR, 0x0000003F
- write32 FSIBCKCR, 0x0000003F
- write32 SUBCKCR, 0x00000080
- write32 SPUACKCR, 0x0000000B
- write32 SPUVCKCR, 0x0000000B
- write32 MSUCKCR, 0x0000013F
- write32 HSICKCR, 0x00000080
- write32 MFCK1CR, 0x0000003F
- write32 MFCK2CR, 0x0000003F
- write32 DSITCKCR, 0x00000107
- write32 DSI0PCKCR, 0x00000313
- write32 DSI1PCKCR, 0x0000130D
- write32 DSI0PHYCR, 0x2A800E0E
- write32 PLL0CR, 0x1E000000
- write32 PLL0CR, 0x2D000000
- write32 PLL1CR, 0x17100000
- write32 PLL2CR, 0x27000080
- write32 PLL3CR, 0x1D000000
- write32 PLL0STPCR, 0x00080000
- write32 PLL1STPCR, 0x000120C0
- write32 PLL2STPCR, 0x00012000
- write32 PLL3STPCR, 0x00000030
- write32 PLLECR, 0x0000000B
- cmp_loop PLLECR, 0x00000B00, 0x00000B00
- write32 DVFSCR3, 0x000120F0
- write32 MPMODE, 0x00000020
- write32 VREFCR, 0x0000028A
- write32 RMSTPCR0, 0xE4628087
- write32 RMSTPCR1, 0xFFFFFFFF
- write32 RMSTPCR2, 0x53FFFFFF
- write32 RMSTPCR3, 0xFFFFFFFF
- write32 RMSTPCR4, 0x00800D3D
- write32 RMSTPCR5, 0xFFFFF3FF
- write32 SMSTPCR2, 0x00000000
- write32 SRCR2, 0x00040000
- and_write32 PLLECR, 0xFFFFFFF7
- cmp_loop PLLECR, 0x00000800, 0x00000000
- write32 HPBCTRL6, 0x00000001
- cmp_loop HPBCTRL6, 0x00000001, 0x00000001
- write32 FRQCRD, 0x00001414
- cmp_loop FRQCRD, 0x80000000, 0x00000000
- write32 PLL3CR, 0x1D000000
- or_write32 PLLECR, 0x00000008
- cmp_loop PLLECR, 0x00000800, 0x00000800
- or_write32 DLLCNT0A, 0x00000002
- write32 SDGENCNTA, 0x00000005
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDCR0A, 0xACC90159
- write32 SDCR1A, 0x00010059
- write32 SDWCRC0A, 0x50874114
- write32 SDWCRC1A, 0x33199B37
- write32 SDWCRC2A, 0x008F2313
- write32 SDWCR00A, 0x31020707
- write32 SDWCR01A, 0x0017040A
- write32 SDWCR10A, 0x31020707
- write32 SDWCR11A, 0x0017040A
- write32 SDDRVCR0A, 0x05555555
- write32 SDWCR2A, 0x30000000
- or_write32 SDPCRA, 0x00000080
- cmp_loop SDPCRA, 0x00000080, 0x00000080
- write32 SDGENCNTA, 0x00002710
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x0000003F
- write32 SDMRA1, 0x00000000
- write32 SDGENCNTA, 0x000001F4
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x0000FF0A
- write32 SDMRA3, 0x00000000
- write32 SDGENCNTA, 0x00000032
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x00002201
- write32 SDMRA1, 0x00000000
- write32 SDMRACR0A, 0x00000402
- write32 SDMRA1, 0x00000000
- write32 SDMRACR0A, 0x00000403
- write32 SDMRA1, 0x00000000
- write32 SDMRA2, 0x00000000
- write32 SDMRTMPCRA, 0x88800004
- write32 SDMRTMPMSKA,0x00000004
- write32 RTCORA, 0xA55A0032
- write32 RTCORHA, 0xA55A000C
- write32 RTCSRA, 0xA55A2048
- or_write32 SDCR0A, 0x00000800
- or_write32 SDCR1A, 0x00000400
- write32 ZQCCRA, 0xFFF20000
- or_write32 DLLCNT0B, 0x00000002
- write32 SDGENCNTB, 0x00000005
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDCR0B, 0xACC90159
- write32 SDCR1B, 0x00010059
- write32 SDWCRC0B, 0x50874114
- write32 SDWCRC1B, 0x33199B37
- write32 SDWCRC2B, 0x008F2313
- write32 SDWCR00B, 0x31020707
- write32 SDWCR01B, 0x0017040A
- write32 SDWCR10B, 0x31020707
- write32 SDWCR11B, 0x0017040A
- write32 SDDRVCR0B, 0x05555555
- write32 SDWCR2B, 0x30000000
- or_write32 SDPCRB, 0x00000080
- cmp_loop SDPCRB, 0x00000080, 0x00000080
- write32 SDGENCNTB, 0x00002710
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x0000003F
- write32 SDMRB1, 0x00000000
- write32 SDGENCNTB, 0x000001F4
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x0000FF0A
- write32 SDMRB3, 0x00000000
- write32 SDGENCNTB, 0x00000032
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x00002201
- write32 SDMRB1, 0x00000000
- write32 SDMRACR0B, 0x00000402
- write32 SDMRB1, 0x00000000
- write32 SDMRACR0B, 0x00000403
- write32 SDMRB1, 0x00000000
- write32 SDMRB2, 0x00000000
- write32 SDMRTMPCRB, 0x88800004
- write32 SDMRTMPMSKB, 0x00000004
- write32 RTCORB, 0xA55A0032
- write32 RTCORHB, 0xA55A000C
- write32 RTCSRB, 0xA55A2048
- or_write32 SDCR0B, 0x00000800
- or_write32 SDCR1B, 0x00000400
- write32 ZQCCRB, 0xFFF20000
- or_write32 SDPDCR0B, 0x00030000
- write32 DPHYCNT1B, 0xA5390000
- write32 DPHYCNT0B, 0x00001200
- write32 DPHYCNT1B, 0x07CE0000
- write32 DPHYCNT0B, 0x00001247
- cmp_loop DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000
- and_write32 SDPDCR0B, 0xFFFCFFFF
- write32 FRQCRD, 0x00000B0B
- cmp_loop FRQCRD, 0x80000000, 0x00000000
Can't all this be simplified by using tables?
I like this style. Because the information of the register is because it can be formed from a data sheet automatically. It is very painful to make a table from a data sheet separately. However, I obey it if a policy of ARM is to use the table.
I will fix this and resend.
- bx lr
- .pool
- .align 4
diff --git a/boards.cfg b/boards.cfg index 9ef903a..dfd9908 100644 --- a/boards.cfg +++ b/boards.cfg @@ -232,6 +232,7 @@ harmony arm armv7 harmony nvidia seaboard arm armv7 seaboard nvidia tegra2 ventana arm armv7 ventana nvidia tegra2 u8500_href arm armv7 u8500 st-ericsson u8500 +kzm_a9_gt arm armv7 kzm kmc rmobile actux1_4_16 arm ixp actux1 - - actux1:FLASH2X2 actux1_4_32 arm ixp actux1 - - actux1:FLASH2X2,RAM_32MB actux1_8_16 arm ixp actux1 - - actux1:FLASH1X8 diff --git a/include/configs/kzm_a9_gt.h b/include/configs/kzm_a9_gt.h new file mode 100644 index 0000000..48b7afa --- /dev/null +++ b/include/configs/kzm_a9_gt.h @@ -0,0 +1,164 @@ +/*
- Copyright (C) 2012 Nobuhiro Iwamatsu nobuhiro.iwamatsu.yj@renesas.com
- Copyright (C) 2012 Renesas Solutions Corp.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#ifndef __KZM_A9_GT_H +#define __KZM_A9_GT_H
+#undef DEBUG
+#define CONFIG_ARM_CORTEXA9 1
I think the "1" is unneeded; dito below.
OK, I rewrite config of this board.
+#define CONFIG_RMOBILE 1 +#define CONFIG_SH73A0 1 +#define CONFIG_KZM_A9_GT 1 +#define CONFIG_MACH_TYPE MACH_TYPE_KZM9G
+#include <asm/arch/rmobile.h>
+#define CONFIG_ARCH_CPU_INIT 1 +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_BOARD_EARLY_INIT_F 1 +#define CONFIG_L2_OFF 1
+#include <config_cmd_default.h> +#define CONFIG_CMDLINE_TAG 1 +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_DOS_PARTITION 1 +#define CONFIG_CMD_FAT 1
+#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTARGS "root=/dev/null console=ttySC4,115200" +#define CONFIG_INTEGRATOR 1 +#define CONFIG_ARCH_CINTEGRATOR 1 +#define CONFIG_BOOTDELAY 3
+#define CONFIG_VERSION_VARIABLE +#undef CONFIG_SHOW_BOOT_PROGRESS
+/* MEMORY */ +#define KZM_SDRAM_BASE (0x40000000) +#define PHYS_SDRAM KZM_SDRAM_BASE +#define PHYS_SDRAM_SIZE (512 * 1024 * 1024) +#define CONFIG_NR_DRAM_BANKS (1)
+/* NOR Flash */ +#define KZM_FLASH_BASE (0x00000000) +#define CONFIG_SYS_FLASH_BASE (KZM_FLASH_BASE) +#define CONFIG_SYS_FLASH_CFI_WIDTH (FLASH_CFI_16BIT) +#define CONFIG_SYS_MAX_FLASH_BANKS (1) +#define CONFIG_SYS_MAX_FLASH_SECT (512)
+/* prompt */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT "> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_PBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_BARGSIZE 512 +#define CONFIG_SYS_BAUDRATE_TABLE { 115200 }
+/* SCIF */ +#define CONFIG_SCIF_CONSOLE 1 +#define CONFIG_CONS_SCIF4 1 +#undef CONFIG_SYS_CONSOLE_INFO_QUIET +#undef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE +#undef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
+#define CONFIG_SYS_MEMTEST_START (KZM_SDRAM_BASE) +#define CONFIG_SYS_MEMTEST_END \
- (CONFIG_SYS_MEMTEST_START + (60 * 1024 * 1024))
+#undef CONFIG_SYS_ALT_MEMTEST +#undef CONFIG_SYS_MEMTEST_SCRATCH +#undef CONFIG_SYS_LOADS_BAUD_CHANGE
+#define CONFIG_SYS_INIT_RAM_ADDR (0xE5600000) /* MERAM */ +#define CONFIG_SYS_INIT_RAM_SIZE (0x00010000) +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
- CONFIG_SYS_INIT_RAM_SIZE - \
- GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_SDRAM_BASE KZM_SDRAM_BASE +#define CONFIG_SYS_SDRAM_SIZE PHYS_SDRAM_SIZE +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 32 * 1024 * 1024)
+#define CONFIG_SYS_MONITOR_BASE (KZM_FLASH_BASE) +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024) +#define CONFIG_SYS_GBL_DATA_SIZE (256) +#define CONFIG_SYS_BOOTMAPSZ (8 * 1024 * 1024)
+#define CONFIG_SYS_TEXT_BASE 0x00000000 +#define CONFIG_STANDALONE_LOAD_ADDR 0x41000000
+/* FLASH */ +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#undef CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define FLASH_SECTOR_SIZE (256 * 1024) /* 256 KB sectors */ +#define CONFIG_ENV_SIZE FLASH_SECTOR_SIZE +#define CONFIG_ENV_OFFSET FLASH_SECTOR_SIZE +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
+/* Timeout for Flash erase operations (in ms) */ +#define CONFIG_SYS_FLASH_ERASE_TOUT (3 * 1000) +/* Timeout for Flash write operations (in ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT (3 * 1000) +/* Timeout for Flash set sector lock bit operations (in ms) */ +#define CONFIG_SYS_FLASH_LOCK_TOUT (3 * 1000) +/* Timeout for Flash clear lock bit operations (in ms) */ +#define CONFIG_SYS_FLASH_UNLOCK_TOUT (3 * 1000)
+#undef CONFIG_SYS_FLASH_PROTECTION +#undef CONFIG_SYS_DIRECT_FLASH_TFTP +#define CONFIG_ENV_IS_IN_FLASH
+/* GPIO / PFC */ +#define CONFIG_SH_GPIO_PFC 1
+/* Clock */ +#define CONFIG_SYS_CLK_FREQ 48000000 +#define CONFIG_SYS_CPU_CLK (1196000000) +#define TMU_CLK_DIVIDER (4) /* 4 (default), 16, 64, 256 or 1024 */ +#define CFG_HZ (1000) +#define CONFIG_SYS_HZ CFG_HZ
+/* Ether */ +#define CONFIG_NET_MULTI 1 +#define CONFIG_CMD_PING 1 +#define CONFIG_CMD_DHCP 1 +#define CONFIG_SMC911X 1 +#define CONFIG_SMC911X_BASE (0x10000000) +#define CONFIG_SMC911X_32_BIT 1
+/* I2C */ +#define CONFIG_CMD_I2C 1 +#define CONFIG_SH_I2C 1 +#define CONFIG_HARD_I2C 1 +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_SYS_MAX_I2C_BUS 2 +#define CONFIG_SYS_I2C_MODULE 1 +#define CONFIG_SYS_I2C_SPEED 100000 /* 100 kHz */ +#define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SH_I2C_DATA_HIGH 4 +#define CONFIG_SH_I2C_DATA_LOW 5 +#define CONFIG_SH_I2C_CLOCK (41666666) +#define CONFIG_SH_I2C_BASE0 (0xE6820000) +#define CONFIG_SH_I2C_BASE1 (0xE6822000)
+#endif /* __KZM_A9_GT_H */
Best regards, Nobuhiro

Dear Nobuhiro Iwamatsu,
In message CABMQnV+RAOvBXAgnMv9Vo2HYjqZ7uZ2-TOx91qAYNrWX4PQM_Q@mail.gmail.com you wrote:
...
--- /dev/null +++ b/board/kmc/kzm/lowlevel_init.S
...
and_write32 LIFEC_SEC_SRC, 0xFFFFFFE7
and_write32 SRCR3, 0xFFFF7FFF
and_write32 SMSTPCR2,0xFFFBFFFF
and_write32 SRCR2, 0xFFFBFFFF
write32 PLLECR, 0x00000000
cmp_loop PLLECR, 0x00000F00, 0x00000000
cmp_loop FRQCRB, 0x80000000, 0x00000000
write32 PLL0CR, 0x2D000000
write32 PLL1CR, 0x17100000
write32 FRQCRB, 0x96235880
cmp_loop FRQCRB, 0x80000000, 0x00000000
write32 FLCKCR, 0x0000000B
and_write32 SMSTPCR0, 0xFFFFFFFD
and_write32 SRCR0, 0xFFFFFFFD
write32 SMGPIOTIME, 0x00000514
write32 SMCMT2TIME, 0x00000514
write32 SMCPGTIME, 0x00000514
write32 SMSYSCTIME, 0x00000514
write32 DVFSCR4, 0x00092000
write32 DVFSCR5, 0x000000DC
write32 PLLECR, 0x00000000
cmp_loop PLLECR, 0x00000F00, 0x00000000
write32 FRQCRA, 0x0012453C
write32 FRQCRB, 0x80331350
cmp_loop FRQCRB, 0x80000000, 0x00000000
write32 FRQCRD, 0x00000B0B
cmp_loop FRQCRD, 0x80000000, 0x00000000
write32 PCLKCR, 0x00000003
write32 VCLKCR1, 0x0000012F
write32 VCLKCR2, 0x00000119
write32 VCLKCR3, 0x00000119
write32 ZBCKCR, 0x00000002
write32 FLCKCR, 0x00000005
write32 SD0CKCR, 0x00000080
write32 SD1CKCR, 0x00000080
write32 SD2CKCR, 0x00000080
write32 FSIACKCR, 0x0000003F
write32 FSIBCKCR, 0x0000003F
write32 SUBCKCR, 0x00000080
write32 SPUACKCR, 0x0000000B
write32 SPUVCKCR, 0x0000000B
write32 MSUCKCR, 0x0000013F
write32 HSICKCR, 0x00000080
write32 MFCK1CR, 0x0000003F
write32 MFCK2CR, 0x0000003F
write32 DSITCKCR, 0x00000107
write32 DSI0PCKCR, 0x00000313
write32 DSI1PCKCR, 0x0000130D
write32 DSI0PHYCR, 0x2A800E0E
write32 PLL0CR, 0x1E000000
write32 PLL0CR, 0x2D000000
write32 PLL1CR, 0x17100000
write32 PLL2CR, 0x27000080
write32 PLL3CR, 0x1D000000
write32 PLL0STPCR, 0x00080000
write32 PLL1STPCR, 0x000120C0
write32 PLL2STPCR, 0x00012000
write32 PLL3STPCR, 0x00000030
write32 PLLECR, 0x0000000B
cmp_loop PLLECR, 0x00000B00, 0x00000B00
write32 DVFSCR3, 0x000120F0
write32 MPMODE, 0x00000020
write32 VREFCR, 0x0000028A
write32 RMSTPCR0, 0xE4628087
write32 RMSTPCR1, 0xFFFFFFFF
write32 RMSTPCR2, 0x53FFFFFF
write32 RMSTPCR3, 0xFFFFFFFF
write32 RMSTPCR4, 0x00800D3D
write32 RMSTPCR5, 0xFFFFF3FF
write32 SMSTPCR2, 0x00000000
write32 SRCR2, 0x00040000
and_write32 PLLECR, 0xFFFFFFF7
cmp_loop PLLECR, 0x00000800, 0x00000000
write32 HPBCTRL6, 0x00000001
cmp_loop HPBCTRL6, 0x00000001, 0x00000001
write32 FRQCRD, 0x00001414
cmp_loop FRQCRD, 0x80000000, 0x00000000
write32 PLL3CR, 0x1D000000
or_write32 PLLECR, 0x00000008
cmp_loop PLLECR, 0x00000800, 0x00000800
or_write32 DLLCNT0A, 0x00000002
write32 SDGENCNTA, 0x00000005
cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
write32 SDCR0A, 0xACC90159
write32 SDCR1A, 0x00010059
write32 SDWCRC0A, 0x50874114
write32 SDWCRC1A, 0x33199B37
write32 SDWCRC2A, 0x008F2313
write32 SDWCR00A, 0x31020707
write32 SDWCR01A, 0x0017040A
write32 SDWCR10A, 0x31020707
write32 SDWCR11A, 0x0017040A
write32 SDDRVCR0A, 0x05555555
write32 SDWCR2A, 0x30000000
or_write32 SDPCRA, 0x00000080
cmp_loop SDPCRA, 0x00000080, 0x00000080
write32 SDGENCNTA, 0x00002710
cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
write32 SDMRACR0A, 0x0000003F
write32 SDMRA1, 0x00000000
write32 SDGENCNTA, 0x000001F4
cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
write32 SDMRACR0A, 0x0000FF0A
write32 SDMRA3, 0x00000000
write32 SDGENCNTA, 0x00000032
cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
write32 SDMRACR0A, 0x00002201
write32 SDMRA1, 0x00000000
write32 SDMRACR0A, 0x00000402
write32 SDMRA1, 0x00000000
write32 SDMRACR0A, 0x00000403
write32 SDMRA1, 0x00000000
write32 SDMRA2, 0x00000000
write32 SDMRTMPCRA, 0x88800004
write32 SDMRTMPMSKA,0x00000004
write32 RTCORA, 0xA55A0032
write32 RTCORHA, 0xA55A000C
write32 RTCSRA, 0xA55A2048
or_write32 SDCR0A, 0x00000800
or_write32 SDCR1A, 0x00000400
write32 ZQCCRA, 0xFFF20000
or_write32 DLLCNT0B, 0x00000002
write32 SDGENCNTB, 0x00000005
cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
write32 SDCR0B, 0xACC90159
write32 SDCR1B, 0x00010059
write32 SDWCRC0B, 0x50874114
write32 SDWCRC1B, 0x33199B37
write32 SDWCRC2B, 0x008F2313
write32 SDWCR00B, 0x31020707
write32 SDWCR01B, 0x0017040A
write32 SDWCR10B, 0x31020707
write32 SDWCR11B, 0x0017040A
write32 SDDRVCR0B, 0x05555555
write32 SDWCR2B, 0x30000000
or_write32 SDPCRB, 0x00000080
cmp_loop SDPCRB, 0x00000080, 0x00000080
write32 SDGENCNTB, 0x00002710
cmp_loop SDGENCNTB, 0xFFFFFFFF,> 0x00000000
write32 SDMRACR0B, 0x0000003F
write32 SDMRB1, 0x00000000
write32 SDGENCNTB, 0x000001F4
cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
write32 SDMRACR0B, 0x0000FF0A
write32 SDMRB3, 0x00000000
write32 SDGENCNTB, 0x00000032
cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
write32 SDMRACR0B, 0x00002201
write32 SDMRB1, 0x00000000
write32 SDMRACR0B, 0x00000402
write32 SDMRB1, 0x00000000
write32 SDMRACR0B, 0x00000403
write32 SDMRB1, 0x00000000
write32 SDMRB2, 0x00000000
write32 SDMRTMPCRB, 0x88800004
write32 SDMRTMPMSKB, 0x00000004
write32 RTCORB, 0xA55A0032
write32 RTCORHB, 0xA55A000C
write32 RTCSRB, 0xA55A2048
or_write32 SDCR0B, 0x00000800
or_write32 SDCR1B, 0x00000400
write32 ZQCCRB, 0xFFF20000
or_write32 SDPDCR0B, 0x00030000
write32 DPHYCNT1B, 0xA5390000
write32 DPHYCNT0B, 0x00001200
write32 DPHYCNT1B, 0x07CE0000
write32 DPHYCNT0B, 0x00001247
cmp_loop DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000
and_write32 SDPDCR0B, 0xFFFCFFFF
write32 FRQCRD, 0x00000B0B
cmp_loop FRQCRD, 0x80000000, 0x00000000
Can't all this be simplified by using tables?
I like this style. Because the information of the register is because it can be formed from a data sheet automatically. It is very painful to make a table from a data sheet separately. However, I obey it if a policy of ARM is to use the table.
I disagree. You cannot really like this style.
Such a list of completely hard-coded magic numbers, without any comments, is not readable and not maintainable. No programmer can like such code. It is a horrible mess.
I wonder why this is written in assembly at all? Why don't you write all this in C? I cannot see any strong reason that would prevent an implementation in C.
Best regards,
Wolfgang Denk

Hi, Wolfgang.
2012/6/27 Wolfgang Denk wd@denx.de:
Dear Nobuhiro Iwamatsu,
In message CABMQnV+RAOvBXAgnMv9Vo2HYjqZ7uZ2-TOx91qAYNrWX4PQM_Q@mail.gmail.com you wrote:
...
--- /dev/null +++ b/board/kmc/kzm/lowlevel_init.S
...
- and_write32 LIFEC_SEC_SRC, 0xFFFFFFE7
- and_write32 SRCR3, 0xFFFF7FFF
- and_write32 SMSTPCR2,0xFFFBFFFF
- and_write32 SRCR2, 0xFFFBFFFF
- write32 PLLECR, 0x00000000
- cmp_loop PLLECR, 0x00000F00, 0x00000000
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 PLL0CR, 0x2D000000
- write32 PLL1CR, 0x17100000
- write32 FRQCRB, 0x96235880
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 FLCKCR, 0x0000000B
- and_write32 SMSTPCR0, 0xFFFFFFFD
- and_write32 SRCR0, 0xFFFFFFFD
- write32 SMGPIOTIME, 0x00000514
- write32 SMCMT2TIME, 0x00000514
- write32 SMCPGTIME, 0x00000514
- write32 SMSYSCTIME, 0x00000514
- write32 DVFSCR4, 0x00092000
- write32 DVFSCR5, 0x000000DC
- write32 PLLECR, 0x00000000
- cmp_loop PLLECR, 0x00000F00, 0x00000000
- write32 FRQCRA, 0x0012453C
- write32 FRQCRB, 0x80331350
- cmp_loop FRQCRB, 0x80000000, 0x00000000
- write32 FRQCRD, 0x00000B0B
- cmp_loop FRQCRD, 0x80000000, 0x00000000
- write32 PCLKCR, 0x00000003
- write32 VCLKCR1, 0x0000012F
- write32 VCLKCR2, 0x00000119
- write32 VCLKCR3, 0x00000119
- write32 ZBCKCR, 0x00000002
- write32 FLCKCR, 0x00000005
- write32 SD0CKCR, 0x00000080
- write32 SD1CKCR, 0x00000080
- write32 SD2CKCR, 0x00000080
- write32 FSIACKCR, 0x0000003F
- write32 FSIBCKCR, 0x0000003F
- write32 SUBCKCR, 0x00000080
- write32 SPUACKCR, 0x0000000B
- write32 SPUVCKCR, 0x0000000B
- write32 MSUCKCR, 0x0000013F
- write32 HSICKCR, 0x00000080
- write32 MFCK1CR, 0x0000003F
- write32 MFCK2CR, 0x0000003F
- write32 DSITCKCR, 0x00000107
- write32 DSI0PCKCR, 0x00000313
- write32 DSI1PCKCR, 0x0000130D
- write32 DSI0PHYCR, 0x2A800E0E
- write32 PLL0CR, 0x1E000000
- write32 PLL0CR, 0x2D000000
- write32 PLL1CR, 0x17100000
- write32 PLL2CR, 0x27000080
- write32 PLL3CR, 0x1D000000
- write32 PLL0STPCR, 0x00080000
- write32 PLL1STPCR, 0x000120C0
- write32 PLL2STPCR, 0x00012000
- write32 PLL3STPCR, 0x00000030
- write32 PLLECR, 0x0000000B
- cmp_loop PLLECR, 0x00000B00, 0x00000B00
- write32 DVFSCR3, 0x000120F0
- write32 MPMODE, 0x00000020
- write32 VREFCR, 0x0000028A
- write32 RMSTPCR0, 0xE4628087
- write32 RMSTPCR1, 0xFFFFFFFF
- write32 RMSTPCR2, 0x53FFFFFF
- write32 RMSTPCR3, 0xFFFFFFFF
- write32 RMSTPCR4, 0x00800D3D
- write32 RMSTPCR5, 0xFFFFF3FF
- write32 SMSTPCR2, 0x00000000
- write32 SRCR2, 0x00040000
- and_write32 PLLECR, 0xFFFFFFF7
- cmp_loop PLLECR, 0x00000800, 0x00000000
- write32 HPBCTRL6, 0x00000001
- cmp_loop HPBCTRL6, 0x00000001, 0x00000001
- write32 FRQCRD, 0x00001414
- cmp_loop FRQCRD, 0x80000000, 0x00000000
- write32 PLL3CR, 0x1D000000
- or_write32 PLLECR, 0x00000008
- cmp_loop PLLECR, 0x00000800, 0x00000800
- or_write32 DLLCNT0A, 0x00000002
- write32 SDGENCNTA, 0x00000005
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDCR0A, 0xACC90159
- write32 SDCR1A, 0x00010059
- write32 SDWCRC0A, 0x50874114
- write32 SDWCRC1A, 0x33199B37
- write32 SDWCRC2A, 0x008F2313
- write32 SDWCR00A, 0x31020707
- write32 SDWCR01A, 0x0017040A
- write32 SDWCR10A, 0x31020707
- write32 SDWCR11A, 0x0017040A
- write32 SDDRVCR0A, 0x05555555
- write32 SDWCR2A, 0x30000000
- or_write32 SDPCRA, 0x00000080
- cmp_loop SDPCRA, 0x00000080, 0x00000080
- write32 SDGENCNTA, 0x00002710
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x0000003F
- write32 SDMRA1, 0x00000000
- write32 SDGENCNTA, 0x000001F4
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x0000FF0A
- write32 SDMRA3, 0x00000000
- write32 SDGENCNTA, 0x00000032
- cmp_loop SDGENCNTA, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0A, 0x00002201
- write32 SDMRA1, 0x00000000
- write32 SDMRACR0A, 0x00000402
- write32 SDMRA1, 0x00000000
- write32 SDMRACR0A, 0x00000403
- write32 SDMRA1, 0x00000000
- write32 SDMRA2, 0x00000000
- write32 SDMRTMPCRA, 0x88800004
- write32 SDMRTMPMSKA,0x00000004
- write32 RTCORA, 0xA55A0032
- write32 RTCORHA, 0xA55A000C
- write32 RTCSRA, 0xA55A2048
- or_write32 SDCR0A, 0x00000800
- or_write32 SDCR1A, 0x00000400
- write32 ZQCCRA, 0xFFF20000
- or_write32 DLLCNT0B, 0x00000002
- write32 SDGENCNTB, 0x00000005
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDCR0B, 0xACC90159
- write32 SDCR1B, 0x00010059
- write32 SDWCRC0B, 0x50874114
- write32 SDWCRC1B, 0x33199B37
- write32 SDWCRC2B, 0x008F2313
- write32 SDWCR00B, 0x31020707
- write32 SDWCR01B, 0x0017040A
- write32 SDWCR10B, 0x31020707
- write32 SDWCR11B, 0x0017040A
- write32 SDDRVCR0B, 0x05555555
- write32 SDWCR2B, 0x30000000
- or_write32 SDPCRB, 0x00000080
- cmp_loop SDPCRB, 0x00000080, 0x00000080
- write32 SDGENCNTB, 0x00002710
- cmp_loop SDGENCNTB, 0xFFFFFFFF,> 0x00000000
- write32 SDMRACR0B, 0x0000003F
- write32 SDMRB1, 0x00000000
- write32 SDGENCNTB, 0x000001F4
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x0000FF0A
- write32 SDMRB3, 0x00000000
- write32 SDGENCNTB, 0x00000032
- cmp_loop SDGENCNTB, 0xFFFFFFFF, 0x00000000
- write32 SDMRACR0B, 0x00002201
- write32 SDMRB1, 0x00000000
- write32 SDMRACR0B, 0x00000402
- write32 SDMRB1, 0x00000000
- write32 SDMRACR0B, 0x00000403
- write32 SDMRB1, 0x00000000
- write32 SDMRB2, 0x00000000
- write32 SDMRTMPCRB, 0x88800004
- write32 SDMRTMPMSKB, 0x00000004
- write32 RTCORB, 0xA55A0032
- write32 RTCORHB, 0xA55A000C
- write32 RTCSRB, 0xA55A2048
- or_write32 SDCR0B, 0x00000800
- or_write32 SDCR1B, 0x00000400
- write32 ZQCCRB, 0xFFF20000
- or_write32 SDPDCR0B, 0x00030000
- write32 DPHYCNT1B, 0xA5390000
- write32 DPHYCNT0B, 0x00001200
- write32 DPHYCNT1B, 0x07CE0000
- write32 DPHYCNT0B, 0x00001247
- cmp_loop DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000
- and_write32 SDPDCR0B, 0xFFFCFFFF
- write32 FRQCRD, 0x00000B0B
- cmp_loop FRQCRD, 0x80000000, 0x00000000
Can't all this be simplified by using tables?
I like this style. Because the information of the register is because it can be formed from a data sheet automatically. It is very painful to make a table from a data sheet separately. However, I obey it if a policy of ARM is to use the table.
I disagree. You cannot really like this style.
Such a list of completely hard-coded magic numbers, without any comments, is not readable and not maintainable. No programmer can like such code. It is a horrible mess.
I agree.
I wonder why this is written in assembly at all? Why don't you write all this in C? I cannot see any strong reason that would prevent an implementation in C.
In my case, the portion of initialization of a board is mounted based on a hardware designer's information, and the manual of CPU. Since these are templates in many cases, a transplant is easy. However, it also knows that there are various problems so that you may point out
OK, I will change coding style for sh port and rmobile port.
Best regards, Nobuhiro
participants (3)
-
Albert ARIBAUD
-
Nobuhiro Iwamatsu
-
Wolfgang Denk