mtd: nand: omap_gpmc: Enable multiple NAND flash devices
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@merica.cz>
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 @@
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 @@
}
/*
- * 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 @@
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 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 @@
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 @@
nand->read_buf = nand_read_buf;
nand->dev_ready = omap_spl_dev_ready;
#endif
-
return 0;
}