summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRostislav Lisovy <lisovy@gmail.com>2014-09-02 16:23:58 +0200
committerTom Rini <trini@ti.com>2014-09-04 13:06:00 -0400
commit5c3f7e0ead6db15dc1888cd126b2420ae87980c4 (patch)
treee60d541865d7f55f2bdb38438a13c6a13a5ed4c0
parentfc12a1f589ff54abafba42f17649955a1536ee04 (diff)
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>
-rw-r--r--drivers/mtd/nand/omap_gpmc.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 1acf06b237..96618e12d0 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;
}