Browse Source

* Patches by Denis Peter, 9 Sep 2003:
add FAT support for IDE, SCSI and USB

* Patches by Gleb Natapov, 2 Sep 2003:
- cleanup of POST code for unsupported architectures
- MPC824x locks way0 of data cache for use as initial RAM;
this patch unlocks it after relocation to RAM and invalidates
the locked entries.

* Patch by Gleb Natapov, 30 Aug 2003:
new I2C driver for mpc107 bridge. Now works from flash.

* Patch by Dave Ellis, 11 Aug 2003:
- JFFS2: fix typo in common/cmd_jffs2.c
- JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option
- JFFS2: remove node version 0 warning
- JFFS2: accept JFFS2 PADDING nodes
- SXNI855T: add AM29LV800 support
- SXNI855T: move environment from EEPROM to flash
- SXNI855T: boot from JFFS2 in NOR or NAND flash

* Patch by Bill Hargen, 11 Aug 2003:
fixes for I2C on MPC8240
- fix i2c_write routine
- fix iprobe command
- eliminates use of global variables, plus dead code, cleanup.

wdenk 21 năm trước cách đây
mục cha
commit
7205e4075d
47 tập tin đã thay đổi với 1270 bổ sung2475 xóa
  1. 27 0
      CHANGELOG
  2. 6 0
      CREDITS
  3. 4 0
      MAINTAINERS
  4. 1 132
      board/mpl/common/common_util.c
  5. 1 3
      board/mpl/common/common_util.h
  6. 141 14
      board/mpl/common/flash.c
  7. 53 22
      board/mpl/common/isa.c
  8. 8 4
      board/mpl/common/isa.h
  9. 5 4
      board/mpl/common/pci_parts.h
  10. 1 1
      board/mpl/common/piix4_pci.h
  11. 4 1
      board/mpl/mip405/cmd_mip405.c
  12. 5 19
      board/mpl/mip405/init.S
  13. 7 0
      board/mpl/mip405/mip405.c
  14. 4 3
      board/mpl/mip405/mip405.h
  15. 85 74
      board/mpl/pip405/init.S
  16. 17 0
      board/mpl/pip405/pip405.c
  17. 32 84
      board/mpl/pip405/pip405.h
  18. 44 0
      board/sixnet/flash.c
  19. 68 0
      board/sixnet/sixnet.c
  20. 9 2
      common/cmd_doc.c
  21. 131 28
      common/cmd_fat.c
  22. 1 1
      common/cmd_jffs2.c
  23. 3 3
      cpu/mpc824x/Makefile
  24. 0 84
      cpu/mpc824x/drivers/i2c/Makefile
  25. 0 91
      cpu/mpc824x/drivers/i2c/Makefile_pc
  26. 0 104
      cpu/mpc824x/drivers/i2c/README
  27. 284 0
      cpu/mpc824x/drivers/i2c/i2c.c
  28. 0 309
      cpu/mpc824x/drivers/i2c/i2c.h
  29. 0 1243
      cpu/mpc824x/drivers/i2c/i2c1.c
  30. 0 52
      cpu/mpc824x/drivers/i2c/i2c2.S
  31. 0 103
      cpu/mpc824x/drivers/i2c/i2c_export.h
  32. 16 1
      cpu/mpc824x/start.S
  33. 27 4
      cpu/pxa/mmc.c
  34. 18 3
      disk/part_dos.c
  35. 4 0
      disk/part_dos.h
  36. 143 41
      fs/fat/fat.c
  37. 75 21
      fs/jffs2/jffs2_1pass.c
  38. 2 2
      include/configs/AdderII.h
  39. 6 4
      include/configs/MIP405.h
  40. 9 3
      include/configs/PIP405.h
  41. 22 7
      include/configs/SXNI855T.h
  42. 1 0
      include/fat.h
  43. 1 0
      include/jffs2/jffs2.h
  44. 1 0
      include/part.h
  45. 2 3
      post/cache_8xx.S
  46. 1 3
      post/ether.c
  47. 1 2
      post/uart.c

+ 27 - 0
CHANGELOG

@@ -2,6 +2,33 @@
 Changes for U-Boot 0.4.8:
 ======================================================================
 
+* Patches by Denis Peter, 9 Sep 2003:
+  add FAT support for IDE, SCSI and USB
+
+* Patches by Gleb Natapov, 2 Sep 2003:
+  - cleanup of POST code for unsupported architectures
+  - MPC824x locks way0 of data cache for use as initial RAM;
+    this patch unlocks it after relocation to RAM and invalidates
+    the locked entries.
+
+* Patch by Gleb Natapov, 30 Aug 2003:
+  new I2C driver for mpc107 bridge. Now works from flash.
+
+* Patch by Dave Ellis, 11 Aug 2003:
+  - JFFS2: fix typo in common/cmd_jffs2.c
+  - JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option
+  - JFFS2: remove node version 0 warning
+  - JFFS2: accept JFFS2 PADDING nodes
+  - SXNI855T: add AM29LV800 support
+  - SXNI855T: move environment from EEPROM to flash
+  - SXNI855T: boot from JFFS2 in NOR or NAND flash
+
+* Patch by Bill Hargen, 11 Aug 2003:
+  fixes for I2C on MPC8240
+  - fix i2c_write routine
+  - fix iprobe command
+  - eliminates use of global variables, plus dead code, cleanup.
+
 * Add support for USB Mass Storage Devices (BBB)
   (tested with USB memory sticks only)
 

+ 6 - 0
CREDITS

@@ -302,3 +302,9 @@ W: www.elinos.com
 N: Pantelis Antoniou
 E: panto@intracom.gr
 D: NETVIA board support, ARTOS support.
+
+N: Raghu Krishnaprasad
+E: Raghu.Krishnaprasad@fci.com
+D: Support for Adder-II MPC852T evaluation board
+W: http://www.forcecomputers.com
+

+ 4 - 0
MAINTAINERS

@@ -108,6 +108,10 @@ Dave Ellis <DGE@sixnetio.com>
 
 	SXNI855T		MPC8xx
 
+Raghu Krishnaprasad <raghu.krishnaprasad@fci.com>
+	
+	ADDERII			MPC852T
+
 Thomas Frieden <ThomasF@hyperion-entertainment.com>
 
 	AmigaOneG3SE		MPC7xx

+ 1 - 132
board/mpl/common/common_util.c

@@ -375,138 +375,6 @@ void show_stdio_dev(void)
 	}
 }
 
-/* ------------------------------------------------------------------------- */
-
-	/* switches the cs0 and the cs1 to the locations.
-	   When boot is TRUE, the the mapping is switched
-	   to the boot configuration, If it is FALSE, the
-	   flash will be switched in the boot area */
-
-#undef SW_CS_DBG
-#ifdef SW_CS_DBG
-#define	SW_CS_PRINTF(fmt,args...)	printf (fmt ,##args)
-#else
-#define SW_CS_PRINTF(fmt,args...)
-#endif
-
-#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
-int switch_cs(unsigned char boot)
-{
-	unsigned long pbcr;
-	int mode;
-
-	mode=get_boot_mode();
-	mtdcr(ebccfga, pb0cr);
-	pbcr = mfdcr (ebccfgd);
-	if (mode & BOOT_MPS) {
-		/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
-		/* we need only to switch if boot from MPS */
-		/* printf(" MPS boot mode detected. ");*/
-		/* printf("cs0 cfg: %lx\n",pbcr); */
-		if(boot) {
-			/* switch to boot configuration */
-			/* this is a 8bit boot, switch cs0 to flash location */
-			SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
-			pbcr&=0x000FFFFF; /*mask base address of the cs0 */
-			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
-			mtdcr(ebccfga, pb0cr);
-			mtdcr(ebccfgd, pbcr);
-			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
-			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
-			pbcr = mfdcr(ebccfgd);
-			SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
-			pbcr&=0x000FFFFF; /*mask base address of the cs1 */
-			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
-			mtdcr(ebccfga, pb1cr);
-			mtdcr(ebccfgd, pbcr);
-			SW_CS_PRINTF("  new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
-		}
-		else {
-			/* map flash to boot area, */
-			SW_CS_PRINTF("map Flash to boot area\n");
-			pbcr&=0x000FFFFF; /*mask base address of the cs0 */
-			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
-			mtdcr(ebccfga, pb0cr);
-			mtdcr(ebccfgd, pbcr);
-			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
-			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
-			pbcr = mfdcr(ebccfgd);
-			SW_CS_PRINTF("  cs1 cfg: %lx\n",pbcr);
-			pbcr&=0x000FFFFF; /*mask base address of the cs1 */
-			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
-			mtdcr(ebccfga, pb1cr);
-			mtdcr(ebccfgd, pbcr);
-			SW_CS_PRINTF("  new cs1 cfg: %lx Flash is on High Address\n",pbcr);
-		}
-		return 1;
-	}
-	else {
-		SW_CS_PRINTF("Normal boot, no switching necessary\n");
-		return 0;
-	}
-
-}
-
-int get_boot_mode(void)
-{
-	unsigned long pbcr;
-	int res = 0;
-	pbcr = mfdcr (strap);
-	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
-		/* boot via MPS or MPS mapping */
-		res = BOOT_MPS;
-	if(pbcr & PSR_ROM_LOC)
-		/* boot via PCI.. */
-		res |= BOOT_PCI;
-	 return res;
-}
-
-/* Setup cs0 parameter finally.
-   Map the flash high (in boot area)
-   This code can only be executed from SDRAM (after relocation).
-*/
-void setup_cs_reloc(void)
-{
-	unsigned long pbcr;
-	/* Since we are relocated, we can set-up the CS finaly
-	 * but first of all, switch off PCI mapping (in case it was a PCI boot) */
-	out32r(PMM0MA,0L);
-	icache_enable (); /* we are relocated */
-	/* for PCI Boot, we have to set-up the remaining CS correctly */
-	pbcr = mfdcr (strap);
-	if(pbcr & PSR_ROM_LOC) {
-		/* boot via PCI.. */
-		if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
-		/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
-			#ifdef DEBUG
-			printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
-			#endif
-			mtdcr (ebccfga, pb0ap);
-			mtdcr (ebccfgd, MPS_AP);
-			mtdcr (ebccfga, pb0cr);
-			mtdcr (ebccfgd, MPS_CR_B);
-		}
-		else {
-			/* Flash boot, set up the Flash on CS0 */
-			#ifdef DEBUG
-			printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
-			#endif
-			mtdcr (ebccfga, pb0ap);
-			mtdcr (ebccfgd, FLASH_AP);
-			mtdcr (ebccfga, pb0cr);
-			mtdcr (ebccfgd, FLASH_CR_B);
-		}
-	}
-	switch_cs(0); /* map Flash High */
-}
-
-
-#elif defined(CONFIG_VCMA9)
-int switch_cs(unsigned char boot)
-{
-    return 0;
-}
-#endif /* CONFIG_VCMA9 */
 
 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
@@ -625,6 +493,7 @@ void doc_init (void)
 
 #ifdef CONFIG_CONSOLE_EXTRA_INFO
 extern GraphicDevice ctfb;
+extern int get_boot_mode(void);
 
 void video_get_info_str (int line_number, char *info)
 {

+ 1 - 3
board/mpl/common/common_util.h

@@ -31,10 +31,8 @@ typedef struct {
 } backup_t;
 
 void get_backup_values(backup_t *buf);
-int switch_cs(unsigned char boot);
+
 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
-int get_boot_mode(void);
-void setup_cs_reloc(void);
 #define BOOT_MPS	0x01
 #define BOOT_PCI	0x02
 #endif

+ 141 - 14
board/mpl/common/flash.c

@@ -39,6 +39,13 @@
 #include <ppc4xx.h>
 #include <asm/processor.h>
 #include "common_util.h"
+#if defined(CONFIG_MIP405)
+#include "../mip405/mip405.h"
+#endif
+#if defined(CONFIG_PIP405)
+#include "../pip405/pip405.h"
+#endif
+#include <405gp_pci.h>
 
 flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/
 /*-----------------------------------------------------------------------
@@ -66,23 +73,102 @@ void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
 #define TRUE            1
 
 /*-----------------------------------------------------------------------
+ * Some CS switching routines:
+ *
+ * On PIP/MIP405 we have 3 (4) possible boot mode
+ *
+ * - Boot from Flash (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from MPS   (Flash CS = CS1, MPS CS = CS0)
+ * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from PCI with MPS map   (Flash CS = CS1, MPS CS = CS0)
+ * The flash init is the first board specific routine which is called
+ * after code relocation (running from SDRAM)
+ * The first thing we do is to map the Flash CS to the Flash area and
+ * the MPS CS to the MPS area. Since the flash size is unknown at this
+ * point, we use the max flash size and the lowest flash address as base.
+ * 
+ * After flash detection we adjust the size of the CS area accordingly.
+ * The board_init_r will fill in wrong values in the board init structure,
+ * but this will be fixed in the misc_init_r routine:
+ * bd->bi_flashstart=0-flash_info[0].size
+ * bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN
+ * bd->bi_flashoffset=0
+ * 
  */
+int get_boot_mode(void)
+{
+	unsigned long pbcr;
+	int res = 0;
+	pbcr = mfdcr (strap);
+	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
+		/* boot via MPS or MPS mapping */
+		res = BOOT_MPS;
+	if(pbcr & PSR_ROM_LOC)
+		/* boot via PCI.. */
+		res |= BOOT_PCI;
+	 return res;
+}
+
+/* Map the flash high (in boot area)
+   This code can only be executed from SDRAM (after relocation).
+*/
+void setup_cs_reloc(void)
+{
+	int mode;
+	/* Since we are relocated, we can set-up the CS finaly
+	 * but first of all, switch off PCI mapping (in case it was a PCI boot) */
+	out32r(PMM0MA,0L);
+	icache_enable (); /* we are relocated */
+	/* get boot mode */
+	mode=get_boot_mode();
+	/* we map the flash high in every case */
+	/* first findout on which cs the flash is */
+	if(mode & BOOT_MPS) {
+		/* map flash high on CS1 and MPS on CS0 */
+		mtdcr (ebccfga, pb0ap);
+		mtdcr (ebccfgd, MPS_AP);
+		mtdcr (ebccfga, pb0cr);
+		mtdcr (ebccfgd, MPS_CR);
+		/* we use the default values (max values) for the flash
+		 * because its real size is not yet known */
+		mtdcr (ebccfga, pb1ap);
+		mtdcr (ebccfgd, FLASH_AP);
+		mtdcr (ebccfga, pb1cr);
+		mtdcr (ebccfgd, FLASH_CR_B);
+	}
+	else {
+		/* map flash high on CS0 and MPS on CS1 */
+		mtdcr (ebccfga, pb1ap);
+		mtdcr (ebccfgd, MPS_AP);
+		mtdcr (ebccfga, pb1cr);
+		mtdcr (ebccfgd, MPS_CR);
+		/* we use the default values (max values) for the flash
+		 * because its real size is not yet known */
+		mtdcr (ebccfga, pb0ap);
+		mtdcr (ebccfgd, FLASH_AP);
+		mtdcr (ebccfga, pb0cr);
+		mtdcr (ebccfgd, FLASH_CR_B);
+	}
+}
+
 
 
 unsigned long flash_init (void)
 {
-	unsigned long size_b0, size_b1;
-	int i;
+	unsigned long size_b0, size_b1,flashcr;
+	int mode, i;
+	extern char version_string;
+	char *p=&version_string;
 
 	/* Since we are relocated, we can set-up the CS finally */
 	setup_cs_reloc();
 	/* get and display boot mode */
-	i=get_boot_mode();
-	if(i & BOOT_PCI)
-		printf("(PCI Boot %s Map) ",(i & BOOT_MPS) ?
+	mode=get_boot_mode();
+	if(mode & BOOT_PCI)
+		printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ?
 			"MPS" : "Flash");
 	else
-		printf("(%s Boot) ",(i & BOOT_MPS) ?
+		printf("(%s Boot) ",(mode & BOOT_MPS) ?
 			"MPS" : "Flash");
 	/* Init: no FLASHes known */
 	for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
@@ -91,7 +177,7 @@ unsigned long flash_init (void)
 
 	/* Static FLASH Bank configuration here - FIXME XXX */
 
-	size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+	size_b0 = flash_get_size((vu_long *)CFG_MONITOR_BASE, &flash_info[0]);
 
 	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
 		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
@@ -109,8 +195,31 @@ unsigned long flash_init (void)
 	flash_info[0].protect[flash_info[0].sector_count-1] = 1;
 	size_b1 = 0 ;
 	flash_info[0].size = size_b0;
+	/* set up flash cs according to the size */
+	if(mode & BOOT_MPS) {
+		/* flash is on CS1 */
+		mtdcr(ebccfga, pb1cr);
+		flashcr = mfdcr (ebccfgd);
+		/* we map the flash high in every case */
+		flashcr&=0x0001FFFF; /* mask out address bits */
+		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
+		flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */
+		mtdcr(ebccfga, pb1cr);
+		mtdcr(ebccfgd, flashcr);
+	}
+	else {
+		/* flash is on CS0 */
+		mtdcr(ebccfga, pb0cr);
+		flashcr = mfdcr (ebccfgd);
+		/* we map the flash high in every case */
+		flashcr&=0x0001FFFF; /* mask out address bits */
+		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
+		flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */
+		mtdcr(ebccfga, pb0cr);
+		mtdcr(ebccfgd, flashcr);
+	}
 #if 0
-	/* include this if you want to test if
+	/* enable this if you want to test if
 	   the relocation has be done ok.
 	   This will disable both Chipselects */
 	mtdcr (ebccfga, pb0cr);
@@ -119,6 +228,14 @@ unsigned long flash_init (void)
 	mtdcr (ebccfgd, 0L);
 	printf("CS0 & CS1 switched off for test\n");
 #endif
+	/* patch version_string */
+	for(i=0;i<0x100;i++) {
+		if(*p=='\n') {
+			*p=0;
+			break;
+		}
+		p++;
+	}
 	return (size_b0);
 }
 
@@ -171,6 +288,8 @@ void flash_print_info  (flash_info_t *info)
 				break;
 	case FLASH_INTEL320T:	printf ("TE28F320C3 (32 Mbit, top sector size)\n");
 				break;
+	case FLASH_AM640U:	printf ("AM29LV640U (64 Mbit, uniform sector size)\n");
+				break;
 	default:		printf ("Unknown Chip Type\n");
 				break;
 	}
@@ -211,7 +330,8 @@ void flash_print_info  (flash_info_t *info)
 
 
 /*-----------------------------------------------------------------------
- */
+ 
+*/
 
 /*
  * The following code cannot be run from FLASH!
@@ -220,7 +340,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
 {
 	short i;
 	FLASH_WORD_SIZE value;
-	ulong base = (ulong)addr;
+	ulong base;
 	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
 
 	/* Write auto select command: read Manufacturer ID */
@@ -250,7 +370,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
 		return (0);			/* no or unknown flash	*/
 	}
 	value = addr2[1];			/* device ID		*/
-	/*	printf("Device value %x\n",value); */
+	/*	printf("Device value %x\n",value); 		    */
 	switch (value) {
 	case (FLASH_WORD_SIZE)AMD_ID_F040B:
 		info->flash_id += FLASH_AM040;
@@ -292,12 +412,17 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
 		info->sector_count = 35;
 		info->size = 0x00200000;
 		break;				/* => 2 MB		*/
-#if 0	/* enable when device IDs are available */
 	case (FLASH_WORD_SIZE)AMD_ID_LV320T:
 		info->flash_id += FLASH_AM320T;
 		info->sector_count = 67;
 		info->size = 0x00400000;
 		break;				/* => 4 MB		*/
+	case (FLASH_WORD_SIZE)AMD_ID_LV640U:
+		info->flash_id += FLASH_AM640U;
+		info->sector_count = 128;
+		info->size = 0x00800000;
+		break;				/* => 8 MB		*/
+#if 0	/* enable when device IDs are available */
 
 	case (FLASH_WORD_SIZE)AMD_ID_LV320B:
 		info->flash_id += FLASH_AM320B;
@@ -328,10 +453,12 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
 		return (0);			/* => no or unknown flash */
 
 	}
-
+	/* base address calculation */
+	base=0-info->size;
 	/* set up sector start address table */
 	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
-	     (info->flash_id  == FLASH_AM040)){
+	     (info->flash_id  == FLASH_AM040) ||
+	     (info->flash_id  == FLASH_AM640U)){
 		for (i = 0; i < info->sector_count; i++)
 			info->start[i] = base + (i * 0x00010000);
 	}

+ 53 - 22
board/mpl/common/isa.c

@@ -32,7 +32,6 @@
 #include "kbd.h"
 #include "video.h"
 
-extern int drv_isa_kbd_init (void);
 
 #undef	ISA_DEBUG
 
@@ -49,6 +48,9 @@ extern int drv_isa_kbd_init (void);
 #define FALSE           0
 #endif
 
+#if defined(CONFIG_PIP405)
+
+extern int drv_isa_kbd_init (void);
 
 /* fdc (logical device 0) */
 const SIO_LOGDEV_TABLE sio_fdc[] = {
@@ -183,7 +185,7 @@ void isa_sio_setup(void)
 		close_cfg_super_IO(0x3F0);
 	}
 }
-
+#endif
 
 /******************************************************************************
  * IRQ Controller
@@ -202,7 +204,7 @@ static struct isa_irq_action isa_irqs[16];
 /*
  * This contains the irq mask for both 8259A irq controllers,
  */
-static unsigned int cached_irq_mask = 0xffff;
+static unsigned int cached_irq_mask = 0xfff9;
 
 #define cached_imr1	(unsigned char)cached_irq_mask
 #define cached_imr2	(unsigned char)(cached_irq_mask>>8)
@@ -387,19 +389,22 @@ int handle_isa_int(void)
 	isr2=in8(ISR_2);
 	isr1=in8(ISR_1);
 	irq=(unsigned char)irqack;
-	if((irq==7)&&((isr1&0x80)==0)) {
+	irq-=32;
+/*	if((irq==7)&&((isr1&0x80)==0)) {
 		PRINTF("IRQ7 detected but not in ISR\n");
 	}
 	else {
-		/* we should handle cascaded interrupts here also */
-		/* printf("ISA Irq %d\n",irq); */
-		isa_irqs[irq].count++;
-	if (isa_irqs[irq].handler != NULL)
-		(*isa_irqs[irq].handler)(isa_irqs[irq].arg);      /* call isr */
-	else
+*/		/* we should handle cascaded interrupts here also */
 	{
-	PRINTF ("bogus interrupt vector 0x%x\n", irq);
-	}
+/*		printf("ISA Irq %d\n",irq); */
+		isa_irqs[irq].count++;
+		if(irq!=2) { /* just swallow the cascade irq 2 */
+			if (isa_irqs[irq].handler != NULL)
+				(*isa_irqs[irq].handler)(isa_irqs[irq].arg);      /* call isr */
+			else {
+				PRINTF ("bogus interrupt vector 0x%x\n", irq);
+			}
+		}
 	}
 	/* issue EOI instruction to clear the IRQ */
 	mask_and_ack_8259A(irq);
@@ -413,13 +418,13 @@ int handle_isa_int(void)
 
 void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
 {
-  if (isa_irqs[vec].handler != NULL) {
-   printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
-	   vec, (uint)handler, (uint)isa_irqs[vec].handler);
-  }
-  isa_irqs[vec].handler = handler;
-  isa_irqs[vec].arg     = arg;
-  enable_8259A_irq(vec);
+	if (isa_irqs[vec].handler != NULL) {
+		printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
+			vec, (uint)handler, (uint)isa_irqs[vec].handler);
+	}
+	isa_irqs[vec].handler = handler;
+	isa_irqs[vec].arg     = arg;
+	enable_8259A_irq(vec);
 	PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask);
 
 }
@@ -427,9 +432,9 @@ void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
 void isa_irq_free_handler(int vec)
 {
 	disable_8259A_irq(vec);
-  isa_irqs[vec].handler = NULL;
-  isa_irqs[vec].arg     = NULL;
-	printf ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
+	isa_irqs[vec].handler = NULL;
+	isa_irqs[vec].arg     = NULL;
+	PRINTF ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
 
 }
 
@@ -448,16 +453,42 @@ void isa_init_irq_contr(void)
 	init_8259A();
 	out8(IMR_2,0xFF);
 }
+/*************************************************************************/
 
+void isa_show_irq(void)
+{
+	int vec;
+
+	printf ("\nISA Interrupt-Information:\n");
+	printf ("Nr  Routine   Arg       Count\n");
+
+	for (vec=0; vec<16; vec++) {
+		if (isa_irqs[vec].handler != NULL) {
+			printf ("%02d  %08lx  %08lx  %d\n",
+				vec,
+				(ulong)isa_irqs[vec].handler,
+				(ulong)isa_irqs[vec].arg,
+				isa_irqs[vec].count);
+		}
+	}
+}
+
+int isa_irq_get_count(int vec)
+{
+	return(isa_irqs[vec].count);
+}
 
 /******************************************************************
  * Init the ISA bus and devices.
  */
 
+#if defined(CONFIG_PIP405)
 
 int isa_init(void)
 {
 	isa_sio_setup();
+	isa_init_irq_contr();
 	drv_isa_kbd_init();
 	return 0;
 }
+#endif

+ 8 - 4
board/mpl/common/isa.h

@@ -21,12 +21,12 @@
  * MA 02111-1307 USA
  */
 
-#ifndef _PIP405_ISA_H_
-#define _PIP405_ISA_H_
+#ifndef _ISA_H_
+#define _ISA_H_
 /* Super IO */
 #define SIO_CFG_PORT	0x3F0	/* Config Port Address */
 
-
+#if defined(CONFIG_PIP405)
 /* table fore SIO initialization */
 typedef struct {
 	const uchar index;
@@ -44,10 +44,14 @@ unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned ch
 void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data);
 void close_cfg_super_IO(int address);
 void isa_sio_setup(void);
-void isa_sio_setup(void);
+#endif
+
 void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);
 void isa_irq_free_handler(int vec);
 int handle_isa_int(void);
+void isa_init_irq_contr(void);
+void isa_show_irq(void);
+int isa_irq_get_count(int vec);
 
 
 #endif

+ 5 - 4
board/mpl/common/pci_parts.h

@@ -92,7 +92,7 @@ extern void pci_pip405_write_regs(struct pci_controller *,
 /* PIIX4 ISA Bridge Function 0 */
 static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
 	{PCI_CFG_PIIX4_SERIRQ,	0xD0,		1}, /* enable Continous SERIRQ Pin */
-	{PCI_CFG_PIIX4_GENCFG,	0x00010041,	4}, /* enable SERIRQs, ISA, PNP	*/
+	{PCI_CFG_PIIX4_GENCFG,	0x00018041,	4}, /* enable SERIRQs, ISA, PNP, GPI11 */
 	{PCI_CFG_PIIX4_TOM,	0xFE,		1}, /* Top of Memory		*/
 	{PCI_CFG_PIIX4_XBCS,	0x02C4,		2}, /* disable all peri CS	*/
 	{PCI_CFG_PIIX4_RTCCFG,	0x21,		1}, /* enable RTC	   	*/
@@ -106,6 +106,7 @@ static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
 
 /* PIIX4 IDE Controller Function 1 */
 static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
+	{PCI_CFG_PIIX4_BMIBA,	0x0001000,	4}, /* set BMI to a valid address */
 	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/
 #if !defined(CONFIG_MIP405T)
 	{PCI_CFG_PIIX4_IDETIM,	0x80008000,	4}, /* enable Both IDE channels	*/
@@ -129,10 +130,10 @@ static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {
 
 /* PIIX4 Power Management Function 3 */
 static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = {
-	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/
-	{PCI_CFG_PIIX4_PMAB,	0x00004000,	4}, /* set PMBA to "valid" value */
-	{PCI_CFG_PIIX4_PMMISC,	0x01,		1}, /* enable PMBA IO access	*/
+	{PCI_CFG_PIIX4_PMBA,	0x00004000,	4}, /* set PMBA to "valid" value */
 	{PCI_CFG_PIIX4_SMBBA,	0x00005000,	4}, /* set SMBBA to "valid" value */
+	{PCI_CFG_PIIX4_PMMISC,	0x01,		1}, /* enable PMBA IO access	*/
+	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/
 	{ }					    /* end of device table 	*/
 };
 /* PPC405 Dummy only used to prevent autosetup on this host bridge */

+ 1 - 1
board/mpl/common/piix4_pci.h

@@ -143,7 +143,7 @@
 #define	PCI_CFG_PIIX4_LEGSUP	0xC0
 
 /* Function 3 Power Management */
-#define	PCI_CFG_PIIX4_PMAB		0x40
+#define	PCI_CFG_PIIX4_PMBA		0x40
 #define	PCI_CFG_PIIX4_CNTA		0x44
 #define	PCI_CFG_PIIX4_CNTB		0x48
 #define	PCI_CFG_PIIX4_GPICTL	0x4C

+ 4 - 1
board/mpl/mip405/cmd_mip405.c

@@ -54,10 +54,13 @@ int do_mip405(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	return (do_mplcommon(cmdtp, flag, argc, argv));
 }
 U_BOOT_CMD(
-	mip405,	6,	1,	do_mip405,
+	mip405,	8,	1,	do_mip405,
 	"mip405  - MIP405 specific Cmds\n",
 	"flash mem [SrcAddr] - updates U-Boot with image in memory\n"
 	"mip405 flash mps - updates U-Boot with image from MPS\n"
+	"mip405 info      - displays board information\n"
+	"mip405 led <on>  - switches LED on (on=1) or off (on=0)\n"
+	"mip405 mem [cnt] - Memory Test <cnt>-times, <cnt> = -1 loop forever\n"
 );
 
 /* ------------------------------------------------------------------------- */

+ 5 - 19
board/mpl/mip405/init.S

@@ -87,19 +87,15 @@ ext_bus_cntlr_init:
 	mfdcr		r4,ebccfgd
 
 	andi.		r0, r4, 0x2000			/* mask out irrelevant bits */
-	beq			0f						/* jump if 8 bit bus width */
+	beq		0f				/* jump if 8 bit bus width */
 
-	/* setup 16 bit things (Flash Boot)
+	/* setup 16 bit things
    *-----------------------------------------------------------------------
    * Memory Bank 0 (16 Bit Flash) initialization
    *---------------------------------------------------------------------- */
 
 	addi    r4,0,pb0ap
 	mtdcr   ebccfga,r4
-/*	addis   r4,0,0xFF8F */
-/*	ori     r4,r4,0xFE80 */
-/*	addis   r4,0,0x9B01 */
-/*	ori     r4,r4,0x5480 */
 	addis   r4,0,(FLASH_AP_B)@h
 	ori     r4,r4,(FLASH_AP_B)@l
 	mtdcr   ebccfgd,r4
@@ -107,8 +103,6 @@ ext_bus_cntlr_init:
 	addi    r4,0,pb0cr
 	mtdcr   ebccfga,r4
 	/* BS=0x010(4MB),BU=0x3(R/W), */
-/*	addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */
-/*	ori     r4,r4,0xA000          / * BW=0x01(16 bits) */
 	addis   r4,0,(FLASH_CR_B)@h
 	ori     r4,r4,(FLASH_CR_B)@l
 	mtdcr   ebccfgd,r4
@@ -123,21 +117,13 @@ ext_bus_cntlr_init:
 	/* 0x7F8FFE80 slowest boot */
 	addi    r4,0,pb0ap
 	mtdcr   ebccfga,r4
-#if 0
-	addis   r4,0,0x9B01
-	ori     r4,r4,0x5480
-#else
 	addis   r4,0,(MPS_AP_B)@h
 	ori     r4,r4,(MPS_AP_B)@l
-#endif
 	mtdcr   ebccfgd,r4
 
 	addi    r4,0,pb0cr
 	mtdcr   ebccfga,r4
 	/* BS=0x010(4MB),BU=0x3(R/W), */
-/*	addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */
-/*	ori     r4,r4,0x8000          / * BW=0x0( 8 bits) */
-
 	addis   r4,0,(MPS_CR_B)@h
 	ori     r4,r4,(MPS_CR_B)@l
 
@@ -178,18 +164,18 @@ ext_bus_cntlr_init:
   ori     r4,r4,0x0000
   mtdcr   ebccfgd,r4
 
-	addi    r4,0,pb6cr
+  addi    r4,0,pb6cr
   mtdcr   ebccfga,r4
   addis   r4,0,0x0000
   ori     r4,r4,0x0000
   mtdcr   ebccfgd,r4
 
-	addi    r4,0,pb7cr
+  addi    r4,0,pb7cr
   mtdcr   ebccfga,r4
   addis   r4,0,0x0000
   ori     r4,r4,0x0000
   mtdcr   ebccfgd,r4
-	nop				/* pass2 DCR errata #8 */
+  nop				/* pass2 DCR errata #8 */
   blr
 
 /*-----------------------------------------------------------------------------

+ 7 - 0
board/mpl/mip405/mip405.c

@@ -667,9 +667,16 @@ static int test_dram (unsigned long ramsize)
 /* used to check if the time in RTC is valid */
 static unsigned long start;
 static struct rtc_time tm;
+extern flash_info_t flash_info[];	/* info for FLASH chips */
 
 int misc_init_r (void)
 {
+	DECLARE_GLOBAL_DATA_PTR;
+	/* adjust flash start and size as well as the offset */
+	gd->bd->bi_flashstart=0-flash_info[0].size;
+	gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN;
+	gd->bd->bi_flashoffset=0;
+
 	/* check, if RTC is running */
 	rtc_get (&tm);
 	start=get_timer(0);

+ 4 - 3
board/mpl/mip405/mip405.h

@@ -137,13 +137,13 @@ void user_led0(unsigned char on);
 					(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
 
 /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define FLASH_BS	2	/* 4 MByte */
+#define FLASH_BS	FLASH_SIZE_PRELIM	/* 4 MByte */
 /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
 #define FLASH_BU	3	/* R/W */
 /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
 #define FLASH_BW	1	/* 16Bit */
 /* CR register for Boot */
-#define FLASH_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+#define FLASH_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
 /* CR register for non Boot */
 #define FLASH_CR	((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
 
@@ -172,11 +172,12 @@ void user_led0(unsigned char on);
 
 /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
 #define MPS_BS		2	/* 4 MByte */
+#define MPS_BS_B		FLASH_SIZE_PRELIM	/* 1 MByte */
 /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
 #define MPS_BU		3	/* R/W */
 /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
 #define MPS_BW		0	/* 8Bit */
 /* CR register for Boot */
-#define MPS_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+#define MPS_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS_B << 17) + (MPS_BU << 15) + (MPS_BW << 13))
 /* CR register for non Boot */
 #define MPS_CR		((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))

+ 85 - 74
board/mpl/pip405/init.S

@@ -41,17 +41,21 @@
 
 #define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/
 
-#include "configs/PIP405.h"
+#include <configs/PIP405.h>
 #include <ppc_asm.tmpl>
 #include <ppc_defs.h>
 
 #include <asm/cache.h>
 #include <asm/mmu.h>
+#include "pip405.h"
 
+  .globl ext_bus_cntlr_init
+ ext_bus_cntlr_init:
+  mflr   r4                      /* save link register */
+  mfdcr  r3,strap                /* get strapping reg */
+  andi.  r0, r3, PSR_ROM_LOC     /* mask out irrelevant bits */
+  bnelr                          /* jump back if PCI boot */
 
-	.globl	ext_bus_cntlr_init
-ext_bus_cntlr_init:
-  mflr    r4                      /* save link register */
   bl      ..getAddr
 ..getAddr:
   mflr    r3                      /* get address of ..getAddr */
@@ -82,7 +86,7 @@ ext_bus_cntlr_init:
 	mfdcr		r4,ebccfgd
 
 	andi.		r0, r4, 0x2000			/* mask out irrelevant bits */
-	beq			0f									/* jump if 8 bit bus width */
+	beq		0f				/* jump if 8 bit bus width */
 
 	/* setup 16 bit things
    *-----------------------------------------------------------------------
@@ -90,74 +94,49 @@ ext_bus_cntlr_init:
    *---------------------------------------------------------------------- */
 
 	addi    r4,0,pb0ap
-  mtdcr   ebccfga,r4
-  addis   r4,0,0x9B01
-  ori     r4,r4,0x5480
-  mtdcr   ebccfgd,r4
-
-  addi    r4,0,pb0cr
-  mtdcr   ebccfga,r4
-	/* BS=0x011(8MB),BU=0x3(R/W), */
-  addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
-  ori     r4,r4,0xA000          /* BW=0x01(16 bits) */
-  mtdcr   ebccfgd,r4
-
-  /*-----------------------------------------------------------------------
-   * Memory Bank 1 (Multi Purpose Socket) initialization
-   *----------------------------------------------------------------------*/
-  addi    r4,0,pb1ap
-  mtdcr   ebccfga,r4
-  addis   r4,0,0x0281
-  ori     r4,r4,0x5480
-  mtdcr   ebccfgd,r4
-
-  addi    r4,0,pb1cr
-  mtdcr   ebccfga,r4
-  /* BS=0x011(8MB),BU=0x3(R/W), */
-  addis   r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h
-  ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */
-  mtdcr   ebccfgd,r4
+	mtdcr   ebccfga,r4
+	addis   r4,0,(FLASH_AP_B)@h
+	ori     r4,r4,(FLASH_AP_B)@l
+	mtdcr   ebccfgd,r4
+
+	addi    r4,0,pb0cr
+	mtdcr   ebccfga,r4
+	/* BS=0x010(4MB),BU=0x3(R/W), */
+	addis   r4,0,(FLASH_CR_B)@h
+	ori     r4,r4,(FLASH_CR_B)@l
+	mtdcr   ebccfgd,r4
 	b				1f
 
 0:
-  /* 8Bit boot mode: */
+	/* 8Bit boot mode: */
 	/*-----------------------------------------------------------------------
-   * Memory Bank 0 Multi Purpose Socket initialization
-   *----------------------------------------------------------------------- */
-
+	* Memory Bank 0 Multi Purpose Socket initialization
+	*----------------------------------------------------------------------- */
+	/* 0x7F8FFE80 slowest boot */
 	addi    r4,0,pb0ap
-  mtdcr   ebccfga,r4
-  addis   r4,0,0x9B01
-  ori     r4,r4,0x5480
-  mtdcr   ebccfgd,r4
+	mtdcr   ebccfga,r4
+	addis   r4,0,(MPS_AP_B)@h
+	ori     r4,r4,(MPS_AP_B)@l
+	mtdcr   ebccfgd,r4
+
+	addi    r4,0,pb0cr
+	mtdcr   ebccfga,r4
+	/* BS=0x010(4MB),BU=0x3(R/W), */
+	addis   r4,0,(MPS_CR_B)@h
+	ori     r4,r4,(MPS_CR_B)@l
+	mtdcr   ebccfgd,r4
 
-  addi    r4,0,pb0cr
-  mtdcr   ebccfga,r4
-	/* BS=0x011(4MB),BU=0x3(R/W), */
-  addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
-  ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */
-  mtdcr   ebccfgd,r4
 
+1:
   /*-----------------------------------------------------------------------
-   * Memory Bank 1 (Flash) initialization
+   * Memory Bank 2-3-4-5-6 (not used) initialization
    *-----------------------------------------------------------------------*/
-  addi    r4,0,pb1ap
-  mtdcr   ebccfga,r4
-  addis   r4,0,0x0281
-  ori     r4,r4,0x5480
-  mtdcr   ebccfgd,r4
-
   addi    r4,0,pb1cr
   mtdcr   ebccfga,r4
-  /* BS=0x011(8MB),BU=0x3(R/W), */
-  addis   r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h
-  ori     r4,r4,0xA000          /* BW=0x0( 8 bits) */
+  addis   r4,0,0x0000
+  ori     r4,r4,0x0000
   mtdcr   ebccfgd,r4
 
-1:
-  /*-----------------------------------------------------------------------
-   * Memory Bank 2-3-4-5-6 (not used) initialization
-   *-----------------------------------------------------------------------*/
   addi    r4,0,pb2cr
   mtdcr   ebccfga,r4
   addis   r4,0,0x0000
@@ -182,28 +161,18 @@ ext_bus_cntlr_init:
   ori     r4,r4,0x0000
   mtdcr   ebccfgd,r4
 
-	addi    r4,0,pb6cr
+  addi    r4,0,pb6cr
   mtdcr   ebccfga,r4
   addis   r4,0,0x0000
   ori     r4,r4,0x0000
-  mtdcr   ebccfgd,r4
-
-	/*-----------------------------------------------------------------------
-   * Memory Bank 7 (Config Register) initialization
-   *----------------------------------------------------------------------- */
-  addi    r4,0,pb7ap
-  mtdcr   ebccfga,r4
-  addis   r4,0,0x0181	      /* Doc says TWT=3 and Openios TWT=3!! */
-  ori     r4,r4,0x5280          /* disable Ready, BEM=0 */
   mtdcr   ebccfgd,r4
 
   addi    r4,0,pb7cr
   mtdcr   ebccfga,r4
-	/* BS=0x0(1MB),BU=0x3(R/W), */
-  addis   r4,0,((CONFIG_PORT_ADDR & 0xFFF00000) | 0x00010000)@h
-  ori     r4,r4,0x8000            /* BW=0x0(8 bits) */
+  addis   r4,0,0x0000
+  ori     r4,r4,0x0000
   mtdcr   ebccfgd,r4
-	nop				/* pass2 DCR errata #8 */
+  nop				/* pass2 DCR errata #8 */
   blr
 
 /*-----------------------------------------------------------------------------
@@ -217,3 +186,45 @@ sdram_init:
 
 
   blr
+
+
+#if defined(CONFIG_BOOT_PCI)
+    .section .bootpg,"ax"
+    .globl _start_pci
+/*******************************************
+ */
+
+_start_pci:
+  /* first handle errata #68 / PCI_18 */
+  iccci   r0, r0          /* invalidate I-cache */
+  lis     r31, 0
+  mticcr  r31             /* ICCR = 0 (all uncachable) */
+  isync
+
+  mfccr0  r28             /* set CCR0[24] = 1 */
+  ori     r28, r28, 0x0080
+  mtccr0  r28
+
+  /* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
+  lis     r28, 0xEF40
+  addi    r28, r28, 0x0004
+  stw     r31, 0x0C(r28)  /* clear PMM0PCIHA */
+  lis     r29, 0xFFF8     /* open 512 kByte */
+  addi    r29, r29, 0x0001/* and enable this region */
+  stwbrx  r29, r0, r28    /* write PMM0MA */
+
+  lis     r28, 0xEEC0     /* address of PCIC0_CFGADDR */
+  addi    r29, r28, 4     /* add 4 to r29 -> PCIC0_CFGDATA */
+
+  lis     r31, 0x8000     /* set en bit bus 0 */
+  ori     r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
+  stwbrx  r31, r0, r28    /* write it */
+
+  lwbrx   r31, r0, r29    /* load XBCS register */
+  oris    r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
+  stwbrx  r31, r0, r29    /* write back XBCS register */
+
+  nop
+  nop
+  b	_start		/* normal start */
+#endif

+ 17 - 0
board/mpl/pip405/pip405.c

@@ -194,6 +194,11 @@ int board_pre_init (void)
 #ifdef SDRAM_DEBUG
 	DECLARE_GLOBAL_DATA_PTR;
 #endif
+	/* set up the config port */
+	mtdcr (ebccfga, pb7ap);
+	mtdcr (ebccfgd, CONFIG_PORT_AP);
+	mtdcr (ebccfga, pb7cr);
+	mtdcr (ebccfgd, CONFIG_PORT_CR);
 
 	memclk = get_bus_freq (tmemclk);
 	tmemclk = 1000000000 / (memclk / 100);	/* in 10 ps units */
@@ -657,8 +662,20 @@ static int test_dram (unsigned long ramsize)
 }
 
 
+extern flash_info_t flash_info[];	/* info for FLASH chips */
+
 int misc_init_r (void)
 {
+	DECLARE_GLOBAL_DATA_PTR;
+	/* adjust flash start and size as well as the offset */
+	gd->bd->bi_flashstart=0-flash_info[0].size;
+	gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN;
+	gd->bd->bi_flashoffset=0;
+
+	/* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
+	if (mfdcr(strap) & PSR_ROM_LOC)
+	       mtspr(ccr0, (mfspr(ccr0) & ~0x80));
+
 	return (0);
 }
 

+ 32 - 84
board/mpl/pip405/pip405.h

@@ -25,6 +25,7 @@
  * Global routines used for PIP405
  *****************************************************************************/
 
+#ifndef __ASSEMBLY__
 
 extern int  mem_test(unsigned long start, unsigned long ramsize,int mode);
 
@@ -35,13 +36,13 @@ void user_led1(unsigned char on);
 
 
 #define PLD_BASE_ADDRESS		CFG_ISA_IO_BASE_ADDRESS + 0x800
-#define PLD_PART_REG				PLD_BASE_ADDRESS + 0
-#define PLD_VERS_REG				PLD_BASE_ADDRESS + 1
+#define PLD_PART_REG			PLD_BASE_ADDRESS + 0
+#define PLD_VERS_REG			PLD_BASE_ADDRESS + 1
 #define PLD_BOARD_CFG_REG		PLD_BASE_ADDRESS + 2
 #define PLD_LED_USER_REG		PLD_BASE_ADDRESS + 3
 #define PLD_SYS_MAN_REG			PLD_BASE_ADDRESS + 4
 #define PLD_FLASH_COM_REG		PLD_BASE_ADDRESS + 5
-#define PLD_CAN_REG					PLD_BASE_ADDRESS + 6
+#define PLD_CAN_REG			PLD_BASE_ADDRESS + 6
 #define PLD_SER_PWR_REG			PLD_BASE_ADDRESS + 7
 #define PLD_COM_PWR_REG			PLD_BASE_ADDRESS + 8
 #define PLD_NIC_VGA_REG			PLD_BASE_ADDRESS + 9
@@ -50,86 +51,32 @@ void user_led1(unsigned char on);
 #define PIIX4_VENDOR_ID			0x8086
 #define PIIX4_IDE_DEV_ID		0x7111
 
+#endif
 
 /* timings */
-/* PLD (CS7) */
-#define PLD_BME	0 	/* Burst disable */
-#define PLD_TWE	5	/* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */
-#define PLD_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */
-#define PLD_OEN	1	/* Cycles from CS low to OE low   */
-#define PLD_WBN	1	/* Cycles from CS low to WE low   */
-#define PLD_WBF	1	/* Cycles from WE high to CS high */
-#define PLD_TH	2	/* Number of hold cycles after transfer */
-#define PLD_RE	0	/* Ready disabled */
-#define PLD_SOR	1	/* Sample on Ready disabled */
-#define PLD_BEM	0	/* Byte Write only active on Write cycles */
-#define PLD_PEN	0	/* Parity disable */
-#define PLD_AP 	((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \
-					(PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5))
-
-/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define PLD_BS	0	/* 1 MByte */
-/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
-#define PLD_BU	3	/* R/W */
-/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
-#define PLD_BW	0	/* 16Bit */
-#define PLD_CR	((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13))
 
-
-/* timings */
-
-#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024))
-/* Dummy CS to get the board revision */
-#define BOARD_BME	0 	/* Burst disable */
-#define BOARD_TWE	255	/* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
-#define BOARD_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */
-#define BOARD_OEN	1	/* Cycles from CS low to OE low   */
-#define BOARD_WBN	1	/* Cycles from CS low to WE low   */
-#define BOARD_WBF	1	/* Cycles from WE high to CS high */
-#define BOARD_TH	2	/* Number of hold cycles after transfer */
-#define BOARD_RE	0	/* Ready disabled */
-#define BOARD_SOR	1	/* Sample on Ready disabled */
-#define BOARD_BEM	0	/* Byte Write only active on Write cycles */
-#define BOARD_PEN	0	/* Parity disable */
-#define BOARD_AP 	((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \
-					(BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5))
+/* CS Config register (CS7) */
+#define CONFIG_PORT_BME	0 	/* Burst disable */
+#define CONFIG_PORT_TWE	255	/* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
+#define CONFIG_PORT_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define CONFIG_PORT_OEN	1	/* Cycles from CS low to OE low   */
+#define CONFIG_PORT_WBN	1	/* Cycles from CS low to WE low   */
+#define CONFIG_PORT_WBF	1	/* Cycles from WE high to CS high */
+#define CONFIG_PORT_TH	2	/* Number of hold cycles after transfer */
+#define CONFIG_PORT_RE	0	/* Ready disabled */
+#define CONFIG_PORT_SOR	1	/* Sample on Ready disabled */
+#define CONFIG_PORT_BEM	0	/* Byte Write only active on Write cycles */
+#define CONFIG_PORT_PEN	0	/* Parity disable */
+#define CONFIG_PORT_AP 	((CONFIG_PORT_BME << 31) + (CONFIG_PORT_TWE << 23) + (CONFIG_PORT_CSN << 18) + (CONFIG_PORT_OEN << 16) + (CONFIG_PORT_WBN << 14) + \
+				(CONFIG_PORT_WBF << 12) + (CONFIG_PORT_TH << 9) + (CONFIG_PORT_RE << 8) + (CONFIG_PORT_SOR << 7) + (CONFIG_PORT_BEM << 6) + (CONFIG_PORT_PEN << 5))
 
 /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define BOARD_BS	0	/* 1 MByte */
+#define CONFIG_PORT_BS	0	/* 1 MByte */
 /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
-#define BOARD_BU	3	/* R/W */
+#define CONFIG_PORT_BU	3	/* R/W */
 /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
-#define BOARD_BW	0	/* 16Bit */
-#define BOARD_CR	((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13))
-
-
-/* UART0 CS2 */
-#define UART0_BME	0 	/* Burst disable */
-#define UART0_TWE	7	/* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */
-#define UART0_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */
-#define UART0_OEN	1	/* Cycles from CS low to OE low   */
-#define UART0_WBN	1	/* Cycles from CS low to WE low   */
-#define UART0_WBF	1	/* Cycles from WE high to CS high */
-#define UART0_TH	2	/* Number of hold cycles after transfer */
-#define UART0_RE	0	/* Ready disabled */
-#define UART0_SOR	1	/* Sample on Ready disabled */
-#define UART0_BEM	0	/* Byte Write only active on Write cycles */
-#define UART0_PEN	0	/* Parity disable */
-#define UART0_AP 	((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \
-					(UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5))
-
-/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define UART0_BS	0	/* 1 MByte */
-/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
-#define UART0_BU	3	/* R/W */
-/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
-#define UART0_BW	0	/* 8Bit */
-#define UART0_CR	((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
-
-/* UART1 CS3 */
-#define UART1_AP UART0_AP /* same timing as UART0 */
-#define UART1_CR	((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
-
+#define CONFIG_PORT_BW	0	/* 16Bit */
+#define CONFIG_PORT_CR	((CONFIG_PORT_ADDR & 0xfff00000) + (CONFIG_PORT_BS << 17) + (CONFIG_PORT_BU << 15) + (CONFIG_PORT_BW << 13))
 
 /* Flash CS0 or CS 1 */
 /* 0x7F8FFE80 slowest timing at all... */
