فهرست منبع

Patch by Yuli Barcohen, 09 Jun 2004:
Add support for 8MB flash SIMM and JFFS2 file system on
Motorola FADS board and its derivatives (MPC86xADS, MPC885ADS).

wdenk 21 سال پیش
والد
کامیت
99edcfb29e
4فایلهای تغییر یافته به همراه106 افزوده شده و 175 حذف شده
  1. 4 0
      CHANGELOG
  2. 23 11
      board/fads/fads.h
  3. 78 163
      board/fads/flash.c
  4. 1 1
      board/fads/u-boot.lds

+ 4 - 0
CHANGELOG

@@ -2,6 +2,10 @@
 Changes since U-Boot 1.1.1:
 ======================================================================
 
+* Patch by Yuli Barcohen, 09 Jun 2004:
+  Add support for 8MB flash SIMM and JFFS2 file system on
+  Motorola FADS board and its derivatives (MPC86xADS, MPC885ADS).
+
 * Patch by Yuli Barcohen, 09 Jun 2004:
   Add support for Analogue&Micro Adder87x and the older AdderII board.
 

+ 23 - 11
board/fads/fads.h

@@ -91,6 +91,7 @@
 #define CONFIG_COMMANDS	(CONFIG_CMD_DFL   \
 			 | CFG_CMD_DHCP   \
 			 | CFG_CMD_IMMAP  \
+			 | CFG_CMD_JFFS2  \
 			 | CFG_CMD_MII    \
 			 | CFG_CMD_PCMCIA \
 			 | CFG_CMD_PING   \
@@ -166,14 +167,24 @@
  * the maximum mapped by the Linux kernel during initialization.
  */
 #define	CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux	*/
+
+#define CFG_MONITOR_BASE	TEXT_BASE
+#define	CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 KB for monitor	*/
+
+#ifdef CONFIG_BZIP2
+#define	CFG_MALLOC_LEN		(2500 << 10)	/* Reserve ~2.5 MB for malloc()	*/
+#else
+#define	CFG_MALLOC_LEN		(384 << 10)	/* Reserve 384 kB for malloc()	*/
+#endif /* CONFIG_BZIP2 */
+
 /*-----------------------------------------------------------------------
  * Flash organization
  */
-#define CFG_FLASH_BASE		TEXT_BASE
-#define CFG_FLASH_SIZE		((uint)(8 * 1024 * 1024))	/* max 8Mbyte */
+#define CFG_FLASH_BASE		CFG_MONITOR_BASE
+#define CFG_FLASH_SIZE		((uint)(8 * 1024 * 1024))	/* max 8Mbyte	*/
 
-#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks		*/
-#define CFG_MAX_FLASH_SECT	16      /* max number of sectors on one chip	*/
+#define CFG_MAX_FLASH_BANKS	4	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	8	/* max number of sectors on one chip	*/
 
 #define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
 #define CFG_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms)	*/
@@ -183,14 +194,14 @@
 #define CFG_ENV_OFFSET		CFG_ENV_SECT_SIZE
 #define	CFG_ENV_SIZE		0x4000	/* Total Size of Environment		*/
 
-#define CFG_MONITOR_BASE	CFG_FLASH_BASE
-#define	CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 KB for monitor	*/
+#define	CFG_DIRECT_FLASH_TFTP
 
-#ifdef CONFIG_BZIP2
-#define	CFG_MALLOC_LEN		(2500 << 10)	/* Reserve ~2.5 MB for malloc()	*/
-#else
-#define	CFG_MALLOC_LEN		(384 << 10)	/* Reserve 384 kB for malloc()	*/
-#endif /* CONFIG_BZIP2 */
+#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
+#define CFG_JFFS2_FIRST_BANK	0
+#define CFG_JFFS2_NUM_BANKS	CFG_MAX_FLASH_BANKS
+#define CFG_JFFS2_FIRST_SECTOR  4
+#define CFG_JFFS2_SORT_FRAGMENTS
+#endif /* CFG_CMD_JFFS2 */
 
 /*-----------------------------------------------------------------------
  * Cache Configuration
@@ -352,6 +363,7 @@
 #define BCSR1_PCCVCCON		 BCSR1_PCCVCC0
 
 #define BCSR2_FLASH_PD_MASK      ((uint)0xF0000000)
+#define BCSR2_FLASH_PD_SHIFT     28
 #define BCSR2_DRAM_PD_MASK       ((uint)0x07800000)
 #define BCSR2_DRAM_PD_SHIFT      23
 #define BCSR2_EXTTOLI_MASK       ((uint)0x00780000)

+ 78 - 163
board/fads/flash.c

@@ -24,7 +24,7 @@
 #include <common.h>
 #include <mpc8xx.h>
 
-flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips        */
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips */
 
 #if defined(CFG_ENV_IS_IN_FLASH)
 # ifndef  CFG_ENV_ADDR
@@ -38,124 +38,103 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips        */
 # endif
 #endif
 
+#define QUAD_ID(id)	((((ulong)(id) & 0xFF) << 24) | \
+			 (((ulong)(id) & 0xFF) << 16) | \
+			 (((ulong)(id) & 0xFF) << 8)  | \
+			 (((ulong)(id) & 0xFF) << 0)    \
+			)
+
 /*-----------------------------------------------------------------------
  * Functions
  */
 static ulong flash_get_size (vu_long * addr, flash_info_t * info);
 static int write_word (flash_info_t * info, ulong dest, ulong data);
-static void flash_get_offsets (ulong base, flash_info_t * info);
 
 /*-----------------------------------------------------------------------
  */
-
 unsigned long flash_init (void)
 {
 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
 	volatile memctl8xx_t *memctl = &immap->im_memctl;
-	unsigned long total_size;
-	unsigned long size_b0, size_b1;
+	vu_long *bcsr = (vu_long *)BCSR_ADDR;
+	unsigned long pd_size, total_size, bsize, or_am;
 	int i;
 
 	/* Init: no FLASHes known */
 	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
 		flash_info[i].flash_id = FLASH_UNKNOWN;
+		flash_info[i].size = 0;
+		flash_info[i].sector_count = 0;
+		flash_info[i].start[0] = 0xFFFFFFFF; /* For TFTP */
 	}
 
-	total_size = 0;
-	size_b0 = 0xffffffff;
+	switch ((bcsr[2] & BCSR2_FLASH_PD_MASK) >> BCSR2_FLASH_PD_SHIFT) {
+	case 2:
+	case 4:
+	case 6:
+		pd_size = 0x800000;
+		or_am = 0xFF800000;
+		break;
 
-	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
-		size_b1 =
-			flash_get_size ((vu_long *) (CFG_FLASH_BASE +
-						     total_size),
-					&flash_info[i]);
+	case 5:
+	case 7:
+		pd_size = 0x400000;
+		or_am = 0xFFC00000;
+		break;
 
-		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
-			printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", i, size_b1, size_b1 >> 20);
-		}
+	case 8:
+		pd_size = 0x200000;
+		or_am = 0xFFE00000;
+		break;
 
-		/* Is this really needed ? - LP */
-		if (size_b1 > size_b0) {
-			printf ("## ERROR: Bank %d (0x%08lx = %ld MB) > Bank %d (0x%08lx = %ld MB)\n", i, size_b1, size_b1 >> 20, i - 1, size_b0, size_b0 >> 20);
-			goto out_error;
-		}
-		size_b0 = size_b1;
-		total_size += size_b1;
+	default:
+		pd_size = 0;
+		or_am = 0xFFE00000;
+		printf("## Unsupported flash detected by BCSR: 0x%08X\n", bcsr[2]);
 	}
 
