diff options
Diffstat (limited to 'board/ti')
-rw-r--r-- | board/ti/logic/Makefile | 6 | ||||
-rw-r--r-- | board/ti/logic/logic-display.c | 33 | ||||
-rw-r--r-- | board/ti/logic/logic-product-id.c | 74 | ||||
-rw-r--r-- | board/ti/logic/logic.c | 116 | ||||
-rw-r--r-- | board/ti/logic/prod-id/Makefile | 50 | ||||
-rw-r--r-- | board/ti/logic/prod-id/interface.h | 15 | ||||
-rw-r--r-- | board/ti/logic/prod-id/startup.c | 124 |
7 files changed, 354 insertions, 64 deletions
diff --git a/board/ti/logic/Makefile b/board/ti/logic/Makefile index 67c7fd3f926..ad1cc270bff 100644 --- a/board/ti/logic/Makefile +++ b/board/ti/logic/Makefile @@ -25,10 +25,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).o -PROD_ID_OBJS := prod-id/query.o prod-id/startup.o prod-id/crc-15.o \ - prod-id/extract.o prod-id/type.o prod-id/size.o +#PROD_ID_OBJS := prod-id/query.o prod-id/startup.o prod-id/crc-15.o \ +# prod-id/extract.o prod-id/type.o prod-id/size.o -COBJS := logic.o logic-data.o logic-at88.o logic-at24.o logic-i2c.o logic-gpio.o logic-display.o logic-product-id.o $(PROD_ID_OBJS) +COBJS := logic.o logic-data.o logic-at88.o logic-at24.o logic-i2c.o logic-gpio.o logic-display.o logic-product-id.o # $(PROD_ID_OBJS) SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/ti/logic/logic-display.c b/board/ti/logic/logic-display.c index 3c0d17c188d..d0efb36e26b 100644 --- a/board/ti/logic/logic-display.c +++ b/board/ti/logic/logic-display.c @@ -354,14 +354,14 @@ struct logic_panel *logic_find_panel(void) strncpy(panel_name, panel, sizeof(panel_name)); panel_name[sizeof(panel_name)-1] = '\0'; - /* Search for trailing "-dvi" or "-hdmi", if found + /* Search for trailing "-dvi"/"-24" or "-hdmi"/"-24", if found * set data_lines and strip off trailing specifier */ data_lines = 16; if ((p = strrchr(panel_name, '-')) != NULL) { - if (!strcmp(p+1, "dvi")) { + if (!strcmp(p+1, "dvi") || !strcmp(p+1, "16")) { data_lines = 16; *p='\0'; - } else if (!strcmp(p+1, "hdmi")) { + } else if (!strcmp(p+1, "hdmi") || !strcmp(p+1, "24")) { data_lines = 24; *p='\0'; } @@ -887,3 +887,30 @@ U_BOOT_CMD(draw_test, 1, 1, do_draw_test, " - Draw ramps/stipples/boarders on LCD", "" ); + +int do_info_video(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + struct omap_video_timings *timing; + printf("Current display parameters:\n"); + printf("name: %s\n", default_panel.name); + printf("config: %#x\n", default_panel.config); + printf("acb: %#x\n", default_panel.acb); + printf("data_lines: %d\n", default_panel.data_lines); + timing = &default_panel.timing; + printf("x_res: %d\n", timing->x_res); + printf("y_res: %d\n", timing->y_res); + printf("pixel_clock: %d\n", timing->pixel_clock); + printf("hsw: %d\n", timing->hsw); + printf("hfp: %d\n", timing->hfp); + printf("hbp: %d\n", timing->hbp); + printf("vsw: %d\n", timing->vsw); + printf("vfp: %d\n", timing->vfp); + printf("vbp: %d\n", timing->vbp); + + return 0; +} + +U_BOOT_CMD(dump_video, 1, 1, do_info_video, + " - Displays information on video parameters", + "" +); diff --git a/board/ti/logic/logic-product-id.c b/board/ti/logic/logic-product-id.c index 4f427f94b63..3142511d973 100644 --- a/board/ti/logic/logic-product-id.c +++ b/board/ti/logic/logic-product-id.c @@ -40,6 +40,20 @@ struct id_data id_data; +void id_fetch_bytes(unsigned char *mem_ptr, int offset, int size, int *oor) +{ + id_printf("%s mem_ptr %p offset %d size %d\n", __FUNCTION__, mem_ptr, offset, size); + if (id_data.root_size && ((offset + size) >= (id_data.root_offset + id_data.root_size))) { + id_error("Attempt to read past end of buffer (offset %u >= (%u + %u))", offset, id_data.root_offset, id_data.root_size); + *oor = -ID_ERANGE; + return; + } + if (at24_read(offset, mem_ptr, size) != 0) { + *oor = -ID_ENODEV; + } + return; +} + /* Fetch a byte of data from the ID data on the i2c bus */ unsigned char id_fetch_byte(unsigned char *mem_ptr, int offset, int *oor) { @@ -47,7 +61,7 @@ unsigned char id_fetch_byte(unsigned char *mem_ptr, int offset, int *oor) /* If data is off end of known size then complain */ if (id_data.root_size && (offset >= (id_data.root_offset + id_data.root_size))) { - id_printf("Attempt to read past end of buffer (offset %u >= size %u)\n", offset, sizeof(id_data_buf)); + id_error("Attempt to read past end of buffer (offset %u >= (%u + %u))", offset, id_data.root_offset, id_data.root_size); *oor = -ID_ERANGE; return 0; /* Force upper layer to recover */ } @@ -84,6 +98,25 @@ int id_printf(const char *fmt, ...) return 0; } +#ifdef DEBUG_NEW_ID_CODE +int id_dbg_printf(const char *fmt, ...) +{ + va_list args; + char printbuffer[256]; + + va_start (args, fmt); + /* For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + vsprintf (printbuffer, fmt, args); + va_end (args); + /* Print the string */ + serial_puts (printbuffer); + + return 0; +} +#endif + void id_error(const char *fmt, ...) { va_list args; @@ -100,6 +133,22 @@ void id_error(const char *fmt, ...) } +static int _at24_setup(void) +{ + int ret; + + ret=at24_wakeup(); + if(ret) + printf("wakeup_err=%d\n", ret); + return ret; +} + +static int _at24_shutdown(void) +{ + at24_shutdown(); + return 0; +} + static int found_id_data; /* Initialize the product ID data and return 0 if found */ static int product_id_init(void) @@ -114,15 +163,8 @@ static int product_id_init(void) * going back to the AT24 to read the data. */ id_data.mem_ptr = (void *)SRAM_BASE; - ret=at24_wakeup(); - if(ret) { - printf("wakeup_err=%d\n", ret); - } - - ret = id_startup(&id_data); - - at24_shutdown(); + ret = id_startup(&id_data, _at24_setup, _at24_shutdown); if (ret != ID_EOK) { return -1; @@ -273,13 +315,25 @@ int logic_extract_gpmc_timing(int cs, int *config_regs) int do_dump_id_data(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[]) { + int i; printf("id_data: mem_ptr %p root_offset %u root_size %u\n", id_data.mem_ptr, id_data.root_offset, id_data.root_size); + + for (i=0; i<(id_data.root_offset + id_data.root_size); ++i) { + if (!(i & 0xf)) { + if (i) + printf("\n"); + printf("%04x:", i); + } + printf(" %02x", id_data.mem_ptr[i]); + } + printf("\n"); + return 1; } U_BOOT_CMD( dump_id_data, 1, 1, do_dump_id_data, "dump_id_data - dump product ID data", - "dump product ID data in human-readable form" + "dump raw new product ID data as hex" ); diff --git a/board/ti/logic/logic.c b/board/ti/logic/logic.c index 94562bdd40c..b6c16b1d402 100644 --- a/board/ti/logic/logic.c +++ b/board/ti/logic/logic.c @@ -31,6 +31,7 @@ #include <netdev.h> #include <flash.h> #include <nand.h> +#include <malloc.h> #include <i2c.h> #include <twl4030.h> #include <asm/io.h> @@ -147,10 +148,59 @@ void nand_switch_ecc_method(int method) omap_nand_switch_ecc(new_mode); } +/* Non-zero if NOR flash exists on SOM */ +int omap3logic_nor_exists; + +/* Dynamic MTD id/parts default value functions */ +static char *omap3logic_mtdparts_default; +static char *omap3logic_mtdids_default; + +char *get_mtdparts_default(void) +{ + char str[strlen(MTDPARTS_NAND_DEFAULT) + strlen(MTDPARTS_NOR_DEFAULT) + 10]; + + if (!omap3logic_mtdparts_default) { + str[0] = '\0'; + if (nand_size()) + strcpy(str, MTDPARTS_NAND_DEFAULT); + if (omap3logic_nor_exists) { + if (strlen(str)) + strcat(str, ";"); + + strcat(str, MTDPARTS_NOR_DEFAULT); + } + omap3logic_mtdparts_default = malloc(strlen(str) + 1); + if (omap3logic_mtdparts_default) + strcpy(omap3logic_mtdparts_default, str); + } + return omap3logic_mtdparts_default; +} + +char *get_mtdids_default(void) +{ + char str[strlen(MTDIDS_NAND_DEFAULT) + strlen(MTDIDS_NOR_DEFAULT) + 10]; + + if (!omap3logic_mtdids_default) { + str[0] = '\0'; + if (nand_size()) + strcpy(str, MTDIDS_NAND_DEFAULT); + if (omap3logic_nor_exists) { + if (strlen(str)) + strcat(str, ","); + strcat(str, MTDIDS_NOR_DEFAULT); + } + omap3logic_mtdids_default = malloc(strlen(str) + 1); + if (omap3logic_mtdids_default) + strcpy(omap3logic_mtdids_default, str); + } + return omap3logic_mtdids_default; +} + /* - * Touchup the environment, specificaly to setenv "defaultecc" + * Touchup the environment, specificaly "defaultecc", the display, + * and mtdids/mtdparts on default environment */ -void touchup_env(void) +void touchup_env(int initial_env) { /* Set the defaultecc environment variable to the "natural" * ECC method supported by the NAND chip */ @@ -163,6 +213,12 @@ void touchup_env(void) /* touchup the display environment variable(s) */ touchup_display_env(); + + if (initial_env) { + /* Need to set mdtids/mtdparts to computed defaults */ + setenv("mtdparts", get_mtdparts_default()); + setenv("mtdids", get_mtdids_default()); + } } /* @@ -226,6 +282,14 @@ int board_init(void) /* Probe for NOR and if found put into sync mode */ fix_flash_sync(); + /* Initialize twl4030 voltages */ + twl4030_power_init(); + + /* If we're a Torpedo, enable BBCHEN charge the backup battery */ + if (gd->bd->bi_arch_number == MACH_TYPE_DM3730_TORPEDO + || gd->bd->bi_arch_number == MACH_TYPE_OMAP3_TORPEDO) { + twl4030_enable_bb_charging(3200, 25); /* 3.2V @ 25uA */ + } return 0; } @@ -243,7 +307,8 @@ int board_late_init(void) #endif #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK - nand_unlock(&nand_info[0], 0x0, nand_info[0].size); + if (nand_size()) + nand_unlock(&nand_info[0], 0x0, nand_info[0].size); #endif #ifdef CONFIG_ENABLE_TWL4030_CHARGING @@ -276,8 +341,6 @@ void init_vaux1_voltage(void) 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); @@ -297,6 +360,27 @@ void init_vaux1_voltage(void) #endif } +/* Mux I2C bus pins appropriately for this board */ +int i2c_mux_bux_pins(int bus) +{ + switch(bus) { + case 0: + /* I2C1_SCA/I2C1_SDL are *always* mixed for I2C */ + break; + case 1: + MUX_VAL(CP(I2C2_SCL), (IEN | PTU | EN | M0)); + MUX_VAL(CP(I2C2_SDA), (IEN | PTU | EN | M0)); + break; + case 2: + MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0)); + MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0)); + break; + default: + return -1; + } + return 0; +} + /* * Check _SYSCONFIG registers and fixup bootrom code leaving them in * non forced-idle/smart-stdby mode @@ -326,11 +410,6 @@ static void check_sysconfig_regs(void) */ int misc_init_r(void) { - -#ifdef CONFIG_DRIVER_OMAP34XX_I2C - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -#endif - /* Turn on vaux1 to make sure voltage is to the product ID chip. * Extract production data from ID chip, used to selectively * initialize portions of the system */ @@ -387,6 +466,9 @@ static void setup_net_chip(void) } /* GPMC CS0 settings for Logic SOM LV/Torpedo NAND settings */ +#if 0 +/* Following are from current DVT (2012-03-13), but don't work on T+W; + * nand-small-stress-test2.sh shows differences between copied files */ #define LOGIC_NAND_GPMC_CONFIG1 0x00001800 #define LOGIC_NAND_GPMC_CONFIG2 0x00090900 #define LOGIC_NAND_GPMC_CONFIG3 0x00090900 @@ -394,6 +476,17 @@ static void setup_net_chip(void) #define LOGIC_NAND_GPMC_CONFIG5 0x0007080A #define LOGIC_NAND_GPMC_CONFIG6 0x000002CF #define LOGIC_NAND_GPMC_CONFIG7 0x00000C70 +#else +/* Timings that look to work on SOM LV/Torpedo after NAND testing; + * not sure if optimal */ +#define LOGIC_NAND_GPMC_CONFIG1 0x00001800 +#define LOGIC_NAND_GPMC_CONFIG2 0x00090900 +#define LOGIC_NAND_GPMC_CONFIG3 0x00090902 +#define LOGIC_NAND_GPMC_CONFIG4 0x07020702 +#define LOGIC_NAND_GPMC_CONFIG5 0x0008080A +#define LOGIC_NAND_GPMC_CONFIG6 0x000002CF +#define LOGIC_NAND_GPMC_CONFIG7 0x00000C70 +#endif static void setup_nand_settings(void) { @@ -509,7 +602,6 @@ static void setup_isp176x_settings(void) * Description: Setting up the configuration GPMC registers specific to the * NOR flash (and place in sync mode if not done). */ -int omap3logic_flash_exists; static void fix_flash_sync(void) { int arch_number; @@ -591,7 +683,7 @@ static void fix_flash_sync(void) } else puts ("NOR: Already initialized in sync mode\n"); - omap3logic_flash_exists = 1; + omap3logic_nor_exists = 1; } int board_eth_init(bd_t *bis) diff --git a/board/ti/logic/prod-id/Makefile b/board/ti/logic/prod-id/Makefile new file mode 100644 index 00000000000..f6dea58ebaf --- /dev/null +++ b/board/ti/logic/prod-id/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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)libprod-id.o + +PROD_ID_OBJS := query.o startup.o crc-15.o \ + extract.o type.o size.o + +COBJS := $(PROD_ID_OBJS) + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +clean: + rm -f $(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/ti/logic/prod-id/interface.h b/board/ti/logic/prod-id/interface.h index 2646df24ed2..8333146a88d 100644 --- a/board/ti/logic/prod-id/interface.h +++ b/board/ti/logic/prod-id/interface.h @@ -47,6 +47,7 @@ struct id_key { * set *oor to non-zero. If mem_ptr is non-NULL use it as a pointer to * a cached copy of the ID data */ extern unsigned char id_fetch_byte(unsigned char *mem_ptr, int offset, int *oor); +extern void id_fetch_bytes(unsigned char *mem_ptr, int offset, int size, int *oor); struct id_data { /* mem_ptr is a pointer to read the initial ID data into, then if not @@ -58,7 +59,10 @@ struct id_data { /* Function to do the intial startup (i.e. figure out how much data, offset of * key table, etc */ -extern int id_startup(struct id_data *data); +extern int id_startup(struct id_data *data, + int (*setup_id_chip)(void), + int (*shutdown_id_chip)(void)); + /* * Functions provided back to callers for use in accessing data */ @@ -82,6 +86,8 @@ extern int id_whatis(struct id_cookie *cookie, idenum_t *type); /* Given a string, return the key code (or -1 if not found) */ extern int id_data_get_key(char *key_name); +/* Define to get id_dbg_printf() output... */ +#undef DEBUG_NEW_ID_CODE /* ID error routine to handle malformed data */ extern void id_error(const char *fmt, ...); @@ -89,6 +95,13 @@ extern void id_error(const char *fmt, ...); /* Ouptut routine */ extern int id_printf(const char *format, ...); +/* Ouptut debug routine; define DEBUG_NEW_ID_CODE to enable it */ +#ifdef DEBUG_NEW_ID_CODE +extern int id_dbg_printf(const char *format, ...); +#else +#define id_dbg_printf(fmt, ...) +#endif + /* User interface functions */ extern int id_dict_size(struct id_data *data, struct id_cookie *cookie); diff --git a/board/ti/logic/prod-id/startup.c b/board/ti/logic/prod-id/startup.c index 73dd74069d8..d87836ccd13 100644 --- a/board/ti/logic/prod-id/startup.c +++ b/board/ti/logic/prod-id/startup.c @@ -19,7 +19,7 @@ struct __attribute__ ((packed)) id_checksums { unsigned short data; } ; -int id_startup(struct id_data *data) +static int _id_startup(struct id_data *data, int first_run) { int i, err; struct id_cookie cookie; @@ -28,68 +28,74 @@ int id_startup(struct id_data *data) unsigned short xsum; struct id_header hdr; struct id_checksums xsums; - unsigned char *mem_ptr = data->mem_ptr; - - /* Clear out data->mem_ptr since we want all the fetches to come - * from the AT24 chip. Once we've validated the CRCs, restore - * data->mem_ptr to allow id_fetch_byte to read from data->mem_ptr - * instead of the AT24 chip. Should speed up accesses dramatically */ - data->mem_ptr = NULL; + unsigned char *mem_ptr; + unsigned char *cache_ptr; + + if (first_run) { + cache_ptr = data->mem_ptr; + data->mem_ptr = NULL; + mem_ptr = NULL; + } else { + cache_ptr = NULL; + mem_ptr = data->mem_ptr; + } + + id_dbg_printf("%s: first_run %d cach_ptr %p mem_ptr %p\n", __FUNCTION__, first_run, cache_ptr, mem_ptr); memset(&cookie, 0, sizeof(cookie)); /* Data starts with the header, should be 'LpId' */ for (i=0; i<4; ++i) { - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; hdr.signature[i] = byte; cookie.offset++; if (err != ID_EOK) { - id_printf("%s[%u]\n", __FILE__, __LINE__); + id_dbg_printf("%s[%u]\n", __FILE__, __LINE__); goto err_ret; } if (hdr.signature[i] != header_tag[i]) { - id_printf("%s[%u]\n", __FILE__, __LINE__); + id_dbg_printf("%s[%u]\n", __FILE__, __LINE__); err = ID_ENODEV; goto err_ret; } } /* First LE 8-bit value is ID format version */ - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; hdr.id_fmt_ver = byte; cookie.offset++; /* Second LE 8-bit value is currently not used */ - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; hdr.unused0 = byte; cookie.offset++; /* Next LE 16-bit value is length of data */ - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; hdr.data_length = byte; cookie.offset++; - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; hdr.data_length |= byte << 8; cookie.offset++; /* Next LE 16-bit value is xsum of header */ - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; xsums.header = byte; cookie.offset++; - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; xsums.header |= byte << 8; @@ -102,20 +108,20 @@ int id_startup(struct id_data *data) crc_15_step(&xsum, p[i]); if (xsum != xsums.header) { - id_printf("%s[%u] xsum: 0x%04x, xsums.header: 0x%04x\n", + id_dbg_printf("%s[%u] xsum: 0x%04x, xsums.header: 0x%04x\n", __FILE__, __LINE__, xsum, xsums.header); err = -ID_EL2NSYNC; goto err_ret; } /* Next LE 16-bit value is xsum of data */ - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; xsums.data = byte; cookie.offset++; - byte = id_fetch_byte(NULL, cookie.offset, &err); + byte = id_fetch_byte(cache_ptr, cookie.offset, &err); if (mem_ptr) mem_ptr[cookie.offset] = byte; xsums.data |= byte << 8; @@ -123,42 +129,57 @@ int id_startup(struct id_data *data) /* Checksum the data (next id_len bytes), must match xsums.data */ xsum = 0; - for (i = 0; i < hdr.data_length; ++i) { - byte = id_fetch_byte(NULL, cookie.offset + i, &err); - if (mem_ptr) - mem_ptr[cookie.offset + i] = byte; + id_dbg_printf("%s: mem_ptr %p\n", __FUNCTION__, mem_ptr); + if (mem_ptr) { + id_fetch_bytes(mem_ptr+cookie.offset, cookie.offset, hdr.data_length, &err); if (err != ID_EOK) { - id_printf("%s[%u]\n", __FILE__, __LINE__); - goto err_ret; + id_error("%s:%d err %d", __FUNCTION__, __LINE__, err); + goto hard_way; + } + for (i = 0; i < hdr.data_length; ++i) { + crc_15_step(&xsum, mem_ptr[cookie.offset + i]); + } + } else { + hard_way: + for (i = 0; i < hdr.data_length; ++i) { + byte = id_fetch_byte(cache_ptr, cookie.offset + i, &err); + if (mem_ptr) + mem_ptr[cookie.offset + i] = byte; + if (err != ID_EOK) { + id_dbg_printf("%s[%u]\n", __FILE__, __LINE__); + goto err_ret; + } + crc_15_step(&xsum, byte); } - crc_15_step(&xsum, byte); } if (xsum != xsums.data) { - id_printf("%s[%u] xsum: 0x%04x, xsums.data: 0x%04x\n", + id_dbg_printf("%s[%u] xsum: 0x%04x, xsums.data: 0x%04x\n", __FILE__, __LINE__, xsum, xsums.data); err = -ID_EL2NSYNC; goto err_ret; } + /* offset is now at the first byte of the root dictionary which contains its span */ data->root_offset = cookie.offset; + cookie.mem_ptr = cache_ptr; data->root_size = extract_unsigned_pnum(&cookie, 5, &err); if (err != ID_EOK) { - id_printf("%s[%u]\n", __FILE__, __LINE__); + id_dbg_printf("%s[%u]\n", __FILE__, __LINE__); goto err_ret; } - data->root_size += cookie.offset - data->root_offset; - -#if 0 - id_printf("Data format version: %u\n", hdr.id_fmt_ver); -#endif - /* Restore data->mem_ptr to allow id_fetch_byte to read * from the cached data instead of the AT24 chip */ data->mem_ptr = mem_ptr; + id_dbg_printf("%s:%d root_size (old %u) now %u + %u\n", __FUNCTION__, __LINE__, + data->root_size, cookie.offset, data->root_offset); + data->root_size += cookie.offset - data->root_offset; + + id_dbg_printf("Data format version: %u\n", hdr.id_fmt_ver); + return ID_EOK; err_ret: @@ -170,6 +191,39 @@ err_ret: return err; } +int id_startup(struct id_data *data, int (*setup_id_chip)(void), int (*shutdown_id_chip)(void)) +{ + int ret, ret2; + void *mem_ptr = data->mem_ptr; + + /* See if product ID already exists in SRAM (i.e. from x-loader) */ + if (data->mem_ptr) { + ret = _id_startup(data, 1); + data->mem_ptr = mem_ptr; + if (!ret) { + id_printf("Found new Product ID data at %p\n", mem_ptr); + return ret; + } + } + + /* No ID data in SRAM, setup the ID chip and read for real */ + ret = (*setup_id_chip)(); + if (ret) { + id_error("%s: setup_id_chip failed!", __FUNCTION__); + return ret; + } + ret = _id_startup(data, 0); + if (!ret) + id_printf("Cache new Product ID data from AT24 to %p\n", mem_ptr); + ret2 = (*shutdown_id_chip)(); + if (ret2) + id_error("%s: shutdown_id_chip failed!", __FUNCTION__); + + if (!ret && ret2) + ret = ret2; + + return ret; +} /* * Reset the cookie to cover the whole root dictionary */ |