Quellcode durchsuchen

Add board/cpu specific NAND chip select function to 440 NDFC
Based on idea and implementation from Jeff Mann
Patch by Stefan Roese, 20 Oct 2006

Stefan Roese vor 18 Jahren
Ursprung
Commit
43a2b0e76a
6 geänderte Dateien mit 58 neuen und 21 gelöschten Zeilen
  1. 4 0
      CHANGELOG
  2. 8 0
      common/cmd_nand.c
  3. 26 13
      cpu/ppc4xx/ndfc.c
  4. 8 1
      drivers/nand/nand.c
  5. 8 7
      include/configs/sequoia.h
  6. 4 0
      include/nand.h

+ 4 - 0
CHANGELOG

@@ -7,6 +7,10 @@ Changes since U-Boot 1.1.4:
 
 * Add (preliminary) support for V38B board
 
+* Add board/cpu specific NAND chip select function to 440 NDFC
+  Based on idea and implementation from Jeff Mann
+  Patch by Stefan Roese, 20 Oct 2006
+
 * PPC405EP: Add support for board configuration of CPC0_PCI register
   This is needed to be able to configure PerWE*/PCI_INT* pin as PerWE*
   Patch by Tolunay Orkun, 07 Apr 2006

+ 8 - 0
common/cmd_nand.c

@@ -178,6 +178,14 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		printf("Device %d: %s", dev, nand_info[dev].name);
 		puts("... is now current device\n");
 		nand_curr_device = dev;
+
+#ifdef CFG_NAND_SELECT_DEVICE
+		/*
+		 * Select the chip in the board/cpu specific driver
+		 */
+		board_nand_select_device(nand_info[dev].priv, dev);
+#endif
+
 		return 0;
 	}
 

+ 26 - 13
cpu/ppc4xx/ndfc.c

@@ -66,7 +66,7 @@ static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd)
 static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
 {
 	struct nand_chip *this = mtdinfo->priv;
-	ulong base = (ulong) this->IO_ADDR_W;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
 
 	if (hwctl & 0x1)
 		out8(base + NDFC_CMD, byte);
@@ -79,7 +79,7 @@ static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
 static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
 {
 	struct nand_chip *this = mtdinfo->priv;
-	ulong base = (ulong) this->IO_ADDR_W;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
 
 	return (in8(base + NDFC_DATA));
 }
@@ -87,7 +87,7 @@ static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
 static int ndfc_dev_ready(struct mtd_info *mtdinfo)
 {
 	struct nand_chip *this = mtdinfo->priv;
-	ulong base = (ulong) this->IO_ADDR_W;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
 
 	while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY))
 		;
@@ -111,30 +111,30 @@ static int ndfc_dev_ready(struct mtd_info *mtdinfo)
 static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
 {
 	struct nand_chip *this = mtdinfo->priv;
-	ulong base = (ulong) this->IO_ADDR_W;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
 	uint32_t *p = (uint32_t *) buf;
 
-	for(;len > 0; len -= 4)
+	for (;len > 0; len -= 4)
 		*p++ = in32(base + NDFC_DATA);
 }
 
 static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
 {
 	struct nand_chip *this = mtdinfo->priv;
-	ulong base = (ulong) this->IO_ADDR_W;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
 	uint32_t *p = (uint32_t *) buf;
 
-	for(; len > 0; len -= 4)
+	for (; len > 0; len -= 4)
 		out32(base + NDFC_DATA, *p++);
 }
 
 static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
 {
 	struct nand_chip *this = mtdinfo->priv;
-	ulong base = (ulong) this->IO_ADDR_W;
+	ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
 	uint32_t *p = (uint32_t *) buf;
 
-	for(; len > 0; len -= 4)
+	for (; len > 0; len -= 4)
 		if (*p++ != in32(base + NDFC_DATA))
 			return -1;
 
@@ -142,8 +142,20 @@ static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len
 }
 #endif /* #ifndef CONFIG_NAND_SPL */
 
+void board_nand_select_device(struct nand_chip *nand, int chip)
+{
+	ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
+
+	/* Set NandFlash Core Configuration Register */
+	/* 1col x 2 rows */
+	out32(base + NDFC_CCR, 0x00000000 | (chip << 24));
+}
+
 void board_nand_init(struct nand_chip *nand)
 {
+	int chip = (ulong)nand->IO_ADDR_W & 0x00000003;
+	ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
+
 	nand->eccmode = NAND_ECC_SOFT;
 
 	nand->hwcontrol  = ndfc_hwcontrol;
@@ -166,10 +178,11 @@ void board_nand_init(struct nand_chip *nand)
 	mtebc(pb0ap, CFG_EBC_PB0AP);
 #endif
 
-	/* Set NandFlash Core Configuration Register */
-	/* Chip select 3, 1col x 2 rows */
-	out32(CFG_NAND_BASE + NDFC_CCR, 0x00000000 | (CFG_NAND_CS << 24));
-	out32(CFG_NAND_BASE + NDFC_BCFG0 + (CFG_NAND_CS << 2), 0x80002222);
+	/*
+	 * Select required NAND chip in NDFC
+	 */
+	board_nand_select_device(nand, chip);
+	out32(base + NDFC_BCFG0 + (chip << 2), 0x80002222);
 }
 
 #endif

+ 8 - 1
drivers/nand/nand.c

@@ -66,8 +66,15 @@ void nand_init(void)
 		size += nand_info[i].size;
 		if (nand_curr_device == -1)
 			nand_curr_device = i;
-}
+	}
 	printf("%lu MiB\n", size / (1024 * 1024));
+
+#ifdef CFG_NAND_SELECT_DEVICE
+	/*
+	 * Select the chip in the board/cpu specific driver
+	 */
+	board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
+#endif
 }
 
 #endif

+ 8 - 7
include/configs/sequoia.h

@@ -134,13 +134,6 @@
 #define CFG_ENV_SIZE_REDUND	(CFG_ENV_SIZE)
 #endif
 
-/*-----------------------------------------------------------------------
- * NAND FLASH
- *----------------------------------------------------------------------*/
-#define CFG_MAX_NAND_DEVICE	1
-#define NAND_MAX_CHIPS		1
-#define CFG_NAND_BASE		CFG_NAND_ADDR
-
 /*
  * IPL (Initial Program Loader, integrated inside CPU)
  * Will load first 4k from NAND (SPL) into cache and execute it from there.
@@ -405,6 +398,14 @@
 #define CFG_EBC_PB2AP		0x24814580
 #define CFG_EBC_PB2CR		(CFG_CPLD | 0x38000)
 
+/*-----------------------------------------------------------------------
+ * NAND FLASH
+ *----------------------------------------------------------------------*/
+#define CFG_MAX_NAND_DEVICE	1
+#define NAND_MAX_CHIPS		1
+#define CFG_NAND_BASE		(CFG_NAND_ADDR + CFG_NAND_CS)
+#define CFG_NAND_SELECT_DEVICE  1	/* nand driver supports mutipl. chips	*/
+
 /*-----------------------------------------------------------------------
  * Cache Configuration
  *----------------------------------------------------------------------*/

+ 4 - 0
include/nand.h

@@ -117,4 +117,8 @@ int nand_lock( nand_info_t *meminfo, int tight );
 int nand_unlock( nand_info_t *meminfo, ulong start, ulong length );
 int nand_get_lock_status(nand_info_t *meminfo, ulong offset);
 
+#ifdef CFG_NAND_SELECT_DEVICE
+void board_nand_select_device(struct nand_chip *nand, int chip);
+#endif
+
 #endif