Skip to contentSkip to conversation

mtd: nand: mxs: Add support for multiple NAND chips

PATCH New Stefan Roese 3 participants 9 messages Dec 2, 2014 – Dec 9, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

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.

Cc Marek Vasut <[email protected]>
Cc Stefano Babic <[email protected]>
Cc Fabio Estevam <[email protected]>
Cc Scott Wood <[email protected]>
---
 drivers/mtd/nand/mxs_nand.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)
drivers/mtd/nand/mxs_nand.c +14 -16
index 7a064ab..5013246 100644
@@ -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:
Signature · 1 line
2.2.0
#1 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 19 lines · Stefan Roese

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).

Quoted 8 lines

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

Shouldn't you see "Device 0" and "Device 1" ?

Quoted 11 lines

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.

Cc Marek Vasut <[email protected]>
Cc Stefano Babic <[email protected]>
Cc Fabio Estevam <[email protected]>
Cc Scott Wood <[email protected]>

Looks pretty trivial, thanks!

Best regards,
Marek Vasut

#2 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 22 lines · Marek Vasut
Quoted 21 lines · Stefan Roese

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:

Quoted 8 lines
Quoted 6 lines

=> nand device

Device 0: 2x nand0, sector size 128 KiB
Page size 2048 b
OOB size 64 b
Erase size 131072 b

Shouldn't you see "Device 0" and "Device 1" ?

The "2x" indicates that there are two identical chips being treated as a single device (chip->numchips).

-Scott

#3 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 32 lines · Scott Wood
Quoted 31 lines · Marek Vasut
Quoted 30 lines · Stefan Roese

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

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Page size 2048 b
OOB size 64 b
Erase size 131072 b

Shouldn't you see "Device 0" and "Device 1" ?

The "2x" indicates that there are two identical chips being treated as a single device (chip->numchips).

Is that correct ? What if I have two different NAND chips on this controller?

Best regards,
Marek Vasut

#4 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 37 lines · Marek Vasut
Quoted 36 lines · Scott Wood
Quoted 35 lines · Marek Vasut
Quoted 33 lines · Stefan Roese

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

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Shouldn't you see "Device 0" and "Device 1" ?

The "2x" indicates that there are two identical chips being treated as a single device (chip->numchips).

Is that correct ? What if I have two different NAND chips on this controller?

Then they need to be represented as separate NAND devices, rather than multiple chips on one device.

-Scott

#5 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 40 lines · Scott Wood
Quoted 39 lines · Marek Vasut
Quoted 38 lines · Scott Wood
Quoted 36 lines · Marek Vasut
Quoted 26 lines · Stefan Roese

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:

Quoted 7 lines

=> nand device

Device 0: 2x nand0, sector size 128 KiB

Page size 2048 b
OOB size 64 b
Erase size 131072 b

Shouldn't you see "Device 0" and "Device 1" ?

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

The "2x" indicates that there are two identical chips being treated as a single device (chip->numchips).

Is that correct ? What if I have two different NAND chips on this controller?

Then they need to be represented as separate NAND devices, rather than multiple chips on one device.

Gee, I wouldn't have though of that, really ;-)

So is this patch correct or not ?

Best regards,
Marek Vasut

#6 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 44 lines · Marek Vasut
Quoted 43 lines · Scott Wood
Quoted 42 lines · Marek Vasut
Quoted 40 lines · Scott Wood
Quoted 29 lines · Marek Vasut
Quoted 28 lines · Stefan Roese

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

Quoted 7 lines
Quoted 5 lines

Device 0: 2x nand0, sector size 128 KiB

Page size 2048 b
OOB size 64 b
Erase size 131072 b

Shouldn't you see "Device 0" and "Device 1" ?

The "2x" indicates that there are two identical chips being treated as a single device (chip->numchips).

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Is that correct ? What if I have two different NAND chips on this controller?

Then they need to be represented as separate NAND devices, rather than multiple chips on one device.

Gee, I wouldn't have though of that, really ;-)

Well, you asked a vague question...

Quoted 1 line

So is this patch correct or not ?

