浏览代码

* Patch by David Mller, 13 Sep 2003:
various changes to VCMA9 board specific files

* Add I2C support for MGT5100 / MPC5200

wdenk 21 年之前
父节点
当前提交
531716e171

+ 5 - 0
CHANGELOG

@@ -2,6 +2,11 @@
 Changes for U-Boot 1.0.0:
 Changes for U-Boot 1.0.0:
 ======================================================================
 ======================================================================
 
 
+* Patch by David Müller, 13 Sep 2003:
+  various changes to VCMA9 board specific files
+
+* Add I2C support for MGT5100 / MPC5200
+
 * Patch by Rune Torgersen, 11 Sep 2003:
 * Patch by Rune Torgersen, 11 Sep 2003:
   Changed default memory option on MPC8266ADS to NOT be Page Based
   Changed default memory option on MPC8266ADS to NOT be Page Based
   Interleave, since this doesn't work very well with the standard
   Interleave, since this doesn't work very well with the standard

+ 2 - 1
README

@@ -203,6 +203,7 @@ Directory Hierarchy:
 - board/mpl/common	Common files for MPL boards
 - board/mpl/common	Common files for MPL boards
 - board/mpl/pip405	Files specific to PIP405     boards
 - board/mpl/pip405	Files specific to PIP405     boards
 - board/mpl/mip405	Files specific to MIP405     boards
 - board/mpl/mip405	Files specific to MIP405     boards
+- board/mpl/vcma9	Files specific to VCMA9      boards
 - board/musenki	Files specific to MUSEKNI    boards
 - board/musenki	Files specific to MUSEKNI    boards
 - board/mvs1	Files specific to MVS1       boards
 - board/mvs1	Files specific to MVS1       boards
 - board/nx823   Files specific to NX823      boards
 - board/nx823   Files specific to NX823      boards
@@ -363,7 +364,7 @@ The following options need to be configured:
 		CONFIG_IMPA7,       CONFIG_LART,       CONFIG_LUBBOCK,
 		CONFIG_IMPA7,       CONFIG_LART,       CONFIG_LUBBOCK,
 		CONFIG_INNOVATOROMAP1510,	CONFIG_INNOVATOROMAP1610
 		CONFIG_INNOVATOROMAP1510,	CONFIG_INNOVATOROMAP1610
 		CONFIG_SHANNON,     CONFIG_SMDK2400,   CONFIG_SMDK2410,
 		CONFIG_SHANNON,     CONFIG_SMDK2400,   CONFIG_SMDK2410,
-		CONFIG_TRAB,	    CONFIG_AT91RM9200DK
+		CONFIG_TRAB,	    CONFIG_VCMA9,      CONFIG_AT91RM9200DK
 
 
 
 
 - CPU Module Type: (if CONFIG_COGENT is defined)
 - CPU Module Type: (if CONFIG_COGENT is defined)

+ 42 - 4
board/mpl/vcma9/cmd_vcma9.c

@@ -41,9 +41,12 @@ static uchar cs8900_chksum(ushort data)
 #endif
 #endif
 
 
 extern void print_vcma9_info(void);
 extern void print_vcma9_info(void);
-extern int vcma9_cantest(void);
+extern int vcma9_cantest(int);
 extern int vcma9_nandtest(void);
 extern int vcma9_nandtest(void);
-extern int vcma9_dactest(void);
+extern int vcma9_nanderase(void);
+extern int vcma9_nandread(ulong);
+extern int vcma9_nandwrite(ulong);
+extern int vcma9_dactest(int);
 extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */
@@ -126,18 +129,53 @@ int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 #endif
 #endif
 #if 0
 #if 0
 	if (strcmp(argv[1], "cantest") == 0) {
 	if (strcmp(argv[1], "cantest") == 0) {
-		vcma9_cantest();
+		if (argc >= 3)
+			vcma9_cantest(strcmp(argv[2], "s") ? 0 : 1);
+		else
+			vcma9_cantest(0);
 		return 0;
 		return 0;
 	}
 	}
 	if (strcmp(argv[1], "nandtest") == 0) {
 	if (strcmp(argv[1], "nandtest") == 0) {
 		vcma9_nandtest();
 		vcma9_nandtest();
 		return 0;
 		return 0;
 	}
 	}
+	if (strcmp(argv[1], "nanderase") == 0) {
+		vcma9_nanderase();
+		return 0;
+	}
+	if (strcmp(argv[1], "nandread") == 0) {
+		ulong offset = 0;
+
+		if (argc >= 3)
+			offset = simple_strtoul(argv[2], NULL, 16);
+
+		vcma9_nandread(offset);
+		return 0;
+	}
+	if (strcmp(argv[1], "nandwrite") == 0) {
+		ulong offset = 0;
+
+		if (argc >= 3)
+			offset = simple_strtoul(argv[2], NULL, 16);
+
+		vcma9_nandwrite(offset);
+		return 0;
+	}
 	if (strcmp(argv[1], "dactest") == 0) {
 	if (strcmp(argv[1], "dactest") == 0) {
-		vcma9_dactest();
+		if (argc >= 3)
+			vcma9_dactest(strcmp(argv[2], "s") ? 0 : 1);
+		else
+		vcma9_dactest(0);
 		return 0;
 		return 0;
 	}
 	}
 #endif
 #endif
 
 
 	return (do_mplcommon(cmdtp, flag, argc, argv));
 	return (do_mplcommon(cmdtp, flag, argc, argv));
 }
 }
+
+U_BOOT_CMD(
+	vcma9, 6, 1, do_vcma9,
+	"vcma9   - VCMA9 specific commands\n",
+	"flash mem [SrcAddr]\n    - updates U-Boot with image in memory\n"
+);
+

+ 7 - 7
board/mpl/vcma9/config.mk

@@ -1,5 +1,5 @@
 #
 #
-# (C) Copyright 2002
+# (C) Copyright 2002, 2003
 # David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
 # David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
 #
 #
 # MPL VCMA9 board with S3C2410X (ARM920T) cpu
 # MPL VCMA9 board with S3C2410X (ARM920T) cpu
@@ -8,17 +8,17 @@
 #
 #
 
 
 #
 #
-# MPL VCMA9 has 1 bank of 64 MB DRAM
-#
-# 3000'0000 to 3400'0000
+# MPL VCMA9 has 1 bank of minimal 16 MB DRAM
+# from 0x30000000
 #
 #
 # Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
 # Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
-# optionally with a ramdisk at 3080'0000
+# optionally with a ramdisk at 3040'0000
 #
 #
-# we load ourself to 33F8'0000
+# we load ourself to 30F8'0000
 #
 #
-# download area is 3300'0000
+# download area is 3080'0000
 #
 #
 
 
 
 
+#TEXT_BASE = 0x30F80000
 TEXT_BASE = 0x33F80000
 TEXT_BASE = 0x33F80000

+ 54 - 5
board/mpl/vcma9/memsetup.S

@@ -34,7 +34,9 @@
 
 
 /* some parameters for the board */
 /* some parameters for the board */
 
 
-#define BWSCON	0x48000000
+#define BWSCON		0x48000000
+#define PLD_BASE	0x2C000000
+#define SDRAM_REG	0x2C000106
 
 
 /* BWSCON */
 /* BWSCON */
 #define DW8		 	(0x0)
 #define DW8		 	(0x0)
@@ -43,6 +45,9 @@
 #define WAIT		 	(0x1<<2)
 #define WAIT		 	(0x1<<2)
 #define UBLB		 	(0x1<<3)
 #define UBLB		 	(0x1<<3)
 
 
+/* BANKSIZE */
+#define BURST_EN		(0x1<<7)
+
 #define B1_BWSCON	  	(DW16)
 #define B1_BWSCON	  	(DW16)
 #define B2_BWSCON	  	(DW32)
 #define B2_BWSCON	  	(DW32)
 #define B3_BWSCON	  	(DW32)
 #define B3_BWSCON	  	(DW32)
@@ -130,24 +135,39 @@ memsetup:
 	/* memory control configuration */
 	/* memory control configuration */
 	/* make r0 relative the current location so that it */
 	/* make r0 relative the current location so that it */
 	/* reads SMRDATA out of FLASH rather than memory ! */
 	/* reads SMRDATA out of FLASH rather than memory ! */
-	ldr     r0, =SMRDATA
+	ldr     r0, =CSDATA
 	ldr	r1, _TEXT_BASE
 	ldr	r1, _TEXT_BASE
 	sub	r0, r0, r1
 	sub	r0, r0, r1
 	ldr	r1, =BWSCON	/* Bus Width Status Controller */
 	ldr	r1, =BWSCON	/* Bus Width Status Controller */
-	add     r2, r0, #13*4
+	add     r2, r0, #CSDATA_END-CSDATA
 0:
 0:
 	ldr     r3, [r0], #4
 	ldr     r3, [r0], #4
 	str     r3, [r1], #4
 	str     r3, [r1], #4
 	cmp     r2, r0
 	cmp     r2, r0
 	bne     0b
 	bne     0b
 
 
