Modifications for 1.2.0:
======================================================================
+* Update LWMON keyboard initialization: we've been told to ignore
+ "Hard Reset" and "Brownout" errors after a reset (when should we
+ check for brownout, then?), and we have to scan the keyboard until
+ it stabilizes.
+
+* Re-arrange initialization sequence: move all getenv() calls that
+ are not strictly necessary earlier to the "run from RAM" part of
+ the code. This gives a measurable acceleration of boot time on
+ systems where getenv_r() is slow (like systems storing the
+ environment in slow EEPROM devices).
+
+* Fix soft-i2c driver (according to the I2C protocol, a device has
+ one I2C clock cycle to respond with ACK. If the device is "slow" or
+ for some other reason it fails to assert ACK within one I2C cycle,
+ it basically means NOT-ACK. The driver waited only half of the time
+ it was supposed to wait (less than one clock).
+
+* Patch by Kenneth Johansson, 20 Sep 2002:
+ Implement chpart and fix the other commands for jffs according to
+ doc/command
+
* Fix environment problems on SMDK2400 and TRAB boards;
Make environment layout backward compatible when no redundancy is
used
/* status codes */
#define KEYBD_STATUS_MASK 0x3F
+#define KEYBD_STATUS_H_RESET 0x20
+#define KEYBD_STATUS_BROWNOUT 0x10
+#define KEYBD_STATUS_WD_RESET 0x08
+#define KEYBD_STATUS_OVERLOAD 0x04
+#define KEYBD_STATUS_ILLEGAL_WR 0x02
+#define KEYBD_STATUS_ILLEGAL_RD 0x01
/* Number of bytes returned from Keyboard Controller */
#define KEYBD_VERSIONLEN 2 /* version information */
int misc_init_r (void)
{
uchar kbd_data[KEYBD_DATALEN];
+ uchar tmp_data[KEYBD_DATALEN];
uchar keybd_env[2 * KEYBD_DATALEN + 1];
uchar val, errcd;
uchar *str;
val = KEYBD_CMD_READ_STATUS;
i2c_write (kbd_addr, 0, 0, &val, 1);
i2c_read (kbd_addr, 0, 0, &errcd, 1);
- errcd &= KEYBD_STATUS_MASK; /* clear unused bits */
+ /* clear unused bits */
+ errcd &= KEYBD_STATUS_MASK;
+ /* clear "irrelevant" bits. Recommended by Martin Rajek, LWN */
+ errcd &= ~(KEYBD_STATUS_H_RESET|KEYBD_STATUS_BROWNOUT);
if (errcd) {
printf ("KEYBD: Error %02X\n", errcd);
}
/* Reset error code and verify */
val = KEYBD_CMD_RESET_ERRORS;
i2c_write (kbd_addr, 0, 0, &val, 1);
- udelay(1000);
+ udelay(1000); /* delay NEEDED by keyboard PIC !!! */
+
val = KEYBD_CMD_READ_STATUS;
i2c_write (kbd_addr, 0, 0, &val, 1);
i2c_read (kbd_addr, 0, 0, &val, 1);
i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_VERSIONLEN);
printf ("KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]);
- /* Read keys */
- val = KEYBD_CMD_READ_KEYS;
- i2c_write (kbd_addr, 0, 0, &val, 1);
- i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+ /*
+ * Read current keyboard state.
+ *
+ * After the error reset it may take some time before the
+ * keyboard PIC picks up a valid keyboard scan - the total
+ * scan time is approx. 1.6 ms (information by Martin Rajek,
+ * 28 Sep 2002). We read a couple of times for the keyboard
+ * to stabilize, using a big enough delay.
+ * 10 times should be enough. If the data is still changing,
+ * we use what we get :-(
+ */
+
+ memset (tmp_data, 0xFF, KEYBD_DATALEN); /* impossible value */
+ for (i=0; i<10; ++i) {
+ val = KEYBD_CMD_READ_KEYS;
+ i2c_write (kbd_addr, 0, 0, &val, 1);
+ i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+ if (memcmp(kbd_data, tmp_data, KEYBD_DATALEN) == 0) {
+ /* consistent state, done */
+ break;
+ }
+ /* remeber last state, delay, and retry */
+ memcpy (tmp_data, kbd_data, KEYBD_DATALEN);
+ udelay (5);
+ }
for (i = 0; i < KEYBD_DATALEN; ++i) {
sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
switch (info->flash_id & FLASH_TYPEMASK) {
case (AMD_ID_LV320B & FLASH_TYPEMASK):
- printf ("2x Am29F320BB (32Mbit)\n");
+ printf ("2x Am29LV320DB (32Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
#include <jffs2/jffs2.h>
+static int part_num=0;
#ifndef CFG_JFFS_CUSTOM_PART
{
extern flash_info_t flash_info[]; /* info for FLASH chips */
int i;
+
+ if(part_num==0){
- if(part.usr_priv==(void*)1)
- return ∂
+ if(part.usr_priv==(void*)1)
+ return ∂
- memset(&part, 0, sizeof(part));
+ memset(&part, 0, sizeof(part));
#if defined(CFG_JFFS2_FIRST_SECTOR)
- part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
+ part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
#else
- part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+ part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
#endif
- /* Figure out flash partition size */
- for (i = CFG_JFFS2_FIRST_BANK; i < CFG_JFFS2_NUM_BANKS+CFG_JFFS2_FIRST_BANK; i++)
- part.size += flash_info[i].size;
+ /* Figure out flash partition size */
+ for (i = CFG_JFFS2_FIRST_BANK; i < CFG_JFFS2_NUM_BANKS+CFG_JFFS2_FIRST_BANK; i++)
+ part.size += flash_info[i].size;
#if defined(CFG_JFFS2_FIRST_SECTOR) && (CFG_JFFS2_FIRST_SECTOR > 0)
- part.size -=
- flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] -
- flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+ part.size -=
+ flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] -
+ flash_info[CFG_JFFS2_FIRST_BANK].start[0];
#endif
- /* unused in current jffs2 loader */
- part.erasesize = 0;
+ /* unused in current jffs2 loader */
+ part.erasesize = 0;
- /* Mark the struct as ready */
- part.usr_priv=(void*)1;
+ /* Mark the struct as ready */
+ part.usr_priv=(void*)1;
- return ∂
+ return ∂
+ }
+ return 0;
}
#endif /* ifndef CFG_JFFS_CUSTOM_PART */
-
int
do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *filename = "vmlinuz";
ulong offset = CFG_LOAD_ADDR;
int size;
+ struct part_info *part;
if (argc >= 2) {
offset = simple_strtoul(argv[1], NULL, 16);
if (argc == 3) {
filename = argv[2];
}
+
+ if (0 != (part=jffs2_part_info(part_num))){
- printf("### JFFS2 loading '%s' to 0x%lx\n", filename, offset);
- size = jffs2_1pass_load((char *)offset, jffs2_part_info(0), filename);
+ printf("### JFFS2 loading '%s' to 0x%lx\n", filename, offset);
+ size = jffs2_1pass_load((char *)offset, part, filename);
- if (size > 0) {
- printf("### JFFS2 load compleate: %d bytes loaded to 0x%lx\n",
- size, offset);
- } else {
- printf("### JFFS2 LOAD ERROR<%x> for %s!\n", size, filename);
+ if (size > 0) {
+ printf("### JFFS2 load compleate: %d bytes loaded to 0x%lx\n",
+ size, offset);
+ } else {
+ printf("### JFFS2 LOAD ERROR<%x> for %s!\n", size, filename);
+ }
+
+ return !(size > 0);
}
- return !(size > 0);
+ printf("Active partition not valid\n");
+ return 0;
}
int
-do_jffs2_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *filename = "/";
int ret;
+ struct part_info *part;
if (argc == 2)
- filename = argv[1];
+ filename = argv[1];
+
+ if (0 != (part=jffs2_part_info(part_num))){
- ret = jffs2_1pass_ls(jffs2_part_info(0), filename);
+ ret = jffs2_1pass_ls(jffs2_part_info(part_num), filename);
- return (ret == 1);
+ return (ret == 1);
+ }
+ printf("Active partition not valid\n");
+ return 0;
}
int
do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret;
+ struct part_info *part;
- ret = jffs2_1pass_info(jffs2_part_info(0));
+ if (0 != (part=jffs2_part_info(part_num))){
- return (ret == 1);
+ ret = jffs2_1pass_info(jffs2_part_info(part_num));
+
+ return (ret == 1);
+ }
+ printf("Active partition not valid\n");
+ return 0;
}
+int
+do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int tmp_part;
+
+ if (argc >= 2) {
+ tmp_part = simple_strtoul(argv[1], NULL, 16);
+ }else{
+ printf("Need partition number in argument list\n");
+ return 0;
+
+ }
+
+ if (jffs2_part_info(tmp_part)){
+ printf("Partiton changed to %d\n",tmp_part);
+ part_num=tmp_part;
+ return 0;
+ }
+
+ printf("Partition %d is not valid partiton\n",tmp_part);
+ return 0;
+
+}
#endif /* CFG_CMD_JFFS2 */
CMD_TBL_BREAK
CMD_TBL_BRGINFO
CMD_TBL_CARINFO
+ CMD_TBL_JFFS2_CHPART
CMD_TBL_CMP
CMD_TBL_CONINFO
CMD_TBL_CONTINUE
CMD_TBL_FDC
CMD_TBL_FLINFO
CMD_TBL_FPGA
+ CMD_TBL_JFFS2_FSINFO
+ CMD_TBL_JFFS2_FSLOAD
CMD_TBL_GETDCR
CMD_TBL_GO
CMD_TBL_HELP
CMD_TBL_IOPINFO
CMD_TBL_IOPSET
CMD_TBL_IRQINFO
- CMD_TBL_JFFS2
CMD_TBL_KGDB
CMD_TBL_LOADB
CMD_TBL_LOADS
CMD_TBL_LOOP
+ CMD_TBL_JFFS2_LS
CMD_TBL_MCCINFO
CMD_TBL_MD
CMD_TBL_MEMCINFO
*/
I2C_SCL(0);
I2C_DELAY;
+ I2C_SDA(1);
I2C_TRISTATE;
I2C_DELAY;
I2C_SCL(1);
I2C_DELAY;
+ I2C_DELAY;
nack = I2C_READ;
- I2C_SDA(0);
- I2C_ACTIVE;
+ I2C_SCL(0);
I2C_DELAY;
+ I2C_ACTIVE;
return(nack); /* not a nack is an ack */
}
volatile memctl8260_t *memctl = &immr->im_memctl;
extern void m8260_cpm_reset (void);
+ /* Pointer is writable since we allocated a register for it */
+ gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+ /* Clear initial global data */
+ memset ((void *) gd, 0, sizeof (gd_t));
+
/* RSR - Reset Status Register - clear all status (5-4) */
gd->reset_status = immr->im_clkrst.car_rsr;
immr->im_clkrst.car_rsr = RSR_ALLBITS;
break 2
brginfo 3
carinfo 3
+chpart 6
cmp 3
coninfo 5
continue 4
fdcboot 4
flinfo 3
fpga 4
+fsinfo 5
+fsload 5
getdcr 6 # IBM 4XX DCR registers
go 2
help 1
loadb 5
loads 5
loop 4
+ls 2
mccinfo 3
md 2
memcinfo 4
#define _CMD_JFFS2_H
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
-#define CMD_TBL_JFFS2 MK_CMD_TBL_ENTRY( \
+
+#define CMD_TBL_JFFS2_FSLOAD MK_CMD_TBL_ENTRY( \
"fsload", 5, 3, 0, do_jffs2_fsload, \
- "fsload - load binary file from a filesystem image\n", \
+ "fsload - load binary file from a filesystem image\n", \
"[ off ] [ filename ]\n" \
" - load binary file from flash bank\n" \
" with offset 'off'\n" \
-), \
- MK_CMD_TBL_ENTRY( \
+),
+
+#define CMD_TBL_JFFS2_FSINFO MK_CMD_TBL_ENTRY( \
"fsinfo", 5, 1, 1, do_jffs2_fsinfo, \
"fsinfo - print information about filesystems\n", \
- "\n" \
" - print information about filesystems\n" \
-), \
- MK_CMD_TBL_ENTRY( \
+),
+
+#define CMD_TBL_JFFS2_LS MK_CMD_TBL_ENTRY( \
"ls", 2, 2, 1, do_jffs2_ls, \
"ls - list files in a directory (default /)\n", \
"[ directory ]\n" \
" - list files in a directory.\n" \
),
+#define CMD_TBL_JFFS2_CHPART MK_CMD_TBL_ENTRY( \
+ "chpart", 6, 2, 0, do_jffs2_chpart, \
+ "chpart - change active partition\n", \
+ " - change active partition\n" \
+),
+
int do_jffs2_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
int do_jffs2_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
int do_jffs2_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-
+int do_jffs2_chpart (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#else
-#define CMD_TBL_JFFS2
+#define CMD_TBL_JFFS2_FSLOAD
+#define CMD_TBL_JFFS2_FSINFO
+#define CMD_TBL_JFFS2_LS
+#define CMD_TBL_JFFS2_CHPART
#endif /* CFG_CMD_JFFS2 */
#endif /* _CMD_JFFS2_H */
* (easy to change)
*/
#define CONFIG_ARM920T 1 /* This is an ARM920T core */
-#define CONFIG_S3C2400 1 /* in a SAMSUNG S3C2400 SoC */
+#define CONFIG_S3C2400 1 /* in a SAMSUNG S3C2400 SoC */
#define CONFIG_SMDK2400 1 /* on an SAMSUNG SMDK2400 Board */
-#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG 1
+
/*
* Size of malloc() pool
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG 1
+
/*
* Size of malloc() pool
*/
DECLARE_GLOBAL_DATA_PTR;
bd_t *bd;
- ulong reg, len, addr, addr_sp;
- int i;
+ ulong len, addr, addr_sp;
gd_t *id;
- char *s, *e;
- uchar tmp[64]; /* long enough for environment variables */
init_fnc_t **init_fnc_ptr;
/* Pointer is writable since we allocated a register for it */
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+#ifndef CONFIG_8260
/* Clear initial global data */
memset ((void *) gd, 0, sizeof (gd_t));
+#endif
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr) () != 0) {
bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */
WATCHDOG_RESET ();
-
- i = getenv_r ("ethaddr", tmp, sizeof (tmp));
- s = (i > 0) ? tmp : NULL;
-
-#if defined (CONFIG_MBX) || defined (CONFIG_RPXCLASSIC) || defined(CONFIG_IAD210)
- if (s == NULL)
- board_get_enetaddr (bd->bi_enetaddr);
- else
-#endif
- for (reg = 0; reg < 6; ++reg) {
- bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
- if (s)
- s = (*e) ? e + 1 : e;
- }
-#ifdef CONFIG_HERMES
- if ((gd->board_type >> 16) == 2)
- bd->bi_ethspeed = gd->board_type & 0xFFFF;
- else
- bd->bi_ethspeed = 0xFFFF;
-#endif
-
-#ifdef CONFIG_NX823
- load_sernum_ethaddr ();
-#endif
-
-#if defined(CFG_GT_6426x) || defined(CONFIG_PN62)
- /* handle the 2nd ethernet address */
-
- i = getenv_r ("eth1addr", tmp, sizeof (tmp));
- s = (i > 0) ? tmp : NULL;
-
- for (reg = 0; reg < 6; ++reg) {
- bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
- if (s)
- s = (*e) ? e + 1 : e;
- }
-#endif
-#if defined(CFG_GT_6426x)
- /* handle the 3rd ethernet address */
-
- i = getenv_r ("eth2addr", tmp, sizeof (tmp));
- s = (i > 0) ? tmp : NULL;
-
- for (reg = 0; reg < 6; ++reg) {
- bd->bi_enet2addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
- if (s)
- s = (*e) ? e + 1 : e;
- }
-#endif
-
bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */
bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */
#if defined(CONFIG_8260)
DECLARE_GLOBAL_DATA_PTR;
cmd_tbl_t *cmdtp;
- char *s;
+ char *s, *e;
bd_t *bd;
+ int i;
extern void malloc_bin_reloc (void);
#ifndef CFG_NO_FLASH
gd->reloc_off = dest_addr - CFG_MONITOR_BASE;
+ /*
+ * Fill in missing fields of bd_info.
+ * We do this here, where we have "normal" access to the
+ * environment; we used to do this still running from ROM,
+ * where had to use getenv_r(), which can be pretty slow when
+ * the environment is in EEPROM.
+ */
+ s = getenv ("ethaddr");
+#if defined (CONFIG_MBX) || defined (CONFIG_RPXCLASSIC) || defined(CONFIG_IAD210)
+ if (s == NULL)
+ board_get_enetaddr (bd->bi_enetaddr);
+ else
+#endif
+ for (i = 0; i < 6; ++i) {
+ bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+#ifdef CONFIG_HERMES
+ if ((gd->board_type >> 16) == 2)
+ bd->bi_ethspeed = gd->board_type & 0xFFFF;
+ else
+ bd->bi_ethspeed = 0xFFFF;
+#endif
+
+#ifdef CONFIG_NX823
+ load_sernum_ethaddr ();
+#endif
+
+#if defined(CFG_GT_6426x) || defined(CONFIG_PN62)
+ /* handle the 2nd ethernet address */
+
+ s = getenv ("eth1addr");
+
+ for (reg = 0; reg < 6; ++reg) {
+ bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+#endif
+#if defined(CFG_GT_6426x)
+ /* handle the 3rd ethernet address */
+
+ s = getenv ("eth2addr");
+
+ for (reg = 0; reg < 6; ++reg) {
+ bd->bi_enet2addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+#endif
+
/*
* We have to relocate the command table manually
*/