summaryrefslogtreecommitdiff
path: root/board/ti/logic
diff options
context:
space:
mode:
Diffstat (limited to 'board/ti/logic')
-rw-r--r--board/ti/logic/Makefile6
-rw-r--r--board/ti/logic/logic-display.c33
-rw-r--r--board/ti/logic/logic-product-id.c74
-rw-r--r--board/ti/logic/logic.c116
-rw-r--r--board/ti/logic/prod-id/Makefile50
-rw-r--r--board/ti/logic/prod-id/interface.h15
-rw-r--r--board/ti/logic/prod-id/startup.c124
7 files changed, 354 insertions, 64 deletions
diff --git a/board/ti/logic/Makefile b/board/ti/logic/Makefile
index 67c7fd3f92..ad1cc270bf 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 3c0d17c188..d0efb36e26 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 4f427f94b6..3142511d97 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 94562bdd40..b6c16b1d40 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 0000000000..f6dea58eba
--- /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 2646df24ed..8333146a88 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 73dd74069d..d87836ccd1 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
*/