+	/* PLD access is now possible */
+	/* r0 == SDRAMDATA */
+	/* r1 == SDRAM controller regs */
+	ldr	r2, =PLD_BASE
+	ldrb	r3, [r2, #SDRAM_REG-PLD_BASE]
+	mov	r4, #SDRAMDATA1_END-SDRAMDATA
+	/* calculate start and end point */
+	mla	r0, r3, r4, r0 
+	add     r2, r0, r4
+0:
+	ldr     r3, [r0], #4
+	str     r3, [r1], #4
+	cmp     r2, r0
+	bne     0b
+	
 	/* everything is fine now */
 	/* everything is fine now */
 	mov	pc, lr
 	mov	pc, lr
 
 
 	.ltorg
 	.ltorg
 /* the literal pools origin */
 /* the literal pools origin */
 
 
-SMRDATA:
+CSDATA:
     .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
     .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
     .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
     .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
     .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
     .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
@@ -155,9 +175,38 @@ SMRDATA:
     .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
     .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
     .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
     .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
     .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
     .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
+CSDATA_END:
+
+SDRAMDATA:
+/* 4Mx8x4 */
+    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+    .word 0x32 + BURST_EN
+    .word 0x30
+    .word 0x30
+SDRAMDATA1_END:
+
+/* 8Mx8x4 (not implemented yet) */
+    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+    .word 0x32 + BURST_EN
+    .word 0x30
+    .word 0x30
+    
+/* 2Mx8x4 (not implemented yet) */
+    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+    .word 0x32 + BURST_EN
+    .word 0x30
+    .word 0x30
+    
+/* 4Mx8x2 (not implemented yet) */
     .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
     .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
     .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
     .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
     .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
     .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
-    .word 0x32
+    .word 0x32 + BURST_EN
     .word 0x30
     .word 0x30
     .word 0x30
     .word 0x30

+ 89 - 38
board/mpl/vcma9/vcma9.c

@@ -130,16 +130,6 @@ int board_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
-int dram_init(void)
-{
-	DECLARE_GLOBAL_DATA_PTR;
-
-	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-
-	return 0;
-}
-
 /*
 /*
  * NAND flash initialization.
  * NAND flash initialization.
  */
  */
@@ -162,9 +152,16 @@ static inline void NF_Reset(void)
 
 
 static inline void NF_Init(void)
 static inline void NF_Init(void)
 {
 {
+#if 0 /* a little bit too optimistic */
 #define TACLS   0
 #define TACLS   0
 #define TWRPH0  3
 #define TWRPH0  3
 #define TWRPH1  0
 #define TWRPH1  0
+#else
+#define TACLS   0
+#define TWRPH0  4
+#define TWRPH1  2
+#endif
+
     NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
     NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
     /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
     /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
     /* 1  1    1     1,   1      xxx,  r xxx,   r xxx */
     /* 1  1    1     1,   1      xxx,  r xxx,   r xxx */
@@ -177,15 +174,12 @@ void
 nand_init(void)
 nand_init(void)
 {
 {
 	S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
 	S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
-	unsigned totlen;
 
 
 	NF_Init();
 	NF_Init();
 #ifdef DEBUG
 #ifdef DEBUG
 	printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
 	printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
 #endif
 #endif
-	totlen = nand_probe((ulong)nand) >> 20;
-
-	printf ("%4lu MB\n", totlen >> 20);
+	printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
 }
 }
 #endif
 #endif
 
 
@@ -193,29 +187,40 @@ nand_init(void)
  * Get some Board/PLD Info
  * Get some Board/PLD Info
  */
  */
 
 
-static uchar Get_PLD_ID(void)
+static u8 Get_PLD_ID(void)
+{
+	VCMA9_PLD * const pld = VCMA9_GetBase_PLD();
+	
+	return(pld->ID);
+}
+
+static u8 Get_PLD_BOARD(void)
 {
 {
-	return(*(volatile uchar *)PLD_ID_REG);
+	VCMA9_PLD * const pld = VCMA9_GetBase_PLD();
+	
+	return(pld->BOARD);
 }
 }
 
 
-static uchar Get_PLD_BOARD(void)
+static u8 Get_PLD_SDRAM(void)
 {
 {
-	return(*(volatile uchar *)PLD_BOARD_REG);
+	VCMA9_PLD * const pld = VCMA9_GetBase_PLD();
+	
+	return(pld->SDRAM);
 }
 }
 
 
-static uchar Get_PLD_Version(void)
+static u8 Get_PLD_Version(void)
 {
 {
 	return((Get_PLD_ID() >> 4) & 0x0F);
 	return((Get_PLD_ID() >> 4) & 0x0F);
 }
 }
 
 
-static uchar Get_PLD_Revision(void)
+static u8 Get_PLD_Revision(void)
 {
 {
 	return(Get_PLD_ID() & 0x0F);
 	return(Get_PLD_ID() & 0x0F);
 }
 }
 
 
 static int Get_Board_Config(void)
 static int Get_Board_Config(void)
 {
 {
-	uchar config = Get_PLD_BOARD() & 0x03;
+	u8 config = Get_PLD_BOARD() & 0x03;
 
 
 	if (config == 3)
 	if (config == 3)
 	    return 1;
 	    return 1;
@@ -228,6 +233,54 @@ static uchar Get_Board_PCB(void)
 	return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A');
 	return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A');
 }
 }
 
 
+static u8 Get_SDRAM_ChipNr(void)
+{
+	switch ((Get_PLD_SDRAM() >> 4) & 0x0F) {
+		case 0: return 4;
+		case 1: return 1;
+		case 2: return 2;
+		default: return 0;
+	}
+}
+
+static ulong Get_SDRAM_ChipSize(void)
+{
+	switch (Get_PLD_SDRAM() & 0x0F) {
+		case 0: return 16 * (1024*1024);
+		case 1: return 32 * (1024*1024);
+		case 2: return  8 * (1024*1024);
+		case 3: return  8 * (1024*1024);
+		default: return 0;
+	}	
+}
+static const char * Get_SDRAM_ChipGeom(void)
+{
+	switch (Get_PLD_SDRAM() & 0x0F) {
+		case 0: return "4Mx8x4";
+		case 1: return "8Mx8x4";
+		case 2: return "2Mx8x4";
+		case 3: return "4Mx8x2";
+		default: return "unknown";
+	}
+}
+
+static void Show_VCMA9_Info(char *board_name, char *serial)
+{
+	printf("Board: %s SN: %s  PCB Rev: %c PLD(%d,%d)\n",
+		board_name, serial, Get_Board_PCB(), Get_PLD_Version(), Get_PLD_Revision());
+	printf("SDRAM: %d chips %s\n", Get_SDRAM_ChipNr(), Get_SDRAM_ChipGeom());
+}
+
+int dram_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = Get_SDRAM_ChipSize() * Get_SDRAM_ChipNr();
+
+	return 0;
+}
+
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */
 
 
 /*
 /*
@@ -240,8 +293,6 @@ int checkboard(void)
 	int i;
 	int i;
 	backup_t *b = (backup_t *) s;
 	backup_t *b = (backup_t *) s;
 
 
-	puts("Board: ");
-
 	i = getenv_r("serial#", s, 32);
 	i = getenv_r("serial#", s, 32);
 	if ((i < 0) || strncmp (s, "VCMA9", 5)) {
 	if ((i < 0) || strncmp (s, "VCMA9", 5)) {
 		get_backup_values (b);
 		get_backup_values (b);
@@ -249,32 +300,23 @@ int checkboard(void)
 			puts ("### No HW ID - assuming VCMA9");
 			puts ("### No HW ID - assuming VCMA9");
 		} else {
 		} else {
 			b->serial_name[5] = 0;
 			b->serial_name[5] = 0;
-			printf ("%s-%d PCB Rev %c SN: %s", b->serial_name, Get_Board_Config(),
-					Get_Board_PCB(), &b->serial_name[6]);
+			Show_VCMA9_Info(b->serial_name, &b->serial_name[6]);
 		}
 		}
 	} else {
 	} else {
 		s[5] = 0;
 		s[5] = 0;
-		printf ("%s-%d PCB Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(),
-				&s[6]);
+		Show_VCMA9_Info(s, &s[6]);
 	}
 	}
-	printf("\n");
+	/*printf("\n");*/
 	return(0);
 	return(0);
 }
 }
 
 
 
 
-void print_vcma9_rev(void)
-{
-	printf("Board: VCMA9-%d PCB Rev: %c (PLD Ver: %d, Rev: %d)\n",
-		Get_Board_Config(), Get_Board_PCB(),
-		Get_PLD_Version(), Get_PLD_Revision());
-}
-
 extern void mem_test_reloc(void);
 extern void mem_test_reloc(void);
 
 
 int last_stage_init(void)
 int last_stage_init(void)
 {
 {
 	mem_test_reloc();
 	mem_test_reloc();
-	print_vcma9_rev();
+	checkboard();
 	show_stdio_dev();
 	show_stdio_dev();
 	check_env();
 	check_env();
 	return 0;
 	return 0;
@@ -295,6 +337,15 @@ int overwrite_console(void)
 * Print VCMA9 Info
 * Print VCMA9 Info
 ************************************************************************/
 ************************************************************************/
 void print_vcma9_info(void)
 void print_vcma9_info(void)
-{
-    print_vcma9_rev();
+{	
+	unsigned char s[50];
+	int i;
+	
+	if ((i = getenv_r("serial#", s, 32)) < 0) {
+		puts ("### No HW ID - assuming VCMA9");
+		printf("i %d", i*24);
+	} else {
+		s[5] = 0;
+		Show_VCMA9_Info(s, &s[6]);
+	}
 }
 }

+ 17 - 9
board/mpl/vcma9/vcma9.h

@@ -1,5 +1,5 @@
 /*
 /*
- * (C) Copyright 2002
+ * (C) Copyright 2002, 2003
  * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
  * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
  *
  *
  * See file CREDITS for list of people who contributed to this
  * See file CREDITS for list of people who contributed to this
@@ -116,11 +116,19 @@ static inline u32 NF_Read_ECC(void)
 
 
 #endif
 #endif
 
 
-
-#define PLD_BASE_ADDRESS		0x2C000100
-#define PLD_ID_REG			(PLD_BASE_ADDRESS + 0)
-#define PLD_NIC_REG			(PLD_BASE_ADDRESS + 1)
-#define PLD_CAN_REG			(PLD_BASE_ADDRESS + 2)
-#define PLD_MISC_REG			(PLD_BASE_ADDRESS + 3)
-#define PLD_GPCD_REG			(PLD_BASE_ADDRESS + 4)
-#define PLD_BOARD_REG			(PLD_BASE_ADDRESS + 5)
+/* VCMA9 PLD regsiters */
+typedef struct {
+	S3C24X0_REG8	ID;
+	S3C24X0_REG8	NIC;
+	S3C24X0_REG8	CAN;
+	S3C24X0_REG8	MISC;
+	S3C24X0_REG8	GPCD;
+	S3C24X0_REG8	BOARD;
+	S3C24X0_REG8	SDRAM;
+} /*__attribute__((__packed__))*/ VCMA9_PLD;
+
+#define VCMA9_PLD_BASE	0x2C000100
+static inline VCMA9_PLD * const VCMA9_GetBase_PLD(void)
+{
+	return (VCMA9_PLD * const)VCMA9_PLD_BASE;
+}

+ 1 - 1
cpu/mpc5xxx/Makefile

@@ -27,7 +27,7 @@ LIB	= lib$(CPU).a
 
 
 START	= start.o
 START	= start.o
 ASOBJS	= io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
 ASOBJS	= io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
-OBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o \
+OBJS	= i2c.o traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o \
 	  loadtask.o fec.o pci_mpc5200.o
 	  loadtask.o fec.o pci_mpc5200.o
 
 
 all:	.depend $(START) $(ASOBJS) $(LIB)
 all:	.depend $(START) $(ASOBJS) $(LIB)

+ 338 - 0
cpu/mpc5xxx/i2c.c

@@ -0,0 +1,338 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_HARD_I2C
+
+#include <mpc5xxx.h>
+#include <i2c.h>
+
+#ifdef CFG_I2C_MODULE
+#define I2C_BASE	MPC5XXX_I2C2
+#else
+#define I2C_BASE	MPC5XXX_I2C1
+#endif
+
+#define I2C_TIMEOUT	100
+#define I2C_RETRIES	3
+
+static int  mpc_reg_in    (volatile u32 *reg);
+static void mpc_reg_out   (volatile u32 *reg, int val, int mask);
+static int  wait_for_bb   (void);
+static int  wait_for_pin  (int *status);
+static int  do_address    (uchar chip, char rdwr_flag);
+static int  send_bytes    (uchar chip, char *buf, int len);
+static int  receive_bytes (uchar chip, char *buf, int len);
+
+static int mpc_reg_in(volatile u32 *reg)
+{
+	return *reg >> 24;
+	__asm__ __volatile__ ("eieio");
+}
+
+static void mpc_reg_out(volatile u32 *reg, int val, int mask)
+{
+	int tmp;
+
+	if (!mask) {
+		*reg = val << 24;
+	} else {
+		tmp = mpc_reg_in(reg);
+		*reg = ((tmp & ~mask) | (val & mask)) << 24;
+	}
+	__asm__ __volatile__ ("eieio");
+
+	return;
+}
+
+static int wait_for_bb(void)
+{
+	struct mpc5xxx_i2c *regs    = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                 timeout = I2C_TIMEOUT;
+	int                 status;
+
+	status = mpc_reg_in(&regs->msr);
+
+	while (timeout-- && (status & I2C_BB)) {
+#if 1
+		volatile int temp;
+		mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
+		temp = mpc_reg_in(&regs->mdr);
+		mpc_reg_out(&regs->mcr, 0, I2C_STA);
+		mpc_reg_out(&regs->mcr, 0, 0);
+		mpc_reg_out(&regs->mcr, I2C_EN, 0);
+#endif
+		udelay(1000);
+		status = mpc_reg_in(&regs->msr);
+	}
+
+	return (status & I2C_BB);
+}
+
+static int wait_for_pin(int *status)
+{
+	struct mpc5xxx_i2c *regs    = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                 timeout = I2C_TIMEOUT;
+
+	*status = mpc_reg_in(&regs->msr);
+
+	while (timeout-- && !(*status & I2C_IF)) {
+		udelay(1000);
+		*status = mpc_reg_in(&regs->msr);
+	}
+
+	if (!(*status & I2C_IF)) {
+		return -1;
+	}
+
+	mpc_reg_out(&regs->msr, 0, I2C_IF);
+
+	return 0;
+}
+
+static int do_address(uchar chip, char rdwr_flag)
+{
+	struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                 status;
+
+	chip <<= 1;
+
+	if (rdwr_flag) {
+		chip |= 1;
+	}
+
+	mpc_reg_out(&regs->mcr, I2C_TX, I2C_TX);
+	mpc_reg_out(&regs->mdr, chip, 0);
+
+        if (wait_for_pin(&status)) {
+                return -2;
+        }
+
+        if (status & I2C_RXAK) {
+                return -3;
+        }
+
+	return 0;
+}
+
+static int send_bytes(uchar chip, char *buf, int len)
+{
+	struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                 wrcount;
+	int                 status;
+
+	for (wrcount = 0; wrcount < len; ++wrcount) {
+
+		mpc_reg_out(&regs->mdr, buf[wrcount], 0);
+
+		if (wait_for_pin(&status)) {
+			break;
+		}
+
+		if (status & I2C_RXAK) {
+			break;
+		}
+
+	}
+
+	return !(wrcount == len);
+}
+
+static int receive_bytes(uchar chip, char *buf, int len)
+{
+	struct mpc5xxx_i2c *regs    = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                 dummy   = 1;
+	int                 rdcount = 0;
+	int                 status;
+	int                 i;
+
+	mpc_reg_out(&regs->mcr, 0, I2C_TX);
+
+	for (i = 0; i < len; ++i) {
+		buf[rdcount] = mpc_reg_in(&regs->mdr);
+
+		if (dummy) {
+			dummy = 0;
+		} else {
+			rdcount++;
+		}
+
+
+		if (wait_for_pin(&status)) {
+			return -4;
+		}
+	}
+
+	mpc_reg_out(&regs->mcr, I2C_TXAK, I2C_TXAK);
+	buf[rdcount++] = mpc_reg_in(&regs->mdr);
+
+	if (wait_for_pin(&status)) {
+		return -5;
+	}
+
+	mpc_reg_out(&regs->mcr, 0, I2C_TXAK);
+
+	return 0;
+}
+
+/**************** I2C API ****************/
+
+void i2c_init(int speed, int saddr)
+{
+	struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
+
+	mpc_reg_out(&regs->mcr, 0, 0);
+	mpc_reg_out(&regs->madr, saddr << 1, 0);
+
+	/* Set clock
+	 */
+	mpc_reg_out(&regs->mfdr, speed, 0);
+
+	/* Enable module
+	 */
+	mpc_reg_out(&regs->mcr, I2C_EN, I2C_INIT_MASK);
+	mpc_reg_out(&regs->msr, 0, I2C_IF);
+
+	return;
+}
+
+int i2c_probe(uchar chip)
+{
+	struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                 i;
+
+	for (i = 0; i < I2C_RETRIES; i++) {
+		mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
+
+		if (! do_address(chip, 0)) {
+			mpc_reg_out(&regs->mcr, 0, I2C_STA);
+			break;
+		}
+
+		mpc_reg_out(&regs->mcr, 0, I2C_STA);
+		udelay(500);
+	}
+
+	return (i == I2C_RETRIES);
+}
+
+int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	uchar                xaddr[4];
+	struct mpc5xxx_i2c * regs        = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                  ret         = -1;
+
+	xaddr[0] = (addr >> 24) & 0xFF;
+	xaddr[1] = (addr >> 16) & 0xFF;
+	xaddr[2] = (addr >>  8) & 0xFF;
+	xaddr[3] =  addr	& 0xFF;
+
+	if (wait_for_bb()) {
+		printf("i2c_read: bus is busy\n");
+		goto Done;
+	}
+
+	mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
+	if (do_address(chip, 0)) {
+		printf("i2c_read: failed to address chip\n");
+		goto Done;
+	}
+
+	if (send_bytes(chip, &xaddr[4-alen], alen)) {
+		printf("i2c_read: send_bytes failed\n");
+		goto Done;
+	}
+
+	mpc_reg_out(&regs->mcr, I2C_RSTA, I2C_RSTA);
+	if (do_address(chip, 1)) {
+		printf("i2c_read: failed to address chip\n");
+		goto Done;
+	}
+
+	if (receive_bytes(chip, buf, len)) {
+		printf("i2c_read: receive_bytes failed\n");
+		goto Done;
+	}
+
+	ret = 0;
+Done:
+	mpc_reg_out(&regs->mcr, 0, I2C_STA);
+	return ret;
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	uchar               xaddr[4];
+	struct mpc5xxx_i2c *regs        = (struct mpc5xxx_i2c *)I2C_BASE;
+	int                 ret         = -1;
+
+	xaddr[0] = (addr >> 24) & 0xFF;
+	xaddr[1] = (addr >> 16) & 0xFF;
+	xaddr[2] = (addr >>  8) & 0xFF;
+	xaddr[3] =  addr	& 0xFF;
+
+        if (wait_for_bb()) {
+		printf("i2c_write: bus is busy\n");
+		goto Done;
+	}
+
+        mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
+        if (do_address(chip, 0)) {
+		printf("i2c_write: failed to address chip\n");
+		goto Done;
+	}
+
+	if (send_bytes(chip, &xaddr[4-alen], alen)) {
+		printf("i2c_write: send_bytes failed\n");
+		goto Done;
+	}
+
+	if (send_bytes(chip, buf, len)) {
+		printf("i2c_write: send_bytes failed\n");
+		goto Done;
+	}
+
+	ret = 0;
+Done:
+	mpc_reg_out(&regs->mcr, 0, I2C_STA);
+	return ret;
+}
+
+uchar i2c_reg_read(uchar chip, uchar reg)
+{
+	char buf;
+
+	i2c_read(chip, reg, 1, &buf, 1);
+
+	return buf;
+}
+
+void i2c_reg_write(uchar chip, uchar reg, uchar val)
+{
+	i2c_write(chip, reg, 1, &val, 1);
+
+	return;
+}
+
+#endif	/* CONFIG_HARD_I2C */

+ 19 - 1
include/configs/IceCube.h

@@ -83,7 +83,8 @@
 /*
 /*
  * Supported commands
  * Supported commands
  */
  */
-#define CONFIG_COMMANDS		(CONFIG_CMD_DFL | ADD_PCI_CMD)
+#define CONFIG_COMMANDS		(CONFIG_CMD_DFL | ADD_PCI_CMD | \
+				 CFG_CMD_I2C | CFG_CMD_EEPROM)
 
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
 #include <cmd_confdefs.h>