-	/* Compute the Address Mask */
-	for (i = 0; (total_size >> i) != 0; ++i) {
+	total_size = 0;
+	for (i = 0; i < CFG_MAX_FLASH_BANKS && total_size < pd_size; ++i) {
+		bsize = flash_get_size((vu_long *)(CFG_FLASH_BASE + total_size),
+				       &flash_info[i]);
+
+		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+			printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+				i, bsize, bsize >> 20);
+		}
+
+		total_size += bsize;
 	}
-	i--;
 
-	if (total_size != (1 << i)) {
-		printf ("## WARNING: Total FLASH size (0x%08lx = %ld MB) is not a power of 2\n", total_size, total_size >> 20);
+	if (total_size != pd_size) {
+		printf("## Detected flash size %lu conflicts with PD data %lu\n",
+		       total_size, pd_size);
 	}
 
 	/* Remap FLASH according to real size */
-	memctl->memc_or0 =
-		((((unsigned long) ~0) << i) & OR_AM_MSK) |
-		CFG_OR_TIMING_FLASH;
-	memctl->memc_br0 = CFG_BR0_PRELIM;
-
-	total_size = 0;
+	memctl->memc_or0 = or_am | CFG_OR_TIMING_FLASH;
 
 	for (i = 0; i < CFG_MAX_FLASH_BANKS && flash_info[i].size != 0; ++i) {
-		/* Re-do sizing to get full correct info */
-		/* Why ? - LP */
-		size_b1 =
-			flash_get_size ((vu_long *) (CFG_FLASH_BASE +
-						     total_size),
-					&flash_info[i]);
-
-		/* This is done by flash_get_size - LP */
-		/* flash_get_offsets (CFG_FLASH_BASE + total_size, &flash_info[i]); */
-
 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
 		/* monitor protection ON by default */
-		flash_protect (FLAG_PROTECT_SET,
-			       CFG_MONITOR_BASE,
-			       CFG_MONITOR_BASE + monitor_flash_len - 1,
-			       &flash_info[i]);
+		if (CFG_MONITOR_BASE >= flash_info[i].start[0])
+			flash_protect (FLAG_PROTECT_SET,
+				       CFG_MONITOR_BASE,
+				       CFG_MONITOR_BASE + monitor_flash_len - 1,
+				       &flash_info[i]);
 #endif
 
 #ifdef	CFG_ENV_IS_IN_FLASH
 		/* ENV protection ON by default */
-		flash_protect (FLAG_PROTECT_SET,
-			       CFG_ENV_ADDR,
-			       CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
-			       &flash_info[i]);
+		if (CFG_ENV_ADDR >= flash_info[i].start[0])
+			flash_protect (FLAG_PROTECT_SET,
+				       CFG_ENV_ADDR,
+				       CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+				       &flash_info[i]);
 #endif
-
-		total_size += size_b1;
 	}
 
-	return (total_size);
-
-      out_error:
-	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
-		flash_info[i].flash_id = FLASH_UNKNOWN;
-		flash_info[i].sector_count = -1;
-		flash_info[i].size = 0;
-	}
-
-	return (0);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void flash_get_offsets (ulong base, flash_info_t * info)
-{
-	int i;
-
-	/* set up sector start address table */
-	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040
-	    || (info->flash_id & FLASH_TYPEMASK) == FLASH_AM080) {
-		/* set sector offsets for uniform sector type   */
-		for (i = 0; i < info->sector_count; i++) {
-			info->start[i] = base + (i * 0x00040000);
-		}
-	}
+	return total_size;
 }
 
 /*-----------------------------------------------------------------------
@@ -235,48 +214,26 @@ void flash_print_info (flash_info_t * info)
 	}
 
 	printf ("\n");
-	return;
 }
 
 /*-----------------------------------------------------------------------
+ * The following code can not run from flash!
  */
-
-
-/*-----------------------------------------------------------------------
- */
-
-/*
- * The following code cannot be run from FLASH!
- */
-
 static ulong flash_get_size (vu_long * addr, flash_info_t * info)
 {
 	short i;
 
-#if 0
-	ulong base = (ulong) addr;
-#endif
-	uchar value;
-
 	/* Write auto select command: read Manufacturer ID */
-#if 0
-	addr[0x0555] = 0x00AA00AA;
-	addr[0x02AA] = 0x00550055;
-	addr[0x0555] = 0x00900090;
-#else
 	addr[0x0555] = 0xAAAAAAAA;
 	addr[0x02AA] = 0x55555555;
 	addr[0x0555] = 0x90909090;
-#endif
-
-	value = addr[0];
 
-	switch (value + (value << 16)) {
-	case AMD_MANUFACT:
+	switch (addr[0]) {
+	case QUAD_ID(AMD_MANUFACT):
 		info->flash_id = FLASH_MAN_AMD;
 		break;
 
-	case FUJ_MANUFACT:
+	case QUAD_ID(FUJ_MANUFACT):
 		info->flash_id = FLASH_MAN_FUJ;
 		break;
 
@@ -287,21 +244,20 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
 		break;
 	}
 
-	value = addr[1];	/* device ID            */
-
-	switch (value) {
-	case AMD_ID_F040B:
+	switch (addr[1]) {	/* device ID            */
+	case QUAD_ID(AMD_ID_F040B):
+	case QUAD_ID(AMD_ID_LV040B):
 		info->flash_id += FLASH_AM040;
 		info->sector_count = 8;
 		info->size = 0x00200000;
 		break;		/* => 2 MB              */
 
-	case AMD_ID_F080B:
+	case QUAD_ID(AMD_ID_F080B):
 		info->flash_id += FLASH_AM080;
 		info->sector_count = 16;
 		info->size = 0x00400000;
 		break;		/* => 4 MB              */
-
+#if 0
 	case AMD_ID_LV400T:
 		info->flash_id += FLASH_AM400T;
 		info->sector_count = 11;
@@ -337,7 +293,7 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
 		info->sector_count = 35;
 		info->size = 0x00400000;
 		break;		/* => 4 MB              */
-#if 0				/* enable when device IDs are available */
+
 	case AMD_ID_LV320T:
 		info->flash_id += FLASH_AM320T;
 		info->sector_count = 67;
@@ -349,11 +305,10 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
 		info->sector_count = 67;
 		info->size = 0x00800000;
 		break;		/* => 8 MB              */
-#endif
+#endif /* 0 */
 	default:
 		info->flash_id = FLASH_UNKNOWN;
 		return (0);	/* => no or unknown flash */
-
 	}
 
 #if 0
@@ -378,7 +333,9 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
 		}
 	}
 #else
-	flash_get_offsets ((ulong) addr, info);
+	/* set sector offsets for uniform sector type */
+	for (i = 0; i < info->sector_count; i++)
+		info->start[i] = (ulong)addr + (i * 0x00040000);
 #endif
 
 	/* check for protected sectors */
@@ -389,25 +346,16 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
 		info->protect[i] = addr[2] & 1;
 	}
 
-	/*
-	 * Prevent writes to uninitialized FLASH.
-	 */
 	if (info->flash_id != FLASH_UNKNOWN) {
 		addr = (volatile unsigned long *) info->start[0];
-#if 0
-		*addr = 0x00F000F0;	/* reset bank */
-#else
 		*addr = 0xF0F0F0F0;	/* reset bank */
-#endif
 	}
 
 	return (info->size);
 }
 
-
 /*-----------------------------------------------------------------------
  */
-
 int flash_erase (flash_info_t * info, int s_first, int s_last)
 {
 	vu_long *addr = (vu_long *) (info->start[0]);
@@ -420,13 +368,13 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
 		} else {
 			printf ("- no sectors to erase\n");
 		}
-		return 1;
+		return ERR_INVAL;
 	}
 
 	if ((info->flash_id == FLASH_UNKNOWN) ||
 	    (info->flash_id > FLASH_AMD_COMP)) {
 		printf ("Can't erase unknown flash type - aborted\n");
-		return 1;
+		return ERR_UNKNOWN_FLASH_TYPE;
 	}
 
 	prot = 0;
@@ -447,29 +395,17 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
 	/* Disable interrupts which might cause a timeout here */
 	flag = disable_interrupts ();
 
-#if 0
-	addr[0x0555] = 0x00AA00AA;
-	addr[0x02AA] = 0x00550055;
-	addr[0x0555] = 0x00800080;
-	addr[0x0555] = 0x00AA00AA;
-	addr[0x02AA] = 0x00550055;
-#else
 	addr[0x0555] = 0xAAAAAAAA;
 	addr[0x02AA] = 0x55555555;
 	addr[0x0555] = 0x80808080;
 	addr[0x0555] = 0xAAAAAAAA;
 	addr[0x02AA] = 0x55555555;
-#endif
 
 	/* Start erase on unprotected sectors */
 	for (sect = s_first; sect <= s_last; sect++) {
 		if (info->protect[sect] == 0) {	/* not protected */
 			addr = (vu_long *) (info->start[sect]);
-#if 0
-			addr[0] = 0x00300030;
-#else
 			addr[0] = 0x30303030;
-#endif
 			l_sect = sect;
 		}
 	}
@@ -490,15 +426,11 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
 	start = get_timer (0);
 	last = start;
 	addr = (vu_long *) (info->start[l_sect]);
-#if 0
-	while ((addr[0] & 0x00800080) != 0x00800080)
-#else
 	while ((addr[0] & 0xFFFFFFFF) != 0xFFFFFFFF)
-#endif
 	{
 		if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
 			printf ("Timeout\n");
-			return 1;
+			return ERR_TIMOUT;
 		}
 		/* show that we're waiting */
 		if ((now - last) > 1000) {	/* every second */
@@ -510,13 +442,10 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
       DONE:
 	/* reset to read mode */
 	addr = (volatile unsigned long *) info->start[0];
-#if 0
-	addr[0] = 0x00F000F0;	/* reset bank */
-#else
 	addr[0] = 0xF0F0F0F0;	/* reset bank */
-#endif
 
 	printf (" done\n");
+
 	return 0;
 }
 
@@ -526,7 +455,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
  * 1 - write timeout
  * 2 - Flash not erased
  */
-
 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 {
 	ulong cp, wp, data;
@@ -605,20 +533,14 @@ static int write_word (flash_info_t * info, ulong dest, ulong data)
 
 	/* Check if Flash is (sufficiently) erased */
 	if ((*((vu_long *) dest) & data) != data) {
-		return (2);
+		return ERR_NOT_ERASED;
 	}
 	/* Disable interrupts which might cause a timeout here */
 	flag = disable_interrupts ();
 
-#if 0
-	addr[0x0555] = 0x00AA00AA;
-	addr[0x02AA] = 0x00550055;
-	addr[0x0555] = 0x00A000A0;
-#else
 	addr[0x0555] = 0xAAAAAAAA;
 	addr[0x02AA] = 0x55555555;
 	addr[0x0555] = 0xA0A0A0A0;
-#endif
 
 	*((vu_long *) dest) = data;
 
@@ -628,18 +550,11 @@ static int write_word (flash_info_t * info, ulong dest, ulong data)
 
 	/* data polling for D7 */
 	start = get_timer (0);
-#if 0
-	while ((*((vu_long *) dest) & 0x00800080) != (data & 0x00800080))
-#else
 	while ((*((vu_long *) dest) & 0x80808080) != (data & 0x80808080))
-#endif
 	{
 		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
-			return (1);
+			return ERR_TIMOUT;
 		}
 	}
 	return (0);
 }
-
-/*-----------------------------------------------------------------------
- */

+ 1 - 1
board/fads/u-boot.lds

@@ -52,7 +52,7 @@ SECTIONS
   {
     cpu/mpc8xx/start.o		(.text)
 
-    . = DEFINED(env_offset) ? env_offset : .;
+    /*. = DEFINED(env_offset) ? env_offset : .;*/
     common/environment.o	(.ppcenv)
 
     *(.text)