mtd: nand: omap_gpmc: Enable multiple NAND flash devices
authorRostislav Lisovy <lisovy@gmail.com>
Tue, 2 Sep 2014 14:23:58 +0000 (16:23 +0200)
committerTom Rini <trini@ti.com>
Thu, 4 Sep 2014 17:06:00 +0000 (13:06 -0400)
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>
drivers/mtd/nand/omap_gpmc.c

index 1acf06b237c354df2c98e37869751a57cd6ce752..96618e12d08105b9e1ddc6b11828fe90b71465f9 100644 (file)
 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
@@ -147,24 +161,6 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
        return 0;
 }
 
-/*
- * 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
@@ -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;
 }