@@ -98,6 +99,23 @@
 /*
 /*
  * I2C configuration
  * I2C configuration
  */
  */
+#define CONFIG_HARD_I2C		1	/* I2C with hardware support */
+#define CFG_I2C_MODULE		1	/* If defined then I2C module #2 is used
+					 * otherwise I2C module #1 is used */
+#ifdef CONFIG_MPC5200
+#define CFG_I2C_SPEED		0x3D	/* 86KHz given 133MHz IPBI */
+#else
+#define CFG_I2C_SPEED		0x35	/* 86KHz given 33MHz IPBI */
+#endif
+#define CFG_I2C_SLAVE		0x7F
+
+/*
+ * EEPROM configuration
+ */
+#define CFG_I2C_EEPROM_ADDR		0x50	/* 1010000x */
+#define CFG_I2C_EEPROM_ADDR_LEN		1
+#define CFG_EEPROM_PAGE_WRITE_BITS	3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	35
 
 
 /*
 /*
  * Flash configuration
  * Flash configuration

+ 4 - 5
include/configs/VCMA9.h

@@ -1,5 +1,5 @@
 /*
 /*
- * (C) Copyright 2002
+ * (C) Copyright 2002, 2003
  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  * Marius Groeger <mgroeger@sysgo.de>
  * Marius Groeger <mgroeger@sysgo.de>
  * Gary Jennejohn <gj@denx.de>
  * Gary Jennejohn <gj@denx.de>
@@ -160,9 +160,10 @@
 #define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size	*/
 #define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size	*/
 
 
 #define CFG_MEMTEST_START	0x30000000	/* memtest works on	*/
 #define CFG_MEMTEST_START	0x30000000	/* memtest works on	*/
-#define CFG_MEMTEST_END		0x33F80000	/* 63.5 MB in DRAM	*/
+#define CFG_MEMTEST_END		0x30F80000	/* 15.5 MB in DRAM	*/
+
 #define CFG_ALT_MEMTEST
 #define CFG_ALT_MEMTEST
-#define	CFG_LOAD_ADDR		0x33000000	/* default load address	*/
+#define	CFG_LOAD_ADDR		0x30800000	/* default load address	*/
 
 
 
 
 #undef  CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */
 #undef  CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */
@@ -197,8 +198,6 @@
  */
  */
 #define CONFIG_NR_DRAM_BANKS	1	   /* we have 1 bank of DRAM */
 #define CONFIG_NR_DRAM_BANKS	1	   /* we have 1 bank of DRAM */
 #define PHYS_SDRAM_1		0x30000000 /* SDRAM Bank #1 */
 #define PHYS_SDRAM_1		0x30000000 /* SDRAM Bank #1 */
-#define PHYS_SDRAM_1_SIZE	0x04000000 /* 64 MB */
-
 #define PHYS_FLASH_1		0x00000000 /* Flash Bank #1 */
 #define PHYS_FLASH_1		0x00000000 /* Flash Bank #1 */
 
 
 #define CFG_FLASH_BASE		PHYS_FLASH_1
 #define CFG_FLASH_BASE		PHYS_FLASH_1

