diff options
author | David Ungar <david.ungar@timesys.com> | 2010-10-11 14:23:54 -0400 |
---|---|---|
committer | David Ungar <david.ungar@timesys.com> | 2010-10-11 14:39:18 -0400 |
commit | 5ecaddd0ed2e7c7a65ccd5eb63b94df1a116e50e (patch) | |
tree | b8945dfe304252c32daa1a322344d8b7e5539c42 /board | |
parent | e652fd7cf6150d7df26e990a828e4f4a68452da4 (diff) |
Product id fix
Diffstat (limited to 'board')
-rw-r--r-- | board/omap3/logic/logic-data.c | 728 | ||||
-rw-r--r-- | board/omap3/logic/logic.c | 38 | ||||
-rw-r--r-- | board/omap3/logic/product_id.h | 2 |
3 files changed, 476 insertions, 292 deletions
diff --git a/board/omap3/logic/logic-data.c b/board/omap3/logic/logic-data.c index cb68eba861f..b6720ce1fcd 100644 --- a/board/omap3/logic/logic-data.c +++ b/board/omap3/logic/logic-data.c @@ -23,10 +23,8 @@ #include <command.h> #include <asm/arch/cpu.h> #include <asm/io.h> -// #include <asm/arch/bits.h> #include <asm/arch/mux.h> #include <asm/arch/sys_proto.h> -// #include <asm/arch/sys_info.h> #include <asm/arch/clocks.h> #include <asm/arch/mem.h> #include <i2c.h> @@ -45,19 +43,19 @@ enum { } I2C_RX_MODE; typedef enum { - GPIO_I2C_SDATA, - GPIO_I2C_SCLK, + GPIO_I2C_SDATA, + GPIO_I2C_SCLK, } GPIO_I2C_PIN; static enum { - GPIO_I2C_UNINIT, - GPIO_I2C_STOPPED, - GPIO_I2C_STARTED, + GPIO_I2C_UNINIT, + GPIO_I2C_STOPPED, + GPIO_I2C_STARTED, } gpio_i2c_bus_state; typedef enum { - GPIO_I2C_INPUT, - GPIO_I2C_OUTPUT, + GPIO_I2C_INPUT, + GPIO_I2C_OUTPUT, } GPIO_I2C_DIRECTION; static int gpio_i2c_clock_high_width, gpio_i2c_clock_low_width; @@ -65,13 +63,6 @@ static int gpio_i2c_coarse_delay; #define DEBUG_PRODUCTION_DATA 0 #define DEBUG_PRODUCTION_DATA_BUF 0 -#define STATIC static - -#if 0 -#define MUX_VAL(OFFSET,VALUE) \ - __raw_writew((VALUE), OMAP34XX_CTRL_BASE + (OFFSET)) -#define CP(x) (CONTROL_PADCONF_##x) -#endif /* * IEN - Input Enable @@ -84,16 +75,16 @@ static int gpio_i2c_coarse_delay; * The commented string gives the final mux configuration for that pin */ -// Put SCLK/SDA pins connected to the product ID into GPIO mode -STATIC void gpio_i2c_config_pins(void) +/* Put SCLK/SDA pins connected to the product ID into GPIO mode */ +static void gpio_i2c_config_pins(void) { MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M4)); /*I2C3_SCL*/ MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M4)); /*I2C3_SDA*/ } -// Restore SCLK/SDA pins connected to the product ID back to I2C mode +/* Restore SCLK/SDA pins connected to the product ID back to I2C mode */ -STATIC void gpio_i2c_restore_pins(void) +static void gpio_i2c_restore_pins(void) { MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0)); /*I2C3_SCL*/ MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0)); /*I2C3_SDA*/ @@ -102,176 +93,176 @@ STATIC void gpio_i2c_restore_pins(void) #define GPIO_I2C_GPIO_SCLK 184 #define GPIO_I2C_GPIO_SDATA 185 -STATIC void gpio_i2c_config_pin(GPIO_I2C_PIN pin, GPIO_I2C_DIRECTION dir) +static void gpio_i2c_config_pin(GPIO_I2C_PIN pin, GPIO_I2C_DIRECTION dir) { - if (dir == GPIO_I2C_INPUT) { - if (pin == GPIO_I2C_SCLK) - pin_init_gpio(GPIO_I2C_GPIO_SCLK, 1); - else - pin_init_gpio(GPIO_I2C_GPIO_SDATA, 1); - } else if (dir == GPIO_I2C_OUTPUT) { - if (pin == GPIO_I2C_SCLK) - pin_init_gpio(GPIO_I2C_GPIO_SCLK, 0); - else - pin_init_gpio(GPIO_I2C_GPIO_SDATA, 0); - } + if (dir == GPIO_I2C_INPUT) { + if (pin == GPIO_I2C_SCLK) + pin_init_gpio(GPIO_I2C_GPIO_SCLK, 1); + else + pin_init_gpio(GPIO_I2C_GPIO_SDATA, 1); + } else if (dir == GPIO_I2C_OUTPUT) { + if (pin == GPIO_I2C_SCLK) + pin_init_gpio(GPIO_I2C_GPIO_SCLK, 0); + else + pin_init_gpio(GPIO_I2C_GPIO_SDATA, 0); + } } -STATIC int gpio_i2c_read_pin(GPIO_I2C_PIN pin) +static int gpio_i2c_read_pin(GPIO_I2C_PIN pin) { - if (pin == GPIO_I2C_SCLK) - return pin_get_gpio_input(GPIO_I2C_GPIO_SCLK); - else - return pin_get_gpio_input(GPIO_I2C_GPIO_SDATA); - return 0; + if (pin == GPIO_I2C_SCLK) + return pin_get_gpio_input(GPIO_I2C_GPIO_SCLK); + else + return pin_get_gpio_input(GPIO_I2C_GPIO_SDATA); + return 0; } -STATIC void gpio_i2c_set_pin_level(GPIO_I2C_PIN pin, int level) +static void gpio_i2c_set_pin_level(GPIO_I2C_PIN pin, int level) { - uint8_t pin_level; - - if (pin == GPIO_I2C_SCLK) { - pin_level = pin_get_gpio_input(GPIO_I2C_GPIO_SCLK); - if (((level == 1) && (pin_level == 0)) || - ((level == 0) && (pin_level == 1))) - pin_set_gpio_dataout(GPIO_I2C_GPIO_SCLK, level); - } else if (pin == GPIO_I2C_SDATA) { - if (level == 0) { - gpio_i2c_config_pin(pin, GPIO_I2C_OUTPUT); - pin_set_gpio_dataout(GPIO_I2C_GPIO_SDATA, 0); - } else { - gpio_i2c_config_pin(pin, GPIO_I2C_INPUT); - } - } + uint8_t pin_level; + + if (pin == GPIO_I2C_SCLK) { + pin_level = pin_get_gpio_input(GPIO_I2C_GPIO_SCLK); + if (((level == 1) && (pin_level == 0)) || + ((level == 0) && (pin_level == 1))) + pin_set_gpio_dataout(GPIO_I2C_GPIO_SCLK, level); + } else if (pin == GPIO_I2C_SDATA) { + if (level == 0) { + gpio_i2c_config_pin(pin, GPIO_I2C_OUTPUT); + pin_set_gpio_dataout(GPIO_I2C_GPIO_SDATA, 0); + } else { + gpio_i2c_config_pin(pin, GPIO_I2C_INPUT); + } + } } -STATIC void gpio_i2c_init(int bps) +static void gpio_i2c_init(int bps) { - gpio_i2c_bus_state = GPIO_I2C_UNINIT; + gpio_i2c_bus_state = GPIO_I2C_UNINIT; - // Config SCLK, SDATA pins - gpio_i2c_config_pin(GPIO_I2C_SCLK, GPIO_I2C_OUTPUT); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + // Config SCLK, SDATA pins + gpio_i2c_config_pin(GPIO_I2C_SCLK, GPIO_I2C_OUTPUT); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); - gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT); + gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT); - gpio_i2c_config_pins(); + gpio_i2c_config_pins(); - // Assume 1:1 clock duty cycle - gpio_i2c_clock_high_width = gpio_i2c_clock_low_width - = 1000000 / bps / 2; + // Assume 1:1 clock duty cycle + gpio_i2c_clock_high_width = gpio_i2c_clock_low_width + = 1000000 / bps / 2; - gpio_i2c_coarse_delay = gpio_i2c_clock_high_width; + gpio_i2c_coarse_delay = gpio_i2c_clock_high_width; } -STATIC int gpio_i2c_busy(void) +static int gpio_i2c_busy(void) { - return (gpio_i2c_bus_state == GPIO_I2C_STARTED); + return (gpio_i2c_bus_state == GPIO_I2C_STARTED); } -STATIC void gpio_i2c_tx_stop(void) +static void gpio_i2c_tx_stop(void) { - if (gpio_i2c_bus_state == GPIO_I2C_STARTED) { - udelay(gpio_i2c_coarse_delay); - - // Pull SDATA low - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); - udelay(gpio_i2c_coarse_delay); - - // Push SCLK high - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); - udelay(gpio_i2c_coarse_delay); - - // Now drive SDATA high - thats a STOP. - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); - udelay(gpio_i2c_coarse_delay); - gpio_i2c_bus_state = GPIO_I2C_STOPPED; - } - + if (gpio_i2c_bus_state == GPIO_I2C_STARTED) { + udelay(gpio_i2c_coarse_delay); + + // Pull SDATA low + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); + udelay(gpio_i2c_coarse_delay); + + // Push SCLK high + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + udelay(gpio_i2c_coarse_delay); + + // Now drive SDATA high - thats a STOP. + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); + udelay(gpio_i2c_coarse_delay); + gpio_i2c_bus_state = GPIO_I2C_STOPPED; + } } -STATIC void gpio_i2c_tx_start(void) +static void gpio_i2c_tx_start(void) { - if (gpio_i2c_bus_state == GPIO_I2C_UNINIT || gpio_i2c_bus_state == GPIO_I2C_STOPPED) { - udelay(gpio_i2c_coarse_delay); - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); - udelay(gpio_i2c_coarse_delay); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); - udelay(gpio_i2c_coarse_delay); - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); - udelay(gpio_i2c_coarse_delay); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); - udelay(gpio_i2c_coarse_delay); - gpio_i2c_bus_state = GPIO_I2C_STARTED; - } + if (gpio_i2c_bus_state == GPIO_I2C_UNINIT + || gpio_i2c_bus_state == GPIO_I2C_STOPPED) { + udelay(gpio_i2c_coarse_delay); + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); + udelay(gpio_i2c_coarse_delay); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + udelay(gpio_i2c_coarse_delay); + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); + udelay(gpio_i2c_coarse_delay); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); + udelay(gpio_i2c_coarse_delay); + gpio_i2c_bus_state = GPIO_I2C_STARTED; + } } // Return !0 if NACK -STATIC int gpio_i2c_tx_byte(uint8_t data) +static int gpio_i2c_tx_byte(uint8_t data) { - uint8_t clock, tx_bit_mask=0x80, nack; - - if (gpio_i2c_bus_state != GPIO_I2C_STARTED) - printf("%s: Unexpected I2C bus state!\n", __FUNCTION__); - - udelay(gpio_i2c_coarse_delay); - - for (clock=0; clock <= 7; ++clock) { - if (data & tx_bit_mask) - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); - else - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); - udelay(gpio_i2c_clock_low_width); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); - udelay(gpio_i2c_clock_high_width); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); - tx_bit_mask >>= 1; - } - gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT); - udelay(gpio_i2c_clock_low_width); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); - udelay(gpio_i2c_clock_high_width); - nack = gpio_i2c_read_pin(GPIO_I2C_SDATA); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); - return (nack != 0); + uint8_t clock, tx_bit_mask=0x80, nack; + + if (gpio_i2c_bus_state != GPIO_I2C_STARTED) + printf("%s: Unexpected I2C bus state!\n", __FUNCTION__); + + udelay(gpio_i2c_coarse_delay); + + for (clock=0; clock <= 7; ++clock) { + if (data & tx_bit_mask) + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); + else + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); + udelay(gpio_i2c_clock_low_width); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + udelay(gpio_i2c_clock_high_width); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); + tx_bit_mask >>= 1; + } + gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT); + udelay(gpio_i2c_clock_low_width); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + udelay(gpio_i2c_clock_high_width); + nack = gpio_i2c_read_pin(GPIO_I2C_SDATA); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); + return (nack != 0); } -STATIC int gpio_i2c_rx_byte(uint8_t *data, int rx_mode) +static int gpio_i2c_rx_byte(uint8_t *data, int rx_mode) { - uint8_t clock, data_bit; - - *data = 0; - - gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT); - - udelay(gpio_i2c_coarse_delay); - - for (clock=0; clock<=8; ++clock) { - if (clock < 8) { - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); - udelay(gpio_i2c_clock_high_width); - data_bit = gpio_i2c_read_pin(GPIO_I2C_SDATA); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); - *data = (*data << 1) | data_bit; - } else { - if ((rx_mode == RX_MODE_LAST_BYTE) || (rx_mode == RX_MODE_ONE_BYTE)) - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); - else - gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); - - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); - udelay(gpio_i2c_clock_high_width); - gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); - } - udelay(gpio_i2c_clock_low_width); - } - - return 0; + uint8_t clock, data_bit; + + *data = 0; + + gpio_i2c_config_pin(GPIO_I2C_SDATA, GPIO_I2C_INPUT); + + udelay(gpio_i2c_coarse_delay); + + for (clock=0; clock<=8; ++clock) { + if (clock < 8) { + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + udelay(gpio_i2c_clock_high_width); + data_bit = gpio_i2c_read_pin(GPIO_I2C_SDATA); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); + *data = (*data << 1) | data_bit; + } else { + if ((rx_mode == RX_MODE_LAST_BYTE) || (rx_mode == RX_MODE_ONE_BYTE)) + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 1); + else + gpio_i2c_set_pin_level(GPIO_I2C_SDATA, 0); + + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + udelay(gpio_i2c_clock_high_width); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); + } + udelay(gpio_i2c_clock_low_width); + } + + return 0; } -STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen) +static int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen) { int timeout = 1000; int retry; @@ -279,15 +270,15 @@ STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen) int tick, err, idx; if (DEBUG_PRODUCTION_DATA) { - char buf[128]; - int i, offset; - for (offset = 0, i=0; i<len; ++i) { - if (!i) - offset = sprintf(buf, "%02x", data[i]); - else - offset += sprintf(&buf[offset], " %02x", data[i]); - } - printf("%s: %s\n", __FUNCTION__, buf); + char buf[3 * len + 2]; + int i, offset; + for (offset = 0, i=0; i<len; ++i) { + if (!i) + offset = sprintf(buf, "%02x", data[i]); + else + offset += sprintf(&buf[offset], " %02x", data[i]); + } + printf("%s: %s\n", __FUNCTION__, buf); } // Wait for bus @@ -295,7 +286,7 @@ STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen) udelay(100); if (!timeout) - printf("%s:%d i2c_busy never return zero!\n", __FUNCTION__, __LINE__); + printf("%s:%d i2c_busy never return zero!\n", __FUNCTION__, __LINE__); retry = 0; do { @@ -321,71 +312,201 @@ STATIC int send_packet(uint8_t *data, int len, uint8_t *rxbuf, int rxlen) } while (err && (retry++ < 5)); if (err) - return err; + return err; // Are we expecting a response? if (rxbuf) { - for (idx = 0; idx < rxlen; ++idx) { - if (rxlen == 1) - rx_mode = RX_MODE_ONE_BYTE; - else if (idx == (rxlen - 1)) - rx_mode = RX_MODE_LAST_BYTE; - else if (idx == (rxlen - 2)) - rx_mode = RX_MODE_NEXT_TO_LAST_BYTE; - else if (idx == 0) - rx_mode = RX_MODE_FIRST_BYTE; - else - rx_mode = RX_MODE_MIDDLE_BYTE; - - err = gpio_i2c_rx_byte(&rxbuf[idx], rx_mode); - if (DEBUG_PRODUCTION_DATA) { - if (err) - printf("%s:%d err idx %d\n", __FUNCTION__, __LINE__, idx); - } - // tx_ack(); - } + for (idx = 0; idx < rxlen; ++idx) { + if (rxlen == 1) + rx_mode = RX_MODE_ONE_BYTE; + else if (idx == (rxlen - 1)) + rx_mode = RX_MODE_LAST_BYTE; + else if (idx == (rxlen - 2)) + rx_mode = RX_MODE_NEXT_TO_LAST_BYTE; + else if (idx == 0) + rx_mode = RX_MODE_FIRST_BYTE; + else + rx_mode = RX_MODE_MIDDLE_BYTE; + + err = gpio_i2c_rx_byte(&rxbuf[idx], rx_mode); + if (DEBUG_PRODUCTION_DATA) { + if (err) + printf("%s:%d err idx %d\n", __FUNCTION__, __LINE__, idx); + } + } } gpio_i2c_tx_stop(); return err; } +/* + * Identify the device + */ +struct device_param { + char *name; + unsigned char reset[8]; // ATR for part + unsigned int zones; // number of zones + unsigned int zonesize; // bytes per zone +}; + +static const struct device_param answers[] = { + + { + .name = "AT88SC0104C", + .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x01}, + .zones = 4, + .zonesize = 32 + }, + { + .name = "AT88SC0204C", + .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x02}, + .zones = 4, + .zonesize = 64 + }, + { + .name = "AT88SC0404C", + .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x04}, + .zones = 4, + .zonesize = 128 + }, + { + .name = "AT88SC0808C", + .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x08}, + .zones = 8, + .zonesize = 128 + }, + { + .name = "AT88SC1616C", + .reset = {0x3B, 0xB2, 0x11, 0x00, 0x10, 0x80, 0x00, 0x16}, + .zones = 16, + .zonesize = 128 + }, + { + .name = "AT88SC3216C", + .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x00, 0x32}, + .zones = 16, + .zonesize = 256 + }, + { + .name = "AT88SC6416C", + .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x00, 0x64}, + .zones = 16, + .zonesize = 512 + }, + { + .name = "AT88SC12816C", + .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x01, 0x28}, + .zones = 16, + .zonesize = 1024 + }, + { + .name = "AT88SC25616C", + .reset = {0x3B, 0xB3, 0x11, 0x00, 0x00, 0x00, 0x02, 0x56}, + .zones = 16, + .zonesize = 2048 + }, +}; + +static const struct device_param *devptr; /* pointer to ID'd device */ + +#define CMD_SYSTEM_READ 0xB6 + +static int +identify_device(void) +{ + const struct device_param *p; + unsigned char cmd[] = { CMD_SYSTEM_READ, 0x00, 0x00, 0x00 }; + unsigned char buf[8]; + int err; + int i,j; + + err = send_packet(cmd, sizeof(cmd), buf, sizeof(buf)); + if (err) + return err; + + if (DEBUG_PRODUCTION_DATA) + printf("%s: ident %02x %02x %02x %02x %02x %02x %02x %02x\n", __FUNCTION__, + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + + for (p=answers,i=0; i<sizeof(answers)/sizeof(answers[0]); ++i,++p) { + for (j=0; j<8 && (p->reset[j] == buf[j]); ++j) + ; + if (j==8) { + devptr = p; + + if (DEBUG_PRODUCTION_DATA) + printf("%s: device %s zones %u zonesize %u\n", __FUNCTION__, + devptr->name, devptr->zones, devptr->zonesize); + + return 0; + } + } + + printf("%s: ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x unknown!\n", __FUNCTION__, + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + + return -1; +} + #define CMD_SYSTEM_WRITE 0xB4 -STATIC int +static int set_user_zone(int zone) { - unsigned char cmd[] = { CMD_SYSTEM_WRITE, 0x03, 0x00, 0x00 }; - if (DEBUG_PRODUCTION_DATA) - printf("%s: zone %d\n", __FUNCTION__, zone); - cmd[2] = zone; - return send_packet(cmd, sizeof(cmd), NULL, 0); + unsigned char cmd[] = { CMD_SYSTEM_WRITE, 0x03, 0x00, 0x00 }; + + if (DEBUG_PRODUCTION_DATA) + printf("%s: zone %d\n", __FUNCTION__, zone); + cmd[2] = zone; + return send_packet(cmd, sizeof(cmd), NULL, 0); } #define CMD_READ_USER_ZONE 0xB2 -STATIC int -read_user_zone(unsigned char *buf, int len, int startoff) +static int +read_user_zone(unsigned int offset, unsigned char *buf, int len) { - unsigned char cmd[] = { CMD_READ_USER_ZONE, 0x00, 0x00, 0x00 }; - int ret; - cmd[2] = startoff; - cmd[3] = len; - ret = send_packet(cmd, sizeof(cmd), buf, len); - - if (DEBUG_PRODUCTION_DATA_BUF) { - char obuf[128]; - int i,j,offset; - for (i = 0, offset=0; i<len; i+=16) { - for (j = 0; j<16 && i+j<len; ++j) - if (!j) - offset = sprintf(obuf, "%02x", buf[i+j]); - else - offset += sprintf(&obuf[offset], " %02x", buf[i+j]); - printf("%s\n", obuf); - } - } - return ret; + unsigned char cmd[] = { CMD_READ_USER_ZONE, 0x00, 0x00, 0x00 }; + int ret; + unsigned int startzone, endzone; + + if (DEBUG_PRODUCTION_DATA) + printf("%s: offset %u len %d\n", __FUNCTION__, offset, len); + + // abort if we're not in one zone, or past the end of the device + startzone = offset / devptr->zonesize; + endzone = (offset + (len - 1)) / devptr->zonesize; + if (startzone != endzone) { + printf("%s: startzone %d != endzone %d (len %d, offset %d)\n", __FUNCTION__, startzone, endzone, offset, len); + return -1; + } + if (endzone > devptr->zones) { + printf("%s: endzone %d > numzones\n", __FUNCTION__, endzone); + return -1; + } + + // Set the zone + if (set_user_zone(startzone)) + return -1; + + cmd[2] = offset % devptr->zonesize; + cmd[3] = len; + ret = send_packet(cmd, sizeof(cmd), buf, len); + + if (DEBUG_PRODUCTION_DATA_BUF) { + char obuf[128]; + int i,j,offset; + for (i = 0, offset=0; i<len; i+=16) { + for (j = 0; j<16 && i+j<len; ++j) + if (!j) + offset = sprintf(obuf, "%02x", buf[i+j]); + else + offset += sprintf(&obuf[offset], " %02x", buf[i+j]); + printf("%s\n", obuf); + } + } + return ret; } #define XMK_STR(x) #x @@ -394,23 +515,26 @@ int production_data_valid; struct product_id_data product_id_data; -void board_get_nth_enetaddr (unsigned char *enetaddr, int which) +/* + * Extract/set an ethernet address. + * Which is the address in the environment, position is which MAC address + * in the product ID data + */ +void board_get_nth_enetaddr (unsigned char *enetaddr, int which, int position) { - unsigned char *mac = &product_id_data.d.zone2.mac[which][0]; + unsigned char *mac = &product_id_data.d.zone2.mac[position][0]; char *s = NULL, *e; int i; char ethbuf[18]; - // If the data is bogus, or the MAC address is 00:00:00 or ff:ff:ff - // then blow zeros into the address. // We only handle the first two interfaces (LAN/WiFi)... if (which >= 2) return; -#if 0 - printf("%s:%d valid %d which %d %02x:%02x:%02x\n", __FUNCTION__, __LINE__, production_data_valid, which, - mac[0], mac[1], mac[2]); -#endif + if (DEBUG_PRODUCTION_DATA) + printf("%s: valid %d which %d %02x:%02x:%02x\n", __FUNCTION__, + production_data_valid, which, + mac[0], mac[1], mac[2]); memset(enetaddr, '\0', 6); if (!production_data_valid || @@ -418,17 +542,11 @@ void board_get_nth_enetaddr (unsigned char *enetaddr, int which) || (mac[0] == 0x00 && mac[1] == 0x00 && mac[2] == 0x00)) { s = getenv("ethaddr"); - // Skip the WiFi for rev 1 boards (no WiFi address) - if (which == 1) - return; - #ifdef CONFIG_ETHADDR if (!s) s = MK_STR(CONFIG_ETHADDR); #endif -#if 1 - printf("%s:%d %s\n", __FUNCTION__, __LINE__, s); -#endif + printf("%s which %d %s\n", __FUNCTION__, which, s); for (i = 0; i < 6; ++i) { enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0; if (s) @@ -526,7 +644,7 @@ static void extract_model_number_revision(struct product_id_data *p, char *buf, strncpy(buf, product_id_data.d.zone1.model_number, buflen); buf[buflen-1] = '\0'; i = strlen(buf); - if (i + 3 < buflen) { + if (i && (i + 3 < buflen)) { buf[i] = '-'; buf[i+1] = product_id_data.d.zone1.model_revision; buf[i+2] = '\0'; @@ -535,66 +653,98 @@ static void extract_model_number_revision(struct product_id_data *p, char *buf, int fetch_production_data(void) { - int err = 0; - char buf[36]; - int header_version; - int checksum; - - gpio_i2c_init(50000); - - printf("Read production data: "); - if (set_user_zone(0) || read_user_zone((unsigned char *)&product_id_data.d.u_zone0, sizeof(product_id_data.d.u_zone0), 0)) { - printf("failed!\n"); - err = -1; - goto out; - } - - // If the header doesn't match, we can't map any of the data - if (extract_header_version(&product_id_data, &header_version)) { - err = -2; - printf("failed - invalid header version %d!\n", header_version); - goto out; - } - - if (set_user_zone(1) || read_user_zone((unsigned char *)&product_id_data.d.zone1, sizeof(product_id_data.d.zone1), 0)) { - printf("failed!\n"); - err = -3; - goto out; - } - - if (set_user_zone(2) || read_user_zone((unsigned char *)&product_id_data.d.zone2, sizeof(product_id_data.d.zone2), 0)) { - printf("failed!\n"); - err = -4; - goto out; - } - - printf("done\n"); - - // Correct endianess issues - product_id_data.d.zone2.processor_type = le16_to_cpu(product_id_data.d.zone2.processor_type); - product_id_data.d.zone2.features = le32_to_cpu(product_id_data.d.zone2.features); - product_id_data.d.zone2.platform_bits = le32_to_cpu(product_id_data.d.zone2.platform_bits); - - // Print out the name, model number, and set MAC addresses - extract_product_id_part_number(&product_id_data, buf, sizeof(buf)); - - printf("Part Number : %s\n", buf); - extract_model_number_revision(&product_id_data, buf, sizeof(buf)); - printf("Model Name : %s\n", buf); - extract_serial_number(&product_id_data, buf, sizeof(buf)); - printf("Serial Number: %s\n", buf); - - out: - production_data_valid = !err; - - // Restore pins back to their intended use - gpio_i2c_restore_pins(); - - // Clone the production data into SRAM - checksum = calculate_checksum(&product_id_data.d, sizeof(product_id_data.d)); - product_id_data.checksum = checksum; - *(struct product_id_data *)(SRAM_BASE) = product_id_data; - - return err; + DECLARE_GLOBAL_DATA_PTR; + + int err = 0; + char buf[36]; + int header_version; + int checksum; + int i; + + // Make sure voltage is to productID chip! + gpio_i2c_init(50000); + + /* The productID chip wants at least 5 clocks to wake it up... */ + gpio_i2c_config_pin(GPIO_I2C_SCLK, GPIO_I2C_OUTPUT); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + for (i=0; i<10; ++i) { + udelay(100); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 0); + udelay(100); + gpio_i2c_set_pin_level(GPIO_I2C_SCLK, 1); + } + + printf("Read production data: "); + + if (identify_device()) { + printf("failed to identify device!\n"); + err = -1; + goto out; + } + + if (read_user_zone(0, (unsigned char *)&product_id_data.d.u_zone0, sizeof(product_id_data.d.u_zone0))) { + printf("failed!\n"); + err = -1; + goto out; + } + + // If the header doesn't match, we can't map any of the data + if (extract_header_version(&product_id_data, &header_version)) { + printf("failed - invalid header version %d!\n", header_version); + err = -2; + goto out; + } + + if (read_user_zone(32, (unsigned char *)&product_id_data.d.zone1, sizeof(product_id_data.d.zone1))) { + printf("failed!\n"); + err = -3; + goto out; + } + + if (read_user_zone(64, (unsigned char *)&product_id_data.d.zone2, sizeof(product_id_data.d.zone2))) { + printf("failed!\n"); + err = -4; + goto out; + } + + printf("done\n"); + + // Correct endianess issues + product_id_data.d.zone2.processor_type = le16_to_cpu(product_id_data.d.zone2.processor_type); + product_id_data.d.zone2.features = le32_to_cpu(product_id_data.d.zone2.features); + product_id_data.d.zone2.platform_bits = le32_to_cpu(product_id_data.d.zone2.platform_bits); + + // Print out the name, model number, and set MAC addresses + extract_product_id_part_number(&product_id_data, buf, sizeof(buf)); + + printf("Part Number : %s\n", buf); + extract_model_number_revision(&product_id_data, buf, sizeof(buf)); + if (strlen(buf)) + printf("Model Name : %s\n", buf); + extract_serial_number(&product_id_data, buf, sizeof(buf)); + printf("Serial Number: %s\n", buf); + printf("Wired Lan MAC: 00:08:ee:%02x:%02x:%02x\n", + product_id_data.d.zone2.mac[0][0], + product_id_data.d.zone2.mac[0][1], + product_id_data.d.zone2.mac[0][2]); + + if (gd->bd->bi_arch_number == MACH_TYPE_OMAP3530_LV_SOM) + printf("Wirless MAC: 00:08:ee:%02x:%02x:%02x\n", + product_id_data.d.zone2.mac[1][0], + product_id_data.d.zone2.mac[1][1], + product_id_data.d.zone2.mac[1][2]); + + out: + production_data_valid = !err; + + // Restore pins back to their intended use + gpio_i2c_restore_pins(); + + // Clone the production data into SRAM + checksum = calculate_checksum(&product_id_data.d, sizeof(product_id_data.d)); + product_id_data.checksum = checksum; + *(struct product_id_data *)(SRAM_BASE) = product_id_data; + + return err; } diff --git a/board/omap3/logic/logic.c b/board/omap3/logic/logic.c index 807f91b33ff..e0bcbc4bf37 100644 --- a/board/omap3/logic/logic.c +++ b/board/omap3/logic/logic.c @@ -145,6 +145,37 @@ int misc_init_r(void) return 0; } +// Turn on VAUX1 voltage to 3.0 volts to drive level shifters and +// power 3.0v parts (tsc2004 and Product ID chip) +#define I2C_TRITON2 0x4b /* Address of Triton power group */ + +void init_vaux1_voltage(void) +{ +#ifdef CONFIG_DRIVER_OMAP34XX_I2C + unsigned char data; + unsigned short msg; + + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + // Select the output voltage + data = 0x04; + i2c_write(I2C_TRITON2, 0x72, 1, &data, 1); + // Select the Processor resource group + data = 0x20; + i2c_write(I2C_TRITON2, 0x72, 1, &data, 1); + // Enable I2C access to the Power bus + data = 0x02; + i2c_write(I2C_TRITON2, 0x4a, 1, &data, 1); + // Send message MSB + msg = (1<<13) | (1<<4) | (0xd<<0); // group(process_grp1):resource(vaux1):res_active; + data = msg >> 8; + i2c_write(I2C_TRITON2, 0x4b, 1, &data, 1); + // Send message LSB + data = msg & 0xff; + i2c_write(I2C_TRITON2, 0x4c, 1, &data, 1); +#endif +} + /****************************************************************************** * Routine: late_board_init * Description: Late hardware init. @@ -155,12 +186,15 @@ int board_late_init(void) // DECLARE_GLOBAL_DATA_PTR; + // Turn on vaux1 to make sure voltage is to the product ID chip + init_vaux1_voltage(); fetch_production_data(); // Extract production data + // Fetch the ethaddr of the LAN - board_get_nth_enetaddr(enetaddr, 0); + board_get_nth_enetaddr(enetaddr, 0, 0); #ifdef CONFIG_HAS_ETH1 // Fetch the ethaddr of the WiFi - board_get_nth_enetaddr(enetaddr, 1); + board_get_nth_enetaddr(enetaddr, 1, 1); #endif return 0; } diff --git a/board/omap3/logic/product_id.h b/board/omap3/logic/product_id.h index 0980f481ea4..77ee9d7d0e9 100644 --- a/board/omap3/logic/product_id.h +++ b/board/omap3/logic/product_id.h @@ -87,4 +87,4 @@ static inline int calculate_checksum(void *p, int len) } extern int fetch_production_data(void); -extern void board_get_nth_enetaddr (unsigned char *enetaddr, int which); +extern void board_get_nth_enetaddr (unsigned char *enetaddr, int which, int position); |