@@ -149,19 +96,19 @@ void user_led1(unsigned char on);
 #define FLASH_PEN	0	/* Parity disable */
 /* Access Parameter Register for non Boot */
 #define FLASH_AP 	((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
-					(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+				(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
 /* Access Parameter Register for Boot */
 #define FLASH_AP_B 	((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
-					(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+				(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
 
 /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define FLASH_BS	2	/* 4 MByte */
+#define FLASH_BS	FLASH_SIZE_PRELIM	/* 4 MByte */
 /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
 #define FLASH_BU	3	/* R/W */
 /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
 #define FLASH_BW	1	/* 16Bit */
 /* CR register for Boot */
-#define FLASH_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+#define FLASH_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
 /* CR register for non Boot */
 #define FLASH_CR	((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
 
@@ -183,18 +130,19 @@ void user_led1(unsigned char on);
 #define MPS_PEN		0	/* Parity disable */
 /* Access Parameter Register for non Boot */
 #define MPS_AP 		((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
-					(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+				(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
 /* Access Parameter Register for Boot */
-#define MPS_AP_B 		((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
-					(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+#define MPS_AP_B 	((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+				(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
 
 /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
 #define MPS_BS		2	/* 4 MByte */
+#define MPS_BS_B		FLASH_SIZE_PRELIM	/* 1 MByte */
 /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
 #define MPS_BU		3	/* R/W */
 /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
 #define MPS_BW		0	/* 8Bit */
 /* CR register for Boot */
-#define MPS_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+#define MPS_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
 /* CR register for non Boot */
 #define MPS_CR		((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))

+ 44 - 0
board/sixnet/flash.c

@@ -23,6 +23,10 @@
 
 #include <common.h>
 #include <mpc8xx.h>
+/* environment.h defines the various CFG_ENV_... values in terms
+ * of whichever ones are given in the configuration file.
+ */
+#include <environment.h>
 
 flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/
 
@@ -104,6 +108,19 @@ unsigned long flash_init (void)
 		      &flash_info[0]);
 #endif
 
+#ifdef CFG_ENV_ADDR
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_ENV_ADDR,
+			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_ADDR_REDUND
+	flash_protect ( FLAG_PROTECT_SET,
+			CFG_ENV_ADDR_REDUND,
+			CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
+			&flash_info[0]);
+#endif
+
 	return (size_b);
 }
 
@@ -154,6 +171,21 @@ static void flash_get_offsets (ulong base, flash_info_t *info)
 		for( i = 0; i < info->sector_count; i++ )
 			info->start[i] = base + (i * sect_size);
 	}
+	else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
+		 && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM800T) {
+
+		int sect_size;		/* number of bytes/sector */
+
+		sect_size = 0x00010000 * (sizeof(FPW)/2);
+
+		/* set up sector start address table (top boot sector type) */
+		for (i = 0; i < info->sector_count - 3; i++)
+			info->start[i] = base + (i * sect_size);
+		i = info->sector_count - 1;
+		info->start[i--] = base + (info->size - 0x00004000) * (sizeof(FPW)/2);
+		info->start[i--] = base + (info->size - 0x00006000) * (sizeof(FPW)/2);
+		info->start[i--] = base + (info->size - 0x00008000) * (sizeof(FPW)/2);
+	}
 }
 
 /*-----------------------------------------------------------------------
@@ -196,6 +228,9 @@ void flash_print_info (flash_info_t *info)
 	}
 
 	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_AM800T:
+		fmt = "29LV800B%s (8 Mbit, %s)\n";
+		break;
 	case FLASH_AM640U:
 		fmt = "29LV641D (64 Mbit, uniform sectors)\n";
 		break;
@@ -295,6 +330,12 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
 	/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
 	if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) {
 
+	case (FPW)AMD_ID_LV800T:
+		info->flash_id += FLASH_AM800T;
+		info->sector_count = 19;
+		info->size = 0x00100000 * (sizeof(FPW)/2);
+		break;				/* => 1 or 2 MiB	*/
+
 	case (FPW)AMD_ID_LV640U:	/* 29LV640 and 29LV641 have same ID */
 		info->flash_id += FLASH_AM640U;
 		info->sector_count = 128;
@@ -401,6 +442,7 @@ static void flash_sync_real_protect(flash_info_t *info)
 	break;
 
     case FLASH_AM640U:
+    case FLASH_AM800T:
     default:
 	/* no hardware protect that we support */
 	break;
@@ -438,6 +480,7 @@ int	flash_erase (flash_info_t *info, int s_first, int s_last)
 	case FLASH_28F320C3B:
 	case FLASH_28F640C3B:
 	case FLASH_AM640U:
+	case FLASH_AM800T:
 		break;
 	case FLASH_UNKNOWN:
 	default:
@@ -735,6 +778,7 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
 		break;
 
 	case FLASH_AM640U:
+	case FLASH_AM800T:
 	default:
 		/* no hardware protect that we support */
 		info->protect[sector] = prot;

+ 68 - 0
board/sixnet/sixnet.c

@@ -24,6 +24,7 @@
 
 #include <common.h>
 #include <config.h>
+#include <jffs2/jffs2.h>
 #include <mpc8xx.h>
 #include <net.h>	/* for eth_init() */
 #include <rtc.h>
@@ -602,3 +603,70 @@ long int initdram(int board_type)
 
 	return (size_sdram);
 }
+
+#ifdef CFG_JFFS_CUSTOM_PART
+
+static struct part_info part;
+
+#define jffs2_block(i)	\
+	((struct jffs2_unknown_node*)(CFG_JFFS2_BASE + (i) * 65536))
+
+struct part_info* jffs2_part_info(int part_num)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	bd_t *bd = gd->bd;
+	char* s;
+	int i;
+	int bootnor = 0;	/* assume booting from NAND flash */
+
+	if (part_num != 0)
+		return 0;	/* only support one partition */
+
+	if (part.usr_priv == (void*)1)
+		return &part;	/* already have part info */
+
+	memset(&part, 0, sizeof(part));
+
+	if (nand_dev_desc[0].ChipID == NAND_ChipID_UNKNOWN)
+		bootnor = 1;
+	else if (bd->bi_flashsize < 0x800000)
+		bootnor = 0;
+	else for (i = 0; !bootnor && i < 4; ++i) {
+		/* boot from NOR if JFFS2 info in any of
+		 * first 4 erase blocks
+		 */
+
+		if (jffs2_block(i)->magic == JFFS2_MAGIC_BITMASK)
+			bootnor = 1;
+	}
+
+	if (bootnor) {
+		/* no NAND flash or boot in NOR, use NOR flash */
+		part.offset = (unsigned char *)CFG_JFFS2_BASE;
+		part.size = CFG_JFFS2_SIZE;
+	}
+	else {
+		char readcmd[60];
+
+		/* boot info in NAND flash, get and use copy in RAM */
+
+		/* override info from environment if present */
+		s = getenv("fsaddr");
+		part.offset = s ? (void *)simple_strtoul(s, NULL, 16)
+				: (void *)CFG_JFFS2_RAMBASE;
+		s = getenv("fssize");
+		part.size = s ? simple_strtoul(s, NULL, 16)
+			      : CFG_JFFS2_RAMSIZE;
+
+		/* read from nand flash */
+		sprintf(readcmd, "nand read.jffs2 %x 0 %x",
+			(uint32_t)part.offset, part.size);
+		run_command(readcmd, 0);
+	}
+
+	part.erasesize = 0;	/* unused */
+	part.usr_priv=(void*)1;	/* ready */
+
+	return &part;
+}
+#endif /* ifdef CFG_JFFS_CUSTOM_PART */

+ 9 - 2
common/cmd_doc.c

@@ -861,8 +861,13 @@ static int find_boot_record(struct NFTLrecord *nftl)
 		memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
 
 		/* Do some sanity checks on it */
-		if (mh->UnitSizeFactor != 0xff) {
-			puts ("Sorry, we don't support UnitSizeFactor "
+		if (mh->UnitSizeFactor == 0) {
+#ifdef NFTL_DEBUG
+			puts ("UnitSizeFactor 0x00 detected.\n"
+			      "This violates the spec but we think we know what it means...\n");
+#endif
+		} else if (mh->UnitSizeFactor != 0xff) {
+			printf ("Sorry, we don't support UnitSizeFactor "
 			      "of != 1 yet.\n");
 			return -1;
 		}
@@ -950,6 +955,8 @@ static void DoC2k_init(struct DiskOnChip* this)
 
 	/* Ident all the chips present. */
 	DoC_ScanChips(this);
+	if ((!this->numchips) || (!this->chips))
+		return;
 
 	nftl = &this->nftl;
 

+ 131 - 28
common/cmd_fat.c

@@ -36,76 +36,179 @@
 
 #include <fat.h>
 
-extern block_dev_desc_t *ide_get_dev (int dev);
+
+
+
+block_dev_desc_t *get_dev (char* ifname, int dev)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_IDE)
+	if (strncmp(ifname,"ide",3)==0) {
+		extern block_dev_desc_t * ide_get_dev(int dev);
+		return(ide_get_dev(dev));
+	}
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+	if (strncmp(ifname,"scsi",4)==0) {
+		extern block_dev_desc_t * scsi_get_dev(int dev);
+		return(scsi_get_dev(dev));
+	}
+#endif
+#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
+	if (strncmp(ifname,"usb",3)==0) {
+		extern block_dev_desc_t * usb_stor_get_dev(int dev);
+		return(usb_stor_get_dev(dev));
+	}
+#endif
+#if defined(CONFIG_MMC)
+	if (strncmp(ifname,"mmc",3)==0) {
+		extern block_dev_desc_t *  mmc_get_dev(int dev);
+		return(mmc_get_dev(dev));
+	}
+#endif
+	return NULL;
+}
+
 
 int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	long size;
 	unsigned long offset;
 	unsigned long count;
