From: Stefan Roese <sr@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] mtd: nand: mxs: Add support for multiple NAND chips
Date: Tue, 2 Dec 2014 14:26:14 +0100 [thread overview]
Message-ID: <1417526774-32508-1-git-send-email-sr@denx.de> (raw)
This patch adds support for multiple NAND chips connected to the
i.MX6. Linux already supports this configuration. So lets port
the missing features to the U-Boot driver to support more than
one NAND chip here as well.
The necessary changes in detail are:
- Only use DMA channel 0 for all NAND chips:
Linux: a7c12d01 (mtd: gpmi: use DMA channel 0 for all the
nand chips)
d159d8b7 (mtd: gpmi: decouple the chip select from
the DMA channel)
- On i.MX6 only use ready/busy pin for CS0:
Linux: 7caa4fd2 (mtd: gpmi: imx6: fix the wrong method for
checking ready/busy)
To enable this feature the board needs to configure
CONFIG_SYS_NAND_MAX_CHIPS to 2 (or more).
With these changes I'm able to detect and acces 2 NAND chips:
=> nand device
Device 0: 2x nand0, sector size 128 KiB
Page size 2048 b
OOB size 64 b
Erase size 131072 b
Please note that this is also needed to support a NAND chip with
multiple chips embedded in one die, e.g. Micron MT29F32G08QAA.
Tested on a i.MX6DL based board with 2 Micron MT29F4G08AB
chips.
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
---
drivers/mtd/nand/mxs_nand.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index 7a064ab..5013246 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -263,7 +263,7 @@ static void mxs_nand_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
struct nand_chip *nand = mtd->priv;
struct mxs_nand_info *nand_info = nand->priv;
struct mxs_dma_desc *d;
- uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
+ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
int ret;
/*
@@ -340,13 +340,17 @@ static void mxs_nand_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
static int mxs_nand_device_ready(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
- struct mxs_nand_info *nand_info = chip->priv;
+ __maybe_unused struct mxs_nand_info *nand_info = chip->priv;
struct mxs_gpmi_regs *gpmi_regs =
(struct mxs_gpmi_regs *)MXS_GPMI_BASE;
uint32_t tmp;
tmp = readl(&gpmi_regs->hw_gpmi_stat);
+#if defined(CONFIG_MX6)
+ tmp >>= (GPMI_STAT_READY_BUSY_OFFSET + 0);
+#else
tmp >>= (GPMI_STAT_READY_BUSY_OFFSET + nand_info->cur_chip);
+#endif
return tmp & 1;
}
@@ -409,7 +413,7 @@ static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length)
struct nand_chip *nand = mtd->priv;
struct mxs_nand_info *nand_info = nand->priv;
struct mxs_dma_desc *d;
- uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
+ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
int ret;
if (length > NAND_MAX_PAGESIZE) {
@@ -490,7 +494,7 @@ static void mxs_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
struct nand_chip *nand = mtd->priv;
struct mxs_nand_info *nand_info = nand->priv;
struct mxs_dma_desc *d;
- uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
+ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
int ret;
if (length > NAND_MAX_PAGESIZE) {
@@ -554,7 +558,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
{
struct mxs_nand_info *nand_info = nand->priv;
struct mxs_dma_desc *d;
- uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
+ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
uint32_t corrected = 0, failed = 0;
uint8_t *status;
int i, ret;
@@ -701,7 +705,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
{
struct mxs_nand_info *nand_info = nand->priv;
struct mxs_dma_desc *d;
- uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
+ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
int ret;
memcpy(nand_info->data_buf, buf, mtd->writesize);
@@ -1068,7 +1072,7 @@ int mxs_nand_init(struct mxs_nand_info *info)
(struct mxs_gpmi_regs *)MXS_GPMI_BASE;
struct mxs_bch_regs *bch_regs =
(struct mxs_bch_regs *)MXS_BCH_BASE;
- int i = 0, j;
+ int i = 0;
info->desc = malloc(sizeof(struct mxs_dma_desc *) *
MXS_NAND_DMA_DESCRIPTOR_COUNT);
@@ -1083,11 +1087,8 @@ int mxs_nand_init(struct mxs_nand_info *info)
}
/* Init the DMA controller. */
- for (j = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
- j <= MXS_DMA_CHANNEL_AHB_APBH_GPMI7; j++) {
- if (mxs_dma_init_channel(j))
- goto err3;
- }
+ if (mxs_dma_init_channel(0))
+ goto err2;
/* Reset the GPMI block. */
mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
@@ -1100,13 +1101,10 @@ int mxs_nand_init(struct mxs_nand_info *info)
clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1,
GPMI_CTRL1_GPMI_MODE,
GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
- GPMI_CTRL1_BCH_MODE);
+ GPMI_CTRL1_BCH_MODE | GPMI_CTRL1_DECOUPLE_CS);
return 0;
-err3:
- for (--j; j >= 0; j--)
- mxs_dma_release(j);
err2:
free(info->desc);
err1:
--
2.2.0
next reply other threads:[~2014-12-02 13:26 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-02 13:26 Stefan Roese [this message]
2014-12-06 13:07 ` [U-Boot] [PATCH] mtd: nand: mxs: Add support for multiple NAND chips Marek Vasut
2014-12-06 23:45 ` Scott Wood
2014-12-07 1:32 ` Marek Vasut
2014-12-07 1:50 ` Scott Wood
2014-12-07 5:26 ` Marek Vasut
2014-12-08 22:53 ` Scott Wood
2014-12-09 7:20 ` Stefan Roese
2014-12-09 7:34 ` Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1417526774-32508-1-git-send-email-sr@denx.de \
--to=sr@denx.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox