summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorScott Sweeny <scott.sweeny@timesys.com>2009-04-29 11:19:44 -0400
committerScott Sweeny <scott.sweeny@timesys.com>2009-04-29 11:19:44 -0400
commit1f6422345c3594647eb16e33194be62906dbdc22 (patch)
treea1b5a9cb51216df1b6ccdd434bfef6788627ed28 /common
parente6b6d16de73de6a76e2ec4338291e828b860f040 (diff)
Add support for OMAP3430 Labrador
This patch originally from LogicPD OMAP35x Release 1.5.0 Original Patch Name: u-boot-1.1.4-omap3430-labrador.patch
Diffstat (limited to 'common')
-rw-r--r--common/Makefile5
-rw-r--r--common/cmd_bdinfo.c16
-rw-r--r--common/cmd_bedbug.c575
-rw-r--r--common/cmd_boot.c8
-rw-r--r--common/cmd_bootm.c88
-rw-r--r--common/cmd_date.c3
-rw-r--r--common/cmd_doc.c31
-rw-r--r--common/cmd_elf.c8
-rw-r--r--common/cmd_fdc.c4
-rw-r--r--common/cmd_flash.c20
-rw-r--r--common/cmd_i2c.c28
-rw-r--r--common/cmd_ide.c12
-rw-r--r--common/cmd_immap.c6
-rw-r--r--common/cmd_jffs2.c35
-rw-r--r--common/cmd_load.c115
-rw-r--r--common/cmd_log.c5
-rw-r--r--common/cmd_mem.c2
-rw-r--r--common/cmd_mii.c5
-rw-r--r--common/cmd_nand.c1987
-rw-r--r--common/cmd_nvedit.c12
-rw-r--r--common/cmd_onenand.c194
-rw-r--r--common/cmd_pcmcia.c3211
-rw-r--r--common/cmd_reginfo.c2
-rw-r--r--common/cmd_usb.c7
-rw-r--r--common/command.c4
-rw-r--r--common/console.c18
-rw-r--r--common/crc16.c107
-rw-r--r--common/devices.c4
-rw-r--r--common/dlmalloc.c4
-rw-r--r--common/env_common.c12
-rw-r--r--common/env_dataflash.c4
-rw-r--r--common/env_eeprom.c4
-rw-r--r--common/env_flash.c81
-rw-r--r--common/env_nand.c199
-rw-r--r--common/env_nowhere.c6
-rw-r--r--common/env_nvram.c6
-rw-r--r--common/env_onenand.c156
-rw-r--r--common/environment.c3
-rw-r--r--common/exports.c3
-rw-r--r--common/flash.c2
-rw-r--r--common/ft_build.c49
-rw-r--r--common/hush.c3
-rw-r--r--common/lcd.c7
-rw-r--r--common/lynxkdi.c11
-rw-r--r--common/main.c499
-rw-r--r--common/serial.c26
-rw-r--r--common/soft_i2c.c18
-rw-r--r--common/usb.c91
-rw-r--r--common/usb_storage.c4
-rw-r--r--common/xyzModem.c746
50 files changed, 3138 insertions, 5308 deletions
diff --git a/common/Makefile b/common/Makefile
index 7dbf84a555e..e588c73119e 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -38,20 +38,21 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \
cmd_load.o cmd_log.o \
cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
cmd_nand.o cmd_net.o cmd_nvedit.o \
+ cmd_onenand.o \
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
cmd_usb.o cmd_vfd.o \
command.o console.o devices.o dlmalloc.o docecc.o \
environment.o env_common.o \
env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
- env_nvram.o env_nowhere.o \
+ env_nvram.o env_nowhere.o env_onenand.o \
exports.o \
flash.o fpga.o ft_build.o \
hush.o kgdb.o lcd.o lists.o lynxkdi.o \
memsize.o miiphybb.o miiphyutil.o \
s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
usb.o usb_kbd.o usb_storage.o \
- virtex2.o xilinx.o
+ virtex2.o xilinx.o crc16.o xyzModem.o
OBJS = $(AOBJS) $(COBJS)
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index 40e28dd9d23..256e4bc7968 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -28,6 +28,7 @@
#include <command.h>
#include <net.h> /* for print_IPaddr */
+DECLARE_GLOBAL_DATA_PTR;
#if (CONFIG_COMMANDS & CFG_CMD_BDI)
static void print_num(const char *, ulong);
@@ -39,8 +40,6 @@ static void print_str(const char *, const char *);
int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
int i;
bd_t *bd = gd->bd;
char buf[32];
@@ -62,11 +61,12 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
print_num ("bootflags", bd->bi_bootflags );
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300) || \
- defined(CONFIG_440EP) || defined(CONFIG_440GR)
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440SP)
print_str ("procfreq", strmhz(buf, bd->bi_procfreq));
print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq));
#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300) || \
- defined(CONFIG_440EP) || defined(CONFIG_440GR)
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq));
#endif
#else /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300, CONFIG_440EP CONFIG_440GR */
@@ -127,8 +127,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
int i;
bd_t *bd = gd->bd;
@@ -153,8 +151,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
int i;
bd_t *bd = gd->bd;
@@ -187,8 +183,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
int i;
bd_t *bd = gd->bd;
@@ -215,8 +209,6 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
int i;
bd_t *bd = gd->bd;
diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c
index cdb379de216..48086a62809 100644
--- a/common/cmd_bedbug.c
+++ b/common/cmd_bedbug.c
@@ -11,187 +11,183 @@
#include <bedbug/regs.h>
#include <bedbug/ppc.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
-extern void show_regs __P((struct pt_regs*));
-extern int run_command __P((const char*, int));
+extern void show_regs __P ((struct pt_regs *));
+extern int run_command __P ((const char *, int));
extern char console_buffer[];
-ulong dis_last_addr = 0; /* Last address disassembled */
-ulong dis_last_len = 20; /* Default disassembler length */
-CPU_DEBUG_CTX bug_ctx; /* Bedbug context structure */
-
+ulong dis_last_addr = 0; /* Last address disassembled */
+ulong dis_last_len = 20; /* Default disassembler length */
+CPU_DEBUG_CTX bug_ctx; /* Bedbug context structure */
+
/* ======================================================================
* U-Boot's puts function does not append a newline, so the bedbug stuff
* will use this for the output of the dis/assembler.
* ====================================================================== */
-int bedbug_puts(const char *str)
+int bedbug_puts (const char *str)
{
- /* -------------------------------------------------- */
+ /* -------------------------------------------------- */
- printf( "%s\r\n", str );
- return 0;
-} /* bedbug_puts */
+ printf ("%s\r\n", str);
+ return 0;
+} /* bedbug_puts */
+
-
/* ======================================================================
* Initialize the bug_ctx structure used by the bedbug debugger. This is
* specific to the CPU since each has different debug registers and
* settings.
* ====================================================================== */
-void bedbug_init( void )
+void bedbug_init (void)
{
- /* -------------------------------------------------- */
+ /* -------------------------------------------------- */
#if defined(CONFIG_4xx)
- void bedbug405_init( void );
- bedbug405_init();
+ void bedbug405_init (void);
+
+ bedbug405_init ();
#elif defined(CONFIG_8xx)
- void bedbug860_init( void );
- bedbug860_init();
+ void bedbug860_init (void);
+
+ bedbug860_init ();
#endif
#if defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)
- /* Processors that are 603e core based */
- void bedbug603e_init( void );
+ /* Processors that are 603e core based */
+ void bedbug603e_init (void);
- bedbug603e_init();
+ bedbug603e_init ();
#endif
- return;
-} /* bedbug_init */
+ return;
+} /* bedbug_init */
+
-
/* ======================================================================
* Entry point from the interpreter to the disassembler. Repeated calls
* will resume from the last disassembled address.
* ====================================================================== */
-int do_bedbug_dis (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_dis (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- ulong addr; /* Address to start disassembly from */
- ulong len; /* # of instructions to disassemble */
- /* -------------------------------------------------- */
-
- /* Setup to go from the last address if none is given */
- addr = dis_last_addr;
- len = dis_last_len;
-
- if (argc < 2)
- {
- printf ("Usage:\n%s\n", cmdtp->usage);
- return 1;
- }
-
- if(( flag & CMD_FLAG_REPEAT ) == 0 )
- {
- /* New command */
- addr = simple_strtoul( argv[1], NULL, 16 );
-
- /* If an extra param is given then it is the length */
- if( argc > 2 )
- len = simple_strtoul( argv[2], NULL, 16 );
- }
-
- /* Run the disassembler */
- disppc( (unsigned char *)addr, 0, len, bedbug_puts, F_RADHEX );
-
- dis_last_addr = addr + (len * 4);
- dis_last_len = len;
- return 0;
-} /* do_bedbug_dis */
-U_BOOT_CMD(
- ds, 3, 1, do_bedbug_dis,
- "ds - disassemble memory\n",
- "ds <address> [# instructions]\n"
-);
+ ulong addr; /* Address to start disassembly from */
+ ulong len; /* # of instructions to disassemble */
+
+ /* -------------------------------------------------- */
+
+ /* Setup to go from the last address if none is given */
+ addr = dis_last_addr;
+ len = dis_last_len;
+
+ if (argc < 2) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ if ((flag & CMD_FLAG_REPEAT) == 0) {
+ /* New command */
+ addr = simple_strtoul (argv[1], NULL, 16);
+
+ /* If an extra param is given then it is the length */
+ if (argc > 2)
+ len = simple_strtoul (argv[2], NULL, 16);
+ }
+
+ /* Run the disassembler */
+ disppc ((unsigned char *) addr, 0, len, bedbug_puts, F_RADHEX);
+
+ dis_last_addr = addr + (len * 4);
+ dis_last_len = len;
+ return 0;
+} /* do_bedbug_dis */
+
+U_BOOT_CMD (ds, 3, 1, do_bedbug_dis,
+ "ds - disassemble memory\n",
+ "ds <address> [# instructions]\n");
/* ======================================================================
* Entry point from the interpreter to the assembler. Assembles
* instructions in consecutive memory locations until a '.' (period) is
* entered on a line by itself.
* ====================================================================== */
-int do_bedbug_asm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_asm (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- long mem_addr; /* Address to assemble into */
- unsigned long instr; /* Machine code for text */
- char prompt[ 15 ]; /* Prompt string for user input */
- int asm_err; /* Error code from the assembler*/
- /* -------------------------------------------------- */
- int rcode = 0;
-
- if (argc < 2)
- {
- printf ("Usage:\n%s\n", cmdtp->usage);
- return 1;
- }
-
- printf( "\nEnter '.' when done\n" );
- mem_addr = simple_strtoul( argv[ 1 ], NULL, 16 );
-
- while( 1 )
- {
- putc( '\n' );
- disppc( (unsigned char *)mem_addr, 0, 1, bedbug_puts, F_RADHEX );
-
- sprintf( prompt, "%08lx: ", mem_addr );
- readline( prompt );
-
- if( console_buffer[ 0 ] && strcmp( console_buffer, "." ))
- {
- if(( instr = asmppc( mem_addr, console_buffer, &asm_err )) != 0 )
- {
- *(unsigned long *)mem_addr = instr;
- mem_addr += 4;
- }
- else
- {
- printf( "*** Error: %s ***\n", asm_error_str( asm_err ));
- rcode = 1;
- }
- }
- else
- {
- break;
- }
- }
- return rcode;
-} /* do_bedbug_asm */
-U_BOOT_CMD(
- as, 2, 0, do_bedbug_asm,
- "as - assemble memory\n",
- "as <address>\n"
-);
+ long mem_addr; /* Address to assemble into */
+ unsigned long instr; /* Machine code for text */
+ char prompt[15]; /* Prompt string for user input */
+ int asm_err; /* Error code from the assembler */
+
+ /* -------------------------------------------------- */
+ int rcode = 0;
+
+ if (argc < 2) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ printf ("\nEnter '.' when done\n");
+ mem_addr = simple_strtoul (argv[1], NULL, 16);
+
+ while (1) {
+ putc ('\n');
+ disppc ((unsigned char *) mem_addr, 0, 1, bedbug_puts,
+ F_RADHEX);
+
+ sprintf (prompt, "%08lx: ", mem_addr);
+ readline (prompt);
+
+ if (console_buffer[0] && strcmp (console_buffer, ".")) {
+ if ((instr =
+ asmppc (mem_addr, console_buffer,
+ &asm_err)) != 0) {
+ *(unsigned long *) mem_addr = instr;
+ mem_addr += 4;
+ } else {
+ printf ("*** Error: %s ***\n",
+ asm_error_str (asm_err));
+ rcode = 1;
+ }
+ } else {
+ break;
+ }
+ }
+ return rcode;
+} /* do_bedbug_asm */
+
+U_BOOT_CMD (as, 2, 0, do_bedbug_asm,
+ "as - assemble memory\n", "as <address>\n");
/* ======================================================================
* Used to set a break point from the interpreter. Simply calls into the
* CPU-specific break point set routine.
* ====================================================================== */
-int do_bedbug_break (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_break (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- /* -------------------------------------------------- */
- if( bug_ctx.do_break )
- (*bug_ctx.do_break)( cmdtp, flag, argc, argv );
- return 0;
-
-} /* do_bedbug_break */
-U_BOOT_CMD(
- break, 3, 0, do_bedbug_break,
- "break - set or clear a breakpoint\n",
- " - Set or clear a breakpoint\n"
- "break <address> - Break at an address\n"
- "break off <bp#> - Disable breakpoint.\n"
- "break show - List breakpoints.\n"
-);
+ /* -------------------------------------------------- */
+ if (bug_ctx.do_break)
+ (*bug_ctx.do_break) (cmdtp, flag, argc, argv);
+ return 0;
+
+} /* do_bedbug_break */
+
+U_BOOT_CMD (break, 3, 0, do_bedbug_break,
+ "break - set or clear a breakpoint\n",
+ " - Set or clear a breakpoint\n"
+ "break <address> - Break at an address\n"
+ "break off <bp#> - Disable breakpoint.\n"
+ "break show - List breakpoints.\n");
/* ======================================================================
* Called from the debug interrupt routine. Simply calls the CPU-specific
@@ -200,16 +196,16 @@ U_BOOT_CMD(
void do_bedbug_breakpoint (struct pt_regs *regs)
{
- /* -------------------------------------------------- */
+ /* -------------------------------------------------- */
- if( bug_ctx.break_isr )
- (*bug_ctx.break_isr)( regs );
+ if (bug_ctx.break_isr)
+ (*bug_ctx.break_isr) (regs);
- return;
-} /* do_bedbug_breakpoint */
+ return;
+} /* do_bedbug_breakpoint */
+
-
/* ======================================================================
* Called from the CPU-specific breakpoint handling routine. Enter a
* mini main loop until the stopped flag is cleared from the breakpoint
@@ -218,81 +214,77 @@ void do_bedbug_breakpoint (struct pt_regs *regs)
* This handles the parts of the debugger that are common to all CPU's.
* ====================================================================== */
-void bedbug_main_loop( unsigned long addr, struct pt_regs *regs )
+void bedbug_main_loop (unsigned long addr, struct pt_regs *regs)
{
- int len; /* Length of command line */
- int flag; /* Command flags */
- int rc = 0; /* Result from run_command*/
- char prompt_str[ 20 ]; /* Prompt string */
- static char lastcommand[ CFG_CBSIZE ] = {0}; /* previous command */
- /* -------------------------------------------------- */
+ int len; /* Length of command line */
+ int flag; /* Command flags */
+ int rc = 0; /* Result from run_command */
+ char prompt_str[20]; /* Prompt string */
+ static char lastcommand[CFG_CBSIZE] = { 0 }; /* previous command */
+ /* -------------------------------------------------- */
- if( bug_ctx.clear )
- (*bug_ctx.clear)( bug_ctx.current_bp );
+ if (bug_ctx.clear)
+ (*bug_ctx.clear) (bug_ctx.current_bp);
- printf( "Breakpoint %d: ", bug_ctx.current_bp );
- disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX );
+ printf ("Breakpoint %d: ", bug_ctx.current_bp);
+ disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX);
- bug_ctx.stopped = 1;
- bug_ctx.regs = regs;
+ bug_ctx.stopped = 1;
+ bug_ctx.regs = regs;
- sprintf( prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp );
+ sprintf (prompt_str, "BEDBUG.%d =>", bug_ctx.current_bp);
- /* A miniature main loop */
- while( bug_ctx.stopped )
- {
- len = readline( prompt_str );
+ /* A miniature main loop */
+ while (bug_ctx.stopped) {
+ len = readline (prompt_str);
- flag = 0; /* assume no special flags for now */
+ flag = 0; /* assume no special flags for now */
- if (len > 0)
- strcpy( lastcommand, console_buffer );
- else if( len == 0 )
- flag |= CMD_FLAG_REPEAT;
+ if (len > 0)
+ strcpy (lastcommand, console_buffer);
+ else if (len == 0)
+ flag |= CMD_FLAG_REPEAT;
- if (len == -1)
- printf ("<INTERRUPT>\n");
- else
- rc = run_command( lastcommand, flag );
+ if (len == -1)
+ printf ("<INTERRUPT>\n");
+ else
+ rc = run_command (lastcommand, flag);
- if (rc <= 0) {
- /* invalid command or not repeatable, forget it */
- lastcommand[0] = 0;
- }
- }
+ if (rc <= 0) {
+ /* invalid command or not repeatable, forget it */
+ lastcommand[0] = 0;
+ }
+ }
- bug_ctx.regs = NULL;
- bug_ctx.current_bp = 0;
+ bug_ctx.regs = NULL;
+ bug_ctx.current_bp = 0;
- return;
-} /* bedbug_main_loop */
+ return;
+} /* bedbug_main_loop */
+
-
/* ======================================================================
* Interpreter command to continue from a breakpoint. Just clears the
* stopped flag in the context so that the breakpoint routine will
* return.
* ====================================================================== */
-int do_bedbug_continue (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-
+int do_bedbug_continue (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- /* -------------------------------------------------- */
-
- if( ! bug_ctx.stopped )
- {
- printf( "Not at a breakpoint\n" );
- return 1;
- }
-
- bug_ctx.stopped = 0;
- return 0;
-} /* do_bedbug_continue */
-U_BOOT_CMD(
- continue, 1, 0, do_bedbug_continue,
- "continue- continue from a breakpoint\n",
- " - continue from a breakpoint.\n"
-);
+ /* -------------------------------------------------- */
+
+ if (!bug_ctx.stopped) {
+ printf ("Not at a breakpoint\n");
+ return 1;
+ }
+
+ bug_ctx.stopped = 0;
+ return 0;
+} /* do_bedbug_continue */
+
+U_BOOT_CMD (continue, 1, 0, do_bedbug_continue,
+ "continue- continue from a breakpoint\n",
+ " - continue from a breakpoint.\n");
/* ======================================================================
* Interpreter command to continue to the next instruction, stepping into
@@ -300,31 +292,30 @@ U_BOOT_CMD(
* the address passes control to the CPU-specific set breakpoint routine
* for the current breakpoint number.
* ====================================================================== */
-int do_bedbug_step (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- unsigned long addr; /* Address to stop at */
- /* -------------------------------------------------- */
-
- if( ! bug_ctx.stopped )
- {
- printf( "Not at a breakpoint\n" );
- return 1;
- }
-
- if( !find_next_address( (unsigned char *)&addr, FALSE, bug_ctx.regs ))
- return 1;
-
- if( bug_ctx.set )
- (*bug_ctx.set)( bug_ctx.current_bp, addr );
-
- bug_ctx.stopped = 0;
- return 0;
-} /* do_bedbug_step */
-U_BOOT_CMD(
- step, 1, 1, do_bedbug_step,
- "step - single step execution.\n",
- " - single step execution.\n"
-);
+ unsigned long addr; /* Address to stop at */
+
+ /* -------------------------------------------------- */
+
+ if (!bug_ctx.stopped) {
+ printf ("Not at a breakpoint\n");
+ return 1;
+ }
+
+ if (!find_next_address ((unsigned char *) &addr, FALSE, bug_ctx.regs))
+ return 1;
+
+ if (bug_ctx.set)
+ (*bug_ctx.set) (bug_ctx.current_bp, addr);
+
+ bug_ctx.stopped = 0;
+ return 0;
+} /* do_bedbug_step */
+
+U_BOOT_CMD (step, 1, 1, do_bedbug_step,
+ "step - single step execution.\n",
+ " - single step execution.\n");
/* ======================================================================
* Interpreter command to continue to the next instruction, stepping over
@@ -332,105 +323,97 @@ U_BOOT_CMD(
* the address passes control to the CPU-specific set breakpoint routine
* for the current breakpoint number.
* ====================================================================== */
-int do_bedbug_next (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- unsigned long addr; /* Address to stop at */
- /* -------------------------------------------------- */
-
- if( ! bug_ctx.stopped )
- {
- printf( "Not at a breakpoint\n" );
- return 1;
- }
-
- if( !find_next_address( (unsigned char *)&addr, TRUE, bug_ctx.regs ))
- return 1;
-
- if( bug_ctx.set )
- (*bug_ctx.set)( bug_ctx.current_bp, addr );
-
- bug_ctx.stopped = 0;
- return 0;
-} /* do_bedbug_next */
-U_BOOT_CMD(
- next, 1, 1, do_bedbug_next,
- "next - single step execution, stepping over subroutines.\n",
- " - single step execution, stepping over subroutines.\n"
-);
+ unsigned long addr; /* Address to stop at */
+
+ /* -------------------------------------------------- */
+
+ if (!bug_ctx.stopped) {
+ printf ("Not at a breakpoint\n");
+ return 1;
+ }
+
+ if (!find_next_address ((unsigned char *) &addr, TRUE, bug_ctx.regs))
+ return 1;
+
+ if (bug_ctx.set)
+ (*bug_ctx.set) (bug_ctx.current_bp, addr);
+
+ bug_ctx.stopped = 0;
+ return 0;
+} /* do_bedbug_next */
+
+U_BOOT_CMD (next, 1, 1, do_bedbug_next,
+ "next - single step execution, stepping over subroutines.\n",
+ " - single step execution, stepping over subroutines.\n");
/* ======================================================================
* Interpreter command to print the current stack. This assumes an EABI
* architecture, so it starts with GPR R1 and works back up the stack.
* ====================================================================== */
-int do_bedbug_stack (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_stack (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
- unsigned long sp; /* Stack pointer */
- unsigned long func; /* LR from stack */
- int depth; /* Stack iteration level */
- int skip = 1; /* Flag to skip the first entry */
- unsigned long top; /* Top of memory address */
- /* -------------------------------------------------- */
-
- if( ! bug_ctx.stopped )
- {
- printf( "Not at a breakpoint\n" );
- return 1;
- }
-
- top = gd->bd->bi_memstart + gd->bd->bi_memsize;
- depth = 0;
-
- printf( "Depth PC\n" );
- printf( "----- --------\n" );
- printf( "%5d %08lx\n", depth++, bug_ctx.regs->nip );
-
- sp = bug_ctx.regs->gpr[ 1 ];
- func = *(unsigned long *)(sp+4);
-
- while(( func < top ) && ( sp < top ))
- {
- if( !skip )
- printf( "%5d %08lx\n", depth++, func );
- else
- --skip;
-
- sp = *(unsigned long *)sp;
- func = *(unsigned long *)(sp+4);
- }
- return 0;
-} /* do_bedbug_stack */
-U_BOOT_CMD(
- where, 1, 1, do_bedbug_stack,
- "where - Print the running stack.\n",
- " - Print the running stack.\n"
-);
+ unsigned long sp; /* Stack pointer */
+ unsigned long func; /* LR from stack */
+ int depth; /* Stack iteration level */
+ int skip = 1; /* Flag to skip the first entry */
+ unsigned long top; /* Top of memory address */
+
+ /* -------------------------------------------------- */
+
+ if (!bug_ctx.stopped) {
+ printf ("Not at a breakpoint\n");
+ return 1;
+ }
+
+ top = gd->bd->bi_memstart + gd->bd->bi_memsize;
+ depth = 0;
+
+ printf ("Depth PC\n");
+ printf ("----- --------\n");
+ printf ("%5d %08lx\n", depth++, bug_ctx.regs->nip);
+
+ sp = bug_ctx.regs->gpr[1];
+ func = *(unsigned long *) (sp + 4);
+
+ while ((func < top) && (sp < top)) {
+ if (!skip)
+ printf ("%5d %08lx\n", depth++, func);
+ else
+ --skip;
+
+ sp = *(unsigned long *) sp;
+ func = *(unsigned long *) (sp + 4);
+ }
+ return 0;
+} /* do_bedbug_stack */
+
+U_BOOT_CMD (where, 1, 1, do_bedbug_stack,
+ "where - Print the running stack.\n",
+ " - Print the running stack.\n");
/* ======================================================================
* Interpreter command to dump the registers. Calls the CPU-specific
* show registers routine.
* ====================================================================== */
-int do_bedbug_rdump (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_bedbug_rdump (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
- /* -------------------------------------------------- */
-
- if( ! bug_ctx.stopped )
- {
- printf( "Not at a breakpoint\n" );
- return 1;
- }
-
- show_regs( bug_ctx.regs );
- return 0;
-} /* do_bedbug_rdump */
-U_BOOT_CMD(
- rdump, 1, 1, do_bedbug_rdump,
- "rdump - Show registers.\n",
- " - Show registers.\n"
-);
+ /* -------------------------------------------------- */
+
+ if (!bug_ctx.stopped) {
+ printf ("Not at a breakpoint\n");
+ return 1;
+ }
+
+ show_regs (bug_ctx.regs);
+ return 0;
+} /* do_bedbug_rdump */
+
+U_BOOT_CMD (rdump, 1, 1, do_bedbug_rdump,
+ "rdump - Show registers.\n", " - Show registers.\n");
/* ====================================================================== */
-#endif /* CFG_CMD_BEDBUG */
+#endif /* CFG_CMD_BEDBUG */
/*
diff --git a/common/cmd_boot.c b/common/cmd_boot.c
index 5b58d4e2f1f..e68f16f9da0 100644
--- a/common/cmd_boot.c
+++ b/common/cmd_boot.c
@@ -28,14 +28,12 @@
#include <command.h>
#include <net.h>
-
-/* -------------------------------------------------------------------- */
+#if defined(CONFIG_I386)
+DECLARE_GLOBAL_DATA_PTR;
+#endif
int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
-#if defined(CONFIG_I386)
- DECLARE_GLOBAL_DATA_PTR;
-#endif
ulong addr, rc;
int rcode = 0;
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 8599a49d057..31eb385d54d 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -34,10 +34,6 @@
#include <environment.h>
#include <asm/byteorder.h>
-#ifdef CONFIG_OF_FLAT_TREE
-#include <ft_build.h>
-#endif
-
/*cmd_boot.c*/
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
@@ -88,7 +84,7 @@ static int image_info (unsigned long addr);
#if (CONFIG_COMMANDS & CFG_CMD_IMLS)
#include <flash.h>
-extern flash_info_t flash_info[]; /* info for FLASH chips */
+extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#endif
@@ -201,31 +197,29 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
- if (crc32 (0, (uchar *)data, len) != checksum) {
+ if (crc32 (0, (unsigned char *)data, len) != checksum) {
puts ("Bad Header Checksum\n");
SHOW_BOOT_PROGRESS (-2);
return 1;
}
SHOW_BOOT_PROGRESS (3);
-#ifdef CONFIG_HAS_DATAFLASH
- if (addr_dataflash(addr)){
- len = ntohl(hdr->ih_size) + sizeof(image_header_t);
- read_dataflash(addr, len, (char *)CFG_LOAD_ADDR);
- addr = CFG_LOAD_ADDR;
- }
-#endif
-
-
/* for multi-file images we need the data part, too */
print_image_hdr ((image_header_t *)addr);
data = addr + sizeof(image_header_t);
len = ntohl(hdr->ih_size);
+#ifdef CONFIG_HAS_DATAFLASH
+ if (addr_dataflash(addr)){
+ read_dataflash(data, len, (char *)CFG_LOAD_ADDR);
+ data = CFG_LOAD_ADDR;
+ }
+#endif
+
if (verify) {
puts (" Verifying Checksum ... ");
- if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
+ if (crc32 (0, (unsigned char *)data, len) != ntohl(hdr->ih_dcrc)) {
printf ("Bad Data CRC\n");
SHOW_BOOT_PROGRESS (-3);
return 1;
@@ -267,7 +261,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
name = "Standalone Application";
/* A second argument overwrites the load address */
if (argc > 2) {
- hdr->ih_load = htonl(simple_strtoul(argv[2], NULL, 16));
+ hdr->ih_load = simple_strtoul(argv[2], NULL, 16);
}
break;
case IH_TYPE_KERNEL:
@@ -493,11 +487,6 @@ fixup_silent_linux ()
}
#endif /* CONFIG_SILENT_CONSOLE */
-#ifdef CONFIG_OF_FLAT_TREE
-extern const unsigned char oftree_dtb[];
-extern const unsigned int oftree_dtb_len;
-#endif
-
#ifdef CONFIG_PPC
static void
do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
@@ -520,9 +509,6 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
bd_t *kbd;
void (*kernel)(bd_t *, ulong, ulong, ulong, ulong);
image_header_t *hdr = &header;
-#ifdef CONFIG_OF_FLAT_TREE
- char *of_flat_tree;
-#endif
if ((s = getenv ("initrd_high")) != NULL) {
/* a value of "no" or a similar string will act like 0,
@@ -594,12 +580,12 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
kbd->bi_flbfreq /= 1000000L;
kbd->bi_vcofreq /= 1000000L;
#endif
-#if defined(CONFIG_CPM2)
+#if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
kbd->bi_cpmfreq /= 1000000L;
kbd->bi_brgfreq /= 1000000L;
kbd->bi_sccfreq /= 1000000L;
kbd->bi_vco /= 1000000L;
-#endif
+#endif /* CONFIG_8260 */
#if defined(CONFIG_MPC5xxx)
kbd->bi_ipbfreq /= 1000000L;
kbd->bi_pcifreq /= 1000000L;
@@ -633,7 +619,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
checksum = hdr->ih_hcrc;
hdr->ih_hcrc = 0;
- if (crc32 (0, (uchar *)data, len) != checksum) {
+ if (crc32 (0, (char *)data, len) != checksum) {
puts ("Bad Header Checksum\n");
SHOW_BOOT_PROGRESS (-11);
do_reset (cmdtp, flag, argc, argv);
@@ -661,13 +647,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
if (chunk > CHUNKSZ)
chunk = CHUNKSZ;
- csum = crc32 (csum, (uchar *)cdata, chunk);
+ csum = crc32 (csum, (char *)cdata, chunk);
cdata += chunk;
WATCHDOG_RESET();
}
#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
- csum = crc32 (0, (uchar *)data, len);
+ csum = crc32 (0, (char *)data, len);
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
if (csum != hdr->ih_dcrc) {
@@ -788,26 +774,15 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
initrd_end = 0;
}
-#ifdef CONFIG_OF_FLAT_TREE
- if (initrd_start == 0)
- of_flat_tree = (char *)(((ulong)kbd - OF_FLAT_TREE_MAX_SIZE -
- sizeof(bd_t)) & ~0xF);
- else
- of_flat_tree = (char *)((initrd_start - OF_FLAT_TREE_MAX_SIZE -
- sizeof(bd_t)) & ~0xF);
-#endif
debug ("## Transferring control to Linux (at address %08lx) ...\n",
(ulong)kernel);
SHOW_BOOT_PROGRESS (15);
-#ifndef CONFIG_OF_FLAT_TREE
-
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
unlock_ram_in_cache();
#endif
-
/*
* Linux Kernel Parameters:
* r3: ptr to board info data
@@ -817,25 +792,6 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
* r7: End of command line string
*/
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
-
-#else
- ft_setup(of_flat_tree, OF_FLAT_TREE_MAX_SIZE, kbd);
- /* ft_dump_blob(of_flat_tree); */
-
-#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
- unlock_ram_in_cache();
-#endif
- /*
- * Linux Kernel Parameters:
- * r3: ptr to OF flat tree, followed by the board info data
- * r4: initrd_start or 0 if no initrd
- * r5: initrd_end - unused if r4 is 0
- * r6: Start of command line string
- * r7: End of command line string
- */
- (*kernel) ((bd_t *)of_flat_tree, initrd_start, initrd_end, cmd_start, cmd_end);
-
-#endif
}
#endif /* CONFIG_PPC */
@@ -1079,7 +1035,7 @@ static int image_info (ulong addr)
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
- if (crc32 (0, (uchar *)data, len) != checksum) {
+ if (crc32 (0, (unsigned char *)data, len) != checksum) {
puts (" Bad Header Checksum\n");
return 1;
}
@@ -1091,7 +1047,7 @@ static int image_info (ulong addr)
len = ntohl(hdr->ih_size);
puts (" Verifying Checksum ... ");
- if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
+ if (crc32 (0, (unsigned char *)data, len) != ntohl(hdr->ih_dcrc)) {
puts (" Bad Data CRC\n");
return 1;
}
@@ -1124,7 +1080,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
if (info->flash_id == FLASH_UNKNOWN)
goto next_bank;
- for (j=0; j<info->sector_count; ++j) {
+ for (j=0; j<CFG_MAX_FLASH_SECT; ++j) {
if (!(hdr=(image_header_t *)info->start[j]) ||
(ntohl(hdr->ih_magic) != IH_MAGIC))
@@ -1136,7 +1092,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
checksum = ntohl(header.ih_hcrc);
header.ih_hcrc = 0;
- if (crc32 (0, (uchar *)&header, sizeof(image_header_t))
+ if (crc32 (0, (unsigned char *)&header, sizeof(image_header_t))
!= checksum)
goto next_sector;
@@ -1147,7 +1103,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
len = ntohl(hdr->ih_size);
puts (" Verifying Checksum ... ");
- if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
+ if (crc32 (0, (unsigned char *)data, len) != ntohl(hdr->ih_dcrc)) {
puts (" Bad Data CRC\n");
}
puts ("OK\n");
@@ -1241,8 +1197,6 @@ print_type (image_header_t *hdr)
case IH_CPU_SPARC64: arch = "SPARC 64 Bit"; break;
case IH_CPU_M68K: arch = "M68K"; break;
case IH_CPU_MICROBLAZE: arch = "Microblaze"; break;
- case IH_CPU_NIOS: arch = "Nios"; break;
- case IH_CPU_NIOS2: arch = "Nios-II"; break;
default: arch = "Unknown Architecture"; break;
}
diff --git a/common/cmd_date.c b/common/cmd_date.c
index a569d78cadc..84932f75680 100644
--- a/common/cmd_date.c
+++ b/common/cmd_date.c
@@ -28,6 +28,8 @@
#include <command.h>
#include <rtc.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if (CONFIG_COMMANDS & CFG_CMD_DATE)
const char *weekdays[] = {
@@ -40,7 +42,6 @@ int mk_date (char *, struct rtc_time *);
int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
struct rtc_time tm;
int rcode = 0;
diff --git a/common/cmd_doc.c b/common/cmd_doc.c
index 5e9bea30450..ab375169531 100644
--- a/common/cmd_doc.c
+++ b/common/cmd_doc.c
@@ -22,10 +22,7 @@
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
#include <linux/mtd/nftl.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ids.h>
#include <linux/mtd/doc2000.h>
-#include <linux/mtd/nftl.h>
#ifdef CFG_DOC_SUPPORT_2000
#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
@@ -68,6 +65,32 @@ static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE];
/* Current DOC Device */
static int curr_device = -1;
+/* Supported NAND flash devices */
+static struct nand_flash_dev nand_flash_ids[] = {
+ {"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0},
+ {"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0},
+ {"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000, 0},
+ {"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000, 0},
+ {"Toshiba TH58512FT", NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000, 0},
+ {"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000, 0},
+ {"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000, 0},
+ {"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000, 0},
+ {"Toshiba TH58100FT", NAND_MFR_TOSHIBA, 0x79, 27, 0, 3, 0x4000, 0},
+ {"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0},
+ {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0},
+ {"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000, 0},
+ {"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000, 0},
+ {"Samsung unknown 64Mb", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
+ {"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000, 0},
+ {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000, 0},
+ {"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000, 0},
+ {"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0},
+ {"Samsung K9F5616Q0C", NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1},
+ {"Samsung K9K1216Q0C", NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1},
+ {"Samsung K9F1G08U0M", NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0},
+ {NULL,}
+};
+
/* ------------------------------------------------------------------------- */
int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@@ -249,7 +272,7 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
print_image_hdr (hdr);
- cnt = (hdr->ih_size + sizeof(image_header_t));
+ cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
cnt -= SECTORSIZE;
} else {
puts ("\n** Bad Magic Number **\n");
diff --git a/common/cmd_elf.c b/common/cmd_elf.c
index eccf2e9e7b1..1d92bb37d3f 100644
--- a/common/cmd_elf.c
+++ b/common/cmd_elf.c
@@ -19,6 +19,9 @@
#include <net.h>
#include <elf.h>
+#if defined(CONFIG_WALNUT) || defined(CFG_VXWORKS_MAC_PTR)
+DECLARE_GLOBAL_DATA_PTR;
+#endif
#if (CONFIG_COMMANDS & CFG_CMD_ELF)
@@ -78,11 +81,6 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
* ====================================================================== */
int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
-#if defined(CONFIG_WALNUT) || \
- defined(CFG_VXWORKS_MAC_PTR)
- DECLARE_GLOBAL_DATA_PTR;
-#endif
-
unsigned long addr; /* Address of image */
unsigned long bootaddr; /* Address to put the bootline */
char *bootline; /* Text of the bootline */
diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c
index 02dffa38e52..03f4ce6d34c 100644
--- a/common/cmd_fdc.c
+++ b/common/cmd_fdc.c
@@ -836,13 +836,13 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
hdr = (image_header_t *)addr;
- if (hdr->ih_magic != IH_MAGIC) {
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
printf ("Bad Magic Number\n");
return 1;
}
print_image_hdr(hdr);
- imsize= hdr->ih_size+sizeof(image_header_t);
+ imsize= ntohl(hdr->ih_size)+sizeof(image_header_t);
nrofblk=imsize/512;
if((imsize%512)>0)
nrofblk++;
diff --git a/common/cmd_flash.c b/common/cmd_flash.c
index 0aa478306b8..cb1c5bb432b 100644
--- a/common/cmd_flash.c
+++ b/common/cmd_flash.c
@@ -125,13 +125,16 @@ abbrev_spec (char *str, flash_info_t ** pinfo, int *psf, int *psl)
static int
addr_spec(char *arg1, char *arg2, ulong *addr_first, ulong *addr_last)
{
- char len_used = 0; /* indicates if the "start +length" form used */
char *ep;
+ char len_used; /* indicates if the "start +length" form used */
+ char found;
+ ulong bank;
*addr_first = simple_strtoul(arg1, &ep, 16);
if (ep == arg1 || *ep != '\0')
return -1;
+ len_used = 0;
if (arg2 && *arg2 == '+'){
len_used = 1;
++arg2;
@@ -142,9 +145,6 @@ addr_spec(char *arg1, char *arg2, ulong *addr_first, ulong *addr_last)
return -1;
if (len_used){
- char found = 0;
- ulong bank;
-
/*
* *addr_last has the length, compute correct *addr_last
* XXX watch out for the integer overflow! Right now it is
@@ -159,6 +159,7 @@ addr_spec(char *arg1, char *arg2, ulong *addr_first, ulong *addr_last)
*/
/* find the end addr of the sector where the *addr_last is */
+ found = 0;
for (bank = 0; bank < CFG_MAX_FLASH_BANKS && !found; ++bank){
int i;
flash_info_t *info = &flash_info[bank];
@@ -455,6 +456,7 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#ifdef CONFIG_HAS_DATAFLASH
int status;
#endif
+
if (argc < 3) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
@@ -505,12 +507,10 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
info->protect[i] = p;
#endif /* CFG_FLASH_PROTECTION */
}
- }
-
#if defined(CFG_FLASH_PROTECTION)
- if (!rcode) puts (" done\n");
+ if (!rcode) puts (" done\n");
#endif /* CFG_FLASH_PROTECTION */
-
+ }
return rcode;
}
@@ -655,10 +655,10 @@ int flash_sect_protect (int p, ulong addr_first, ulong addr_last)
#endif /* CFG_FLASH_PROTECTION */
}
}
+ }
#if defined(CFG_FLASH_PROTECTION)
- if (!rcode) putc ('\n');
+ puts (" done\n");
#endif /* CFG_FLASH_PROTECTION */
- }
printf ("%sProtected %d sectors\n",
p ? "" : "Un-", protected);
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index c543bb53148..9d816f8ec15 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -874,6 +874,26 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#endif /* CFG_CMD_SDRAM */
+#if defined(CFG_I2C_BUS_SELECT)
+int do_i2c_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ int bus_idx, bus_spd, res = 0;
+ if (argc < 3) {
+ printf("Usage[%d]:\n%s\n", argc, cmdtp->usage);
+ return 1;
+ }
+ bus_idx = simple_strtoul(argv[1], NULL, 16);
+ bus_spd = simple_strtoul(argv[2], NULL, 16);
+ printf("Setting bus[%d] to Speed[%d]: ", bus_idx, bus_spd);
+ res = select_bus(bus_idx, bus_spd);
+ if (res) {
+ printf("FAILED\n");
+ } else {
+ printf("PASS\n");
+ }
+ return res;
+}
+#endif /* bus select */
/***************************************************/
U_BOOT_CMD(
@@ -930,4 +950,12 @@ U_BOOT_CMD(
" (valid chip values 50..57)\n"
);
#endif
+
+#if defined(CFG_I2C_BUS_SELECT)
+U_BOOT_CMD(ibus, 3, 1, do_i2c_bus,
+ "ibus - Select i2c Bus\n",
+ "bus_index speed\n - Selects the bus index and sets the speed (0x64(ST),0x190(FS),0xD48(HS))\n"
+ " (reports success/failure)\n");
+#endif
+
#endif /* CFG_CMD_I2C */
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index b67d35a5a4e..a4155029a7b 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -60,6 +60,10 @@ unsigned long mips_io_port_base = 0;
# define SHOW_BOOT_PROGRESS(arg)
#endif
+#ifdef CONFIG_IDE_8xx_DIRECT
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
#ifdef __PPC__
# define EIEIO __asm__ volatile ("eieio")
# define SYNC __asm__ volatile ("sync")
@@ -498,7 +502,6 @@ void ide_init (void)
{
#ifdef CONFIG_IDE_8xx_DIRECT
- DECLARE_GLOBAL_DATA_PTR;
volatile immap_t *immr = (immap_t *)CFG_IMMR;
volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
#endif
@@ -852,7 +855,7 @@ output_data_short(int dev, ulong *sect_buf, int words)
/* We only need to swap data if we are running on a big endian cpu. */
/* But Au1x00 cpu:s already swaps data in big endian mode! */
-#if defined(__LITTLE_ENDIAN) || defined(CONFIG_AU1X00)
+#if defined(__LITTLE_ENDIAN) || ( defined(CONFIG_AU1X00) && !defined(CONFIG_GTH2) )
#define input_swap_data(x,y,z) input_data(x,y,z)
#else
static void
@@ -878,8 +881,13 @@ input_swap_data(int dev, ulong *sect_buf, int words)
debug("in input swap data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
+#ifdef __MIPS__
+ *dbuf++ = swab16p((u16*)pbuf);
+ *dbuf++ = swab16p((u16*)pbuf);
+#else
*dbuf++ = ld_le16(pbuf);
*dbuf++ = ld_le16(pbuf);
+#endif /* !MIPS */
}
#endif
}
diff --git a/common/cmd_immap.c b/common/cmd_immap.c
index 559d7b4c300..fa79b45a3cc 100644
--- a/common/cmd_immap.c
+++ b/common/cmd_immap.c
@@ -41,6 +41,10 @@
#include <asm/iopin_8260.h>
#endif
+#if defined(CONFIG_8xx) || defined(CONFIG_8260)
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
static void
unimplemented ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
@@ -450,10 +454,8 @@ static void prbrg (int n, uint val)
uint div16 = (val & CPM_BRG_DIV16) != 0;
#if defined(CONFIG_8xx)
- DECLARE_GLOBAL_DATA_PTR;
ulong clock = gd->cpu_clk;
#elif defined(CONFIG_8260)
- DECLARE_GLOBAL_DATA_PTR;
ulong clock = gd->brg_clk;
#endif
diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c
index 34920b1abd3..201c3c1553c 100644
--- a/common/cmd_jffs2.c
+++ b/common/cmd_jffs2.c
@@ -91,7 +91,6 @@
#include <command.h>
#include <malloc.h>
#include <jffs2/jffs2.h>
-#include <linux/mtd/nand.h>
#include <linux/list.h>
#include <linux/ctype.h>
@@ -99,11 +98,19 @@
#include <cramfs/cramfs_fs.h>
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+#ifdef CFG_NAND_LEGACY
+#include <linux/mtd/nand_legacy.h>
+#else /* !CFG_NAND_LEGACY */
+#include <linux/mtd/nand.h>
+#include <nand.h>
+#endif /* !CFG_NAND_LEGACY */
+#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
/* enable/disable debugging messages */
-#define DEBUG
-#undef DEBUG
+#define DEBUG_JFFS
+#undef DEBUG_JFFS
-#ifdef DEBUG
+#ifdef DEBUG_JFFS
# define DEBUGF(fmt, args...) printf(fmt ,##args)
#else
# define DEBUGF(fmt, args...)
@@ -123,7 +130,7 @@
/* this flag needs to be set in part_info struct mask_flags
* field for read-only partitions */
-#define MTD_WRITEABLE 1
+#define MTD_WRITEABLE_CMD 1
#ifdef CONFIG_JFFS2_CMDLINE
/* default values for mtdids and mtdparts variables */
@@ -365,10 +372,9 @@ static int part_validate_nand(struct mtdids *id, struct part_info *part)
{
#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
/* info for NAND chips */
- extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
- struct nand_chip *nand;
+ nand_info_t *nand;
- nand = &nand_dev_desc[id->num];
+ nand = &nand_info[id->num];
if ((unsigned long)(part->offset) % nand->erasesize) {
printf("%s%d: partition (%s) start offset alignment incorrect\n",
@@ -464,7 +470,9 @@ static int part_del(struct mtd_device *dev, struct part_info *part)
}
}
+#ifdef CFG_NAND_LEGACY
jffs2_free_cache(part);
+#endif
list_del(&part->link);
free(part);
dev->num_parts--;
@@ -491,7 +499,9 @@ static void part_delall(struct list_head *head)
list_for_each_safe(entry, n, head) {
part_tmp = list_entry(entry, struct part_info, link);
+#ifdef CFG_NAND_LEGACY
jffs2_free_cache(part_tmp);
+#endif
list_del(entry);
free(part_tmp);
}
@@ -646,7 +656,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
/* test for options */
mask_flags = 0;
if (strncmp(p, "ro", 2) == 0) {
- mask_flags |= MTD_WRITEABLE;
+ mask_flags |= MTD_WRITEABLE_CMD;
p += 2;
}
@@ -713,6 +723,7 @@ static int device_validate(u8 type, u8 num, u32 *size)
if (num < CFG_MAX_FLASH_BANKS) {
extern flash_info_t flash_info[];
*size = flash_info[num].size;
+
return 0;
}
@@ -724,8 +735,12 @@ static int device_validate(u8 type, u8 num, u32 *size)
} else if (type == MTD_DEV_TYPE_NAND) {
#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
if (num < CFG_MAX_NAND_DEVICE) {
+#ifndef CFG_NAND_LEGACY
+ *size = nand_info[num].size;
+#else
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
*size = nand_dev_desc[num].totlen;
+#endif
return 0;
}
@@ -1169,7 +1184,7 @@ static int generate_mtdparts(char *buf, u32 buflen)
}
/* ro mask flag */
- if (part->mask_flags && MTD_WRITEABLE) {
+ if (part->mask_flags && MTD_WRITEABLE_CMD) {
len = 2;
if (len > maxlen)
goto cleanup;
diff --git a/common/cmd_load.c b/common/cmd_load.c
index 749849711a0..f63b8e80561 100644
--- a/common/cmd_load.c
+++ b/common/cmd_load.c
@@ -29,7 +29,13 @@
#include <s_record.h>
#include <net.h>
#include <exports.h>
+#include <xyzModem.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+#if (CONFIG_COMMANDS & CFG_CMD_LOADB)
+static ulong load_serial_ymodem (ulong offset);
+#endif
#if (CONFIG_COMMANDS & CFG_CMD_LOADS)
static ulong load_serial (ulong offset);
@@ -53,7 +59,6 @@ int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
char *env_echo;
int rcode = 0;
#ifdef CFG_LOADS_BAUD_CHANGE
- DECLARE_GLOBAL_DATA_PTR;
int load_baudrate, current_baudrate;
load_baudrate = current_baudrate = gd->baudrate;
@@ -213,7 +218,6 @@ load_serial (ulong offset)
static int
read_record (char *buf, ulong len)
{
- DECLARE_GLOBAL_DATA_PTR;
char *p;
char c;
@@ -256,7 +260,6 @@ int do_save_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
ulong offset = 0;
ulong size = 0;
#ifdef CFG_LOADS_BAUD_CHANGE
- DECLARE_GLOBAL_DATA_PTR;
int save_baudrate, current_baudrate;
save_baudrate = current_baudrate = gd->baudrate;
@@ -433,8 +436,6 @@ char his_quote; /* quote chars he'll use */
int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
ulong offset = 0;
ulong addr;
int load_baudrate, current_baudrate;
@@ -475,21 +476,31 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
}
- printf ("## Ready for binary (kermit) download "
- "to 0x%08lX at %d bps...\n",
- offset,
- load_baudrate);
- addr = load_serial_bin (offset);
+ if (strcmp(argv[0],"loady")==0) {
+ printf ("## Ready for binary (ymodem) download "
+ "to 0x%08lX at %d bps...\n",
+ offset,
+ load_baudrate);
+
+ addr = load_serial_ymodem (offset);
- if (addr == ~0) {
- load_addr = 0;
- printf ("## Binary (kermit) download aborted\n");
- rcode = 1;
} else {
- printf ("## Start Addr = 0x%08lX\n", addr);
- load_addr = addr;
- }
+ printf ("## Ready for binary (kermit) download "
+ "to 0x%08lX at %d bps...\n",
+ offset,
+ load_baudrate);
+ addr = load_serial_bin (offset);
+
+ if (addr == ~0) {
+ load_addr = 0;
+ printf ("## Binary (kermit) download aborted\n");
+ rcode = 1;
+ } else {
+ printf ("## Start Addr = 0x%08lX\n", addr);
+ load_addr = addr;
+ }
+ }
if (load_baudrate != current_baudrate) {
printf ("## Switch baudrate to %d bps and press ESC ...\n",
current_baudrate);
@@ -963,6 +974,68 @@ START:
}
return ((ulong) os_data_addr - (ulong) bin_start_address);
}
+
+static int getcxmodem(void) {
+ if (tstc())
+ return (getc());
+ return -1;
+}
+static ulong load_serial_ymodem (ulong offset)
+{
+ int size;
+ char buf[32];
+ int err;
+ int res;
+ connection_info_t info;
+ char ymodemBuf[1024];
+ ulong store_addr = ~0;
+ ulong addr = 0;
+
+ size = 0;
+ info.mode = xyzModem_ymodem;
+ res = xyzModem_stream_open (&info, &err);
+ if (!res) {
+
+ while ((res =
+ xyzModem_stream_read (ymodemBuf, 1024, &err)) > 0) {
+ store_addr = addr + offset;
+ size += res;
+ addr += res;
+#ifndef CFG_NO_FLASH
+ if (addr2info (store_addr)) {
+ int rc;
+
+ rc = flash_write ((char *) ymodemBuf,
+ store_addr, res);
+ if (rc != 0) {
+ flash_perror (rc);
+ return (~0);
+ }
+ } else
+#endif
+ {
+ memcpy ((char *) (store_addr), ymodemBuf,
+ res);
+ }
+
+ }
+ } else {
+ printf ("%s\n", xyzModem_error (err));
+ }
+
+ xyzModem_stream_close (&err);
+ xyzModem_stream_terminate (false, &getcxmodem);
+
+
+ flush_cache (offset, size);
+
+ printf ("## Total Size = 0x%08x = %d Bytes\n", size, size);
+ sprintf (buf, "%X", size);
+ setenv ("filesize", buf);
+
+ return offset;
+}
+
#endif /* CFG_CMD_LOADB */
/* -------------------------------------------------------------------- */
@@ -1022,6 +1095,14 @@ U_BOOT_CMD(
" with offset 'off' and baudrate 'baud'\n"
);
+U_BOOT_CMD(
+ loady, 3, 0, do_load_serial_bin,
+ "loady - load binary file over serial line (ymodem mode)\n",
+ "[ off ] [ baud ]\n"
+ " - load binary file over serial line"
+ " with offset 'off' and baudrate 'baud'\n"
+);
+
#endif /* CFG_CMD_LOADB */
/* -------------------------------------------------------------------- */
diff --git a/common/cmd_log.c b/common/cmd_log.c
index efc9689c298..042a403026f 100644
--- a/common/cmd_log.c
+++ b/common/cmd_log.c
@@ -46,6 +46,8 @@
#include <post.h>
#include <logbuff.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if defined(CONFIG_LOGBUFFER)
/* Local prototypes */
@@ -73,7 +75,6 @@ static unsigned long *ext_logged_chars;
in linux/kernel/printk */
void logbuff_init_ptrs (void)
{
- DECLARE_GLOBAL_DATA_PTR;
unsigned long *ext_tag;
unsigned long post_word;
char *s;
@@ -139,8 +140,6 @@ static void logbuff_puts (const char *s)
void logbuff_log(char *msg)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if ((gd->post_log_word & LOGBUFF_INITIALIZED)) {
logbuff_printk (msg);
} else {
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 0f4f9b73df9..d0fae6b24c2 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -707,7 +707,7 @@ int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#if defined(CFG_MEMTEST_SCRATCH)
vu_long *dummy = (vu_long*)CFG_MEMTEST_SCRATCH;
#else
- vu_long *dummy = NULL;
+ vu_long *dummy = 0; /* yes, this is address 0x0, not NULL */
#endif
int j;
int iterations = 1;
diff --git a/common/cmd_mii.c b/common/cmd_mii.c
index 48a4e77c55a..ee5e43ee8c7 100644
--- a/common/cmd_mii.c
+++ b/common/cmd_mii.c
@@ -57,6 +57,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
int rcode = 0;
char *devname;
+ if (argc < 2) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
#if defined(CONFIG_8xx) || defined(CONFIG_MCF52x2)
mii_init ();
#endif
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index b0c01d1205a..4c2b1d6c1b9 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -9,6 +9,416 @@
*/
#include <common.h>
+
+
+#ifndef CFG_NAND_LEGACY
+/*
+ *
+ * New NAND support
+ *
+ */
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+
+#include <command.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
+#else
+# define SHOW_BOOT_PROGRESS(arg)
+#endif
+
+#include <jffs2/jffs2.h>
+#include <nand.h>
+
+extern nand_info_t nand_info[]; /* info for NAND chips */
+
+static int nand_dump_oob(nand_info_t *nand, ulong off)
+{
+ return 0;
+}
+
+static int nand_dump(nand_info_t *nand, ulong off)
+{
+ int i;
+ u_char *buf, *p;
+
+ buf = malloc(nand->oobblock + nand->oobsize);
+ if (!buf) {
+ puts("No memory for page buffer\n");
+ return 1;
+ }
+ off &= ~(nand->oobblock - 1);
+ i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize);
+ if (i < 0) {
+ printf("Error (%d) reading page %08x\n", i, off);
+ free(buf);
+ return 1;
+ }
+ printf("Page %08x dump:\n", off);
+ i = nand->oobblock >> 4; p = buf;
+ while (i--) {
+ printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
+ p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
+ p += 16;
+ }
+ puts("OOB:\n");
+ i = nand->oobsize >> 3;
+ while (i--) {
+ printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ p += 8;
+ }
+ free(buf);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void
+arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize)
+{
+ *off = 0;
+ *size = 0;
+
+#if defined(CONFIG_JFFS2_NAND) && defined(CFG_JFFS_CUSTOM_PART)
+ if (argc >= 1 && strcmp(argv[0], "partition") == 0) {
+ int part_num;
+ struct part_info *part;
+ const char *partstr;
+
+ if (argc >= 2)
+ partstr = argv[1];
+ else
+ partstr = getenv("partition");
+
+ if (partstr)
+ part_num = (int)simple_strtoul(partstr, NULL, 10);
+ else
+ part_num = 0;
+
+ part = jffs2_part_info(part_num);
+ if (part == NULL) {
+ printf("\nInvalid partition %d\n", part_num);
+ return;
+ }
+ *size = part->size;
+ *off = (ulong)part->offset;
+ } else
+#endif
+ {
+ if (argc >= 1)
+ *off = (ulong)simple_strtoul(argv[0], NULL, 16);
+ else
+ *off = 0;
+
+ if (argc >= 2)
+ *size = (ulong)simple_strtoul(argv[1], NULL, 16);
+ else
+ *size = totsize - *off;
+
+ }
+
+}
+#if defined(CONFIG_OMAP) && defined(CONFIG_3430LABRADOR)
+extern void omap_nand_switch_ecc(nand_info_t *nand, int hardware);
+extern int nand_unlock(nand_info_t *nand, ulong off, ulong size);
+#else
+#define omap_nand_switch_ecc(x, y) do {} while(0)
+#define nand_unlock(n, o, s) !(1)
+#endif
+
+int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ int i, dev, ret;
+ ulong addr, off, size;
+ char *cmd, *s;
+ nand_info_t *nand;
+
+ /* at least two arguments please */
+ if (argc < 2)
+ goto usage;
+
+ cmd = argv[1];
+
+ if (strcmp(cmd, "info") == 0) {
+
+ putc('\n');
+ for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
+ if (nand_info[i].name)
+ printf("Device %d: %s, sector size %lu KiB\n",
+ i, nand_info[i].name,
+ nand_info[i].erasesize >> 10);
+ }
+ return 0;
+ }
+
+ if (strcmp(cmd, "device") == 0) {
+
+ if (argc < 3) {
+ if ((nand_curr_device < 0) ||
+ (nand_curr_device >= CFG_MAX_NAND_DEVICE))
+ puts("\nno devices available\n");
+ else
+ printf("\nDevice %d: %s\n", nand_curr_device,
+ nand_info[nand_curr_device].name);
+ return 0;
+ }
+ dev = (int)simple_strtoul(argv[2], NULL, 10);
+ if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) {
+ puts("No such device\n");
+ return 1;
+ }
+ printf("Device %d: %s", dev, nand_info[dev].name);
+ puts("... is now current device\n");
+ nand_curr_device = dev;
+ return 0;
+ }
+
+ if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 &&
+ strncmp(cmd, "unlock", 5) != 0 &&
+ strncmp(cmd, "dump", 4) != 0 &&
+ strncmp(cmd, "ecc", 3) != 0 &&
+ strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0)
+ goto usage;
+
+ /* the following commands operate on the current device */
+ if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE ||
+ !nand_info[nand_curr_device].name) {
+ puts("\nno devices available\n");
+ return 1;
+ }
+ nand = &nand_info[nand_curr_device];
+
+ if (strcmp(cmd, "bad") == 0) {
+ printf("\nDevice %d bad blocks:\n", nand_curr_device);
+ for (off = 0; off < nand->size; off += nand->erasesize)
+ if (nand_block_isbad(nand, off))
+ printf(" %08x\n", off);
+ return 0;
+ }
+
+ if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "unlock") == 0) {
+ arg_off_size(argc - 2, argv + 2, &off, &size, nand->size);
+ if (off == 0 && size == 0)
+ return 1;
+
+ i = strncmp(cmd, "erase", 5) == 0; /* 1 = read, 0 = write */
+ printf("\nNAND %s: device %d offset 0x%x, size 0x%x ",
+ i ? "erase" : "unlock", nand_curr_device, off, size);
+ if (i)
+ ret = nand_erase(nand, off, size);
+ else
+ ret = nand_unlock(nand, off, size);
+ printf("%s\n", ret ? "ERROR" : "OK");
+
+ return ret == 0 ? 0 : 1;
+ }
+
+ if (strncmp(cmd, "dump", 4) == 0) {
+ if (argc < 3)
+ goto usage;
+
+ s = strchr(cmd, '.');
+ off = (int)simple_strtoul(argv[2], NULL, 16);
+
+ if (s != NULL && strcmp(s, ".oob") == 0)
+ ret = nand_dump_oob(nand, off);
+ else
+ ret = nand_dump(nand, off);
+
+ return ret == 0 ? 1 : 0;
+
+ }
+ if (strncmp(cmd, "ecc", 3) == 0) {
+ if (argc < 2)
+ goto usage;
+ if (strncmp(argv[2], "hw", 2) == 0)
+ omap_nand_switch_ecc(nand, 1);
+ else if (strncmp(argv[2], "sw", 2) == 0)
+ omap_nand_switch_ecc(nand, 0);
+ else
+ goto usage;
+
+ return 0;
+ }
+
+ /* read write */
+ if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
+ if (argc < 4)
+ goto usage;
+/*
+ s = strchr(cmd, '.');
+ clean = CLEAN_NONE;
+ if (s != NULL) {
+ if (strcmp(s, ".jffs2") == 0 || strcmp(s, ".e") == 0
+ || strcmp(s, ".i"))
+ clean = CLEAN_JFFS2;
+ }
+*/
+ addr = (ulong)simple_strtoul(argv[2], NULL, 16);
+
+ arg_off_size(argc - 3, argv + 3, &off, &size, nand->size);
+ if (off == 0 && size == 0)
+ return 1;
+
+ i = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
+ printf("\nNAND %s: device %d offset %u, size %u ... ",
+ i ? "read" : "write",
+ nand_curr_device, off, size);
+
+ if (i)
+ ret = nand_read(nand, off, &size, (u_char *)addr);
+ else
+ ret = nand_write(nand, off, &size, (u_char *)addr);
+
+ printf(" %d bytes %s: %s\n", size,
+ i ? "read" : "written", ret ? "ERROR" : "OK");
+
+ return ret == 0 ? 0 : 1;
+ }
+usage:
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(nand, 5, 1, do_nand,
+ "nand - NAND sub-system\n",
+ "info - show available NAND devices\n"
+ "nand device [dev] - show or set current device\n"
+ "nand read[.jffs2] - addr off size\n"
+ "nand write[.jffs2] - addr off size - read/write `size' bytes starting\n"
+ " at offset `off' to/from memory address `addr'\n"
+ "nand erase [clean] [off size] - erase `size' bytes from\n"
+ " offset `off' (entire device if not specified)\n"
+ "nand bad - show bad blocks\n"
+ "nand dump[.oob] off - dump page\n"
+ "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
+ "nand markbad off - mark bad block at offset (UNSAFE)\n"
+ "nand biterr off - make a bit error at offset (UNSAFE)\n"
+ "nand ecc [hw/sw] - switch the ecc calculation algorithm \n"
+ "nand unlock off size - unlock `size' bytes from\n"
+ " offset `off' (entire device if not specified)\n");
+
+int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ char *boot_device = NULL;
+ char *ep;
+ int dev;
+ int r;
+ ulong addr, cnt, offset = 0;
+ image_header_t *hdr;
+ nand_info_t *nand;
+
+ switch (argc) {
+ case 1:
+ addr = CFG_LOAD_ADDR;
+ boot_device = getenv("bootdevice");
+ break;
+ case 2:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = getenv("bootdevice");
+ break;
+ case 3:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = argv[2];
+ break;
+ case 4:
+ addr = simple_strtoul(argv[1], NULL, 16);
+ boot_device = argv[2];
+ offset = simple_strtoul(argv[3], NULL, 16);
+ break;
+ default:
+ printf("Usage:\n%s\n", cmdtp->usage);
+ SHOW_BOOT_PROGRESS(-1);
+ return 1;
+ }
+
+ if (!boot_device) {
+ puts("\n** No boot device **\n");
+ SHOW_BOOT_PROGRESS(-1);
+ return 1;
+ }
+
+ dev = simple_strtoul(boot_device, &ep, 16);
+
+ if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) {
+ printf("\n** Device %d not available\n", dev);
+ SHOW_BOOT_PROGRESS(-1);
+ return 1;
+ }
+
+ nand = &nand_info[dev];
+ printf("\nLoading from device %d: %s (offset 0x%lx)\n",
+ dev, nand->name, offset);
+
+ cnt = nand->oobblock;
+ r = nand_read(nand, offset, &cnt, (u_char *) addr);
+ if (r) {
+ printf("** Read error on %d\n", dev);
+ SHOW_BOOT_PROGRESS(-1);
+ return 1;
+ }
+
+ hdr = (image_header_t *) addr;
+
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+ printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
+ SHOW_BOOT_PROGRESS(-1);
+ return 1;
+ }
+
+ print_image_hdr(hdr);
+
+ cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
+
+ r = nand_read(nand, offset, &cnt, (u_char *) addr);
+ if (r) {
+ printf("** Read error on %d\n", dev);
+ SHOW_BOOT_PROGRESS(-1);
+ return 1;
+ }
+
+ /* Loading ok, update default load address */
+
+ load_addr = addr;
+
+ /* Check if we should attempt an auto-start */
+ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
+ char *local_args[2];
+ extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
+
+ local_args[0] = argv[0];
+ local_args[1] = NULL;
+
+ printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
+
+ do_bootm(cmdtp, 0, 1, local_args);
+ return 1;
+ }
+ return 0;
+}
+
+U_BOOT_CMD(nboot, 4, 1, do_nandboot,
+ "nboot - boot from NAND device\n", "loadAddr dev\n");
+
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
+
+#else /* CFG_NAND_LEGACY */
+/*
+ *
+ * Legacy NAND support - to be phased out
+ *
+ */
#include <command.h>
#include <malloc.h>
#include <asm/io.h>
@@ -22,10 +432,11 @@
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
-
-#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_legacy.h>
+#if 0
#include <linux/mtd/nand_ids.h>
#include <jffs2/jffs2.h>
+#endif
#ifdef CONFIG_OMAP1510
void archflashwp(void *archdata, int wp);
@@ -33,15 +444,6 @@ void archflashwp(void *archdata, int wp);
#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
-/*
- * Definition of the out of band configuration structure
- */
-struct nand_oob_config {
- int ecc_pos[6]; /* position of ECC bytes inside oob */
- int badblock_pos; /* position of bad block flag inside oob -1 = inactive */
- int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */
-} oob_config = { {0}, 0, 0};
-
#undef NAND_DEBUG
#undef PSYCHO_DEBUG
@@ -63,41 +465,28 @@ struct nand_oob_config {
#define CONFIG_MTD_NAND_ECC /* enable ECC */
#define CONFIG_MTD_NAND_ECC_JFFS2
-/* bits for nand_rw() `cmd'; or together as needed */
+/* bits for nand_legacy_rw() `cmd'; or together as needed */
#define NANDRW_READ 0x01
#define NANDRW_WRITE 0x00
#define NANDRW_JFFS2 0x02
#define NANDRW_JFFS2_SKIP 0x04
/*
- * Function Prototypes
+ * Imports from nand_legacy.c
*/
-static void nand_print(struct nand_chip *nand);
-int nand_rw (struct nand_chip* nand, int cmd,
- size_t start, size_t len,
- size_t * retlen, u_char * buf);
-int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);
-static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
- size_t * retlen, u_char *buf, u_char *ecc_code);
-static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
- size_t * retlen, const u_char * buf, u_char * ecc_code);
-static void nand_print_bad(struct nand_chip *nand);
-static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
- size_t * retlen, u_char * buf);
-static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
- size_t * retlen, const u_char * buf);
-static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
-#ifdef CONFIG_MTD_NAND_ECC
-static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
-#endif
-
-struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
+extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
+extern int curr_device;
+extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs,
+ size_t len, int clean);
+extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start,
+ size_t len, size_t *retlen, u_char *buf);
+extern void nand_print(struct nand_chip *nand);
+extern void nand_print_bad(struct nand_chip *nand);
+extern int nand_read_oob(struct nand_chip *nand, size_t ofs,
+ size_t len, size_t *retlen, u_char *buf);
+extern int nand_write_oob(struct nand_chip *nand, size_t ofs,
+ size_t len, size_t *retlen, const u_char *buf);
-/* Current NAND Device */
-static int curr_device = -1;
-
-/* ------------------------------------------------------------------------- */
int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
@@ -174,7 +563,7 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
curr_device, off, size);
- ret = nand_erase (nand, off, size, 1);
+ ret = nand_legacy_erase (nand, off, size, 1);
printf("%s\n", ret ? "ERROR" : "OK");
@@ -240,7 +629,7 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
(cmd & NANDRW_READ) ? "read" : "write",
curr_device, off, size);
- ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size,
+ ret = nand_legacy_rw(nand_dev_desc + curr_device, cmd, off, size,
(size_t *)&total, (u_char*)addr);
printf (" %d bytes %s: %s\n", total,
@@ -258,7 +647,8 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
curr_device, off, size);
- ret = nand_erase (nand_dev_desc + curr_device, off, size, clean);
+ ret = nand_legacy_erase (nand_dev_desc + curr_device,
+ off, size, clean);
printf("%s\n", ret ? "ERROR" : "OK");
@@ -284,6 +674,7 @@ U_BOOT_CMD(
" offset `off' (entire device if not specified)\n"
"nand bad - show bad blocks\n"
"nand read.oob addr off size - read out-of-band data\n"
+ "nand read.oob addr off size - read out-of-band data\n"
"nand write.oob addr off size - read out-of-band data\n"
);
@@ -340,8 +731,8 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
offset);
- if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset,
- SECTORSIZE, NULL, (u_char *)addr)) {
+ if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset,
+ SECTORSIZE, NULL, (u_char *)addr)) {
printf ("** Read error on %d\n", dev);
SHOW_BOOT_PROGRESS (-1);
return 1;
@@ -356,13 +747,14 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
cnt -= SECTORSIZE;
} else {
- printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
+ printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic));
SHOW_BOOT_PROGRESS (-1);
return 1;
}
- if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt,
- NULL, (u_char *)(addr+SECTORSIZE))) {
+ if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ,
+ offset + SECTORSIZE, cnt, NULL,
+ (u_char *)(addr+SECTORSIZE))) {
printf ("** Read error on %d\n", dev);
SHOW_BOOT_PROGRESS (-1);
return 1;
@@ -394,1505 +786,6 @@ U_BOOT_CMD(
"loadAddr dev\n"
);
-/* returns 0 if block containing pos is OK:
- * valid erase block and
- * not marked bad, or no bad mark position is specified
- * returns 1 if marked bad or otherwise invalid
- */
-int check_block (struct nand_chip *nand, unsigned long pos)
-{
- size_t retlen;
- uint8_t oob_data;
- uint16_t oob_data16[6];
- int page0 = pos & (-nand->erasesize);
- int page1 = page0 + nand->oobblock;
- int badpos = oob_config.badblock_pos;
-
- if (pos >= nand->totlen)
- return 1;
-
- if (badpos < 0)
- return 0; /* no way to check, assume OK */
-
- if (nand->bus16) {
- if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16)
- || (oob_data16[2] & 0xff00) != 0xff00)
- return 1;
- if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16)
- || (oob_data16[2] & 0xff00) != 0xff00)
- return 1;
- } else {
- /* Note - bad block marker can be on first or second page */
- if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data)
- || oob_data != 0xff
- || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data)
- || oob_data != 0xff)
- return 1;
- }
-
- return 0;
-}
-
-/* print bad blocks in NAND flash */
-static void nand_print_bad(struct nand_chip* nand)
-{
- unsigned long pos;
-
- for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
- if (check_block(nand, pos))
- printf(" 0x%8.8lx\n", pos);
- }
- puts("\n");
-}
-
-/* cmd: 0: NANDRW_WRITE write, fail on bad block
- * 1: NANDRW_READ read, fail on bad block
- * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
- * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
- * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
- */
-int nand_rw (struct nand_chip* nand, int cmd,
- size_t start, size_t len,
- size_t * retlen, u_char * buf)
-{
- int ret = 0, n, total = 0;
- char eccbuf[6];
- /* eblk (once set) is the start of the erase block containing the
- * data being processed.
- */
- unsigned long eblk = ~0; /* force mismatch on first pass */
- unsigned long erasesize = nand->erasesize;
-
- while (len) {
- if ((start & (-erasesize)) != eblk) {
- /* have crossed into new erase block, deal with
- * it if it is sure marked bad.
- */
- eblk = start & (-erasesize); /* start of block */
- if (check_block(nand, eblk)) {
- if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
- while (len > 0 &&
- start - eblk < erasesize) {
- *(buf++) = 0xff;
- ++start;
- ++total;
- --len;
- }
- continue;
- } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
- start += erasesize;
- continue;
- } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
- /* skip bad block */
- start += erasesize;
- continue;
- } else {
- ret = 1;
- break;
- }
- }
- }
- /* The ECC will not be calculated correctly if
- less than 512 is written or read */
- /* Is request at least 512 bytes AND it starts on a proper boundry */
- if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
- printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
-
- if (cmd & NANDRW_READ) {
- ret = nand_read_ecc(nand, start,
- min(len, eblk + erasesize - start),
- (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
- } else {
- ret = nand_write_ecc(nand, start,
- min(len, eblk + erasesize - start),
- (size_t *)&n, (u_char*)buf, (u_char *)eccbuf);
- }
-
- if (ret)
- break;
-
- start += n;
- buf += n;
- total += n;
- len -= n;
- }
- if (retlen)
- *retlen = total;
-
- return ret;
-}
-
-static void nand_print(struct nand_chip *nand)
-{
- if (nand->numchips > 1) {
- printf("%s at 0x%lx,\n"
- "\t %d chips %s, size %d MB, \n"
- "\t total size %ld MB, sector size %ld kB\n",
- nand->name, nand->IO_ADDR, nand->numchips,
- nand->chips_name, 1 << (nand->chipshift - 20),
- nand->totlen >> 20, nand->erasesize >> 10);
- }
- else {
- printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
- print_size(nand->totlen, ", ");
- print_size(nand->erasesize, " sector)\n");
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
-{
- /* This is inline, to optimise the common case, where it's ready instantly */
- int ret = 0;
-
-#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */
- if(ale_wait)
- NAND_WAIT_READY(nand); /* do the worst case 25us wait */
- else
- udelay(10);
-#else /* has functional r/b signal */
- NAND_WAIT_READY(nand);
-#endif
- return ret;
-}
-
-/* NanD_Command: Send a flash command to the flash chip */
-
-static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
-{
- unsigned long nandptr = nand->IO_ADDR;
-
- /* Assert the CLE (Command Latch Enable) line to the flash chip */
- NAND_CTL_SETCLE(nandptr);
-
- /* Send the command */
- WRITE_NAND_COMMAND(command, nandptr);
-
- /* Lower the CLE line */
- NAND_CTL_CLRCLE(nandptr);
-
-#ifdef NAND_NO_RB
- if(command == NAND_CMD_RESET){
- u_char ret_val;
- NanD_Command(nand, NAND_CMD_STATUS);
- do {
- ret_val = READ_NAND(nandptr);/* wait till ready */
- } while((ret_val & 0x40) != 0x40);
- }
-#endif
- return NanD_WaitReady(nand, 0);
-}
-
-/* NanD_Address: Set the current address for the flash chip */
-
-static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
-{
- unsigned long nandptr;
- int i;
-
- nandptr = nand->IO_ADDR;
-
- /* Assert the ALE (Address Latch Enable) line to the flash chip */
- NAND_CTL_SETALE(nandptr);
-
- /* Send the address */
- /* Devices with 256-byte page are addressed as:
- * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
- * there is no device on the market with page256
- * and more than 24 bits.
- * Devices with 512-byte page are addressed as:
- * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
- * 25-31 is sent only if the chip support it.
- * bit 8 changes the read command to be sent
- * (NAND_CMD_READ0 or NAND_CMD_READ1).
- */
-
- if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
- WRITE_NAND_ADDRESS(ofs, nandptr);
-
- ofs = ofs >> nand->page_shift;
-
- if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
- for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) {
- WRITE_NAND_ADDRESS(ofs, nandptr);
- }
- }
-
- /* Lower the ALE line */
- NAND_CTL_CLRALE(nandptr);
-
- /* Wait for the chip to respond */
- return NanD_WaitReady(nand, 1);
-}
-
-/* NanD_SelectChip: Select a given flash chip within the current floor */
-
-static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
-{
- /* Wait for it to be ready */
- return NanD_WaitReady(nand, 0);
-}
-
-/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
-
-static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
-{
- int mfr, id, i;
-
- NAND_ENABLE_CE(nand); /* set pin low */
- /* Reset the chip */
- if (NanD_Command(nand, NAND_CMD_RESET)) {
-#ifdef NAND_DEBUG
- printf("NanD_Command (reset) for %d,%d returned true\n",
- floor, chip);
-#endif
- NAND_DISABLE_CE(nand); /* set pin high */
- return 0;
- }
-
- /* Read the NAND chip ID: 1. Send ReadID command */
- if (NanD_Command(nand, NAND_CMD_READID)) {
-#ifdef NAND_DEBUG
- printf("NanD_Command (ReadID) for %d,%d returned true\n",
- floor, chip);
-#endif
- NAND_DISABLE_CE(nand); /* set pin high */
- return 0;
- }
-
- /* Read the NAND chip ID: 2. Send address byte zero */
- NanD_Address(nand, ADDR_COLUMN, 0);
-
- /* Read the manufacturer and device id codes from the device */
-
- mfr = READ_NAND(nand->IO_ADDR);
-
- id = READ_NAND(nand->IO_ADDR);
-
- NAND_DISABLE_CE(nand); /* set pin high */
-
-#ifdef NAND_DEBUG
- printf("NanD_Command (ReadID) got %x %x\n", mfr, id);
-#endif
- if (mfr == 0xff || mfr == 0) {
- /* No response - return failure */
- return 0;
- }
-
- /* Check it's the same as the first chip we identified.
- * M-Systems say that any given nand_chip device should only
- * contain _one_ type of flash part, although that's not a
- * hardware restriction. */
- if (nand->mfr) {
- if (nand->mfr == mfr && nand->id == id) {
- return 1; /* This is another the same the first */
- } else {
- printf("Flash chip at floor %d, chip %d is different:\n",
- floor, chip);
- }
- }
-
- /* Print and store the manufacturer and ID codes. */
- for (i = 0; nand_flash_ids[i].name != NULL; i++) {
- if (mfr == nand_flash_ids[i].manufacture_id &&
- id == nand_flash_ids[i].model_id) {
-#ifdef NAND_DEBUG
- printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
- "Chip ID: 0x%2.2X (%s)\n", mfr, id,
- nand_flash_ids[i].name);
-#endif
- if (!nand->mfr) {
- nand->mfr = mfr;
- nand->id = id;
- nand->chipshift =
- nand_flash_ids[i].chipshift;
- nand->page256 = nand_flash_ids[i].page256;
- nand->eccsize = 256;
- if (nand->page256) {
- nand->oobblock = 256;
- nand->oobsize = 8;
- nand->page_shift = 8;
- } else {
- nand->oobblock = 512;
- nand->oobsize = 16;
- nand->page_shift = 9;
- }
- nand->pageadrlen = nand_flash_ids[i].pageadrlen;
- nand->erasesize = nand_flash_ids[i].erasesize;
- nand->chips_name = nand_flash_ids[i].name;
- nand->bus16 = nand_flash_ids[i].bus16;
- return 1;
- }
- return 0;
- }
- }
-
-
-#ifdef NAND_DEBUG
- /* We haven't fully identified the chip. Print as much as we know. */
- printf("Unknown flash chip found: %2.2X %2.2X\n",
- id, mfr);
-#endif
-
- return 0;
-}
-
-/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
-
-static void NanD_ScanChips(struct nand_chip *nand)
-{
- int floor, chip;
- int numchips[NAND_MAX_FLOORS];
- int maxchips = NAND_MAX_CHIPS;
- int ret = 1;
-
- nand->numchips = 0;
- nand->mfr = 0;
- nand->id = 0;
-
-
- /* For each floor, find the number of valid chips it contains */
- for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
- ret = 1;
- numchips[floor] = 0;
- for (chip = 0; chip < maxchips && ret != 0; chip++) {
-
- ret = NanD_IdentChip(nand, floor, chip);
- if (ret) {
- numchips[floor]++;
- nand->numchips++;
- }
- }
- }
-
- /* If there are none at all that we recognise, bail */
- if (!nand->numchips) {
-#ifdef NAND_DEBUG
- puts ("No NAND flash chips recognised.\n");
-#endif
- return;
- }
-
- /* Allocate an array to hold the information for each chip */
- nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
- if (!nand->chips) {
- puts ("No memory for allocating chip info structures\n");
- return;
- }
-
- ret = 0;
-
- /* Fill out the chip array with {floor, chipno} for each
- * detected chip in the device. */
- for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
- for (chip = 0; chip < numchips[floor]; chip++) {
- nand->chips[ret].floor = floor;
- nand->chips[ret].chip = chip;
- nand->chips[ret].curadr = 0;
- nand->chips[ret].curmode = 0x50;
- ret++;
- }
- }
-
- /* Calculate and print the total size of the device */
- nand->totlen = nand->numchips * (1 << nand->chipshift);
-
-#ifdef NAND_DEBUG
- printf("%d flash chips found. Total nand_chip size: %ld MB\n",
- nand->numchips, nand->totlen >> 20);
-#endif
-}
-
-/* we need to be fast here, 1 us per read translates to 1 second per meg */
-static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr)
-{
- unsigned long nandptr = nand->IO_ADDR;
-
- NanD_Command (nand, NAND_CMD_READ0);
-
- if (nand->bus16) {
- u16 val;
-
- while (cntr >= 16) {
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- cntr -= 16;
- }
-
- while (cntr > 0) {
- val = READ_NAND (nandptr);
- *data_buf++ = val & 0xff;
- *data_buf++ = val >> 8;
- cntr -= 2;
- }
- } else {
- while (cntr >= 16) {
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- *data_buf++ = READ_NAND (nandptr);
- cntr -= 16;
- }
-
- while (cntr > 0) {
- *data_buf++ = READ_NAND (nandptr);
- cntr--;
- }
- }
-}
-
-/*
- * NAND read with ECC
- */
-static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
- size_t * retlen, u_char *buf, u_char *ecc_code)
-{
- int col, page;
- int ecc_status = 0;
-#ifdef CONFIG_MTD_NAND_ECC
- int j;
- int ecc_failed = 0;
- u_char *data_poi;
- u_char ecc_calc[6];
-#endif
-
- /* Do not allow reads past end of device */
- if ((start + len) > nand->totlen) {
- printf ("%s: Attempt read beyond end of device %x %x %x\n",
- __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
- *retlen = 0;
- return -1;
- }
-
- /* First we calculate the starting page */
- /*page = shr(start, nand->page_shift);*/
- page = start >> nand->page_shift;
-
- /* Get raw starting column */
- col = start & (nand->oobblock - 1);
-
- /* Initialize return value */
- *retlen = 0;
-
- /* Select the NAND device */
- NAND_ENABLE_CE(nand); /* set pin low */
-
- /* Loop until all data read */
- while (*retlen < len) {
-
-#ifdef CONFIG_MTD_NAND_ECC
- /* Do we have this page in cache ? */
- if (nand->cache_page == page)
- goto readdata;
- /* Send the read command */
- NanD_Command(nand, NAND_CMD_READ0);
- if (nand->bus16) {
- NanD_Address(nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + (col >> 1));
- } else {
- NanD_Address(nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + col);
- }
-
- /* Read in a page + oob data */
- NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
-
- /* copy data into cache, for read out of cache and if ecc fails */
- if (nand->data_cache) {
- memcpy (nand->data_cache, nand->data_buf,
- nand->oobblock + nand->oobsize);
- }
-
- /* Pick the ECC bytes out of the oob data */
- for (j = 0; j < 6; j++) {
- ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
- }
-
- /* Calculate the ECC and verify it */
- /* If block was not written with ECC, skip ECC */
- if (oob_config.eccvalid_pos != -1 &&
- (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
-
- nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
- switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
- case -1:
- printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
- ecc_failed++;
- break;
- case 1:
- case 2: /* transfer ECC corrected data to cache */
- if (nand->data_cache)
- memcpy (nand->data_cache, nand->data_buf, 256);
- break;
- }
- }
-
- if (oob_config.eccvalid_pos != -1 &&
- nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
-
- nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
- switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
- case -1:
- printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
- ecc_failed++;
- break;
- case 1:
- case 2: /* transfer ECC corrected data to cache */
- if (nand->data_cache)
- memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
- break;
- }
- }
-readdata:
- /* Read the data from ECC data buffer into return buffer */
- data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
- data_poi += col;
- if ((*retlen + (nand->oobblock - col)) >= len) {
- memcpy (buf + *retlen, data_poi, len - *retlen);
- *retlen = len;
- } else {
- memcpy (buf + *retlen, data_poi, nand->oobblock - col);
- *retlen += nand->oobblock - col;
- }
- /* Set cache page address, invalidate, if ecc_failed */
- nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
-
- ecc_status += ecc_failed;
- ecc_failed = 0;
-
-#else
- /* Send the read command */
- NanD_Command(nand, NAND_CMD_READ0);
- if (nand->bus16) {
- NanD_Address(nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + (col >> 1));
- } else {
- NanD_Address(nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + col);
- }
-
- /* Read the data directly into the return buffer */
- if ((*retlen + (nand->oobblock - col)) >= len) {
- NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
- *retlen = len;
- /* We're done */
- continue;
- } else {
- NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
- *retlen += nand->oobblock - col;
- }
-#endif
- /* For subsequent reads align to page boundary. */
- col = 0;
- /* Increment page address */
- page++;
- }
-
- /* De-select the NAND device */
- NAND_DISABLE_CE(nand); /* set pin high */
-
- /*
- * Return success, if no ECC failures, else -EIO
- * fs driver will take care of that, because
- * retlen == desired len and result == -EIO
- */
- return ecc_status ? -1 : 0;
-}
-
-/*
- * Nand_page_program function is used for write and writev !
- */
-static int nand_write_page (struct nand_chip *nand,
- int page, int col, int last, u_char * ecc_code)
-{
-
- int i;
- unsigned long nandptr = nand->IO_ADDR;
-
-#ifdef CONFIG_MTD_NAND_ECC
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
- int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
-#endif
-#endif
- /* pad oob area */
- for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
- nand->data_buf[i] = 0xff;
-
-#ifdef CONFIG_MTD_NAND_ECC
- /* Zero out the ECC array */
- for (i = 0; i < 6; i++)
- ecc_code[i] = 0x00;
-
- /* Read back previous written data, if col > 0 */
- if (col) {
- NanD_Command (nand, NAND_CMD_READ0);
- if (nand->bus16) {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + (col >> 1));
- } else {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + col);
- }
-
- if (nand->bus16) {
- u16 val;
-
- for (i = 0; i < col; i += 2) {
- val = READ_NAND (nandptr);
- nand->data_buf[i] = val & 0xff;
- nand->data_buf[i + 1] = val >> 8;
- }
- } else {
- for (i = 0; i < col; i++)
- nand->data_buf[i] = READ_NAND (nandptr);
- }
- }
-
- /* Calculate and write the ECC if we have enough data */
- if ((col < nand->eccsize) && (last >= nand->eccsize)) {
- nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
- for (i = 0; i < 3; i++) {
- nand->data_buf[(nand->oobblock +
- oob_config.ecc_pos[i])] = ecc_code[i];
- }
- if (oob_config.eccvalid_pos != -1) {
- nand->data_buf[nand->oobblock +
- oob_config.eccvalid_pos] = 0xf0;
- }
- }
-
- /* Calculate and write the second ECC if we have enough data */
- if ((nand->oobblock == 512) && (last == nand->oobblock)) {
- nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
- for (i = 3; i < 6; i++) {
- nand->data_buf[(nand->oobblock +
- oob_config.ecc_pos[i])] = ecc_code[i];
- }
- if (oob_config.eccvalid_pos != -1) {
- nand->data_buf[nand->oobblock +
- oob_config.eccvalid_pos] &= 0x0f;
- }
- }
-#endif
- /* Prepad for partial page programming !!! */
- for (i = 0; i < col; i++)
- nand->data_buf[i] = 0xff;
-
- /* Postpad for partial page programming !!! oob is already padded */
- for (i = last; i < nand->oobblock; i++)
- nand->data_buf[i] = 0xff;
-
- /* Send command to begin auto page programming */
- NanD_Command (nand, NAND_CMD_READ0);
- NanD_Command (nand, NAND_CMD_SEQIN);
- if (nand->bus16) {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + (col >> 1));
- } else {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + col);
- }
-
- /* Write out complete page of data */
- if (nand->bus16) {
- for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) {
- WRITE_NAND (nand->data_buf[i] +
- (nand->data_buf[i + 1] << 8),
- nand->IO_ADDR);
- }
- } else {
- for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
- WRITE_NAND (nand->data_buf[i], nand->IO_ADDR);
- }
-
- /* Send command to actually program the data */
- NanD_Command (nand, NAND_CMD_PAGEPROG);
- NanD_Command (nand, NAND_CMD_STATUS);
-#ifdef NAND_NO_RB
- {
- u_char ret_val;
-
- do {
- ret_val = READ_NAND (nandptr); /* wait till ready */
- } while ((ret_val & 0x40) != 0x40);
- }
-#endif
- /* See if device thinks it succeeded */
- if (READ_NAND (nand->IO_ADDR) & 0x01) {
- printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__,
- page);
- return -1;
- }
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
- /*
- * The NAND device assumes that it is always writing to
- * a cleanly erased page. Hence, it performs its internal
- * write verification only on bits that transitioned from
- * 1 to 0. The device does NOT verify the whole page on a
- * byte by byte basis. It is possible that the page was
- * not completely erased or the page is becoming unusable
- * due to wear. The read with ECC would catch the error
- * later when the ECC page check fails, but we would rather
- * catch it early in the page write stage. Better to write
- * no data than invalid data.
- */
-
- /* Send command to read back the page */
- if (col < nand->eccsize)
- NanD_Command (nand, NAND_CMD_READ0);
- else
- NanD_Command (nand, NAND_CMD_READ1);
- if (nand->bus16) {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + (col >> 1));
- } else {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + col);
- }
-
- /* Loop through and verify the data */
- if (nand->bus16) {
- for (i = col; i < last; i = +2) {
- if ((nand->data_buf[i] +
- (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) {
- printf ("%s: Failed write verify, page 0x%08x ",
- __FUNCTION__, page);
- return -1;
- }
- }
- } else {
- for (i = col; i < last; i++) {
- if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) {
- printf ("%s: Failed write verify, page 0x%08x ",
- __FUNCTION__, page);
- return -1;
- }
- }
- }
-
-#ifdef CONFIG_MTD_NAND_ECC
- /*
- * We also want to check that the ECC bytes wrote
- * correctly for the same reasons stated above.
- */
- NanD_Command (nand, NAND_CMD_READOOB);
- if (nand->bus16) {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + (col >> 1));
- } else {
- NanD_Address (nand, ADDR_COLUMN_PAGE,
- (page << nand->page_shift) + col);
- }
- if (nand->bus16) {
- for (i = 0; i < nand->oobsize; i += 2) {
- u16 val;
-
- val = READ_NAND (nand->IO_ADDR);
- nand->data_buf[i] = val & 0xff;
- nand->data_buf[i + 1] = val >> 8;
- }
- } else {
- for (i = 0; i < nand->oobsize; i++) {
- nand->data_buf[i] = READ_NAND (nand->IO_ADDR);
- }
- }
- for (i = 0; i < ecc_bytes; i++) {
- if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
- printf ("%s: Failed ECC write "
- "verify, page 0x%08x, "
- "%6i bytes were succesful\n",
- __FUNCTION__, page, i);
- return -1;
- }
- }
-#endif /* CONFIG_MTD_NAND_ECC */
-#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */
- return 0;
-}
-
-static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
- size_t * retlen, const u_char * buf, u_char * ecc_code)
-{
- int i, page, col, cnt, ret = 0;
-
- /* Do not allow write past end of device */
- if ((to + len) > nand->totlen) {
- printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
- return -1;
- }
-
- /* Shift to get page */
- page = ((int) to) >> nand->page_shift;
-
- /* Get the starting column */
- col = to & (nand->oobblock - 1);
-
- /* Initialize return length value */
- *retlen = 0;
-
- /* Select the NAND device */
-#ifdef CONFIG_OMAP1510
- archflashwp(0,0);
-#endif
-#ifdef CFG_NAND_WP
- NAND_WP_OFF();
-#endif
-
- NAND_ENABLE_CE(nand); /* set pin low */
-
- /* Check the WP bit */
- NanD_Command(nand, NAND_CMD_STATUS);
- if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
- printf ("%s: Device is write protected!!!\n", __FUNCTION__);
- ret = -1;
- goto out;
- }
-
- /* Loop until all data is written */
- while (*retlen < len) {
- /* Invalidate cache, if we write to this page */
- if (nand->cache_page == page)
- nand->cache_page = -1;
-
- /* Write data into buffer */
- if ((col + len) >= nand->oobblock) {
- for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) {
- nand->data_buf[i] = buf[(*retlen + cnt)];
- }
- } else {
- for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) {
- nand->data_buf[i] = buf[(*retlen + cnt)];
- }
- }
- /* We use the same function for write and writev !) */
- ret = nand_write_page (nand, page, col, i, ecc_code);
- if (ret)
- goto out;
-
- /* Next data start at page boundary */
- col = 0;
-
- /* Update written bytes count */
- *retlen += cnt;
-
- /* Increment page address */
- page++;
- }
-
- /* Return happy */
- *retlen = len;
-
-out:
- /* De-select the NAND device */
- NAND_DISABLE_CE(nand); /* set pin high */
-#ifdef CONFIG_OMAP1510
- archflashwp(0,1);
-#endif
-#ifdef CFG_NAND_WP
- NAND_WP_ON();
-#endif
-
- return ret;
-}
-
-/* read from the 16 bytes of oob data that correspond to a 512 byte
- * page or 2 256-byte pages.
- */
-static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
- size_t * retlen, u_char * buf)
-{
- int len256 = 0;
- struct Nand *mychip;
- int ret = 0;
-
- mychip = &nand->chips[ofs >> nand->chipshift];
-
- /* update address for 2M x 8bit devices. OOB starts on the second */
- /* page to maintain compatibility with nand_read_ecc. */
- if (nand->page256) {
- if (!(ofs & 0x8))
- ofs += 0x100;
- else
- ofs -= 0x8;
- }
-
- NAND_ENABLE_CE(nand); /* set pin low */
- NanD_Command(nand, NAND_CMD_READOOB);
- if (nand->bus16) {
- NanD_Address(nand, ADDR_COLUMN_PAGE,
- ((ofs >> nand->page_shift) << nand->page_shift) +
- ((ofs & (nand->oobblock - 1)) >> 1));
- } else {
- NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
- }
-
- /* treat crossing 8-byte OOB data for 2M x 8bit devices */
- /* Note: datasheet says it should automaticaly wrap to the */
- /* next OOB block, but it didn't work here. mf. */
- if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
- len256 = (ofs | 0x7) + 1 - ofs;
- NanD_ReadBuf(nand, buf, len256);
-
- NanD_Command(nand, NAND_CMD_READOOB);
- NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
- }
-
- NanD_ReadBuf(nand, &buf[len256], len - len256);
-
- *retlen = len;
- /* Reading the full OOB data drops us off of the end of the page,
- * causing the flash device to go into busy mode, so we need
- * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
-
- ret = NanD_WaitReady(nand, 1);
- NAND_DISABLE_CE(nand); /* set pin high */
-
- return ret;
-
-}
-
-/* write to the 16 bytes of oob data that correspond to a 512 byte
- * page or 2 256-byte pages.
- */
-static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
- size_t * retlen, const u_char * buf)
-{
- int len256 = 0;
- int i;
- unsigned long nandptr = nand->IO_ADDR;
-
-#ifdef PSYCHO_DEBUG
- printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
- (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
- buf[8], buf[9], buf[14],buf[15]);
-#endif
-
- NAND_ENABLE_CE(nand); /* set pin low to enable chip */
-
- /* Reset the chip */
- NanD_Command(nand, NAND_CMD_RESET);
-
- /* issue the Read2 command to set the pointer to the Spare Data Area. */
- NanD_Command(nand, NAND_CMD_READOOB);
- if (nand->bus16) {
- NanD_Address(nand, ADDR_COLUMN_PAGE,
- ((ofs >> nand->page_shift) << nand->page_shift) +
- ((ofs & (nand->oobblock - 1)) >> 1));
- } else {
- NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
- }
-
- /* update address for 2M x 8bit devices. OOB starts on the second */
- /* page to maintain compatibility with nand_read_ecc. */
- if (nand->page256) {
- if (!(ofs & 0x8))
- ofs += 0x100;
- else
- ofs -= 0x8;
- }
-
- /* issue the Serial Data In command to initial the Page Program process */
- NanD_Command(nand, NAND_CMD_SEQIN);
- if (nand->bus16) {
- NanD_Address(nand, ADDR_COLUMN_PAGE,
- ((ofs >> nand->page_shift) << nand->page_shift) +
- ((ofs & (nand->oobblock - 1)) >> 1));
- } else {
- NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
- }
-
- /* treat crossing 8-byte OOB data for 2M x 8bit devices */
- /* Note: datasheet says it should automaticaly wrap to the */
- /* next OOB block, but it didn't work here. mf. */
- if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
- len256 = (ofs | 0x7) + 1 - ofs;
- for (i = 0; i < len256; i++)
- WRITE_NAND(buf[i], nandptr);
-
- NanD_Command(nand, NAND_CMD_PAGEPROG);
- NanD_Command(nand, NAND_CMD_STATUS);
-#ifdef NAND_NO_RB
- { u_char ret_val;
- do {
- ret_val = READ_NAND(nandptr); /* wait till ready */
- } while ((ret_val & 0x40) != 0x40);
- }
-#endif
- if (READ_NAND(nandptr) & 1) {
- puts ("Error programming oob data\n");
- /* There was an error */
- NAND_DISABLE_CE(nand); /* set pin high */
- *retlen = 0;
- return -1;
- }
- NanD_Command(nand, NAND_CMD_SEQIN);
- NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
- }
-
- if (nand->bus16) {
- for (i = len256; i < len; i += 2) {
- WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr);
- }
- } else {
- for (i = len256; i < len; i++)
- WRITE_NAND(buf[i], nandptr);
- }
-
- NanD_Command(nand, NAND_CMD_PAGEPROG);
- NanD_Command(nand, NAND_CMD_STATUS);
-#ifdef NAND_NO_RB
- { u_char ret_val;
- do {
- ret_val = READ_NAND(nandptr); /* wait till ready */
- } while ((ret_val & 0x40) != 0x40);
- }
-#endif
- if (READ_NAND(nandptr) & 1) {
- puts ("Error programming oob data\n");
- /* There was an error */
- NAND_DISABLE_CE(nand); /* set pin high */
- *retlen = 0;
- return -1;
- }
-
- NAND_DISABLE_CE(nand); /* set pin high */
- *retlen = len;
- return 0;
-
-}
-
-int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
-{
- /* This is defined as a structure so it will work on any system
- * using native endian jffs2 (the default).
- */
- static struct jffs2_unknown_node clean_marker = {
- JFFS2_MAGIC_BITMASK,
- JFFS2_NODETYPE_CLEANMARKER,
- 8 /* 8 bytes in this node */
- };
- unsigned long nandptr;
- struct Nand *mychip;
- int ret = 0;
-
- if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
- printf ("Offset and size must be sector aligned, erasesize = %d\n",
- (int) nand->erasesize);
- return -1;
- }
-
- nandptr = nand->IO_ADDR;
-
- /* Select the NAND device */
-#ifdef CONFIG_OMAP1510
- archflashwp(0,0);
-#endif
-#ifdef CFG_NAND_WP
- NAND_WP_OFF();
-#endif
- NAND_ENABLE_CE(nand); /* set pin low */
-
- /* Check the WP bit */
- NanD_Command(nand, NAND_CMD_STATUS);
- if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
- printf ("nand_write_ecc: Device is write protected!!!\n");
- ret = -1;
- goto out;
- }
-
- /* Check the WP bit */
- NanD_Command(nand, NAND_CMD_STATUS);
- if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
- printf ("%s: Device is write protected!!!\n", __FUNCTION__);
- ret = -1;
- goto out;
- }
-
- /* FIXME: Do nand in the background. Use timers or schedule_task() */
- while(len) {
- /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
- mychip = &nand->chips[ofs >> nand->chipshift];
-
- /* always check for bad block first, genuine bad blocks
- * should _never_ be erased.
- */
- if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
- /* Select the NAND device */
- NAND_ENABLE_CE(nand); /* set pin low */
-
- NanD_Command(nand, NAND_CMD_ERASE1);
- NanD_Address(nand, ADDR_PAGE, ofs);
- NanD_Command(nand, NAND_CMD_ERASE2);
-
- NanD_Command(nand, NAND_CMD_STATUS);
-
-#ifdef NAND_NO_RB
- { u_char ret_val;
- do {
- ret_val = READ_NAND(nandptr); /* wait till ready */
- } while ((ret_val & 0x40) != 0x40);
- }
-#endif
- if (READ_NAND(nandptr) & 1) {
- printf ("%s: Error erasing at 0x%lx\n",
- __FUNCTION__, (long)ofs);
- /* There was an error */
- ret = -1;
- goto out;
- }
- if (clean) {
- int n; /* return value not used */
- int p, l;
-
- /* clean marker position and size depend
- * on the page size, since 256 byte pages
- * only have 8 bytes of oob data
- */
- if (nand->page256) {
- p = NAND_JFFS2_OOB8_FSDAPOS;
- l = NAND_JFFS2_OOB8_FSDALEN;
- } else {
- p = NAND_JFFS2_OOB16_FSDAPOS;
- l = NAND_JFFS2_OOB16_FSDALEN;
- }
-
- ret = nand_write_oob(nand, ofs + p, l, (size_t *)&n,
- (u_char *)&clean_marker);
- /* quit here if write failed */
- if (ret)
- goto out;
- }
- }
- ofs += nand->erasesize;
- len -= nand->erasesize;
- }
-
-out:
- /* De-select the NAND device */
- NAND_DISABLE_CE(nand); /* set pin high */
-#ifdef CONFIG_OMAP1510
- archflashwp(0,1);
-#endif
-#ifdef CFG_NAND_WP
- NAND_WP_ON();
-#endif
-
- return ret;
-}
-
-static inline int nandcheck(unsigned long potential, unsigned long physadr)
-{
- return 0;
-}
-
-unsigned long nand_probe(unsigned long physadr)
-{
- struct nand_chip *nand = NULL;
- int i = 0, ChipID = 1;
-
-#ifdef CONFIG_MTD_NAND_ECC_JFFS2
- oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
- oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
- oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
- oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
- oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
- oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
- oob_config.eccvalid_pos = 4;
-#else
- oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
- oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
- oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
- oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
- oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
- oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
- oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
-#endif
- oob_config.badblock_pos = 5;
-
- for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
- if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
- nand = &nand_dev_desc[i];
- break;
- }
- }
- if (!nand)
- return (0);
-
- memset((char *)nand, 0, sizeof(struct nand_chip));
-
- nand->IO_ADDR = physadr;
- nand->cache_page = -1; /* init the cache page */
- NanD_ScanChips(nand);
-
- if (nand->totlen == 0) {
- /* no chips found, clean up and quit */
- memset((char *)nand, 0, sizeof(struct nand_chip));
- nand->ChipID = NAND_ChipID_UNKNOWN;
- return (0);
- }
-
- nand->ChipID = ChipID;
- if (curr_device == -1)
- curr_device = i;
-
- nand->data_buf = malloc (nand->oobblock + nand->oobsize);
- if (!nand->data_buf) {
- puts ("Cannot allocate memory for data structures.\n");
- return (0);
- }
-
- return (nand->totlen);
-}
-
-#ifdef CONFIG_MTD_NAND_ECC
-/*
- * Pre-calculated 256-way 1 byte column parity
- */
-static const u_char nand_ecc_precalc_table[] = {
- 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
- 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
- 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
- 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
- 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
- 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
- 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
- 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
- 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
- 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
- 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
- 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
- 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
- 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
- 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
- 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
- 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
- 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
- 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
- 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
- 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
- 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
- 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
- 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
- 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
- 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
- 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
- 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
- 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
- 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
- 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
- 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
-};
-
-
-/*
- * Creates non-inverted ECC code from line parity
- */
-static void nand_trans_result(u_char reg2, u_char reg3,
- u_char *ecc_code)
-{
- u_char a, b, i, tmp1, tmp2;
-
- /* Initialize variables */
- a = b = 0x80;
- tmp1 = tmp2 = 0;
-
- /* Calculate first ECC byte */
- for (i = 0; i < 4; i++) {
- if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
- tmp1 |= b;
- b >>= 1;
- if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
- tmp1 |= b;
- b >>= 1;
- a >>= 1;
- }
-
- /* Calculate second ECC byte */
- b = 0x80;
- for (i = 0; i < 4; i++) {
- if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
- tmp2 |= b;
- b >>= 1;
- if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
- tmp2 |= b;
- b >>= 1;
- a >>= 1;
- }
-
- /* Store two of the ECC bytes */
- ecc_code[0] = tmp1;
- ecc_code[1] = tmp2;
-}
-
-/*
- * Calculate 3 byte ECC code for 256 byte block
- */
-static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
-{
- u_char idx, reg1, reg3;
- int j;
-
- /* Initialize variables */
- reg1 = reg3 = 0;
- ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
-
- /* Build up column parity */
- for(j = 0; j < 256; j++) {
-
- /* Get CP0 - CP5 from table */
- idx = nand_ecc_precalc_table[dat[j]];
- reg1 ^= idx;
-
- /* All bit XOR = 1 ? */
- if (idx & 0x40) {
- reg3 ^= (u_char) j;
- }
- }
-
- /* Create non-inverted ECC code from line parity */
- nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
-
- /* Calculate final ECC code */
- ecc_code[0] = ~ecc_code[0];
- ecc_code[1] = ~ecc_code[1];
- ecc_code[2] = ((~reg1) << 2) | 0x03;
-}
-
-/*
- * Detect and correct a 1 bit error for 256 byte block
- */
-static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
-{
- u_char a, b, c, d1, d2, d3, add, bit, i;
-
- /* Do error detection */
- d1 = calc_ecc[0] ^ read_ecc[0];
- d2 = calc_ecc[1] ^ read_ecc[1];
- d3 = calc_ecc[2] ^ read_ecc[2];
-
- if ((d1 | d2 | d3) == 0) {
- /* No errors */
- return 0;
- } else {
- a = (d1 ^ (d1 >> 1)) & 0x55;
- b = (d2 ^ (d2 >> 1)) & 0x55;
- c = (d3 ^ (d3 >> 1)) & 0x54;
-
- /* Found and will correct single bit error in the data */
- if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
- c = 0x80;
- add = 0;
- a = 0x80;
- for (i=0; i<4; i++) {
- if (d1 & c)
- add |= a;
- c >>= 2;
- a >>= 1;
- }
- c = 0x80;
- for (i=0; i<4; i++) {
- if (d2 & c)
- add |= a;
- c >>= 2;
- a >>= 1;
- }
- bit = 0;
- b = 0x04;
- c = 0x80;
- for (i=0; i<3; i++) {
- if (d3 & c)
- bit |= b;
- c >>= 2;
- b >>= 1;
- }
- b = 0x01;
- a = dat[add];
- a ^= (b << bit);
- dat[add] = a;
- return 1;
- }
- else {
- i = 0;
- while (d1) {
- if (d1 & 0x01)
- ++i;
- d1 >>= 1;
- }
- while (d2) {
- if (d2 & 0x01)
- ++i;
- d2 >>= 1;
- }
- while (d3) {
- if (d3 & 0x01)
- ++i;
- d3 >>= 1;
- }
- if (i == 1) {
- /* ECC Code Error Correction */
- read_ecc[0] = calc_ecc[0];
- read_ecc[1] = calc_ecc[1];
- read_ecc[2] = calc_ecc[2];
- return 2;
- }
- else {
- /* Uncorrectable Error */
- return -1;
- }
- }
- }
-
- /* Should never happen */
- return -1;
-}
-
-#endif
-
-#ifdef CONFIG_JFFS2_NAND
-
-int read_jffs2_nand(size_t start, size_t len,
- size_t * retlen, u_char * buf, int nanddev)
-{
- return nand_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2,
- start, len, retlen, buf);
-}
-
-#endif /* CONFIG_JFFS2_NAND */
-
-
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
+
+#endif /* CFG_NAND_LEGACY */
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 1babffec2e0..6257fbd23e6 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -50,6 +50,8 @@
#include <net.h>
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
#if !defined(CFG_ENV_IS_IN_NVRAM) && \
!defined(CFG_ENV_IS_IN_EEPROM) && \
!defined(CFG_ENV_IS_IN_FLASH) && \
@@ -152,8 +154,6 @@ int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int _do_setenv (int flag, int argc, char *argv[])
{
- DECLARE_GLOBAL_DATA_PTR;
-
int i, len, oldval;
int console = -1;
uchar *env, *nxt = NULL;
@@ -532,7 +532,9 @@ int getenv_r (char *name, char *buf, unsigned len)
#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
- (CFG_CMD_ENV|CFG_CMD_FLASH))
+ (CFG_CMD_ENV|CFG_CMD_FLASH)) || \
+ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == \
+ (CFG_CMD_ENV|CFG_CMD_NAND))
int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
extern char * env_name_spec;
@@ -588,7 +590,9 @@ U_BOOT_CMD(
#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
- (CFG_CMD_ENV|CFG_CMD_FLASH))
+ (CFG_CMD_ENV|CFG_CMD_FLASH)) || \
+ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == \
+ (CFG_CMD_ENV|CFG_CMD_NAND))
U_BOOT_CMD(
saveenv, 1, 0, do_saveenv,
"saveenv - save environment variables to persistent storage\n",
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
new file mode 100644
index 00000000000..08cb054430a
--- /dev/null
+++ b/common/cmd_onenand.c
@@ -0,0 +1,194 @@
+/*
+ * U-Boot command for OneNAND support
+ *
+ * Copyright (C) 2005 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <command.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_ONENAND)
+
+#include <linux/mtd/onenand.h>
+
+extern struct mtd_info onenand_mtd;
+extern struct onenand_chip onenand_chip;
+
+int do_onenand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int ret = 0;
+
+ switch (argc) {
+ case 0:
+ case 1:
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+
+ case 2:
+ onenand_print_device_info(onenand_chip.device_id, 1);
+ return 0;
+
+ default:
+ /* At least 4 args */
+ if (strncmp(argv[1], "erase", 5) == 0) {
+ struct erase_info instr;
+ ulong start, end;
+ char *endtail;
+ ulong block;
+
+ if (strncmp(argv[2], "block", 5) == 0) {
+ start = simple_strtoul(argv[3], NULL, 10);
+ endtail = strchr(argv[3], '-');
+ end = simple_strtoul(endtail+1, NULL, 10);
+ } else {
+ start = simple_strtoul(argv[2], NULL, 10);
+ end = simple_strtoul(argv[3], NULL, 10);
+ start -= (unsigned long) onenand_chip.base;
+ end -= (unsigned long) onenand_chip.base;
+ }
+
+ if (!end || end < 0)
+ end = start;
+
+ printf("Erase block from %d to %d\n", start, end);
+
+ for (block = start; block <= end; block++) {
+ instr.addr = block << onenand_chip.erase_shift;
+ instr.len = 1 << onenand_chip.erase_shift;
+ ret = onenand_erase(&onenand_mtd, &instr);
+ if (ret) {
+ printf("erase failed %d\n", block);
+ break;
+ }
+ }
+
+ return 0;
+ }
+
+ if (strncmp(argv[1], "read", 4) == 0) {
+ ulong addr = simple_strtoul(argv[2], NULL, 16);
+ ulong ofs = simple_strtoul(argv[3], NULL, 16);
+ size_t len = simple_strtoul(argv[4], NULL, 16);
+ size_t retlen = 0;
+ int oob = strncmp(argv[1], "read.oob", 8) ? 0 : 1;
+
+
+ if (oob)
+ onenand_read_oob(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
+ else
+ onenand_read(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
+ printf("Done\n");
+
+ return 0;
+ }
+
+ if (strncmp(argv[1], "write", 5) == 0) {
+ int ret ;
+ ulong addr = simple_strtoul(argv[2], NULL, 16);
+ ulong ofs = simple_strtoul(argv[3], NULL, 16);
+ size_t len = simple_strtoul(argv[4], NULL, 16);
+ size_t retlen = 0;
+
+ printf("onenadwrite: addr = 0x%x, ofs = 0x%x, len = 0x%x\n", addr, ofs, len);
+ ret = onenand_write(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
+ if (ret)
+ printf("Error writing oneNAND: ret = %d\n", ret);
+ else
+ printf("Done. ret = %d\n", ret);
+
+ return 0;
+ }
+
+ if (strncmp(argv[1], "block", 5) == 0) {
+ ulong addr = simple_strtoul(argv[2], NULL, 16);
+ ulong block = simple_strtoul(argv[3], NULL, 10);
+ ulong page = simple_strtoul(argv[4], NULL, 10);
+ size_t len = simple_strtol(argv[5], NULL, 10);
+ size_t retlen = 0;
+ ulong ofs;
+ int oob = strncmp(argv[1], "block.oob", 9) ? 0 : 1;
+
+ ofs = block << onenand_chip.erase_shift;
+ if (page)
+ ofs += page << onenand_chip.page_shift;
+
+ if (!len) {
+ if (oob)
+ len = 64;
+ else
+ len = 512;
+ }
+
+ if (oob)
+ onenand_read_oob(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
+ else
+ onenand_read(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
+ return 0;
+ }
+
+ if (strncmp(argv[1], "unlock", 6) == 0) {
+ ulong start = simple_strtoul(argv[2], NULL, 10);
+ ulong ofs = simple_strtoul(argv[3], NULL, 10);
+
+ if (!ofs)
+ ofs = (1 << onenand_chip.erase_shift);
+
+ start = start << onenand_chip.erase_shift;
+ printf("start = 0x%08x, ofs = 0x%08x\n",
+ start, ofs);
+ onenand_unlock(&onenand_mtd, start, start + ofs);
+
+ return 0;
+ }
+
+ if (strncmp(argv[1], "save", 4) == 0 &&
+ strncmp(argv[2], "bootloader", 10) == 0) {
+ ulong addr = simple_strtoul(argv[3], NULL, 16);
+ struct erase_info instr;
+ int ofs = 0;
+ int len = 0x20000;
+ size_t retlen;
+
+ printf("save bootloader...\n");
+
+ if (!addr)
+ break;
+
+ onenand_unlock(&onenand_mtd, ofs, len);
+
+ instr.addr = 0 << onenand_chip.erase_shift;
+ instr.len = 1 << onenand_chip.erase_shift;
+ onenand_erase(&onenand_mtd, &instr);
+
+ onenand_write(&onenand_mtd, ofs, len, &retlen, (u_char *) addr);
+ onenand_unlock(&onenand_mtd, CFG_ENV_ADDR, onenand_mtd.size - CFG_ENV_ADDR);
+ return 0;
+ }
+
+ break;
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ onenand, 6, 1, do_onenand,
+ "onenand - OneNAND sub-system\n",
+ "info - show available OneNAND devices\n"
+ "onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
+ "onenand write addr ofs len - write data at ofs with len from addr\n"
+ "onenand erase block start-end - erase block from start to end\n"
+ "onenand erase saddr eaddr - erase block start addr to end addr\n"
+ "onenand block[.oob] addr block [page] [len] - "
+ "read data with (block [, page]) to addr\n"
+ "onenand unlock start-end - unlock block from start to end\n"
+ "onenand save bootloader addr - save bootloader at addr\n"
+);
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_ONENAND) */
+
diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c
index 62446d4efeb..2eb5b26f2c4 100644
--- a/common/cmd_pcmcia.c
+++ b/common/cmd_pcmcia.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000-2004
+ * (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -57,75 +57,14 @@
#include <command.h>
#include <config.h>
#include <pcmcia.h>
-#if defined(CONFIG_8xx)
-#include <mpc8xx.h>
-#endif
-#if defined(CONFIG_LWMON)
-#include <i2c.h>
-#endif
-#ifdef CONFIG_PXA_PCMCIA
-#include <asm/arch/pxa-regs.h>
-#endif
-
#include <asm/io.h>
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
- ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
-
-int pcmcia_on (void);
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int pcmcia_off (void);
-#endif
-
-#ifdef CONFIG_I82365
-
-extern int i82365_init (void);
-extern void i82365_exit (void);
-
-#else /* ! CONFIG_I82365 */
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot);
-#endif
-static int hardware_enable (int slot);
-static int voltage_set(int slot, int vcc, int vpp);
-
-#if (! defined(CONFIG_I82365)) && (! defined(CONFIG_PXA_PCMCIA))
-static u_int m8xx_get_graycode(u_int size);
-#endif /* !CONFIG_I82365, !CONFIG_PXA_PCMCIA */
-#if 0
-static u_int m8xx_get_speed(u_int ns, u_int is_io);
-#endif
-
/* -------------------------------------------------------------------- */
-#ifndef CONFIG_PXA_PCMCIA
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-/* look up table for pgcrx registers */
-
-static u_int *pcmcia_pgcrx[2] = {
- &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
- &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
-};
-#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
-
-#endif /* CONFIG_PXA_PCMCIA */
-
-#endif /* CONFIG_I82365 */
-
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
-static void print_funcid (int func);
-static void print_fixed (volatile uchar *p);
-static int identify (volatile uchar *p);
-static int check_ide_device (int slot);
-#endif /* CONFIG_IDE_8xx_PCCARD, CONFIG_PXA_PCMCIA */
-
-const char *indent = "\t ";
-
-/* -------------------------------------------------------------------- */
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+extern int pcmcia_on (void);
+extern int pcmcia_off (void);
int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
@@ -136,7 +75,7 @@ int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
if (strcmp(argv[1],"on") == 0) {
- rcode = pcmcia_on ();
+ rcode = pcmcia_on ();
} else if (strcmp(argv[1],"off") == 0) {
rcode = pcmcia_off ();
} else {
@@ -146,2478 +85,82 @@ int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return rcode;
}
-#endif /* CFG_CMD_PCMCIA */
-
-/* -------------------------------------------------------------------- */
-#ifdef CONFIG_I82365
-int pcmcia_on (void)
-{
- u_int rc;
-
- debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
-
- rc = i82365_init();
+U_BOOT_CMD(
+ pinit, 2, 1, do_pinit,
+ "pinit - PCMCIA sub-system\n",
+ "on - power on PCMCIA socket\n"
+ "pinit off - power off PCMCIA socket\n"
+ );
- if (rc == 0) {
- rc = check_ide_device(0);
- }
+#endif /* CONFIG_COMMANDS & CFG_CMD_PCMCIA */
- return (rc);
-}
-#else
+/* -------------------------------------------------------------------- */
-#ifndef CONFIG_PXA_PCMCIA
+#undef CHECK_IDE_DEVICE
-#ifdef CONFIG_HMI10
-# define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
+#if (CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
+#define CHECK_IDE_DEVICE
#endif
-#if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
-# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
-#else
-# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
+
+#if defined(CONFIG_PXA_PCMCIA)
+#define CHECK_IDE_DEVICE
#endif
-int pcmcia_on (void)
-{
- int i;
- u_long reg, base;
- pcmcia_win_t *win;
- u_int slotbit;
- u_int rc, slot;
+#ifdef CHECK_IDE_DEVICE
- debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
+int ide_devices_found;
+static uchar *known_cards[] = {
+ (uchar *)"ARGOSY PnPIDE D5",
+ NULL
+};
- /* intialize the fixed memory windows */
- win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
- base = CFG_PCMCIA_MEM_ADDR;
+#define MAX_TUPEL_SZ 512
+#define MAX_FEATURES 4
- if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
- printf ("Cannot set window size to 0x%08x\n",
- CFG_PCMCIA_MEM_SIZE);
- return (1);
- }
+#define MAX_IDENT_CHARS 64
+#define MAX_IDENT_FIELDS 4
- slotbit = PCMCIA_SLOT_x;
- for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
- win->br = base;
+#define indent "\t "
-#if (PCMCIA_SOCKETS_NO == 2)
- if (i == 4) /* Another slot starting from win 4 */
- slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
-#endif
- switch (i) {
-#ifdef CONFIG_IDE_8xx_PCCARD
- case 4:
-#ifdef CONFIG_HMI10
- { /* map FRAM area */
- win->or = ( PCMCIA_BSIZE_256K
- | PCMCIA_PPS_8
- | PCMCIA_PRS_ATTR
- | slotbit
- | PCMCIA_PV
- | HMI10_FRAM_TIMING );
- break;
- }
-#endif
- case 0: { /* map attribute memory */
- win->or = ( PCMCIA_BSIZE_64M
- | PCMCIA_PPS_8
- | PCMCIA_PRS_ATTR
- | slotbit
- | PCMCIA_PV
- | CFG_PCMCIA_TIMING );
+static void print_funcid (int func)
+{
+ puts (indent);
+ switch (func) {
+ case CISTPL_FUNCID_MULTI:
+ puts (" Multi-Function");
break;
- }
- case 5:
- case 1: { /* map I/O window for data reg */
- win->or = ( PCMCIA_BSIZE_1K
- | PCMCIA_PPS_16
- | PCMCIA_PRS_IO
- | slotbit
- | PCMCIA_PV
- | CFG_PCMCIA_TIMING );
+ case CISTPL_FUNCID_MEMORY:
+ puts (" Memory");
break;
- }
- case 6:
- case 2: { /* map I/O window for cmd/ctrl reg block */
- win->or = ( PCMCIA_BSIZE_1K
- | PCMCIA_PPS_8
- | PCMCIA_PRS_IO
- | slotbit
- | PCMCIA_PV
- | CFG_PCMCIA_TIMING );
+ case CISTPL_FUNCID_SERIAL:
+ puts (" Serial Port");
break;
- }
-#endif /* CONFIG_IDE_8xx_PCCARD */
-#ifdef CONFIG_HMI10
- case 3: { /* map I/O window for 4xUART data/ctrl */
- win->br += 0x40000;
- win->or = ( PCMCIA_BSIZE_256K
- | PCMCIA_PPS_8
- | PCMCIA_PRS_IO
- | slotbit
- | PCMCIA_PV
- | CFG_PCMCIA_TIMING );
+ case CISTPL_FUNCID_PARALLEL:
+ puts (" Parallel Port");
break;
- }
-#endif /* CONFIG_HMI10 */
- default: /* set to not valid */
- win->or = 0;
+ case CISTPL_FUNCID_FIXED:
+ puts (" Fixed Disk");
break;
- }
-
- debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
- i, win->br, win->or);
- base += CFG_PCMCIA_MEM_SIZE;
- ++win;
- }
-
- for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
- /* turn off voltage */
- if ((rc = voltage_set(slot, 0, 0)))
- continue;
-
- /* Enable external hardware */
- if ((rc = hardware_enable(slot)))
- continue;
-
-#ifdef CONFIG_IDE_8xx_PCCARD
- if ((rc = check_ide_device(i)))
- continue;
-#endif
- }
- return (rc);
-}
-
-#endif /* CONFIG_PXA_PCMCIA */
-
-#endif /* CONFIG_I82365 */
-
-#ifdef CONFIG_PXA_PCMCIA
-
-static int hardware_enable (int slot)
-{
- return 0; /* No hardware to enable */
-}
-
-static int hardware_disable(int slot)
-{
- return 0; /* No hardware to disable */
-}
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- return 0;
-}
-
-void msWait(unsigned msVal)
-{
- udelay(msVal*1000);
-}
-
-int pcmcia_on (void)
-{
- unsigned int reg_arr[] = {
- 0x48000028, CFG_MCMEM0_VAL,
- 0x4800002c, CFG_MCMEM1_VAL,
- 0x48000030, CFG_MCATT0_VAL,
- 0x48000034, CFG_MCATT1_VAL,
- 0x48000038, CFG_MCIO0_VAL,
- 0x4800003c, CFG_MCIO1_VAL,
-
- 0, 0
- };
- int i, rc;
-
-#ifdef CONFIG_EXADRON1
- int cardDetect;
- volatile unsigned int *v_pBCRReg =
- (volatile unsigned int *) 0x08000000;
-#endif
-
- debug ("%s\n", __FUNCTION__);
-
- i = 0;
- while (reg_arr[i])
- *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
- udelay (1000);
-
- debug ("%s: programmed mem controller \n", __FUNCTION__);
-
-#ifdef CONFIG_EXADRON1
-
-/*define useful BCR masks */
-#define BCR_CF_INIT_VAL 0x00007230
-#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL 0x00007231
-#define BCR_CF_PWRON_BUSOFF_RESETON_VAL 0x00007233
-#define BCR_CF_PWRON_BUSON_RESETON_VAL 0x00007213
-#define BCR_CF_PWRON_BUSON_RESETOFF_VAL 0x00007211
-
- /* we see from the GPIO bit if the card is present */
- cardDetect = !(GPLR0 & GPIO_bit (14));
-
- if (cardDetect) {
- printf ("No PCMCIA card found!\n");
- }
-
- /* reset the card via the BCR line */
- *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
- msWait (1500);
-
- /* enable address bus */
- GPCR1 = 0x01;
- /* and the first CF slot */
- MECR = 0x00000002;
-
-#endif /* EXADRON 1 */
-
- rc = check_ide_device (0); /* use just slot 0 */
-
- return rc;
-}
-
-#endif /* CONFIG_PXA_PCMCIA */
-
-/* -------------------------------------------------------------------- */
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-
-#ifdef CONFIG_I82365
-static int pcmcia_off (void)
-{
- printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
-
- i82365_exit();
-
- return 0;
-}
-#else
-
-#ifndef CONFIG_PXA_PCMCIA
-
-static int pcmcia_off (void)
-{
- int i;
- pcmcia_win_t *win;
-
- printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
-
- /* clear interrupt state, and disable interrupts */
- ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
- ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
-
- /* turn off interrupt and disable CxOE */
- PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
-
- /* turn off memory windows */
- win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
-
- for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
- /* disable memory window */
- win->or = 0;
- ++win;
- }
-
- /* turn off voltage */
- voltage_set(_slot_, 0, 0);
-
- /* disable external hardware */
- printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
- hardware_disable(_slot_);
- return 0;
-}
-
-#endif /* CONFIG_PXA_PCMCIA */
-
-#endif /* CONFIG_I82365 */
-
-#ifdef CONFIG_PXA_PCMCIA
-static int pcmcia_off (void)
-{
- return 0;
-}
-#endif
-
-#endif /* CFG_CMD_PCMCIA */
-
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
-
-#define MAX_TUPEL_SZ 512
-#define MAX_FEATURES 4
-
-int ide_devices_found;
-static int check_ide_device (int slot)
-{
- volatile uchar *ident = NULL;
- volatile uchar *feature_p[MAX_FEATURES];
- volatile uchar *p, *start, *addr;
- int n_features = 0;
- uchar func_id = ~0;
- uchar code, len;
- ushort config_base = 0;
- int found = 0;
- int i;
-
- addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
- CFG_PCMCIA_MEM_SIZE * (slot * 4));
- debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
-
- start = p = (volatile uchar *) addr;
-
- while ((p - start) < MAX_TUPEL_SZ) {
-
- code = *p; p += 2;
-
- if (code == 0xFF) { /* End of chain */
+ case CISTPL_FUNCID_VIDEO:
+ puts (" Video Adapter");
break;
- }
-
- len = *p; p += 2;
-#if defined(DEBUG) && (DEBUG > 1)
- { volatile uchar *q = p;
- printf ("\nTuple code %02x length %d\n\tData:",
- code, len);
-
- for (i = 0; i < len; ++i) {
- printf (" %02x", *q);
- q+= 2;
- }
- }
-#endif /* DEBUG */
- switch (code) {
- case CISTPL_VERS_1:
- ident = p + 4;
+ case CISTPL_FUNCID_NETWORK:
+ puts (" Network Adapter");
break;
- case CISTPL_FUNCID:
- /* Fix for broken SanDisk which may have 0x80 bit set */
- func_id = *p & 0x7F;
+ case CISTPL_FUNCID_AIMS:
+ puts (" AIMS Card");
break;
- case CISTPL_FUNCE:
- if (n_features < MAX_FEATURES)
- feature_p[n_features++] = p;
+ case CISTPL_FUNCID_SCSI:
+ puts (" SCSI Adapter");
break;
- case CISTPL_CONFIG:
- config_base = (*(p+6) << 8) + (*(p+4));
- debug ("\n## Config_base = %04x ###\n", config_base);
default:
- break;
- }
- p += 2 * len;
- }
-
- found = identify (ident);
-
- if (func_id != ((uchar)~0)) {
- print_funcid (func_id);
-
- if (func_id == CISTPL_FUNCID_FIXED)
- found = 1;
- else
- return (1); /* no disk drive */
- }
-
- for (i=0; i<n_features; ++i) {
- print_fixed (feature_p[i]);
- }
-
- if (!found) {
- printf ("unknown card type\n");
- return (1);
- }
-
- ide_devices_found |= (1 << slot);
-
-#if CONFIG_CPC45
-#else
- /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
- *((uchar *)(addr + config_base)) = 1;
-#endif
-#if 0
- printf("\n## Config_base = %04x ###\n", config_base);
- printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
- printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
- printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
- printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
-#endif
- return (0);
-}
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
-/* -------------------------------------------------------------------- */
-
-
-/* -------------------------------------------------------------------- */
-/* board specific stuff: */
-/* voltage_set(), hardware_enable() and hardware_disable() */
-/* -------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------- */
-/* RPX Boards from Embedded Planet */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
-
-/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
- * SYPCR is write once only, therefore must the slowest memory be faster
- * than the bus monitor or we will get a machine check due to the bus timeout.
- */
-
-#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
-
-#undef PCMCIA_BMT_LIMIT
-#define PCMCIA_BMT_LIMIT (6*8)
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- u_long reg = 0;
-
- switch(vcc) {
- case 0: break;
- case 33: reg |= BCSR1_PCVCTL4; break;
- case 50: reg |= BCSR1_PCVCTL5; break;
- default: return 1;
- }
-
- switch(vpp) {
- case 0: break;
- case 33:
- case 50:
- if(vcc == vpp)
- reg |= BCSR1_PCVCTL6;
- else
- return 1;
- break;
- case 120:
- reg |= BCSR1_PCVCTL7;
- default: return 1;
- }
-
- if(vcc == 120)
- return 1;
-
- /* first, turn off all power */
-
- *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
- | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
-
- /* enable new powersettings */
-
- *((uint *)RPX_CSR_ADDR) |= reg;
-
- return 0;
-}
-
-#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-static int hardware_enable (int slot)
-{
- return 0; /* No hardware to enable */
-}
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- return 0; /* No hardware to disable */
-}
-#endif /* CFG_CMD_PCMCIA */
-#endif /* CONFIG_RPXCLASSIC */
-
-/* -------------------------------------------------------------------- */
-/* (F)ADS Boards from Motorola */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
-
-#ifdef CONFIG_ADS
-#define PCMCIA_BOARD_MSG "ADS"
-#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
-#else
-#define PCMCIA_BOARD_MSG "FADS"
-#endif
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- u_long reg = 0;
-
- switch(vpp) {
- case 0: reg = 0; break;
- case 50: reg = 1; break;
- case 120: reg = 2; break;
- default: return 1;
- }
-
- switch(vcc) {
- case 0: reg = 0; break;
-#ifdef CONFIG_ADS
- case 50: reg = BCSR1_PCCVCCON; break;
-#endif
-#ifdef CONFIG_FADS
- case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
- case 50: reg = BCSR1_PCCVCC1; break;
-#endif
- default: return 1;
- }
-
- /* first, turn off all power */
-
-#ifdef CONFIG_ADS
- *((uint *)BCSR1) |= BCSR1_PCCVCCON;
-#endif
-#ifdef CONFIG_FADS
- *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
-#endif
- *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
-
- /* enable new powersettings */
-
-#ifdef CONFIG_ADS
- *((uint *)BCSR1) &= ~reg;
-#endif
-#ifdef CONFIG_FADS
- *((uint *)BCSR1) |= reg;
-#endif
-
- *((uint *)BCSR1) |= reg << 20;
-
- return 0;
-}
-
-#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-
-static int hardware_enable(int slot)
-{
- *((uint *)BCSR1) &= ~BCSR1_PCCEN;
- return 0;
-}
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- *((uint *)BCSR1) &= ~BCSR1_PCCEN;
- return 0;
-}
-#endif /* CFG_CMD_PCMCIA */
-
-#endif /* (F)ADS */
-
-/* -------------------------------------------------------------------- */
-/* TQM8xxL Boards by TQ Components */
-/* SC8xx Boards by SinoVee Microsystems */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
-
-#if defined(CONFIG_TQM8xxL)
-#define PCMCIA_BOARD_MSG "TQM8xxL"
-#endif
-#if defined(CONFIG_SVM_SC8xx)
-#define PCMCIA_BOARD_MSG "SC8xx"
-#endif
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, mask;
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
- sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(slot);
- pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
-#ifndef NSCU_OE_INV
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
-#endif
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
-#ifndef CONFIG_HMI10
-#ifndef CONFIG_NSCU
- /*
- * Configure Port C pins for
- * 5 Volts Enable and 3 Volts enable
- */
- immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
- immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
- /* remove all power */
-
- immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
-#endif
-#else /* CONFIG_HMI10 */
- /*
- * Configure Port B pins for
- * 5 Volts Enable and 3 Volts enable
- */
- immap->im_cpm.cp_pbpar &= ~(0x00000300);
-
- /* remove all power */
- immap->im_cpm.cp_pbdat |= 0x00000300;
-#endif /* CONFIG_HMI10 */
-
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
-#ifndef CONFIG_HMI10
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
-#else
- if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
-#endif /* CONFIG_HMI10 */
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On.
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- reg = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- reg,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
-#ifndef CONFIG_NSCU
- if ((reg & mask) == mask) {
-#ifndef CONFIG_HMI10
- immap->im_ioport.iop_pcdat |= 0x0004;
-#else
- immap->im_cpm.cp_pbdat &= ~(0x0000100);
-#endif /* CONFIG_HMI10 */
- puts (" 5.0V card found: ");
- } else {
-#ifndef CONFIG_HMI10
- immap->im_ioport.iop_pcdat |= 0x0002;
-#else
- immap->im_cpm.cp_pbdat &= ~(0x0000200);
-#endif /* CONFIG_HMI10 */
- puts (" 3.3V card found: ");
- }
-#ifndef CONFIG_HMI10
- immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
-#else
- immap->im_cpm.cp_pbdir |= 0x00000300;
-#endif /* CONFIG_HMI10 */
-#else
- if ((reg & mask) == mask) {
- puts (" 5.0V card found: ");
- } else {
- puts (" 3.3V card found: ");
- }
-#endif
-#if 0
- /* VCC switch error flag, PCMCIA slot INPACK_ pin */
- cp->cp_pbdir &= ~(0x0020 | 0x0010);
- cp->cp_pbpar &= ~(0x0020 | 0x0010);
- udelay(500000);
-#endif
- udelay(1000);
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
-#ifndef NSCU_OE_INV
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
-#else
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
-#endif
- PCMCIA_PGCRX(slot) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-
-#ifndef CONFIG_HMI10
-#ifndef CONFIG_NSCU
- /* remove all power */
- immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
-#endif
-#else /* CONFIG_HMI10 */
- immap->im_cpm.cp_pbdat |= 0x00000300;
-#endif /* CONFIG_HMI10 */
-
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
-#ifndef NSCU_OE_INV
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
-#endif
- PCMCIA_PGCRX(slot) = reg;
-
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-#ifdef CONFIG_NSCU
-static int voltage_set(int slot, int vcc, int vpp)
-{
- return 0;
-}
-#else
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("voltage_set: "
- PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
-#ifndef NSCU_OE_INV
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
-#else
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
-#endif
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
-#ifndef CONFIG_HMI10
- /*
- * Configure Port C pins for
- * 5 Volts Enable and 3 Volts enable,
- * Turn off all power
- */
- debug ("PCMCIA power OFF\n");
- immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
- immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
- immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
-
- reg = 0;
- switch(vcc) {
- case 0: break;
- case 33: reg |= 0x0002; break;
- case 50: reg |= 0x0004; break;
- default: goto done;
- }
-#else /* CONFIG_HMI10 */
- /*
- * Configure Port B pins for
- * 5 Volts Enable and 3 Volts enable,
- * Turn off all power
- */
- debug ("PCMCIA power OFF\n");
- immap->im_cpm.cp_pbpar &= ~(0x00000300);
- /* remove all power */
-
- immap->im_cpm.cp_pbdat |= 0x00000300;
-
- reg = 0;
- switch(vcc) {
- case 0: break;
- case 33: reg |= 0x00000200; break;
- case 50: reg |= 0x00000100; break;
- default: goto done;
-}
-#endif /* CONFIG_HMI10 */
-
- /* Checking supported voltages */
-
- debug ("PIPR: 0x%x --> %s\n",
- pcmp->pcmc_pipr,
- (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
-#ifndef CONFIG_HMI10
- immap->im_ioport.iop_pcdat |= reg;
- immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
-#else
- immap->im_cpm.cp_pbdat &= !reg;
- immap->im_cpm.cp_pbdir |= 0x00000300;
-#endif /* CONFIG_HMI10 */
- if (reg) {
-#ifndef CONFIG_HMI10
- debug ("PCMCIA powered at %sV\n",
- (reg&0x0004) ? "5.0" : "3.3");
-#else
- debug ("PCMCIA powered at %sV\n",
- (reg&0x00000200) ? "5.0" : "3.3");
-#endif /* CONFIG_HMI10 */
- } else {
- debug ("PCMCIA powered down\n");
- }
-
-done:
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
-#ifndef NSCU_OE_INV
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
-#else
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
-#endif
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
- return (0);
-}
-#endif
-
-#endif /* TQM8xxL */
-
-
-/* -------------------------------------------------------------------- */
-/* LWMON Board */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_LWMON)
-
-#define PCMCIA_BOARD_MSG "LWMON"
-
-/* #define's for MAX1604 Power Switch */
-#define MAX1604_OP_SUS 0x80
-#define MAX1604_VCCBON 0x40
-#define MAX1604_VCC_35 0x20
-#define MAX1604_VCCBHIZ 0x10
-#define MAX1604_VPPBON 0x08
-#define MAX1604_VPPBPBPGM 0x04
-#define MAX1604_VPPBHIZ 0x02
-/* reserved 0x01 */
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, mask;
- uchar val;
-
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- /* Switch on PCMCIA port in PIC register 0x60 */
- reg = pic_read (0x60);
- debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
- reg &= ~0x10;
- /* reg |= 0x08; Vpp not needed */
- pic_write (0x60, reg);
-#ifdef DEBUG
- reg = pic_read (0x60);
- printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
-#endif
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
- sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On.
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- reg = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- reg,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
- if ((reg & mask) == mask) {
- val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
- puts (" 5.0V card found: ");
- } else {
- val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
- puts (" 3.3V card found: ");
- }
-
- /* switch VCC on */
- val |= MAX1604_OP_SUS | MAX1604_VCCBON;
- i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
- i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
-
- udelay(500000);
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
- uchar val;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-
- /* remove all power, put output in high impedance state */
- val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
- i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
- i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
-
- /* Configure PCMCIA General Control Register */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- /* Switch off PCMCIA port in PIC register 0x60 */
- reg = pic_read (0x60);
- debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
- reg |= 0x10;
- reg &= ~0x08;
- pic_write (0x60, reg);
-#ifdef DEBUG
- reg = pic_read (0x60);
- printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
-#endif
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
- uchar val;
-
- debug ("voltage_set: "
- PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Turn off all power (switch to high impedance)
- */
- debug ("PCMCIA power OFF\n");
- val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
- i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
- i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
-
- val = 0;
- switch(vcc) {
- case 0: break;
- case 33: val = MAX1604_VCC_35; break;
- case 50: break;
- default: goto done;
- }
-
- /* Checking supported voltages */
-
- debug ("PIPR: 0x%x --> %s\n",
- pcmp->pcmc_pipr,
- (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
- i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
- if (val) {
- debug ("PCMCIA powered at %sV\n",
- (val & MAX1604_VCC_35) ? "3.3" : "5.0");
- } else {
- debug ("PCMCIA powered down\n");
- }
-
-done:
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
- return (0);
-}
-
-#endif /* LWMON */
-
-/* -------------------------------------------------------------------- */
-/* GTH board by Corelatus AB */
-/* -------------------------------------------------------------------- */
-#if defined(CONFIG_GTH)
-
-#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
-
-static int voltage_set (int slot, int vcc, int vpp)
-{ /* Do nothing */
- return 0;
-}
-
-static int hardware_enable (int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, mask;
-
- debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
-
- immap = (immap_t *) CFG_IMMR;
- sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX (_slot_) = reg;
- udelay (500);
-
- /*
- * Make sure there is a card in the slot,
- * then configure the interface.
- */
- udelay (10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__, __FUNCTION__,
- &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & 0x98000000) {
- printf (" No Card found\n");
- return (1);
- }
-
- mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
- reg = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- reg,
- (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
- (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX (_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX (_slot_) = reg;
-
- udelay (250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return 0;
-}
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- return 0; /* No hardware to disable */
-}
-#endif /* CFG_CMD_PCMCIA */
-#endif /* CONFIG_GTH */
-
-/* -------------------------------------------------------------------- */
-/* ICU862 Boards by Cambridge Broadband Ltd. */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_ICU862)
-
-#define PCMCIA_BOARD_MSG "ICU862"
-
-static void cfg_port_B (void);
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, pipr, mask;
- int i;
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
- cfg_port_B ();
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
- sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- pipr = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- pipr,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
-
- reg = cp->cp_pbdat;
- if ((pipr & mask) == mask) {
- reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
- TPS2205_VCC3); /* 3V off */
- reg &= ~(TPS2205_VCC5); /* 5V on */
- puts (" 5.0V card found: ");
- } else {
- reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
- TPS2205_VCC5); /* 5V off */
- reg &= ~(TPS2205_VCC3); /* 3V on */
- puts (" 3.3V card found: ");
- }
-
- debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
- reg,
- (reg & TPS2205_VCC3) ? "off" : "on",
- (reg & TPS2205_VCC5) ? "off" : "on",
- (reg & TPS2205_VPP_PGM) ? "off" : "on",
- (reg & TPS2205_VPP_VCC) ? "off" : "on" );
-
- cp->cp_pbdat = reg;
-
- /* Wait 500 ms; use this to check for over-current */
- for (i=0; i<5000; ++i) {
- if ((cp->cp_pbdat & TPS2205_OC) == 0) {
- printf (" *** Overcurrent - Safety shutdown ***\n");
- cp->cp_pbdat &= ~(TPS2205_SHDN);
- return (1);
- }
- udelay (100);
- }
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-
- /* Shut down */
- cp->cp_pbdat &= ~(TPS2205_SHDN);
-
- /* Configure PCMCIA General Control Register */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("voltage_set: "
- PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- immap = (immap_t *)CFG_IMMR;
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Configure Port C pins for
- * 5 Volts Enable and 3 Volts enable,
- * Turn all power pins to Hi-Z
- */
- debug ("PCMCIA power OFF\n");
- cfg_port_B (); /* Enables switch, but all in Hi-Z */
-
- reg = cp->cp_pbdat;
-
- switch(vcc) {
- case 0: break; /* Switch off */
- case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
- case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
- default: goto done;
- }
-
- /* Checking supported voltages */
-
- debug ("PIPR: 0x%x --> %s\n",
- pcmp->pcmc_pipr,
- (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
- cp->cp_pbdat = reg;
-
-#ifdef DEBUG
- {
- char *s;
-
- if ((reg & TPS2205_VCC3) == 0) {
- s = "at 3.3V";
- } else if ((reg & TPS2205_VCC5) == 0) {
- s = "at 5.0V";
- } else {
- s = "down";
- }
- printf ("PCMCIA powered %s\n", s);
- }
-#endif
-
-done:
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
- return (0);
-}
-
-static void cfg_port_B (void)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- uint reg;
-
- immap = (immap_t *)CFG_IMMR;
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /*
- * Configure Port B for TPS2205 PC-Card Power-Interface Switch
- *
- * Switch off all voltages, assert shutdown
- */
- reg = cp->cp_pbdat;
- reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
- TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
- TPS2205_SHDN); /* enable switch */
- cp->cp_pbdat = reg;
-
- cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
-
- reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
- cp->cp_pbdir = reg | TPS2205_OUTPUTS;
-
- debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
- cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
-}
-
-#endif /* ICU862 */
-
-
-/* -------------------------------------------------------------------- */
-/* C2MON Boards by TTTech Computertechnik AG */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_C2MON)
-
-#define PCMCIA_BOARD_MSG "C2MON"
-
-static void cfg_ports (void);
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, pipr, mask;
- ushort sreg;
- int i;
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
- cfg_ports ();
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
- sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- pipr = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- pipr,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
-
- sreg = immap->im_ioport.iop_pcdat;
- if ((pipr & mask) == mask) {
- sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
- TPS2211_VCCD1); /* 5V on */
- sreg &= ~(TPS2211_VCCD0); /* 3V off */
- puts (" 5.0V card found: ");
- } else {
- sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
- TPS2211_VCCD0); /* 3V on */
- sreg &= ~(TPS2211_VCCD1); /* 5V off */
- puts (" 3.3V card found: ");
- }
-
- debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
- sreg,
- ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
- (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
- );
-
- immap->im_ioport.iop_pcdat = sreg;
-
- /* Wait 500 ms; use this to check for over-current */
- for (i=0; i<5000; ++i) {
- if ((cp->cp_pbdat & TPS2211_OC) == 0) {
- printf (" *** Overcurrent - Safety shutdown ***\n");
- immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
- return (1);
- }
- udelay (100);
- }
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-
- /* Configure PCMCIA General Control Register */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- /* ALl voltages off / Hi-Z */
- immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
- TPS2211_VCCD0 | TPS2211_VCCD1 );
-
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
- ushort sreg;
-
- debug ("voltage_set: "
- PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- immap = (immap_t *)CFG_IMMR;
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Configure Port C pins for
- * 5 Volts Enable and 3 Volts enable,
- * Turn all power pins to Hi-Z
- */
- debug ("PCMCIA power OFF\n");
- cfg_ports (); /* Enables switch, but all in Hi-Z */
-
- sreg = immap->im_ioport.iop_pcdat;
- sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
-
- switch(vcc) {
- case 0: break; /* Switch off */
- case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
- sreg &= ~TPS2211_VCCD1;
- break;
- case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
- sreg |= TPS2211_VCCD1;
- break;
- default: goto done;
- }
-
- /* Checking supported voltages */
-
- debug ("PIPR: 0x%x --> %s\n",
- pcmp->pcmc_pipr,
- (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
- immap->im_ioport.iop_pcdat = sreg;
-
-#ifdef DEBUG
- {
- char *s;
-
- if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
- s = "at 3.3V";
- } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
- s = "at 5.0V";
- } else {
- s = "down";
- }
- printf ("PCMCIA powered %s\n", s);
- }
-#endif
-
-done:
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
- return (0);
-}
-
-static void cfg_ports (void)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- ushort sreg;
-
- immap = (immap_t *)CFG_IMMR;
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /*
- * Configure Port C for TPS2211 PC-Card Power-Interface Switch
- *
- * Switch off all voltages, assert shutdown
- */
- sreg = immap->im_ioport.iop_pcdat;
- sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
- sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
- immap->im_ioport.iop_pcdat = sreg;
-
- immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
- immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
-
- debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
- immap->im_ioport.iop_pcpar,
- immap->im_ioport.iop_pcdir,
- immap->im_ioport.iop_pcdat);
-
- /*
- * Configure Port B for TPS2211 PC-Card Power-Interface Switch
- *
- * Over-Current Input only
- */
- cp->cp_pbpar &= ~(TPS2211_INPUTS);
- cp->cp_pbdir &= ~(TPS2211_INPUTS);
-
- debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
- cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
-}
-
-#endif /* C2MON */
-
-/* -------------------------------------------------------------------- */
-/* MBX board from Morotola */
-/* -------------------------------------------------------------------- */
-
-#if defined( CONFIG_MBX )
-#include <../board/mbx8xx/csr.h>
-
-/* A lot of this has been taken from the RPX code in this file it works from me.
- I have added the voltage selection for the MBX board. */
-
-/* MBX voltage bit in control register #2 */
-#define CR2_VPP12 ((uchar)0x10)
-#define CR2_VPPVDD ((uchar)0x20)
-#define CR2_VDD5 ((uchar)0x40)
-#define CR2_VDD3 ((uchar)0x80)
-
-#define PCMCIA_BOARD_MSG "MBX860"
-
-static int voltage_set (int slot, int vcc, int vpp)
-{
- uchar reg = 0;
-
- debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
-
- switch (vcc) {
- case 0:
- break;
- case 33:
- reg |= CR2_VDD3;
- break;
- case 50:
- reg |= CR2_VDD5;
- break;
- default:
- return 1;
- }
-
- switch (vpp) {
- case 0:
- break;
- case 33:
- case 50:
- if (vcc == vpp) {
- reg |= CR2_VPPVDD;
- } else {
- return 1;
- }
- break;
- case 120:
- reg |= CR2_VPP12;
- break;
- default:
- return 1;
- }
-
- /* first, turn off all power */
- MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
-
- /* enable new powersettings */
- MBX_CSR2 |= reg;
- debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
-
- return (0);
-}
-
-static int hardware_enable (int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, mask;
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
- 'A' + slot);
-
- udelay (10000);
-
- immap = (immap_t *) CFG_IMMR;
- sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX (_slot_) = reg;
- udelay (500);
-
- /* remove all power */
- voltage_set (slot, 0, 0);
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
-#ifndef CONFIG_HMI10
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
-#else
- if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
-#endif /* CONFIG_HMI10 */
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On.
- */
- mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
- reg = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
- (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
- (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
-
- if ((reg & mask) == mask) {
- voltage_set (_slot_, 50, 0);
- printf (" 5.0V card found: ");
- } else {
- voltage_set (_slot_, 33, 0);
- printf (" 3.3V card found: ");
- }
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX (_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX (_slot_) = reg;
-
- udelay (250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable (int slot)
-{
- return 0; /* No hardware to disable */
-}
-#endif /* CFG_CMD_PCMCIA */
-#endif /* CONFIG_MBX */
-/* -------------------------------------------------------------------- */
-/* R360MPI Board */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_R360MPI)
-
-#define PCMCIA_BOARD_MSG "R360MPI"
-
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, mask;
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
- sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Configure Ports A, B & C pins for
- * 5 Volts Enable and 3 Volts enable
- */
- immap->im_ioport.iop_pcpar &= ~(0x0400);
- immap->im_ioport.iop_pcso &= ~(0x0400);/*
- immap->im_ioport.iop_pcdir |= 0x0400;*/
-
- immap->im_ioport.iop_papar &= ~(0x0200);/*
- immap->im_ioport.iop_padir |= 0x0200;*/
-#if 0
- immap->im_ioport.iop_pbpar &= ~(0xC000);
- immap->im_ioport.iop_pbdir &= ~(0xC000);
-#endif
- /* remove all power */
-
- immap->im_ioport.iop_pcdat |= 0x0400;
- immap->im_ioport.iop_padat |= 0x0200;
-
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On.
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- reg = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- reg,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
- if ((reg & mask) == mask) {
- immap->im_ioport.iop_pcdat &= ~(0x4000);
- puts (" 5.0V card found: ");
- } else {
- immap->im_ioport.iop_padat &= ~(0x0002);
- puts (" 3.3V card found: ");
- }
- immap->im_ioport.iop_pcdir |= 0x0400;
- immap->im_ioport.iop_padir |= 0x0200;
-#if 0
- /* VCC switch error flag, PCMCIA slot INPACK_ pin */
- cp->cp_pbdir &= ~(0x0020 | 0x0010);
- cp->cp_pbpar &= ~(0x0020 | 0x0010);
- udelay(500000);
-#endif
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-
- /* remove all power */
- immap->im_ioport.iop_pcdat |= 0x0400;
- immap->im_ioport.iop_padat |= 0x0200;
-
- /* Configure PCMCIA General Control Register */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("voltage_set: "
- PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Configure Ports A & C pins for
- * 5 Volts Enable and 3 Volts enable,
- * Turn off all power
- */
- debug ("PCMCIA power OFF\n");
- immap->im_ioport.iop_pcpar &= ~(0x0400);
- immap->im_ioport.iop_pcso &= ~(0x0400);/*
- immap->im_ioport.iop_pcdir |= 0x0400;*/
-
- immap->im_ioport.iop_papar &= ~(0x0200);/*
- immap->im_ioport.iop_padir |= 0x0200;*/
-
- immap->im_ioport.iop_pcdat |= 0x0400;
- immap->im_ioport.iop_padat |= 0x0200;
-
- reg = 0;
- switch(vcc) {
- case 0: break;
- case 33: reg |= 0x0200; break;
- case 50: reg |= 0x0400; break;
- default: goto done;
- }
-
- /* Checking supported voltages */
-
- debug ("PIPR: 0x%x --> %s\n",
- pcmp->pcmc_pipr,
- (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
- if (reg & 0x0200)
- immap->im_ioport.iop_pcdat &= !reg;
- if (reg & 0x0400)
- immap->im_ioport.iop_padat &= !reg;
- immap->im_ioport.iop_pcdir |= 0x0200;
- immap->im_ioport.iop_padir |= 0x0400;
- if (reg) {
- debug ("PCMCIA powered at %sV\n",
- (reg&0x0400) ? "5.0" : "3.3");
- } else {
- debug ("PCMCIA powered down\n");
- }
-
-done:
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
- return (0);
-}
-
-#endif /* R360MPI */
-
-/* -------------------------------------------------------------------- */
-/* KUP4K and KUP4X Boards */
-/* -------------------------------------------------------------------- */
-#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
-
-#define PCMCIA_BOARD_MSG "KUP"
-
-#define KUP4K_PCMCIA_B_3V3 (0x00020000)
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, mask;
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
- sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(slot);
- pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(slot) = reg;
- udelay(2500);
-
- /*
- * Configure Port B pins for
- * 3 Volts enable
- */
- if (slot) { /* Slot A is built-in */
- cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
- cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
- /* remove all power */
- cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
- }
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On.
- */
- printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- reg = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- reg,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
- if ((reg & mask) == mask) {
- puts (" 5.0V card found: NOT SUPPORTED !!!\n");
- } else {
- if(slot)
- cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
- puts (" 3.3V card found: ");
- }
-#if 0
- /* VCC switch error flag, PCMCIA slot INPACK_ pin */
- cp->cp_pbdir &= ~(0x0020 | 0x0010);
- cp->cp_pbpar &= ~(0x0020 | 0x0010);
- udelay(500000);
-#endif
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(slot) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /* remove all power */
- if (slot)
- cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
-
- /* Configure PCMCIA General Control Register */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(slot) = reg;
-
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("voltage_set: " \
- PCMCIA_BOARD_MSG \
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- if (!slot) /* Slot A is not configurable */
- return 0;
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
- debug ("PCMCIA power OFF\n");
- /*
- * Configure Port B pins for
- * 3 Volts enable
- */
- cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
- cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
- /* remove all power */
- cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
-
- switch(vcc) {
- case 0: break;
- case 33:
- cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
- debug ("PCMCIA powered at 3.3V\n");
- break;
- case 50:
- debug ("PCMCIA: 5Volt vcc not supported\n");
- break;
- default:
- puts("PCMCIA: vcc not supported");
- break;
- }
- udelay(10000);
- /* Checking supported voltages */
-
- debug ("PIPR: 0x%x --> %s\n",
- pcmp->pcmc_pipr,
- (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
- ? "only 5 V --> NOT SUPPORTED"
- : "can do 3.3V");
-
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
- return (0);
-}
-
-#endif /* KUP4K || KUP4X */
-
-
-/* -------------------------------------------------------------------- */
-/* End of Board Specific Stuff */
-/* -------------------------------------------------------------------- */
-
-
-/* -------------------------------------------------------------------- */
-/* MPC8xx Specific Stuff - should go to MPC8xx directory */
-/* -------------------------------------------------------------------- */
-
-/*
- * Search this table to see if the windowsize is
- * supported...
- */
-
-#define M8XX_SIZES_NO 32
-
-static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
-{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
- 0x00000080, 0x00000040, 0x00000010, 0x00000020,
- 0x00008000, 0x00004000, 0x00001000, 0x00002000,
- 0x00000100, 0x00000200, 0x00000800, 0x00000400,
-
- 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
- 0x00010000, 0x00020000, 0x00080000, 0x00040000,
- 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
-
-
-/* -------------------------------------------------------------------- */
-
-#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
-
-static u_int m8xx_get_graycode(u_int size)
-{
- u_int k;
-
- for (k = 0; k < M8XX_SIZES_NO; k++) {
- if(m8xx_size_to_gray[k] == size)
+ puts (" Unknown");
break;
}
-
- if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
- k = -1;
-
- return k;
-}
-
-#endif /* CONFIG_I82365 */
-
-/* -------------------------------------------------------------------- */
-
-#if 0
-static u_int m8xx_get_speed(u_int ns, u_int is_io)
-{
- u_int reg, clocks, psst, psl, psht;
-
- if(!ns) {
-
- /*
- * We get called with IO maps setup to 0ns
- * if not specified by the user.
- * They should be 255ns.
- */
-
- if(is_io)
- ns = 255;
- else
- ns = 100; /* fast memory if 0 */
- }
-
- /*
- * In PSST, PSL, PSHT fields we tell the controller
- * timing parameters in CLKOUT clock cycles.
- * CLKOUT is the same as GCLK2_50.
- */
-
-/* how we want to adjust the timing - in percent */
-
-#define ADJ 180 /* 80 % longer accesstime - to be sure */
-
- clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
- clocks = (clocks * ADJ) / (100*1000);
-
- if(clocks >= PCMCIA_BMT_LIMIT) {
- DEBUG(0, "Max access time limit reached\n");
- clocks = PCMCIA_BMT_LIMIT-1;
- }
-
- psst = clocks / 7; /* setup time */
- psht = clocks / 7; /* hold time */
- psl = (clocks * 5) / 7; /* strobe length */
-
- psst += clocks - (psst + psht + psl);
-
- reg = psst << 12;
- reg |= psl << 7;
- reg |= psht << 16;
-
- return reg;
-}
-#endif
-
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
-static void print_funcid (int func)
-{
- puts (indent);
- switch (func) {
- case CISTPL_FUNCID_MULTI:
- puts (" Multi-Function");
- break;
- case CISTPL_FUNCID_MEMORY:
- puts (" Memory");
- break;
- case CISTPL_FUNCID_SERIAL:
- puts (" Serial Port");
- break;
- case CISTPL_FUNCID_PARALLEL:
- puts (" Parallel Port");
- break;
- case CISTPL_FUNCID_FIXED:
- puts (" Fixed Disk");
- break;
- case CISTPL_FUNCID_VIDEO:
- puts (" Video Adapter");
- break;
- case CISTPL_FUNCID_NETWORK:
- puts (" Network Adapter");
- break;
- case CISTPL_FUNCID_AIMS:
- puts (" AIMS Card");
- break;
- case CISTPL_FUNCID_SCSI:
- puts (" SCSI Adapter");
- break;
- default:
- puts (" Unknown");
- break;
- }
puts (" Card\n");
}
-#endif /* CONFIG_IDE_8xx_PCCARD */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
static void print_fixed (volatile uchar *p)
{
if (p == NULL)
@@ -2626,16 +169,16 @@ static void print_fixed (volatile uchar *p)
puts(indent);
switch (*p) {
- case CISTPL_FUNCE_IDE_IFACE:
- { uchar iface = *(p+2);
+ case CISTPL_FUNCE_IDE_IFACE:
+ { uchar iface = *(p+2);
puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
puts (" interface ");
break;
- }
- case CISTPL_FUNCE_IDE_MASTER:
- case CISTPL_FUNCE_IDE_SLAVE:
- { uchar f1 = *(p+2);
+ }
+ case CISTPL_FUNCE_IDE_MASTER:
+ case CISTPL_FUNCE_IDE_SLAVE:
+ { uchar f1 = *(p+2);
uchar f2 = *(p+4);
puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
@@ -2667,23 +210,10 @@ static void print_fixed (volatile uchar *p)
puts (" [IOis16]");
break;
- }
+ }
}
putc ('\n');
}
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
-
-#define MAX_IDENT_CHARS 64
-#define MAX_IDENT_FIELDS 4
-
-static uchar *known_cards[] = {
- (uchar *)"ARGOSY PnPIDE D5",
- NULL
-};
static int identify (volatile uchar *p)
{
@@ -2735,576 +265,101 @@ static int identify (volatile uchar *p)
return (0); /* don't know */
}
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
-/* -------------------------------------------------------------------- */
-/* NETTA board by Intracom S.A. */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_NETTA)
-
-/* some sane bit macros */
-#define _BD(_b) (1U << (31-(_b)))
-#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
-
-#define _BW(_b) (1U << (15-(_b)))
-#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
-
-#define _BB(_b) (1U << (7-(_b)))
-#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
-
-#define _B(_b) _BD(_b)
-#define _BR(_l, _h) _BDR(_l, _h)
-
-#define PCMCIA_BOARD_MSG "NETTA"
-
-static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
-
-static void cfg_vppd(int no)
-{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask;
-
- if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
- return;
-
- mask = vppd_masks[no];
-
- immap->im_ioport.iop_papar &= ~mask;
- immap->im_ioport.iop_paodr &= ~mask;
- immap->im_ioport.iop_padir |= mask;
-}
-
-static void set_vppd(int no, int what)
-{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask;
-
- if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
- return;
-
- mask = vppd_masks[no];
-
- if (what)
- immap->im_ioport.iop_padat |= mask;
- else
- immap->im_ioport.iop_padat &= ~mask;
-}
-
-static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
-
-static void cfg_vccd(int no)
-{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask;
-
- if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
- return;
-
- mask = vccd_masks[no];
-
- immap->im_ioport.iop_papar &= ~mask;
- immap->im_ioport.iop_paodr &= ~mask;
- immap->im_ioport.iop_padir |= mask;
-}
-
-static void set_vccd(int no, int what)
-{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask;
-
- if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
- return;
-
- mask = vccd_masks[no];
-
- if (what)
- immap->im_ioport.iop_padat |= mask;
- else
- immap->im_ioport.iop_padat &= ~mask;
-}
-
-static const unsigned short oc_mask = _BW(8);
-
-static void cfg_oc(void)
-{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask = oc_mask;
-
- immap->im_ioport.iop_pcdir &= ~mask;
- immap->im_ioport.iop_pcso &= ~mask;
- immap->im_ioport.iop_pcint &= ~mask;
- immap->im_ioport.iop_pcpar &= ~mask;
-}
-
-static int get_oc(void)
-{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask = oc_mask;
- int what;
-
- what = !!(immap->im_ioport.iop_pcdat & mask);;
- return what;
-}
-
-static const unsigned short shdn_mask = _BW(12);
-
-static void cfg_shdn(void)
-{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask;
-
- mask = shdn_mask;
-
- immap->im_ioport.iop_papar &= ~mask;
- immap->im_ioport.iop_paodr &= ~mask;
- immap->im_ioport.iop_padir |= mask;
-}
-static void set_shdn(int what)
+int check_ide_device (int slot)
{
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
- unsigned short mask;
-
- mask = shdn_mask;
-
- if (what)
- immap->im_ioport.iop_padat |= mask;
- else
- immap->im_ioport.iop_padat &= ~mask;
-}
-
-static void cfg_ports (void);
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, pipr, mask;
+ volatile uchar *ident = NULL;
+ volatile uchar *feature_p[MAX_FEATURES];
+ volatile uchar *p, *start, *addr;
+ int n_features = 0;
+ uchar func_id = ~0;
+ uchar code, len;
+ ushort config_base = 0;
+ int found = 0;
int i;
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
- cfg_ports ();
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+ addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
+ CFG_PCMCIA_MEM_SIZE * (slot * 4));
+ debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
+ start = p = (volatile uchar *) addr;
- udelay(500);
+ while ((p - start) < MAX_TUPEL_SZ) {
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
- printf (" No Card found\n");
- return (1);
- }
+ code = *p; p += 2;
- /*
- * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- pipr = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- pipr,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
+ if (code == 0xFF) { /* End of chain */
+ break;
+ }
- if ((pipr & mask) == mask) {
- set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
- set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
- puts (" 5.0V card found: ");
- } else {
- set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
- set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
- puts (" 3.3V card found: ");
- }
+ len = *p; p += 2;
+#if defined(DEBUG) && (DEBUG > 1)
+ { volatile uchar *q = p;
+ printf ("\nTuple code %02x length %d\n\tData:",
+ code, len);
- /* Wait 500 ms; use this to check for over-current */
- for (i=0; i<5000; ++i) {
- if (!get_oc()) {
- printf (" *** Overcurrent - Safety shutdown ***\n");
- set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
- return (1);
+ for (i = 0; i < len; ++i) {
+ printf (" %02x", *q);
+ q+= 2;
+ }
}
- udelay (100);
+#endif /* DEBUG */
+ switch (code) {
+ case CISTPL_VERS_1:
+ ident = p + 4;
+ break;
+ case CISTPL_FUNCID:
+ /* Fix for broken SanDisk which may have 0x80 bit set */
+ func_id = *p & 0x7F;
+ break;
+ case CISTPL_FUNCE:
+ if (n_features < MAX_FEATURES)
+ feature_p[n_features++] = p;
+ break;
+ case CISTPL_CONFIG:
+ config_base = (*(p+6) << 8) + (*(p+4));
+ debug ("\n## Config_base = %04x ###\n", config_base);
+ default:
+ break;
+ }
+ p += 2 * len;
}
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-
- /* Configure PCMCIA General Control Register */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- /* All voltages off / Hi-Z */
- set_vppd(0, 1); set_vppd(1, 1);
- set_vccd(0, 1); set_vccd(1, 1);
-
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
- ushort sreg;
-
- debug ("voltage_set: "
- PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- immap = (immap_t *)CFG_IMMR;
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Configure Port C pins for
- * 5 Volts Enable and 3 Volts enable,
- * Turn all power pins to Hi-Z
- */
- debug ("PCMCIA power OFF\n");
- cfg_ports (); /* Enables switch, but all in Hi-Z */
-
- sreg = immap->im_ioport.iop_pcdat;
- set_vppd(0, 1); set_vppd(1, 1);
-
- switch(vcc) {
- case 0:
- break; /* Switch off */
-
- case 33:
- set_vccd(0, 1); set_vccd(1, 0);
- break;
+ found = identify (ident);
- case 50:
- set_vccd(0, 0); set_vccd(1, 1);
- break;
+ if (func_id != ((uchar)~0)) {
+ print_funcid (func_id);
- default:
- goto done;
+ if (func_id == CISTPL_FUNCID_FIXED)
+ found = 1;
+ else
+ return (1); /* no disk drive */
}
- /* Checking supported voltages */
-
- debug ("PIPR: 0x%x --> %s\n",
- pcmp->pcmc_pipr,
- (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
-done:
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
- return (0);
-}
-
-static void cfg_ports (void)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
-
- immap = (immap_t *)CFG_IMMR;
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
-
- cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
- cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
- cfg_shdn();
- cfg_oc();
-
- /*
- * Configure Port A for TPS2211 PC-Card Power-Interface Switch
- *
- * Switch off all voltages, assert shutdown
- */
- set_vppd(0, 1); set_vppd(1, 1);
- set_vccd(0, 0); set_vccd(1, 0);
- set_shdn(1);
-
- udelay(100000);
-}
-
-#endif /* NETTA */
-
-
-/* -------------------------------------------------------------------- */
-/* UC100 Boards */
-/* -------------------------------------------------------------------- */
-
-#if defined(CONFIG_UC100)
-
-#define PCMCIA_BOARD_MSG "UC100"
-
-/*
- * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
- * This leads to board-hangup! (sr, 8 Dez. 2004)
- */
-
-static void cfg_ports (void);
-
-static int hardware_enable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- volatile sysconf8xx_t *sysp;
- uint reg, mask;
-
- debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- immap = (immap_t *)CFG_IMMR;
- sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
-
- /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
- cfg_ports ();
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
- sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
-
- /* clear interrupt state, and disable interrupts */
- pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
- pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- debug ("[%d] %s: PIPR(%p)=0x%x\n",
- __LINE__,__FUNCTION__,
- &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
- if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
- printf (" No Card found\n");
- return (1);
+ for (i=0; i<n_features; ++i) {
+ print_fixed (feature_p[i]);
}
- /*
- * Power On.
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- reg = pcmp->pcmc_pipr;
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- reg,
- (reg&PCMCIA_VS1(slot))?"n":"ff",
- (reg&PCMCIA_VS2(slot))?"n":"ff");
- if ((reg & mask) == mask) {
- puts (" 5.0V card found: ");
- } else {
- puts (" 3.3V card found: ");
+ if (!found) {
+ printf ("unknown card type\n");
+ return (1);
}
- /* switch VCC on */
- immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
-
- udelay(10000);
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug ("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-static int hardware_disable(int slot)
-{
- volatile immap_t *immap;
- volatile cpm8xx_t *cp;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
-
- /* switch VCC off */
- immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
-
- /* Configure PCMCIA General Control Register */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- PCMCIA_PGCRX(_slot_) = reg;
-
- udelay(10000);
-
- return (0);
-}
-#endif /* CFG_CMD_PCMCIA */
-
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- volatile immap_t *immap;
- volatile pcmconf8xx_t *pcmp;
- u_long reg;
-
- debug ("voltage_set: "
- PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- immap = (immap_t *)CFG_IMMR;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug ("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
-
- /*
- * Configure Port C pins for
- * 5 Volts Enable and 3 Volts enable,
- * Turn all power pins to Hi-Z
- */
- debug ("PCMCIA power OFF\n");
- cfg_ports (); /* Enables switch, but all in Hi-Z */
-
- debug ("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(_slot_);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- PCMCIA_PGCRX(_slot_) = reg;
- udelay(500);
+ ide_devices_found |= (1 << slot);
- debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
- slot+'A');
+#if CONFIG_CPC45
+#else
+ /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
+ *((uchar *)(addr + config_base)) = 1;
+#endif
+#if 0
+ printf("\n## Config_base = %04x ###\n", config_base);
+ printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
+ printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
+ printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
+ printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
+#endif
return (0);
}
-static void cfg_ports (void)
-{
- volatile immap_t *immap;
-
- immap = (immap_t *)CFG_IMMR;
-
- /*
- * Configure Port A for MAX1602 PC-Card Power-Interface Switch
- */
- immap->im_ioport.iop_padat &= ~0x8000; /* set port x output to low */
- immap->im_ioport.iop_padir |= 0x8000; /* enable port x as output */
-
- debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
- immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
- immap->im_ioport.iop_padat);
-}
-
-#endif /* UC100 */
-
-
-/* -------------------------------------------------------------------- */
-
-#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
-
-/**************************************************/
-
-#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
-U_BOOT_CMD(
- pinit, 2, 1, do_pinit,
- "pinit - PCMCIA sub-system\n",
- "on - power on PCMCIA socket\n"
- "pinit off - power off PCMCIA socket\n"
-);
-#endif
+#endif /* CHECK_IDE_DEVICE */
diff --git a/common/cmd_reginfo.c b/common/cmd_reginfo.c
index 15ac16aef4e..f428f7e9aa6 100644
--- a/common/cmd_reginfo.c
+++ b/common/cmd_reginfo.c
@@ -328,7 +328,7 @@ int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
(*(volatile ulong*)MPC5XXX_ADDECR & 0x02000000) ? 1 : 0);
printf ("\tSDRAMCS0: %08X\n",
*(volatile ulong*)MPC5XXX_SDRAM_CS0CFG);
- printf ("\tSDRAMCS0: %08X\n",
+ printf ("\tSDRAMCS1: %08X\n",
*(volatile ulong*)MPC5XXX_SDRAM_CS1CFG);
#endif /* CONFIG_MPC5200 */
return 0;
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index fdfd042acaa..28c05aa20ea 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -186,7 +186,7 @@ void usb_display_conf_desc(struct usb_config_descriptor *config,struct usb_devic
void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,struct usb_device *dev)
{
printf(" Interface: %d\n",ifdesc->bInterfaceNumber);
- printf(" - Alternate Settings %d, Endpoints: %d\n",ifdesc->bAlternateSetting,ifdesc->bNumEndpoints);
+ printf(" - Alternate Setting %d, Endpoints: %d\n",ifdesc->bAlternateSetting,ifdesc->bNumEndpoints);
printf(" - Class ");
usb_display_class_sub(ifdesc->bInterfaceClass,ifdesc->bInterfaceSubClass,ifdesc->bInterfaceProtocol);
printf("\n");
@@ -444,6 +444,7 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int i;
struct usb_device *dev = NULL;
+ extern char usb_started;
#ifdef CONFIG_USB_STORAGE
block_dev_desc_t *stor_dev;
#endif
@@ -477,6 +478,10 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
usb_stop();
return 0;
}
+ if (!usb_started) {
+ printf("USB is stopped. Please issue 'usb start' first.\n");
+ return 1;
+ }
if (strncmp(argv[1],"tree",4) == 0) {
printf("\nDevice Tree:\n");
usb_show_tree(usb_get_dev_index(0));
diff --git a/common/command.c b/common/command.c
index 2b4c5547b31..e917975a733 100644
--- a/common/command.c
+++ b/common/command.c
@@ -42,6 +42,8 @@ U_BOOT_CMD(
NULL
);
+#if (CONFIG_COMMANDS & CFG_CMD_ECHO)
+
int
do_echo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
@@ -74,6 +76,8 @@ U_BOOT_CMD(
" - echo args to console; \\c suppresses newline\n"
);
+#endif /* CFG_CMD_ECHO */
+
#ifdef CFG_HUSH_PARSER
int
diff --git a/common/console.c b/common/console.c
index 3c535d23d6d..e9f23bec182 100644
--- a/common/console.c
+++ b/common/console.c
@@ -27,6 +27,8 @@
#include <console.h>
#include <exports.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#ifdef CONFIG_AMIGAONEG3SE
int console_changed = 0;
#endif
@@ -48,7 +50,6 @@ extern int overwrite_console (void);
static int console_setfile (int file, device_t * dev)
{
- DECLARE_GLOBAL_DATA_PTR;
int error = 0;
if (dev == NULL)
@@ -161,8 +162,6 @@ void fprintf (int file, const char *fmt, ...)
int getc (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (gd->flags & GD_FLG_DEVINIT) {
/* Get from the standard input */
return fgetc (stdin);
@@ -174,8 +173,6 @@ int getc (void)
int tstc (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (gd->flags & GD_FLG_DEVINIT) {
/* Test the standard input */
return ftstc (stdin);
@@ -187,8 +184,6 @@ int tstc (void)
void putc (const char c)
{
- DECLARE_GLOBAL_DATA_PTR;
-
#ifdef CONFIG_SILENT_CONSOLE
if (gd->flags & GD_FLG_SILENT)
return;
@@ -205,8 +200,6 @@ void putc (const char c)
void puts (const char *s)
{
- DECLARE_GLOBAL_DATA_PTR;
-
#ifdef CONFIG_SILENT_CONSOLE
if (gd->flags & GD_FLG_SILENT)
return;
@@ -258,8 +251,6 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */
static int ctrlc_was_pressed = 0;
int ctrlc (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (!ctrlc_disabled && gd->have_console) {
if (tstc ()) {
switch (getc ()) {
@@ -370,8 +361,6 @@ int console_assign (int file, char *devname)
/* Called before relocation - use serial functions */
int console_init_f (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
gd->have_console = 1;
#ifdef CONFIG_SILENT_CONSOLE
@@ -407,7 +396,6 @@ device_t *search_device (int flags, char *name)
/* Called after the relocation - use desired console functions */
int console_init_r (void)
{
- DECLARE_GLOBAL_DATA_PTR;
char *stdinname, *stdoutname, *stderrname;
device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
#ifdef CFG_CONSOLE_ENV_OVERWRITE
@@ -499,8 +487,6 @@ int console_init_r (void)
/* Called after the relocation - use desired console functions */
int console_init_r (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
device_t *inputdev = NULL, *outputdev = NULL;
int i, items = ListNumItems (devlist);
diff --git a/common/crc16.c b/common/crc16.c
new file mode 100644
index 00000000000..6904365e592
--- /dev/null
+++ b/common/crc16.c
@@ -0,0 +1,107 @@
+/*
+ *==========================================================================
+ *
+ * crc16.c
+ *
+ * 16 bit CRC with polynomial x^16+x^12+x^5+1
+ *
+ *==========================================================================
+ *####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating System.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ * Copyright (C) 2002 Gary Thomas
+ *
+ * eCos 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 or (at your option) any later version.
+ *
+ * eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+ *
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ *
+ * Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+ * at http: *sources.redhat.com/ecos/ecos-license/
+ * -------------------------------------------
+ *####ECOSGPLCOPYRIGHTEND####
+ *==========================================================================
+ *#####DESCRIPTIONBEGIN####
+ *
+ * Author(s): gthomas
+ * Contributors: gthomas,asl
+ * Date: 2001-01-31
+ * Purpose:
+ * Description:
+ *
+ * This code is part of eCos (tm).
+ *
+ *####DESCRIPTIONEND####
+ *
+ *==========================================================================
+ */
+
+#include "crc.h"
+
+/* Table of CRC constants - implements x^16+x^12+x^5+1 */
+static const uint16_t crc16_tab[] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
+};
+
+uint16_t
+cyg_crc16(unsigned char *buf, int len)
+{
+ int i;
+ uint16_t cksum;
+
+ cksum = 0;
+ for (i = 0; i < len; i++) {
+ cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xFF] ^ (cksum << 8);
+ }
+ return cksum;
+}
diff --git a/common/devices.c b/common/devices.c
index bd4dfa024a9..ddf8f8ee2d9 100644
--- a/common/devices.c
+++ b/common/devices.c
@@ -34,6 +34,8 @@
#include <i2c.h>
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
list_t devlist = 0;
device_t *stdio_devices[] = { NULL, NULL, NULL };
char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
@@ -160,8 +162,6 @@ int device_deregister(char *devname)
int devices_init (void)
{
#ifndef CONFIG_ARM /* already relocated for current ARM implementation */
- DECLARE_GLOBAL_DATA_PTR;
-
ulong relocation_offset = gd->reloc_off;
int i;
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 0c0487228e5..20c206913c6 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -949,6 +949,8 @@ void malloc_stats();
#endif /* 0 */ /* Moved to malloc.h */
#include <common.h>
+DECLARE_GLOBAL_DATA_PTR;
+
/*
Emulation of sbrk for WIN32
All code within the ifdef WIN32 is untested by me.
@@ -1493,8 +1495,6 @@ static mbinptr av_[NAV * 2 + 2] = {
void malloc_bin_reloc (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
unsigned long *p = (unsigned long *)(&av_[2]);
int i;
for (i=2; i<(sizeof(av_)/sizeof(mbinptr)); ++i) {
diff --git a/common/env_common.c b/common/env_common.c
index 3201135ea2e..f841694cbe9 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -37,6 +37,8 @@
# define SHOW_BOOT_PROGRESS(arg)
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
#ifdef CONFIG_AMIGAONEG3SE
extern void enable_nvram(void);
extern void disable_nvram(void);
@@ -150,7 +152,6 @@ void env_crc_update (void)
static uchar env_get_char_init (int index)
{
- DECLARE_GLOBAL_DATA_PTR;
uchar c;
/* if crc was bad, use the default environment */
@@ -167,7 +168,6 @@ static uchar env_get_char_init (int index)
#ifdef CONFIG_AMIGAONEG3SE
uchar env_get_char_memory (int index)
{
- DECLARE_GLOBAL_DATA_PTR;
uchar retval;
enable_nvram();
if (gd->env_valid) {
@@ -181,8 +181,6 @@ uchar env_get_char_memory (int index)
#else
uchar env_get_char_memory (int index)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (gd->env_valid) {
return ( *((uchar *)(gd->env_addr + index)) );
} else {
@@ -193,8 +191,6 @@ uchar env_get_char_memory (int index)
uchar *env_get_addr (int index)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (gd->env_valid) {
return ( ((uchar *)(gd->env_addr + index)) );
} else {
@@ -204,8 +200,6 @@ uchar *env_get_addr (int index)
void env_relocate (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
gd->reloc_off);
@@ -283,7 +277,7 @@ int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)
for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
;
- lval = (char *)env_get_addr(i);
+ lval = env_get_addr(i);
rval = strchr(lval, '=');
if (rval != NULL) {
vallen = rval - lval;
diff --git a/common/env_dataflash.c b/common/env_dataflash.c
index 8834da032bd..93fff29b05a 100644
--- a/common/env_dataflash.c
+++ b/common/env_dataflash.c
@@ -26,6 +26,8 @@
#include <linux/stddef.h>
#include <dataflash.h>
+DECLARE_GLOBAL_DATA_PTR;
+
env_t *env_ptr = NULL;
char * env_name_spec = "dataflash";
@@ -68,8 +70,6 @@ int i;
*/
int env_init(void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
ulong crc, len, new;
unsigned off;
uchar buf[64];
diff --git a/common/env_eeprom.c b/common/env_eeprom.c
index 50c623e37e3..2adc129c677 100644
--- a/common/env_eeprom.c
+++ b/common/env_eeprom.c
@@ -32,6 +32,8 @@
#include <environment.h>
#include <linux/stddef.h>
+DECLARE_GLOBAL_DATA_PTR;
+
env_t *env_ptr = NULL;
char * env_name_spec = "EEPROM";
@@ -75,8 +77,6 @@ int saveenv(void)
*/
int env_init(void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
ulong crc, len, new;
unsigned off;
uchar buf[64];
diff --git a/common/env_flash.c b/common/env_flash.c
index a2ea9c41406..7dd29172aa4 100644
--- a/common/env_flash.c
+++ b/common/env_flash.c
@@ -35,6 +35,8 @@
#include <linux/stddef.h>
#include <malloc.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH))
#define CMD_SAVEENV
#elif defined(CFG_ENV_ADDR_REDUND)
@@ -51,6 +53,22 @@
# endif
#endif
+#if (defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)) || defined (ENV_IS_VARIABLE)
+#define SMALL_SECTOR 1
+#endif
+
+#ifdef ENV_IS_VARIABLE
+char * flash_env_name_spec = "Flash";
+/* update these elsewhere */
+extern env_t *env_ptr;
+
+#ifdef CMD_SAVEENV
+/* static env_t *flash_addr = (env_t *)(&environment[0]);-broken on ARM-wd-*/
+env_t *flash_addr = 0;
+#endif
+
+#else /* !ENV_IS_VARIABLE */
+
char * env_name_spec = "Flash";
#ifdef ENV_IS_EMBEDDED
@@ -61,6 +79,7 @@ env_t *env_ptr = (env_t *)(&environment[0]);
#ifdef CMD_SAVEENV
/* static env_t *flash_addr = (env_t *)(&environment[0]);-broken on ARM-wd-*/
static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
+
#endif
#else /* ! ENV_IS_EMBEDDED */
@@ -83,14 +102,18 @@ static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1;
#define OBSOLETE_FLAG 0
#endif /* CFG_ENV_ADDR_REDUND */
+#endif /* ENV_IS_VARIABLE */
+
extern uchar default_environment[];
extern int default_environment_size;
+#ifdef ENV_IS_VARIABLE
+uchar flash_env_get_char_spec (int index)
+#else
uchar env_get_char_spec (int index)
+#endif
{
- DECLARE_GLOBAL_DATA_PTR;
-
return ( *((uchar *)(gd->env_addr + index)) );
}
@@ -98,7 +121,6 @@ uchar env_get_char_spec (int index)
int env_init(void)
{
- DECLARE_GLOBAL_DATA_PTR;
int crc1_ok = 0, crc2_ok = 0;
uchar flag1 = flash_addr->flags;
@@ -108,13 +130,6 @@ int env_init(void)
ulong addr1 = (ulong)&(flash_addr->data);
ulong addr2 = (ulong)&(flash_addr_new->data);
-#ifdef CONFIG_OMAP2420H4
- int flash_probe(void);
-
- if(flash_probe() == 0)
- goto bad_flash;
-#endif
-
crc1_ok = (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc);
crc2_ok = (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc);
@@ -144,9 +159,6 @@ int env_init(void)
gd->env_valid = 2;
}
-#ifdef CONFIG_OMAP2420H4
-bad_flash:
-#endif
return (0);
}
@@ -158,6 +170,10 @@ int saveenv(void)
char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
ulong up_data = 0;
+#else
+#if SMALL_SECTOR
+ ulong up_data = 0;
+#endif
#endif
debug ("Protect off %08lX ... %08lX\n",
@@ -174,7 +190,8 @@ int saveenv(void)
goto Done;
}
-#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
+#if SMALL_SECTOR
+ if (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE) {
up_data = (end_addr_new + 1 - ((long)flash_addr_new + CFG_ENV_SIZE));
debug ("Data to save 0x%x\n", up_data);
if (up_data) {
@@ -202,7 +219,7 @@ int saveenv(void)
debug (" %08lX ... %08lX ...",
(ulong)&(flash_addr_new->data),
sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data));
- if ((rc = flash_write((char *)env_ptr->data,
+ if ((rc = flash_write(env_ptr->data,
(ulong)&(flash_addr_new->data),
sizeof(env_ptr->data))) ||
(rc = flash_write((char *)&(env_ptr->crc),
@@ -220,7 +237,7 @@ int saveenv(void)
}
puts ("done\n");
-#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
+#if SMALL_SECTOR
if (up_data) { /* restore the rest of sector */
debug ("Restoring the rest of data to 0x%x len 0x%x\n",
(long)flash_addr_new + CFG_ENV_SIZE, up_data);
@@ -251,30 +268,25 @@ Done:
/* try to re-protect */
(void) flash_sect_protect (1, (ulong)flash_addr, end_addr);
(void) flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
-
return rc;
}
#endif /* CMD_SAVEENV */
#else /* ! CFG_ENV_ADDR_REDUND */
+#ifdef ENV_IS_VARIABLE
+int flash_env_init(void)
+#else
int env_init(void)
+#endif
{
- DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_OMAP2420H4
- int flash_probe(void);
- if(flash_probe() == 0)
- goto bad_flash;
-#endif
if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
gd->env_addr = (ulong)&(env_ptr->data);
gd->env_valid = 1;
return(0);
}
-#ifdef CONFIG_OMAP2420H4
-bad_flash:
-#endif
+
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
return (0);
@@ -282,20 +294,23 @@ bad_flash:
#ifdef CMD_SAVEENV
+#ifdef ENV_IS_VARIABLE
+int flash_saveenv(void)
+#else
int saveenv(void)
+#endif
{
int len, rc;
ulong end_addr;
ulong flash_sect_addr;
-#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
+#if SMALL_SECTOR
ulong flash_offset;
uchar env_buffer[CFG_ENV_SECT_SIZE];
#else
uchar *env_buffer = (uchar *)env_ptr;
#endif /* CFG_ENV_SECT_SIZE */
int rcode = 0;
-
-#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
+#if SMALL_SECTOR
flash_offset = ((ulong)flash_addr) & (CFG_ENV_SECT_SIZE-1);
flash_sect_addr = ((ulong)flash_addr) & ~(CFG_ENV_SECT_SIZE-1);
@@ -354,12 +369,14 @@ int saveenv(void)
#endif /* CFG_ENV_ADDR_REDUND */
+#ifdef ENV_IS_VARIABLE
+void flash_env_relocate_spec(void)
+#else
void env_relocate_spec (void)
+#endif
{
-#if !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND)
+#if defined(ENV_IS_VARIABLE) || !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND)
#ifdef CFG_ENV_ADDR_REDUND
- DECLARE_GLOBAL_DATA_PTR;
-
if (gd->env_addr != (ulong)&(flash_addr->data)) {
env_t * etmp = flash_addr;
ulong ltmp = end_addr;
diff --git a/common/env_nand.c b/common/env_nand.c
index 60aba1e7e66..376154d5910 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -36,42 +36,41 @@
#include <command.h>
#include <environment.h>
#include <linux/stddef.h>
-#include <linux/mtd/nand.h>
+#include <malloc.h>
+#include <nand.h>
#if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_NAND)) == (CFG_CMD_ENV|CFG_CMD_NAND))
#define CMD_SAVEENV
+#elif defined(CFG_ENV_OFFSET_REDUND)
+#error Cannot use CFG_ENV_OFFSET_REDUND without CFG_CMD_ENV & CFG_CMD_NAND
#endif
-#if defined(CFG_ENV_SIZE_REDUND)
-#error CFG_ENV_SIZE_REDUND not supported yet
+#if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND != CFG_ENV_SIZE)
+#error CFG_ENV_SIZE_REDUND should be the same as CFG_ENV_SIZE
#endif
-#if defined(CFG_ENV_ADDR_REDUND)
-#error CFG_ENV_ADDR_REDUND and CFG_ENV_IS_IN_NAND not supported yet
-#endif
-
-
#ifdef CONFIG_INFERNO
#error CONFIG_INFERNO not supported yet
#endif
-/* references to names in cmd_nand.c */
-#define NANDRW_READ 0x01
-#define NANDRW_WRITE 0x00
-#define NANDRW_JFFS2 0x02
-extern struct nand_chip nand_dev_desc[];
-int nand_rw (struct nand_chip* nand, int cmd,
+int nand_legacy_rw (struct nand_chip* nand, int cmd,
size_t start, size_t len,
size_t * retlen, u_char * buf);
-int nand_erase(struct nand_chip* nand, size_t ofs,
- size_t len, int clean);
+
+/* info for NAND chips, defined in drivers/nand/nand.c */
+extern nand_info_t nand_info[];
/* references to names in env_common.c */
extern uchar default_environment[];
extern int default_environment_size;
-char * env_name_spec = "NAND";
+#ifdef ENV_IS_VARIABLE
+char * nand_env_name_spec = "NAND";
+extern env_t *env_ptr;
+
+#else /* !ENV_IS_VARIABLE */
+char * env_name_spec = "NAND";
#ifdef ENV_IS_EMBEDDED
extern uchar environment[];
@@ -80,15 +79,19 @@ env_t *env_ptr = (env_t *)(&environment[0]);
env_t *env_ptr = 0;
#endif /* ENV_IS_EMBEDDED */
+#endif /* ENV_IS_VARIABLE */
/* local functions */
static void use_default(void);
+DECLARE_GLOBAL_DATA_PTR;
+#ifdef ENV_IS_VARIABLE
+uchar nand_env_get_char_spec (int index)
+#else
uchar env_get_char_spec (int index)
+#endif
{
- DECLARE_GLOBAL_DATA_PTR;
-
return ( *((uchar *)(gd->env_addr + index)) );
}
@@ -99,61 +102,175 @@ uchar env_get_char_spec (int index)
* will call our relocate function which will does
* the real validation.
*/
+#ifdef ENV_IS_VARIABLE
+int nand_env_init(void)
+#else
int env_init(void)
+#endif
{
- DECLARE_GLOBAL_DATA_PTR;
-
- gd->env_addr = (ulong)&default_environment[0];
+ gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 1;
return (0);
}
#ifdef CMD_SAVEENV
+/*
+ * The legacy NAND code saved the environment in the first NAND device i.e.,
+ * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
+ */
+#ifdef CFG_ENV_OFFSET_REDUND
+#ifdef ENV_IS_VARIABLE
+int nand_saveenv(void)
+#else
int saveenv(void)
+#endif
{
- int total, ret = 0;
- puts ("Erasing Nand...");
- if (nand_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))
- return 1;
+ ulong total;
+ int ret = 0;
+
+ env_ptr->flags++;
+ total = CFG_ENV_SIZE;
+
+ if(gd->env_valid == 1) {
+ puts ("Erasing redundant Nand...");
+ if (nand_erase(&nand_info[0],
+ CFG_ENV_OFFSET_REDUND, CFG_ENV_SIZE))
+ return 1;
+ puts ("Writing to redundant Nand... ");
+ ret = nand_write(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total,
+ (u_char*) env_ptr);
+ } else {
+ puts ("Erasing Nand...");
+ if (nand_erase(&nand_info[0],
+ CFG_ENV_OFFSET, CFG_ENV_SIZE))
+ return 1;
+
+ puts ("Writing to Nand... ");
+ ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total,
+ (u_char*) env_ptr);
+ }
+ if (ret || total != CFG_ENV_SIZE)
+ return 1;
+
+ puts ("done\n");
+ gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
+ return ret;
+}
+#else /* ! CFG_ENV_OFFSET_REDUND */
+#ifdef ENV_IS_VARIABLE
+int nand_saveenv(void)
+#else
+int saveenv(void)
+#endif
+{
+ ulong total;
+ int ret = 0;
+
+ puts ("Erasing Nand...");
+ if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
+ return 1;
puts ("Writing to Nand... ");
- ret = nand_rw(nand_dev_desc + 0,
- NANDRW_WRITE | NANDRW_JFFS2, CFG_ENV_OFFSET, CFG_ENV_SIZE,
- &total, (u_char*)env_ptr);
- if (ret || total != CFG_ENV_SIZE)
+ total = CFG_ENV_SIZE;
+ ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
+ if (ret || total != CFG_ENV_SIZE)
return 1;
- puts ("done\n");
- return ret;
+ puts ("done\n");
+ return ret;
}
+#endif /* CFG_ENV_OFFSET_REDUND */
#endif /* CMD_SAVEENV */
+#ifdef CFG_ENV_OFFSET_REDUND
+#ifdef ENV_IS_VARIABLE
+void nand_env_relocate_spec (void)
+#else
+void env_relocate_spec (void)
+#endif
+{
+#if !defined(ENV_IS_EMBEDDED)
+ ulong total;
+ int crc1_ok = 0, crc2_ok = 0;
+ env_t *tmp_env1, *tmp_env2;
+
+ total = CFG_ENV_SIZE;
+ tmp_env1 = (env_t *) malloc(CFG_ENV_SIZE);
+ tmp_env2 = (env_t *) malloc(CFG_ENV_SIZE);
+
+ nand_read(&nand_info[0], CFG_ENV_OFFSET, &total,
+ (u_char*) tmp_env1);
+ nand_read(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total,
+ (u_char*) tmp_env2);
+
+ crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
+ crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
+
+ if(!crc1_ok && !crc2_ok)
+ return use_default();
+ else if(crc1_ok && !crc2_ok)
+ gd->env_valid = 1;
+ else if(!crc1_ok && crc2_ok)
+ gd->env_valid = 2;
+ else {
+ /* both ok - check serial */
+ if(tmp_env1->flags == 255 && tmp_env2->flags == 0)
+ gd->env_valid = 2;
+ else if(tmp_env2->flags == 255 && tmp_env1->flags == 0)
+ gd->env_valid = 1;
+ else if(tmp_env1->flags > tmp_env2->flags)
+ gd->env_valid = 1;
+ else if(tmp_env2->flags > tmp_env1->flags)
+ gd->env_valid = 2;
+ else /* flags are equal - almost impossible */
+ gd->env_valid = 1;
+
+ }
+
+ free(env_ptr);
+ if(gd->env_valid == 1) {
+ env_ptr = tmp_env1;
+ free(tmp_env2);
+ } else {
+ env_ptr = tmp_env2;
+ free(tmp_env1);
+ }
+
+#endif /* ! ENV_IS_EMBEDDED */
+}
+#else /* ! CFG_ENV_OFFSET_REDUND */
+/*
+ * The legacy NAND code saved the environment in the first NAND device i.e.,
+ * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
+ */
+#ifdef ENV_IS_VARIABLE
+void nand_env_relocate_spec (void)
+#else
void env_relocate_spec (void)
+#endif
{
#if !defined(ENV_IS_EMBEDDED)
- int ret, total;
+ ulong total;
+ int ret;
- ret = nand_rw(nand_dev_desc + 0,
- NANDRW_READ | NANDRW_JFFS2, CFG_ENV_OFFSET, CFG_ENV_SIZE,
- &total, (u_char*)env_ptr);
+ total = CFG_ENV_SIZE;
+ ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
if (ret || total != CFG_ENV_SIZE)
return use_default();
if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
return use_default();
#endif /* ! ENV_IS_EMBEDDED */
-
}
+#endif /* CFG_ENV_OFFSET_REDUND */
static void use_default()
{
- DECLARE_GLOBAL_DATA_PTR;
-
puts ("*** Warning - bad CRC or NAND, using default environment\n\n");
- if (default_environment_size > CFG_ENV_SIZE){
+ if (default_environment_size > CFG_ENV_SIZE){
puts ("*** Error - default environment is too large\n\n");
return;
}
@@ -163,7 +280,7 @@ static void use_default()
default_environment,
default_environment_size);
env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
- gd->env_valid = 1;
+ gd->env_valid = 1;
}
diff --git a/common/env_nowhere.c b/common/env_nowhere.c
index ee4237c7e90..17ecc775ff9 100644
--- a/common/env_nowhere.c
+++ b/common/env_nowhere.c
@@ -32,6 +32,8 @@
#include <environment.h>
#include <linux/stddef.h>
+DECLARE_GLOBAL_DATA_PTR;
+
env_t *env_ptr = NULL;
extern uchar default_environment[];
@@ -44,8 +46,6 @@ void env_relocate_spec (void)
uchar env_get_char_spec (int index)
{
- DECLARE_GLOBAL_DATA_PTR;
-
return ( *((uchar *)(gd->env_addr + index)) );
}
@@ -56,8 +56,6 @@ uchar env_get_char_spec (int index)
*/
int env_init(void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
diff --git a/common/env_nvram.c b/common/env_nvram.c
index a406e427a24..7c18896cb04 100644
--- a/common/env_nvram.c
+++ b/common/env_nvram.c
@@ -42,6 +42,8 @@
#include <common.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#ifdef CFG_ENV_IS_IN_NVRAM /* Environment is in NVRAM */
#include <command.h>
@@ -74,7 +76,6 @@ uchar env_get_char_spec (int index)
return c;
#else
- DECLARE_GLOBAL_DATA_PTR;
uchar retval;
enable_nvram();
retval = *((uchar *)(gd->env_addr + index));
@@ -92,8 +93,6 @@ uchar env_get_char_spec (int index)
return c;
#else
- DECLARE_GLOBAL_DATA_PTR;
-
return *((uchar *)(gd->env_addr + index));
#endif
}
@@ -135,7 +134,6 @@ int saveenv (void)
*/
int env_init (void)
{
- DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_AMIGAONEG3SE
enable_nvram();
#endif
diff --git a/common/env_onenand.c b/common/env_onenand.c
new file mode 100644
index 00000000000..274e52d10f2
--- /dev/null
+++ b/common/env_onenand.c
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2005 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * 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>
+
+#if defined(CFG_ENV_IS_IN_ONENAND) /* Environment is in OneNAND */
+
+#include <command.h>
+#include <environment.h>
+#include <linux/stddef.h>
+#include <malloc.h>
+
+#include <linux/mtd/onenand.h>
+
+extern struct mtd_info onenand_mtd;
+extern struct onenand_chip onenand_chip;
+
+/* References to names in env_common.c */
+extern uchar default_environment[];
+
+#define ONENAND_ENV_SIZE(mtd) (mtd.oobblock - ENV_HEADER_SIZE)
+
+#ifdef ENV_IS_VARIABLE
+char * onenand_env_name_spec = "OneNAND";
+unsigned char onenand_env[MAX_ONENAND_PAGESIZE];
+extern env_t *env_ptr;
+
+#else /* !ENV_IS_VARIABLE */
+
+char * env_name_spec = "OneNAND";
+
+#ifdef ENV_IS_EMBEDDED
+extern uchar environment[];
+env_t *env_ptr = (env_t *) (&environment[0]);
+#else /* ! ENV_IS_EMBEDDED */
+static unsigned char onenand_env[MAX_ONENAND_PAGESIZE];
+env_t *env_ptr = (env_t *) onenand_env;
+#endif /* ENV_IS_EMBEDDED */
+
+#endif /* ENV_IS_VARIABLE */
+
+#ifdef ENV_IS_VARIABLE
+uchar onenand_env_get_char_spec (int index)
+#else
+uchar env_get_char_spec (int index)
+#endif
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ return (*((uchar *)(gd->env_addr + index)));
+}
+
+#ifdef ENV_IS_VARIABLE
+void onenand_env_relocate_spec(void)
+#else
+void env_relocate_spec(void)
+#endif
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned long env_addr;
+ int use_default = 0;
+ size_t retlen;
+
+ env_addr = CFG_ENV_ADDR;
+
+ /* Check OneNAND exist */
+
+ if (onenand_mtd.oobblock)
+ /* Ignore read fail */
+ onenand_read(&onenand_mtd, env_addr, onenand_mtd.oobblock,
+ &retlen, (u_char *) env_ptr);
+ else
+ onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE;
+
+
+ if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) != env_ptr->crc)
+ use_default = 1;
+
+ if (use_default) {
+ memcpy(env_ptr->data, default_environment, ONENAND_ENV_SIZE(onenand_mtd));
+ env_ptr->crc = crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd));
+ }
+
+ gd->env_addr = (ulong) &env_ptr->data;
+ gd->env_valid = 1;
+}
+
+#ifdef ENV_IS_VARIABLE
+int onenand_saveenv(void)
+#else
+int saveenv(void)
+#endif
+{
+ unsigned long env_addr = CFG_ENV_ADDR;
+ struct erase_info instr;
+ size_t retlen;
+
+
+ instr.len = CFG_ENV_SIZE;
+ instr.addr = env_addr;
+ printf("Erasing oneNand...");
+ if (onenand_erase(&onenand_mtd, &instr)) {
+ printf("OneNAND: erase failed at 0x%08x\n", env_addr);
+ return 1;
+ }
+ printf("done\n");
+
+ /* update crc */
+ env_ptr->crc = crc32(0, env_ptr->data, onenand_mtd.oobblock - ENV_HEADER_SIZE);
+
+ printf("Writing to oneNand... ");
+ if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.oobblock, &retlen, (u_char *) env_ptr)) {
+ printf("OneNAND: write failed at 0x%08x\n", instr.addr);
+ return 2;
+ }
+ printf ("done\n");
+
+ return 0;
+}
+
+#ifdef ENV_IS_VARIABLE
+int onenand_env_init(void)
+#else
+int env_init(void)
+#endif
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /* use default */
+ gd->env_addr = (ulong) &default_environment[0];
+ gd->env_valid = 1;
+
+ return 0;
+}
+
+#endif /* CFG_ENV_IS_IN_ONENAND */
diff --git a/common/environment.c b/common/environment.c
index c7f54c6bd86..81471ce71cd 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -59,7 +59,8 @@
defined(CONFIG_TQM8xxL) || \
defined(CONFIG_RRVISION) || \
defined(CONFIG_TRAB) || \
- defined(CONFIG_PPCHAMELEONEVB) ) && \
+ defined(CONFIG_PPCHAMELEONEVB) || \
+ defined(CONFIG_M5271EVB)) && \
defined(ENV_CRC) /* Environment embedded in U-Boot .ppcenv section */
/* XXX - This only works with GNU C */
# define __PPCENV__ __attribute__ ((section(".ppcenv")))
diff --git a/common/exports.c b/common/exports.c
index 9858217ae0c..ef253381697 100644
--- a/common/exports.c
+++ b/common/exports.c
@@ -1,6 +1,8 @@
#include <common.h>
#include <exports.h>
+DECLARE_GLOBAL_DATA_PTR;
+
static void dummy(void)
{
}
@@ -12,7 +14,6 @@ unsigned long get_version(void)
void jumptable_init (void)
{
- DECLARE_GLOBAL_DATA_PTR;
int i;
gd->jt = (void **) malloc (XF_MAX * sizeof (void *));
diff --git a/common/flash.c b/common/flash.c
index a64bc985299..ce3983a1a68 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -103,7 +103,6 @@ addr2info (ulong addr)
#ifndef CONFIG_SPD823TS
flash_info_t *info;
int i;
-
for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
if (info->flash_id != FLASH_UNKNOWN &&
addr >= info->start[0] &&
@@ -117,7 +116,6 @@ addr2info (ulong addr)
}
}
#endif /* CONFIG_SPD823TS */
-
return (NULL);
}
diff --git a/common/ft_build.c b/common/ft_build.c
index 65a274f8408..9e9c906fc1f 100644
--- a/common/ft_build.c
+++ b/common/ft_build.c
@@ -163,7 +163,7 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = cpu_to_be64(size);
- cxt->pres += 18; /* advance */
+ cxt->pres += 16; /* advance */
((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = 0;
@@ -529,6 +529,7 @@ extern uchar(*env_get_char) (int);
#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) }
+#ifdef CONFIG_OF_HAS_BD_T
static const struct {
const char *name;
int offset;
@@ -574,19 +575,24 @@ static const struct {
#endif
BDM(baudrate),
};
+#endif
-void ft_setup(void *blob, int size, bd_t * bd)
+void ft_setup(void *blob, int size, bd_t * bd, ulong initrd_start, ulong initrd_end)
{
- DECLARE_GLOBAL_DATA_PTR;
- u8 *end;
u32 *p;
int len;
struct ft_cxt cxt;
- int i, k, nxt;
- static char tmpenv[256];
- char *s, *lval, *rval;
ulong clock;
- uint32_t v;
+#if defined(CONFIG_OF_HAS_UBOOT_ENV)
+ int k, nxt;
+#endif
+#if defined(CONFIG_OF_HAS_BD_T)
+ u8 *end;
+#endif
+#if defined(CONFIG_OF_HAS_UBOOT_ENV) || defined(CONFIG_OF_HAS_BD_T)
+ int i;
+ static char tmpenv[256];
+#endif
/* disable OF tree; booting old kernel */
if (getenv("disable_of") != NULL) {
@@ -596,7 +602,8 @@ void ft_setup(void *blob, int size, bd_t * bd)
ft_begin(&cxt, blob, size);
- /* fs_add_rsvmap not used */
+ if (initrd_start && initrd_end)
+ ft_add_rsvmap(&cxt, initrd_start, initrd_end - initrd_start + 1);
ft_begin_tree(&cxt);
@@ -610,9 +617,12 @@ void ft_setup(void *blob, int size, bd_t * bd)
/* back into root */
ft_backtrack_node(&cxt);
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
ft_begin_node(&cxt, "u-boot-env");
for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+ char *s, *lval, *rval;
+
for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) ;
s = tmpenv;
for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
@@ -629,12 +639,20 @@ void ft_setup(void *blob, int size, bd_t * bd)
}
ft_end_node(&cxt);
+#endif
ft_begin_node(&cxt, "chosen");
ft_prop_str(&cxt, "name", "chosen");
ft_prop_str(&cxt, "bootargs", getenv("bootargs"));
ft_prop_int(&cxt, "linux,platform", 0x600); /* what is this? */
+ if (initrd_start && initrd_end) {
+ ft_prop_int(&cxt, "linux,initrd-start", initrd_start);
+ ft_prop_int(&cxt, "linux,initrd-end", initrd_end);
+ }
+#ifdef OF_STDOUT_PATH
+ ft_prop_str(&cxt, "linux,stdout-path", OF_STDOUT_PATH);
+#endif
ft_end_node(&cxt);
@@ -647,14 +665,19 @@ void ft_setup(void *blob, int size, bd_t * bd)
ft_dump_blob(blob);
*/
+#ifdef CONFIG_OF_HAS_BD_T
/* paste the bd_t at the end of the flat tree */
end = (char *)blob +
be32_to_cpu(((struct boot_param_header *)blob)->totalsize);
memcpy(end, bd, sizeof(*bd));
+#endif
#ifdef CONFIG_PPC
+#ifdef CONFIG_OF_HAS_BD_T
for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
+ uint32_t v;
+
sprintf(tmpenv, "/bd_t/%s", bd_map[i].name);
v = *(uint32_t *)((char *)bd + bd_map[i].offset);
@@ -670,6 +693,7 @@ void ft_setup(void *blob, int size, bd_t * bd)
p = ft_get_prop(blob, "/bd_t/ethspeed", &len);
if (p != NULL)
*p = cpu_to_be32((uint32_t) bd->bi_ethspeed);
+#endif
clock = bd->bi_intfreq;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/clock-frequency", &len);
@@ -680,11 +704,14 @@ void ft_setup(void *blob, int size, bd_t * bd)
clock = OF_TBCLK;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/timebase-frequency", &len);
if (p != NULL)
- *p = cpu_to_be32(OF_TBCLK);
+ *p = cpu_to_be32(clock);
#endif
-
#endif /* __powerpc__ */
+#ifdef CONFIG_OF_BOARD_SETUP
+ ft_board_setup(blob, bd);
+#endif
+
/*
printf("final OF-tree\n");
ft_dump_blob(blob);
diff --git a/common/hush.c b/common/hush.c
index bb5041a08d8..feb5627ff2e 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -138,6 +138,8 @@ extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /
#endif
#ifdef __U_BOOT__
+DECLARE_GLOBAL_DATA_PTR;
+
#define EXIT_SUCCESS 0
#define EOF -1
#define syntax() syntax_err()
@@ -3272,7 +3274,6 @@ int parse_file_outer(void)
#ifdef __U_BOOT__
static void u_boot_hush_reloc(void)
{
- DECLARE_GLOBAL_DATA_PTR;
unsigned long addr;
struct reserved_combo *r;
diff --git a/common/lcd.c b/common/lcd.c
index e64972fd813..0be1912a359 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -50,7 +50,6 @@
#include <lcdvideo.h>
#endif
-
#ifdef CONFIG_LCD
/************************************************************************/
@@ -68,6 +67,8 @@
# endif
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
ulong lcd_setmem (ulong addr);
static void lcd_drawchars (ushort x, ushort y, uchar *str, int count);
@@ -339,8 +340,6 @@ static void test_pattern (void)
int drv_lcd_init (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
device_t lcddev;
int rc;
@@ -682,8 +681,6 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
static void *lcd_logo (void)
{
#ifdef CONFIG_LCD_INFO
- DECLARE_GLOBAL_DATA_PTR;
-
char info[80];
char temp[32];
#endif /* CONFIG_LCD_INFO */
diff --git a/common/lynxkdi.c b/common/lynxkdi.c
index 797d8cc880d..76a271b966d 100644
--- a/common/lynxkdi.c
+++ b/common/lynxkdi.c
@@ -20,14 +20,15 @@
#if defined(CONFIG_LYNXKDI)
#include <lynxkdi.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
void lynxkdi_boot ( image_header_t *hdr )
{
- void (*lynxkdi)(void) = (void(*)(void))hdr->ih_ep;
+ void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep);
lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020;
bd_t *kbd;
- DECLARE_GLOBAL_DATA_PTR;
- u32 *psz = (u32 *)(hdr->ih_load + 0x0204);
+ u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204);
memset( parms, 0, sizeof(*parms));
kbd = gd->bd;
@@ -39,9 +40,9 @@ void lynxkdi_boot ( image_header_t *hdr )
/* Do a simple check for Bluecat so we can pass the
* kernel command line parameters.
*/
- if( le32_to_cpu(*psz) == hdr->ih_size ){
+ if( le32_to_cpu(*psz) == ntohl(hdr->ih_size) ){ /* FIXME: NOT SURE HERE ! */
char *args;
- char *cmdline = (char *)(hdr->ih_load + 0x020c);
+ char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c);
int len;
printf("Booting Bluecat KDI ...\n");
diff --git a/common/main.c b/common/main.c
index f042f3a636f..3788bd5e4a1 100644
--- a/common/main.c
+++ b/common/main.c
@@ -2,6 +2,10 @@
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
+ * Add to readline cmdline-editing by
+ * (C) Copyright 2005
+ * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com>
+ *
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -36,6 +40,10 @@
#include <post.h>
+#ifdef CONFIG_SILENT_CONSOLE
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
#if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY)
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* for do_reset() prototype */
#endif
@@ -45,7 +53,6 @@ extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#define MAX_DELAY_STOP_STR 32
-static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
static int parse_line (char *, char *[]);
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
static int abortboot(int);
@@ -55,8 +62,11 @@ static int abortboot(int);
char console_buffer[CFG_CBSIZE]; /* console I/O buffer */
+#ifndef CONFIG_CMDLINE_EDITING
+static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
static char erase_seq[] = "\b \b"; /* erase sequence */
static char tab_seq[] = " "; /* used to expand TABs */
+#endif /* CONFIG_CMDLINE_EDITING */
#ifdef CONFIG_BOOT_RETRY_TIME
static uint64_t endtime = 0; /* must be set, default is instant timeout */
@@ -105,14 +115,10 @@ static __inline__ int abortboot(int bootdelay)
u_int i;
#ifdef CONFIG_SILENT_CONSOLE
- {
- DECLARE_GLOBAL_DATA_PTR;
-
- if (gd->flags & GD_FLG_SILENT) {
- /* Restore serial console */
- console_assign (stdout, "serial");
- console_assign (stderr, "serial");
- }
+ if (gd->flags & GD_FLG_SILENT) {
+ /* Restore serial console */
+ console_assign (stdout, "serial");
+ console_assign (stderr, "serial");
}
#endif
@@ -195,17 +201,13 @@ static __inline__ int abortboot(int bootdelay)
# endif
#ifdef CONFIG_SILENT_CONSOLE
- {
- DECLARE_GLOBAL_DATA_PTR;
-
- if (abort) {
- /* permanently enable normal console output */
- gd->flags &= ~(GD_FLG_SILENT);
- } else if (gd->flags & GD_FLG_SILENT) {
- /* Restore silent console */
- console_assign (stdout, "nulldev");
- console_assign (stderr, "nulldev");
- }
+ if (abort) {
+ /* permanently enable normal console output */
+ gd->flags &= ~(GD_FLG_SILENT);
+ } else if (gd->flags & GD_FLG_SILENT) {
+ /* Restore silent console */
+ console_assign (stdout, "nulldev");
+ console_assign (stderr, "nulldev");
}
#endif
@@ -223,14 +225,10 @@ static __inline__ int abortboot(int bootdelay)
int abort = 0;
#ifdef CONFIG_SILENT_CONSOLE
- {
- DECLARE_GLOBAL_DATA_PTR;
-
- if (gd->flags & GD_FLG_SILENT) {
- /* Restore serial console */
- console_assign (stdout, "serial");
- console_assign (stderr, "serial");
- }
+ if (gd->flags & GD_FLG_SILENT) {
+ /* Restore serial console */
+ console_assign (stdout, "serial");
+ console_assign (stderr, "serial");
}
#endif
@@ -279,17 +277,13 @@ static __inline__ int abortboot(int bootdelay)
putc ('\n');
#ifdef CONFIG_SILENT_CONSOLE
- {
- DECLARE_GLOBAL_DATA_PTR;
-
- if (abort) {
- /* permanently enable normal console output */
- gd->flags &= ~(GD_FLG_SILENT);
- } else if (gd->flags & GD_FLG_SILENT) {
- /* Restore silent console */
- console_assign (stdout, "nulldev");
- console_assign (stderr, "nulldev");
- }
+ if (abort) {
+ /* permanently enable normal console output */
+ gd->flags &= ~(GD_FLG_SILENT);
+ } else if (gd->flags & GD_FLG_SILENT) {
+ /* Restore silent console */
+ console_assign (stdout, "nulldev");
+ console_assign (stderr, "nulldev");
}
#endif
@@ -528,6 +522,406 @@ void reset_cmd_timeout(void)
}
#endif
+#ifdef CONFIG_CMDLINE_EDITING
+
+/*
+ * cmdline-editing related codes from vivi.
+ * Author: Janghoon Lyu <nandy@mizi.com>
+ */
+
+#if 1 /* avoid redundand code -- wd */
+#define putnstr(str,n) do { \
+ printf ("%.*s", n, str); \
+ } while (0)
+#else
+void putnstr(const char *str, size_t n)
+{
+ if (str == NULL)
+ return;
+
+ while (n && *str != '\0') {
+ putc(*str);
+ str++;
+ n--;
+ }
+}
+#endif
+
+#define CTL_CH(c) ((c) - 'a' + 1)
+
+#define MAX_CMDBUF_SIZE 256
+
+#define CTL_BACKSPACE ('\b')
+#define DEL ((char)255)
+#define DEL7 ((char)127)
+#define CREAD_HIST_CHAR ('!')
+
+#define getcmd_putch(ch) putc(ch)
+#define getcmd_getch() getc()
+#define getcmd_cbeep() getcmd_putch('\a')
+
+#define HIST_MAX 20
+#define HIST_SIZE MAX_CMDBUF_SIZE
+
+static int hist_max = 0;
+static int hist_add_idx = 0;
+static int hist_cur = -1;
+unsigned hist_num = 0;
+
+char* hist_list[HIST_MAX];
+char hist_lines[HIST_MAX][HIST_SIZE];
+
+#define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1)
+
+static void hist_init(void)
+{
+ int i;
+
+ hist_max = 0;
+ hist_add_idx = 0;
+ hist_cur = -1;
+ hist_num = 0;
+
+ for (i = 0; i < HIST_MAX; i++) {
+ hist_list[i] = hist_lines[i];
+ hist_list[i][0] = '\0';
+ }
+}
+
+static void cread_add_to_hist(char *line)
+{
+ strcpy(hist_list[hist_add_idx], line);
+
+ if (++hist_add_idx >= HIST_MAX)
+ hist_add_idx = 0;
+
+ if (hist_add_idx > hist_max)
+ hist_max = hist_add_idx;
+
+ hist_num++;
+}
+
+static char* hist_prev(void)
+{
+ char *ret;
+ int old_cur;
+
+ if (hist_cur < 0)
+ return NULL;
+
+ old_cur = hist_cur;
+ if (--hist_cur < 0)
+ hist_cur = hist_max;
+
+ if (hist_cur == hist_add_idx) {
+ hist_cur = old_cur;
+ ret = NULL;
+ } else
+ ret = hist_list[hist_cur];
+
+ return (ret);
+}
+
+static char* hist_next(void)
+{
+ char *ret;
+
+ if (hist_cur < 0)
+ return NULL;
+
+ if (hist_cur == hist_add_idx)
+ return NULL;
+
+ if (++hist_cur > hist_max)
+ hist_cur = 0;
+
+ if (hist_cur == hist_add_idx) {
+ ret = "";
+ } else
+ ret = hist_list[hist_cur];
+
+ return (ret);
+}
+
+#ifndef CONFIG_CMDLINE_EDITING
+static void cread_print_hist_list(void)
+{
+ int i;
+ unsigned long n;
+
+ n = hist_num - hist_max;
+
+ i = hist_add_idx + 1;
+ while (1) {
+ if (i > hist_max)
+ i = 0;
+ if (i == hist_add_idx)
+ break;
+ printf("%s\n", hist_list[i]);
+ n++;
+ i++;
+ }
+}
+#endif /* CONFIG_CMDLINE_EDITING */
+
+#define BEGINNING_OF_LINE() { \
+ while (num) { \
+ getcmd_putch(CTL_BACKSPACE); \
+ num--; \
+ } \
+}
+
+#define ERASE_TO_EOL() { \
+ if (num < eol_num) { \
+ int tmp; \
+ for (tmp = num; tmp < eol_num; tmp++) \
+ getcmd_putch(' '); \
+ while (tmp-- > num) \
+ getcmd_putch(CTL_BACKSPACE); \
+ eol_num = num; \
+ } \
+}
+
+#define REFRESH_TO_EOL() { \
+ if (num < eol_num) { \
+ wlen = eol_num - num; \
+ putnstr(buf + num, wlen); \
+ num = eol_num; \
+ } \
+}
+
+static void cread_add_char(char ichar, int insert, unsigned long *num,
+ unsigned long *eol_num, char *buf, unsigned long len)
+{
+ unsigned long wlen;
+
+ /* room ??? */
+ if (insert || *num == *eol_num) {
+ if (*eol_num > len - 1) {
+ getcmd_cbeep();
+ return;
+ }
+ (*eol_num)++;
+ }
+
+ if (insert) {
+ wlen = *eol_num - *num;
+ if (wlen > 1) {
+ memmove(&buf[*num+1], &buf[*num], wlen-1);
+ }
+
+ buf[*num] = ichar;
+ putnstr(buf + *num, wlen);
+ (*num)++;
+ while (--wlen) {
+ getcmd_putch(CTL_BACKSPACE);
+ }
+ } else {
+ /* echo the character */
+ wlen = 1;
+ buf[*num] = ichar;
+ putnstr(buf + *num, wlen);
+ (*num)++;
+ }
+}
+
+static void cread_add_str(char *str, int strsize, int insert, unsigned long *num,
+ unsigned long *eol_num, char *buf, unsigned long len)
+{
+ while (strsize--) {
+ cread_add_char(*str, insert, num, eol_num, buf, len);
+ str++;
+ }
+}
+
+static int cread_line(char *buf, unsigned int *len)
+{
+ unsigned long num = 0;
+ unsigned long eol_num = 0;
+ unsigned long rlen;
+ unsigned long wlen;
+ char ichar;
+ int insert = 1;
+ int esc_len = 0;
+ int rc = 0;
+ char esc_save[8];
+
+ while (1) {
+ rlen = 1;
+ ichar = getcmd_getch();
+
+ if ((ichar == '\n') || (ichar == '\r')) {
+ putc('\n');
+ break;
+ }
+
+ /*
+ * handle standard linux xterm esc sequences for arrow key, etc.
+ */
+ if (esc_len != 0) {
+ if (esc_len == 1) {
+ if (ichar == '[') {
+ esc_save[esc_len] = ichar;
+ esc_len = 2;
+ } else {
+ cread_add_str(esc_save, esc_len, insert,
+ &num, &eol_num, buf, *len);
+ esc_len = 0;
+ }
+ continue;
+ }
+
+ switch (ichar) {
+
+ case 'D': /* <- key */
+ ichar = CTL_CH('b');
+ esc_len = 0;
+ break;
+ case 'C': /* -> key */
+ ichar = CTL_CH('f');
+ esc_len = 0;
+ break; /* pass off to ^F handler */
+ case 'H': /* Home key */
+ ichar = CTL_CH('a');
+ esc_len = 0;
+ break; /* pass off to ^A handler */
+ case 'A': /* up arrow */
+ ichar = CTL_CH('p');
+ esc_len = 0;
+ break; /* pass off to ^P handler */
+ case 'B': /* down arrow */
+ ichar = CTL_CH('n');
+ esc_len = 0;
+ break; /* pass off to ^N handler */
+ default:
+ esc_save[esc_len++] = ichar;
+ cread_add_str(esc_save, esc_len, insert,
+ &num, &eol_num, buf, *len);
+ esc_len = 0;
+ continue;
+ }
+ }
+
+ switch (ichar) {
+ case 0x1b:
+ if (esc_len == 0) {
+ esc_save[esc_len] = ichar;
+ esc_len = 1;
+ } else {
+ puts("impossible condition #876\n");
+ esc_len = 0;
+ }
+ break;
+
+ case CTL_CH('a'):
+ BEGINNING_OF_LINE();
+ break;
+ case CTL_CH('c'): /* ^C - break */
+ *buf = '\0'; /* discard input */
+ return (-1);
+ case CTL_CH('f'):
+ if (num < eol_num) {
+ getcmd_putch(buf[num]);
+ num++;
+ }
+ break;
+ case CTL_CH('b'):
+ if (num) {
+ getcmd_putch(CTL_BACKSPACE);
+ num--;
+ }
+ break;
+ case CTL_CH('d'):
+ if (num < eol_num) {
+ wlen = eol_num - num - 1;
+ if (wlen) {
+ memmove(&buf[num], &buf[num+1], wlen);
+ putnstr(buf + num, wlen);
+ }
+
+ getcmd_putch(' ');
+ do {
+ getcmd_putch(CTL_BACKSPACE);
+ } while (wlen--);
+ eol_num--;
+ }
+ break;
+ case CTL_CH('k'):
+ ERASE_TO_EOL();
+ break;
+ case CTL_CH('e'):
+ REFRESH_TO_EOL();
+ break;
+ case CTL_CH('o'):
+ insert = !insert;
+ break;
+ case CTL_CH('x'):
+ BEGINNING_OF_LINE();
+ ERASE_TO_EOL();
+ break;
+ case DEL:
+ case DEL7:
+ case 8:
+ if (num) {
+ wlen = eol_num - num;
+ num--;
+ memmove(&buf[num], &buf[num+1], wlen);
+ getcmd_putch(CTL_BACKSPACE);
+ putnstr(buf + num, wlen);
+ getcmd_putch(' ');
+ do {
+ getcmd_putch(CTL_BACKSPACE);
+ } while (wlen--);
+ eol_num--;
+ }
+ break;
+ case CTL_CH('p'):
+ case CTL_CH('n'):
+ {
+ char * hline;
+
+ esc_len = 0;
+
+ if (ichar == CTL_CH('p'))
+ hline = hist_prev();
+ else
+ hline = hist_next();
+
+ if (!hline) {
+ getcmd_cbeep();
+ continue;
+ }
+
+ /* nuke the current line */
+ /* first, go home */
+ BEGINNING_OF_LINE();
+
+ /* erase to end of line */
+ ERASE_TO_EOL();
+
+ /* copy new line into place and display */
+ strcpy(buf, hline);
+ eol_num = strlen(buf);
+ REFRESH_TO_EOL();
+ continue;
+ }
+ default:
+ cread_add_char(ichar, insert, &num, &eol_num, buf, *len);
+ break;
+ }
+ }
+ *len = eol_num;
+ buf[eol_num] = '\0'; /* lose the newline */
+
+ if (buf[0] && buf[0] != CREAD_HIST_CHAR)
+ cread_add_to_hist(buf);
+ hist_cur = hist_add_idx;
+
+ return (rc);
+}
+
+#endif /* CONFIG_CMDLINE_EDITING */
+
/****************************************************************************/
/*
@@ -540,6 +934,21 @@ void reset_cmd_timeout(void)
*/
int readline (const char *const prompt)
{
+#ifdef CONFIG_CMDLINE_EDITING
+ char *p = console_buffer;
+ unsigned int len=MAX_CMDBUF_SIZE;
+ static int initted = 0;
+
+ if (!initted) {
+ hist_init();
+ initted = 1;
+ }
+
+ puts (prompt);
+
+ cread_line(p, &len);
+ return len;
+#else
char *p = console_buffer;
int n = 0; /* buffer index */
int plen = 0; /* prompt length */
@@ -635,10 +1044,12 @@ int readline (const char *const prompt)
}
}
}
+#endif /* CONFIG_CMDLINE_EDITING */
}
/****************************************************************************/
+#ifndef CONFIG_CMDLINE_EDITING
static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen)
{
char *s;
@@ -668,6 +1079,7 @@ static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen)
(*np)--;
return (p);
}
+#endif /* CONFIG_CMDLINE_EDITING */
/****************************************************************************/
@@ -919,7 +1331,10 @@ int run_command (const char *cmd, int flag)
process_macros (token, finaltoken);
/* Extract arguments */
- argc = parse_line (finaltoken, argv);
+ if ((argc = parse_line (finaltoken, argv)) == 0) {
+ rc = -1; /* no command at all */
+ continue;
+ }
/* Look up command in command table */
if ((cmdtp = find_cmd(argv[0])) == NULL) {
@@ -945,9 +1360,9 @@ int run_command (const char *cmd, int flag)
puts ("'bootd' recursion detected\n");
rc = -1;
continue;
- }
- else
+ } else {
flag |= CMD_FLAG_BOOTD;
+ }
}
#endif /* CFG_CMD_BOOTD */
diff --git a/common/serial.c b/common/serial.c
index 22d8fd0584f..38057d21f6c 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -25,6 +25,8 @@
#include <serial.h>
#include <devices.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if defined(CONFIG_SERIAL_MULTI)
static struct serial_device *serial_devices = NULL;
@@ -39,8 +41,12 @@ struct serial_device *default_serial_console (void)
|| defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
return &serial_scc_device;
#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
- || defined(CONFIG_405EP)
- return &serial0_device;
+ || defined(CONFIG_405EP) || defined(CONFIG_MPC5xxx)
+#if defined(CONFIG_UART1_CONSOLE)
+ return &serial1_device;
+#else
+ return &serial0_device;
+#endif
#else
#error No default console
#endif
@@ -49,8 +55,6 @@ struct serial_device *default_serial_console (void)
static int serial_register (struct serial_device *dev)
{
- DECLARE_GLOBAL_DATA_PTR;
-
dev->init += gd->reloc_off;
dev->setbrg += gd->reloc_off;
dev->getc += gd->reloc_off;
@@ -75,7 +79,7 @@ void serial_initialize (void)
#endif
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
- || defined(CONFIG_405EP)
+ || defined(CONFIG_405EP) || defined(CONFIG_MPC5xxx)
serial_register(&serial0_device);
serial_register(&serial1_device);
#endif
@@ -131,8 +135,6 @@ void serial_reinit_all (void)
int serial_init (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
struct serial_device *dev = default_serial_console ();
@@ -144,8 +146,6 @@ int serial_init (void)
void serial_setbrg (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
struct serial_device *dev = default_serial_console ();
@@ -158,8 +158,6 @@ void serial_setbrg (void)
int serial_getc (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
struct serial_device *dev = default_serial_console ();
@@ -171,8 +169,6 @@ int serial_getc (void)
int serial_tstc (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
struct serial_device *dev = default_serial_console ();
@@ -184,8 +180,6 @@ int serial_tstc (void)
void serial_putc (const char c)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
struct serial_device *dev = default_serial_console ();
@@ -198,8 +192,6 @@ void serial_putc (const char c)
void serial_puts (const char *s)
{
- DECLARE_GLOBAL_DATA_PTR;
-
if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
struct serial_device *dev = default_serial_console ();
diff --git a/common/soft_i2c.c b/common/soft_i2c.c
index 3d0e08c6ff3..edad51bc418 100644
--- a/common/soft_i2c.c
+++ b/common/soft_i2c.c
@@ -33,12 +33,19 @@
#include <asm/io.h>
#include <asm/arch/hardware.h>
#endif
+#ifdef CONFIG_IXP425 /* only valid for IXP425 */
+#include <asm/arch/ixp425.h>
+#endif
#include <i2c.h>
#if defined(CONFIG_SOFT_I2C)
/* #define DEBUG_I2C */
+#ifdef DEBUG_I2C
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
/*-----------------------------------------------------------------------
* Definitions
@@ -53,7 +60,6 @@
#ifdef DEBUG_I2C
#define PRINTD(fmt,args...) do { \
- DECLARE_GLOBAL_DATA_PTR; \
if (gd->have_console) \
printf (fmt ,##args); \
} while (0)
@@ -164,13 +170,10 @@ static void send_ack(int ack)
volatile immap_t *immr = (immap_t *)CFG_IMMR;
#endif
- I2C_ACTIVE;
I2C_SCL(0);
I2C_DELAY;
-
- I2C_SDA(ack);
-
I2C_ACTIVE;
+ I2C_SDA(ack);
I2C_DELAY;
I2C_SCL(1);
I2C_DELAY;
@@ -288,7 +291,10 @@ int i2c_probe(uchar addr)
{
int rc;
- /* perform 1 byte read transaction */
+ /*
+ * perform 1 byte write transaction with just address byte
+ * (fake write)
+ */
send_start();
rc = write_byte ((addr << 1) | 0);
send_stop();
diff --git a/common/usb.c b/common/usb.c
index d9515e659cf..0857494b27b 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -72,6 +72,8 @@ static int running;
static int asynch_allowed;
static struct devrequest setup_packet;
+char usb_started; /* flag for the started/stopped USB status */
+
/**********************************************************************
* some forward declerations...
*/
@@ -110,10 +112,12 @@ int usb_init(void)
printf("scanning bus for devices... ");
running=1;
usb_scan_devices();
+ usb_started = 1;
return 0;
}
else {
printf("Error, couldn't init Lowlevel part\n");
+ usb_started = 0;
return -1;
}
}
@@ -124,6 +128,7 @@ int usb_init(void)
int usb_stop(void)
{
asynch_allowed=1;
+ usb_started = 0;
usb_hub_reset();
return usb_lowlevel_stop();
}
@@ -280,56 +285,68 @@ int usb_set_maxpacket(struct usb_device *dev)
int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
{
struct usb_descriptor_header *head;
- int index,ifno,epno;
- ifno=-1;
- epno=-1;
-
- dev->configno=cfgno;
- head =(struct usb_descriptor_header *)&buffer[0];
- if(head->bDescriptorType!=USB_DT_CONFIG) {
- printf(" ERROR: NOT USB_CONFIG_DESC %x\n",head->bDescriptorType);
+ int index, ifno, epno, curr_if_num;
+ int i;
+ unsigned char *ch;
+
+ ifno = -1;
+ epno = -1;
+ curr_if_num = -1;
+
+ dev->configno = cfgno;
+ head = (struct usb_descriptor_header *) &buffer[0];
+ if(head->bDescriptorType != USB_DT_CONFIG) {
+ printf(" ERROR: NOT USB_CONFIG_DESC %x\n", head->bDescriptorType);
return -1;
}
- memcpy(&dev->config,buffer,buffer[0]);
- dev->config.wTotalLength=swap_16(dev->config.wTotalLength);
- dev->config.no_of_if=0;
+ memcpy(&dev->config, buffer, buffer[0]);
+ dev->config.wTotalLength = swap_16(dev->config.wTotalLength);
+ dev->config.no_of_if = 0;
- index=dev->config.bLength;
+ index = dev->config.bLength;
/* Ok the first entry must be a configuration entry, now process the others */
- head=(struct usb_descriptor_header *)&buffer[index];
- while(index+1 < dev->config.wTotalLength) {
+ head = (struct usb_descriptor_header *) &buffer[index];
+ while(index + 1 < dev->config.wTotalLength) {
switch(head->bDescriptorType) {
case USB_DT_INTERFACE:
- ifno=dev->config.no_of_if;
- dev->config.no_of_if++; /* found an interface desc, increase numbers */
- memcpy(&dev->config.if_desc[ifno],&buffer[index],buffer[index]); /* copy new desc */
- dev->config.if_desc[ifno].no_of_ep=0;
-
+ if(((struct usb_interface_descriptor *) &buffer[index])->
+ bInterfaceNumber != curr_if_num) {
+ /* this is a new interface, copy new desc */
+ ifno = dev->config.no_of_if;
+ dev->config.no_of_if++;
+ memcpy(&dev->config.if_desc[ifno],
+ &buffer[index], buffer[index]);
+ dev->config.if_desc[ifno].no_of_ep = 0;
+ dev->config.if_desc[ifno].num_altsetting = 1;
+ curr_if_num = dev->config.if_desc[ifno].bInterfaceNumber;
+ } else {
+ /* found alternate setting for the interface */
+ dev->config.if_desc[ifno].num_altsetting++;
+ }
break;
case USB_DT_ENDPOINT:
- epno=dev->config.if_desc[ifno].no_of_ep;
+ epno = dev->config.if_desc[ifno].no_of_ep;
dev->config.if_desc[ifno].no_of_ep++; /* found an endpoint */
- memcpy(&dev->config.if_desc[ifno].ep_desc[epno],&buffer[index],buffer[index]);
- dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize
- =swap_16(dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize);
- USB_PRINTF("if %d, ep %d\n",ifno,epno);
+ memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
+ &buffer[index], buffer[index]);
+ dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize =
+ swap_16(dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize);
+ USB_PRINTF("if %d, ep %d\n", ifno, epno);
break;
default:
- if(head->bLength==0)
+ if(head->bLength == 0)
return 1;
- USB_PRINTF("unknown Description Type : %x\n",head->bDescriptorType);
+ USB_PRINTF("unknown Description Type : %x\n", head->bDescriptorType);
{
- int i;
- unsigned char *ch;
- ch=(unsigned char *)head;
- for(i=0;i<head->bLength; i++)
- USB_PRINTF("%02X ",*ch++);
+ ch = (unsigned char *)head;
+ for(i = 0; i < head->bLength; i++)
+ USB_PRINTF("%02X ", *ch++);
USB_PRINTF("\n\n\n");
}
break;
}
- index+=head->bLength;
- head=(struct usb_descriptor_header *)&buffer[index];
+ index += head->bLength;
+ head = (struct usb_descriptor_header *)&buffer[index];
}
return 1;
}
@@ -443,6 +460,14 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
printf("selecting invalid interface %d", interface);
return -1;
}
+ /*
+ * We should return now for devices with only one alternate setting.
+ * According to 9.4.10 of the Universal Serial Bus Specification Revision 2.0
+ * such devices can return with a STALL. This results in some USB sticks
+ * timeouting during initialization and then being unusable in U-Boot.
+ */
+ if (if_face->num_altsetting == 1)
+ return 0;
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 99e4ab0d233..e64470cb91f 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -1139,6 +1139,10 @@ int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t
/* USB007 Mini-USB2 Flash Drive */
(dev->descriptor.idVendor == 0x066f &&
dev->descriptor.idProduct == 0x2010)
+ ||
+ /* SanDisk Corporation Cruzer Micro 20044318410546613953 */
+ (dev->descriptor.idVendor == 0x0781 &&
+ dev->descriptor.idProduct == 0x5151)
)
USB_STOR_PRINTF("usb_stor_get_info: skipping RESET..\n");
else
diff --git a/common/xyzModem.c b/common/xyzModem.c
new file mode 100644
index 00000000000..d1d66e8bb30
--- /dev/null
+++ b/common/xyzModem.c
@@ -0,0 +1,746 @@
+/*
+ *==========================================================================
+ *
+ * xyzModem.c
+ *
+ * RedBoot stream handler for xyzModem protocol
+ *
+ *==========================================================================
+ *####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating System.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+ * Copyright (C) 2002 Gary Thomas
+ *
+ * eCos 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 or (at your option) any later version.
+ *
+ * eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * As a special exception, if other files instantiate templates or use macros
+ * or inline functions from this file, or you compile this file and link it
+ * with other works to produce a work based on this file, this file does not
+ * by itself cause the resulting work to be covered by the GNU General Public
+ * License. However the source code for this file must still be made available
+ * in accordance with section (3) of the GNU General Public License.
+ *
+ * This exception does not invalidate any other reasons why a work based on
+ * this file might be covered by the GNU General Public License.
+ *
+ * Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+ * at http: *sources.redhat.com/ecos/ecos-license/
+ * -------------------------------------------
+ *####ECOSGPLCOPYRIGHTEND####
+ *==========================================================================
+ *#####DESCRIPTIONBEGIN####
+ *
+ * Author(s): gthomas
+ * Contributors: gthomas, tsmith, Yoshinori Sato
+ * Date: 2000-07-14
+ * Purpose:
+ * Description:
+ *
+ * This code is part of RedBoot (tm).
+ *
+ *####DESCRIPTIONEND####
+ *
+ *==========================================================================
+ */
+#include <common.h>
+#include <xyzModem.h>
+#include <stdarg.h>
+#include <crc.h>
+
+/* Assumption - run xyzModem protocol over the console port */
+
+/* Values magic to the protocol */
+#define SOH 0x01
+#define STX 0x02
+#define EOT 0x04
+#define ACK 0x06
+#define BSP 0x08
+#define NAK 0x15
+#define CAN 0x18
+#define EOF 0x1A /* ^Z for DOS officionados */
+
+#define USE_YMODEM_LENGTH
+
+/* Data & state local to the protocol */
+static struct {
+#ifdef REDBOOT
+ hal_virtual_comm_table_t* __chan;
+#else
+ int *__chan;
+#endif
+ unsigned char pkt[1024], *bufp;
+ unsigned char blk,cblk,crc1,crc2;
+ unsigned char next_blk; /* Expected block */
+ int len, mode, total_retries;
+ int total_SOH, total_STX, total_CAN;
+ bool crc_mode, at_eof, tx_ack;
+#ifdef USE_YMODEM_LENGTH
+ unsigned long file_length, read_length;
+#endif
+} xyz;
+
+#define xyzModem_CHAR_TIMEOUT 2000 /* 2 seconds */
+#define xyzModem_MAX_RETRIES 20
+#define xyzModem_MAX_RETRIES_WITH_CRC 10
+#define xyzModem_CAN_COUNT 3 /* Wait for 3 CAN before quitting */
+
+
+#ifndef REDBOOT /*SB */
+typedef int cyg_int32;
+int CYGACC_COMM_IF_GETC_TIMEOUT (char chan,char *c) {
+#define DELAY 20
+ unsigned long counter=0;
+ while (!tstc() && (counter < xyzModem_CHAR_TIMEOUT*1000/DELAY)) {
+ udelay(DELAY);
+ counter++;
+ }
+ if (tstc()) {
+ *c=getc();
+ return 1;
+ }
+ return 0;
+}
+
+void CYGACC_COMM_IF_PUTC(char x,char y) {
+ putc(y);
+}
+
+/* Validate a hex character */
+__inline__ static bool
+_is_hex(char c)
+{
+ return (((c >= '0') && (c <= '9')) ||
+ ((c >= 'A') && (c <= 'F')) ||
+ ((c >= 'a') && (c <= 'f')));
+}
+
+/* Convert a single hex nibble */
+__inline__ static int
+_from_hex(char c)
+{
+ int ret = 0;
+
+ if ((c >= '0') && (c <= '9')) {
+ ret = (c - '0');
+ } else if ((c >= 'a') && (c <= 'f')) {
+ ret = (c - 'a' + 0x0a);
+ } else if ((c >= 'A') && (c <= 'F')) {
+ ret = (c - 'A' + 0x0A);
+ }
+ return ret;
+}
+
+/* Convert a character to lower case */
+__inline__ static char
+_tolower(char c)
+{
+ if ((c >= 'A') && (c <= 'Z')) {
+ c = (c - 'A') + 'a';
+ }
+ return c;
+}
+
+/* Parse (scan) a number */
+bool
+parse_num(char *s, unsigned long *val, char **es, char *delim)
+{
+ bool first = true;
+ int radix = 10;
+ char c;
+ unsigned long result = 0;
+ int digit;
+
+ while (*s == ' ') s++;
+ while (*s) {
+ if (first && (s[0] == '0') && (_tolower(s[1]) == 'x')) {
+ radix = 16;
+ s += 2;
+ }
+ first = false;
+ c = *s++;
+ if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) {
+ /* Valid digit */
+#ifdef CYGPKG_HAL_MIPS
+ /* FIXME: tx49 compiler generates 0x2539018 for MUL which */
+ /* isn't any good. */
+ if (16 == radix)
+ result = result << 4;
+ else
+ result = 10 * result;
+ result += digit;
+#else
+ result = (result * radix) + digit;
+#endif
+ } else {
+ if (delim != (char *)0) {
+ /* See if this character is one of the delimiters */
+ char *dp = delim;
+ while (*dp && (c != *dp)) dp++;
+ if (*dp) break; /* Found a good delimiter */
+ }
+ return false; /* Malformatted number */
+ }
+ }
+ *val = result;
+ if (es != (char **)0) {
+ *es = s;
+ }
+ return true;
+}
+
+#endif
+
+#define USE_SPRINTF
+#ifdef DEBUG
+#ifndef USE_SPRINTF
+/*
+ * Note: this debug setup only works if the target platform has two serial ports
+ * available so that the other one (currently only port 1) can be used for debug
+ * messages.
+ */
+static int
+zm_dprintf(char *fmt, ...)
+{
+ int cur_console;
+ va_list args;
+
+ va_start(args, fmt);
+#ifdef REDBOOT
+ cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+#endif
+ diag_vprintf(fmt, args);
+#ifdef REDBOOT
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console);
+#endif
+}
+
+static void
+zm_flush(void)
+{
+}
+
+#else
+/*
+ * Note: this debug setup works by storing the strings in a fixed buffer
+ */
+#define FINAL
+#ifdef FINAL
+static char *zm_out = (char *)0x00380000;
+static char *zm_out_start = (char *)0x00380000;
+#else
+static char zm_buf[8192];
+static char *zm_out=zm_buf;
+static char *zm_out_start = zm_buf;
+
+#endif
+static int
+zm_dprintf(char *fmt, ...)
+{
+ int len;
+ va_list args;
+
+ va_start(args, fmt);
+ len = diag_vsprintf(zm_out, fmt, args);
+ zm_out += len;
+ return len;
+}
+
+static void
+zm_flush(void)
+{
+#ifdef REDBOOT
+ char *p = zm_out_start;
+ while (*p) mon_write_char(*p++);
+#endif
+ zm_out = zm_out_start;
+}
+#endif
+
+static void
+zm_dump_buf(void *buf, int len)
+{
+#ifdef REDBOOT
+ diag_vdump_buf_with_offset(zm_dprintf, buf, len, 0);
+#else
+
+#endif
+}
+
+static unsigned char zm_buf[2048];
+static unsigned char *zm_bp;
+
+static void
+zm_new(void)
+{
+ zm_bp = zm_buf;
+}
+
+static void
+zm_save(unsigned char c)
+{
+ *zm_bp++ = c;
+}
+
+static void
+zm_dump(int line)
+{
+ zm_dprintf("Packet at line: %d\n", line);
+ zm_dump_buf(zm_buf, zm_bp-zm_buf);
+}
+
+#define ZM_DEBUG(x) x
+#else
+#define ZM_DEBUG(x)
+#endif
+
+/* Wait for the line to go idle */
+static void
+xyzModem_flush(void)
+{
+ int res;
+ char c;
+ while (true) {
+ res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c);
+ if (!res) return;
+ }
+}
+
+static int
+xyzModem_get_hdr(void)
+{
+ char c;
+ int res;
+ bool hdr_found = false;
+ int i, can_total, hdr_chars;
+ unsigned short cksum;
+
+ ZM_DEBUG(zm_new());
+ /* Find the start of a header */
+ can_total = 0;
+ hdr_chars = 0;
+
+ if (xyz.tx_ack) {
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
+ xyz.tx_ack = false;
+ }
+ while (!hdr_found) {
+ res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c);
+ ZM_DEBUG(zm_save(c));
+ if (res) {
+ hdr_chars++;
+ switch (c) {
+ case SOH:
+ xyz.total_SOH++;
+ case STX:
+ if (c == STX) xyz.total_STX++;
+ hdr_found = true;
+ break;
+ case CAN:
+ xyz.total_CAN++;
+ ZM_DEBUG(zm_dump(__LINE__));
+ if (++can_total == xyzModem_CAN_COUNT) {
+ return xyzModem_cancel;
+ } else {
+ /* Wait for multiple CAN to avoid early quits */
+ break;
+ }
+ case EOT:
+ /* EOT only supported if no noise */
+ if (hdr_chars == 1) {
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
+ ZM_DEBUG(zm_dprintf("ACK on EOT #%d\n", __LINE__));
+ ZM_DEBUG(zm_dump(__LINE__));
+ return xyzModem_eof;
+ }
+ default:
+ /* Ignore, waiting for start of header */
+ ;
+ }
+ } else {
+ /* Data stream timed out */
+ xyzModem_flush(); /* Toss any current input */
+ ZM_DEBUG(zm_dump(__LINE__));
+ CYGACC_CALL_IF_DELAY_US((cyg_int32)250000);
+ return xyzModem_timeout;
+ }
+ }
+
+ /* Header found, now read the data */
+ res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.blk);
+ ZM_DEBUG(zm_save(xyz.blk));
+ if (!res) {
+ ZM_DEBUG(zm_dump(__LINE__));
+ return xyzModem_timeout;
+ }
+ res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.cblk);
+ ZM_DEBUG(zm_save(xyz.cblk));
+ if (!res) {
+ ZM_DEBUG(zm_dump(__LINE__));
+ return xyzModem_timeout;
+ }
+ xyz.len = (c == SOH) ? 128 : 1024;
+ xyz.bufp = xyz.pkt;
+ for (i = 0; i < xyz.len; i++) {
+ res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c);
+ ZM_DEBUG(zm_save(c));
+ if (res) {
+ xyz.pkt[i] = c;
+ } else {
+ ZM_DEBUG(zm_dump(__LINE__));
+ return xyzModem_timeout;
+ }
+ }
+ res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.crc1);
+ ZM_DEBUG(zm_save(xyz.crc1));
+ if (!res) {
+ ZM_DEBUG(zm_dump(__LINE__));
+ return xyzModem_timeout;
+ }
+ if (xyz.crc_mode) {
+ res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, (char *)&xyz.crc2);
+ ZM_DEBUG(zm_save(xyz.crc2));
+ if (!res) {
+ ZM_DEBUG(zm_dump(__LINE__));
+ return xyzModem_timeout;
+ }
+ }
+ ZM_DEBUG(zm_dump(__LINE__));
+ /* Validate the message */
+ if ((xyz.blk ^ xyz.cblk) != (unsigned char)0xFF) {
+ ZM_DEBUG(zm_dprintf("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, (xyz.blk ^ xyz.cblk)));
+ ZM_DEBUG(zm_dump_buf(xyz.pkt, xyz.len));
+ xyzModem_flush();
+ return xyzModem_frame;
+ }
+ /* Verify checksum/CRC */
+ if (xyz.crc_mode) {
+ cksum = cyg_crc16(xyz.pkt, xyz.len);
+ if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) {
+ ZM_DEBUG(zm_dprintf("CRC error - recvd: %02x%02x, computed: %x\n",
+ xyz.crc1, xyz.crc2, cksum & 0xFFFF));
+ return xyzModem_cksum;
+ }
+ } else {
+ cksum = 0;
+ for (i = 0; i < xyz.len; i++) {
+ cksum += xyz.pkt[i];
+ }
+ if (xyz.crc1 != (cksum & 0xFF)) {
+ ZM_DEBUG(zm_dprintf("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, cksum & 0xFF));
+ return xyzModem_cksum;
+ }
+ }
+ /* If we get here, the message passes [structural] muster */
+ return 0;
+}
+
+int
+xyzModem_stream_open(connection_info_t *info, int *err)
+{
+#ifdef REDBOOT
+ int console_chan;
+#endif
+ int stat = 0;
+ int retries = xyzModem_MAX_RETRIES;
+ int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC;
+
+/* ZM_DEBUG(zm_out = zm_out_start); */
+#ifdef xyzModem_zmodem
+ if (info->mode == xyzModem_zmodem) {
+ *err = xyzModem_noZmodem;
+ return -1;
+ }
+#endif
+
+#ifdef REDBOOT
+ /* Set up the I/O channel. Note: this allows for using a different port in the future */
+ console_chan = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+ if (info->chan >= 0) {
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(info->chan);
+ } else {
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan);
+ }
+ xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan);
+ CYGACC_COMM_IF_CONTROL(*xyz.__chan, __COMMCTL_SET_TIMEOUT, xyzModem_CHAR_TIMEOUT);
+#else
+/* TODO: CHECK ! */
+ int dummy;
+ xyz.__chan=&dummy;
+#endif
+ xyz.len = 0;
+ xyz.crc_mode = true;
+ xyz.at_eof = false;
+ xyz.tx_ack = false;
+ xyz.mode = info->mode;
+ xyz.total_retries = 0;
+ xyz.total_SOH = 0;
+ xyz.total_STX = 0;
+ xyz.total_CAN = 0;
+#ifdef USE_YMODEM_LENGTH
+ xyz.read_length = 0;
+ xyz.file_length = 0;
+#endif
+
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
+
+ if (xyz.mode == xyzModem_xmodem) {
+ /* X-modem doesn't have an information header - exit here */
+ xyz.next_blk = 1;
+ return 0;
+ }
+
+ while (retries-- > 0) {
+ stat = xyzModem_get_hdr();
+ if (stat == 0) {
+ /* Y-modem file information header */
+ if (xyz.blk == 0) {
+#ifdef USE_YMODEM_LENGTH
+ /* skip filename */
+ while (*xyz.bufp++);
+ /* get the length */
+ parse_num((char *)xyz.bufp, &xyz.file_length, NULL, " ");
+#endif
+ /* The rest of the file name data block quietly discarded */
+ xyz.tx_ack = true;
+ }
+ xyz.next_blk = 1;
+ xyz.len = 0;
+ return 0;
+ } else
+ if (stat == xyzModem_timeout) {
+ if (--crc_retries <= 0) xyz.crc_mode = false;
+ CYGACC_CALL_IF_DELAY_US(5*100000); /* Extra delay for startup */
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
+ xyz.total_retries++;
+ ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__));
+ }
+ if (stat == xyzModem_cancel) {
+ break;
+ }
+ }
+ *err = stat;
+ ZM_DEBUG(zm_flush());
+ return -1;
+}
+
+int
+xyzModem_stream_read(char *buf, int size, int *err)
+{
+ int stat, total, len;
+ int retries;
+
+ total = 0;
+ stat = xyzModem_cancel;
+ /* Try and get 'size' bytes into the buffer */
+ while (!xyz.at_eof && (size > 0)) {
+ if (xyz.len == 0) {
+ retries = xyzModem_MAX_RETRIES;
+ while (retries-- > 0) {
+ stat = xyzModem_get_hdr();
+ if (stat == 0) {
+ if (xyz.blk == xyz.next_blk) {
+ xyz.tx_ack = true;
+ ZM_DEBUG(zm_dprintf("ACK block %d (%d)\n", xyz.blk, __LINE__));
+ xyz.next_blk = (xyz.next_blk + 1) & 0xFF;
+
+#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH)
+ if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) {
+#else
+ if (1) {
+#endif
+ /* Data blocks can be padded with ^Z (EOF) characters */
+ /* This code tries to detect and remove them */
+ if ((xyz.bufp[xyz.len-1] == EOF) &&
+ (xyz.bufp[xyz.len-2] == EOF) &&
+ (xyz.bufp[xyz.len-3] == EOF)) {
+ while (xyz.len && (xyz.bufp[xyz.len-1] == EOF)) {
+ xyz.len--;
+ }
+ }
+ }
+
+#ifdef USE_YMODEM_LENGTH
+ /*
+ * See if accumulated length exceeds that of the file.
+ * If so, reduce size (i.e., cut out pad bytes)
+ * Only do this for Y-modem (and Z-modem should it ever
+ * be supported since it can fall back to Y-modem mode).
+ */
+ if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length) {
+ xyz.read_length += xyz.len;
+ if (xyz.read_length > xyz.file_length) {
+ xyz.len -= (xyz.read_length - xyz.file_length);
+ }
+ }
+#endif
+ break;
+ } else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF)) {
+ /* Just re-ACK this so sender will get on with it */
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
+ continue; /* Need new header */
+ } else {
+ stat = xyzModem_sequence;
+ }
+ }
+ if (stat == xyzModem_cancel) {
+ break;
+ }
+ if (stat == xyzModem_eof) {
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
+ ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__));
+ if (xyz.mode == xyzModem_ymodem) {
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
+ xyz.total_retries++;
+ ZM_DEBUG(zm_dprintf("Reading Final Header\n"));
+ stat = xyzModem_get_hdr();
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
+ ZM_DEBUG(zm_dprintf("FINAL ACK (%d)\n", __LINE__));
+ }
+ xyz.at_eof = true;
+ break;
+ }
+ CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
+ xyz.total_retries++;
+ ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__));
+ }
+ if (stat < 0) {
+ *err = stat;
+ xyz.len = -1;
+ return total;
+ }
+ }
+ /* Don't "read" data from the EOF protocol package */
+ if (!xyz.at_eof) {
+ len = xyz.len;
+ if (size < len) len = size;
+ memcpy(buf, xyz.bufp, len);
+ size -= len;
+ buf += len;
+ total += len;
+ xyz.len -= len;
+ xyz.bufp += len;
+ }
+ }
+ return total;
+}
+
+void
+xyzModem_stream_close(int *err)
+{
+ diag_printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n",
+ xyz.crc_mode ? "CRC" : "Cksum",
+ xyz.total_SOH, xyz.total_STX, xyz.total_CAN,
+ xyz.total_retries);
+ ZM_DEBUG(zm_flush());
+}
+
+/* Need to be able to clean out the input buffer, so have to take the */
+/* getc */
+void xyzModem_stream_terminate(bool abort, int (*getc)(void))
+{
+ int c;
+
+ if (abort) {
+ ZM_DEBUG(zm_dprintf("!!!! TRANSFER ABORT !!!!\n"));
+ switch (xyz.mode) {
+ case xyzModem_xmodem:
+ case xyzModem_ymodem:
+ /* The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal */
+ /* number of Backspaces is a friendly way to get the other end to abort. */
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+ CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+ /* Now consume the rest of what's waiting on the line. */
+ ZM_DEBUG(zm_dprintf("Flushing serial line.\n"));
+ xyzModem_flush();
+ xyz.at_eof = true;
+ break;
+#ifdef xyzModem_zmodem
+ case xyzModem_zmodem:
+ /* Might support it some day I suppose. */
+#endif
+ break;
+ }
+ } else {
+ ZM_DEBUG(zm_dprintf("Engaging cleanup mode...\n"));
+ /*
+ * Consume any trailing crap left in the inbuffer from
+ * previous recieved blocks. Since very few files are an exact multiple
+ * of the transfer block size, there will almost always be some gunk here.
+ * If we don't eat it now, RedBoot will think the user typed it.
+ */
+ ZM_DEBUG(zm_dprintf("Trailing gunk:\n"));
+ while ((c = (*getc)()) > -1) ;
+ ZM_DEBUG(zm_dprintf("\n"));
+ /*
+ * Make a small delay to give terminal programs like minicom
+ * time to get control again after their file transfer program
+ * exits.
+ */
+ CYGACC_CALL_IF_DELAY_US((cyg_int32)250000);
+ }
+}
+
+char *
+xyzModem_error(int err)
+{
+ switch (err) {
+ case xyzModem_access:
+ return "Can't access file";
+ break;
+ case xyzModem_noZmodem:
+ return "Sorry, zModem not available yet";
+ break;
+ case xyzModem_timeout:
+ return "Timed out";
+ break;
+ case xyzModem_eof:
+ return "End of file";
+ break;
+ case xyzModem_cancel:
+ return "Cancelled";
+ break;
+ case xyzModem_frame:
+ return "Invalid framing";
+ break;
+ case xyzModem_cksum:
+ return "CRC/checksum error";
+ break;
+ case xyzModem_sequence:
+ return "Block sequence error";
+ break;
+ default:
+ return "Unknown error";
+ break;
+ }
+}
+
+/*
+ * RedBoot interface
+ */
+#if 0 /* SB */
+GETC_IO_FUNCS(xyzModem_io, xyzModem_stream_open, xyzModem_stream_close,
+ xyzModem_stream_terminate, xyzModem_stream_read, xyzModem_error);
+RedBoot_load(xmodem, xyzModem_io, false, false, xyzModem_xmodem);
+RedBoot_load(ymodem, xyzModem_io, false, false, xyzModem_ymodem);
+#endif