+	block_dev_desc_t *dev_desc=NULL;
+	int dev=0;
+	int part=1;
+	char *ep;
 
-	if (argc < 3) {
-		printf ("usage:fatload <filename> <addr> [bytes]\n");
+	if (argc < 5) {
+		printf ("usage: fatload <interface> <dev[:part]> <addr> <filename> [bytes]\n");
 		return (0);
 	}
-
-	offset = simple_strtoul (argv[2], NULL, 16);
-	if (argc == 4)
-		count = simple_strtoul (argv[3], NULL, 16);
+	dev = (int)simple_strtoul (argv[2], &ep, 16);
+	dev_desc=get_dev(argv[1],dev);
+	if (dev_desc==NULL) {
+		puts ("\n** Invalid boot device **\n");
+		return 1;
+	}
+	if (*ep) {
+		if (*ep != ':') {
+			puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+			return 1;
+		}
+		part = (int)simple_strtoul(++ep, NULL, 16);
+	}
+	if (fat_register_device(dev_desc,part)!=0) {
+		printf ("\n** Unable to use %s %d:%d for fatload **\n",argv[1],dev,part);
+		return 1;
+	}
+	offset = simple_strtoul (argv[3], NULL, 16);
+	if (argc == 6)
+		count = simple_strtoul (argv[5], NULL, 16);
 	else
 		count = 0;
+	size = file_fat_read (argv[4], (unsigned char *) offset, count);
 
-	size = file_fat_read (argv[1], (unsigned char *) offset, count);
-
-	printf ("%ld bytes read\n", size);
+	if(size==-1)
+		printf("\n** Unable to read \"%s\" from %s %d:%d **\n",argv[4],argv[1],dev,part);
+	else
+		printf ("\n%ld bytes read\n", size);
 
 	return size;
 }
 
+
+
+
 U_BOOT_CMD(
-	fatload,	4,	0,	do_fat_fsload,
+	fatload,	6,	0,	do_fat_fsload,
 	"fatload - load binary file from a dos filesystem\n",
-	"[ off ] [ filename ]\n"
-	"    - load binary file from dos filesystem\n"
-	"      with offset 'off'\n"
+	"<interface> <dev[:part]>  <addr> <filename> [bytes]\n"
+	"    - load binary file 'filename' from 'dev' on 'interface'\n"
+	"      to address 'addr' from dos filesystem\n"
 );
 
 int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	char *filename = "/";
 	int ret;
+	int dev=0;
+	int part=1;
+	char *ep;
+	block_dev_desc_t *dev_desc=NULL;
 
-	if (argc == 2)
-		ret = file_fat_ls (argv[1]);
+	if (argc < 3) {
+		printf ("usage: fatls <interface> <dev[:part]> [directory]\n");
+		return (0);
+	}
+	dev = (int)simple_strtoul (argv[2], &ep, 16);
+	dev_desc=get_dev(argv[1],dev);
+	if (dev_desc==NULL) {
+		puts ("\n** Invalid boot device **\n");
+		return 1;
+	}
+	if (*ep) {
+		if (*ep != ':') {
+			puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+			return 1;
+		}
+		part = (int)simple_strtoul(++ep, NULL, 16);
+	}
+	if (fat_register_device(dev_desc,part)!=0) {
+		printf ("\n** Unable to use %s %d:%d for fatls **\n",argv[1],dev,part);
+		return 1;
+	}
+	if (argc == 4)
+		ret = file_fat_ls (argv[3]);
 	else
 		ret = file_fat_ls (filename);
 
+	if(ret!=0)
+		printf("No Fat FS detected\n");
 	return (ret);
 }
 
 U_BOOT_CMD(
-	fatls,	2,	1,	do_fat_ls,
+	fatls,	4,	1,	do_fat_ls,
 	"fatls   - list files in a directory (default /)\n",
-	"[ directory ]\n"
-	"    - list files in a directory\n"
+	"<interface> <dev[:part]> [directory]\n"
+	"    - list files from 'dev' on 'interface' in a 'directory'\n"
 );
 
 int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-	int ret;
+	int dev=0;
+	int part=1;
+	char *ep;
+	block_dev_desc_t *dev_desc=NULL;
 
-	ret = 0;
-
-	printf ("FAT info: %d\n", file_fat_detectfs ());
-
-	return (ret);
+	if (argc < 2) {
+		printf ("usage: fatinfo <interface> <dev[:part]>\n");
+		return (0);
+	}
+	dev = (int)simple_strtoul (argv[2], &ep, 16);
+	dev_desc=get_dev(argv[1],dev);
+	if (dev_desc==NULL) {
+		puts ("\n** Invalid boot device **\n");
+		return 1;
+	}
+	if (*ep) {
+		if (*ep != ':') {
+			puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+			return 1;
+		}
+		part = (int)simple_strtoul(++ep, NULL, 16);
+	}
+	if (fat_register_device(dev_desc,part)!=0) {
+		printf ("\n** Unable to use %s %d:%d for fatinfo **\n",argv[1],dev,part);
+		return 1;
+	}
+	return (file_fat_detectfs ());
 }
 
 U_BOOT_CMD(
-	fatinfo,	1,	1,	do_fat_fsinfo,
+	fatinfo,	3,	1,	do_fat_fsinfo,
 	"fatinfo - print information about filesystem\n",
-	"\n"
-	"    - print information about filesystem\n"
+	"<interface> <dev[:part]>\n"
+	"    - print information about filesystem from 'dev' on 'interface'\n"
 );
 
 #ifdef NOT_IMPLEMENTED_YET

+ 1 - 1
common/cmd_jffs2.c

@@ -174,7 +174,7 @@ do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 
 	if (jffs2_part_info(tmp_part)){
-		printf("Partiton changed to %d\n",tmp_part);
+		printf("Partition changed to %d\n",tmp_part);
 		part_num=tmp_part;
 		return 0;
 	}

+ 3 - 3
cpu/mpc824x/Makefile

@@ -25,14 +25,14 @@ include $(TOPDIR)/config.mk
 
 LIB	= lib$(CPU).a
 
-START	= start.S drivers/i2c/i2c2.o
+START	= start.S
 OBJS	= traps.o cpu.o cpu_init.o interrupts.o speed.o \
-	  drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o bedbug_603e.o
+	  drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o
 
 all:	.depend $(START) $(LIB)
 
 $(LIB):	$(OBJS)
-	$(AR) crv $@ $(OBJS) drivers/i2c/i2c2.o
+	$(AR) crv $@ $(OBJS)
 
 bedbug_603e.c:
 	ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c

+ 0 - 84
cpu/mpc824x/drivers/i2c/Makefile

@@ -1,84 +0,0 @@
-##########################################################################
-#
-#       Copyright Motorola, Inc. 1997
-#       ALL RIGHTS RESERVED
-#
-#       You are hereby granted a copyright license to use, modify, and
-#       distribute the SOFTWARE so long as this entire notice is retained
-#       without alteration in any modified and/or redistributed versions,
-#       and that such modified versions are clearly identified as such.
-#       No licenses are granted by implication, estoppel or otherwise under
-#       any patents or trademarks of Motorola, Inc.
-#
-#       The SOFTWARE is provided on an "AS IS" basis and without warranty.
-#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-#       INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2c.a
-
-#DEBUG  = -g
-DEBUG   = -DI2CDBG
-LST     = -Hanno -S
-OPTIM   =
-CC      = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP    = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT   = -big_si -c
-ASDEBUG = -l -fm
-AS      = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT	=  -Bbase=0 -q -Qn -r
-LKCMD   =
-LINK    =  /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL     = rm
-COPY    = cp
-LIST    = ls
-
-OBJECTS = i2c1.o i2c2.o
-
-all: $(TARGET)
-
-objects: $(OBJECTS)
-
-$(TARGET): $(OBJECTS)
-	$(LINK) $(OBJECTS) -o $@
-
-clean:
-	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
-#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
-	$(CCobj) $<
-
-.c.s:
-	$(CCobj) $(LST) $<
-
-i2c1.o: i2c_export.h i2c.h i2c1.c
-
-i2c2.o: i2c.h i2c2.s

+ 0 - 91
cpu/mpc824x/drivers/i2c/Makefile_pc

@@ -1,91 +0,0 @@
-##########################################################################
-#
-#       makefile_pc for use with PC mksnt tools  dink32/drivers/i2c
-#
-#       Copyright Motorola, Inc. 1997
-#       ALL RIGHTS RESERVED
-#
-#       You are hereby granted a copyright license to use, modify, and
-#       distribute the SOFTWARE so long as this entire notice is retained
-#       without alteration in any modified and/or redistributed versions,
-#       and that such modified versions are clearly identified as such.
-#       No licenses are granted by implication, estoppel or otherwise under
-#       any patents or trademarks of Motorola, Inc.
-#
-#       The SOFTWARE is provided on an "AS IS" basis and without warranty.
-#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-#       INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2c.a
-
-#DEBUG  = -g
-DEBUG   = -DI2CDBG
-LST     = -Hanno -S
-OPTIM   =
-CC      = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP    = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT   = -big_si -c
-ASDEBUG = -l -fm
-AS      = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT	=  -Bbase=0 -q -Qn -r
-LKCMD   =
-LINK    = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL     = rm
-COPY    = cp
-LIST    = ls
-
-OBJECTS = i2c1.o i2c2.o
-
-all: $(TARGET)
-
-objects: $(OBJECTS)
-
-$(TARGET): $(OBJECTS)
-	$(LINK) $(OBJECTS) -o $@
-
-clean:
-	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i
-#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
-	$(CCobj) $<
-
-.c.s:
-	$(CCobj) $(LST) $<
-
-i2c1.o: i2c_export.h i2c.h i2c1.c
-	$(CCobj) $<
-
-
-i2c2.o: i2c.h i2c2.s
-	$(DEL) -f $*.i
-	$(PREP) -Hasmcpp $<
-	$(AS) $(ASOPT) $*.i

+ 0 - 104
cpu/mpc824x/drivers/i2c/README

@@ -1,104 +0,0 @@
-CONTENT:
-
-   i2c.h
-   i2c1.c
-   i2c2.s
-
-WHAT ARE THESE FILES:
-
-These files contain MPC8240 (Kahlua) I2C
-driver routines. The driver routines are not
-written for any specific operating system.
-They serves the purpose of code sample, and
-jump-start for using the MPC8240 I2C unit.
-
-For the reason of correctness of C language
-syntax, these files are compiled by Metaware
-C compiler and assembler.
-
-ENDIAN NOTATION:
-
-The algorithm is designed for big-endian mode,
-software is responsible for byte swapping.
-
-USAGE:
-
-1. The host system that is running on MPC8240
-   shall link the files listed here. The memory
-   location of driver routines shall take into
-   account of that driver routines need to run
-   in supervisor mode and they process I2C
-   interrupt.
-
-2. The host system is responsible for configuring
-   the MPC8240 including Embedded Utilities Memory
-   Block. All I2C driver functions require the
-   content of Embedded Utilities Memory Block
-   Base Address Register, EUMBBAR, as the first
-   parameter.
-
-3. Before I2C unit of MPC8240 can be used,
-   initialize I2C unit by calling I2C_Init
-   with the corresponding parameters.
-
-   Note that the I2CFDR register shall be written
-   once during the initialization. If it is written
-   in the midst of transers, or after I2C STOPs or
-   REPEAT STATRs, depending on the data written,
-   a long reset time may be encountered.
-
-4. After I2C unit has been successfully initialized,
-   use the Application level API to send data or
-   receive data upon the desired mode, Master or
-   Slave.
-
-5. If the host system is also using the EPIC unit
-   on MPC8240, the system can register the
-   I2C_ISR with the EPIC including other
-   desired resources.
-
-   If the host system does not using the EPIC unit
-   on MPC8240, I2C_Timer_Event function can
-   be called for each desired time interval.
-
-   In both cases, the host system is free to provide
-   its own timer event handler and interrupt service
-   routine.
-
-6. The I2C driver routines contains a set
-   of utilities, Set and Get, for host system
-   to query and modify the desired I2C registers.
-
-7. It is the host system's responsibility of
-   queueing the I2C I/O request. The host
-   system shall check the I2C_ISR return code
-   for I2C I/O status. If I2C_ISR returns
-   I2CBUFFEMPTY or I2CBUFFFULL, it means
-   I2C unit has completed a I/O request
-   stated by the Application API.
-
-8. If the host system has more than one master
-   mode I2C unit I/O requests but doesn't want
-   to be intervented by being addressed as slave,
-   the host system can use the master mode
-   Application API with stop_flag set to 0 in
-   conjunction with is_cnt flag set to 1.
-   The first API call sets both stop_flag and
-   is_cnt to 0, indicating a START condition
-   shall be generated but when the end of
-   transaction is reached, do not generate a
-   STOP condition. Once the host system is
-   informed that the transaction has been
-   completed, the next Application API call
-   shall set is_cnt flag to 1, indicating a
-   repeated START condition shall be generated.
-   The last Application API call shall set
-   stop_flag
-   to 1.
-
-9. The I2C_Timer_Event function containes
-   a user defined function pointer. It
-   serves the purpose of providing the
-   host system a way to use its own event
-   handler instead of the I2C_ISR provided
-   here.

+ 284 - 0
cpu/mpc824x/drivers/i2c/i2c.c

@@ -0,0 +1,284 @@
+/*
+ * (C) Copyright 2003
+ * Gleb Natapov <gnatapov@mrv.com>
+ * Some bits are taken from linux driver writen by adrian@humboldt.co.uk
+ *
+ * Hardware I2C driver for MPC107 PCI bridge.
+ *
+ * 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>
+
+#undef I2CDBG
+
+#ifdef CONFIG_HARD_I2C
+#include <i2c.h>
+
+#define TIMEOUT (CFG_HZ/4)
+
+#define I2C_Addr ((unsigned *)(CFG_EUMB_ADDR + 0x3000))
+
+#define I2CADR &I2C_Addr[0]
+#define I2CFDR  &I2C_Addr[1]
+#define I2CCCR  &I2C_Addr[2]
+#define I2CCSR  &I2C_Addr[3]
+#define I2CCDR  &I2C_Addr[4]
+
+#define MPC107_CCR_MEN  0x80
+#define MPC107_CCR_MIEN 0x40
+#define MPC107_CCR_MSTA 0x20
+#define MPC107_CCR_MTX  0x10
+#define MPC107_CCR_TXAK 0x08
+#define MPC107_CCR_RSTA 0x04
+
+#define MPC107_CSR_MCF  0x80
+#define MPC107_CSR_MAAS 0x40
+#define MPC107_CSR_MBB  0x20
+#define MPC107_CSR_MAL  0x10
+#define MPC107_CSR_SRW  0x04
+#define MPC107_CSR_MIF  0x02
+#define MPC107_CSR_RXAK 0x01
+
+#define I2C_READ  1
+#define I2C_WRITE 0
+
+/* taken from linux include/asm-ppc/io.h */
+inline unsigned in_le32 (volatile unsigned *addr)
+{
+	unsigned ret;
+
+	__asm__ __volatile__ ("lwbrx %0,0,%1;\n"
+			      "twi 0,%0,0;\n"
+			      "isync":"=r" (ret): "r" (addr), "m" (*addr));
+	return ret;
+}
+
+inline void out_le32 (volatile unsigned *addr, int val)
+{
+	__asm__ __volatile__ ("stwbrx %1,0,%2; eieio":"=m" (*addr):"r" (val),
+			      "r" (addr));
+}
+
+#define writel(val, addr) out_le32(addr, val)
+#define readl(addr) in_le32(addr)
+
+void i2c_init (int speed, int slaveadd)
+{
+	/* stop I2C controller */
+	writel (0x0, I2CCCR);
+	/* set clock */
+	writel (0x1020, I2CFDR);
+	/* write slave address */
+	writel (slaveadd, I2CADR);
+	/* clear status register */
+	writel (0x0, I2CCSR);
+	/* start I2C controller */
+	writel (MPC107_CCR_MEN, I2CCCR);
+
+	return;
+}
+
+static __inline__ int i2c_wait4bus (void)
+{
+	ulong timeval = get_timer (0);
+
+	while (readl (I2CCSR) & MPC107_CSR_MBB)
+		if (get_timer (timeval) > TIMEOUT)
+			return -1;
+
+	return 0;
+}
+
+static __inline__ int i2c_wait (int write)
+{
+	u32 csr;
+	ulong timeval = get_timer (0);
+
+	do {
+		csr = readl (I2CCSR);
+
+		if (!(csr & MPC107_CSR_MIF))
+			continue;
+
+		writel (0x0, I2CCSR);
+
+		if (csr & MPC107_CSR_MAL) {
+#ifdef I2CDBG
+			printf ("i2c_wait: MAL\n");
+#endif
+			return -1;
+		}
+
+		if (!(csr & MPC107_CSR_MCF)) {
+#ifdef I2CDBG
+			printf ("i2c_wait: unfinished\n");
+#endif
+			return -1;
+		}
+
+		if (write == I2C_WRITE && (csr & MPC107_CSR_RXAK)) {
+#ifdef I2CDBG
+			printf ("i2c_wait: No RXACK\n");
+#endif
+			return -1;
+		}
+
+		return 0;
+	} while (get_timer (timeval) < TIMEOUT);
+
+#ifdef I2CDBG
+	printf ("i2c_wait: timed out\n");
+#endif
+	return -1;
+}
+
+static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta)
+{
+	writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX |
+		(rsta ? MPC107_CCR_RSTA : 0), I2CCCR);
+
+	writel ((dev << 1) | dir, I2CCDR);
+
+	if (i2c_wait (I2C_WRITE) < 0)
+		return 0;
+
+	return 1;
+}
+
+static __inline__ int __i2c_write (u8 * data, int length)
+{
+	int i;
+
+	writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX, I2CCCR);
+
+	for (i = 0; i < length; i++) {
+		writel (data[i], I2CCDR);
+
+		if (i2c_wait (I2C_WRITE) < 0)
+			break;
+	}
+
+	return i;
+}
+
+static __inline__ int __i2c_read (u8 * data, int length)
+{
+	int i;
+
+	writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+		((length == 1) ? MPC107_CCR_TXAK : 0), I2CCCR);
+
+	/* dummy read */
+	readl (I2CCDR);
+
+	for (i = 0; i < length; i++) {
+		if (i2c_wait (I2C_READ) < 0)
+			break;
+
+		/* Generate ack on last next to last byte */
+		if (i == length - 2)
+			writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+				MPC107_CCR_TXAK, I2CCCR);
+
+		/* Generate stop on last byte */
+		if (i == length - 1)
+			writel (MPC107_CCR_MEN | MPC107_CCR_TXAK, I2CCCR);
+
+		data[i] = readl (I2CCDR);
+	}
+
+	return i;
+}
+
+int i2c_read (u8 dev, uint addr, int alen, u8 * data, int length)
+{
+	int i = 0;
+	u8 *a = (u8 *) & addr;
+
+	if (i2c_wait4bus () < 0)
+		goto exit;
+
+	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
+		goto exit;
+
+	if (__i2c_write (&a[4 - alen], alen) != alen)
+		goto exit;
+
+	if (i2c_write_addr (dev, I2C_READ, 1) == 0)
+		goto exit;
+
+	i = __i2c_read (data, length);
+
+exit:
+	writel (MPC107_CCR_MEN, I2CCCR);
+
+	return !(i == length);
+}
+
+int i2c_write (u8 dev, uint addr, int alen, u8 * data, int length)
+{
+	int i = 0;
+	u8 *a = (u8 *) & addr;
+
+	if (i2c_wait4bus () < 0)
+		goto exit;
+
+	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
+		goto exit;
+
+	if (__i2c_write (&a[4 - alen], alen) != alen)
+		goto exit;
+
+	i = __i2c_write (data, length);
+
+exit:
+	writel (MPC107_CCR_MEN, I2CCCR);
+
+	return !(i == length);
+}
+
+int i2c_probe (uchar chip)
+{
+	int tmp;
+
+	/*
+	 * Try to read the first location of the chip.  The underlying
+	 * driver doesn't appear to support sending just the chip address
+	 * and looking for an <ACK> back.
+	 */
+	udelay (10000);
+	return i2c_read (chip, 0, 1, (char *) &tmp, 1);
+}
+
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
+{
+	char buf[1];
+
+	i2c_read (i2c_addr, reg, 1, buf, 1);
+
+	return (buf[0]);
+}
+
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
+{
+	i2c_write (i2c_addr, reg, 1, &val, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */

+ 0 - 309
cpu/mpc824x/drivers/i2c/i2c.h

@@ -1,309 +0,0 @@
-#ifndef I2C_H
-#define I2C_H
-
-/****************************************************
- *
- * Copyright Motrola 1999
- *
- ****************************************************/
-#define get_eumbbar() CFG_EUMB_ADDR
-
-#define I2CADR    0x00003000
-#define I2CFDR    0x00003004
-#define I2CCR     0x00003008
-#define I2CSR     0x0000300C
-#define I2CDR     0x00003010
-
-typedef enum _i2cstatus
-{
- I2CSUCCESS     = 0x3000,
- I2CADDRESS,
- I2CERROR,
- I2CBUFFFULL,
- I2CBUFFEMPTY,
- I2CXMITERROR,
- I2CRCVERROR,
- I2CBUSBUSY,
- I2CALOSS,
- I2CNOEVENT,
-} I2CStatus;
-
-typedef enum i2c_control
-{
- MEN  = 0x00000080,
- MIEN = 0x00000040,
- MSTA = 0x00000020,
- MTX  = 0x00000010,
- TXAK = 0x00000008,
- RSTA = 0x00000004,
-} I2C_CONTROL;
-
-typedef enum i2c_status
-{
-  MCF   =  0x00000080,
-  MAAS  =  0x00000040,
-  MBB   =  0x00000020,
-  MAL   =  0x00000010,
-  SRW   =  0x00000004,
-  MIF   =  0x00000002,
-  RXAK  =  0x00000001,
-} I2C_STATUS;
-
-typedef struct _i2c_ctrl
-{
-	unsigned int reserved0 : 24;
-	unsigned int men       : 1;
-	unsigned int mien      : 1;
-	unsigned int msta      : 1;
-	unsigned int mtx       : 1;
-	unsigned int txak      : 1;
-	unsigned int rsta      : 1;
-	unsigned int reserved1 : 2;
-} I2C_CTRL;
-
-typedef struct _i2c_stat
-{
-	unsigned int rsrv0    : 24;
-	unsigned int mcf      : 1;
-	unsigned int maas     : 1;
-	unsigned int mbb      : 1;
-	unsigned int mal      : 1;
-	unsigned int rsrv1    : 1;
-	unsigned int srw      : 1;
-	unsigned int mif      : 1;
-	unsigned int rxak     : 1;
-} I2C_STAT;
-
-typedef enum _i2c_mode
-{
-	RCV =  0,
-	XMIT = 1,
-} I2C_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the funcitonality provided by I2C driver
- *
- * Note: Its App.s responsibility to swap the data
- *       byte. In our API, we just transfer whatever
- *       we are given
- **************************************************/
-/**
- * Note:
- *
- * In all following functions,
- * the caller shall pass the configured embedded utility memory
- * block base, EUMBBAR.
- **/
-
-/* Send a buffer of data to the intended rcv_addr.
- * If stop_flag is set, after the whole buffer
- * is sent, generate a STOP signal provided that the
- * receiver doesn't signal the STOP in the middle.
- * I2C is the master performing transmitting. If
- * no STOP signal is generated at the end of current
- * transaction, the master can generate a START signal
- * to another slave addr.
- *
- * return I2CSUCCESS if no error.
- */
-static I2CStatus I2C_put( unsigned int  eumbbar,
-						  unsigned char rcv_addr,    /* receiver's address */
-			      unsigned char *buffer_ptr, /* pointer of data to be sent */
-					      unsigned int  length,      /* number of byte of in the buffer */
-					      unsigned int  stop_flag,   /* 1 - signal STOP when buffer is empty
-									  * 0 - no STOP signal when buffer is empty
-												  */
-						  unsigned int  is_cnt );    /* 1 - this is a restart, don't check MBB
-						      * 0 - this is a new start, check MBB
-													  */
-
-/* Receive a buffer of data from the desired sender_addr
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the master performing receiving. If no STOP signal
- * is generated, the master can generate a START signal
- * to another slave addr.
- *
- * return I2CSUCCESS if no error.
- */
-static I2CStatus I2C_get( unsigned int  eumbbar,
-						  unsigned char sender_addr, /* sender's address */
-					      unsigned char *buffer_ptr, /* pointer of receiving buffer */
-					  unsigned int  length,      /* length of the receiving buffer */
-					      unsigned int  stop_flag,   /* 1 - signal STOP when buffer is full
-									  * 0 - no STOP signal when buffer is full
-												      */
-						  unsigned int  is_cnt );    /* 1 - this is a restart, don't check MBB
-						      * 0 - this is a new start, check MBB
-													  */
-
-#if 0 /* the I2C_write and I2C_read functions are not active */
-/* Send a buffer of data to the requiring master.
- * If stop_flag is set, after the whole buffer is sent,
- * generate a STOP signal provided that the requiring
- * receiver doesn't signal the STOP in the middle.
- * I2C is the slave performing transmitting.
- *
- * return I2CSUCCESS if no error.
- *
- * Note: due to the Kahlua design, slave transmitter
- *       shall not signal STOP since there is no way
- *       for master to detect it, causing I2C bus hung.
- *
- *       For the above reason, the stop_flag is always
- *       set, i.e., 1.
- *
- *       programmer shall use the timer on Kahlua to
- *       control the interval of data byte at the
- *       master side.
- */
-static I2CStatus I2C_write( unsigned int eumbbar,
-						    unsigned char *buffer_ptr, /* pointer of data to be sent */
-						unsigned int  length,      /* number of byte of in the buffer */
-						unsigned int  stop_flag ); /* 1 - signal STOP when buffer is empty
-											* 0 - no STOP signal when buffer is empty
-												    */
-
- /* Receive a buffer of data from the sending master.
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the slave performing receiving.
- *
- * return I2CSUCCESS if no error.
- */
-static I2CStatus I2C_read(unsigned int  eumbbar,
-						  unsigned char *buffer_ptr, /* pointer of receiving buffer */
-					      unsigned int  length,      /* length of the receiving buffer */
-					  unsigned int  stop_flag ); /* 1 - signal STOP when buffer is full
-									  * 0 - no STOP signal when buffer is full
-												      */
-#endif /* of if0 for turning off I2C_read & I2C_write */
-
-/* if interrupt is not used, this is the timer event handler.
- * After each fixed time interval, this function can be called
- * to check the I2C status and call appropriate function to
- * handle the status event.
- */
-static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( unsigned int ) );
-
-/********************* Kernel API ************************
- * Kernel APIs are functions I2C driver provides to the
- * O.S.
- *********************************************************/
-
-/******************* device I/O function ***************/
-
-/*  Generate a START signal in the desired mode.
- *  I2C is the master.
- *
- * return I2CSUCCESS if no error.
- *        I2CERROR   if i2c unit is not enabled.
- *        I2CBUSBUSY if bus cannot be granted
- */
-static I2CStatus I2C_Start( unsigned int  eumbbar,
-						    unsigned char slave_addr, /* address of the receiver */
-				I2C_MODE     mode,       /* XMIT(1) - put (write)
-										  * RCV(0)  - get (read)
-													  */
-						    unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB
-													* 0 - this is a new start, check MBB
-						    */
-
-/* Generate a STOP signal to terminate the transaction. */
-static I2CStatus I2C_Stop( unsigned int eumbbar );
-
-/*  Do a one-byte master transmit.
- *
- *  return I2CBUFFEMPTY if this is the last byte.
- *  Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Master_Xmit( unsigned int eumbbar );
-
-/*  Do a one-byte master receive.
- *
- *  return I2CBUFFFULL if this is the last byte.
- *  Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Master_Rcv( unsigned int eumbbar );
-
-/*  Do a one-byte slave transmit.
- *
- *  return I2CBUFFEMPTY if this is the last byte.
- *  Otherwise return I2CSUCCESS
- *
- */
-static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar );
-
-/* Do a one-byte slave receive.
- *
- *  return I2CBUFFFULL if this is the last byte.
- *  Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Slave_Rcv( unsigned int eumbbar  );
-
-/* Process slave address phase.
- *
- * return I2CADDRESS if this is slave receiver's address phase
- * Otherwise return the result of slave xmit one byte.
- */
-static I2CStatus I2C_Slave_Addr( unsigned int eumbbar );
-
-/******************* Device Control Fucntion ****************/
-/*  Initialize I2C unit with desired frequency divider,
- *  driver's slave address w/o interrupt enabled.
- *
- *  This function must be called before I2C unit can
- *  be used.
- */
-static I2CStatus I2C_Init( unsigned int  eumbbar,
-						   unsigned char fdr,       /* frequency divider */
-			       unsigned char addr,      /* driver's address used for receiving */
-					   unsigned int en_int);    /* 1 - enable I2C interrupt
-									 * 0 - disable I2C interrup
-												 */
-
-/* I2C interrupt service routine.
- *
- * return I2CADDRESS if it is receiver's (either master or slave) address phase.
- * return the result of xmit or receive one byte
- */
-static I2CStatus I2C_ISR(unsigned int eumbbar  );
-
-/* Set I2C Status, i.e., write to I2CSR */
-static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat );
-
-/* Query I2C Status, i.e., read I2CSR */
-static I2C_STAT I2C_Get_Stat( unsigned int eumbbar );
-
-/* Change I2C Control bits, i.e., write to I2CCR */
-static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ); /* new control value */
-
-/* Query I2C Control bits, i.e., read I2CCR */
-static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar );
-
-/* This function performs the work for I2C_do_transaction.  The work is
- * split into this function to enable I2C_do_transaction to first transmit
- * the data address to the I2C slave device without putting the data address
- * into the first byte of the buffer.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- *        I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- *        I2C_RESTART, this is a continuation of existing transaction
- */
-static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int,
-				 I2C_TRANSACTION_MODE act,
-				 unsigned char i2c_addr,
-				 int len,
-				 unsigned char *buffer,
-				 I2C_STOP_MODE stop,
-				 int retry,
-				 I2C_RESTART_MODE rsta);
-#endif

+ 0 - 1243
cpu/mpc824x/drivers/i2c/i2c1.c

@@ -1,1243 +0,0 @@
-/*************************************************************
- *
- * Copyright @ Motorola, 1999
- *
- ************************************************************/
-#include <common.h>
-
-#ifdef CONFIG_HARD_I2C
-#include <i2c.h>
-#include "i2c_export.h"
-#include "i2c.h"
-
-#undef  I2CDBG0
-#undef  DEBUG
-
-/* Define a macro to use an optional application-layer print function, if
- * one was passed to the I2C library during initialization.  If there was
- * no function pointer passed, this protects against calling it.  Also define
- * the global variable that holds the passed pointer.
- */
-#define TIMEOUT (CFG_HZ/4)
-#define PRINT if ( app_print ) app_print
-static int (*app_print) (char *, ...);
-
-/******************* Internal to I2C Driver *****************/
-static unsigned int ByteToXmit = 0;
-static unsigned int XmitByte = 0;
-static unsigned char *XmitBuf = 0;
-static unsigned int XmitBufEmptyStop = 0;
-static unsigned int ByteToRcv = 0;
-static unsigned int RcvByte = 0;
-static unsigned char *RcvBuf = 0;
-static unsigned int RcvBufFulStop = 0;
-static unsigned int MasterRcvAddress = 0;
-
-/* Set by call to get_eumbbar during I2C_Initialize.
- * This could be globally available to the I2C library, but there is
- * an advantage to passing it as a parameter: it is already in a register
- * and doesn't have to be loaded from memory.  Also, that is the way the
- * I2C library was already implemented and I don't want to change it without
- * a more detailed analysis.
- * It is being set as a global variable in I2C_Initialize to hide it from
- * the DINK application layer, because it is Kahlua-specific.  I think that
- * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
- * a Kahlua-specific library dealing with the embedded utilities memory block.
- * Right now, get_eumbbar is defined in dink32/kahlua.s.  The other two are
- * defined in dink32/drivers/i2c/i2c2.s.
- */
-static unsigned int Global_eumbbar = 0;
-
-extern unsigned int load_runtime_reg (unsigned int eumbbar,
-				      unsigned int reg);
-
-extern unsigned int store_runtime_reg (unsigned int eumbbar,
-				       unsigned int reg, unsigned int val);
-
-/************************** API *****************/
-
-/* Application Program Interface (API) are the calls provided by the I2C
- * library to upper layer applications (i.e., DINK) to access the Kahlua
- * I2C bus interface.  The functions and values that are part of this API
- * are declared in i2c_export.h.
- */
-
-/*  Initialize I2C unit with the following:
- *  driver's slave address
- *  interrupt enabled
- *  optional pointer to application layer print function
- *
- *  These parameters may be added:
- *  desired clock rate
- *  digital filter frequency sampling rate
- *
- *  This function must be called before I2C unit can be used.
- */
-I2C_Status I2C_Initialize (unsigned char addr,
-			   I2C_INTERRUPT_MODE en_int,
-			   int (*p) (char *, ...))
-{
-	I2CStatus status;
-
-	/* establish the pointer, if there is one, to the application's "printf" */
-	app_print = p;
-
-	/* If this is the first call, get the embedded utilities memory block
-	 * base address.  I'm not sure what to do about error handling here:
-	 * if a non-zero value is returned, accept it.
-	 */
-	if (Global_eumbbar == 0)
-		Global_eumbbar = get_eumbbar ();
-	if (Global_eumbbar == 0) {
-		PRINT ("I2C_Initialize: can't find EUMBBAR\n");
-		return I2C_ERROR;
-	}
-
-	/* validate the I2C address */
-	if (addr & 0x80) {
-		PRINT ("I2C_Initialize, I2C address invalid:  %d 0x%x\n",
-			   (unsigned int) addr, (unsigned int) addr);
-		return I2C_ERROR;
-	}
-
-	/* Call the internal I2C library function to perform work.
-	 * Accept the default frequency sampling rate (no way to set it currently,
-	 * via I2C_Init) and set the clock frequency to something reasonable.
-	 */
-	status = I2C_Init (Global_eumbbar, (unsigned char) 0x31, addr, en_int);
-	if (status != I2CSUCCESS) {
-		PRINT ("I2C_Initialize: error in initiation\n");
-		return I2C_ERROR;
-	}
-
-	/* all is well */
-	return I2C_SUCCESS;
-}
-
-
-/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
- * are implemented.  Both are only in polling mode.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * data_addr is the address of the data on the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- *	  I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- *	  I2C_RESTART, this is a continuation of existing transaction
- */
-I2C_Status I2C_do_transaction ( I2C_INTERRUPT_MODE en_int,
-				I2C_TRANSACTION_MODE act,
-				unsigned char i2c_addr,
-				unsigned char data_addr,
-				int len,
-				char *buffer,
-				I2C_STOP_MODE stop,
-				int retry, I2C_RESTART_MODE rsta)
-{
-	I2C_Status status;
-	unsigned char data_addr_buffer[1];
-
-#if 1
-/* This is a temporary work-around.  The I2C library breaks the protocol
- * if it attempts to handle a data transmission in more than one
- * transaction, so the data address and the actual data bytes are put
- * into a single buffer before sending it to the library internal functions.
- * The problem is related to being able to restart a transaction without
- * sending the I2C device address or repeating the data address.  It may take
- * a day or two to sort it all out, so I'll have to get back to it later.
- * Look at I2C_Start to see about using some status flags (I'm not sure that
- * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic
- * in the library is insufficient) to control correct handling of the protocol.
- */
-	unsigned char dummy_buffer[257];
-
-	if (act == I2C_MASTER_XMIT) {
-		int i;
-
-		if (len > 256)
-			return I2C_ERROR;
-		for (i = 1; i <= len; i++)
-			dummy_buffer[i] = buffer[i - 1];
-		dummy_buffer[0] = data_addr;
-		status = I2C_do_buffer (en_int, act, i2c_addr, 1 + len,
-					dummy_buffer, stop, retry, rsta);
-		if (status != I2C_SUCCESS) {
-			PRINT ("I2C_do_transaction: can't perform data transfer\n");
-			return I2C_ERROR;
-		}
-		return I2C_SUCCESS;
-	}
-#endif	/* end of temp work-around */
-
-	/* validate requested transaction type */
-	if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) {
-		PRINT ("I2C_do_transaction, invalid transaction request:  %d\n",
-			act);
-		return I2C_ERROR;
-	}
-
-	/* range check the I2C address */
-	if (i2c_addr & 0x80) {
-		PRINT ("I2C_do_transaction, I2C address out of range:  %d 0x%x\n",
-			(unsigned int) i2c_addr, (unsigned int) i2c_addr);
-		return I2C_ERROR;
-	} else {
-		data_addr_buffer[0] = data_addr;
-	}
-
-	/*
-	 * We first have to contact the slave device and transmit the
-	 * data address. Be careful about the STOP and restart stuff.
-	 * We don't want to signal STOP after sending the data
-	 * address, but this could be a continuation if the
-	 * application didn't release the bus after the previous
-	 * transaction, by not sending a STOP after it.
-	 */
-	status = I2C_do_buffer (en_int, I2C_MASTER_XMIT, i2c_addr, 1,
-				data_addr_buffer, I2C_NO_STOP, retry, rsta);
-	if (status != I2C_SUCCESS) {
-		PRINT ("I2C_do_transaction: can't send data address for read\n");
-		return I2C_ERROR;
-	}
-
-	/* The data transfer will be a continuation. */
-	rsta = I2C_RESTART;
-
-	/* now handle the user data */
-	status = I2C_do_buffer (en_int, act, i2c_addr, len,
-				buffer, stop, retry, rsta);
-	if (status != I2C_SUCCESS) {
-		PRINT ("I2C_do_transaction: can't perform data transfer\n");
-		return I2C_ERROR;
-	}
-
-	/* all is well */
-	return I2C_SUCCESS;
-}
-
-/* This function performs the work for I2C_do_transaction.  The work is
- * split into this function to enable I2C_do_transaction to first transmit
- * the data address to the I2C slave device without putting the data address
- * into the first byte of the buffer.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- *	  I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- *	  I2C_RESTART, this is a continuation of existing transaction
- */
-static I2C_Status I2C_do_buffer (I2C_INTERRUPT_MODE en_int,
-				 I2C_TRANSACTION_MODE act,
-				 unsigned char i2c_addr,
-				 int len,
-				 unsigned char *buffer,
-				 I2C_STOP_MODE stop,
-				 int retry, I2C_RESTART_MODE rsta)
-{
-	I2CStatus rval;
-	unsigned int dev_stat;
-
-	if (act == I2C_MASTER_RCV) {
-		/* set up for master-receive transaction */
-		rval = I2C_get (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
-	} else {
-		/* set up for master-transmit transaction */
-		rval = I2C_put (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
-	}
-
-	/* validate the setup */
-	if (rval != I2CSUCCESS) {
-		dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
-		PRINT ("Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat);
-		I2C_Stop (Global_eumbbar);
-		return I2C_ERROR;
-	}
-
-	if (en_int == 1) {
-		/* this should not happen, no interrupt handling yet */
-		return I2C_SUCCESS;
-	}
-
-	/* this performs the polling action, when the transfer is completed,
-	 * the status returned from I2C_Timer_Event will be I2CBUFFFULL or
-	 * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the
-	 * transaction is not yet complete, anything else is an error.
-	 */
-	while (rval == I2CSUCCESS || rval == I2CADDRESS) {
-		int timeval = get_timer (0);
-
-		/* poll the device until something happens */
-		do {
-			rval = I2C_Timer_Event (Global_eumbbar, 0);
-		}
-		while (rval == I2CNOEVENT && get_timer (timeval) < TIMEOUT);
-
-		/* check for error condition */
-		if (rval == I2CSUCCESS   ||
-		    rval == I2CBUFFFULL  ||
-		    rval == I2CBUFFEMPTY ||
-		    rval == I2CADDRESS) {
-			;	/* do nothing */
-		} else {
-			/* report the error condition */
-			dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
-			PRINT ("Error(I2C_do_buffer):  code(0x%08x), status(0x%08x)\n",
-				   rval, dev_stat);
-			return I2C_ERROR;
-		}
-	}
-
-	/* all is well */
-	return I2C_SUCCESS;
-}
-
-/**
- * Note:
- *
- * In all following functions,
- * the caller shall pass the configured embedded utility memory
- * block base, EUMBBAR.
- **/
-
-/***********************************************************
- * function: I2C_put
- *
- * description:
-   Send a buffer of data to the intended rcv_addr.
- * If stop_flag is set, after the whole buffer
- * is sent, generate a STOP signal provided that the
- * receiver doesn't signal the STOP in the middle.
- * I2C is the master performing transmitting. If
- * no STOP signal is generated at the end of current
- * transaction, the master can generate a START signal
- * to another slave addr.
- *
- * note: this is master xmit API
- *********************************************************/
-static I2CStatus I2C_put (unsigned int eumbbar, unsigned char rcv_addr,	/* receiver's address */
-	  unsigned char *buffer_ptr,	/* pointer of data to be sent */
-	  unsigned int length,	/* number of byte of in the buffer */
-	  unsigned int stop_flag,	/* 1 - signal STOP when buffer is empty
-					 * 0 - no STOP signal when buffer is empty
-					 */
-	  unsigned int is_cnt)
-{					/* 1 - this is a restart, don't check MBB
-					 * 0 - this is a new start, check MBB
-					 */
-	if (buffer_ptr == 0 || length == 0) {
-		return I2CERROR;
-	}
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__);
-#endif
-
-	XmitByte = 0;
-	ByteToXmit = length;
-	XmitBuf = buffer_ptr;
-	XmitBufEmptyStop = stop_flag;
-
-	RcvByte = 0;
-	ByteToRcv = 0;
-	RcvBuf = 0;
-
-	/* we are the master, start transaction */
-	return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt);
-}
-
-/***********************************************************
- * function: I2C_get
- *
- * description:
- * Receive a buffer of data from the desired sender_addr
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the master performing receiving. If no STOP signal
- * is generated, the master can generate a START signal
- * to another slave addr.
- *
- * note: this is master receive API
- **********************************************************/
-static I2CStatus I2C_get (unsigned int eumbbar, unsigned char rcv_from,	/* sender's address */
-		  unsigned char *buffer_ptr,	/* pointer of receiving buffer */
-		  unsigned int length,	/* length of the receiving buffer */
-		  unsigned int stop_flag,	/* 1 - signal STOP when buffer is full
-						 * 0 - no STOP signal when buffer is full
-						 */
-		  unsigned int is_cnt)
-{						/* 1 - this is a restart, don't check MBB
-						 * 0 - this is a new start, check MBB
-						 */
-	if (buffer_ptr == 0 || length == 0) {
-		return I2CERROR;
-	}
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__);
-#endif
-
-	RcvByte = 0;
-	ByteToRcv = length;
-	RcvBuf = buffer_ptr;
-	RcvBufFulStop = stop_flag;
-
-	XmitByte = 0;
-	ByteToXmit = 0;
-	XmitBuf = 0;
-
-	/* we are the master, start the transaction */
-	return I2C_Start (eumbbar, rcv_from, RCV, is_cnt);
-
-}
-
-#if 0	/* turn off dead code */
-/*********************************************************
- * function: I2C_write
- *
- * description:
- * Send a buffer of data to the requiring master.
- * If stop_flag is set, after the whole buffer is sent,
- * generate a STOP signal provided that the requiring
- * receiver doesn't signal the STOP in the middle.
- * I2C is the slave performing transmitting.
- *
- * Note: this is slave xmit API.
- *
- *       due to the current Kahlua design, slave transmitter
- *       shall not signal STOP since there is no way
- *       for master to detect it, causing I2C bus hung.
- *
- *       For the above reason, the stop_flag is always
- *       set, i.e., 0.
- *
- *       programmer shall use the timer on Kahlua to
- *       control the interval of data byte at the
- *       master side.
- *******************************************************/
-static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of data to be sent */
-		unsigned int length,	/* number of byte of in the buffer */
-		unsigned int stop_flag)
-{					/* 1 - signal STOP when buffer is empty
-					 * 0 - no STOP signal when buffer is empty
-					 */
-	if (buffer_ptr == 0 || length == 0) {
-		return I2CERROR;
-	}
-
-	XmitByte = 0;
-	ByteToXmit = length;
-	XmitBuf = buffer_ptr;
-	XmitBufEmptyStop = 0;	/* in order to avoid bus hung, ignored the user's stop_flag */
-
-	RcvByte = 0;
-	ByteToRcv = 0;
-	RcvBuf = 0;
-
-	/* we are the slave, just wait for being called, or pull */
-	/* I2C_Timer_Event( eumbbar ); */
-}
-
-/******************************************************
- * function: I2C_read
- *
- * description:
- * Receive a buffer of data from the sending master.
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the slave performing receiving.
- *
- * note: this is slave receive API
- ****************************************************/
-static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of receiving buffer */
-		   unsigned int length,	/* length of the receiving buffer */
-		   unsigned int stop_flag)
-{					/* 1 - signal STOP when buffer is full
-					 * 0 - no STOP signal when buffer is full
-					 */
-	if (buffer_ptr == 0 || length == 0) {
-		return I2CERROR;
-	}
-
-	RcvByte = 0;
-	ByteToRcv = length;
-	RcvBuf = buffer_ptr;
-	RcvBufFulStop = stop_flag;
-
-	XmitByte = 0;
-	ByteToXmit = 0;
-	XmitBuf = 0;
-
-	/* wait for master to call us, or poll */
-	/* I2C_Timer_Event( eumbbar ); */
-}
-#endif	/* turn off dead code */
-
-/*********************************************************
- * function: I2c_Timer_Event
- *
- * description:
- * if interrupt is not used, this is the timer event handler.
- * After each fixed time interval, this function can be called
- * to check the I2C status and call appropriate function to
- * handle the status event.
- ********************************************************/
-static I2CStatus I2C_Timer_Event (unsigned int eumbbar,
-				  I2CStatus (*handler) (unsigned int))
-{
-	I2C_STAT stat;
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__);
-#endif
-
-	stat = I2C_Get_Stat (eumbbar);
-
-	if (stat.mif == 1) {
-		if (handler == 0) {
-			return I2C_ISR (eumbbar);
-		} else {
-			return (*handler) (eumbbar);
-		}
-	}
-
-	return I2CNOEVENT;
-}
-
-
-/****************** Device I/O function *****************/
-
-/******************************************************
- * function: I2C_Start
- *
- * description: Generate a START signal in the desired mode.
- *		I2C is the master.
- *
- *		Return I2CSUCCESS if no error.
- *
- * note:
- ****************************************************/
-static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr,	/* address of the receiver */
-			I2C_MODE mode,	/* XMIT(1) - put (write)
-					 * RCV(0)  - get (read)
-					 */
-			unsigned int is_cnt)
-{					/* 1 - this is a restart, don't check MBB
-					 * 0 - this is a new start
-					 */
-	unsigned int tmp = 0;
-	I2C_STAT stat;
-	I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__,
-		   __LINE__, slave_addr, mode, is_cnt);
-#endif
-
-	ctrl = I2C_Get_Ctrl (eumbbar);
-
-	/* first make sure I2C has been initialized */
-	if (ctrl.men == 0) {
-		return I2CERROR;
-	}
-
-	/* next make sure bus is idle */
-	stat = I2C_Get_Stat (eumbbar);
-
-	if (is_cnt == 0 && stat.mbb == 1) {
-		/* sorry, we lost */
-		return I2CBUSBUSY;
-	} else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) {
-		/* sorry, we lost the bus */
-		return I2CALOSS;
-	}
-
-
-	/* OK, I2C is enabled and we have the bus */
-
-	/* prepare to write the slave address */
-	ctrl.msta = 1;
-	ctrl.mtx = 1;
-	ctrl.txak = 0;
-	ctrl.rsta = is_cnt;		/* set the repeat start bit */
-	I2C_Set_Ctrl (eumbbar, ctrl);
-
-	/* write the slave address and xmit/rcv mode bit */
-	tmp = load_runtime_reg (eumbbar, I2CDR);
-	tmp = (tmp & 0xffffff00) |
-	      ((slave_addr & 0x007f) << 1) |
-	      (mode == XMIT ? 0x0 : 0x1);
-	store_runtime_reg (eumbbar, I2CDR, tmp);
-
-	if (mode == RCV) {
-		MasterRcvAddress = 1;
-	} else {
-		MasterRcvAddress = 0;
-	}
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__);
-#endif
-
-	/* wait for the interrupt or poll  */
-	return I2CSUCCESS;
-}
-
-/***********************************************************
- * function: I2c_Stop
- *
- * description: Generate a STOP signal to terminate the master
- *		transaction.
- *		return I2CSUCCESS
- *
- **********************************************************/
-static I2CStatus I2C_Stop (unsigned int eumbbar)
-{
-	I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__);
-#endif
-
-	ctrl = I2C_Get_Ctrl (eumbbar);
-	ctrl.msta = 0;
-	I2C_Set_Ctrl (eumbbar, ctrl);
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__);
-#endif
-
-	return I2CSUCCESS;
-}
-
-/****************************************************
- * function: I2C_Master_Xmit
- *
- * description: Master sends one byte of data to
- *		slave target
- *
- *		return I2CSUCCESS if the byte transmitted.
- *		Otherwise no-zero
- *
- * Note: condition must meet when this function is called:
- *       I2CSR(MIF) == 1 && I2CSR(MCF)  == 1  && I2CSR(RXAK) == 0
- *       I2CCR(MSTA) == 1  && I2CCR(MTX) == 1
- *
- ***************************************************/
-static I2CStatus I2C_Master_Xmit (unsigned int eumbbar)
-{
-	unsigned int val;
-
-	if (ByteToXmit > 0) {
-
-		if (ByteToXmit == XmitByte) {
-			/* all xmitted */
-			ByteToXmit = 0;
-
-			if (XmitBufEmptyStop == 1) {
-				I2C_Stop (eumbbar);
-			}
-
-			return I2CBUFFEMPTY;
-
-		}
-#ifdef I2CDBG0
-		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
-			   *(XmitBuf + XmitByte));
-#endif
-
-		val = *(XmitBuf + XmitByte);
-		val &= 0x000000ff;
-		store_runtime_reg (eumbbar, I2CDR, val);
-		XmitByte++;
-
-		return I2CSUCCESS;
-
-	}
-
-	return I2CBUFFEMPTY;
-}
-
-/***********************************************
- * function: I2C_Master_Rcv
- *
- * description: master reads one byte data
- *		from slave source
- *
- *		return I2CSUCCESS if no error
- *
- * Note: condition must meet when this function is called:
- *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
- *       I2CCR(MSTA) == 1 && I2CCR(MTX) == 0
- *
- ***********************************************/
-static I2CStatus I2C_Master_Rcv (unsigned int eumbbar)
-{
-	I2C_CTRL ctrl;
-	unsigned int val;
-
-	if (ByteToRcv > 0) {
-
-		if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) {
-			/* master requests more than or equal to 2 bytes
-			 * we are reading 2nd to last byte
-			 */
-
-			/* we need to set I2CCR(TXAK) to generate a STOP */
-			ctrl = I2C_Get_Ctrl (eumbbar);
-			ctrl.txak = 1;
-			I2C_Set_Ctrl (eumbbar, ctrl);
-
-			/* Kahlua will automatically generate a STOP
-			 * next time a transaction happens
-			 */
-
-			/* note: the case of master requesting one byte is
-			 *       handled in I2C_ISR
-			 */
-		}
-
-		/* generat a STOP before reading the last byte */
-		if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) {
-			I2C_Stop (eumbbar);
-		}
-
-		val = load_runtime_reg (eumbbar, I2CDR);
-		*(RcvBuf + RcvByte) = val & 0xFF;
-
-#ifdef I2CDBG0
-		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
-			   *(RcvBuf + RcvByte));
-#endif
-
-		RcvByte++;
-
-		if (ByteToRcv == RcvByte) {
-			ByteToRcv = 0;
-
-			return I2CBUFFFULL;
-		}
-
-		return I2CSUCCESS;
-	}
-
-	return I2CBUFFFULL;
-
-}
-
-/****************************************************
- * function: I2C_Slave_Xmit
- *
- * description: Slave sends one byte of data to
- *		requesting destination
- *
- *	  return SUCCESS if the byte transmitted. Otherwise
- *	  No-zero
- *
- * Note: condition must meet when this function is called:
- *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&  I2CSR(RXAK) = 0
- *       I2CCR(MSTA) == 0  && I2CCR(MTX) == 1
- *
- ***************************************************/
-static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar)
-{
-	unsigned int val;
-
-	if (ByteToXmit > 0) {
-
-		if (ByteToXmit == XmitByte) {
-			/* no more data to send */
-			ByteToXmit = 0;
-
-			/*
-			 * do not toggle I2CCR(MTX). Doing so will
-			 * cause bus-hung since current Kahlua design
-			 * does not give master a way to detect slave
-			 * stop. It is always a good idea for master
-			 * to use timer to prevent the long long
-			 * delays
-			 */
-
-			return I2CBUFFEMPTY;
-		}
-#ifdef I2CDBG
-		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
-			   *(XmitBuf + XmitByte));
-#endif
-
-		val = *(XmitBuf + XmitByte);
-		val &= 0x000000ff;
-		store_runtime_reg (eumbbar, I2CDR, val);
-		XmitByte++;
-
-		return I2CSUCCESS;
-	}
-
-	return I2CBUFFEMPTY;
-}
-
-/***********************************************
- * function: I2C_Slave_Rcv
- *
- * description: slave reads one byte data
- *		from master source
- *
- *		return I2CSUCCESS if no error otherwise non-zero
- *
- * Note: condition must meet when this function is called:
- *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
- *       I2CCR(MSTA) == 0 && I2CCR(MTX)  = 0
- *
- ***********************************************/
-static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar)
-{
-	unsigned int val;
-	I2C_CTRL ctrl;
-
-	if (ByteToRcv > 0) {
-		val = load_runtime_reg (eumbbar, I2CDR);
-		*(RcvBuf + RcvByte) = val & 0xff;
-#ifdef I2CDBG
-		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
-			   *(RcvBuf + RcvByte));
-#endif
-		RcvByte++;
-
-		if (ByteToRcv == RcvByte) {
-			if (RcvBufFulStop == 1) {
-				/* all done */
-				ctrl = I2C_Get_Ctrl (eumbbar);
-				ctrl.txak = 1;
-				I2C_Set_Ctrl (eumbbar, ctrl);
-			}
-
-			ByteToRcv = 0;
-			return I2CBUFFFULL;
-		}
-
-		return I2CSUCCESS;
-	}
-
-	return I2CBUFFFULL;
-}
-
-/****************** Device Control Function *************/
-
-/*********************************************************
- * function: I2C_Init
- *
- * description: Initialize I2C unit with desired frequency divider,
- *		master's listening address, with interrupt enabled
- *		or disabled.
- *
- * note:
- ********************************************************/
-static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr,	/* frequency divider */
-		   unsigned char slave_addr,	/* driver's address used for receiving */
-		   unsigned int en_int)
-{						/* 1 - enable I2C interrupt
-						 * 0 - disable I2C interrup
-						 */
-	I2C_CTRL ctrl;
-	unsigned int tmp;
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__);
-#endif
-
-	ctrl = I2C_Get_Ctrl (eumbbar);
-	/* disable the I2C module before we change everything */
-	ctrl.men = 0;
-	I2C_Set_Ctrl (eumbbar, ctrl);
-
-	/* set the frequency diver */
-	tmp = load_runtime_reg (eumbbar, I2CFDR);
-	tmp = (tmp & 0xffffffc0) | (fdr & 0x3f);
-	store_runtime_reg (eumbbar, I2CFDR, tmp);
-
-	/* Set our listening (slave) address */
-	tmp = load_runtime_reg (eumbbar, I2CADR);
-	tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1);
-	store_runtime_reg (eumbbar, I2CADR, tmp);
-
-	/* enable I2C with desired interrupt setting */
-	ctrl.men = 1;
-	ctrl.mien = en_int & 0x1;
-	I2C_Set_Ctrl (eumbbar, ctrl);
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__);
-#endif
-
-	return I2CSUCCESS;
-
-}
-
-/*****************************************
- * function I2c_Get_Stat
- *
- * description: Query I2C Status, i.e., read I2CSR
- *
- ****************************************/
-static I2C_STAT I2C_Get_Stat (unsigned int eumbbar)
-{
-	unsigned int temp;
-	I2C_STAT stat;
-
-	temp = load_runtime_reg (eumbbar, I2CSR);
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp);
-#endif
-
-	stat.rsrv0 = (temp & 0xffffff00) >> 8;
-	stat.mcf   = (temp & 0x00000080) >> 7;
-	stat.maas  = (temp & 0x00000040) >> 6;
-	stat.mbb   = (temp & 0x00000020) >> 5;
-	stat.mal   = (temp & 0x00000010) >> 4;
-	stat.rsrv1 = (temp & 0x00000008) >> 3;
-	stat.srw   = (temp & 0x00000004) >> 2;
-	stat.mif   = (temp & 0x00000002) >> 1;
-	stat.rxak  = (temp & 0x00000001);
-	return stat;
-}
-
-/*********************************************
- * function: I2c_Set_Ctrl
- *
- * description: Change I2C Control bits,
- *		i.e., write to I2CCR
- *
- ********************************************/
-static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl)
-{						/* new control value */
-	unsigned int temp = load_runtime_reg (eumbbar, I2CCR);
-
-	temp &= 0xffffff03;
-	temp |= ((ctrl.men  & 0x1) << 7);
-	temp |= ((ctrl.mien & 0x1) << 6);
-	temp |= ((ctrl.msta & 0x1) << 5);
-	temp |= ((ctrl.mtx  & 0x1) << 4);
-	temp |= ((ctrl.txak & 0x1) << 3);
-	temp |= ((ctrl.rsta & 0x1) << 2);
-#ifdef I2CDBG0
-	PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp);
-#endif
-	store_runtime_reg (eumbbar, I2CCR, temp);
-
-}
-
-/*****************************************
- * function: I2C_Get_Ctrl
- *
- * description: Query I2C Control bits,
- *		i.e., read I2CCR
- *****************************************/
-static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar)
-{
-	union {
-		I2C_CTRL ctrl;
-		unsigned int temp;
-	} s;
-
-	s.temp = load_runtime_reg (eumbbar, I2CCR);
-#ifdef I2CDBG0
-	PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp);
-#endif
-
-	return s.ctrl;
-}
-
-
-/****************************************
- * function: I2C_Slave_Addr
- *
- * description: Process slave address phase.
- *		return I2CSUCCESS if no error
- *
- * note: Precondition for calling this function:
- *       I2CSR(MIF) == 1 &&
- *       I2CSR(MAAS) == 1
- ****************************************/
-static I2CStatus I2C_Slave_Addr (unsigned int eumbbar)
-{
-	I2C_STAT stat = I2C_Get_Stat (eumbbar);
-	I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar);
-
-	if (stat.srw == 1) {
-		/* we are asked to xmit */
-		ctrl.mtx = 1;
-		I2C_Set_Ctrl (eumbbar, ctrl);	/* set MTX */
-		return I2C_Slave_Xmit (eumbbar);
-	}
-
-	/* we are asked to receive data */
-	ctrl.mtx = 0;
-	I2C_Set_Ctrl (eumbbar, ctrl);
-	(void) load_runtime_reg (eumbbar, I2CDR);	/* do a fake read to start */
-
-	return I2CADDRESS;
-}
-
-/***********************************************
- * function: I2C_ISR
- *
- * description: I2C Interrupt service routine
- *
- * note: Precondition:
- *      I2CSR(MIF) == 1
- **********************************************/
-static I2CStatus I2C_ISR (unsigned int eumbbar)
-{
-	I2C_STAT stat;
-	I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__);
-#endif
-
-	stat = I2C_Get_Stat (eumbbar);
-	ctrl = I2C_Get_Ctrl (eumbbar);
-
-	/* clear MIF */
-	stat.mif = 0;
-
-	/* Now let see what kind of event this is */
-	if (stat.mcf == 1) {
-		/* transfer compete */
-
-		/* clear the MIF bit */
-		I2C_Set_Stat (eumbbar, stat);
-
-		if (ctrl.msta == 1) {
-			/* master */
-			if (ctrl.mtx == 1) {
-				/* check if this is the address phase for master receive */
-				if (MasterRcvAddress == 1) {
-					/* Yes, it is the address phase of master receive */
-					ctrl.mtx = 0;
-					/* now check how much we want to receive */
-					if (ByteToRcv == 1 && RcvBufFulStop == 1) {
-						ctrl.txak = 1;
-					}
-
-					I2C_Set_Ctrl (eumbbar, ctrl);
-					(void) load_runtime_reg (eumbbar, I2CDR);	/* fake read first */
-
-					MasterRcvAddress = 0;
-					return I2CADDRESS;
-
-				}
-
-				/* master xmit */
-				if (stat.rxak == 0) {
-					/* slave has acknowledged */
-					return I2C_Master_Xmit (eumbbar);
-				}
-
-				/* slave has not acknowledged yet, generate a STOP */
-				if (XmitBufEmptyStop == 1) {
-					ctrl.msta = 0;
-					I2C_Set_Ctrl (eumbbar, ctrl);
-				}
-
-				return I2CSUCCESS;
-			}
-
-			/* master receive */
-			return I2C_Master_Rcv (eumbbar);
-		}
-
-		/* slave */
-		if (ctrl.mtx == 1) {
-			/* slave xmit */
-			if (stat.rxak == 0) {
-				/* master has acknowledged */
-				return I2C_Slave_Xmit (eumbbar);
-			}
-
-			/* master has not acknowledged, wait for STOP */
-			/* do nothing for preventing bus from hung */
-			return I2CSUCCESS;
-		}
-
-		/* slave rcv */
-		return I2C_Slave_Rcv (eumbbar);
-
-	} else if (stat.maas == 1) {
-		/* received a call from master */
-
-		/* clear the MIF bit */
-		I2C_Set_Stat (eumbbar, stat);
-
-		/* master is calling us, process the address phase */
-		return I2C_Slave_Addr (eumbbar);
-	} else {
-		/* has to be arbitration lost */
-		stat.mal = 0;
-		I2C_Set_Stat (eumbbar, stat);
-
-		ctrl.msta = 0;			/* return to receive mode */
-		I2C_Set_Ctrl (eumbbar, ctrl);
-	}
-
-	return I2CSUCCESS;
-
-}
-
-/******************************************************
- * function: I2C_Set_Stat
- *
- * description: modify the I2CSR
- *
- *****************************************************/
-static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat)
-{
-	union {
-		unsigned int val;
-		I2C_STAT stat;
-	} s_tmp;
-	union {
-		unsigned int val;
-		I2C_STAT stat;
-	} s;
-
-	s.val = load_runtime_reg (eumbbar, I2CSR);
-	s.val &= 0xffffff08;
-	s_tmp.stat = stat;
-	s.val |= (s_tmp.val & 0xf7);
-
-#ifdef I2CDBG0
-	PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val);
-#endif
-
-	store_runtime_reg (eumbbar, I2CSR, s.val);
-
-}
-
-/******************************************************
- * The following are routines to glue the rest of
- * U-Boot to the Sandpoint I2C driver.
- *****************************************************/
-
-void i2c_init (int speed, int slaveadd)
-{
-#ifdef CFG_I2C_INIT_BOARD
-	/*
-	 * call board specific i2c bus reset routine before accessing the
-	 * environment, which might be in a chip on that bus. For details
-	 * about this problem see doc/I2C_Edge_Conditions.
-	 */
-	i2c_init_board();
-#endif
-
-#ifdef DEBUG
-	I2C_Initialize (0x7f, 0, (void *) printf);
-#else
-	I2C_Initialize (0x7f, 0, 0);
-#endif
-}
-
-int i2c_probe (uchar chip)
-{
-	int tmp;
-
-	/*
-	 * Try to read the first location of the chip.  The underlying
-	 * driver doesn't appear to support sending just the chip address
-	 * and looking for an <ACK> back.
-	 */
-	udelay(10000);
-	return i2c_read (chip, 0, 1, (char *)&tmp, 1);
-}
-
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-	I2CStatus status;
-	uchar xaddr[4];
-
-	if (alen > 0) {
-		xaddr[0] = (addr >> 24) & 0xFF;
-		xaddr[1] = (addr >> 16) & 0xFF;
-		xaddr[2] = (addr >> 8) & 0xFF;
-		xaddr[3] = addr & 0xFF;
-
-		status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen,
-					&xaddr[4 - alen], I2C_NO_STOP, 1,
-					I2C_NO_RESTART);
-		if (status != I2C_SUCCESS) {
-			PRINT ("i2c_read: can't send data address for read\n");
-			return 1;
-		}
-	}
-
-	/* The data transfer will be a continuation. */
-	status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len,
-				buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART :
-				I2C_NO_RESTART));
-
-	if (status != I2C_SUCCESS) {
-		PRINT ("i2c_read: can't perform data transfer\n");
-		return 1;
-	}
-
-	return 0;
-}
-
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
-	I2CStatus status;
-	uchar dummy_buffer[I2C_RXTX_LEN + 2];
-	uchar *p;
-	int i;
-
-	/* fill in address in big endian order */
-	for (i=alen-1; i>=0; --i) {
-		buffer[i] = addr & 0xFF;
-		addr >>= 8;
-	}
-	/* fill in data */
-	p = dummy_buffer + alen;
-
-	for (i=0; i<len; ++i)
-		*p++ = *buffer++;
-
-	status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len,
-				dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART);
-
-#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS
-	udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
-#endif
-	if (status != I2C_SUCCESS) {
-		PRINT ("i2c_write: can't perform data transfer\n");
-		return 1;
-	}
-
-	return 0;
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
-	char buf[1];
-
-	i2c_init (0, 0);
-
-	i2c_read (i2c_addr, reg, 1, buf, 1);
-
-	return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
-	i2c_init (0, 0);
-
-	i2c_write (i2c_addr, reg, 1, &val, 1);
-}
-
-#endif	/* CONFIG_HARD_I2C */