In all its details? I don't know, as I'm not familiar with the hardware. With regards to the question about non-identical devices, this patch doesn't add support for that. So it's a question of what the requirements are, and whether it's being used in the right circumstances. If you have non-identical NAND chips, make sure CONFIG_SYS_NAND_MAX_CHIPS is 1.

A better question might be, does this approach make sense, versus implementing support for multiple devices? What does Linux support?

-Scott

#7 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 23 lines · Scott Wood
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 12 lines
Quoted 9 lines
Quoted 7 lines

=> nand device

Device 0: 2x nand0, sector size 128 KiB

Page size 2048 b
OOB size 64 b
Erase size 131072 b

Shouldn't you see "Device 0" and "Device 1" ?

The "2x" indicates that there are two identical chips being treated as a single device (chip->numchips).

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Is that correct ? What if I have two different NAND chips on this controller?

Then they need to be represented as separate NAND devices, rather than multiple chips on one device.

Gee, I wouldn't have though of that, really ;-)

Well, you asked a vague question...

Quoted 8 lines
Quoted 1 line

So is this patch correct or not ?

In all its details? I don't know, as I'm not familiar with the hardware. With regards to the question about non-identical devices, this patch doesn't add support for that. So it's a question of what the requirements are, and whether it's being used in the right circumstances. If you have non-identical NAND chips, make sure CONFIG_SYS_NAND_MAX_CHIPS is 1.

Correct. Using CONFIG_SYS_NAND_MAX_CHIPS support identical chips. This is exactly what I need in my case. And is also needed for NAND devices that have multiple NAND chips embedded on one die. You then need this possibility to support multiple chips. Otherwise not the whole device can be accessed.

Quoted 2 lines

A better question might be, does this approach make sense, versus implementing support for multiple devices? What does Linux support?

Linux does it exactly in the same way:

[    1.089439] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xdc
[    1.095864] nand: Micron MT29F4G08ABADAH4
[    1.099896] nand: 512MiB, SLC, page size: 2048, OOB size: 64
[    1.105871] nand: 2 chips detected

...

And exposes those 2 chips as one NAND device. By using this patch we also use the same MTD partitioning in U-Boot and Linux (mtdparts environment).

I hope now all is clear.

Thanks,
Stefan

#8 lore raw

PATCH 1/1 mtd: nand: mxs: Add support for multiple NAND chips

Quoted 48 lines · Stefan Roese
Quoted 23 lines · Scott Wood
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 12 lines
Quoted 9 lines
Quoted 7 lines

=> nand device

Device 0: 2x nand0, sector size 128 KiB

Page size 2048 b
OOB size 64 b
Erase size 131072 b

Shouldn't you see "Device 0" and "Device 1" ?

The "2x" indicates that there are two identical chips being treated as a single device (chip->numchips).

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Is that correct ? What if I have two different NAND chips on this controller?

Then they need to be represented as separate NAND devices, rather than multiple chips on one device.

Gee, I wouldn't have though of that, really ;-)

Well, you asked a vague question...

Quoted 8 lines
Quoted 1 line

So is this patch correct or not ?

In all its details? I don't know, as I'm not familiar with the hardware. With regards to the question about non-identical devices, this patch doesn't add support for that. So it's a question of what the requirements are, and whether it's being used in the right circumstances. If you have non-identical NAND chips, make sure CONFIG_SYS_NAND_MAX_CHIPS is 1.

Correct. Using CONFIG_SYS_NAND_MAX_CHIPS support identical chips. This is exactly what I need in my case. And is also needed for NAND devices that have multiple NAND chips embedded on one die. You then need this possibility to support multiple chips. Otherwise not the whole device can be accessed.

Quoted 2 lines

A better question might be, does this approach make sense, versus implementing support for multiple devices? What does Linux support?

Linux does it exactly in the same way:

[    1.089439] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xdc
[    1.095864] nand: Micron MT29F4G08ABADAH4
[    1.099896] nand: 512MiB, SLC, page size: 2048, OOB size: 64
[    1.105871] nand: 2 chips detected
Quoted 7 lines

...

And exposes those 2 chips as one NAND device. By using this patch we also use the same MTD partitioning in U-Boot and Linux (mtdparts environment).

I hope now all is clear.

Yes, it is now. Thank you both for the detailed explanation!

Best regards,
Marek Vasut