+ 29 - 0
include/mpc5xxx.h

@@ -108,6 +108,9 @@
 
 
 #define	MPC5XXX_FEC		(CFG_MBAR + 0x3000)
 #define	MPC5XXX_FEC		(CFG_MBAR + 0x3000)
 
 
+#define MPC5XXX_I2C1		(CFG_MBAR + 0x3D00)
+#define MPC5XXX_I2C2		(CFG_MBAR + 0x3D40)
+
 #if defined(CONFIG_MGT5100)
 #if defined(CONFIG_MGT5100)
 #define MPC5XXX_SRAM		(CFG_MBAR + 0x4000)
 #define MPC5XXX_SRAM		(CFG_MBAR + 0x4000)
 #define MPC5XXX_SRAM_SIZE	(8*1024)
 #define MPC5XXX_SRAM_SIZE	(8*1024)
@@ -197,6 +200,24 @@
 #define MPC5XXX_GPT0_ENABLE		(MPC5XXX_GPT + 0x0)
 #define MPC5XXX_GPT0_ENABLE		(MPC5XXX_GPT + 0x0)
 #define MPC5XXX_GPT0_COUNTER		(MPC5XXX_GPT + 0x4)
 #define MPC5XXX_GPT0_COUNTER		(MPC5XXX_GPT + 0x4)
 
 