+ 0 - 52
cpu/mpc824x/drivers/i2c/i2c2.S

@@ -1,52 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-#include <config.h>
-#ifdef CONFIG_HARD_I2C
-#include <ppc_asm.tmpl>
-#include <asm/mmu.h>
-/**********************************************************
- * function: load_runtime_reg
- *
- * input:  r3 - value of eumbbar
- *         r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
-	.text
-	.align 2
-	.global load_runtime_reg
-load_runtime_reg:
-
-/*	xor r5,r5,r5
- *	or  r5,r5,r3
- *
- *	lwbrx	r3,r4,r5
- */
-	lwbrx r3,r4,r3
-	sync
-
-	bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- *        r4 - register offset in embedded utility space
- *        r5 - new value to be stored
- *
- ****************************************************************/
-	.text
-	.align 2
-	.global store_runtime_reg
-store_runtime_reg:
-
-	stwbrx r5,  r4, r3
-	sync
-
-	bclr   20,0
-
-#endif /* CONFIG_HARD_I2C */

+ 0 - 103
cpu/mpc824x/drivers/i2c/i2c_export.h

@@ -1,103 +0,0 @@
-#ifndef I2C_EXPORT_H
-#define I2C_EXPORT_H
-
-/****************************************************
- *
- * Copyright Motrola 1999
- *
- ****************************************************/
-
-/* These are the defined return values for the I2C_do_transaction function.
- * Any non-zero value indicates failure.  Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _i2c_status
-{
- I2C_SUCCESS     = 0,
- I2C_ERROR,
-} I2C_Status;
-
-/* These are the defined tasks for I2C_do_transaction.
- * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
- */
-typedef enum _i2c_transaction_mode
-{
-	I2C_MASTER_RCV =  0,
-	I2C_MASTER_XMIT = 1,
-} I2C_TRANSACTION_MODE;
-
-typedef enum _i2c_interrupt_mode
-{
-	I2C_INT_DISABLE =  0,
-	I2C_INT_ENABLE = 1,
-} I2C_INTERRUPT_MODE;
-
-typedef enum _i2c_stop
-{
-	I2C_NO_STOP =  0,
-	I2C_STOP = 1,
-} I2C_STOP_MODE;
-
-typedef enum _i2c_restart
-{
-	I2C_NO_RESTART =  0,
-	I2C_RESTART = 1,
-} I2C_RESTART_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by I2C driver.
- * This is a "generic" I2C interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- *       byte. In our API, we just transfer whatever
- *       we are given
- **************************************************/
-
-
-/*  Initialize I2C unit with the following:
- *  driver's slave address
- *  interrupt enabled
- *  optional pointer to application layer print function
- *
- *  These parameters may be added:
- *  desired clock rate
- *  digital filter frequency sampling rate
- *
- *  This function must be called before I2C unit can be used.
- */
-extern I2C_Status I2C_Initialize(
-	unsigned char addr,            /* driver's I2C slave address */
-	I2C_INTERRUPT_MODE en_int,     /* 1 - enable I2C interrupt
-					* 0 - disable I2C interrupt
-					*/
-	int (*app_print_function)(char *,...)); /* pointer to optional "printf"
-						 * provided by application
-						 */
-
-/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
- * are implemented.  Both are only in polling mode.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- *        I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- *        I2C_RESTART, this is a continuation of existing transaction
- */
-extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
-				      I2C_TRANSACTION_MODE act,
-				      unsigned char i2c_addr,
-				      unsigned char data_addr,
-				      int len,
-				      char *buffer,
-				      I2C_STOP_MODE stop,
-				      int retry,
-				      I2C_RESTART_MODE rsta);
-#endif

+ 16 - 1
cpu/mpc824x/start.S

@@ -526,11 +526,26 @@ relocate_code:
 	stwu	r0,-4(r7)
 	bdnz	3b
 
+4:
+#if !defined(CONFIG_BMW)
+/* Unlock the data cache and invalidate locked area */
+	xor	r0, r0, r0
+	mtspr	1011, r0
+	lis	r4, CFG_INIT_RAM_ADDR@h
+	ori	r4, r4, CFG_INIT_RAM_ADDR@l
+	li	r0, 128
+	mtctr	r0
+41:
+	dcbi	r0, r4
+	addi	r4, r4, 32
+	bdnz	41b
+#endif
+
 /*
  * Now flush the cache: note that we must start from a cache aligned
  * address. Otherwise we might miss one cache line.
  */
-4:	cmpwi	r6,0
+	cmpwi	r6,0
 	add	r5,r3,r5
 	beq	7f		/* Always flush prefetch queue in any case */
 	subi	r0,r6,1

+ 27 - 4
cpu/pxa/mmc.c

@@ -26,11 +26,19 @@
 #include <mmc.h>
 #include <asm/errno.h>
 #include <asm/arch/hardware.h>
+#include <part.h>
 
 #ifdef CONFIG_MMC
 
 extern int
-fat_register_read(int(*block_read)(int device, ulong blknr, ulong blkcnt, uchar *buffer));
+fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+
+static block_dev_desc_t mmc_dev;
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+	return ((block_dev_desc_t *)&mmc_dev);
+}
 
 /*
  * FIXME needs to read cid and csd info to determine block size
@@ -379,9 +387,9 @@ mmc_write(uchar *src, ulong dst, int size)
 	return 0;
 }
 
-int
+ulong
 /****************************************************/
-mmc_bread(int dev_num, ulong blknr, ulong blkcnt, uchar *dst)
+mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
 /****************************************************/
 {
 	int mmc_block_size = MMC_BLOCK_SIZE;
@@ -441,6 +449,21 @@ mmc_init(int verbose)
 			printf("Month = %d\n",cid->month);
 			printf("Year = %d\n",1997 + cid->year);
 		}
+		/* fill in device description */
+		mmc_dev.if_type = IF_TYPE_MMC;
+		mmc_dev.dev = 0;
+		mmc_dev.lun = 0;
+		mmc_dev.type = 0;
+		/* FIXME fill in the correct size (is set to 32MByte) */
+		mmc_dev.blksz = 512;
+		mmc_dev.lba = 0x10000;
+		sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x",
+				cid->id[0], cid->id[1], cid->id[2],
+				cid->sn[0], cid->sn[1], cid->sn[2]);
+		sprintf(mmc_dev.product,"%s",cid->name);
+		sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev);
+		mmc_dev.removable = 0;
+		mmc_dev.block_read = mmc_bread;
 
 		/* MMC exists, get CSD too */
 		resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
@@ -458,7 +481,7 @@ mmc_init(int verbose)
 	MMC_CLKRT = 0;	/* 20 MHz */
 	resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
 
-	fat_register_read(mmc_bread);
+	fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ 
 
 	return rc;
 }

+ 18 - 3
disk/part_dos.c

@@ -67,6 +67,17 @@ static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_nu
 		(is_extended (p->sys_ind) ? " Extd" : ""));
 }
 
+static int test_block_type(unsigned char *buffer)
+{
+	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
+	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
+		return (-1);
+	} /* no DOS Signature at all */
+	if(strncmp(&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0)
+		return DOS_PBR; /* is PBR */
+	return DOS_MBR;	    /* Is MBR */
+}
+
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
@@ -94,14 +105,18 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s
 			dev_desc->dev, ext_part_sector);
 		return;
 	}
-	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
-		buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
+	i=test_block_type(buffer);
+	if(i==-1) {
 		printf ("bad MBR sector signature 0x%02x%02x\n",
 			buffer[DOS_PART_MAGIC_OFFSET],
 			buffer[DOS_PART_MAGIC_OFFSET + 1]);
 		return;
 	}
-
+	if(i==DOS_PBR) {
+		printf ("    1\t\t         0\t%10ld\t%2x\n",
+			dev_desc->lba, buffer[DOS_PBR_MEDIA_TYPE_OFFSET]);
+		return;
+	}
 	/* Print all primary/logical partitions */
 	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
 	for (i = 0; i < 4; i++, pt++) {

+ 4 - 0
disk/part_dos.h

@@ -34,6 +34,10 @@
 #endif
 #define DOS_PART_TBL_OFFSET	0x1be
 #define DOS_PART_MAGIC_OFFSET	0x1fe
+#define DOS_PBR_FSTYPE_OFFSET	0x36
+#define DOS_PBR_MEDIA_TYPE_OFFSET	0x15
+#define DOS_MBR	0
+#define DOS_PBR	1
 
 typedef struct dos_partition {
 	unsigned char boot_ind;		/* 0x80 - active			*/

+ 143 - 41
fs/fat/fat.c

@@ -29,6 +29,7 @@
 #include <config.h>
 #include <fat.h>
 #include <asm/byteorder.h>
+#include <part.h>
 
 #if (CONFIG_COMMANDS & CFG_CMD_FAT)
 
@@ -44,26 +45,70 @@ downcase(char *str)
 	}
 }
 
-int (*dev_block_read)(int device, __u32 blknr, __u32 blkcnt, __u8 *buffer) = 0;
+static  block_dev_desc_t *cur_dev = NULL;
+static unsigned long part_offset = 0;
+static int cur_part = 1;
+
+#define DOS_PART_TBL_OFFSET	0x1be
+#define DOS_PART_MAGIC_OFFSET	0x1fe
+#define DOS_FS_TYPE_OFFSET	0x36
 
 int disk_read (__u32 startblock, __u32 getsize, __u8 * bufptr)
 {
-	/* FIXME we need to determine the start block of the
-	 * partition where the DOS FS resides
-	 */
-	startblock += 32;
-
-	if (dev_block_read) {
-		return dev_block_read (0, startblock, getsize, bufptr);
+	startblock += part_offset;
+	if (cur_dev == NULL)
+		return -1;
+	if (cur_dev->block_read) {
+		return cur_dev->block_read (cur_dev->dev, startblock, getsize, (unsigned long *)bufptr);
 	}
 	return -1;
 }
 
 
 int
-fat_register_read (int (*block_read)(int, __u32, __u32, __u8 *))
+fat_register_device(block_dev_desc_t *dev_desc, int part_no)
 {
-	dev_block_read = block_read;
+	unsigned char buffer[SECTOR_SIZE];
+
+	if (!dev_desc->block_read)
+		return -1;
+	cur_dev=dev_desc;
+	/* check if we have a MBR (on floppies we have only a PBR) */
+	if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
+		printf ("** Can't read from device %d **\n", dev_desc->dev);
+		return -1;
+	}
+	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
+		buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
+		/* no signature found */
+		return -1;
+	}
+	if(!strncmp(&buffer[DOS_FS_TYPE_OFFSET],"FAT",3)) {
+		/* ok, we assume we are on a PBR only */
+		cur_part = 1;
+		part_offset=0;
+	}
+	else {
+#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)
+		disk_partition_t info;
+		if(!get_partition_info(dev_desc, part_no, &info)) {
+			part_offset = info.start;
+			cur_part = part_no;
+		}
+		else {
+			printf ("** Partition %d not valid on device %d **\n",part_no,dev_desc->dev);
+			return -1;
+		}
+#else
+		/* FIXME we need to determine the start block of the
+		 * partition where the DOS FS resides. This can be done
+		 * by using the get_partition_info routine. For this
+		 * purpose the libpart must be included.
+		 */
+		part_offset=32;
+		cur_part = 1;
+#endif
+	}
 	return 0;
 }
 
@@ -246,25 +291,21 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size)
 	}
 
 	FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect);
-	while (size > 0) {
-		if (size >= FS_BLOCK_SIZE) {
-			if (disk_read(startsect + idx, 1, buffer) < 0) {
-				FAT_DPRINT("Error reading data\n");
-				return -1;
-			}
-		} else {
-			__u8 tmpbuf[FS_BLOCK_SIZE];
-			if (disk_read(startsect + idx, 1, tmpbuf) < 0) {
-				FAT_DPRINT("Error reading data\n");
-				return -1;
-			}
-			memcpy(buffer, tmpbuf, size);
-
-			return 0;
+	if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) {
+		FAT_DPRINT("Error reading data\n");
+		return -1;
+	}
+	if(size % FS_BLOCK_SIZE) {
+		__u8 tmpbuf[FS_BLOCK_SIZE];
+		idx= size/FS_BLOCK_SIZE;
+		if (disk_read(startsect + idx, 1, tmpbuf) < 0) {
+			FAT_DPRINT("Error reading data\n");
+			return -1;
 		}
-		buffer += FS_BLOCK_SIZE;
-		size -= FS_BLOCK_SIZE;
-		idx++;
+		buffer += idx*FS_BLOCK_SIZE;
+
+		memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE);
+		return 0;
 	}
 
 	return 0;
@@ -283,6 +324,8 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
 	unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
 	unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE;
 	__u32 curclust = START(dentptr);
+	__u32 endclust, newclust;
+	unsigned long actsize;
 
 	FAT_DPRINT("Filesize: %ld bytes\n", filesize);
 
@@ -290,25 +333,56 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
 
 	FAT_DPRINT("Reading: %ld bytes\n", filesize);
 
+	actsize=bytesperclust;
+	endclust=curclust;
 	do {
-		int getsize = (filesize > bytesperclust) ? bytesperclust :
-			filesize;
-
-		if (get_cluster(mydata, curclust, buffer, getsize) != 0) {
+		/* search for consecutive clusters */
+		while(actsize < filesize) {
+			newclust = get_fatent(mydata, endclust);
+			if((newclust -1)!=endclust)
+				goto getit;
+			if (newclust <= 0x0001 || newclust >= 0xfff0) {
+				FAT_DPRINT("curclust: 0x%x\n", newclust);
+				FAT_DPRINT("Invalid FAT entry\n");
+				return gotsize;
+			}
+			endclust=newclust;
+			actsize+= bytesperclust;
+		}
+		/* actsize >= file size */
+		actsize -= bytesperclust;
+		/* get remaining clusters */
+		if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
 			FAT_ERROR("Error reading cluster\n");
 			return -1;
 		}
-		gotsize += getsize;
-		filesize -= getsize;
-		if (filesize <= 0) return gotsize;
-		buffer += getsize;
-
-		curclust = get_fatent(mydata, curclust);
+		/* get remaining bytes */
+		gotsize += (int)actsize;
+		filesize -= actsize;
+		buffer += actsize;
+		actsize= filesize;
+		if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) {
+			FAT_ERROR("Error reading cluster\n");
+			return -1;
+		}
+		gotsize+=actsize;
+		return gotsize;
+getit:
+		if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
+			FAT_ERROR("Error reading cluster\n");
+			return -1;
+		}
+		gotsize += (int)actsize;
+		filesize -= actsize;
+		buffer += actsize;
+		curclust = get_fatent(mydata, endclust);
 		if (curclust <= 0x0001 || curclust >= 0xfff0) {
 			FAT_DPRINT("curclust: 0x%x\n", curclust);
 			FAT_ERROR("Invalid FAT entry\n");
 			return gotsize;
 		}
+		actsize=bytesperclust;
+		endclust=curclust;
 	} while (1);
 }
 
@@ -641,7 +715,7 @@ static long
 do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
 	     int dols)
 {
-    __u8 block[FS_BLOCK_SIZE];  /* Block buffer */
+    __u8 block[MAX_CLUSTSIZE];  /* Block buffer */
     char fnamecopy[2048];
     boot_sector bs;
     volume_info volinfo;
@@ -713,7 +787,7 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
     while (1) {
 	int i;
 
-	if (disk_read (cursect, 1, block) < 0) {
+	if (disk_read (cursect, mydata->clust_size, block) < 0) {
 	    FAT_DPRINT ("Error: reading rootdir block\n");
 	    return -1;
 	}
@@ -880,8 +954,35 @@ file_fat_detectfs(void)
 	boot_sector	bs;
 	volume_info	volinfo;
 	int		fatsize;
+	char	vol_label[12];
 
-	return read_bootsectandvi(&bs, &volinfo, &fatsize);
+	if(cur_dev==NULL) {
+		printf("No current device\n");
+		return 1;
+	}
+#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)
+	printf("Interface:  ");
+	switch(cur_dev->if_type) {
+		case IF_TYPE_IDE :	printf("IDE"); break;
+		case IF_TYPE_SCSI :	printf("SCSI"); break;
+		case IF_TYPE_ATAPI :	printf("ATAPI"); break;
+		case IF_TYPE_USB :	printf("USB"); break;
+		case IF_TYPE_DOC :	printf("DOC"); break;
+		case IF_TYPE_MMC :	printf("MMC"); break;
+		default :		printf("Unknown");
+	}
+	printf("\n  Device %d: ",cur_dev->dev);
+	dev_print(cur_dev);
+#endif
+	if(read_bootsectandvi(&bs, &volinfo, &fatsize)) {
+		printf("\nNo valid FAT fs found\n");
+		return 1;
+	}
+	memcpy (vol_label, volinfo.volume_label, 11);
+	vol_label[11] = '\0';
+	volinfo.fs_type[5]='\0';
+	printf("Partition %d: Filesystem: %s \"%s\"\n",cur_part,volinfo.fs_type,vol_label);
+	return 0;
 }
 
 
@@ -895,6 +996,7 @@ file_fat_ls(const char *dir)
 long
 file_fat_read(const char *filename, void *buffer, unsigned long maxsize)
 {
+	printf("reading %s\n",filename);
 	return do_fat_read(filename, buffer, maxsize, LS_NO);
 }
 

+ 75 - 21
fs/jffs2/jffs2_1pass.c

@@ -1,4 +1,3 @@
-/* vi: set sw=4 ts=4: */
 /*
 -------------------------------------------------------------------------
  * Filename:      jffs2.c
@@ -265,20 +264,56 @@ insert_node(struct b_list *list, u32 offset)
 }
 
 #ifdef CFG_JFFS2_SORT_FRAGMENTS
+/* Sort data entries with the latest version last, so that if there
+ * is overlapping data the latest version will be used.
+ */
 static int compare_inodes(struct b_node *new, struct b_node *old)
 {
 	struct jffs2_raw_inode *jNew = (struct jffs2_raw_inode *)new->offset;
 	struct jffs2_raw_inode *jOld = (struct jffs2_raw_inode *)old->offset;
 
-	return jNew->version < jOld->version;
+	return jNew->version > jOld->version;
 }
 
+/* Sort directory entries so all entries in the same directory
+ * with the same name are grouped together, with the latest version
+ * last. This makes it easy to eliminate all but the latest version
+ * by marking the previous version dead by setting the inode to 0.
+ */
 static int compare_dirents(struct b_node *new, struct b_node *old)
 {
 	struct jffs2_raw_dirent *jNew = (struct jffs2_raw_dirent *)new->offset;
 	struct jffs2_raw_dirent *jOld = (struct jffs2_raw_dirent *)old->offset;
-
-	return jNew->version > jOld->version;
+	int cmp;
+
+	/* ascending sort by pino */
+	if (jNew->pino != jOld->pino)
+		return jNew->pino > jOld->pino;
+
+	/* pino is the same, so use ascending sort by nsize, so
+	 * we don't do strncmp unless we really must.
+	 */
+	if (jNew->nsize != jOld->nsize)
+		return jNew->nsize > jOld->nsize;
+
+	/* length is also the same, so use ascending sort by name
+	 */
+	cmp = strncmp(jNew->name, jOld->name, jNew->nsize);
+	if (cmp != 0)
+		return cmp > 0;
+
+	/* we have duplicate names in this directory, so use ascending
+	 * sort by version
+	 */
+	if (jNew->version > jOld->version) {
+		/* since jNew is newer, we know jOld is not valid, so
+		 * mark it with inode 0 and it will not be used
+		 */
+		jOld->ino = 0;
+		return 1;
+	}
+	
+	return 0;
 }
 #endif
 
@@ -327,12 +362,31 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
 	struct b_node *b;
 	struct jffs2_raw_inode *jNode;
 	u32 totalSize = 0;
-	u16 latestVersion = 0;
+	u32 latestVersion = 0;
 	char *lDest;
 	char *src;
 	long ret;
 	int i;
 	u32 counter = 0;
+#ifdef CFG_JFFS2_SORT_FRAGMENTS
+	/* Find file size before loading any data, so fragments that
+	 * start past the end of file can be ignored. A fragment
+	 * that is partially in the file is loaded, so extra data may
+	 * be loaded up to the next 4K boundary above the file size.
+	 * This shouldn't cause trouble when loading kernel images, so
+	 * we will live with it.
+	 */
+	for (b = pL->frag.listHead; b != NULL; b = b->next) {
+		jNode = (struct jffs2_raw_inode *) (b->offset);
+		if ((inode == jNode->ino)) {
+			/* get actual file length from the newest node */
+			if (jNode->version >= latestVersion) {
+				totalSize = jNode->isize;
+				latestVersion = jNode->version;
+			}
+		}
+	}
+#endif
 
 	for (b = pL->frag.listHead; b != NULL; b = b->next) {
 		jNode = (struct jffs2_raw_inode *) (b->offset);
@@ -349,11 +403,14 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
 			putLabeledWord("read_inode: usercompr = ", jNode->usercompr);
 			putLabeledWord("read_inode: flags = ", jNode->flags);
 #endif
+
+#ifndef CFG_JFFS2_SORT_FRAGMENTS
 			/* get actual file length from the newest node */
 			if (jNode->version >= latestVersion) {
 				totalSize = jNode->isize;
 				latestVersion = jNode->version;
 			}
+#endif
 
 			if(dest) {
 				src = ((char *) jNode) + sizeof(struct jffs2_raw_inode);
@@ -430,15 +487,11 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)
 		if ((pino == jDir->pino) && (len == jDir->nsize) &&
 		    (jDir->ino) &&	/* 0 for unlink */
 		    (!strncmp(jDir->name, name, len))) {	/* a match */
-			if (jDir->version < version) continue;
+			if (jDir->version < version)
+				continue;
 
-		        if(jDir->version == 0) {
-			    	/* Is this legal? */
-				putstr(" ** WARNING ** ");
-				putnstr(jDir->name, jDir->nsize);
-				putstr(" is version 0 (in find, ignoring)\r\n");
-			} else if(jDir->version == version) {
-			    	/* Im pretty sure this isn't ... */
+			if (jDir->version == version && inode != 0) {
+			    	/* I'm pretty sure this isn't legal */
 				putstr(" ** ERROR ** ");
 				putnstr(jDir->name, jDir->nsize);
 				putLabeledWord(" has dup version =", version);
@@ -643,15 +696,11 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)
 	for(b = pL->dir.listHead; b; b = b->next) {
 		jDir = (struct jffs2_raw_dirent *) (b->offset);
 		if (ino == jDir->ino) {
-		    	if(jDir->version < version) continue;
+		    	if (jDir->version < version)
+				continue;
 
-			if(jDir->version == 0) {
-			    	/* Is this legal? */
-				putstr(" ** WARNING ** ");
-				putnstr(jDir->name, jDir->nsize);
-				putstr(" is version 0 (in resolve, ignoring)\r\n");
-			} else if(jDir->version == version) {
-			    	/* Im pretty sure this isn't ... */
+			if (jDir->version == version && jDirFound) {
+			    	/* I'm pretty sure this isn't legal */
 				putstr(" ** ERROR ** ");
 				putnstr(jDir->name, jDir->nsize);
 				putLabeledWord(" has dup version (resolve) = ",
@@ -891,6 +940,11 @@ jffs2_1pass_build_lists(struct part_info * part)
 					printf("OOPS Cleanmarker has bad size "
 						"%d != %d\n", node->totlen,
 						sizeof(struct jffs2_unknown_node));
+			} else if (node->nodetype == JFFS2_NODETYPE_PADDING) {
+				if (node->totlen < sizeof(struct jffs2_unknown_node))
+					printf("OOPS Padding has bad size "
+						"%d < %d\n", node->totlen,
+						sizeof(struct jffs2_unknown_node));
 			} else {
 				printf("Unknown node type: %x len %d "
 					"offset 0x%x\n", node->nodetype,

+ 2 - 2
include/configs/AdderII.h

@@ -48,10 +48,10 @@
 #define CONFIG_CLOCKS_IN_MHZ	1
 
 /* Monitor Functions */
-#define CONFIG_COMMANDS		( CFG_CMD_FLASH | \
+#define CONFIG_COMMANDS		( CFG_CMD_ENV	| \
+				  CFG_CMD_FLASH | \
 				  CFG_CMD_MEMORY| \
 				  CFG_CMD_NET   | \
-				  CFG_CMD_ENV	| \
 				  CFG_CMD_PING  | \
 				  CFG_CMD_SDRAM )
 

+ 6 - 4
include/configs/MIP405.h

@@ -67,6 +67,7 @@
 			CFG_CMD_DATE	| \
 			CFG_CMD_ELF	| \
 			CFG_CMD_MII	| \
+			CFG_CMD_FAT | \
 			CFG_CMD_PING	| \
 			CFG_CMD_SAVES	| \
 			CFG_CMD_BSP	)
@@ -246,9 +247,10 @@
 /*
  * Init Memory Controller:
  */
-
-#define FLASH_BASE0_PRELIM	0xFFC00000	/* FLASH bank #0	*/
-#define FLASH_BASE1_PRELIM	0		/* FLASH bank #1	*/
+#define FLASH_MAX_SIZE		0x00800000		/* 8MByte max */
+#define FLASH_BASE_PRELIM	0xFF800000  /* open the flash CS */
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define FLASH_SIZE_PRELIM	 3  /* maximal flash FLASH size bank #0	*/
 
 #define CONFIG_BOARD_PRE_INIT
 
@@ -325,7 +327,7 @@
 #undef	CONFIG_IDE_LED	       /* no led for ide supported     */
 #define CONFIG_IDE_RESET       /* reset for ide supported...	*/
 #define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */
-
+#define CONFIG_SUPPORT_VFAT
 /************************************************************
  * ATAPI support (experimental)
  ************************************************************/

+ 9 - 3
include/configs/PIP405.h

@@ -50,11 +50,13 @@
 			CFG_CMD_PCI	| \
 			CFG_CMD_CACHE	| \
 			CFG_CMD_IRQ	| \
+			CFG_CMD_ECHO	| \
 			CFG_CMD_EEPROM	| \
 			CFG_CMD_I2C	| \
 			CFG_CMD_REGINFO | \
 			CFG_CMD_FDC	| \
 			CFG_CMD_SCSI	| \
+			CFG_CMD_FAT 	| \
 			CFG_CMD_DATE	| \
 			CFG_CMD_ELF	| \
 			CFG_CMD_USB	| \
@@ -141,7 +143,7 @@
 #define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/
 #define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
 
-
+#define CONFIG_MISC_INIT_R
 /***********************************************************
  * Miscellaneous configurable options
  **********************************************************/
@@ -231,9 +233,12 @@
 /*
  * Init Memory Controller:
  */
+#define FLASH_MAX_SIZE		0x00800000		/* 8MByte max */
+#define FLASH_BASE_PRELIM	0xFF800000  /* open the flash CS */
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define FLASH_SIZE_PRELIM	 3  /* maximal flash FLASH size bank #0	*/
 
-#define FLASH_BASE0_PRELIM	0xFFC00000	/* FLASH bank #0	*/
-#define FLASH_BASE1_PRELIM	0		/* FLASH bank #1	*/
+#define CONFIG_BOARD_PRE_INIT
 
 /* Configuration Port location */
 #define CONFIG_PORT_ADDR	0xF4000000
@@ -299,6 +304,7 @@
 #undef	CONFIG_IDE_LED			/* no led for ide supported	*/
 #define CONFIG_IDE_RESET		/* reset for ide supported...	*/
 #define CONFIG_IDE_RESET_ROUTINE	/* with a special reset function */
+#define CONFIG_SUPPORT_VFAT
 
 /************************************************************
  * ATAPI support (experimental)

+ 22 - 7
include/configs/SXNI855T.h

@@ -145,12 +145,22 @@
 
 #define CONFIG_COMMANDS		(CONFIG_CMD_DFL		| \
 				 CFG_CMD_EEPROM		| \
+				 CFG_CMD_JFFS2		| \
 				 CFG_CMD_NAND		| \
 				 CFG_CMD_DATE)
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
 
+#define CFG_JFFS_CUSTOM_PART
+#define CFG_JFFS2_SORT_FRAGMENTS
+/* JFFS2 location when using NOR flash */
+#define CFG_JFFS2_BASE	(CFG_FLASH_BASE + 0x80000)
+#define CFG_JFFS2_SIZE	(0x780000)
+/* JFFS2 location (in RAM) when using NAND flash */
+#define	CFG_JFFS2_RAMBASE 0x400000
+#define	CFG_JFFS2_RAMSIZE 0x200000	/* NAND boot partition is 2MiB	*/
+
 /* NAND flash support */
 #define CONFIG_MTD_NAND_ECC_JFFS2
 #define CFG_MAX_NAND_DEVICE	1	/* Max number of NAND devices	*/
@@ -405,13 +415,18 @@
 
 #define CONFIG_RESET_ON_PANIC		/* reset if system panic() */
 
-/* to put environment in EEROM */
-#define	CFG_ENV_IS_IN_EEPROM	1
-#define CFG_ENV_OFFSET		0	/* Start right at beginning of NVRAM */
-#define CFG_ENV_SIZE		1024	/* Use only a part of it*/
-
-#if 1
-#define CONFIG_BOOT_RETRY_TIME	60	/* boot if no command in 60 seconds */
+#define CFG_ENV_IS_IN_FLASH
+#ifdef CFG_ENV_IS_IN_FLASH
+  /* environment is in FLASH */
+  #define CFG_ENV_ADDR		0xF8040000	/* AM29LV641 or AM29LV800BT */
+  #define CFG_ENV_ADDR_REDUND	0xF8050000	/* AM29LV641 or AM29LV800BT */
+  #define CFG_ENV_SECT_SIZE	0x00010000
+  #define CFG_ENV_SIZE		0x00002000
+#else
+  /* environment is in EEPROM */
+  #define CFG_ENV_IS_IN_EEPROM		1
+  #define CFG_ENV_OFFSET		0	/* at beginning of EEPROM */
+  #define CFG_ENV_SIZE		     1024	/* Use only a part of it*/
 #endif
 
 #if 1

+ 1 - 0
include/fat.h

@@ -204,5 +204,6 @@ int file_fat_detectfs(void);
 int file_fat_ls(const char *dir);
 long file_fat_read(const char *filename, void *buffer, unsigned long maxsize);
 const char *file_getfsname(int idx);
+int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
 
 #endif /* _FAT_H_ */

+ 1 - 0
include/jffs2/jffs2.h

@@ -82,6 +82,7 @@
 #define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)
 #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)
 #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
+#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
 
 /* Maybe later... */
 /*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */

+ 1 - 0
include/part.h

@@ -50,6 +50,7 @@ typedef struct block_dev_desc {
 #define IF_TYPE_ATAPI		3
 #define IF_TYPE_USB		4
 #define IF_TYPE_DOC		5
+#define IF_TYPE_MMC		6
 
 /* Part types */
 #define	PART_TYPE_UNKNOWN	0x00

+ 2 - 3
post/cache_8xx.S

@@ -27,8 +27,7 @@
     defined(CONFIG_MPC850) || \
     defined(CONFIG_MPC855) || \
     defined(CONFIG_MPC860) || \
-    defined(CONFIG_MPC862) || \
-    defined(CONFIG_MPC824X)
+    defined(CONFIG_MPC862)
 
 #include <post.h>
 #include <ppc_asm.tmpl>
@@ -491,6 +490,6 @@ cache_post_test6_data:
 	mtlr	r0
 	blr
 
-#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 || MPC824X */
+#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 */
 #endif /* CONFIG_POST & CFG_POST_CACHE */
 #endif /* CONFIG_POST */

+ 1 - 3
post/ether.c

@@ -38,7 +38,7 @@
 #ifdef CONFIG_POST
 
 #include <post.h>
-
+#if CONFIG_POST & CFG_POST_ETHER
 #if defined(CONFIG_8xx)
 #include <commproc.h>
 #elif defined(CONFIG_MPC8260)
@@ -50,8 +50,6 @@
 #include <command.h>
 #include <net.h>
 
-#if CONFIG_POST & CFG_POST_ETHER
-
 #define MIN_PACKET_LENGTH	64
 #define MAX_PACKET_LENGTH	256
 #define TEST_NUM		1

+ 1 - 2
post/uart.c

@@ -39,6 +39,7 @@
 #ifdef CONFIG_POST
 
 #include <post.h>
+#if CONFIG_POST & CFG_POST_UART
 #if defined(CONFIG_8xx)
 #include <commproc.h>
 #elif defined(CONFIG_MPC8260)
@@ -49,8 +50,6 @@
 #include <command.h>
 #include <net.h>
 
-#if CONFIG_POST & CFG_POST_UART
-
 #define CTLR_SMC 0
 #define CTLR_SCC 1