[U-Boot] [PATCH] mtd: nand: omap_gpmc: Enable multiple NAND flash devices

Rostislav Lisovy lisovy at gmail.com
Tue Sep 2 16:23:58 CEST 2014


Since the CS of a device connected to the GPMC was
stored in the global variable, it was not possible to
use multiple devices. In this patch the CS is stored per
device in its 'struct omap_nand_info'. This makes it
possible to use up to 'GPMC_MAX_CS' NAND Flash devices
connected to U-boot.

Signed-off-by: Rostislav Lisovy <lisovy at merica.cz>
---
Tested with custom AM335x board having two different
NAND flash chips (CS0 and CS1).

To use/test the change, the particular board.c should contain:
+	/*
+	 * gpmc_init is capable of initializing only one device
+	 * of each type (i.e. 1x NAND, 1x NOR, etc.). Since we
+	 * have 2 NAND flash devices, we have to do the initialization
+	 * manually
+	 */
 	gpmc_init();
+	enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0],
+			      CONFIG_SYS_NAND_BASE, GPMC_SIZE_16M);
+	enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[1],
+			      CONFIG_SYS_NAND_BASE + (16*1024*1024),
+			      GPMC_SIZE_16M);

and your configuration file:
-#define CONFIG_SYS_MAX_NAND_DEVICE     1
+#define CONFIG_SYS_MAX_NAND_DEVICE	2

-#define MTDIDS_DEFAULT			"nand0=omap2-nand.0"
+#define MTDIDS_DEFAULT			"nand0=omap2-nand.0,nand1=omap2-nand.1"

+#define MTDIDS_DEFAULT			"nand0=omap2-nand.0,nand1=omap2-nand.1"
 #define MTDPARTS_DEFAULT		"mtdparts=omap2-nand.0:" \
-					"-(Filesystem);"
+					"-(Filesystem);" \
+					"omap2-nand.1:" \
+					"-(Filesystem2);"

---
 drivers/mtd/nand/omap_gpmc.c | 42 ++++++++++++++++++++----------------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 1acf06b..96618e1 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -27,10 +27,22 @@
 static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
 				0x97, 0x79, 0xe5, 0x24, 0xb5};
 #endif
-static uint8_t cs;
+static uint8_t cs_next;
 static __maybe_unused struct nand_ecclayout omap_ecclayout;
 
 /*
+ * Driver configurations
+ */
+struct omap_nand_info {
+	struct bch_control *control;
+	enum omap_ecc ecc_scheme;
+	int cs;
+};
+
+/* We are wasting a bit of memory but al least we are safe */
+static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
+
+/*
  * omap_nand_hwcontrol - Set the address pointers corretly for the
  *			following address/data/command operation
  */
@@ -38,6 +50,8 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
 				uint32_t ctrl)
 {
 	register struct nand_chip *this = mtd->priv;
+	struct omap_nand_info *info = this->priv;
+	int cs = info->cs;
 
 	/*
 	 * Point the IO_ADDR to DATA and ADDRESS registers instead
@@ -148,24 +162,6 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
 }
 
 /*
- * Driver configurations
- */
-struct omap_nand_info {
-	struct bch_control *control;
-	enum omap_ecc ecc_scheme;
-};
-
-/*
- * This can be a single instance cause all current users have only one NAND
- * with nearly the same setup (BCH8, some with ELM and others with sw BCH
- * library).
- * When some users with other BCH strength will exists this have to change!
- */
-static __maybe_unused struct omap_nand_info omap_nand_info = {
-	.control = NULL
-};
-
-/*
  * omap_reverse_list - re-orders list elements in reverse order [internal]
  * @list:	pointer to start of list
  * @length:	length of list
@@ -198,6 +194,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 	unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
 	u32 ecc_size_config_val = 0;
 	u32 ecc_config_val = 0;
+	int cs = info->cs;
 
 	/* configure GPMC for specific ecc-scheme */
 	switch (info->ecc_scheme) {
@@ -826,7 +823,7 @@ int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
 int board_nand_init(struct nand_chip *nand)
 {
 	int32_t gpmc_config = 0;
-	cs = 0;
+	int cs = cs_next++;
 	int err = 0;
 	/*
 	 * xloader/Uboot's gpmc configuration would have configured GPMC for
@@ -856,7 +853,9 @@ int board_nand_init(struct nand_chip *nand)
 
 	nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
 	nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
-	nand->priv	= &omap_nand_info;
+	omap_nand_info[cs].control = NULL;
+	omap_nand_info[cs].cs = cs;
+	nand->priv	= &omap_nand_info[cs];
 	nand->cmd_ctrl	= omap_nand_hwcontrol;
 	nand->options	|= NAND_NO_PADDING | NAND_CACHEPRG;
 	nand->chip_delay = 100;
@@ -890,6 +889,5 @@ int board_nand_init(struct nand_chip *nand)
 		nand->read_buf = nand_read_buf;
 	nand->dev_ready = omap_spl_dev_ready;
 #endif
-
 	return 0;
 }
-- 
1.9.1



More information about the U-Boot mailing list