+/* I2Cn control register bits */
+#define I2C_EN		0x80
+#define I2C_IEN		0x40
+#define I2C_STA		0x20
+#define I2C_TX		0x10
+#define I2C_TXAK	0x08
+#define I2C_RSTA	0x04
+#define I2C_INIT_MASK	(I2C_EN | I2C_STA | I2C_TX | I2C_RSTA)
+
+/* I2Cn status register bits */
+#define I2C_CF		0x80
+#define I2C_AAS		0x40
+#define I2C_BB		0x20
+#define I2C_AL		0x10
+#define I2C_SRW		0x04
+#define I2C_IF		0x02
+#define I2C_RXAK	0x01
+
 /* Programmable Serial Controller (PSC) status register bits */
 /* Programmable Serial Controller (PSC) status register bits */
 #define PSC_SR_CDE		0x0080
 #define PSC_SR_CDE		0x0080
 #define PSC_SR_RXRDY		0x0100
 #define PSC_SR_RXRDY		0x0100
@@ -505,6 +526,14 @@ struct mpc5xxx_sdma {
 	volatile u32 EU37;		/* SDMA + 0xfc */
 	volatile u32 EU37;		/* SDMA + 0xfc */
 };
 };
 
 
+struct mpc5xxx_i2c {
+	volatile u32 madr;		/* I2Cn + 0x00 */
+	volatile u32 mfdr;		/* I2Cn + 0x04 */
+	volatile u32 mcr;		/* I2Cn + 0x08 */
+	volatile u32 msr;		/* I2Cn + 0x0C */
+	volatile u32 mdr;		/* I2Cn + 0x10 */
+};
+
 /* function prototypes */
 /* function prototypes */
 void loadtask(int basetask, int tasks);
 void loadtask(int basetask, int tasks);
 
 

+ 10 - 8
rtc/s3c24x0_rtc.c

@@ -80,13 +80,15 @@ void rtc_get (struct rtc_time *tmp)
 	SetRTC_Access(RTC_ENABLE);
 	SetRTC_Access(RTC_ENABLE);
 
 
 	/* read RTC registers */
 	/* read RTC registers */
-	sec	= rtc->BCDSEC;
-	min	= rtc->BCDMIN;
-	hour	= rtc->BCDHOUR;
-	mday	= rtc->BCDDATE;
-	wday	= rtc->BCDDAY;
-	mon	= rtc->BCDMON;
-	year	= rtc->BCDYEAR;
+	do {
+		sec	= rtc->BCDSEC;
+		min	= rtc->BCDMIN;
+		hour	= rtc->BCDHOUR;
+		mday	= rtc->BCDDATE;
+		wday	= rtc->BCDDAY;
+		mon	= rtc->BCDMON;
+		year	= rtc->BCDYEAR;
+	} while (sec != rtc->BCDSEC);
 
 
 	/* read ALARM registers */
 	/* read ALARM registers */
 	a_sec	= rtc->ALMSEC;
 	a_sec	= rtc->ALMSEC;
@@ -170,7 +172,7 @@ void rtc_reset (void)
 	S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
 	S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
 
 
 	rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08;
 	rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08;
-	rtc->RTCCON &= ~0x08;
+	rtc->RTCCON &= ~(0x08|0x01);
 }
 }
 
 
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */