mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 00/14] Add i.MX7 NAND xload support
@ 2022-11-01 15:30 Sascha Hauer
  2022-11-01 15:30 ` [PATCH 01/14] mtd: nand: nand-mxs: Move register definitions to separate file Sascha Hauer
                   ` (13 more replies)
  0 siblings, 14 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

This series adds i.MX7 NAND xload support. We have made quite a mess
with the different register defines for both the APBH DMA support and
the GPMI controller, so this is cleaned up first. There are other
cleanups and bugfixes as well, so adding i.MX7 support has become the
smallest thing in this series ;)

Sascha

Ahmad Fatoum (1):
  ARM: i.MX: xload-gpmi-nand: refactor for more SoC support

Sascha Hauer (13):
  mtd: nand: nand-mxs: Move register definitions to separate file
  ARM: i.MX: xload nand: Use common register defines
  ARM: i.MX: xload nand: add common readid
  dma: apbh-dma: Simplify code
  dma: apbh-dma: unify register defines
  imx-bbu-nand-fcb: pull printing debug info out of get_fcb()
  ARM: i.MX: xload nand: Pull ECC status checking out of read page
  ARM: i.MX: xload nand: Use final page layout from FCB
  imx-bbu-nand-fcb: Fix reading FCB information from BCH registers
  ARM: i.MX: xload nand: reset NAND before accessing it
  ARM: i.MX: xload nand: Move mxs_nand_mode_fcb_62bit() to header file
  ARM: i.MX: xload nand: Implement i.MX7 support
  imx-bbu-nand-fcb: Add fcb command

 arch/arm/mach-imx/include/mach/imx6-regs.h |   2 +
 arch/arm/mach-imx/include/mach/imx7-regs.h |   1 +
 arch/arm/mach-imx/include/mach/xload.h     |   1 +
 arch/arm/mach-imx/xload-gpmi-nand.c        | 637 +++++++++++----------
 commands/Kconfig                           |   9 +
 common/imx-bbu-nand-fcb.c                  | 199 +++++--
 drivers/dma/apbh_dma.c                     | 514 +----------------
 drivers/mtd/nand/nand_mxs.c                | 412 ++++---------
 include/dma/apbh-dma.h                     |  95 ++-
 include/soc/imx/gpmi-nand.h                | 141 +++++
 10 files changed, 791 insertions(+), 1220 deletions(-)
 create mode 100644 include/soc/imx/gpmi-nand.h

-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/14] mtd: nand: nand-mxs: Move register definitions to separate file
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-02  8:08   ` Marco Felsch
  2022-11-01 15:30 ` [PATCH 02/14] ARM: i.MX: xload nand: Use common register defines Sascha Hauer
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

The GPMI registers are needed in the MTD GPMI driver and also in the
xload-gpmi driver. So far both use their own set of register defines.
Move the MTD GPMI register defines to include/ so that we can use them
in the xload driver as well.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_mxs.c | 186 ++++++------------------------------
 include/soc/imx/gpmi-nand.h | 114 ++++++++++++++++++++++
 2 files changed, 145 insertions(+), 155 deletions(-)
 create mode 100644 include/soc/imx/gpmi-nand.h

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 5faa17a4bd..d711708ff2 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -21,6 +21,7 @@
 #include <linux/types.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/bitfield.h>
 #include <of_mtd.h>
 #include <common.h>
 #include <dma.h>
@@ -32,139 +33,10 @@
 #include <dma/apbh-dma.h>
 #include <stmp-device.h>
 #include <mach/generic.h>
+#include <soc/imx/gpmi-nand.h>
 
 #include "internals.h"
 
-#define	MX28_BLOCK_SFTRST				(1 << 31)
-#define	MX28_BLOCK_CLKGATE				(1 << 30)
-
-#define GPMI_CTRL0					0x00000000
-#define	GPMI_CTRL0_RUN					(1 << 29)
-#define	GPMI_CTRL0_DEV_IRQ_EN				(1 << 28)
-/* Disable for now since we don't need it and it is different on MX23.
-#define	GPMI_CTRL0_LOCK_CS				(1 << 27)
-*/
-#define	GPMI_CTRL0_UDMA					(1 << 26)
-#define	GPMI_CTRL0_COMMAND_MODE_MASK			(0x3 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_OFFSET			24
-#define	GPMI_CTRL0_COMMAND_MODE_WRITE			(0x0 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_READ			(0x1 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE	(0x2 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY		(0x3 << 24)
-#define	GPMI_CTRL0_WORD_LENGTH				(1 << 23)
-/* Careful: Is 0x3 on MX23
-#define	GPMI_CTRL0_CS_MASK				(0x7 << 20)
-*/
-#define	GPMI_CTRL0_CS_OFFSET				20
-#define	GPMI_CTRL0_ADDRESS_MASK				(0x7 << 17)
-#define	GPMI_CTRL0_ADDRESS_OFFSET			17
-#define	GPMI_CTRL0_ADDRESS_NAND_DATA			(0x0 << 17)
-#define	GPMI_CTRL0_ADDRESS_NAND_CLE			(0x1 << 17)
-#define	GPMI_CTRL0_ADDRESS_NAND_ALE			(0x2 << 17)
-#define	GPMI_CTRL0_ADDRESS_INCREMENT			(1 << 16)
-#define	GPMI_CTRL0_XFER_COUNT_MASK			0xffff
-#define	GPMI_CTRL0_XFER_COUNT_OFFSET			0
-
-#define GPMI_CTRL1					0x00000060
-#define GPMI_CTRL1_SET					0x00000064
-#define GPMI_CTRL1_CLR					0x00000068
-#define	GPMI_CTRL1_DECOUPLE_CS				(1 << 24)
-#define	GPMI_CTRL1_WRN_DLY(d)				(((d) & 0x3) << 22)
-#define	GPMI_CTRL1_TIMEOUT_IRQ_EN			(1 << 20)
-#define	GPMI_CTRL1_GANGED_RDYBUSY			(1 << 19)
-#define	GPMI_CTRL1_BCH_MODE				(1 << 18)
-#define	GPMI_CTRL1_DLL_ENABLE				(1 << 17)
-#define	GPMI_CTRL1_HALF_PERIOD				(1 << 16)
-#define	GPMI_CTRL1_RDN_DELAY(d)				(((d) & 0xf) << 12)
-#define	GPMI_CTRL1_DMA2ECC_MODE				(1 << 11)
-#define	GPMI_CTRL1_DEV_IRQ				(1 << 10)
-#define	GPMI_CTRL1_TIMEOUT_IRQ				(1 << 9)
-#define	GPMI_CTRL1_BURST_EN				(1 << 8)
-#define	GPMI_CTRL1_ABORT_WAIT_REQUEST			(1 << 7)
-#define	GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_MASK	(0x7 << 4)
-#define	GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_OFFSET	4
-#define	GPMI_CTRL1_DEV_RESET				(1 << 3)
-#define	GPMI_CTRL1_ATA_IRQRDY_POLARITY			(1 << 2)
-#define	GPMI_CTRL1_CAMERA_MODE				(1 << 1)
-#define	GPMI_CTRL1_GPMI_MODE				(1 << 0)
-
-#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS		0x0
-#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS		0x1
-#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS		0x2
-#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY		0x3
-
-#define GPMI_TIMING0					0x00000070
-
-#define	GPMI_TIMING0_ADDRESS_SETUP(d)			(((d) & 0xff) << 16)
-#define	GPMI_TIMING0_DATA_HOLD(d)			(((d) & 0xff) << 8)
-#define	GPMI_TIMING0_DATA_SETUP(d)			(((d) & 0xff) << 0)
-
-#define GPMI_TIMING1					0x00000080
-#define	GPMI_TIMING1_BUSY_TIMEOUT(d)			(((d) & 0xffff) << 16)
-
-#define	GPMI_ECCCTRL_HANDLE_MASK			(0xffff << 16)
-#define	GPMI_ECCCTRL_HANDLE_OFFSET			16
-#define	GPMI_ECCCTRL_ECC_CMD_MASK			(0x3 << 13)
-#define	GPMI_ECCCTRL_ECC_CMD_OFFSET			13
-#define	GPMI_ECCCTRL_ECC_CMD_DECODE			(0x0 << 13)
-#define	GPMI_ECCCTRL_ECC_CMD_ENCODE			(0x1 << 13)
-#define GPMI_ECCCTRL_RANDOMIZER_ENABLE                  (1 << 11)
-#define GPMI_ECCCTRL_RANDOMIZER_TYPE0                   0
-#define GPMI_ECCCTRL_RANDOMIZER_TYPE1                   (1 << 9)
-#define GPMI_ECCCTRL_RANDOMIZER_TYPE2                   (2 << 9)
-#define	GPMI_ECCCTRL_ENABLE_ECC				(1 << 12)
-#define	GPMI_ECCCTRL_BUFFER_MASK_MASK			0x1ff
-#define	GPMI_ECCCTRL_BUFFER_MASK_OFFSET			0
-#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_AUXONLY		0x100
-#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE		0x1ff
-
-#define GPMI_STAT				0x000000b0
-#define	GPMI_STAT_READY_BUSY_OFFSET			24
-
-#define GPMI_DEBUG				0x000000c0
-#define GPMI_DEBUG_READY0_OFFSET			28
-
-#define GPMI_VERSION				0x000000d0
-#define GPMI_VERSION_MINOR_OFFSET			16
-#define GPMI_VERSION_TYPE_MX23			0x0300
-
-#define BCH_CTRL				0x00000000
-#define	BCH_CTRL_COMPLETE_IRQ			(1 << 0)
-#define	BCH_CTRL_COMPLETE_IRQ_EN		(1 << 8)
-
-#define BCH_LAYOUTSELECT			0x00000070
-
-#define BCH_FLASH0LAYOUT0			0x00000080
-#define	BCH_FLASHLAYOUT0_NBLOCKS_MASK			(0xff << 24)
-#define	BCH_FLASHLAYOUT0_NBLOCKS_OFFSET			24
-#define	BCH_FLASHLAYOUT0_META_SIZE_MASK			(0xff << 16)
-#define	BCH_FLASHLAYOUT0_META_SIZE_OFFSET		16
-#define	BCH_FLASHLAYOUT0_ECC0_MASK			(0xf << 12)
-#define	BCH_FLASHLAYOUT0_ECC0_OFFSET			12
-#define	IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET		11
-#define	BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET		0
-#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1_MASK		BIT(10)
-#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET		10
-
-#define BCH_FLASH0LAYOUT1			0x00000090
-#define	BCH_FLASHLAYOUT1_PAGE_SIZE_MASK			(0xffff << 16)
-#define	BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET		16
-#define	BCH_FLASHLAYOUT1_ECCN_MASK			(0xf << 12)
-#define	BCH_FLASHLAYOUT1_ECCN_OFFSET			12
-#define	IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET		11
-#define	BCH_FLASHLAYOUT1_GF13_0_GF14_1_MASK		BIT(10)
-#define	BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET		10
-#define	BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET		0
-
-#define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
-
-#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
-#define	MXS_NAND_METADATA_SIZE			10
-
-#define	MXS_NAND_COMMAND_BUFFER_SIZE		32
-
-#define	MXS_NAND_BCH_TIMEOUT			10000
-
 enum gpmi_type {
 	GPMI_MXS,
 	GPMI_IMX6,
@@ -503,7 +375,7 @@ static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctr
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		nand_info->cmd_queue_len;
@@ -634,7 +506,7 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		length;
 
@@ -659,7 +531,7 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
 
 	mxs_dma_desc_append(channel, d);
@@ -713,7 +585,7 @@ static void mxs_nand_write_buf(struct nand_chip *chip, const uint8_t *buf,
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		length;
 
@@ -749,16 +621,22 @@ static void mxs_nand_config_bch(struct nand_chip *chip, int readlen)
 	else
 		chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
 
-	fl0 = (mxs_nand_ecc_chunk_cnt(readlen) - 1)
-			<< BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
-	fl0 |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
-	fl0 |= (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET;
-	fl0 |= chunk_size;
+	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, mxs_nand_ecc_chunk_cnt(readlen) - 1);
+	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, MXS_NAND_METADATA_SIZE);
+	if (mxs_nand_is_imx6(nand_info))
+		fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, chip->ecc.strength >> 1);
+	else
+		fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_ECC0, chip->ecc.strength >> 1);
+	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, chunk_size);
 	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
 
-	fl1 = readlen << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
-	fl1 |= (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET;
-	fl1 |= chunk_size;
+	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, readlen);
+	if (mxs_nand_is_imx6(nand_info))
+		fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, chip->ecc.strength >> 1);
+	else
+		fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_ECCN, chip->ecc.strength >> 1);
+
+	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, chunk_size);
 	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
 }
 
@@ -781,7 +659,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
 
 	mxs_dma_desc_append(channel, d);
@@ -797,7 +675,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		readtotal;
 	d->cmd.pio_words[1] = 0;
@@ -829,7 +707,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		readtotal;
 	d->cmd.pio_words[1] = 0;
@@ -1037,7 +915,7 @@ static int mxs_nand_ecc_write_page(struct nand_chip *chip, const uint8_t *buf,
 	d->cmd.pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
+		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
 	d->cmd.pio_words[1] = 0;
 	d->cmd.pio_words[2] =
@@ -1276,23 +1154,21 @@ static void mxs_nand_mode_fcb_62bit(struct mxs_nand_info *nand_info)
 	bch_regs = nand_info->bch_base;
 
 	/* 8 ecc_chunks */
-	fl0 = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
+	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, 7);
 	/* 32 bytes for metadata */
-	fl0 |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
+	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, 32);
 	/* using ECC62 level to be performed */
-	fl0 |= 0x1F << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET;
+	fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, 0x1f);
 	/* 0x20 * 4 bytes of the data0 block */
-	fl0 |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET;
-	fl0 |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
+	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, 0x20);
 	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
 
 	/* 1024 for data + 838 for OOB */
-	fl1 = BCH62_PAGESIZE << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
+	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, BCH62_PAGESIZE);
 	/* using ECC62 level to be performed */
-	fl1 |= 0x1f << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET;
+	fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, 0x1f);
 	/* 0x20 * 4 bytes of the data0 block */
-	fl1 |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET;
-	fl1 |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
+	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, 0x20);
 	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
 }
 
diff --git a/include/soc/imx/gpmi-nand.h b/include/soc/imx/gpmi-nand.h
new file mode 100644
index 0000000000..f7a2caa1d6
--- /dev/null
+++ b/include/soc/imx/gpmi-nand.h
@@ -0,0 +1,114 @@
+#ifndef __SOC_IMX_GPMI_NAND_H
+#define __SOC_IMX_GPMI_NAND_H
+
+#include <linux/bitfield.h>
+
+#define GPMI_CTRL0				0x00000000
+#define GPMI_CTRL0_SFTRST				BIT(31)
+#define	GPMI_CTRL0_RUN					BIT(29)
+#define	GPMI_CTRL0_DEV_IRQ_EN				BIT(28)
+#define	GPMI_CTRL0_UDMA					BIT(26)
+#define	GPMI_CTRL0_COMMAND_MODE				GENMASK(25, 24)
+#define	GPMI_CTRL0_COMMAND_MODE_WRITE			(0x0 << 24)
+#define	GPMI_CTRL0_COMMAND_MODE_READ			(0x1 << 24)
+#define	GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE	(0x2 << 24)
+#define	GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY		(0x3 << 24)
+#define	GPMI_CTRL0_WORD_LENGTH				(1 << 23)
+#define	GPMI_CTRL0_CS					GENMASK(22, 20)
+#define	GPMI_CTRL0_ADDRESS				GENMASK(19, 17)
+#define	GPMI_CTRL0_ADDRESS_NAND_DATA			(0x0 << 17)
+#define	GPMI_CTRL0_ADDRESS_NAND_CLE			(0x1 << 17)
+#define	GPMI_CTRL0_ADDRESS_NAND_ALE			(0x2 << 17)
+#define	GPMI_CTRL0_ADDRESS_INCREMENT			BIT(16)
+#define	GPMI_CTRL0_XFER_COUNT				GENMASK(15, 0)
+
+#define GPMI_CTRL1				0x00000060
+#define GPMI_CTRL1_SET				0x00000064
+#define GPMI_CTRL1_CLR				0x00000068
+#define	GPMI_CTRL1_DECOUPLE_CS				BIT(24)
+#define	GPMI_CTRL1_WRN_DLY(d)				(((d) & 0x3) << 22)
+#define	GPMI_CTRL1_TIMEOUT_IRQ_EN			BIT(20)
+#define	GPMI_CTRL1_GANGED_RDYBUSY			BIT(19)
+#define	GPMI_CTRL1_BCH_MODE				BIT(18)
+#define	GPMI_CTRL1_DLL_ENABLE				BIT(17)
+#define	GPMI_CTRL1_HALF_PERIOD				BIT(16)
+#define	GPMI_CTRL1_RDN_DELAY(d)				(((d) & 0xf) << 12)
+#define	GPMI_CTRL1_DMA2ECC_MODE				BIT(11)
+#define	GPMI_CTRL1_DEV_IRQ				BIT(10)
+#define	GPMI_CTRL1_TIMEOUT_IRQ				BIT(9)
+#define	GPMI_CTRL1_BURST_EN				BIT(8)
+#define	GPMI_CTRL1_ABORT_WAIT_REQUEST			BIT(7)
+#define	GPMI_CTRL1_ABORT_WAIT_FOR_READY			GENMASK(6, 4)
+#define	GPMI_CTRL1_DEV_RESET				BIT(3)
+#define	GPMI_CTRL1_ATA_IRQRDY_POLARITY			BIT(2)
+#define	GPMI_CTRL1_CAMERA_MODE				BIT(1)
+#define	GPMI_CTRL1_GPMI_MODE				BIT(0)
+
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS		0x0
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS		0x1
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS		0x2
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY		0x3
+
+#define GPMI_TIMING0				0x00000070
+
+#define	GPMI_TIMING0_ADDRESS_SETUP(d)			(((d) & 0xff) << 16)
+#define	GPMI_TIMING0_DATA_HOLD(d)			(((d) & 0xff) << 8)
+#define	GPMI_TIMING0_DATA_SETUP(d)			(((d) & 0xff) << 0)
+
+#define GPMI_TIMING1				0x00000080
+#define	GPMI_TIMING1_BUSY_TIMEOUT(d)			(((d) & 0xffff) << 16)
+
+#define	GPMI_ECCCTRL_HANDLE				GENMASK(31, 16)
+#define	GPMI_ECCCTRL_ECC_CMD				GENMASK(14, 13)
+#define	GPMI_ECCCTRL_ECC_CMD_DECODE			(0x0 << 13)
+#define	GPMI_ECCCTRL_ECC_CMD_ENCODE			(0x1 << 13)
+#define GPMI_ECCCTRL_RANDOMIZER_ENABLE                  BIT(11)
+#define GPMI_ECCCTRL_RANDOMIZER_TYPE0                   0
+#define GPMI_ECCCTRL_RANDOMIZER_TYPE1                   (1 << 9)
+#define GPMI_ECCCTRL_RANDOMIZER_TYPE2                   (2 << 9)
+#define	GPMI_ECCCTRL_ENABLE_ECC				BIT(12)
+#define	GPMI_ECCCTRL_BUFFER_MASK			GENMASK(8, 0)
+#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_AUXONLY		0x100
+#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE		0x1ff
+
+#define GPMI_STAT				0x000000b0
+#define	GPMI_STAT_READY_BUSY_OFFSET			24
+
+#define GPMI_DEBUG				0x000000c0
+#define GPMI_DEBUG_READY0_OFFSET			28
+
+#define GPMI_VERSION				0x000000d0
+#define GPMI_VERSION_MINOR_OFFSET			16
+#define GPMI_VERSION_TYPE_MX23				0x0300
+
+#define BCH_CTRL				0x00000000
+#define	BCH_CTRL_COMPLETE_IRQ				BIT(0)
+#define	BCH_CTRL_COMPLETE_IRQ_EN			BIT(8)
+
+#define BCH_LAYOUTSELECT			0x00000070
+
+#define BCH_FLASH0LAYOUT0			0x00000080
+#define	BCH_FLASHLAYOUT0_NBLOCKS			GENMASK(31, 24)
+#define	BCH_FLASHLAYOUT0_META_SIZE			GENMASK(23, 16)
+#define	BCH_FLASHLAYOUT0_ECC0				GENMASK(15, 12)
+#define	IMX6_BCH_FLASHLAYOUT0_ECC0			GENMASK(15, 11)
+#define	BCH_FLASHLAYOUT0_DATA0_SIZE			GENMASK(9, 0)
+#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1			BIT(10)
+
+#define BCH_FLASH0LAYOUT1			0x00000090
+#define	BCH_FLASHLAYOUT1_PAGE_SIZE			GENMASK(31, 16)
+#define	BCH_FLASHLAYOUT1_ECCN				GENMASK(15, 12)
+#define	IMX6_BCH_FLASHLAYOUT1_ECCN			GENMASK(15, 11)
+#define	BCH_FLASHLAYOUT1_GF13_0_GF14_1			BIT(10)
+#define	BCH_FLASHLAYOUT1_DATAN_SIZE			GENMASK(9, 0)
+
+#define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
+
+#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
+#define	MXS_NAND_METADATA_SIZE			10
+
+#define	MXS_NAND_COMMAND_BUFFER_SIZE		32
+
+#define	MXS_NAND_BCH_TIMEOUT			10000
+
+#endif /* __SOC_IMX_GPMI_NAND_H */
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 02/14] ARM: i.MX: xload nand: Use common register defines
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
  2022-11-01 15:30 ` [PATCH 01/14] mtd: nand: nand-mxs: Move register definitions to separate file Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-02  8:10   ` Marco Felsch
  2022-11-01 15:30 ` [PATCH 03/14] ARM: i.MX: xload nand: add common readid Sascha Hauer
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

We have a set of GPMI register defines in include/, so use them for the
xload driver as well.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/xload-gpmi-nand.c | 66 ++++++++---------------------
 1 file changed, 17 insertions(+), 49 deletions(-)

diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index 3a4f331ce6..6ac9af762f 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -11,6 +11,7 @@
 #include <mach/xload.h>
 #include <soc/imx/imx-nand-bcb.h>
 #include <linux/mtd/rawnand.h>
+#include <soc/imx/gpmi-nand.h>
 #include <mach/imx6-regs.h>
 #include <mach/clock-imx6.h>
 
@@ -203,39 +204,6 @@ static int mxs_dma_run(struct mxs_dma_chan *pchan, struct mxs_dma_cmd *pdesc,
 
 /* ----------------------------- NAND driver part -------------------------- */
 
-#define	GPMI_CTRL0					0x00000000
-#define	GPMI_CTRL0_RUN					(1 << 29)
-#define	GPMI_CTRL0_DEV_IRQ_EN				(1 << 28)
-#define	GPMI_CTRL0_UDMA					(1 << 26)
-#define	GPMI_CTRL0_COMMAND_MODE_MASK			(0x3 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_OFFSET			24
-#define	GPMI_CTRL0_COMMAND_MODE_WRITE			(0x0 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_READ			(0x1 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE	(0x2 << 24)
-#define	GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY		(0x3 << 24)
-#define	GPMI_CTRL0_WORD_LENGTH				(1 << 23)
-#define	GPMI_CTRL0_CS(cs)				((cs) << 20)
-#define	GPMI_CTRL0_ADDRESS_MASK				(0x7 << 17)
-#define	GPMI_CTRL0_ADDRESS_OFFSET			17
-#define	GPMI_CTRL0_ADDRESS_NAND_DATA			(0x0 << 17)
-#define	GPMI_CTRL0_ADDRESS_NAND_CLE			(0x1 << 17)
-#define	GPMI_CTRL0_ADDRESS_NAND_ALE			(0x2 << 17)
-#define	GPMI_CTRL0_ADDRESS_INCREMENT			(1 << 16)
-#define	GPMI_CTRL0_XFER_COUNT_MASK			0xffff
-#define	GPMI_CTRL0_XFER_COUNT_OFFSET			0
-
-#define	GPMI_ECCCTRL_ECC_CMD_DECODE			(0x0 << 13)
-#define	GPMI_ECCCTRL_ENABLE_ECC				(1 << 12)
-#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE		0x1ff
-
-#define	BCH_CTRL					0x00000000
-#define	BCH_CTRL_COMPLETE_IRQ				(1 << 0)
-
-#define	MXS_NAND_DMA_DESCRIPTOR_COUNT			6
-#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE			512
-#define	MXS_NAND_METADATA_SIZE				10
-#define	MXS_NAND_COMMAND_BUFFER_SIZE			128
-
 struct mxs_nand_info {
 	void __iomem *io_base;
 	void __iomem *bch_base;
@@ -352,7 +320,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		cmd_queue_len;
@@ -372,7 +340,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		cmd_queue_len;
@@ -386,7 +354,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
 
 	if (raw) {
@@ -398,7 +366,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 			DMACMD_COMMAND_DMA_WRITE;
 		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 			GPMI_CTRL0_WORD_LENGTH |
-			GPMI_CTRL0_CS(info->cs) |
+			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 			GPMI_CTRL0_ADDRESS_NAND_DATA |
 			(writesize + oobsize);
 		d->address = (dma_addr_t)databuf;
@@ -408,7 +376,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 		d->data = DMACMD_WAIT4END | DMACMD_PIO_WORDS(6);
 		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 			GPMI_CTRL0_WORD_LENGTH |
-			GPMI_CTRL0_CS(info->cs) |
+			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 			GPMI_CTRL0_ADDRESS_NAND_DATA |
 			(writesize + oobsize);
 		d->pio_words[1] = 0;
@@ -426,7 +394,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 			DMACMD_PIO_WORDS(3);
 		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 			GPMI_CTRL0_WORD_LENGTH |
-			GPMI_CTRL0_CS(info->cs) |
+			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 			GPMI_CTRL0_ADDRESS_NAND_DATA |
 			(writesize + oobsize);
 	}
@@ -499,7 +467,7 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		cmd_queue_len;
@@ -512,7 +480,7 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
 		DMACMD_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		(1);
 	d->address = (dma_addr_t)databuf;
@@ -557,7 +525,7 @@ static int mxs_nand_reset(struct mxs_nand_info *info, void *databuf)
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		cmd_queue_len;
@@ -629,7 +597,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		cmd_queue_len;
@@ -643,7 +611,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
 
 	/* Compile DMA descriptor - read. */
@@ -654,7 +622,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 		DMACMD_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		(sizeof(struct nand_onfi_params));
 	d->address = (dma_addr_t)databuf;
@@ -733,7 +701,7 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		cmd_queue_len;
@@ -746,7 +714,7 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
 		DMACMD_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		(sizeof(struct onfi_header));
 	d->address = (dma_addr_t)databuf;
@@ -811,7 +779,7 @@ static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf)
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_CLE |
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		cmd_queue_len;
@@ -824,7 +792,7 @@ static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf)
 		DMACMD_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
-		GPMI_CTRL0_CS(info->cs) |
+		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		(sizeof(struct readid_data));
 	d->address = (dma_addr_t)databuf;
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 03/14] ARM: i.MX: xload nand: add common readid
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
  2022-11-01 15:30 ` [PATCH 01/14] mtd: nand: nand-mxs: Move register definitions to separate file Sascha Hauer
  2022-11-01 15:30 ` [PATCH 02/14] ARM: i.MX: xload nand: Use common register defines Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-02  8:23   ` Marco Felsch
  2022-11-01 15:30 ` [PATCH 04/14] dma: apbh-dma: Simplify code Sascha Hauer
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

mxs_nand_check_onfi() and mxs_nand_read_id() setup the same DMA
descriptors with only a small difference. factor out a common
read_id function from it and share the code.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/xload-gpmi-nand.c | 148 ++++++++++------------------
 1 file changed, 54 insertions(+), 94 deletions(-)

diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index 6ac9af762f..ffbd5c22e3 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -668,7 +668,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 	return ret;
 }
 
-static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
+static int mxs_nand_read_id(struct mxs_nand_info *info, u8 adr, void *databuf, size_t len)
 {
 	int ret;
 	u8 *cmd_buf;
@@ -676,13 +676,6 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
 	int descnum = 0;
 	int cmd_queue_len;
 
-	struct onfi_header {
-		u8 byte0;
-		u8 byte1;
-		u8 byte2;
-		u8 byte3;
-	} onfi_head;
-
 	memset(info->desc, 0,
 		sizeof(*info->desc) * MXS_NAND_DMA_DESCRIPTOR_COUNT);
 
@@ -692,7 +685,7 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
 	d = &info->desc[descnum++];
 	d->address = (dma_addr_t)(cmd_buf);
 	cmd_buf[cmd_queue_len++] = NAND_CMD_READID;
-	cmd_buf[cmd_queue_len++] = 0x20;
+	cmd_buf[cmd_queue_len++] = adr;
 
 	d->data = DMACMD_COMMAND_DMA_READ |
 		DMACMD_WAIT4END |
@@ -710,13 +703,13 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
 	d = &info->desc[descnum++];
 	d->data = DMACMD_WAIT4END |
 		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(sizeof(struct onfi_header)) |
+		DMACMD_XFER_COUNT(len) |
 		DMACMD_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
-		(sizeof(struct onfi_header));
+		len;
 	d->address = (dma_addr_t)databuf;
 
 	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
@@ -725,119 +718,86 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
 
 	/* Execute the DMA chain. */
 	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
-	if (ret) {
+	if (ret)
 		pr_err("DMA read error\n");
-		return ret;
-	}
 
-	memcpy(&onfi_head, databuf, sizeof(struct onfi_header));
+	return ret;
+}
+
+struct onfi_header {
+	u8 byte0;
+	u8 byte1;
+	u8 byte2;
+	u8 byte3;
+};
+
+static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
+{
+	int ret;
+	struct onfi_header *onfi_head = databuf;
+
+	ret = mxs_nand_read_id(info, 0x20, databuf, sizeof(struct onfi_header));
+	if (ret)
+		return ret;
 
-	pr_debug("ONFI Byte0: 0x%x\n", onfi_head.byte0);
-	pr_debug("ONFI Byte1: 0x%x\n", onfi_head.byte1);
-	pr_debug("ONFI Byte2: 0x%x\n", onfi_head.byte2);
-	pr_debug("ONFI Byte3: 0x%x\n", onfi_head.byte3);
+	pr_debug("ONFI Byte0: 0x%x\n", onfi_head->byte0);
+	pr_debug("ONFI Byte1: 0x%x\n", onfi_head->byte1);
+	pr_debug("ONFI Byte2: 0x%x\n", onfi_head->byte2);
+	pr_debug("ONFI Byte3: 0x%x\n", onfi_head->byte3);
 
 	/* check if returned values correspond to ascii characters "ONFI" */
-	if (onfi_head.byte0 != 0x4f || onfi_head.byte1 != 0x4e ||
-		onfi_head.byte2 != 0x46 || onfi_head.byte3 != 0x49)
+	if (onfi_head->byte0 != 0x4f || onfi_head->byte1 != 0x4e ||
+		onfi_head->byte2 != 0x46 || onfi_head->byte3 != 0x49)
 		return 1;
 
 	return 0;
 }
 
+struct readid_data {
+	u8 byte0;
+	u8 byte1;
+	u8 byte2;
+	u8 byte3;
+	u8 byte4;
+} id_data;
+
 static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf)
 {
 	int ret;
-	u8 *cmd_buf;
-	struct mxs_dma_cmd *d;
-	int descnum = 0;
-	int cmd_queue_len;
-
-	struct readid_data {
-		u8 byte0;
-		u8 byte1;
-		u8 byte2;
-		u8 byte3;
-		u8 byte4;
-	} id_data;
-
-	memset(info->desc, 0,
-		sizeof(*info->desc) * MXS_NAND_DMA_DESCRIPTOR_COUNT);
+	struct readid_data *id_data = databuf;
 
-	/* Compile DMA descriptor - READID */
-	cmd_buf = info->cmd_buf;
-	cmd_queue_len = 0;
-	d = &info->desc[descnum++];
-	d->address = (dma_addr_t)(cmd_buf);
-	cmd_buf[cmd_queue_len++] = NAND_CMD_READID;
-	cmd_buf[cmd_queue_len++] = 0x00;
-
-	d->data = DMACMD_COMMAND_DMA_READ |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(cmd_queue_len);
-
-	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
-		GPMI_CTRL0_WORD_LENGTH |
-		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
-		GPMI_CTRL0_ADDRESS_NAND_CLE |
-		GPMI_CTRL0_ADDRESS_INCREMENT |
-		cmd_queue_len;
-
-	/* Compile DMA descriptor - read. */
-	d = &info->desc[descnum++];
-	d->data = DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(sizeof(struct readid_data)) |
-		DMACMD_COMMAND_DMA_WRITE;
-	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
-		GPMI_CTRL0_WORD_LENGTH |
-		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
-		GPMI_CTRL0_ADDRESS_NAND_DATA |
-		(sizeof(struct readid_data));
-	d->address = (dma_addr_t)databuf;
-
-	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
-	d = &info->desc[descnum++];
-	d->data = DMACMD_IRQ | DMACMD_DEC_SEM;
-
-	/* Execute the DMA chain. */
-	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
-	if (ret) {
-		pr_err("DMA read error\n");
+	ret = mxs_nand_read_id(info, 0x0, databuf, sizeof(struct readid_data));
+	if (ret)
 		return ret;
-	}
-
-	memcpy(&id_data, databuf, sizeof(struct readid_data));
 
-	pr_debug("NAND Byte0: 0x%x\n", id_data.byte0);
-	pr_debug("NAND Byte1: 0x%x\n", id_data.byte1);
-	pr_debug("NAND Byte2: 0x%x\n", id_data.byte2);
-	pr_debug("NAND Byte3: 0x%x\n", id_data.byte3);
-	pr_debug("NAND Byte4: 0x%x\n", id_data.byte4);
+	pr_debug("NAND Byte0: 0x%x\n", id_data->byte0);
+	pr_debug("NAND Byte1: 0x%x\n", id_data->byte1);
+	pr_debug("NAND Byte2: 0x%x\n", id_data->byte2);
+	pr_debug("NAND Byte3: 0x%x\n", id_data->byte3);
+	pr_debug("NAND Byte4: 0x%x\n", id_data->byte4);
 
-	if (id_data.byte0 == 0xff || id_data.byte1 == 0xff ||
-		id_data.byte2 == 0xff || id_data.byte3 == 0xff ||
-		id_data.byte4 == 0xff) {
+	if (id_data->byte0 == 0xff || id_data->byte1 == 0xff ||
+		id_data->byte2 == 0xff || id_data->byte3 == 0xff ||
+		id_data->byte4 == 0xff) {
 		pr_err("\"READ ID\" returned 0xff, possible error!\n");
 		return -EOVERFLOW;
 	}
 
 	/* Fill the NAND organization struct with data */
 	info->organization.bits_per_cell =
-		(1 << ((id_data.byte2 >> 2) & 0x3)) * 2;
+		(1 << ((id_data->byte2 >> 2) & 0x3)) * 2;
 	info->organization.pagesize =
-		(1 << (id_data.byte3 & 0x3)) * SZ_1K;
-	info->organization.oobsize = id_data.byte3 & 0x4 ?
+		(1 << (id_data->byte3 & 0x3)) * SZ_1K;
+	info->organization.oobsize = id_data->byte3 & 0x4 ?
 		info->organization.pagesize / 512 * 16 :
 		info->organization.pagesize / 512 * 8;
 	info->organization.pages_per_eraseblock =
-		(1 << ((id_data.byte3 >> 4) & 0x3)) * SZ_64K /
+		(1 << ((id_data->byte3 >> 4) & 0x3)) * SZ_64K /
 		info->organization.pagesize;
 	info->organization.planes_per_lun =
-		1 << ((id_data.byte4 >> 2) & 0x3);
+		1 << ((id_data->byte4 >> 2) & 0x3);
 	info->nand_size = info->organization.planes_per_lun *
-		(1 << ((id_data.byte4 >> 4) & 0x7)) * SZ_8M;
+		(1 << ((id_data->byte4 >> 4) & 0x7)) * SZ_8M;
 	info->organization.eraseblocks_per_lun = info->nand_size /
 		(info->organization.pages_per_eraseblock *
 		info->organization.pagesize);
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 04/14] dma: apbh-dma: Simplify code
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (2 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 03/14] ARM: i.MX: xload nand: add common readid Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-01 15:30 ` [PATCH 05/14] dma: apbh-dma: unify register defines Sascha Hauer
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

The apbh-dma driver supports chaining DMA descriptors while the DMA
engine is running. This is unused in barebox as well as in the Kernel.
We just queue one descriptor chain and wait for its completion, and
the MTD layer doesn't even support the more advanced features. Just
drop the unused code and greatly simplify it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/apbh_dma.c      | 487 ++----------------------------------
 drivers/mtd/nand/nand_mxs.c | 182 ++++++--------
 include/dma/apbh-dma.h      |  48 +---
 3 files changed, 98 insertions(+), 619 deletions(-)

diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c
index 83bd783d34..e93bffd595 100644
--- a/drivers/dma/apbh_dma.c
+++ b/drivers/dma/apbh_dma.c
@@ -43,8 +43,6 @@
 #define	BM_APBHX_CHn_SEMA_PHORE			(0xff << 16)
 #define	BP_APBHX_CHn_SEMA_PHORE			16
 
-static struct mxs_dma_chan mxs_dma_channels[MXS_MAX_DMA_CHANNELS];
-
 enum mxs_dma_id {
 	UNKNOWN_DMA_ID,
 	IMX23_DMA,
@@ -66,185 +64,9 @@ static struct apbh_dma *apbh_dma;
  */
 static int mxs_dma_validate_chan(int channel)
 {
-	struct mxs_dma_chan *pchan;
-
 	if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS))
 		return -EINVAL;
 
-	pchan = mxs_dma_channels + channel;
-	if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED))
-		return -EINVAL;
-
-	return 0;
-}
-
-/*
- * Return the address of the command within a descriptor.
- */
-static unsigned int mxs_dma_cmd_address(struct mxs_dma_desc *desc)
-{
-	return desc->address + offsetof(struct mxs_dma_desc, cmd);
-}
-
-/*
- * Read a DMA channel's hardware semaphore.
- *
- * As used by the MXS platform's DMA software, the DMA channel's hardware
- * semaphore reflects the number of DMA commands the hardware will process, but
- * has not yet finished. This is a volatile value read directly from hardware,
- * so it must be be viewed as immediately stale.
- *
- * If the channel is not marked busy, or has finished processing all its
- * commands, this value should be zero.
- *
- * See mxs_dma_append() for details on how DMA command blocks must be configured
- * to maintain the expected behavior of the semaphore's value.
- */
-static int mxs_dma_read_semaphore(int channel)
-{
-	struct apbh_dma *apbh = apbh_dma;
-	uint32_t tmp;
-	int ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
-
-	if (apbh_dma_is_imx23(apbh))
-		tmp = readl(apbh->regs + HW_APBHX_CHn_SEMA_MX23(channel));
-	else
-		tmp = readl(apbh->regs + HW_APBHX_CHn_SEMA_MX28(channel));
-
-	tmp &= BM_APBHX_CHn_SEMA_PHORE;
-	tmp >>= BP_APBHX_CHn_SEMA_PHORE;
-
-	return tmp;
-}
-
-/*
- * Enable a DMA channel.
- *
- * If the given channel has any DMA descriptors on its active list, this
- * function causes the DMA hardware to begin processing them.
- *
- * This function marks the DMA channel as "busy," whether or not there are any
- * descriptors to process.
- */
-static int mxs_dma_enable(int channel)
-{
-	struct apbh_dma *apbh = apbh_dma;
-	unsigned int sem;
-	struct mxs_dma_chan *pchan;
-	struct mxs_dma_desc *pdesc;
-	int channel_bit, ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
-
-	pchan = mxs_dma_channels + channel;
-
-	if (pchan->pending_num == 0) {
-		pchan->flags |= MXS_DMA_FLAGS_BUSY;
-		return 0;
-	}
-
-	pdesc = list_first_entry(&pchan->active, struct mxs_dma_desc, node);
-	if (pdesc == NULL)
-		return -EFAULT;
-
-	if (pchan->flags & MXS_DMA_FLAGS_BUSY) {
-		if (!(pdesc->cmd.data & MXS_DMA_DESC_CHAIN))
-			return 0;
-
-		sem = mxs_dma_read_semaphore(channel);
-		if (sem == 0)
-			return 0;
-
-		if (sem == 1) {
-			pdesc = list_entry(pdesc->node.next,
-					   struct mxs_dma_desc, node);
-			if (apbh_dma_is_imx23(apbh))
-				writel(mxs_dma_cmd_address(pdesc),
-					apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX23(channel));
-			else
-				writel(mxs_dma_cmd_address(pdesc),
-					apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX28(channel));
-		}
-
-		if (apbh_dma_is_imx23(apbh))
-			writel(pchan->pending_num,
-					apbh->regs + HW_APBHX_CHn_SEMA_MX23(channel));
-		else
-			writel(pchan->pending_num,
-					apbh->regs + HW_APBHX_CHn_SEMA_MX28(channel));
-
-		pchan->active_num += pchan->pending_num;
-		pchan->pending_num = 0;
-	} else {
-		pchan->active_num += pchan->pending_num;
-		pchan->pending_num = 0;
-		if (apbh_dma_is_imx23(apbh)) {
-			writel(mxs_dma_cmd_address(pdesc),
-				apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX23(channel));
-			writel(pchan->active_num,
-				apbh->regs + HW_APBHX_CHn_SEMA_MX23(channel));
-			channel_bit = channel + BP_APBH_CTRL0_CLKGATE_CHANNEL;
-		} else {
-			writel(mxs_dma_cmd_address(pdesc),
-				apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX28(channel));
-			writel(pchan->active_num,
-				apbh->regs + HW_APBHX_CHn_SEMA_MX28(channel));
-			channel_bit = channel;
-		}
-		writel(1 << channel_bit, apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR);
-	}
-
-	pchan->flags |= MXS_DMA_FLAGS_BUSY;
-	return 0;
-}
-
-/*
- * Disable a DMA channel.
- *
- * This function shuts down a DMA channel and marks it as "not busy." Any
- * descriptors on the active list are immediately moved to the head of the
- * "done" list, whether or not they have actually been processed by the
- * hardware. The "ready" flags of these descriptors are NOT cleared, so they
- * still appear to be active.
- *
- * This function immediately shuts down a DMA channel's hardware, aborting any
- * I/O that may be in progress, potentially leaving I/O hardware in an undefined
- * state. It is unwise to call this function if there is ANY chance the hardware
- * is still processing a command.
- */
-static int mxs_dma_disable(int channel)
-{
-	struct mxs_dma_chan *pchan;
-	struct apbh_dma *apbh = apbh_dma;
-	int channel_bit, ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
-
-	pchan = mxs_dma_channels + channel;
-
-	if (!(pchan->flags & MXS_DMA_FLAGS_BUSY))
-		return -EINVAL;
-
-	if (apbh_dma_is_imx23(apbh))
-		channel_bit = channel + BP_APBH_CTRL0_CLKGATE_CHANNEL;
-	else
-		channel_bit = channel + 0;
-
-	writel(1 << channel_bit, apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
-
-	pchan->flags &= ~MXS_DMA_FLAGS_BUSY;
-	pchan->active_num = 0;
-	pchan->pending_num = 0;
-	list_splice_init(&pchan->active, &pchan->done);
-
 	return 0;
 }
 
@@ -254,11 +76,6 @@ static int mxs_dma_disable(int channel)
 static int mxs_dma_reset(int channel)
 {
 	struct apbh_dma *apbh = apbh_dma;
-	int ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
 
 	if (apbh_dma_is_imx23(apbh))
 		writel(1 << (channel + BP_APBH_CTRL0_RESET_CHANNEL),
@@ -270,30 +87,6 @@ static int mxs_dma_reset(int channel)
 	return 0;
 }
 
-/*
- * Enable or disable DMA interrupt.
- *
- * This function enables the given DMA channel to interrupt the CPU.
- */
-static int mxs_dma_enable_irq(int channel, int enable)
-{
-	struct apbh_dma *apbh = apbh_dma;
-	int ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
-
-	if (enable)
-		writel(1 << (channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN),
-			apbh->regs + HW_APBHX_CTRL1 + STMP_OFFSET_REG_SET);
-	else
-		writel(1 << (channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN),
-			apbh->regs + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR);
-
-	return 0;
-}
-
 /*
  * Clear DMA interrupt.
  *
@@ -303,11 +96,6 @@ static int mxs_dma_enable_irq(int channel, int enable)
 static int mxs_dma_ack_irq(int channel)
 {
 	struct apbh_dma *apbh = apbh_dma;
-	int ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
 
 	writel(1 << channel, apbh->regs + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR);
 	writel(1 << channel, apbh->regs + HW_APBHX_CTRL2 + STMP_OFFSET_REG_CLR);
@@ -315,230 +103,12 @@ static int mxs_dma_ack_irq(int channel)
 	return 0;
 }
 
-/*
- * Request to reserve a DMA channel
- */
-static int mxs_dma_request(int channel)
-{
-	struct mxs_dma_chan *pchan;
-
-	if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS))
-		return -EINVAL;
-
-	pchan = mxs_dma_channels + channel;
-	if ((pchan->flags & MXS_DMA_FLAGS_VALID) != MXS_DMA_FLAGS_VALID)
-		return -ENODEV;
-
-	if (pchan->flags & MXS_DMA_FLAGS_ALLOCATED)
-		return -EBUSY;
-
-	pchan->flags |= MXS_DMA_FLAGS_ALLOCATED;
-	pchan->active_num = 0;
-	pchan->pending_num = 0;
-
-	INIT_LIST_HEAD(&pchan->active);
-	INIT_LIST_HEAD(&pchan->done);
-
-	return 0;
-}
-
-/*
- * Release a DMA channel.
- *
- * This function releases a DMA channel from its current owner.
- *
- * The channel will NOT be released if it's marked "busy" (see
- * mxs_dma_enable()).
- */
-static int mxs_dma_release(int channel)
-{
-	struct mxs_dma_chan *pchan;
-	int ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
-
-	pchan = mxs_dma_channels + channel;
-
-	if (pchan->flags & MXS_DMA_FLAGS_BUSY)
-		return -EBUSY;
-
-	pchan->dev = 0;
-	pchan->active_num = 0;
-	pchan->pending_num = 0;
-	pchan->flags &= ~MXS_DMA_FLAGS_ALLOCATED;
-
-	return 0;
-}
-
-/*
- * Allocate DMA descriptor
- */
-struct mxs_dma_desc *mxs_dma_desc_alloc(void)
-{
-	struct mxs_dma_desc *pdesc;
-	dma_addr_t dma_address;
-
-	pdesc = dma_alloc_coherent(sizeof(struct mxs_dma_desc),
-				   &dma_address);
-
-	if (pdesc == NULL)
-		return NULL;
-
-	pdesc->address = dma_address;
-
-	return pdesc;
-};
-
-/*
- * Free DMA descriptor
- */
-void mxs_dma_desc_free(struct mxs_dma_desc *pdesc)
-{
-	if (pdesc == NULL)
-		return;
-
-	free(pdesc);
-}
-
-/*
- * Add a DMA descriptor to a channel.
- *
- * If the descriptor list for this channel is not empty, this function sets the
- * CHAIN bit and the NEXTCMD_ADDR fields in the last descriptor's DMA command so
- * it will chain to the new descriptor's command.
- *
- * Then, this function marks the new descriptor as "ready," adds it to the end
- * of the active descriptor list, and increments the count of pending
- * descriptors.
- *
- * The MXS platform DMA software imposes some rules on DMA commands to maintain
- * important invariants. These rules are NOT checked, but they must be carefully
- * applied by software that uses MXS DMA channels.
- *
- * Invariant:
- *     The DMA channel's hardware semaphore must reflect the number of DMA
- *     commands the hardware will process, but has not yet finished.
- *
- * Explanation:
- *     A DMA channel begins processing commands when its hardware semaphore is
- *     written with a value greater than zero, and it stops processing commands
- *     when the semaphore returns to zero.
- *
- *     When a channel finishes a DMA command, it will decrement its semaphore if
- *     the DECREMENT_SEMAPHORE bit is set in that command's flags bits.
- *
- *     In principle, it's not necessary for the DECREMENT_SEMAPHORE to be set,
- *     unless it suits the purposes of the software. For example, one could
- *     construct a series of five DMA commands, with the DECREMENT_SEMAPHORE
- *     bit set only in the last one. Then, setting the DMA channel's hardware
- *     semaphore to one would cause the entire series of five commands to be
- *     processed. However, this example would violate the invariant given above.
- *
- * Rule:
- *    ALL DMA commands MUST have the DECREMENT_SEMAPHORE bit set so that the DMA
- *    channel's hardware semaphore will be decremented EVERY time a command is
- *    processed.
- */
-int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc)
-{
-	struct mxs_dma_chan *pchan;
-	struct mxs_dma_desc *last;
-	int ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
-
-	pchan = mxs_dma_channels + channel;
-
-	pdesc->cmd.next = mxs_dma_cmd_address(pdesc);
-	pdesc->flags |= MXS_DMA_DESC_FIRST | MXS_DMA_DESC_LAST;
-
-	if (!list_empty(&pchan->active)) {
-		last = list_entry(pchan->active.prev, struct mxs_dma_desc,
-					node);
-
-		pdesc->flags &= ~MXS_DMA_DESC_FIRST;
-		last->flags &= ~MXS_DMA_DESC_LAST;
-
-		last->cmd.next = mxs_dma_cmd_address(pdesc);
-		last->cmd.data |= MXS_DMA_DESC_CHAIN;
-	}
-	pdesc->flags |= MXS_DMA_DESC_READY;
-	if (pdesc->flags & MXS_DMA_DESC_FIRST)
-		pchan->pending_num++;
-	list_add_tail(&pdesc->node, &pchan->active);
-
-	return ret;
-}
-
-/*
- * Clean up processed DMA descriptors.
- *
- * This function removes processed DMA descriptors from the "active" list. Pass
- * in a non-NULL list head to get the descriptors moved to your list. Pass NULL
- * to get the descriptors moved to the channel's "done" list. Descriptors on
- * the "done" list can be retrieved with mxs_dma_get_finished().
- *
- * This function marks the DMA channel as "not busy" if no unprocessed
- * descriptors remain on the "active" list.
- */
-static int mxs_dma_finish(int channel, struct list_head *head)
-{
-	int sem;
-	struct mxs_dma_chan *pchan;
-	struct list_head *p, *q;
-	struct mxs_dma_desc *pdesc;
-	int ret;
-
-	ret = mxs_dma_validate_chan(channel);
-	if (ret)
-		return ret;
-
-	pchan = mxs_dma_channels + channel;
-
-	sem = mxs_dma_read_semaphore(channel);
-	if (sem < 0)
-		return sem;
-
-	if (sem == pchan->active_num)
-		return 0;
-
-	list_for_each_safe(p, q, &pchan->active) {
-		if ((pchan->active_num) <= sem)
-			break;
-
-		pdesc = list_entry(p, struct mxs_dma_desc, node);
-		pdesc->flags &= ~MXS_DMA_DESC_READY;
-
-		if (head)
-			list_move_tail(p, head);
-		else
-			list_move_tail(p, &pchan->done);
-
-		if (pdesc->flags & MXS_DMA_DESC_LAST)
-			pchan->active_num--;
-	}
-
-	if (sem == 0)
-		pchan->flags &= ~MXS_DMA_FLAGS_BUSY;
-
-	return 0;
-}
-
 /*
  * Wait for DMA channel to complete
  */
 static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan)
 {
 	struct apbh_dma *apbh = apbh_dma;
-	int ret;
-
-	ret = mxs_dma_validate_chan(chan);
-	if (ret)
-		return ret;
 
 	while (--timeout) {
 		if (readl(apbh->regs + HW_APBHX_CTRL1) & (1 << chan))
@@ -546,38 +116,47 @@ static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan)
 		udelay(1);
 	}
 
-	if (timeout == 0) {
-		ret = -ETIMEDOUT;
-		mxs_dma_reset(chan);
-	}
+	if (!timeout)
+		return -ETIMEDOUT;
 
-	return ret;
+	return 0;
 }
 
 /*
  * Execute the DMA channel
  */
-int mxs_dma_go(int chan)
+int mxs_dma_go(int chan, struct mxs_dma_cmd *cmd, int ncmds)
 {
+	struct apbh_dma *apbh = apbh_dma;
 	uint32_t timeout = 10000;
-	int ret;
+	int i, ret, channel_bit;
+
+	ret = mxs_dma_validate_chan(chan);
+	if (ret)
+		return ret;
 
-	LIST_HEAD(tmp_desc_list);
+	for (i = 0; i < ncmds - 1; i++) {
+		cmd[i].next = (unsigned long)(&cmd[i + 1]);
+		cmd[i].data |= MXS_DMA_DESC_CHAIN;
+	}
 
-	mxs_dma_enable_irq(chan, 1);
-	mxs_dma_enable(chan);
+	if (apbh_dma_is_imx23(apbh)) {
+		writel(cmd, apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX23(chan));
+		writel(1, apbh->regs + HW_APBHX_CHn_SEMA_MX23(chan));
+		channel_bit = chan + BP_APBH_CTRL0_CLKGATE_CHANNEL;
+	} else {
+		writel(cmd, apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX28(chan));
+		writel(1, apbh->regs + HW_APBHX_CHn_SEMA_MX28(chan));
+		channel_bit = chan;
+	}
+	writel(1 << channel_bit, apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR);
 
 	/* Wait for DMA to finish. */
 	ret = mxs_dma_wait_complete(timeout, chan);
 
-	/* Clear out the descriptors we just ran. */
-	mxs_dma_finish(chan, &tmp_desc_list);
-
 	/* Shut the DMA channel down. */
 	mxs_dma_ack_irq(chan);
 	mxs_dma_reset(chan);
-	mxs_dma_enable_irq(chan, 0);
-	mxs_dma_disable(chan);
 
 	return ret;
 }
@@ -589,7 +168,6 @@ static int apbh_dma_probe(struct device_d *dev)
 {
 	struct resource *iores;
 	struct apbh_dma *apbh;
-	struct mxs_dma_chan *pchan;
 	enum mxs_dma_id id;
 	int ret, channel;
 
@@ -627,28 +205,11 @@ static int apbh_dma_probe(struct device_d *dev)
 		apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
 
 	for (channel = 0; channel < MXS_MAX_DMA_CHANNELS; channel++) {
-		pchan = mxs_dma_channels + channel;
-		pchan->flags = MXS_DMA_FLAGS_VALID;
-
-		ret = mxs_dma_request(channel);
-
-		if (ret) {
-			printf("MXS DMA: Can't acquire DMA channel %i\n",
-				channel);
-
-			goto err;
-		}
-
 		mxs_dma_reset(channel);
 		mxs_dma_ack_irq(channel);
 	}
 
 	return 0;
-
-err:
-	while (--channel >= 0)
-		mxs_dma_release(channel);
-	return ret;
 }
 
 static struct platform_device_id apbh_ids[] = {
diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index d711708ff2..9f53c437b7 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -102,7 +102,7 @@ struct mxs_nand_info {
 				loff_t to, struct mtd_oob_ops *ops);
 
 	/* DMA descriptors */
-	struct mxs_dma_desc	**desc;
+	struct mxs_dma_cmd	*desc;
 	uint32_t		desc_index;
 
 #define GPMI_ASYNC_EDO_ENABLED	(1 << 0)
@@ -118,16 +118,16 @@ static inline int mxs_nand_is_imx6(struct mxs_nand_info *info)
 	return info->type == GPMI_IMX6;
 }
 
-static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info)
+static struct mxs_dma_cmd *mxs_nand_get_dma_desc(struct mxs_nand_info *info)
 {
-	struct mxs_dma_desc *desc;
+	struct mxs_dma_cmd *desc;
 
 	if (info->desc_index >= MXS_NAND_DMA_DESCRIPTOR_COUNT) {
 		printf("MXS NAND: Too many DMA descriptors requested\n");
 		return NULL;
 	}
 
-	desc = info->desc[info->desc_index];
+	desc = &info->desc[info->desc_index];
 	info->desc_index++;
 
 	return desc;
@@ -136,12 +136,11 @@ static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info)
 static void mxs_nand_return_dma_descs(struct mxs_nand_info *info)
 {
 	int i;
-	struct mxs_dma_desc *desc;
+	struct mxs_dma_cmd *desc;
 
 	for (i = 0; i < info->desc_index; i++) {
-		desc = info->desc[i];
-		memset(desc, 0, sizeof(struct mxs_dma_desc));
-		desc->address = (dma_addr_t)desc;
+		desc = &info->desc[i];
+		memset(desc, 0, sizeof(struct mxs_dma_cmd));
 	}
 
 	info->desc_index = 0;
@@ -324,7 +323,7 @@ static int mxs_nand_wait_for_bch_complete(struct mxs_nand_info *nand_info)
 static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctrl)
 {
 	struct mxs_nand_info *nand_info = chip->priv;
-	struct mxs_dma_desc *d;
+	struct mxs_dma_cmd *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret;
 
@@ -364,15 +363,15 @@ static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctr
 
 	/* Compile the DMA descriptor -- a descriptor that sends command. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_CHAIN | MXS_DMA_DESC_DEC_SEM |
 		MXS_DMA_DESC_WAIT4END | (3 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
 		(nand_info->cmd_queue_len << MXS_DMA_DESC_BYTES_OFFSET);
 
-	d->cmd.address = (dma_addr_t)nand_info->cmd_buf;
+	d->address = (dma_addr_t)nand_info->cmd_buf;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
@@ -380,10 +379,8 @@ static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctr
 		GPMI_CTRL0_ADDRESS_INCREMENT |
 		nand_info->cmd_queue_len;
 
-	mxs_dma_desc_append(channel, d);
-
 	/* Execute the DMA chain. */
-	ret = mxs_dma_go(channel);
+	ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index);
 	if (ret)
 		printf("MXS NAND: Error sending command (%d)\n", ret);
 
@@ -479,7 +476,7 @@ static void mxs_nand_swap_block_mark(struct nand_chip *chip,
 static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
 {
 	struct mxs_nand_info *nand_info = chip->priv;
-	struct mxs_dma_desc *d;
+	struct mxs_dma_cmd *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret;
 
@@ -495,23 +492,21 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
 
 	/* Compile the DMA descriptor - a descriptor that reads data. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_DMA_WRITE | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
 		(1 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
 		(length << MXS_DMA_DESC_BYTES_OFFSET);
 
-	d->cmd.address = (dma_addr_t)nand_info->data_buf;
+	d->address = (dma_addr_t)nand_info->data_buf;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		length;
 
-	mxs_dma_desc_append(channel, d);
-
 	/*
 	 * A DMA descriptor that waits for the command to end and the chip to
 	 * become ready.
@@ -521,23 +516,21 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
 	 * did that and no one has re-thought it yet.
 	 */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_DEC_SEM |
 		MXS_DMA_DESC_WAIT4END | (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
 
-	d->cmd.address = 0;
+	d->address = 0;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
 
-	mxs_dma_desc_append(channel, d);
-
 	/* Execute the DMA chain. */
-	ret = mxs_dma_go(channel);
+	ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index);
 	if (ret) {
 		printf("MXS NAND: DMA read error\n");
 		goto rtn;
@@ -556,7 +549,7 @@ static void mxs_nand_write_buf(struct nand_chip *chip, const uint8_t *buf,
 				int length)
 {
 	struct mxs_nand_info *nand_info = chip->priv;
-	struct mxs_dma_desc *d;
+	struct mxs_dma_cmd *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret;
 
@@ -574,25 +567,23 @@ static void mxs_nand_write_buf(struct nand_chip *chip, const uint8_t *buf,
 
 	/* Compile the DMA descriptor - a descriptor that writes data. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
 		(4 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
 		(length << MXS_DMA_DESC_BYTES_OFFSET);
 
-	d->cmd.address = (dma_addr_t)nand_info->data_buf;
+	d->address = (dma_addr_t)nand_info->data_buf;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		length;
 
-	mxs_dma_desc_append(channel, d);
-
 	/* Execute the DMA chain. */
-	ret = mxs_dma_go(channel);
+	ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index);
 	if (ret)
 		printf("MXS NAND: DMA write error\n");
 
@@ -644,89 +635,81 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 				bool randomizer, int page)
 {
 	struct mxs_nand_info *nand_info = chip->priv;
-	struct mxs_dma_desc *d;
+	struct mxs_dma_cmd *d;
 	int ret;
 
 	/* Compile the DMA descriptor - wait for ready. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
 		MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END |
 		(1 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
 
-	d->cmd.address = 0;
+	d->address = 0;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
 
-	mxs_dma_desc_append(channel, d);
-
 	/* Compile the DMA descriptor - enable the BCH block and read. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
 		MXS_DMA_DESC_WAIT4END |	(6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
 
-	d->cmd.address = 0;
+	d->address = 0;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		readtotal;
-	d->cmd.pio_words[1] = 0;
-	d->cmd.pio_words[2] =
+	d->pio_words[1] = 0;
+	d->pio_words[2] =
 		GPMI_ECCCTRL_ENABLE_ECC |
 		GPMI_ECCCTRL_ECC_CMD_DECODE |
 		GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
-	d->cmd.pio_words[3] = readtotal;
-	d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
-	d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
+	d->pio_words[3] = readtotal;
+	d->pio_words[4] = (dma_addr_t)nand_info->data_buf;
+	d->pio_words[5] = (dma_addr_t)nand_info->oob_buf;
 
 	if (randomizer) {
-		d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
+		d->pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
 				       GPMI_ECCCTRL_RANDOMIZER_TYPE2;
-		d->cmd.pio_words[3] |= (page % 256) << 16;
+		d->pio_words[3] |= (page % 256) << 16;
 	}
 
-	mxs_dma_desc_append(channel, d);
-
 	/* Compile the DMA descriptor - disable the BCH block. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
 		MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END |
 		(3 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
 
-	d->cmd.address = 0;
+	d->address = 0;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
 		readtotal;
-	d->cmd.pio_words[1] = 0;
-	d->cmd.pio_words[2] = 0;
-
-	mxs_dma_desc_append(channel, d);
+	d->pio_words[1] = 0;
+	d->pio_words[2] = 0;
 
 	/* Compile the DMA descriptor - deassert the NAND lock and interrupt. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_DEC_SEM;
 
-	d->cmd.address = 0;
-
-	mxs_dma_desc_append(channel, d);
+	d->address = 0;
 
 	/* Execute the DMA chain. */
-	ret = mxs_dma_go(channel);
+	ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index);
 	if (ret) {
 		dev_err(nand_info->dev, "MXS NAND: DMA read error (ecc)\n");
 		goto out;
@@ -891,7 +874,7 @@ static int mxs_nand_ecc_write_page(struct nand_chip *chip, const uint8_t *buf,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct mxs_nand_info *nand_info = chip->priv;
-	struct mxs_dma_desc *d;
+	struct mxs_dma_cmd *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret = 0;
 
@@ -905,31 +888,29 @@ static int mxs_nand_ecc_write_page(struct nand_chip *chip, const uint8_t *buf,
 
 	/* Compile the DMA descriptor - write data. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data =
+	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
 		(6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
 
-	d->cmd.address = 0;
+	d->address = 0;
 
-	d->cmd.pio_words[0] =
+	d->pio_words[0] =
 		GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA;
-	d->cmd.pio_words[1] = 0;
-	d->cmd.pio_words[2] =
+	d->pio_words[1] = 0;
+	d->pio_words[2] =
 		GPMI_ECCCTRL_ENABLE_ECC |
 		GPMI_ECCCTRL_ECC_CMD_ENCODE |
 		GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
-	d->cmd.pio_words[3] = (mtd->writesize + mtd->oobsize);
-	d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
-	d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
-
-	mxs_dma_desc_append(channel, d);
+	d->pio_words[3] = (mtd->writesize + mtd->oobsize);
+	d->pio_words[4] = (dma_addr_t)nand_info->data_buf;
+	d->pio_words[5] = (dma_addr_t)nand_info->oob_buf;
 
 	/* Execute the DMA chain. */
-	ret = mxs_dma_go(channel);
+	ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index);
 	if (ret) {
 		printf("MXS NAND: DMA write error\n");
 		goto rtn;
@@ -1242,7 +1223,7 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size)
 	struct nand_chip *chip;
 	struct mtd_info *mtd = mxs_nand_mtd;
 	struct mxs_nand_info *nand_info;
-	struct mxs_dma_desc *d;
+	struct mxs_dma_cmd *d;
 	uint32_t channel;
 	int ret = 0;
 	int page;
@@ -1273,24 +1254,24 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size)
 
 	/* Compile the DMA descriptor - write data. */
 	d = mxs_nand_get_dma_desc(nand_info);
-	d->cmd.data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
+	d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
 		      MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
 		      (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
 
-	d->cmd.address = 0;
+	d->address = 0;
 
-	d->cmd.pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
+	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 			      GPMI_CTRL0_WORD_LENGTH |
 			      GPMI_CTRL0_ADDRESS_NAND_DATA;
-	d->cmd.pio_words[1] = 0;
-	d->cmd.pio_words[2] = GPMI_ECCCTRL_ENABLE_ECC |
+	d->pio_words[1] = 0;
+	d->pio_words[2] = GPMI_ECCCTRL_ENABLE_ECC |
 			      GPMI_ECCCTRL_ECC_CMD_ENCODE |
 			      GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
-	d->cmd.pio_words[3] = BCH62_PAGESIZE;
-	d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
-	d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
+	d->pio_words[3] = BCH62_PAGESIZE;
+	d->pio_words[4] = (dma_addr_t)nand_info->data_buf;
+	d->pio_words[5] = (dma_addr_t)nand_info->oob_buf;
 
-	d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
+	d->pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
 			       GPMI_ECCCTRL_RANDOMIZER_TYPE2;
 	/*
 	 * Write NAND page number needed to be randomized
@@ -1299,12 +1280,10 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size)
 	 * The value is between 0-255. For additional details
 	 * check 9.6.6.4 of i.MX7D Applications Processor reference
 	 */
-	d->cmd.pio_words[3] |= (page % 256) << 16;
-
-	mxs_dma_desc_append(channel, d);
+	d->pio_words[3] |= (page % 256) << 16;
 
 	/* Execute the DMA chain. */
-	ret = mxs_dma_go(channel);
+	ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index);
 	if (ret) {
 		dev_err(nand_info->dev, "MXS NAND: DMA write error: %d\n", ret);
 		goto out;
@@ -1416,20 +1395,13 @@ static int mxs_nand_hw_init(struct mxs_nand_info *info)
 {
 	void __iomem *gpmi_regs = info->io_base;
 	void __iomem *bch_regs = info->bch_base;
-	int i = 0, ret;
+	int ret;
 	u32 val;
 
-	info->desc = malloc(sizeof(struct mxs_dma_desc *) *
-				MXS_NAND_DMA_DESCRIPTOR_COUNT);
+	info->desc = dma_alloc_coherent(sizeof(struct mxs_dma_cmd) * MXS_NAND_DMA_DESCRIPTOR_COUNT,
+				   DMA_ADDRESS_BROKEN);
 	if (!info->desc)
-		goto err1;
-
-	/* Allocate the DMA descriptors. */
-	for (i = 0; i < MXS_NAND_DMA_DESCRIPTOR_COUNT; i++) {
-		info->desc[i] = mxs_dma_desc_alloc();
-		if (!info->desc[i])
-			goto err2;
-	}
+		return -ENOMEM;
 
 	/* Reset the GPMI block. */
 	ret = stmp_reset_block(gpmi_regs + GPMI_CTRL0, 0);
@@ -1456,14 +1428,6 @@ static int mxs_nand_hw_init(struct mxs_nand_info *info)
 	writel(val, gpmi_regs + GPMI_CTRL1);
 
 	return 0;
-
-err2:
-	free(info->desc);
-err1:
-	for (--i; i >= 0; i--)
-		mxs_dma_desc_free(info->desc[i]);
-	printf("MXS NAND: Unable to allocate DMA descriptors\n");
-	return -ENOMEM;
 }
 
 static void mxs_nand_probe_dt(struct device_d *dev, struct mxs_nand_info *nand_info)
diff --git a/include/dma/apbh-dma.h b/include/dma/apbh-dma.h
index f10bb6f615..e5b5825925 100644
--- a/include/dma/apbh-dma.h
+++ b/include/dma/apbh-dma.h
@@ -88,53 +88,7 @@ struct mxs_dma_cmd {
 	unsigned long		pio_words[APBH_DMA_PIO_WORDS];
 };
 
-/*
- * MXS DMA command descriptor.
- *
- * This structure incorporates an MXS DMA hardware command structure, along
- * with metadata.
- */
-#define	MXS_DMA_DESC_FIRST	(1 << 0)
-#define	MXS_DMA_DESC_LAST	(1 << 1)
-#define	MXS_DMA_DESC_READY	(1 << 31)
-
-struct mxs_dma_desc {
-	struct mxs_dma_cmd	cmd;
-	unsigned int		flags;
-	dma_addr_t		address;
-	void			*buffer;
-	struct list_head	node;
-};
-
-/**
- * MXS DMA channel
- *
- * This structure represents a single DMA channel. The MXS platform code
- * maintains an array of these structures to represent every DMA channel in the
- * system (see mxs_dma_channels).
- */
-#define	MXS_DMA_FLAGS_IDLE	0
-#define	MXS_DMA_FLAGS_BUSY	(1 << 0)
-#define	MXS_DMA_FLAGS_FREE	0
-#define	MXS_DMA_FLAGS_ALLOCATED	(1 << 16)
-#define	MXS_DMA_FLAGS_VALID	(1 << 31)
-
-struct mxs_dma_chan {
-	const char *name;
-	unsigned long dev;
-	struct mxs_dma_device *dma;
-	unsigned int flags;
-	unsigned int active_num;
-	unsigned int pending_num;
-	struct list_head active;
-	struct list_head done;
-};
-
-struct mxs_dma_desc *mxs_dma_desc_alloc(void);
-void mxs_dma_desc_free(struct mxs_dma_desc *);
-int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc);
-
-int mxs_dma_go(int chan);
+int mxs_dma_go(int chan, struct mxs_dma_cmd *cmd, int ncmds);
 int mxs_dma_init(void);
 
 #endif	/* __DMA_H__ */
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 05/14] dma: apbh-dma: unify register defines
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (3 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 04/14] dma: apbh-dma: Simplify code Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-01 15:30 ` [PATCH 06/14] ARM: i.MX: xload-gpmi-nand: refactor for more SoC support Sascha Hauer
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

We have different register defines for the apbh-dma controller. One set
is used in the regular driver, the other one in the xload code. Move the
register defines to a common place and unify their names.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/xload-gpmi-nand.c | 171 ++++++++++------------------
 drivers/dma/apbh_dma.c              |  27 -----
 drivers/mtd/nand/nand_mxs.c         |  24 ++--
 include/dma/apbh-dma.h              |  47 ++++++--
 4 files changed, 106 insertions(+), 163 deletions(-)

diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index ffbd5c22e3..165c4c5b85 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -14,41 +14,7 @@
 #include <soc/imx/gpmi-nand.h>
 #include <mach/imx6-regs.h>
 #include <mach/clock-imx6.h>
-
-/*
- * MXS DMA hardware command.
- *
- * This structure describes the in-memory layout of an entire DMA command,
- * including space for the maximum number of PIO accesses. See the appropriate
- * reference manual for a detailed description of what these fields mean to the
- * DMA hardware.
- */
-#define	DMACMD_COMMAND_DMA_WRITE	0x1
-#define	DMACMD_COMMAND_DMA_READ		0x2
-#define	DMACMD_COMMAND_DMA_SENSE	0x3
-#define	DMACMD_CHAIN			(1 << 2)
-#define	DMACMD_IRQ			(1 << 3)
-#define	DMACMD_NAND_LOCK		(1 << 4)
-#define	DMACMD_NAND_WAIT_4_READY	(1 << 5)
-#define	DMACMD_DEC_SEM			(1 << 6)
-#define	DMACMD_WAIT4END			(1 << 7)
-#define	DMACMD_HALT_ON_TERMINATE	(1 << 8)
-#define	DMACMD_TERMINATE_FLUSH		(1 << 9)
-#define	DMACMD_PIO_WORDS(words)		((words) << 12)
-#define	DMACMD_XFER_COUNT(x)		((x) << 16)
-
-struct mxs_dma_cmd {
-	unsigned long		next;
-	unsigned long		data;
-	unsigned long		address;
-#define	APBH_DMA_PIO_WORDS	6
-	unsigned long		pio_words[APBH_DMA_PIO_WORDS];
-};
-
-enum mxs_dma_id {
-	IMX23_DMA,
-	IMX28_DMA,
-};
+#include <dma/apbh-dma.h>
 
 struct apbh_dma {
 	void __iomem *regs;
@@ -61,25 +27,6 @@ struct mxs_dma_chan {
 	struct apbh_dma *apbh;
 };
 
-#define	HW_APBHX_CTRL0				0x000
-#define	BM_APBH_CTRL0_APB_BURST8_EN		(1 << 29)
-#define	BM_APBH_CTRL0_APB_BURST_EN		(1 << 28)
-#define	BP_APBH_CTRL0_CLKGATE_CHANNEL		8
-#define	BP_APBH_CTRL0_RESET_CHANNEL		16
-#define	HW_APBHX_CTRL1				0x010
-#define	BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN	16
-#define	HW_APBHX_CTRL2				0x020
-#define	HW_APBHX_CHANNEL_CTRL			0x030
-#define	BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL	16
-#define	BP_APBHX_VERSION_MAJOR			24
-#define	HW_APBHX_CHn_NXTCMDAR_MX23(n)		(0x050 + (n) * 0x70)
-#define	HW_APBHX_CHn_NXTCMDAR_MX28(n)		(0x110 + (n) * 0x70)
-#define	HW_APBHX_CHn_SEMA_MX23(n)		(0x080 + (n) * 0x70)
-#define	HW_APBHX_CHn_SEMA_MX28(n)		(0x140 + (n) * 0x70)
-#define	NAND_ONFI_CRC_BASE			0x4f4e
-
-#define apbh_dma_is_imx23(aphb) ((apbh)->id == IMX23_DMA)
-
 /* udelay() is not available in PBL, need to improvise */
 static void __udelay(int us)
 {
@@ -168,7 +115,7 @@ static int mxs_dma_run(struct mxs_dma_chan *pchan, struct mxs_dma_cmd *pdesc,
 	/* chain descriptors */
 	for (i = 0; i < num - 1; i++) {
 		pdesc[i].next = (unsigned long)(&pdesc[i + 1]);
-		pdesc[i].data |= DMACMD_CHAIN;
+		pdesc[i].data |= MXS_DMA_DESC_CHAIN;
 	}
 
 	writel(1 << (pchan->channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN),
@@ -313,10 +260,10 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 	if ((max_pagenum - 1) >= SZ_64K)
 		cmd_buf[cmd_queue_len++] = pagenum >> 16;
 
-	d->data = DMACMD_COMMAND_DMA_READ |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(cmd_queue_len);
+	d->data = MXS_DMA_DESC_COMMAND_DMA_READ |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(cmd_queue_len);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -333,10 +280,10 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 
 	cmd_buf[cmd_queue_len++] = NAND_CMD_READSTART;
 
-	d->data = DMACMD_COMMAND_DMA_READ |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(cmd_queue_len);
+	d->data = MXS_DMA_DESC_COMMAND_DMA_READ |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(cmd_queue_len);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -347,10 +294,10 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 
 	/* Compile DMA descriptor - wait for ready. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_CHAIN |
-		DMACMD_NAND_WAIT_4_READY |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(2);
+	d->data = MXS_DMA_DESC_CHAIN |
+		MXS_DMA_DESC_NAND_WAIT_4_READY |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(2);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -360,10 +307,10 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 	if (raw) {
 		/* Compile DMA descriptor - read. */
 		d = &info->desc[descnum++];
-		d->data = DMACMD_WAIT4END |
-			DMACMD_PIO_WORDS(1) |
-			DMACMD_XFER_COUNT(writesize + oobsize) |
-			DMACMD_COMMAND_DMA_WRITE;
+		d->data = MXS_DMA_DESC_WAIT4END |
+			MXS_DMA_DESC_PIO_WORDS(1) |
+			MXS_DMA_DESC_XFER_COUNT(writesize + oobsize) |
+			MXS_DMA_DESC_COMMAND_DMA_WRITE;
 		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 			GPMI_CTRL0_WORD_LENGTH |
 			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
@@ -373,7 +320,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 	} else {
 		/* Compile DMA descriptor - enable the BCH block and read. */
 		d = &info->desc[descnum++];
-		d->data = DMACMD_WAIT4END | DMACMD_PIO_WORDS(6);
+		d->data = MXS_DMA_DESC_WAIT4END | MXS_DMA_DESC_PIO_WORDS(6);
 		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 			GPMI_CTRL0_WORD_LENGTH |
 			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
@@ -389,9 +336,9 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 
 		/* Compile DMA descriptor - disable the BCH block. */
 		d = &info->desc[descnum++];
-		d->data = DMACMD_NAND_WAIT_4_READY |
-			DMACMD_WAIT4END |
-			DMACMD_PIO_WORDS(3);
+		d->data = MXS_DMA_DESC_NAND_WAIT_4_READY |
+			MXS_DMA_DESC_WAIT4END |
+			MXS_DMA_DESC_PIO_WORDS(3);
 		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 			GPMI_CTRL0_WORD_LENGTH |
 			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
@@ -401,7 +348,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 
 	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_IRQ | DMACMD_DEC_SEM;
+	d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM;
 
 	/* Execute the DMA chain. */
 	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
@@ -460,10 +407,10 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
 	d->address = (dma_addr_t)(cmd_buf);
 	cmd_buf[cmd_queue_len++] = NAND_CMD_STATUS;
 
-	d->data = DMACMD_COMMAND_DMA_READ |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(cmd_queue_len);
+	d->data = MXS_DMA_DESC_COMMAND_DMA_READ |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(cmd_queue_len);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -474,10 +421,10 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
 
 	/* Compile DMA descriptor - read. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(1) |
-		DMACMD_COMMAND_DMA_WRITE;
+	d->data = MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(1) |
+		MXS_DMA_DESC_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
@@ -487,7 +434,7 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
 
 	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_IRQ | DMACMD_DEC_SEM;
+	d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM;
 
 	/* Execute the DMA chain. */
 	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
@@ -518,10 +465,10 @@ static int mxs_nand_reset(struct mxs_nand_info *info, void *databuf)
 	d->address = (dma_addr_t)(cmd_buf);
 	cmd_buf[cmd_queue_len++] = NAND_CMD_RESET;
 
-	d->data = DMACMD_COMMAND_DMA_READ |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(cmd_queue_len);
+	d->data = MXS_DMA_DESC_COMMAND_DMA_READ |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(cmd_queue_len);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -532,7 +479,7 @@ static int mxs_nand_reset(struct mxs_nand_info *info, void *databuf)
 
 	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_IRQ | DMACMD_DEC_SEM;
+	d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM;
 
 	/* Execute the DMA chain. */
 	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
@@ -590,10 +537,10 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 	cmd_buf[cmd_queue_len++] = NAND_CMD_PARAM;
 	cmd_buf[cmd_queue_len++] = 0x00;
 
-	d->data = DMACMD_COMMAND_DMA_READ |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(cmd_queue_len);
+	d->data = MXS_DMA_DESC_COMMAND_DMA_READ |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(cmd_queue_len);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -604,10 +551,10 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 
 	/* Compile DMA descriptor - wait for ready. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_CHAIN |
-		DMACMD_NAND_WAIT_4_READY |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(2);
+	d->data = MXS_DMA_DESC_CHAIN |
+		MXS_DMA_DESC_NAND_WAIT_4_READY |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(2);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -616,10 +563,10 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 
 	/* Compile DMA descriptor - read. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(sizeof(struct nand_onfi_params)) |
-		DMACMD_COMMAND_DMA_WRITE;
+	d->data = MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(sizeof(struct nand_onfi_params)) |
+		MXS_DMA_DESC_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
@@ -629,7 +576,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
 
 	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_IRQ | DMACMD_DEC_SEM;
+	d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM;
 
 	/* Execute the DMA chain. */
 	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
@@ -687,10 +634,10 @@ static int mxs_nand_read_id(struct mxs_nand_info *info, u8 adr, void *databuf, s
 	cmd_buf[cmd_queue_len++] = NAND_CMD_READID;
 	cmd_buf[cmd_queue_len++] = adr;
 
-	d->data = DMACMD_COMMAND_DMA_READ |
-		DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(cmd_queue_len);
+	d->data = MXS_DMA_DESC_COMMAND_DMA_READ |
+		MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(cmd_queue_len);
 
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
 		GPMI_CTRL0_WORD_LENGTH |
@@ -701,10 +648,10 @@ static int mxs_nand_read_id(struct mxs_nand_info *info, u8 adr, void *databuf, s
 
 	/* Compile DMA descriptor - read. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_WAIT4END |
-		DMACMD_PIO_WORDS(1) |
-		DMACMD_XFER_COUNT(len) |
-		DMACMD_COMMAND_DMA_WRITE;
+	d->data = MXS_DMA_DESC_WAIT4END |
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(len) |
+		MXS_DMA_DESC_COMMAND_DMA_WRITE;
 	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
 		GPMI_CTRL0_WORD_LENGTH |
 		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
@@ -714,7 +661,7 @@ static int mxs_nand_read_id(struct mxs_nand_info *info, u8 adr, void *databuf, s
 
 	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
 	d = &info->desc[descnum++];
-	d->data = DMACMD_IRQ | DMACMD_DEC_SEM;
+	d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM;
 
 	/* Execute the DMA chain. */
 	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c
index e93bffd595..767c095314 100644
--- a/drivers/dma/apbh_dma.c
+++ b/drivers/dma/apbh_dma.c
@@ -24,39 +24,12 @@
 #include <init.h>
 #include <io.h>
 
-
-#define HW_APBHX_CTRL0				0x000
-#define BM_APBH_CTRL0_APB_BURST8_EN		(1 << 29)
-#define BM_APBH_CTRL0_APB_BURST_EN		(1 << 28)
-#define BP_APBH_CTRL0_CLKGATE_CHANNEL		8
-#define BP_APBH_CTRL0_RESET_CHANNEL		16
-#define HW_APBHX_CTRL1				0x010
-#define	BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN	16
-#define HW_APBHX_CTRL2				0x020
-#define HW_APBHX_CHANNEL_CTRL			0x030
-#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL	16
-#define BP_APBHX_VERSION_MAJOR			24
-#define HW_APBHX_CHn_NXTCMDAR_MX23(n)		(0x050 + (n) * 0x70)
-#define HW_APBHX_CHn_NXTCMDAR_MX28(n)		(0x110 + (n) * 0x70)
-#define HW_APBHX_CHn_SEMA_MX23(n)		(0x080 + (n) * 0x70)
-#define HW_APBHX_CHn_SEMA_MX28(n)		(0x140 + (n) * 0x70)
-#define	BM_APBHX_CHn_SEMA_PHORE			(0xff << 16)
-#define	BP_APBHX_CHn_SEMA_PHORE			16
-
-enum mxs_dma_id {
-	UNKNOWN_DMA_ID,
-	IMX23_DMA,
-	IMX28_DMA,
-};
-
 struct apbh_dma {
 	void __iomem *regs;
 	struct clk *clk;
 	enum mxs_dma_id id;
 };
 
-#define apbh_dma_is_imx23(aphb) ((apbh)->id == IMX23_DMA)
-
 static struct apbh_dma *apbh_dma;
 
 /*
diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 9f53c437b7..b162c23743 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -366,8 +366,8 @@ static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctr
 	d->data =
 		MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_CHAIN | MXS_DMA_DESC_DEC_SEM |
-		MXS_DMA_DESC_WAIT4END | (3 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
-		(nand_info->cmd_queue_len << MXS_DMA_DESC_BYTES_OFFSET);
+		MXS_DMA_DESC_WAIT4END | MXS_DMA_DESC_PIO_WORDS(3) |
+		MXS_DMA_DESC_XFER_COUNT(nand_info->cmd_queue_len);
 
 	d->address = (dma_addr_t)nand_info->cmd_buf;
 
@@ -495,8 +495,8 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
 	d->data =
 		MXS_DMA_DESC_COMMAND_DMA_WRITE | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
-		(1 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
-		(length << MXS_DMA_DESC_BYTES_OFFSET);
+		MXS_DMA_DESC_PIO_WORDS(1) |
+		MXS_DMA_DESC_XFER_COUNT(length);
 
 	d->address = (dma_addr_t)nand_info->data_buf;
 
@@ -519,7 +519,7 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
 	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_DEC_SEM |
-		MXS_DMA_DESC_WAIT4END | (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+		MXS_DMA_DESC_WAIT4END | MXS_DMA_DESC_PIO_WORDS(4);
 
 	d->address = 0;
 
@@ -570,8 +570,8 @@ static void mxs_nand_write_buf(struct nand_chip *chip, const uint8_t *buf,
 	d->data =
 		MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
-		(4 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
-		(length << MXS_DMA_DESC_BYTES_OFFSET);
+		MXS_DMA_DESC_PIO_WORDS(4) |
+		MXS_DMA_DESC_XFER_COUNT(length);
 
 	d->address = (dma_addr_t)nand_info->data_buf;
 
@@ -643,7 +643,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
 		MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END |
-		(1 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+		MXS_DMA_DESC_PIO_WORDS(1);
 
 	d->address = 0;
 
@@ -657,7 +657,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 	d = mxs_nand_get_dma_desc(nand_info);
 	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
-		MXS_DMA_DESC_WAIT4END |	(6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+		MXS_DMA_DESC_WAIT4END |	MXS_DMA_DESC_PIO_WORDS(6);
 
 	d->address = 0;
 
@@ -687,7 +687,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
 		MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END |
-		(3 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+		MXS_DMA_DESC_PIO_WORDS(3);
 
 	d->address = 0;
 
@@ -891,7 +891,7 @@ static int mxs_nand_ecc_write_page(struct nand_chip *chip, const uint8_t *buf,
 	d->data =
 		MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
 		MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
-		(6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+		MXS_DMA_DESC_PIO_WORDS(6);
 
 	d->address = 0;
 
@@ -1256,7 +1256,7 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size)
 	d = mxs_nand_get_dma_desc(nand_info);
 	d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
 		      MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
-		      (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+		      MXS_DMA_DESC_PIO_WORDS(6);
 
 	d->address = 0;
 
diff --git a/include/dma/apbh-dma.h b/include/dma/apbh-dma.h
index e5b5825925..4584b504c2 100644
--- a/include/dma/apbh-dma.h
+++ b/include/dma/apbh-dma.h
@@ -30,6 +30,31 @@
 
 #define MXS_DMA_ALIGNMENT	32
 
+#define	HW_APBHX_CTRL0				0x000
+#define	BM_APBH_CTRL0_APB_BURST8_EN		BIT(29)
+#define	BM_APBH_CTRL0_APB_BURST_EN		BIT(28)
+#define	BP_APBH_CTRL0_CLKGATE_CHANNEL		8
+#define	BP_APBH_CTRL0_RESET_CHANNEL		16
+#define	HW_APBHX_CTRL1				0x010
+#define	BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN	16
+#define	HW_APBHX_CTRL2				0x020
+#define	HW_APBHX_CHANNEL_CTRL			0x030
+#define	BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL	16
+#define	BP_APBHX_VERSION_MAJOR			24
+#define	HW_APBHX_CHn_NXTCMDAR_MX23(n)		(0x050 + (n) * 0x70)
+#define	HW_APBHX_CHn_NXTCMDAR_MX28(n)		(0x110 + (n) * 0x70)
+#define	HW_APBHX_CHn_SEMA_MX23(n)		(0x080 + (n) * 0x70)
+#define	HW_APBHX_CHn_SEMA_MX28(n)		(0x140 + (n) * 0x70)
+#define	NAND_ONFI_CRC_BASE			0x4f4e
+
+enum mxs_dma_id {
+	UNKNOWN_DMA_ID,
+	IMX23_DMA,
+	IMX28_DMA,
+};
+
+#define apbh_dma_is_imx23(aphb) ((apbh)->id == IMX23_DMA)
+
 /*
  * MXS DMA channels
  */
@@ -64,18 +89,16 @@ enum {
 #define	MXS_DMA_DESC_COMMAND_DMA_WRITE	0x1
 #define	MXS_DMA_DESC_COMMAND_DMA_READ	0x2
 #define	MXS_DMA_DESC_COMMAND_DMA_SENSE	0x3
-#define	MXS_DMA_DESC_CHAIN		(1 << 2)
-#define	MXS_DMA_DESC_IRQ		(1 << 3)
-#define	MXS_DMA_DESC_NAND_LOCK		(1 << 4)
-#define	MXS_DMA_DESC_NAND_WAIT_4_READY	(1 << 5)
-#define	MXS_DMA_DESC_DEC_SEM		(1 << 6)
-#define	MXS_DMA_DESC_WAIT4END		(1 << 7)
-#define	MXS_DMA_DESC_HALT_ON_TERMINATE	(1 << 8)
-#define	MXS_DMA_DESC_TERMINATE_FLUSH	(1 << 9)
-#define	MXS_DMA_DESC_PIO_WORDS_MASK	(0xf << 12)
-#define	MXS_DMA_DESC_PIO_WORDS_OFFSET	12
-#define	MXS_DMA_DESC_BYTES_MASK		(0xffff << 16)
-#define	MXS_DMA_DESC_BYTES_OFFSET	16
+#define	MXS_DMA_DESC_CHAIN		BIT(2)
+#define	MXS_DMA_DESC_IRQ		BIT(3)
+#define	MXS_DMA_DESC_NAND_LOCK		BIT(4)
+#define	MXS_DMA_DESC_NAND_WAIT_4_READY	BIT(5)
+#define	MXS_DMA_DESC_DEC_SEM		BIT(6)
+#define	MXS_DMA_DESC_WAIT4END		BIT(7)
+#define	MXS_DMA_DESC_HALT_ON_TERMINATE	BIT(8)
+#define	MXS_DMA_DESC_TERMINATE_FLUSH	BIT(9)
+#define	MXS_DMA_DESC_PIO_WORDS(words)	((words) << 12)
+#define	MXS_DMA_DESC_XFER_COUNT(x)	((x) << 16)
 
 struct mxs_dma_cmd {
 	unsigned long		next;
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 06/14] ARM: i.MX: xload-gpmi-nand: refactor for more SoC support
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (4 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 05/14] dma: apbh-dma: unify register defines Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-01 15:30 ` [PATCH 07/14] imx-bbu-nand-fcb: pull printing debug info out of get_fcb() Sascha Hauer
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List; +Cc: Ahmad Fatoum

From: Ahmad Fatoum <a.fatoum@pengutronix.de>

The code hardcodes i.MX6 addresses, which needs to be factored out for
use in other SoCs' startup. Do this by creating a new imx_nand_params
to hold these information and passing it into the now more generic
code.

No functional change intended. Untested as I got no i.MX6 directly
booting from NAND.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imx6-regs.h |  2 +
 arch/arm/mach-imx/xload-gpmi-nand.c        | 76 ++++++++++++----------
 2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h
index 35f03036cb..39e2751533 100644
--- a/arch/arm/mach-imx/include/mach/imx6-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx6-regs.h
@@ -3,7 +3,9 @@
 #ifndef __MACH_IMX6_REGS_H
 #define __MACH_IMX6_REGS_H
 
+#define MX6_APBH_BASE_ADDR		0x00110000
 #define MX6_GPMI_BASE_ADDR		0x00112000
+#define MX6_BCH_BASE_ADDR		0x00114000
 
 #define MX6_FAST1_BASE_ADDR		0x00c00000
 #define MX6_FAST2_BASE_ADDR		0x00b00000
diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index 165c4c5b85..a7398cc26a 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -999,49 +999,44 @@ static int read_firmware(struct mxs_nand_info *info, int startpage,
 	return 0;
 }
 
-static int __maybe_unused imx6_nand_load_image(void *cmdbuf, void *descs,
-	void *databuf, void *dest, int len)
+struct imx_nand_params {
+	struct mxs_nand_info info;
+	struct apbh_dma apbh;
+	void *sdram;
+};
+
+static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
+					       void *databuf, void *dest, int len)
 {
-	struct mxs_nand_info info = {
-		.io_base = (void *)0x00112000,
-		.bch_base = (void *)0x00114000,
-	};
-	struct apbh_dma apbh = {
-		.id = IMX28_DMA,
-		.regs = (void *)0x00110000,
-	};
+	struct mxs_nand_info *info = &params->info;
 	struct mxs_dma_chan pchan = {
 		.channel = 0, /* MXS: MXS_DMA_CHANNEL_AHB_APBH_GPMI0 */
-		.apbh = &apbh,
+		.apbh = &params->apbh,
 	};
 	int ret;
 	struct fcb_block *fcb;
 
-	info.dma_channel = &pchan;
+	info->dma_channel = &pchan;
 
 	pr_debug("cmdbuf: 0x%p descs: 0x%p databuf: 0x%p dest: 0x%p\n",
-			cmdbuf, descs, databuf, dest);
-
-	/* Command buffers */
-	info.cmd_buf = cmdbuf;
-	info.desc = descs;
+			info->cmd_buf, info->desc, databuf, dest);
 
-	ret = mxs_nand_get_info(&info, databuf);
+	ret = mxs_nand_get_info(info, databuf);
 	if (ret)
 		return ret;
 
-	ret = get_fcb(&info, databuf);
+	ret = get_fcb(info, databuf);
 	if (ret)
 		return ret;
 
-	fcb = &info.fcb;
+	fcb = &info->fcb;
 
-	get_dbbt(&info, databuf);
+	get_dbbt(info, databuf);
 
-	ret = read_firmware(&info, fcb->Firmware1_startingPage, dest, len);
+	ret = read_firmware(info, fcb->Firmware1_startingPage, dest, len);
 	if (ret) {
 		pr_err("Failed to read firmware1, trying firmware2\n");
-		ret = read_firmware(&info, fcb->Firmware2_startingPage,
+		ret = read_firmware(info, fcb->Firmware2_startingPage,
 			dest, len);
 		if (ret) {
 			pr_err("Failed to also read firmware2\n");
@@ -1052,24 +1047,21 @@ static int __maybe_unused imx6_nand_load_image(void *cmdbuf, void *descs,
 	return 0;
 }
 
-int imx6_nand_start_image(void)
+static int imx_nand_start_image(struct imx_nand_params *params)
 {
+	struct mxs_nand_info *info = &params->info;
 	int ret;
-	void *sdram = (void *)0x10000000;
 	void __noreturn (*bb)(void);
-	void *cmdbuf, *databuf, *descs;
+	void *databuf;
 
-	cmdbuf = sdram;
-	descs = sdram + MXS_NAND_COMMAND_BUFFER_SIZE;
-	databuf = descs +
+	/* Command buffers */
+	info->cmd_buf = params->sdram;
+	info->desc = params->sdram + MXS_NAND_COMMAND_BUFFER_SIZE;
+	databuf = info->desc +
 		sizeof(struct mxs_dma_cmd) * MXS_NAND_DMA_DESCRIPTOR_COUNT;
 	bb = (void *)PAGE_ALIGN((unsigned long)databuf + SZ_8K);
 
-	/* Apply ERR007117 workaround */
-	imx6_errata_007117_enable();
-
-	ret = imx6_nand_load_image(cmdbuf, descs, databuf,
-		bb, imx_image_size());
+	ret = imx6_nand_load_image(params, databuf, bb, imx_image_size());
 	if (ret) {
 		pr_err("Loading image failed: %d\n", ret);
 		return ret;
@@ -1082,3 +1074,19 @@ int imx6_nand_start_image(void)
 
 	bb();
 }
+
+int imx6_nand_start_image(void)
+{
+	static struct imx_nand_params params = {
+		.info.io_base = IOMEM(MX6_GPMI_BASE_ADDR),
+		.info.bch_base = IOMEM(MX6_BCH_BASE_ADDR),
+		.apbh.regs = IOMEM(MX6_APBH_BASE_ADDR),
+		.apbh.id = IMX28_DMA,
+		.sdram = (void *)MX6_MMDC_PORT01_BASE_ADDR,
+	};
+
+	/* Apply ERR007117 workaround */
+	imx6_errata_007117_enable();
+
+	return imx_nand_start_image(&params);
+}
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 07/14] imx-bbu-nand-fcb: pull printing debug info out of get_fcb()
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (5 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 06/14] ARM: i.MX: xload-gpmi-nand: refactor for more SoC support Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-01 15:30 ` [PATCH 08/14] ARM: i.MX: xload nand: Pull ECC status checking out of read page Sascha Hauer
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

get_fcb() will be split into SoC specific variants. As a preparation
pull printing the fcb debug info out of this function to not have
to duplicate it in the SoC specific variants later.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/xload-gpmi-nand.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index a7398cc26a..dc4cc45be0 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -869,17 +869,6 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf)
 			continue;
 		}
 
-		pr_debug("Found FCB:\n");
-		pr_debug("PageDataSize:     0x%08x\n", fcb->PageDataSize);
-		pr_debug("TotalPageSize:    0x%08x\n", fcb->TotalPageSize);
-		pr_debug("SectorsPerBlock:  0x%08x\n", fcb->SectorsPerBlock);
-		pr_debug("FW1_startingPage: 0x%08x\n",
-			fcb->Firmware1_startingPage);
-		pr_debug("PagesInFW1:       0x%08x\n", fcb->PagesInFirmware1);
-		pr_debug("FW2_startingPage: 0x%08x\n",
-			fcb->Firmware2_startingPage);
-		pr_debug("PagesInFW2:       0x%08x\n", fcb->PagesInFirmware2);
-
 		return 0;
 	}
 
@@ -1031,6 +1020,17 @@ static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
 
 	fcb = &info->fcb;
 
+	pr_debug("Found FCB:\n");
+	pr_debug("PageDataSize:     0x%08x\n", fcb->PageDataSize);
+	pr_debug("TotalPageSize:    0x%08x\n", fcb->TotalPageSize);
+	pr_debug("SectorsPerBlock:  0x%08x\n", fcb->SectorsPerBlock);
+	pr_debug("FW1_startingPage: 0x%08x\n",
+		fcb->Firmware1_startingPage);
+	pr_debug("PagesInFW1:       0x%08x\n", fcb->PagesInFirmware1);
+	pr_debug("FW2_startingPage: 0x%08x\n",
+		fcb->Firmware2_startingPage);
+	pr_debug("PagesInFW2:       0x%08x\n", fcb->PagesInFirmware2);
+
 	get_dbbt(info, databuf);
 
 	ret = read_firmware(info, fcb->Firmware1_startingPage, dest, len);
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 08/14] ARM: i.MX: xload nand: Pull ECC status checking out of read page
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (6 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 07/14] imx-bbu-nand-fcb: pull printing debug info out of get_fcb() Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-02  8:33   ` Marco Felsch
  2022-11-01 15:30 ` [PATCH 09/14] ARM: i.MX: xload nand: Use final page layout from FCB Sascha Hauer
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

The read page code can be reused by upcoming i.MX7 support, but the ECC
checking will be different. Pull ECC status checking out of the read
page code to make that reusable on i.MX7.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/xload-gpmi-nand.c | 42 ++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index dc4cc45be0..543ec108ba 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -236,8 +236,6 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 	int cmd_queue_len;
 	u8 *cmd_buf;
 	int ret;
-	uint8_t	*status;
-	int i;
 	int timeout;
 	int descnum = 0;
 	int max_pagenum = info->nand_size /
@@ -375,20 +373,26 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 	writel(BCH_CTRL_COMPLETE_IRQ,
 		bch_regs + BCH_CTRL + STMP_OFFSET_REG_CLR);
 
-	/* Loop over status bytes, accumulating ECC status. */
-	status = databuf + writesize + mxs_nand_aux_status_offset();
-	for (i = 0; i < writesize / MXS_NAND_CHUNK_DATA_CHUNK_SIZE; i++) {
-		if (status[i] == 0xfe) {
-			ret = -EBADMSG;
-			goto err;
-		}
-	}
-
 	ret = 0;
 err:
 	return ret;
 }
 
+static int mxs_nand_get_ecc_status(struct mxs_nand_info *info, void *databuf)
+{
+	uint8_t	*status;
+	int i;
+
+	/* Loop over status bytes, accumulating ECC status. */
+	status = databuf + info->organization.pagesize + mxs_nand_aux_status_offset();
+	for (i = 0; i < info->organization.pagesize / MXS_NAND_CHUNK_DATA_CHUNK_SIZE; i++) {
+		if (status[i] == 0xfe)
+			return -EBADMSG;
+	}
+
+	return 0;
+}
+
 static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
 {
 	int ret;
@@ -851,6 +855,10 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf)
 		if (ret)
 			continue;
 
+		ret = mxs_nand_get_ecc_status(info, databuf);
+		if (ret)
+			continue;
+
 		memcpy(fcb, databuf + mxs_nand_aux_status_offset(),
 			sizeof(*fcb));
 
@@ -886,7 +894,11 @@ static int get_dbbt(struct mxs_nand_info *info, void *databuf)
 		page = startpage + i * info->organization.pages_per_eraseblock;
 
 		ret = mxs_nand_read_page(info, info->organization.pagesize,
-			info->organization.oobsize, page, databuf, 0);
+			info->organization.oobsize, page, databuf, 0, false);
+		if (ret)
+			continue;
+
+		ret = mxs_nand_get_ecc_status(info, databuf);
 		if (ret)
 			continue;
 
@@ -900,7 +912,11 @@ static int get_dbbt(struct mxs_nand_info *info, void *databuf)
 			return -ENOENT;
 
 		ret = mxs_nand_read_page(info, info->organization.pagesize,
-			info->organization.oobsize, page + 4, databuf, 0);
+			info->organization.oobsize, page + 4, databuf, 0, false);
+		if (ret)
+			continue;
+
+		ret = mxs_nand_get_ecc_status(info, databuf);
 		if (ret)
 			continue;
 
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 09/14] ARM: i.MX: xload nand: Use final page layout from FCB
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (7 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 08/14] ARM: i.MX: xload nand: Pull ECC status checking out of read page Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-01 15:30 ` [PATCH 10/14] imx-bbu-nand-fcb: Fix reading FCB information from BCH registers Sascha Hauer
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

For non ONFI NAND chips we decode the page layout from the extended ID
information from NAND (basically what nand_decode_ext_id() does in the
MTD layer). For some chips this information is not entirely correct
though. For example some Toshiba chips have this quirk:

        /*
         * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
         * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
         * follows:
         * - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm,
         *                         110b -> 24nm
         * - ID byte 5, bit[7]:    1 -> BENAND, 0 -> raw SLC
         */
        if (chip->id.len >= 6 && nand_is_slc(chip) &&
            (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
            !(chip->id.data[4] & TOSHIBA_NAND_ID4_IS_BENAND) /* !BENAND */) {
                memorg->oobsize = 32 * memorg->pagesize >> 9;
                mtd->oobsize = memorg->oobsize;
        }

We could try and add these kind of quirks into the xload code, but we
already have the correct information in the FCB. So as long as the
initial information from the ID is enough to read the FCB, we can use
the information containekd therein for further reading from the NAND.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/xload-gpmi-nand.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index 543ec108ba..af20c11fa6 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -1020,6 +1020,8 @@ static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
 	};
 	int ret;
 	struct fcb_block *fcb;
+	void __iomem *bch_regs = info->bch_base;
+	u32 fl0, fl1;
 
 	info->dma_channel = &pchan;
 
@@ -1047,6 +1049,21 @@ static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
 		fcb->Firmware2_startingPage);
 	pr_debug("PagesInFW2:       0x%08x\n", fcb->PagesInFirmware2);
 
+	info->organization.oobsize = fcb->TotalPageSize - fcb->PageDataSize;
+	info->organization.pagesize = fcb->PageDataSize;
+
+	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, fcb->NumEccBlocksPerPage) |
+		FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, fcb->MetadataBytes) |
+		FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, fcb->EccBlock0EccType) |
+		(fcb->BCHType ? BCH_FLASHLAYOUT0_GF13_0_GF14_1 : 0) |
+		FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, fcb->EccBlock0Size / 4);
+	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, fcb->TotalPageSize) |
+		FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, fcb->EccBlockNEccType) |
+		(fcb->BCHType ? BCH_FLASHLAYOUT1_GF13_0_GF14_1 : 0) |
+		FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, fcb->EccBlockNSize / 4);
+	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
+	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
+
 	get_dbbt(info, databuf);
 
 	ret = read_firmware(info, fcb->Firmware1_startingPage, dest, len);
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 10/14] imx-bbu-nand-fcb: Fix reading FCB information from BCH registers
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (8 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 09/14] ARM: i.MX: xload nand: Use final page layout from FCB Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-01 15:30 ` [PATCH 11/14] ARM: i.MX: xload nand: reset NAND before accessing it Sascha Hauer
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

fcb->EccBlock0Size and fcb->EccBlock0EccType must be extracted from
the BCH_FLASH0LAYOUT0 register, not from the BCH_FLASH0LAYOUT1 register.

As we always use the same ECC block size for both the first and the
subsequent blocks there's no functional change in this patch, it's only
for consistency.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/imx-bbu-nand-fcb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
index 63c81e4ed6..05bee912e4 100644
--- a/common/imx-bbu-nand-fcb.c
+++ b/common/imx-bbu-nand-fcb.c
@@ -1572,10 +1572,10 @@ static void imx7_fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
 	fl0 = readl(bch_regs + BCH_FLASH0LAYOUT0);
 	fcb->MetadataBytes = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
 	fcb->NumEccBlocksPerPage = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS);
+	fcb->EccBlock0Size = 4 * BF_VAL(fl0, BCH_FLASHLAYOUT0_DATA0_SIZE);
+	fcb->EccBlock0EccType = BF_VAL(fl0, BCH_FLASHLAYOUT0_ECC0);
 
 	fl1 = readl(bch_regs + BCH_FLASH0LAYOUT1);
-	fcb->EccBlock0Size = 4 * BF_VAL(fl1, BCH_FLASHLAYOUT0_DATA0_SIZE);
-	fcb->EccBlock0EccType = BF_VAL(fl1, BCH_FLASHLAYOUT0_ECC0);
 	fcb->EccBlockNSize = 4 * BF_VAL(fl1, BCH_FLASHLAYOUT1_DATAN_SIZE);
 	fcb->EccBlockNEccType = BF_VAL(fl1, BCH_FLASHLAYOUT1_ECCN);
 	fcb->BCHType = BF_VAL(fl1, BCH_FLASHLAYOUT1_GF13_0_GF14_1);
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 11/14] ARM: i.MX: xload nand: reset NAND before accessing it
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (9 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 10/14] imx-bbu-nand-fcb: Fix reading FCB information from BCH registers Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-01 15:30 ` [PATCH 12/14] ARM: i.MX: xload nand: Move mxs_nand_mode_fcb_62bit() to header file Sascha Hauer
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

One particular NAND chip here (Toshiba TC58NVG2S0H) doesn't like it when
the ID or ONFI information is read before the NAND chip is resetted. It
works once, but with the second read the chip will not deliver data
anymore. Reset the NAND chip before accessing it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/xload-gpmi-nand.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index af20c11fa6..7e4033d74f 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -760,6 +760,10 @@ static int mxs_nand_get_info(struct mxs_nand_info *info, void *databuf)
 {
 	int ret, i;
 
+	ret = mxs_nand_reset(info, databuf);
+	if (ret)
+		return ret;
+
 	ret = mxs_nand_check_onfi(info, databuf);
 	if (ret) {
 		if (ret != 1)
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 12/14] ARM: i.MX: xload nand: Move mxs_nand_mode_fcb_62bit() to header file
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (10 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 11/14] ARM: i.MX: xload nand: reset NAND before accessing it Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-02  8:37   ` Marco Felsch
  2022-11-01 15:30 ` [PATCH 13/14] ARM: i.MX: xload nand: Implement i.MX7 support Sascha Hauer
  2022-11-01 15:30 ` [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command Sascha Hauer
  13 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

mxs_nand_mode_fcb_62bit() can be shared between the regular MTD NAND
driver and the upcoming i.MX7 xload driver. Move to header file.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_mxs.c | 34 ++--------------------------------
 include/soc/imx/gpmi-nand.h | 27 +++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index b162c23743..79a8fbdefa 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -1123,36 +1123,6 @@ static int mxs_nand_block_markbad(struct nand_chip *chip , loff_t ofs)
 	return 0;
 }
 
-#define BCH62_WRITESIZE		1024
-#define BCH62_OOBSIZE		838
-#define BCH62_PAGESIZE		(BCH62_WRITESIZE + BCH62_OOBSIZE)
-
-static void mxs_nand_mode_fcb_62bit(struct mxs_nand_info *nand_info)
-{
-	void __iomem *bch_regs;
-	u32 fl0, fl1;
-
-	bch_regs = nand_info->bch_base;
-
-	/* 8 ecc_chunks */
-	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, 7);
-	/* 32 bytes for metadata */
-	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, 32);
-	/* using ECC62 level to be performed */
-	fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, 0x1f);
-	/* 0x20 * 4 bytes of the data0 block */
-	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, 0x20);
-	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
-
-	/* 1024 for data + 838 for OOB */
-	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, BCH62_PAGESIZE);
-	/* using ECC62 level to be performed */
-	fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, 0x1f);
-	/* 0x20 * 4 bytes of the data0 block */
-	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, 0x20);
-	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
-}
-
 int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size)
 {
 	struct nand_chip *chip;
@@ -1174,7 +1144,7 @@ int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size)
 
 	page = block * (mtd->erasesize / mtd->writesize);
 
-	mxs_nand_mode_fcb_62bit(nand_info);
+	mxs_nand_mode_fcb_62bit(nand_info->bch_base);
 
 	nand_read_page_op(chip, page, 0, NULL, 0);
 
@@ -1238,7 +1208,7 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size)
 	nand_info = chip->priv;
 	channel = nand_info->dma_channel_base;
 
-	mxs_nand_mode_fcb_62bit(nand_info);
+	mxs_nand_mode_fcb_62bit(nand_info->bch_base);
 
 	nand_select_target(chip, 0);
 
diff --git a/include/soc/imx/gpmi-nand.h b/include/soc/imx/gpmi-nand.h
index f7a2caa1d6..8c30dee8ab 100644
--- a/include/soc/imx/gpmi-nand.h
+++ b/include/soc/imx/gpmi-nand.h
@@ -111,4 +111,31 @@
 
 #define	MXS_NAND_BCH_TIMEOUT			10000
 
+#define BCH62_WRITESIZE		1024
+#define BCH62_OOBSIZE		838
+#define BCH62_PAGESIZE		(BCH62_WRITESIZE + BCH62_OOBSIZE)
+
+static void mxs_nand_mode_fcb_62bit(void __iomem *bch_regs)
+{
+	u32 fl0, fl1;
+
+	/* 8 ecc_chunks */
+	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, 7);
+	/* 32 bytes for metadata */
+	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, 32);
+	/* using ECC62 level to be performed */
+	fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, 0x1f);
+	/* 0x20 * 4 bytes of the data0 block */
+	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, 0x20);
+	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
+
+	/* 1024 for data + 838 for OOB */
+	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, BCH62_PAGESIZE);
+	/* using ECC62 level to be performed */
+	fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, 0x1f);
+	/* 0x20 * 4 bytes of the data0 block */
+	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, 0x20);
+	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
+}
+
 #endif /* __SOC_IMX_GPMI_NAND_H */
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 13/14] ARM: i.MX: xload nand: Implement i.MX7 support
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (11 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 12/14] ARM: i.MX: xload nand: Move mxs_nand_mode_fcb_62bit() to header file Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-02  8:41   ` Marco Felsch
  2022-11-01 15:30 ` [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command Sascha Hauer
  13 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

i.MX7 xload NAND support works like on i.MX6, but the FCB is in a
different format. The FCB page uses BCH62 ECC, has 8 ECC chunks with
128 bytes each with a resulting total page size of 1862 bytes. Also
the page data is written with a pseudo randomizer enabled.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imx7-regs.h |  1 +
 arch/arm/mach-imx/include/mach/xload.h     |  1 +
 arch/arm/mach-imx/xload-gpmi-nand.c        | 95 ++++++++++++++++++++--
 3 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx7-regs.h b/arch/arm/mach-imx/include/mach/imx7-regs.h
index 1ee7d86e0e..379be9e062 100644
--- a/arch/arm/mach-imx/include/mach/imx7-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx7-regs.h
@@ -118,6 +118,7 @@
 #define MX7_ENET1_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3E0000)
 #define MX7_ENET2_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3F0000)
 
+#define	MX7_APBH_BASE			0x33000000
 #define MX7_GPMI_BASE			0x33002000
 #define MX7_BCH_BASE			0x33004000
 
diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h
index 82bf663c42..ca0055aee2 100644
--- a/arch/arm/mach-imx/include/mach/xload.h
+++ b/arch/arm/mach-imx/include/mach/xload.h
@@ -12,6 +12,7 @@ int imx6_spi_start_image(int instance);
 int imx6_esdhc_start_image(int instance);
 int imx6_nand_start_image(void);
 int imx7_esdhc_start_image(int instance);
+int imx7_nand_start_image(void);
 int imx8m_esdhc_load_image(int instance, bool start);
 int imx8mn_esdhc_load_image(int instance, bool start);
 int imx8mp_esdhc_load_image(int instance, bool start);
diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
index 7e4033d74f..edffd69e6b 100644
--- a/arch/arm/mach-imx/xload-gpmi-nand.c
+++ b/arch/arm/mach-imx/xload-gpmi-nand.c
@@ -13,6 +13,7 @@
 #include <linux/mtd/rawnand.h>
 #include <soc/imx/gpmi-nand.h>
 #include <mach/imx6-regs.h>
+#include <mach/imx7-regs.h>
 #include <mach/clock-imx6.h>
 #include <dma/apbh-dma.h>
 
@@ -228,7 +229,7 @@ static uint32_t mxs_nand_aux_status_offset(void)
 }
 
 static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
-		int oobsize, int pagenum, void *databuf, int raw)
+		int oobsize, int pagenum, void *databuf, int raw, bool randomizer)
 {
 	void __iomem *bch_regs = info->bch_base;
 	unsigned column = 0;
@@ -332,6 +333,12 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
 		d->pio_words[4] = (dma_addr_t)databuf;
 		d->pio_words[5] = (dma_addr_t)(databuf + writesize);
 
+		if (randomizer) {
+			d->pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
+					   GPMI_ECCCTRL_RANDOMIZER_TYPE2;
+			d->pio_words[3] |= (pagenum % 256) << 16;
+		}
+
 		/* Compile DMA descriptor - disable the BCH block. */
 		d = &info->desc[descnum++];
 		d->data = MXS_DMA_DESC_NAND_WAIT_4_READY |
@@ -841,7 +848,7 @@ static uint32_t calc_chksum(void *buf, size_t size)
 	return ~chksum;
 }
 
-static int get_fcb(struct mxs_nand_info *info, void *databuf)
+static int imx6_get_fcb(struct mxs_nand_info *info, void *databuf)
 {
 	int i, pagenum, ret;
 	uint32_t checksum;
@@ -849,13 +856,13 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf)
 
 	/* First page read fails, this shouldn't be necessary */
 	mxs_nand_read_page(info, info->organization.pagesize,
-		info->organization.oobsize, 0, databuf, 1);
+		info->organization.oobsize, 0, databuf, 1, false);
 
 	for (i = 0; i < 4; i++) {
 		pagenum = info->organization.pages_per_eraseblock * i;
 
 		ret = mxs_nand_read_page(info, info->organization.pagesize,
-			info->organization.oobsize, pagenum, databuf, 1);
+			info->organization.oobsize, pagenum, databuf, 1, false);
 		if (ret)
 			continue;
 
@@ -887,6 +894,66 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf)
 	return -EINVAL;
 }
 
+static int imx7_get_fcb_n(struct mxs_nand_info *info, void *databuf, int num)
+{
+	int ret;
+	int flips = 0;
+	uint8_t	*status;
+	int i;
+
+	ret = mxs_nand_read_page(info, BCH62_WRITESIZE, BCH62_OOBSIZE,
+				 info->organization.pages_per_eraseblock * num, databuf, 0, true);
+	if (ret)
+		return ret;
+
+	/* Loop over status bytes, accumulating ECC status. */
+	status = databuf + BCH62_WRITESIZE + 32;
+
+	for (i = 0; i < 8; i++) {
+		switch (status[i]) {
+		case 0x0:
+			break;
+		case 0xff:
+			/*
+			 * A status of 0xff means the chunk is erased, but due to
+			 * the randomizer we see this as random data. Explicitly
+			 * memset it.
+			 */
+			memset(databuf + 0x80 * i, 0xff, 0x80);
+			break;
+		case 0xfe:
+			return -EBADMSG;
+		default:
+			flips += status[0];
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int imx7_get_fcb(struct mxs_nand_info *info, void *databuf)
+{
+	int i, ret;
+	struct fcb_block *fcb = &info->fcb;
+
+	mxs_nand_mode_fcb_62bit(info->bch_base);
+
+	for (i = 0; i < 4; i++) {
+		ret = imx7_get_fcb_n(info, databuf, i);
+		if (!ret)
+			break;
+	}
+
+	if (ret) {
+		pr_err("Cannot find FCB\n");
+	} else {
+		memcpy(fcb, databuf, sizeof(*fcb));
+	}
+
+	return ret;
+}
+
 static int get_dbbt(struct mxs_nand_info *info, void *databuf)
 {
 	int i, ret;
@@ -991,7 +1058,7 @@ static int read_firmware(struct mxs_nand_info *info, int startpage,
 		}
 
 		ret = mxs_nand_read_page(info, pagesize, oobsize,
-			curpage, dest, 0);
+			curpage, dest, 0, false);
 		if (ret) {
 			pr_debug("Failed to read page %d\n", curpage);
 			return ret;
@@ -1012,6 +1079,7 @@ struct imx_nand_params {
 	struct mxs_nand_info info;
 	struct apbh_dma apbh;
 	void *sdram;
+	int (*get_fcb)(struct mxs_nand_info *info, void *databuf);
 };
 
 static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
@@ -1036,7 +1104,7 @@ static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
 	if (ret)
 		return ret;
 
-	ret = get_fcb(info, databuf);
+	ret = params->get_fcb(info, databuf);
 	if (ret)
 		return ret;
 
@@ -1120,6 +1188,7 @@ int imx6_nand_start_image(void)
 		.apbh.regs = IOMEM(MX6_APBH_BASE_ADDR),
 		.apbh.id = IMX28_DMA,
 		.sdram = (void *)MX6_MMDC_PORT01_BASE_ADDR,
+		.get_fcb = imx6_get_fcb,
 	};
 
 	/* Apply ERR007117 workaround */
@@ -1127,3 +1196,17 @@ int imx6_nand_start_image(void)
 
 	return imx_nand_start_image(&params);
 }
+
+int imx7_nand_start_image(void)
+{
+	static struct imx_nand_params params = {
+		.info.io_base = IOMEM(MX7_GPMI_BASE),
+		.info.bch_base = IOMEM(MX7_BCH_BASE),
+		.apbh.regs = IOMEM(MX7_APBH_BASE),
+		.apbh.id = IMX28_DMA,
+		.sdram = (void *)MX7_DDR_BASE_ADDR,
+		.get_fcb = imx7_get_fcb,
+	};
+
+	return imx_nand_start_image(&params);
+}
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command
  2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
                   ` (12 preceding siblings ...)
  2022-11-01 15:30 ` [PATCH 13/14] ARM: i.MX: xload nand: Implement i.MX7 support Sascha Hauer
@ 2022-11-01 15:30 ` Sascha Hauer
  2022-11-02  8:44   ` Marco Felsch
  13 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-01 15:30 UTC (permalink / raw)
  To: Barebox List

The FCB on NAND has a special page layout and thus can't be read with
the normal MTD driver. Add a fcb command for printing information about
the installed FCB on the console.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig          |   9 ++
 common/imx-bbu-nand-fcb.c | 195 ++++++++++++++++++++++++++++----------
 2 files changed, 153 insertions(+), 51 deletions(-)

diff --git a/commands/Kconfig b/commands/Kconfig
index 9894ecb9aa..cab72b9226 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -326,6 +326,15 @@ config CMD_SLICE
 	  command can be used to print informations about slices and also to manipulate
 	  them on the command line for debugging purposes.
 
+config CMD_FCB
+	depends on BAREBOX_UPDATE_IMX_NAND_FCB
+	tristate
+	prompt "fcb"
+	help
+	  Several i.MX SoCs booting from NAND flash need a so called Flash Control Block
+	  at the beginning of the NAND device. The fcb command prints information about
+	  the FCB.
+
 # end Information commands
 endmenu
 
diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
index 05bee912e4..39425c7fc3 100644
--- a/common/imx-bbu-nand-fcb.c
+++ b/common/imx-bbu-nand-fcb.c
@@ -14,6 +14,8 @@
 #include <linux/sizes.h>
 #include <bbu.h>
 #include <fs.h>
+#include <command.h>
+#include <complete.h>
 #include <linux/mtd/mtd-abi.h>
 #include <linux/mtd/nand_mxs.h>
 #include <linux/mtd/mtd.h>
@@ -284,57 +286,57 @@ static __maybe_unused void dump_fcb(void *buf)
 {
 	struct fcb_block *fcb = buf;
 
-	pr_debug("Checksum:                   0x%08x\n", fcb->Checksum);
-	pr_debug("FingerPrint:                0x%08x\n", fcb->FingerPrint);
-	pr_debug("Version:                    0x%08x\n", fcb->Version);
-	pr_debug("DataSetup:                  0x%02x\n", fcb->DataSetup);
-	pr_debug("DataHold:                   0x%02x\n", fcb->DataHold);
-	pr_debug("AddressSetup:               0x%02x\n", fcb->AddressSetup);
-	pr_debug("DSAMPLE_TIME:               0x%02x\n", fcb->DSAMPLE_TIME);
-	pr_debug("NandTimingState:            0x%02x\n", fcb->NandTimingState);
-	pr_debug("REA:                        0x%02x\n", fcb->REA);
-	pr_debug("RLOH:                       0x%02x\n", fcb->RLOH);
-	pr_debug("RHOH:                       0x%02x\n", fcb->RHOH);
-	pr_debug("PageDataSize:               0x%08x\n", fcb->PageDataSize);
-	pr_debug("TotalPageSize:              0x%08x\n", fcb->TotalPageSize);
-	pr_debug("SectorsPerBlock:            0x%08x\n", fcb->SectorsPerBlock);
-	pr_debug("NumberOfNANDs:              0x%08x\n", fcb->NumberOfNANDs);
-	pr_debug("TotalInternalDie:           0x%08x\n", fcb->TotalInternalDie);
-	pr_debug("CellType:                   0x%08x\n", fcb->CellType);
-	pr_debug("EccBlockNEccType:           0x%08x\n", fcb->EccBlockNEccType);
-	pr_debug("EccBlock0Size:              0x%08x\n", fcb->EccBlock0Size);
-	pr_debug("EccBlockNSize:              0x%08x\n", fcb->EccBlockNSize);
-	pr_debug("EccBlock0EccType:           0x%08x\n", fcb->EccBlock0EccType);
-	pr_debug("MetadataBytes:              0x%08x\n", fcb->MetadataBytes);
-	pr_debug("NumEccBlocksPerPage:        0x%08x\n", fcb->NumEccBlocksPerPage);
-	pr_debug("EccBlockNEccLevelSDK:       0x%08x\n", fcb->EccBlockNEccLevelSDK);
-	pr_debug("EccBlock0SizeSDK:           0x%08x\n", fcb->EccBlock0SizeSDK);
-	pr_debug("EccBlockNSizeSDK:           0x%08x\n", fcb->EccBlockNSizeSDK);
-	pr_debug("EccBlock0EccLevelSDK:       0x%08x\n", fcb->EccBlock0EccLevelSDK);
-	pr_debug("NumEccBlocksPerPageSDK:     0x%08x\n", fcb->NumEccBlocksPerPageSDK);
-	pr_debug("MetadataBytesSDK:           0x%08x\n", fcb->MetadataBytesSDK);
-	pr_debug("EraseThreshold:             0x%08x\n", fcb->EraseThreshold);
-	pr_debug("BootPatch:                  0x%08x\n", fcb->BootPatch);
-	pr_debug("PatchSectors:               0x%08x\n", fcb->PatchSectors);
-	pr_debug("Firmware1_startingPage:     0x%08x\n", fcb->Firmware1_startingPage);
-	pr_debug("Firmware2_startingPage:     0x%08x\n", fcb->Firmware2_startingPage);
-	pr_debug("PagesInFirmware1:           0x%08x\n", fcb->PagesInFirmware1);
-	pr_debug("PagesInFirmware2:           0x%08x\n", fcb->PagesInFirmware2);
-	pr_debug("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress);
-	pr_debug("BadBlockMarkerByte:         0x%08x\n", fcb->BadBlockMarkerByte);
-	pr_debug("BadBlockMarkerStartBit:     0x%08x\n", fcb->BadBlockMarkerStartBit);
-	pr_debug("BBMarkerPhysicalOffset:     0x%08x\n", fcb->BBMarkerPhysicalOffset);
-	pr_debug("BCHType:                    0x%08x\n", fcb->BCHType);
-	pr_debug("TMTiming2_ReadLatency:      0x%08x\n", fcb->TMTiming2_ReadLatency);
-	pr_debug("TMTiming2_PreambleDelay:    0x%08x\n", fcb->TMTiming2_PreambleDelay);
-	pr_debug("TMTiming2_CEDelay:          0x%08x\n", fcb->TMTiming2_CEDelay);
-	pr_debug("TMTiming2_PostambleDelay:   0x%08x\n", fcb->TMTiming2_PostambleDelay);
-	pr_debug("TMTiming2_CmdAddPause:      0x%08x\n", fcb->TMTiming2_CmdAddPause);
-	pr_debug("TMTiming2_DataPause:        0x%08x\n", fcb->TMTiming2_DataPause);
-	pr_debug("TMSpeed:                    0x%08x\n", fcb->TMSpeed);
-	pr_debug("TMTiming1_BusyTimeout:      0x%08x\n", fcb->TMTiming1_BusyTimeout);
-	pr_debug("DISBBM:                     0x%08x\n", fcb->DISBBM);
-	pr_debug("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData);
+	printf("Checksum:                   0x%08x\n", fcb->Checksum);
+	printf("FingerPrint:                0x%08x\n", fcb->FingerPrint);
+	printf("Version:                    0x%08x\n", fcb->Version);
+	printf("DataSetup:                  0x%02x\n", fcb->DataSetup);
+	printf("DataHold:                   0x%02x\n", fcb->DataHold);
+	printf("AddressSetup:               0x%02x\n", fcb->AddressSetup);
+	printf("DSAMPLE_TIME:               0x%02x\n", fcb->DSAMPLE_TIME);
+	printf("NandTimingState:            0x%02x\n", fcb->NandTimingState);
+	printf("REA:                        0x%02x\n", fcb->REA);
+	printf("RLOH:                       0x%02x\n", fcb->RLOH);
+	printf("RHOH:                       0x%02x\n", fcb->RHOH);
+	printf("PageDataSize:               0x%08x\n", fcb->PageDataSize);
+	printf("TotalPageSize:              0x%08x\n", fcb->TotalPageSize);
+	printf("SectorsPerBlock:            0x%08x\n", fcb->SectorsPerBlock);
+	printf("NumberOfNANDs:              0x%08x\n", fcb->NumberOfNANDs);
+	printf("TotalInternalDie:           0x%08x\n", fcb->TotalInternalDie);
+	printf("CellType:                   0x%08x\n", fcb->CellType);
+	printf("EccBlockNEccType:           0x%08x\n", fcb->EccBlockNEccType);
+	printf("EccBlock0Size:              0x%08x\n", fcb->EccBlock0Size);
+	printf("EccBlockNSize:              0x%08x\n", fcb->EccBlockNSize);
+	printf("EccBlock0EccType:           0x%08x\n", fcb->EccBlock0EccType);
+	printf("MetadataBytes:              0x%08x\n", fcb->MetadataBytes);
+	printf("NumEccBlocksPerPage:        0x%08x\n", fcb->NumEccBlocksPerPage);
+	printf("EccBlockNEccLevelSDK:       0x%08x\n", fcb->EccBlockNEccLevelSDK);
+	printf("EccBlock0SizeSDK:           0x%08x\n", fcb->EccBlock0SizeSDK);
+	printf("EccBlockNSizeSDK:           0x%08x\n", fcb->EccBlockNSizeSDK);
+	printf("EccBlock0EccLevelSDK:       0x%08x\n", fcb->EccBlock0EccLevelSDK);
+	printf("NumEccBlocksPerPageSDK:     0x%08x\n", fcb->NumEccBlocksPerPageSDK);
+	printf("MetadataBytesSDK:           0x%08x\n", fcb->MetadataBytesSDK);
+	printf("EraseThreshold:             0x%08x\n", fcb->EraseThreshold);
+	printf("BootPatch:                  0x%08x\n", fcb->BootPatch);
+	printf("PatchSectors:               0x%08x\n", fcb->PatchSectors);
+	printf("Firmware1_startingPage:     0x%08x\n", fcb->Firmware1_startingPage);
+	printf("Firmware2_startingPage:     0x%08x\n", fcb->Firmware2_startingPage);
+	printf("PagesInFirmware1:           0x%08x\n", fcb->PagesInFirmware1);
+	printf("PagesInFirmware2:           0x%08x\n", fcb->PagesInFirmware2);
+	printf("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress);
+	printf("BadBlockMarkerByte:         0x%08x\n", fcb->BadBlockMarkerByte);
+	printf("BadBlockMarkerStartBit:     0x%08x\n", fcb->BadBlockMarkerStartBit);
+	printf("BBMarkerPhysicalOffset:     0x%08x\n", fcb->BBMarkerPhysicalOffset);
+	printf("BCHType:                    0x%08x\n", fcb->BCHType);
+	printf("TMTiming2_ReadLatency:      0x%08x\n", fcb->TMTiming2_ReadLatency);
+	printf("TMTiming2_PreambleDelay:    0x%08x\n", fcb->TMTiming2_PreambleDelay);
+	printf("TMTiming2_CEDelay:          0x%08x\n", fcb->TMTiming2_CEDelay);
+	printf("TMTiming2_PostambleDelay:   0x%08x\n", fcb->TMTiming2_PostambleDelay);
+	printf("TMTiming2_CmdAddPause:      0x%08x\n", fcb->TMTiming2_CmdAddPause);
+	printf("TMTiming2_DataPause:        0x%08x\n", fcb->TMTiming2_DataPause);
+	printf("TMSpeed:                    0x%08x\n", fcb->TMSpeed);
+	printf("TMTiming1_BusyTimeout:      0x%08x\n", fcb->TMTiming1_BusyTimeout);
+	printf("DISBBM:                     0x%08x\n", fcb->DISBBM);
+	printf("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData);
 }
 
 static __maybe_unused ssize_t raw_read_page(struct mtd_info *mtd, void *dst, loff_t offset)
@@ -1625,3 +1627,94 @@ int imx7_bbu_nand_register_handler(const char *name, unsigned long flags)
 	return ret;
 }
 #endif
+
+static void dump_fcb_n(struct fcb_block **fcbs, int n)
+{
+	int i;
+
+	if (!n || !fcbs[n])
+		goto skip_compare;
+
+	for (i = 0; i < n; i++) {
+		if (!fcbs[i] || !fcbs[n])
+			continue;
+
+		if (!memcmp(fcbs[i], fcbs[n], sizeof(struct fcb_block))) {
+			printf("FCB block#%d: same as FCB block#%d\n", n, i);
+			return;
+		}
+	}
+
+skip_compare:
+	if (fcbs[n]) {
+		printf("FCB block#%d:\n", n);
+		dump_fcb(fcbs[n]);
+	} else {
+		printf("FCB block#%d: NULL\n", n);
+	}
+}
+
+#ifdef CONFIG_ARCH_IMX28
+static int fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb)
+{
+	return fcb_read_hamming_13_8(mtd, block, retfcb);
+}
+#else
+static int fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb)
+{
+	if (cpu_is_mx7())
+		return imx7_fcb_read(mtd, block, retfcb);
+	else if (fcb_is_bch_encoded())
+		return fcb_read_bch(mtd, block, retfcb);
+	else
+		return fcb_read_hamming_13_8(mtd, block, retfcb);
+}
+#endif
+
+static int cmd_fcb(int argc, char *argv[])
+{
+	struct cdev *cdev;
+	struct mtd_info *mtd;
+	struct fcb_block *fcb[4] = {};
+	int i, ret;
+
+	cdev = cdev_open_by_name("nand0", O_RDONLY);
+	if (!cdev) {
+		printf("Cannot open nand0\n");
+		return COMMAND_ERROR;
+	}
+
+	mtd = cdev->mtd;
+	if (!mtd) {
+		ret = COMMAND_ERROR;
+		goto out;
+	}
+
+	for (i = 0; i < 4; i++)
+		fcb_read(mtd, i, &fcb[i]);
+
+	for (i = 0; i < 4; i++)
+		dump_fcb_n(fcb, i);
+
+	for (i = 0; i < 4; i++)
+		free(fcb[i]);
+
+	ret = 0;
+
+out:
+	cdev_close(cdev);
+
+	return ret;
+}
+
+BAREBOX_CMD_HELP_START(fcb)
+BAREBOX_CMD_HELP_TEXT("Dump FCB as found on /dev/nand0")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(fcb)
+	.cmd = cmd_fcb,
+	BAREBOX_CMD_DESC("Dump Flash Control Block (FCB)")
+	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+	BAREBOX_CMD_HELP(cmd_fcb_help)
+	BAREBOX_CMD_COMPLETE(empty_complete)
+BAREBOX_CMD_END
-- 
2.30.2




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/14] mtd: nand: nand-mxs: Move register definitions to separate file
  2022-11-01 15:30 ` [PATCH 01/14] mtd: nand: nand-mxs: Move register definitions to separate file Sascha Hauer
@ 2022-11-02  8:08   ` Marco Felsch
  0 siblings, 0 replies; 26+ messages in thread
From: Marco Felsch @ 2022-11-02  8:08 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On 22-11-01, Sascha Hauer wrote:
> The GPMI registers are needed in the MTD GPMI driver and also in the
> xload-gpmi driver. So far both use their own set of register defines.
> Move the MTD GPMI register defines to include/ so that we can use them
> in the xload driver as well.

Nit: Should we note that we are replacing the manual bitops by
FIELD_PREP?

Regards,
  Marco

> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/mtd/nand/nand_mxs.c | 186 ++++++------------------------------
>  include/soc/imx/gpmi-nand.h | 114 ++++++++++++++++++++++
>  2 files changed, 145 insertions(+), 155 deletions(-)
>  create mode 100644 include/soc/imx/gpmi-nand.h
> 
> diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
> index 5faa17a4bd..d711708ff2 100644
> --- a/drivers/mtd/nand/nand_mxs.c
> +++ b/drivers/mtd/nand/nand_mxs.c
> @@ -21,6 +21,7 @@
>  #include <linux/types.h>
>  #include <linux/clk.h>
>  #include <linux/err.h>
> +#include <linux/bitfield.h>
>  #include <of_mtd.h>
>  #include <common.h>
>  #include <dma.h>
> @@ -32,139 +33,10 @@
>  #include <dma/apbh-dma.h>
>  #include <stmp-device.h>
>  #include <mach/generic.h>
> +#include <soc/imx/gpmi-nand.h>
>  
>  #include "internals.h"
>  
> -#define	MX28_BLOCK_SFTRST				(1 << 31)
> -#define	MX28_BLOCK_CLKGATE				(1 << 30)
> -
> -#define GPMI_CTRL0					0x00000000
> -#define	GPMI_CTRL0_RUN					(1 << 29)
> -#define	GPMI_CTRL0_DEV_IRQ_EN				(1 << 28)
> -/* Disable for now since we don't need it and it is different on MX23.
> -#define	GPMI_CTRL0_LOCK_CS				(1 << 27)
> -*/
> -#define	GPMI_CTRL0_UDMA					(1 << 26)
> -#define	GPMI_CTRL0_COMMAND_MODE_MASK			(0x3 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_OFFSET			24
> -#define	GPMI_CTRL0_COMMAND_MODE_WRITE			(0x0 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_READ			(0x1 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE	(0x2 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY		(0x3 << 24)
> -#define	GPMI_CTRL0_WORD_LENGTH				(1 << 23)
> -/* Careful: Is 0x3 on MX23
> -#define	GPMI_CTRL0_CS_MASK				(0x7 << 20)
> -*/
> -#define	GPMI_CTRL0_CS_OFFSET				20
> -#define	GPMI_CTRL0_ADDRESS_MASK				(0x7 << 17)
> -#define	GPMI_CTRL0_ADDRESS_OFFSET			17
> -#define	GPMI_CTRL0_ADDRESS_NAND_DATA			(0x0 << 17)
> -#define	GPMI_CTRL0_ADDRESS_NAND_CLE			(0x1 << 17)
> -#define	GPMI_CTRL0_ADDRESS_NAND_ALE			(0x2 << 17)
> -#define	GPMI_CTRL0_ADDRESS_INCREMENT			(1 << 16)
> -#define	GPMI_CTRL0_XFER_COUNT_MASK			0xffff
> -#define	GPMI_CTRL0_XFER_COUNT_OFFSET			0
> -
> -#define GPMI_CTRL1					0x00000060
> -#define GPMI_CTRL1_SET					0x00000064
> -#define GPMI_CTRL1_CLR					0x00000068
> -#define	GPMI_CTRL1_DECOUPLE_CS				(1 << 24)
> -#define	GPMI_CTRL1_WRN_DLY(d)				(((d) & 0x3) << 22)
> -#define	GPMI_CTRL1_TIMEOUT_IRQ_EN			(1 << 20)
> -#define	GPMI_CTRL1_GANGED_RDYBUSY			(1 << 19)
> -#define	GPMI_CTRL1_BCH_MODE				(1 << 18)
> -#define	GPMI_CTRL1_DLL_ENABLE				(1 << 17)
> -#define	GPMI_CTRL1_HALF_PERIOD				(1 << 16)
> -#define	GPMI_CTRL1_RDN_DELAY(d)				(((d) & 0xf) << 12)
> -#define	GPMI_CTRL1_DMA2ECC_MODE				(1 << 11)
> -#define	GPMI_CTRL1_DEV_IRQ				(1 << 10)
> -#define	GPMI_CTRL1_TIMEOUT_IRQ				(1 << 9)
> -#define	GPMI_CTRL1_BURST_EN				(1 << 8)
> -#define	GPMI_CTRL1_ABORT_WAIT_REQUEST			(1 << 7)
> -#define	GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_MASK	(0x7 << 4)
> -#define	GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_OFFSET	4
> -#define	GPMI_CTRL1_DEV_RESET				(1 << 3)
> -#define	GPMI_CTRL1_ATA_IRQRDY_POLARITY			(1 << 2)
> -#define	GPMI_CTRL1_CAMERA_MODE				(1 << 1)
> -#define	GPMI_CTRL1_GPMI_MODE				(1 << 0)
> -
> -#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS		0x0
> -#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS		0x1
> -#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS		0x2
> -#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY		0x3
> -
> -#define GPMI_TIMING0					0x00000070
> -
> -#define	GPMI_TIMING0_ADDRESS_SETUP(d)			(((d) & 0xff) << 16)
> -#define	GPMI_TIMING0_DATA_HOLD(d)			(((d) & 0xff) << 8)
> -#define	GPMI_TIMING0_DATA_SETUP(d)			(((d) & 0xff) << 0)
> -
> -#define GPMI_TIMING1					0x00000080
> -#define	GPMI_TIMING1_BUSY_TIMEOUT(d)			(((d) & 0xffff) << 16)
> -
> -#define	GPMI_ECCCTRL_HANDLE_MASK			(0xffff << 16)
> -#define	GPMI_ECCCTRL_HANDLE_OFFSET			16
> -#define	GPMI_ECCCTRL_ECC_CMD_MASK			(0x3 << 13)
> -#define	GPMI_ECCCTRL_ECC_CMD_OFFSET			13
> -#define	GPMI_ECCCTRL_ECC_CMD_DECODE			(0x0 << 13)
> -#define	GPMI_ECCCTRL_ECC_CMD_ENCODE			(0x1 << 13)
> -#define GPMI_ECCCTRL_RANDOMIZER_ENABLE                  (1 << 11)
> -#define GPMI_ECCCTRL_RANDOMIZER_TYPE0                   0
> -#define GPMI_ECCCTRL_RANDOMIZER_TYPE1                   (1 << 9)
> -#define GPMI_ECCCTRL_RANDOMIZER_TYPE2                   (2 << 9)
> -#define	GPMI_ECCCTRL_ENABLE_ECC				(1 << 12)
> -#define	GPMI_ECCCTRL_BUFFER_MASK_MASK			0x1ff
> -#define	GPMI_ECCCTRL_BUFFER_MASK_OFFSET			0
> -#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_AUXONLY		0x100
> -#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE		0x1ff
> -
> -#define GPMI_STAT				0x000000b0
> -#define	GPMI_STAT_READY_BUSY_OFFSET			24
> -
> -#define GPMI_DEBUG				0x000000c0
> -#define GPMI_DEBUG_READY0_OFFSET			28
> -
> -#define GPMI_VERSION				0x000000d0
> -#define GPMI_VERSION_MINOR_OFFSET			16
> -#define GPMI_VERSION_TYPE_MX23			0x0300
> -
> -#define BCH_CTRL				0x00000000
> -#define	BCH_CTRL_COMPLETE_IRQ			(1 << 0)
> -#define	BCH_CTRL_COMPLETE_IRQ_EN		(1 << 8)
> -
> -#define BCH_LAYOUTSELECT			0x00000070
> -
> -#define BCH_FLASH0LAYOUT0			0x00000080
> -#define	BCH_FLASHLAYOUT0_NBLOCKS_MASK			(0xff << 24)
> -#define	BCH_FLASHLAYOUT0_NBLOCKS_OFFSET			24
> -#define	BCH_FLASHLAYOUT0_META_SIZE_MASK			(0xff << 16)
> -#define	BCH_FLASHLAYOUT0_META_SIZE_OFFSET		16
> -#define	BCH_FLASHLAYOUT0_ECC0_MASK			(0xf << 12)
> -#define	BCH_FLASHLAYOUT0_ECC0_OFFSET			12
> -#define	IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET		11
> -#define	BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET		0
> -#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1_MASK		BIT(10)
> -#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET		10
> -
> -#define BCH_FLASH0LAYOUT1			0x00000090
> -#define	BCH_FLASHLAYOUT1_PAGE_SIZE_MASK			(0xffff << 16)
> -#define	BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET		16
> -#define	BCH_FLASHLAYOUT1_ECCN_MASK			(0xf << 12)
> -#define	BCH_FLASHLAYOUT1_ECCN_OFFSET			12
> -#define	IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET		11
> -#define	BCH_FLASHLAYOUT1_GF13_0_GF14_1_MASK		BIT(10)
> -#define	BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET		10
> -#define	BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET		0
> -
> -#define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
> -
> -#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
> -#define	MXS_NAND_METADATA_SIZE			10
> -
> -#define	MXS_NAND_COMMAND_BUFFER_SIZE		32
> -
> -#define	MXS_NAND_BCH_TIMEOUT			10000
> -
>  enum gpmi_type {
>  	GPMI_MXS,
>  	GPMI_IMX6,
> @@ -503,7 +375,7 @@ static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctr
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		nand_info->cmd_queue_len;
> @@ -634,7 +506,7 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_READ |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		length;
>  
> @@ -659,7 +531,7 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length)
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA;
>  
>  	mxs_dma_desc_append(channel, d);
> @@ -713,7 +585,7 @@ static void mxs_nand_write_buf(struct nand_chip *chip, const uint8_t *buf,
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		length;
>  
> @@ -749,16 +621,22 @@ static void mxs_nand_config_bch(struct nand_chip *chip, int readlen)
>  	else
>  		chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
>  
> -	fl0 = (mxs_nand_ecc_chunk_cnt(readlen) - 1)
> -			<< BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
> -	fl0 |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
> -	fl0 |= (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET;
> -	fl0 |= chunk_size;
> +	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, mxs_nand_ecc_chunk_cnt(readlen) - 1);
> +	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, MXS_NAND_METADATA_SIZE);
> +	if (mxs_nand_is_imx6(nand_info))
> +		fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, chip->ecc.strength >> 1);
> +	else
> +		fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_ECC0, chip->ecc.strength >> 1);
> +	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, chunk_size);
>  	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
>  
> -	fl1 = readlen << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
> -	fl1 |= (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET;
> -	fl1 |= chunk_size;
> +	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, readlen);
> +	if (mxs_nand_is_imx6(nand_info))
> +		fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, chip->ecc.strength >> 1);
> +	else
> +		fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_ECCN, chip->ecc.strength >> 1);
> +
> +	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, chunk_size);
>  	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
>  }
>  
> @@ -781,7 +659,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA;
>  
>  	mxs_dma_desc_append(channel, d);
> @@ -797,7 +675,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_READ |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		readtotal;
>  	d->cmd.pio_words[1] = 0;
> @@ -829,7 +707,7 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		readtotal;
>  	d->cmd.pio_words[1] = 0;
> @@ -1037,7 +915,7 @@ static int mxs_nand_ecc_write_page(struct nand_chip *chip, const uint8_t *buf,
>  	d->cmd.pio_words[0] =
>  		GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
> +		FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA;
>  	d->cmd.pio_words[1] = 0;
>  	d->cmd.pio_words[2] =
> @@ -1276,23 +1154,21 @@ static void mxs_nand_mode_fcb_62bit(struct mxs_nand_info *nand_info)
>  	bch_regs = nand_info->bch_base;
>  
>  	/* 8 ecc_chunks */
> -	fl0 = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
> +	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, 7);
>  	/* 32 bytes for metadata */
> -	fl0 |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
> +	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, 32);
>  	/* using ECC62 level to be performed */
> -	fl0 |= 0x1F << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET;
> +	fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, 0x1f);
>  	/* 0x20 * 4 bytes of the data0 block */
> -	fl0 |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET;
> -	fl0 |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
> +	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, 0x20);
>  	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
>  
>  	/* 1024 for data + 838 for OOB */
> -	fl1 = BCH62_PAGESIZE << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
> +	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, BCH62_PAGESIZE);
>  	/* using ECC62 level to be performed */
> -	fl1 |= 0x1f << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET;
> +	fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, 0x1f);
>  	/* 0x20 * 4 bytes of the data0 block */
> -	fl1 |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET;
> -	fl1 |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
> +	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, 0x20);
>  	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
>  }
>  
> diff --git a/include/soc/imx/gpmi-nand.h b/include/soc/imx/gpmi-nand.h
> new file mode 100644
> index 0000000000..f7a2caa1d6
> --- /dev/null
> +++ b/include/soc/imx/gpmi-nand.h
> @@ -0,0 +1,114 @@
> +#ifndef __SOC_IMX_GPMI_NAND_H
> +#define __SOC_IMX_GPMI_NAND_H
> +
> +#include <linux/bitfield.h>
> +
> +#define GPMI_CTRL0				0x00000000
> +#define GPMI_CTRL0_SFTRST				BIT(31)
> +#define	GPMI_CTRL0_RUN					BIT(29)
> +#define	GPMI_CTRL0_DEV_IRQ_EN				BIT(28)
> +#define	GPMI_CTRL0_UDMA					BIT(26)
> +#define	GPMI_CTRL0_COMMAND_MODE				GENMASK(25, 24)
> +#define	GPMI_CTRL0_COMMAND_MODE_WRITE			(0x0 << 24)
> +#define	GPMI_CTRL0_COMMAND_MODE_READ			(0x1 << 24)
> +#define	GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE	(0x2 << 24)
> +#define	GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY		(0x3 << 24)
> +#define	GPMI_CTRL0_WORD_LENGTH				(1 << 23)
> +#define	GPMI_CTRL0_CS					GENMASK(22, 20)
> +#define	GPMI_CTRL0_ADDRESS				GENMASK(19, 17)
> +#define	GPMI_CTRL0_ADDRESS_NAND_DATA			(0x0 << 17)
> +#define	GPMI_CTRL0_ADDRESS_NAND_CLE			(0x1 << 17)
> +#define	GPMI_CTRL0_ADDRESS_NAND_ALE			(0x2 << 17)
> +#define	GPMI_CTRL0_ADDRESS_INCREMENT			BIT(16)
> +#define	GPMI_CTRL0_XFER_COUNT				GENMASK(15, 0)
> +
> +#define GPMI_CTRL1				0x00000060
> +#define GPMI_CTRL1_SET				0x00000064
> +#define GPMI_CTRL1_CLR				0x00000068
> +#define	GPMI_CTRL1_DECOUPLE_CS				BIT(24)
> +#define	GPMI_CTRL1_WRN_DLY(d)				(((d) & 0x3) << 22)
> +#define	GPMI_CTRL1_TIMEOUT_IRQ_EN			BIT(20)
> +#define	GPMI_CTRL1_GANGED_RDYBUSY			BIT(19)
> +#define	GPMI_CTRL1_BCH_MODE				BIT(18)
> +#define	GPMI_CTRL1_DLL_ENABLE				BIT(17)
> +#define	GPMI_CTRL1_HALF_PERIOD				BIT(16)
> +#define	GPMI_CTRL1_RDN_DELAY(d)				(((d) & 0xf) << 12)
> +#define	GPMI_CTRL1_DMA2ECC_MODE				BIT(11)
> +#define	GPMI_CTRL1_DEV_IRQ				BIT(10)
> +#define	GPMI_CTRL1_TIMEOUT_IRQ				BIT(9)
> +#define	GPMI_CTRL1_BURST_EN				BIT(8)
> +#define	GPMI_CTRL1_ABORT_WAIT_REQUEST			BIT(7)
> +#define	GPMI_CTRL1_ABORT_WAIT_FOR_READY			GENMASK(6, 4)
> +#define	GPMI_CTRL1_DEV_RESET				BIT(3)
> +#define	GPMI_CTRL1_ATA_IRQRDY_POLARITY			BIT(2)
> +#define	GPMI_CTRL1_CAMERA_MODE				BIT(1)
> +#define	GPMI_CTRL1_GPMI_MODE				BIT(0)
> +
> +#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS		0x0
> +#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS		0x1
> +#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS		0x2
> +#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY		0x3
> +
> +#define GPMI_TIMING0				0x00000070
> +
> +#define	GPMI_TIMING0_ADDRESS_SETUP(d)			(((d) & 0xff) << 16)
> +#define	GPMI_TIMING0_DATA_HOLD(d)			(((d) & 0xff) << 8)
> +#define	GPMI_TIMING0_DATA_SETUP(d)			(((d) & 0xff) << 0)
> +
> +#define GPMI_TIMING1				0x00000080
> +#define	GPMI_TIMING1_BUSY_TIMEOUT(d)			(((d) & 0xffff) << 16)
> +
> +#define	GPMI_ECCCTRL_HANDLE				GENMASK(31, 16)
> +#define	GPMI_ECCCTRL_ECC_CMD				GENMASK(14, 13)
> +#define	GPMI_ECCCTRL_ECC_CMD_DECODE			(0x0 << 13)
> +#define	GPMI_ECCCTRL_ECC_CMD_ENCODE			(0x1 << 13)
> +#define GPMI_ECCCTRL_RANDOMIZER_ENABLE                  BIT(11)
> +#define GPMI_ECCCTRL_RANDOMIZER_TYPE0                   0
> +#define GPMI_ECCCTRL_RANDOMIZER_TYPE1                   (1 << 9)
> +#define GPMI_ECCCTRL_RANDOMIZER_TYPE2                   (2 << 9)
> +#define	GPMI_ECCCTRL_ENABLE_ECC				BIT(12)
> +#define	GPMI_ECCCTRL_BUFFER_MASK			GENMASK(8, 0)
> +#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_AUXONLY		0x100
> +#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE		0x1ff
> +
> +#define GPMI_STAT				0x000000b0
> +#define	GPMI_STAT_READY_BUSY_OFFSET			24
> +
> +#define GPMI_DEBUG				0x000000c0
> +#define GPMI_DEBUG_READY0_OFFSET			28
> +
> +#define GPMI_VERSION				0x000000d0
> +#define GPMI_VERSION_MINOR_OFFSET			16
> +#define GPMI_VERSION_TYPE_MX23				0x0300
> +
> +#define BCH_CTRL				0x00000000
> +#define	BCH_CTRL_COMPLETE_IRQ				BIT(0)
> +#define	BCH_CTRL_COMPLETE_IRQ_EN			BIT(8)
> +
> +#define BCH_LAYOUTSELECT			0x00000070
> +
> +#define BCH_FLASH0LAYOUT0			0x00000080
> +#define	BCH_FLASHLAYOUT0_NBLOCKS			GENMASK(31, 24)
> +#define	BCH_FLASHLAYOUT0_META_SIZE			GENMASK(23, 16)
> +#define	BCH_FLASHLAYOUT0_ECC0				GENMASK(15, 12)
> +#define	IMX6_BCH_FLASHLAYOUT0_ECC0			GENMASK(15, 11)
> +#define	BCH_FLASHLAYOUT0_DATA0_SIZE			GENMASK(9, 0)
> +#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1			BIT(10)
> +
> +#define BCH_FLASH0LAYOUT1			0x00000090
> +#define	BCH_FLASHLAYOUT1_PAGE_SIZE			GENMASK(31, 16)
> +#define	BCH_FLASHLAYOUT1_ECCN				GENMASK(15, 12)
> +#define	IMX6_BCH_FLASHLAYOUT1_ECCN			GENMASK(15, 11)
> +#define	BCH_FLASHLAYOUT1_GF13_0_GF14_1			BIT(10)
> +#define	BCH_FLASHLAYOUT1_DATAN_SIZE			GENMASK(9, 0)
> +
> +#define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
> +
> +#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
> +#define	MXS_NAND_METADATA_SIZE			10
> +
> +#define	MXS_NAND_COMMAND_BUFFER_SIZE		32
> +
> +#define	MXS_NAND_BCH_TIMEOUT			10000
> +
> +#endif /* __SOC_IMX_GPMI_NAND_H */
> -- 
> 2.30.2
> 
> 
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 02/14] ARM: i.MX: xload nand: Use common register defines
  2022-11-01 15:30 ` [PATCH 02/14] ARM: i.MX: xload nand: Use common register defines Sascha Hauer
@ 2022-11-02  8:10   ` Marco Felsch
  0 siblings, 0 replies; 26+ messages in thread
From: Marco Felsch @ 2022-11-02  8:10 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On 22-11-01, Sascha Hauer wrote:
> We have a set of GPMI register defines in include/, so use them for the
> xload driver as well.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  arch/arm/mach-imx/xload-gpmi-nand.c | 66 ++++++++---------------------
>  1 file changed, 17 insertions(+), 49 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
> index 3a4f331ce6..6ac9af762f 100644
> --- a/arch/arm/mach-imx/xload-gpmi-nand.c
> +++ b/arch/arm/mach-imx/xload-gpmi-nand.c
> @@ -11,6 +11,7 @@
>  #include <mach/xload.h>
>  #include <soc/imx/imx-nand-bcb.h>
>  #include <linux/mtd/rawnand.h>
> +#include <soc/imx/gpmi-nand.h>
>  #include <mach/imx6-regs.h>
>  #include <mach/clock-imx6.h>

missing bitfield.h include.

Also should we say in the commit message that we are using the
FIELD_PREP now by this change?

Regards,
  Marco


>  
> @@ -203,39 +204,6 @@ static int mxs_dma_run(struct mxs_dma_chan *pchan, struct mxs_dma_cmd *pdesc,
>  
>  /* ----------------------------- NAND driver part -------------------------- */
>  
> -#define	GPMI_CTRL0					0x00000000
> -#define	GPMI_CTRL0_RUN					(1 << 29)
> -#define	GPMI_CTRL0_DEV_IRQ_EN				(1 << 28)
> -#define	GPMI_CTRL0_UDMA					(1 << 26)
> -#define	GPMI_CTRL0_COMMAND_MODE_MASK			(0x3 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_OFFSET			24
> -#define	GPMI_CTRL0_COMMAND_MODE_WRITE			(0x0 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_READ			(0x1 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE	(0x2 << 24)
> -#define	GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY		(0x3 << 24)
> -#define	GPMI_CTRL0_WORD_LENGTH				(1 << 23)
> -#define	GPMI_CTRL0_CS(cs)				((cs) << 20)
> -#define	GPMI_CTRL0_ADDRESS_MASK				(0x7 << 17)
> -#define	GPMI_CTRL0_ADDRESS_OFFSET			17
> -#define	GPMI_CTRL0_ADDRESS_NAND_DATA			(0x0 << 17)
> -#define	GPMI_CTRL0_ADDRESS_NAND_CLE			(0x1 << 17)
> -#define	GPMI_CTRL0_ADDRESS_NAND_ALE			(0x2 << 17)
> -#define	GPMI_CTRL0_ADDRESS_INCREMENT			(1 << 16)
> -#define	GPMI_CTRL0_XFER_COUNT_MASK			0xffff
> -#define	GPMI_CTRL0_XFER_COUNT_OFFSET			0
> -
> -#define	GPMI_ECCCTRL_ECC_CMD_DECODE			(0x0 << 13)
> -#define	GPMI_ECCCTRL_ENABLE_ECC				(1 << 12)
> -#define	GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE		0x1ff
> -
> -#define	BCH_CTRL					0x00000000
> -#define	BCH_CTRL_COMPLETE_IRQ				(1 << 0)
> -
> -#define	MXS_NAND_DMA_DESCRIPTOR_COUNT			6
> -#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE			512
> -#define	MXS_NAND_METADATA_SIZE				10
> -#define	MXS_NAND_COMMAND_BUFFER_SIZE			128
> -
>  struct mxs_nand_info {
>  	void __iomem *io_base;
>  	void __iomem *bch_base;
> @@ -352,7 +320,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		cmd_queue_len;
> @@ -372,7 +340,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		cmd_queue_len;
> @@ -386,7 +354,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA;
>  
>  	if (raw) {
> @@ -398,7 +366,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  			DMACMD_COMMAND_DMA_WRITE;
>  		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
>  			GPMI_CTRL0_WORD_LENGTH |
> -			GPMI_CTRL0_CS(info->cs) |
> +			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  			GPMI_CTRL0_ADDRESS_NAND_DATA |
>  			(writesize + oobsize);
>  		d->address = (dma_addr_t)databuf;
> @@ -408,7 +376,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  		d->data = DMACMD_WAIT4END | DMACMD_PIO_WORDS(6);
>  		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
>  			GPMI_CTRL0_WORD_LENGTH |
> -			GPMI_CTRL0_CS(info->cs) |
> +			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  			GPMI_CTRL0_ADDRESS_NAND_DATA |
>  			(writesize + oobsize);
>  		d->pio_words[1] = 0;
> @@ -426,7 +394,7 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  			DMACMD_PIO_WORDS(3);
>  		d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
>  			GPMI_CTRL0_WORD_LENGTH |
> -			GPMI_CTRL0_CS(info->cs) |
> +			FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  			GPMI_CTRL0_ADDRESS_NAND_DATA |
>  			(writesize + oobsize);
>  	}
> @@ -499,7 +467,7 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		cmd_queue_len;
> @@ -512,7 +480,7 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
>  		DMACMD_COMMAND_DMA_WRITE;
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		(1);
>  	d->address = (dma_addr_t)databuf;
> @@ -557,7 +525,7 @@ static int mxs_nand_reset(struct mxs_nand_info *info, void *databuf)
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		cmd_queue_len;
> @@ -629,7 +597,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		cmd_queue_len;
> @@ -643,7 +611,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA;
>  
>  	/* Compile DMA descriptor - read. */
> @@ -654,7 +622,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
>  		DMACMD_COMMAND_DMA_WRITE;
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		(sizeof(struct nand_onfi_params));
>  	d->address = (dma_addr_t)databuf;
> @@ -733,7 +701,7 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		cmd_queue_len;
> @@ -746,7 +714,7 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
>  		DMACMD_COMMAND_DMA_WRITE;
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		(sizeof(struct onfi_header));
>  	d->address = (dma_addr_t)databuf;
> @@ -811,7 +779,7 @@ static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf)
>  
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_CLE |
>  		GPMI_CTRL0_ADDRESS_INCREMENT |
>  		cmd_queue_len;
> @@ -824,7 +792,7 @@ static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf)
>  		DMACMD_COMMAND_DMA_WRITE;
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
>  		GPMI_CTRL0_WORD_LENGTH |
> -		GPMI_CTRL0_CS(info->cs) |
> +		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
>  		(sizeof(struct readid_data));
>  	d->address = (dma_addr_t)databuf;
> -- 
> 2.30.2
> 
> 
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 03/14] ARM: i.MX: xload nand: add common readid
  2022-11-01 15:30 ` [PATCH 03/14] ARM: i.MX: xload nand: add common readid Sascha Hauer
@ 2022-11-02  8:23   ` Marco Felsch
  0 siblings, 0 replies; 26+ messages in thread
From: Marco Felsch @ 2022-11-02  8:23 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On 22-11-01, Sascha Hauer wrote:
> mxs_nand_check_onfi() and mxs_nand_read_id() setup the same DMA
> descriptors with only a small difference. factor out a common
> read_id function from it and share the code.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  arch/arm/mach-imx/xload-gpmi-nand.c | 148 ++++++++++------------------
>  1 file changed, 54 insertions(+), 94 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
> index 6ac9af762f..ffbd5c22e3 100644
> --- a/arch/arm/mach-imx/xload-gpmi-nand.c
> +++ b/arch/arm/mach-imx/xload-gpmi-nand.c
> @@ -668,7 +668,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf)
>  	return ret;
>  }
>  
> -static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
> +static int mxs_nand_read_id(struct mxs_nand_info *info, u8 adr, void *databuf, size_t len)
>  {
>  	int ret;
>  	u8 *cmd_buf;
> @@ -676,13 +676,6 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
>  	int descnum = 0;
>  	int cmd_queue_len;
>  
> -	struct onfi_header {
> -		u8 byte0;
> -		u8 byte1;
> -		u8 byte2;
> -		u8 byte3;
> -	} onfi_head;
> -
>  	memset(info->desc, 0,
>  		sizeof(*info->desc) * MXS_NAND_DMA_DESCRIPTOR_COUNT);
>  
> @@ -692,7 +685,7 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
>  	d = &info->desc[descnum++];
>  	d->address = (dma_addr_t)(cmd_buf);
>  	cmd_buf[cmd_queue_len++] = NAND_CMD_READID;
> -	cmd_buf[cmd_queue_len++] = 0x20;
> +	cmd_buf[cmd_queue_len++] = adr;
>  
>  	d->data = DMACMD_COMMAND_DMA_READ |
>  		DMACMD_WAIT4END |
> @@ -710,13 +703,13 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
>  	d = &info->desc[descnum++];
>  	d->data = DMACMD_WAIT4END |
>  		DMACMD_PIO_WORDS(1) |
> -		DMACMD_XFER_COUNT(sizeof(struct onfi_header)) |
> +		DMACMD_XFER_COUNT(len) |
>  		DMACMD_COMMAND_DMA_WRITE;
>  	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
>  		GPMI_CTRL0_WORD_LENGTH |
>  		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
>  		GPMI_CTRL0_ADDRESS_NAND_DATA |
> -		(sizeof(struct onfi_header));
> +		len;
>  	d->address = (dma_addr_t)databuf;
>  
>  	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
> @@ -725,119 +718,86 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
>  
>  	/* Execute the DMA chain. */
>  	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
> -	if (ret) {
> +	if (ret)
>  		pr_err("DMA read error\n");
> -		return ret;
> -	}
>  
> -	memcpy(&onfi_head, databuf, sizeof(struct onfi_header));
> +	return ret;
> +}
> +
> +struct onfi_header {
> +	u8 byte0;
> +	u8 byte1;
> +	u8 byte2;
> +	u8 byte3;
> +};
> +
> +static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf)
> +{
> +	int ret;
> +	struct onfi_header *onfi_head = databuf;
> +
> +	ret = mxs_nand_read_id(info, 0x20, databuf, sizeof(struct onfi_header));
> +	if (ret)
> +		return ret;
>  
> -	pr_debug("ONFI Byte0: 0x%x\n", onfi_head.byte0);
> -	pr_debug("ONFI Byte1: 0x%x\n", onfi_head.byte1);
> -	pr_debug("ONFI Byte2: 0x%x\n", onfi_head.byte2);
> -	pr_debug("ONFI Byte3: 0x%x\n", onfi_head.byte3);
> +	pr_debug("ONFI Byte0: 0x%x\n", onfi_head->byte0);
> +	pr_debug("ONFI Byte1: 0x%x\n", onfi_head->byte1);
> +	pr_debug("ONFI Byte2: 0x%x\n", onfi_head->byte2);
> +	pr_debug("ONFI Byte3: 0x%x\n", onfi_head->byte3);
>  
>  	/* check if returned values correspond to ascii characters "ONFI" */
> -	if (onfi_head.byte0 != 0x4f || onfi_head.byte1 != 0x4e ||
> -		onfi_head.byte2 != 0x46 || onfi_head.byte3 != 0x49)
> +	if (onfi_head->byte0 != 0x4f || onfi_head->byte1 != 0x4e ||
> +		onfi_head->byte2 != 0x46 || onfi_head->byte3 != 0x49)

Nit: Should we change the compare to something like this:
  onfi_head->byte0 != 'O'
  onfi_head->byte1 != 'N'

This way we can remove the comment.

>  		return 1;
>  
>  	return 0;
>  }
>  
> +struct readid_data {
> +	u8 byte0;
> +	u8 byte1;
> +	u8 byte2;
> +	u8 byte3;
> +	u8 byte4;
> +} id_data;

The id_data variable is unsused.

Regards,
  Marco

>  static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf)
>  {
>  	int ret;
> -	u8 *cmd_buf;
> -	struct mxs_dma_cmd *d;
> -	int descnum = 0;
> -	int cmd_queue_len;
> -
> -	struct readid_data {
> -		u8 byte0;
> -		u8 byte1;
> -		u8 byte2;
> -		u8 byte3;
> -		u8 byte4;
> -	} id_data;
> -
> -	memset(info->desc, 0,
> -		sizeof(*info->desc) * MXS_NAND_DMA_DESCRIPTOR_COUNT);
> +	struct readid_data *id_data = databuf;
>  
> -	/* Compile DMA descriptor - READID */
> -	cmd_buf = info->cmd_buf;
> -	cmd_queue_len = 0;
> -	d = &info->desc[descnum++];
> -	d->address = (dma_addr_t)(cmd_buf);
> -	cmd_buf[cmd_queue_len++] = NAND_CMD_READID;
> -	cmd_buf[cmd_queue_len++] = 0x00;
> -
> -	d->data = DMACMD_COMMAND_DMA_READ |
> -		DMACMD_WAIT4END |
> -		DMACMD_PIO_WORDS(1) |
> -		DMACMD_XFER_COUNT(cmd_queue_len);
> -
> -	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE |
> -		GPMI_CTRL0_WORD_LENGTH |
> -		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
> -		GPMI_CTRL0_ADDRESS_NAND_CLE |
> -		GPMI_CTRL0_ADDRESS_INCREMENT |
> -		cmd_queue_len;
> -
> -	/* Compile DMA descriptor - read. */
> -	d = &info->desc[descnum++];
> -	d->data = DMACMD_WAIT4END |
> -		DMACMD_PIO_WORDS(1) |
> -		DMACMD_XFER_COUNT(sizeof(struct readid_data)) |
> -		DMACMD_COMMAND_DMA_WRITE;
> -	d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ |
> -		GPMI_CTRL0_WORD_LENGTH |
> -		FIELD_PREP(GPMI_CTRL0_CS, info->cs) |
> -		GPMI_CTRL0_ADDRESS_NAND_DATA |
> -		(sizeof(struct readid_data));
> -	d->address = (dma_addr_t)databuf;
> -
> -	/* Compile DMA descriptor - de-assert the NAND lock and interrupt. */
> -	d = &info->desc[descnum++];
> -	d->data = DMACMD_IRQ | DMACMD_DEC_SEM;
> -
> -	/* Execute the DMA chain. */
> -	ret = mxs_dma_run(info->dma_channel, info->desc, descnum);
> -	if (ret) {
> -		pr_err("DMA read error\n");
> +	ret = mxs_nand_read_id(info, 0x0, databuf, sizeof(struct readid_data));
> +	if (ret)
>  		return ret;
> -	}
> -
> -	memcpy(&id_data, databuf, sizeof(struct readid_data));
>  
> -	pr_debug("NAND Byte0: 0x%x\n", id_data.byte0);
> -	pr_debug("NAND Byte1: 0x%x\n", id_data.byte1);
> -	pr_debug("NAND Byte2: 0x%x\n", id_data.byte2);
> -	pr_debug("NAND Byte3: 0x%x\n", id_data.byte3);
> -	pr_debug("NAND Byte4: 0x%x\n", id_data.byte4);
> +	pr_debug("NAND Byte0: 0x%x\n", id_data->byte0);
> +	pr_debug("NAND Byte1: 0x%x\n", id_data->byte1);
> +	pr_debug("NAND Byte2: 0x%x\n", id_data->byte2);
> +	pr_debug("NAND Byte3: 0x%x\n", id_data->byte3);
> +	pr_debug("NAND Byte4: 0x%x\n", id_data->byte4);
>  
> -	if (id_data.byte0 == 0xff || id_data.byte1 == 0xff ||
> -		id_data.byte2 == 0xff || id_data.byte3 == 0xff ||
> -		id_data.byte4 == 0xff) {
> +	if (id_data->byte0 == 0xff || id_data->byte1 == 0xff ||
> +		id_data->byte2 == 0xff || id_data->byte3 == 0xff ||
> +		id_data->byte4 == 0xff) {
>  		pr_err("\"READ ID\" returned 0xff, possible error!\n");
>  		return -EOVERFLOW;
>  	}
>  
>  	/* Fill the NAND organization struct with data */
>  	info->organization.bits_per_cell =
> -		(1 << ((id_data.byte2 >> 2) & 0x3)) * 2;
> +		(1 << ((id_data->byte2 >> 2) & 0x3)) * 2;
>  	info->organization.pagesize =
> -		(1 << (id_data.byte3 & 0x3)) * SZ_1K;
> -	info->organization.oobsize = id_data.byte3 & 0x4 ?
> +		(1 << (id_data->byte3 & 0x3)) * SZ_1K;
> +	info->organization.oobsize = id_data->byte3 & 0x4 ?
>  		info->organization.pagesize / 512 * 16 :
>  		info->organization.pagesize / 512 * 8;
>  	info->organization.pages_per_eraseblock =
> -		(1 << ((id_data.byte3 >> 4) & 0x3)) * SZ_64K /
> +		(1 << ((id_data->byte3 >> 4) & 0x3)) * SZ_64K /
>  		info->organization.pagesize;
>  	info->organization.planes_per_lun =
> -		1 << ((id_data.byte4 >> 2) & 0x3);
> +		1 << ((id_data->byte4 >> 2) & 0x3);
>  	info->nand_size = info->organization.planes_per_lun *
> -		(1 << ((id_data.byte4 >> 4) & 0x7)) * SZ_8M;
> +		(1 << ((id_data->byte4 >> 4) & 0x7)) * SZ_8M;
>  	info->organization.eraseblocks_per_lun = info->nand_size /
>  		(info->organization.pages_per_eraseblock *
>  		info->organization.pagesize);
> -- 
> 2.30.2
> 
> 
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 08/14] ARM: i.MX: xload nand: Pull ECC status checking out of read page
  2022-11-01 15:30 ` [PATCH 08/14] ARM: i.MX: xload nand: Pull ECC status checking out of read page Sascha Hauer
@ 2022-11-02  8:33   ` Marco Felsch
  0 siblings, 0 replies; 26+ messages in thread
From: Marco Felsch @ 2022-11-02  8:33 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On 22-11-01, Sascha Hauer wrote:
> The read page code can be reused by upcoming i.MX7 support, but the ECC
> checking will be different. Pull ECC status checking out of the read
> page code to make that reusable on i.MX7.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  arch/arm/mach-imx/xload-gpmi-nand.c | 42 ++++++++++++++++++++---------
>  1 file changed, 29 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
> index dc4cc45be0..543ec108ba 100644
> --- a/arch/arm/mach-imx/xload-gpmi-nand.c
> +++ b/arch/arm/mach-imx/xload-gpmi-nand.c
> @@ -236,8 +236,6 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  	int cmd_queue_len;
>  	u8 *cmd_buf;
>  	int ret;
> -	uint8_t	*status;
> -	int i;
>  	int timeout;
>  	int descnum = 0;
>  	int max_pagenum = info->nand_size /
> @@ -375,20 +373,26 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  	writel(BCH_CTRL_COMPLETE_IRQ,
>  		bch_regs + BCH_CTRL + STMP_OFFSET_REG_CLR);
>  
> -	/* Loop over status bytes, accumulating ECC status. */
> -	status = databuf + writesize + mxs_nand_aux_status_offset();
> -	for (i = 0; i < writesize / MXS_NAND_CHUNK_DATA_CHUNK_SIZE; i++) {
> -		if (status[i] == 0xfe) {
> -			ret = -EBADMSG;
> -			goto err;
> -		}
> -	}
> -
>  	ret = 0;
>  err:
>  	return ret;
>  }
>  
> +static int mxs_nand_get_ecc_status(struct mxs_nand_info *info, void *databuf)
> +{
> +	uint8_t	*status;
> +	int i;
> +
> +	/* Loop over status bytes, accumulating ECC status. */
> +	status = databuf + info->organization.pagesize + mxs_nand_aux_status_offset();
> +	for (i = 0; i < info->organization.pagesize / MXS_NAND_CHUNK_DATA_CHUNK_SIZE; i++) {
> +		if (status[i] == 0xfe)
> +			return -EBADMSG;
> +	}
> +
> +	return 0;
> +}
> +
>  static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf)
>  {
>  	int ret;
> @@ -851,6 +855,10 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf)
>  		if (ret)
>  			continue;
>  
> +		ret = mxs_nand_get_ecc_status(info, databuf);
> +		if (ret)
> +			continue;
> +
>  		memcpy(fcb, databuf + mxs_nand_aux_status_offset(),
>  			sizeof(*fcb));
>  
> @@ -886,7 +894,11 @@ static int get_dbbt(struct mxs_nand_info *info, void *databuf)
>  		page = startpage + i * info->organization.pages_per_eraseblock;
>  
>  		ret = mxs_nand_read_page(info, info->organization.pagesize,
> -			info->organization.oobsize, page, databuf, 0);
> +			info->organization.oobsize, page, databuf, 0, false);

Maybe I didn't saw the change, but where did you changed the function
declaration?

Regards,
  Marco

> +		if (ret)
> +			continue;
> +
> +		ret = mxs_nand_get_ecc_status(info, databuf);
>  		if (ret)
>  			continue;
>  
> @@ -900,7 +912,11 @@ static int get_dbbt(struct mxs_nand_info *info, void *databuf)
>  			return -ENOENT;
>  
>  		ret = mxs_nand_read_page(info, info->organization.pagesize,
> -			info->organization.oobsize, page + 4, databuf, 0);
> +			info->organization.oobsize, page + 4, databuf, 0, false);
> +		if (ret)
> +			continue;
> +
> +		ret = mxs_nand_get_ecc_status(info, databuf);
>  		if (ret)
>  			continue;
>  
> -- 
> 2.30.2
> 
> 
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 12/14] ARM: i.MX: xload nand: Move mxs_nand_mode_fcb_62bit() to header file
  2022-11-01 15:30 ` [PATCH 12/14] ARM: i.MX: xload nand: Move mxs_nand_mode_fcb_62bit() to header file Sascha Hauer
@ 2022-11-02  8:37   ` Marco Felsch
  0 siblings, 0 replies; 26+ messages in thread
From: Marco Felsch @ 2022-11-02  8:37 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On 22-11-01, Sascha Hauer wrote:
> mxs_nand_mode_fcb_62bit() can be shared between the regular MTD NAND
> driver and the upcoming i.MX7 xload driver. Move to header file.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/mtd/nand/nand_mxs.c | 34 ++--------------------------------
>  include/soc/imx/gpmi-nand.h | 27 +++++++++++++++++++++++++++
>  2 files changed, 29 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
> index b162c23743..79a8fbdefa 100644
> --- a/drivers/mtd/nand/nand_mxs.c
> +++ b/drivers/mtd/nand/nand_mxs.c
> @@ -1123,36 +1123,6 @@ static int mxs_nand_block_markbad(struct nand_chip *chip , loff_t ofs)
>  	return 0;
>  }
>  
> -#define BCH62_WRITESIZE		1024
> -#define BCH62_OOBSIZE		838
> -#define BCH62_PAGESIZE		(BCH62_WRITESIZE + BCH62_OOBSIZE)
> -
> -static void mxs_nand_mode_fcb_62bit(struct mxs_nand_info *nand_info)
> -{
> -	void __iomem *bch_regs;
> -	u32 fl0, fl1;
> -
> -	bch_regs = nand_info->bch_base;
> -
> -	/* 8 ecc_chunks */
> -	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, 7);
> -	/* 32 bytes for metadata */
> -	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, 32);
> -	/* using ECC62 level to be performed */
> -	fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, 0x1f);
> -	/* 0x20 * 4 bytes of the data0 block */
> -	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, 0x20);
> -	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
> -
> -	/* 1024 for data + 838 for OOB */
> -	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, BCH62_PAGESIZE);
> -	/* using ECC62 level to be performed */
> -	fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, 0x1f);
> -	/* 0x20 * 4 bytes of the data0 block */
> -	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, 0x20);
> -	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
> -}
> -
>  int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size)
>  {
>  	struct nand_chip *chip;
> @@ -1174,7 +1144,7 @@ int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size)
>  
>  	page = block * (mtd->erasesize / mtd->writesize);
>  
> -	mxs_nand_mode_fcb_62bit(nand_info);
> +	mxs_nand_mode_fcb_62bit(nand_info->bch_base);
>  
>  	nand_read_page_op(chip, page, 0, NULL, 0);
>  
> @@ -1238,7 +1208,7 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size)
>  	nand_info = chip->priv;
>  	channel = nand_info->dma_channel_base;
>  
> -	mxs_nand_mode_fcb_62bit(nand_info);
> +	mxs_nand_mode_fcb_62bit(nand_info->bch_base);
>  
>  	nand_select_target(chip, 0);
>  
> diff --git a/include/soc/imx/gpmi-nand.h b/include/soc/imx/gpmi-nand.h
> index f7a2caa1d6..8c30dee8ab 100644
> --- a/include/soc/imx/gpmi-nand.h
> +++ b/include/soc/imx/gpmi-nand.h
> @@ -111,4 +111,31 @@
>  
>  #define	MXS_NAND_BCH_TIMEOUT			10000
>  
> +#define BCH62_WRITESIZE		1024
> +#define BCH62_OOBSIZE		838
> +#define BCH62_PAGESIZE		(BCH62_WRITESIZE + BCH62_OOBSIZE)
> +

Nit: Maybe put a small comment here so we can easily see why we are
doing this.

Regards,
  Marco

> +static void mxs_nand_mode_fcb_62bit(void __iomem *bch_regs)
> +{
> +	u32 fl0, fl1;
> +
> +	/* 8 ecc_chunks */
> +	fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, 7);
> +	/* 32 bytes for metadata */
> +	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, 32);
> +	/* using ECC62 level to be performed */
> +	fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, 0x1f);
> +	/* 0x20 * 4 bytes of the data0 block */
> +	fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, 0x20);
> +	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
> +
> +	/* 1024 for data + 838 for OOB */
> +	fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, BCH62_PAGESIZE);
> +	/* using ECC62 level to be performed */
> +	fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, 0x1f);
> +	/* 0x20 * 4 bytes of the data0 block */
> +	fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, 0x20);
> +	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
> +}
> +
>  #endif /* __SOC_IMX_GPMI_NAND_H */
> -- 
> 2.30.2
> 
> 
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 13/14] ARM: i.MX: xload nand: Implement i.MX7 support
  2022-11-01 15:30 ` [PATCH 13/14] ARM: i.MX: xload nand: Implement i.MX7 support Sascha Hauer
@ 2022-11-02  8:41   ` Marco Felsch
  2022-11-02  8:46     ` Sascha Hauer
  0 siblings, 1 reply; 26+ messages in thread
From: Marco Felsch @ 2022-11-02  8:41 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On 22-11-01, Sascha Hauer wrote:
> i.MX7 xload NAND support works like on i.MX6, but the FCB is in a
> different format. The FCB page uses BCH62 ECC, has 8 ECC chunks with
> 128 bytes each with a resulting total page size of 1862 bytes. Also
> the page data is written with a pseudo randomizer enabled.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  arch/arm/mach-imx/include/mach/imx7-regs.h |  1 +
>  arch/arm/mach-imx/include/mach/xload.h     |  1 +
>  arch/arm/mach-imx/xload-gpmi-nand.c        | 95 ++++++++++++++++++++--
>  3 files changed, 91 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/include/mach/imx7-regs.h b/arch/arm/mach-imx/include/mach/imx7-regs.h
> index 1ee7d86e0e..379be9e062 100644
> --- a/arch/arm/mach-imx/include/mach/imx7-regs.h
> +++ b/arch/arm/mach-imx/include/mach/imx7-regs.h
> @@ -118,6 +118,7 @@
>  #define MX7_ENET1_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3E0000)
>  #define MX7_ENET2_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3F0000)
>  
> +#define	MX7_APBH_BASE			0x33000000
>  #define MX7_GPMI_BASE			0x33002000
>  #define MX7_BCH_BASE			0x33004000
>  
> diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h
> index 82bf663c42..ca0055aee2 100644
> --- a/arch/arm/mach-imx/include/mach/xload.h
> +++ b/arch/arm/mach-imx/include/mach/xload.h
> @@ -12,6 +12,7 @@ int imx6_spi_start_image(int instance);
>  int imx6_esdhc_start_image(int instance);
>  int imx6_nand_start_image(void);
>  int imx7_esdhc_start_image(int instance);
> +int imx7_nand_start_image(void);
>  int imx8m_esdhc_load_image(int instance, bool start);
>  int imx8mn_esdhc_load_image(int instance, bool start);
>  int imx8mp_esdhc_load_image(int instance, bool start);
> diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
> index 7e4033d74f..edffd69e6b 100644
> --- a/arch/arm/mach-imx/xload-gpmi-nand.c
> +++ b/arch/arm/mach-imx/xload-gpmi-nand.c
> @@ -13,6 +13,7 @@
>  #include <linux/mtd/rawnand.h>
>  #include <soc/imx/gpmi-nand.h>
>  #include <mach/imx6-regs.h>
> +#include <mach/imx7-regs.h>
>  #include <mach/clock-imx6.h>
>  #include <dma/apbh-dma.h>
>  
> @@ -228,7 +229,7 @@ static uint32_t mxs_nand_aux_status_offset(void)
>  }
>  
>  static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
> -		int oobsize, int pagenum, void *databuf, int raw)
> +		int oobsize, int pagenum, void *databuf, int raw, bool randomizer)

Here the change comes, so this anwers my question.

Regards,
  Marco

>  {
>  	void __iomem *bch_regs = info->bch_base;
>  	unsigned column = 0;
> @@ -332,6 +333,12 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
>  		d->pio_words[4] = (dma_addr_t)databuf;
>  		d->pio_words[5] = (dma_addr_t)(databuf + writesize);
>  
> +		if (randomizer) {
> +			d->pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
> +					   GPMI_ECCCTRL_RANDOMIZER_TYPE2;
> +			d->pio_words[3] |= (pagenum % 256) << 16;
> +		}
> +
>  		/* Compile DMA descriptor - disable the BCH block. */
>  		d = &info->desc[descnum++];
>  		d->data = MXS_DMA_DESC_NAND_WAIT_4_READY |
> @@ -841,7 +848,7 @@ static uint32_t calc_chksum(void *buf, size_t size)
>  	return ~chksum;
>  }
>  
> -static int get_fcb(struct mxs_nand_info *info, void *databuf)
> +static int imx6_get_fcb(struct mxs_nand_info *info, void *databuf)
>  {
>  	int i, pagenum, ret;
>  	uint32_t checksum;
> @@ -849,13 +856,13 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf)
>  
>  	/* First page read fails, this shouldn't be necessary */
>  	mxs_nand_read_page(info, info->organization.pagesize,
> -		info->organization.oobsize, 0, databuf, 1);
> +		info->organization.oobsize, 0, databuf, 1, false);
>  
>  	for (i = 0; i < 4; i++) {
>  		pagenum = info->organization.pages_per_eraseblock * i;
>  
>  		ret = mxs_nand_read_page(info, info->organization.pagesize,
> -			info->organization.oobsize, pagenum, databuf, 1);
> +			info->organization.oobsize, pagenum, databuf, 1, false);
>  		if (ret)
>  			continue;
>  
> @@ -887,6 +894,66 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf)
>  	return -EINVAL;
>  }
>  
> +static int imx7_get_fcb_n(struct mxs_nand_info *info, void *databuf, int num)
> +{
> +	int ret;
> +	int flips = 0;
> +	uint8_t	*status;
> +	int i;
> +
> +	ret = mxs_nand_read_page(info, BCH62_WRITESIZE, BCH62_OOBSIZE,
> +				 info->organization.pages_per_eraseblock * num, databuf, 0, true);
> +	if (ret)
> +		return ret;
> +
> +	/* Loop over status bytes, accumulating ECC status. */
> +	status = databuf + BCH62_WRITESIZE + 32;
> +
> +	for (i = 0; i < 8; i++) {
> +		switch (status[i]) {
> +		case 0x0:
> +			break;
> +		case 0xff:
> +			/*
> +			 * A status of 0xff means the chunk is erased, but due to
> +			 * the randomizer we see this as random data. Explicitly
> +			 * memset it.
> +			 */
> +			memset(databuf + 0x80 * i, 0xff, 0x80);
> +			break;
> +		case 0xfe:
> +			return -EBADMSG;
> +		default:
> +			flips += status[0];
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int imx7_get_fcb(struct mxs_nand_info *info, void *databuf)
> +{
> +	int i, ret;
> +	struct fcb_block *fcb = &info->fcb;
> +
> +	mxs_nand_mode_fcb_62bit(info->bch_base);
> +
> +	for (i = 0; i < 4; i++) {
> +		ret = imx7_get_fcb_n(info, databuf, i);
> +		if (!ret)
> +			break;
> +	}
> +
> +	if (ret) {
> +		pr_err("Cannot find FCB\n");
> +	} else {
> +		memcpy(fcb, databuf, sizeof(*fcb));
> +	}
> +
> +	return ret;
> +}
> +
>  static int get_dbbt(struct mxs_nand_info *info, void *databuf)
>  {
>  	int i, ret;
> @@ -991,7 +1058,7 @@ static int read_firmware(struct mxs_nand_info *info, int startpage,
>  		}
>  
>  		ret = mxs_nand_read_page(info, pagesize, oobsize,
> -			curpage, dest, 0);
> +			curpage, dest, 0, false);
>  		if (ret) {
>  			pr_debug("Failed to read page %d\n", curpage);
>  			return ret;
> @@ -1012,6 +1079,7 @@ struct imx_nand_params {
>  	struct mxs_nand_info info;
>  	struct apbh_dma apbh;
>  	void *sdram;
> +	int (*get_fcb)(struct mxs_nand_info *info, void *databuf);
>  };
>  
>  static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
> @@ -1036,7 +1104,7 @@ static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params,
>  	if (ret)
>  		return ret;
>  
> -	ret = get_fcb(info, databuf);
> +	ret = params->get_fcb(info, databuf);
>  	if (ret)
>  		return ret;
>  
> @@ -1120,6 +1188,7 @@ int imx6_nand_start_image(void)
>  		.apbh.regs = IOMEM(MX6_APBH_BASE_ADDR),
>  		.apbh.id = IMX28_DMA,
>  		.sdram = (void *)MX6_MMDC_PORT01_BASE_ADDR,
> +		.get_fcb = imx6_get_fcb,
>  	};
>  
>  	/* Apply ERR007117 workaround */
> @@ -1127,3 +1196,17 @@ int imx6_nand_start_image(void)
>  
>  	return imx_nand_start_image(&params);
>  }
> +
> +int imx7_nand_start_image(void)
> +{
> +	static struct imx_nand_params params = {
> +		.info.io_base = IOMEM(MX7_GPMI_BASE),
> +		.info.bch_base = IOMEM(MX7_BCH_BASE),
> +		.apbh.regs = IOMEM(MX7_APBH_BASE),
> +		.apbh.id = IMX28_DMA,
> +		.sdram = (void *)MX7_DDR_BASE_ADDR,
> +		.get_fcb = imx7_get_fcb,
> +	};
> +
> +	return imx_nand_start_image(&params);
> +}
> -- 
> 2.30.2
> 
> 
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command
  2022-11-01 15:30 ` [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command Sascha Hauer
@ 2022-11-02  8:44   ` Marco Felsch
  2022-11-02 10:55     ` Sascha Hauer
  0 siblings, 1 reply; 26+ messages in thread
From: Marco Felsch @ 2022-11-02  8:44 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On 22-11-01, Sascha Hauer wrote:
> The FCB on NAND has a special page layout and thus can't be read with
> the normal MTD driver. Add a fcb command for printing information about
> the installed FCB on the console.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  commands/Kconfig          |   9 ++
>  common/imx-bbu-nand-fcb.c | 195 ++++++++++++++++++++++++++++----------
>  2 files changed, 153 insertions(+), 51 deletions(-)
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 9894ecb9aa..cab72b9226 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -326,6 +326,15 @@ config CMD_SLICE
>  	  command can be used to print informations about slices and also to manipulate
>  	  them on the command line for debugging purposes.
>  
> +config CMD_FCB
> +	depends on BAREBOX_UPDATE_IMX_NAND_FCB
> +	tristate
> +	prompt "fcb"
> +	help
> +	  Several i.MX SoCs booting from NAND flash need a so called Flash Control Block
> +	  at the beginning of the NAND device. The fcb command prints information about
> +	  the FCB.
> +
>  # end Information commands
>  endmenu
>  
> diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
> index 05bee912e4..39425c7fc3 100644
> --- a/common/imx-bbu-nand-fcb.c
> +++ b/common/imx-bbu-nand-fcb.c
> @@ -14,6 +14,8 @@
>  #include <linux/sizes.h>
>  #include <bbu.h>
>  #include <fs.h>
> +#include <command.h>
> +#include <complete.h>
>  #include <linux/mtd/mtd-abi.h>
>  #include <linux/mtd/nand_mxs.h>
>  #include <linux/mtd/mtd.h>
> @@ -284,57 +286,57 @@ static __maybe_unused void dump_fcb(void *buf)
>  {
>  	struct fcb_block *fcb = buf;
>  
> -	pr_debug("Checksum:                   0x%08x\n", fcb->Checksum);
> -	pr_debug("FingerPrint:                0x%08x\n", fcb->FingerPrint);
> -	pr_debug("Version:                    0x%08x\n", fcb->Version);
> -	pr_debug("DataSetup:                  0x%02x\n", fcb->DataSetup);
> -	pr_debug("DataHold:                   0x%02x\n", fcb->DataHold);
> -	pr_debug("AddressSetup:               0x%02x\n", fcb->AddressSetup);
> -	pr_debug("DSAMPLE_TIME:               0x%02x\n", fcb->DSAMPLE_TIME);
> -	pr_debug("NandTimingState:            0x%02x\n", fcb->NandTimingState);
> -	pr_debug("REA:                        0x%02x\n", fcb->REA);
> -	pr_debug("RLOH:                       0x%02x\n", fcb->RLOH);
> -	pr_debug("RHOH:                       0x%02x\n", fcb->RHOH);
> -	pr_debug("PageDataSize:               0x%08x\n", fcb->PageDataSize);
> -	pr_debug("TotalPageSize:              0x%08x\n", fcb->TotalPageSize);
> -	pr_debug("SectorsPerBlock:            0x%08x\n", fcb->SectorsPerBlock);
> -	pr_debug("NumberOfNANDs:              0x%08x\n", fcb->NumberOfNANDs);
> -	pr_debug("TotalInternalDie:           0x%08x\n", fcb->TotalInternalDie);
> -	pr_debug("CellType:                   0x%08x\n", fcb->CellType);
> -	pr_debug("EccBlockNEccType:           0x%08x\n", fcb->EccBlockNEccType);
> -	pr_debug("EccBlock0Size:              0x%08x\n", fcb->EccBlock0Size);
> -	pr_debug("EccBlockNSize:              0x%08x\n", fcb->EccBlockNSize);
> -	pr_debug("EccBlock0EccType:           0x%08x\n", fcb->EccBlock0EccType);
> -	pr_debug("MetadataBytes:              0x%08x\n", fcb->MetadataBytes);
> -	pr_debug("NumEccBlocksPerPage:        0x%08x\n", fcb->NumEccBlocksPerPage);
> -	pr_debug("EccBlockNEccLevelSDK:       0x%08x\n", fcb->EccBlockNEccLevelSDK);
> -	pr_debug("EccBlock0SizeSDK:           0x%08x\n", fcb->EccBlock0SizeSDK);
> -	pr_debug("EccBlockNSizeSDK:           0x%08x\n", fcb->EccBlockNSizeSDK);
> -	pr_debug("EccBlock0EccLevelSDK:       0x%08x\n", fcb->EccBlock0EccLevelSDK);
> -	pr_debug("NumEccBlocksPerPageSDK:     0x%08x\n", fcb->NumEccBlocksPerPageSDK);
> -	pr_debug("MetadataBytesSDK:           0x%08x\n", fcb->MetadataBytesSDK);
> -	pr_debug("EraseThreshold:             0x%08x\n", fcb->EraseThreshold);
> -	pr_debug("BootPatch:                  0x%08x\n", fcb->BootPatch);
> -	pr_debug("PatchSectors:               0x%08x\n", fcb->PatchSectors);
> -	pr_debug("Firmware1_startingPage:     0x%08x\n", fcb->Firmware1_startingPage);
> -	pr_debug("Firmware2_startingPage:     0x%08x\n", fcb->Firmware2_startingPage);
> -	pr_debug("PagesInFirmware1:           0x%08x\n", fcb->PagesInFirmware1);
> -	pr_debug("PagesInFirmware2:           0x%08x\n", fcb->PagesInFirmware2);
> -	pr_debug("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress);
> -	pr_debug("BadBlockMarkerByte:         0x%08x\n", fcb->BadBlockMarkerByte);
> -	pr_debug("BadBlockMarkerStartBit:     0x%08x\n", fcb->BadBlockMarkerStartBit);
> -	pr_debug("BBMarkerPhysicalOffset:     0x%08x\n", fcb->BBMarkerPhysicalOffset);
> -	pr_debug("BCHType:                    0x%08x\n", fcb->BCHType);
> -	pr_debug("TMTiming2_ReadLatency:      0x%08x\n", fcb->TMTiming2_ReadLatency);
> -	pr_debug("TMTiming2_PreambleDelay:    0x%08x\n", fcb->TMTiming2_PreambleDelay);
> -	pr_debug("TMTiming2_CEDelay:          0x%08x\n", fcb->TMTiming2_CEDelay);
> -	pr_debug("TMTiming2_PostambleDelay:   0x%08x\n", fcb->TMTiming2_PostambleDelay);
> -	pr_debug("TMTiming2_CmdAddPause:      0x%08x\n", fcb->TMTiming2_CmdAddPause);
> -	pr_debug("TMTiming2_DataPause:        0x%08x\n", fcb->TMTiming2_DataPause);
> -	pr_debug("TMSpeed:                    0x%08x\n", fcb->TMSpeed);
> -	pr_debug("TMTiming1_BusyTimeout:      0x%08x\n", fcb->TMTiming1_BusyTimeout);
> -	pr_debug("DISBBM:                     0x%08x\n", fcb->DISBBM);
> -	pr_debug("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData);
> +	printf("Checksum:                   0x%08x\n", fcb->Checksum);
> +	printf("FingerPrint:                0x%08x\n", fcb->FingerPrint);
> +	printf("Version:                    0x%08x\n", fcb->Version);
> +	printf("DataSetup:                  0x%02x\n", fcb->DataSetup);
> +	printf("DataHold:                   0x%02x\n", fcb->DataHold);
> +	printf("AddressSetup:               0x%02x\n", fcb->AddressSetup);
> +	printf("DSAMPLE_TIME:               0x%02x\n", fcb->DSAMPLE_TIME);
> +	printf("NandTimingState:            0x%02x\n", fcb->NandTimingState);
> +	printf("REA:                        0x%02x\n", fcb->REA);
> +	printf("RLOH:                       0x%02x\n", fcb->RLOH);
> +	printf("RHOH:                       0x%02x\n", fcb->RHOH);
> +	printf("PageDataSize:               0x%08x\n", fcb->PageDataSize);
> +	printf("TotalPageSize:              0x%08x\n", fcb->TotalPageSize);
> +	printf("SectorsPerBlock:            0x%08x\n", fcb->SectorsPerBlock);
> +	printf("NumberOfNANDs:              0x%08x\n", fcb->NumberOfNANDs);
> +	printf("TotalInternalDie:           0x%08x\n", fcb->TotalInternalDie);
> +	printf("CellType:                   0x%08x\n", fcb->CellType);
> +	printf("EccBlockNEccType:           0x%08x\n", fcb->EccBlockNEccType);
> +	printf("EccBlock0Size:              0x%08x\n", fcb->EccBlock0Size);
> +	printf("EccBlockNSize:              0x%08x\n", fcb->EccBlockNSize);
> +	printf("EccBlock0EccType:           0x%08x\n", fcb->EccBlock0EccType);
> +	printf("MetadataBytes:              0x%08x\n", fcb->MetadataBytes);
> +	printf("NumEccBlocksPerPage:        0x%08x\n", fcb->NumEccBlocksPerPage);
> +	printf("EccBlockNEccLevelSDK:       0x%08x\n", fcb->EccBlockNEccLevelSDK);
> +	printf("EccBlock0SizeSDK:           0x%08x\n", fcb->EccBlock0SizeSDK);
> +	printf("EccBlockNSizeSDK:           0x%08x\n", fcb->EccBlockNSizeSDK);
> +	printf("EccBlock0EccLevelSDK:       0x%08x\n", fcb->EccBlock0EccLevelSDK);
> +	printf("NumEccBlocksPerPageSDK:     0x%08x\n", fcb->NumEccBlocksPerPageSDK);
> +	printf("MetadataBytesSDK:           0x%08x\n", fcb->MetadataBytesSDK);
> +	printf("EraseThreshold:             0x%08x\n", fcb->EraseThreshold);
> +	printf("BootPatch:                  0x%08x\n", fcb->BootPatch);
> +	printf("PatchSectors:               0x%08x\n", fcb->PatchSectors);
> +	printf("Firmware1_startingPage:     0x%08x\n", fcb->Firmware1_startingPage);
> +	printf("Firmware2_startingPage:     0x%08x\n", fcb->Firmware2_startingPage);
> +	printf("PagesInFirmware1:           0x%08x\n", fcb->PagesInFirmware1);
> +	printf("PagesInFirmware2:           0x%08x\n", fcb->PagesInFirmware2);
> +	printf("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress);
> +	printf("BadBlockMarkerByte:         0x%08x\n", fcb->BadBlockMarkerByte);
> +	printf("BadBlockMarkerStartBit:     0x%08x\n", fcb->BadBlockMarkerStartBit);
> +	printf("BBMarkerPhysicalOffset:     0x%08x\n", fcb->BBMarkerPhysicalOffset);
> +	printf("BCHType:                    0x%08x\n", fcb->BCHType);
> +	printf("TMTiming2_ReadLatency:      0x%08x\n", fcb->TMTiming2_ReadLatency);
> +	printf("TMTiming2_PreambleDelay:    0x%08x\n", fcb->TMTiming2_PreambleDelay);
> +	printf("TMTiming2_CEDelay:          0x%08x\n", fcb->TMTiming2_CEDelay);
> +	printf("TMTiming2_PostambleDelay:   0x%08x\n", fcb->TMTiming2_PostambleDelay);
> +	printf("TMTiming2_CmdAddPause:      0x%08x\n", fcb->TMTiming2_CmdAddPause);
> +	printf("TMTiming2_DataPause:        0x%08x\n", fcb->TMTiming2_DataPause);
> +	printf("TMSpeed:                    0x%08x\n", fcb->TMSpeed);
> +	printf("TMTiming1_BusyTimeout:      0x%08x\n", fcb->TMTiming1_BusyTimeout);
> +	printf("DISBBM:                     0x%08x\n", fcb->DISBBM);
> +	printf("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData);
>  }
>  
>  static __maybe_unused ssize_t raw_read_page(struct mtd_info *mtd, void *dst, loff_t offset)
> @@ -1625,3 +1627,94 @@ int imx7_bbu_nand_register_handler(const char *name, unsigned long flags)
>  	return ret;
>  }
>  #endif
> +
> +static void dump_fcb_n(struct fcb_block **fcbs, int n)
> +{
> +	int i;
> +
> +	if (!n || !fcbs[n])
> +		goto skip_compare;
> +
> +	for (i = 0; i < n; i++) {
> +		if (!fcbs[i] || !fcbs[n])
> +			continue;
> +
> +		if (!memcmp(fcbs[i], fcbs[n], sizeof(struct fcb_block))) {
> +			printf("FCB block#%d: same as FCB block#%d\n", n, i);
> +			return;
> +		}
> +	}
> +
> +skip_compare:
> +	if (fcbs[n]) {
> +		printf("FCB block#%d:\n", n);
> +		dump_fcb(fcbs[n]);
> +	} else {
> +		printf("FCB block#%d: NULL\n", n);
> +	}
> +}
> +
> +#ifdef CONFIG_ARCH_IMX28

Why this #ifdef? Can't we do this by cpu_is_mx28()?

Regards,
  Marco

> +static int fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb)
> +{
> +	return fcb_read_hamming_13_8(mtd, block, retfcb);
> +}
> +#else
> +static int fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb)
> +{
> +	if (cpu_is_mx7())
> +		return imx7_fcb_read(mtd, block, retfcb);
> +	else if (fcb_is_bch_encoded())
> +		return fcb_read_bch(mtd, block, retfcb);
> +	else
> +		return fcb_read_hamming_13_8(mtd, block, retfcb);
> +}
> +#endif
> +
> +static int cmd_fcb(int argc, char *argv[])
> +{
> +	struct cdev *cdev;
> +	struct mtd_info *mtd;
> +	struct fcb_block *fcb[4] = {};
> +	int i, ret;
> +
> +	cdev = cdev_open_by_name("nand0", O_RDONLY);
> +	if (!cdev) {
> +		printf("Cannot open nand0\n");
> +		return COMMAND_ERROR;
> +	}
> +
> +	mtd = cdev->mtd;
> +	if (!mtd) {
> +		ret = COMMAND_ERROR;
> +		goto out;
> +	}
> +
> +	for (i = 0; i < 4; i++)
> +		fcb_read(mtd, i, &fcb[i]);
> +
> +	for (i = 0; i < 4; i++)
> +		dump_fcb_n(fcb, i);
> +
> +	for (i = 0; i < 4; i++)
> +		free(fcb[i]);
> +
> +	ret = 0;
> +
> +out:
> +	cdev_close(cdev);
> +
> +	return ret;
> +}
> +
> +BAREBOX_CMD_HELP_START(fcb)
> +BAREBOX_CMD_HELP_TEXT("Dump FCB as found on /dev/nand0")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(fcb)
> +	.cmd = cmd_fcb,
> +	BAREBOX_CMD_DESC("Dump Flash Control Block (FCB)")
> +	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
> +	BAREBOX_CMD_HELP(cmd_fcb_help)
> +	BAREBOX_CMD_COMPLETE(empty_complete)
> +BAREBOX_CMD_END
> -- 
> 2.30.2
> 
> 
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 13/14] ARM: i.MX: xload nand: Implement i.MX7 support
  2022-11-02  8:41   ` Marco Felsch
@ 2022-11-02  8:46     ` Sascha Hauer
  0 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-02  8:46 UTC (permalink / raw)
  To: Marco Felsch; +Cc: Barebox List

On Wed, Nov 02, 2022 at 09:41:18AM +0100, Marco Felsch wrote:
> Hi Sascha,
> 
> On 22-11-01, Sascha Hauer wrote:
> > i.MX7 xload NAND support works like on i.MX6, but the FCB is in a
> > different format. The FCB page uses BCH62 ECC, has 8 ECC chunks with
> > 128 bytes each with a resulting total page size of 1862 bytes. Also
> > the page data is written with a pseudo randomizer enabled.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> >  arch/arm/mach-imx/include/mach/imx7-regs.h |  1 +
> >  arch/arm/mach-imx/include/mach/xload.h     |  1 +
> >  arch/arm/mach-imx/xload-gpmi-nand.c        | 95 ++++++++++++++++++++--
> >  3 files changed, 91 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/arm/mach-imx/include/mach/imx7-regs.h b/arch/arm/mach-imx/include/mach/imx7-regs.h
> > index 1ee7d86e0e..379be9e062 100644
> > --- a/arch/arm/mach-imx/include/mach/imx7-regs.h
> > +++ b/arch/arm/mach-imx/include/mach/imx7-regs.h
> > @@ -118,6 +118,7 @@
> >  #define MX7_ENET1_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3E0000)
> >  #define MX7_ENET2_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3F0000)
> >  
> > +#define	MX7_APBH_BASE			0x33000000
> >  #define MX7_GPMI_BASE			0x33002000
> >  #define MX7_BCH_BASE			0x33004000
> >  
> > diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h
> > index 82bf663c42..ca0055aee2 100644
> > --- a/arch/arm/mach-imx/include/mach/xload.h
> > +++ b/arch/arm/mach-imx/include/mach/xload.h
> > @@ -12,6 +12,7 @@ int imx6_spi_start_image(int instance);
> >  int imx6_esdhc_start_image(int instance);
> >  int imx6_nand_start_image(void);
> >  int imx7_esdhc_start_image(int instance);
> > +int imx7_nand_start_image(void);
> >  int imx8m_esdhc_load_image(int instance, bool start);
> >  int imx8mn_esdhc_load_image(int instance, bool start);
> >  int imx8mp_esdhc_load_image(int instance, bool start);
> > diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c
> > index 7e4033d74f..edffd69e6b 100644
> > --- a/arch/arm/mach-imx/xload-gpmi-nand.c
> > +++ b/arch/arm/mach-imx/xload-gpmi-nand.c
> > @@ -13,6 +13,7 @@
> >  #include <linux/mtd/rawnand.h>
> >  #include <soc/imx/gpmi-nand.h>
> >  #include <mach/imx6-regs.h>
> > +#include <mach/imx7-regs.h>
> >  #include <mach/clock-imx6.h>
> >  #include <dma/apbh-dma.h>
> >  
> > @@ -228,7 +229,7 @@ static uint32_t mxs_nand_aux_status_offset(void)
> >  }
> >  
> >  static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize,
> > -		int oobsize, int pagenum, void *databuf, int raw)
> > +		int oobsize, int pagenum, void *databuf, int raw, bool randomizer)
> 
> Here the change comes, so this anwers my question.

Yes, moved the offending hunk here.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command
  2022-11-02  8:44   ` Marco Felsch
@ 2022-11-02 10:55     ` Sascha Hauer
  2022-11-02 11:01       ` Marco Felsch
  0 siblings, 1 reply; 26+ messages in thread
From: Sascha Hauer @ 2022-11-02 10:55 UTC (permalink / raw)
  To: Marco Felsch; +Cc: Barebox List

On Wed, Nov 02, 2022 at 09:44:41AM +0100, Marco Felsch wrote:
> > +static void dump_fcb_n(struct fcb_block **fcbs, int n)
> > +{
> > +	int i;
> > +
> > +	if (!n || !fcbs[n])
> > +		goto skip_compare;
> > +
> > +	for (i = 0; i < n; i++) {
> > +		if (!fcbs[i] || !fcbs[n])
> > +			continue;
> > +
> > +		if (!memcmp(fcbs[i], fcbs[n], sizeof(struct fcb_block))) {
> > +			printf("FCB block#%d: same as FCB block#%d\n", n, i);
> > +			return;
> > +		}
> > +	}
> > +
> > +skip_compare:
> > +	if (fcbs[n]) {
> > +		printf("FCB block#%d:\n", n);
> > +		dump_fcb(fcbs[n]);
> > +	} else {
> > +		printf("FCB block#%d: NULL\n", n);
> > +	}
> > +}
> > +
> > +#ifdef CONFIG_ARCH_IMX28
> 
> Why this #ifdef? Can't we do this by cpu_is_mx28()?

i.MX28 is a different architecture in barebox, it's in
arch/arm/mach-mxs/. We do not have the cpu_is_mx7() and cpu_is_mx6ul()
macros there.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command
  2022-11-02 10:55     ` Sascha Hauer
@ 2022-11-02 11:01       ` Marco Felsch
  2022-11-02 11:29         ` Sascha Hauer
  0 siblings, 1 reply; 26+ messages in thread
From: Marco Felsch @ 2022-11-02 11:01 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

On 22-11-02, Sascha Hauer wrote:
> On Wed, Nov 02, 2022 at 09:44:41AM +0100, Marco Felsch wrote:
> > > +static void dump_fcb_n(struct fcb_block **fcbs, int n)
> > > +{
> > > +	int i;
> > > +
> > > +	if (!n || !fcbs[n])
> > > +		goto skip_compare;
> > > +
> > > +	for (i = 0; i < n; i++) {
> > > +		if (!fcbs[i] || !fcbs[n])
> > > +			continue;
> > > +
> > > +		if (!memcmp(fcbs[i], fcbs[n], sizeof(struct fcb_block))) {
> > > +			printf("FCB block#%d: same as FCB block#%d\n", n, i);
> > > +			return;
> > > +		}
> > > +	}
> > > +
> > > +skip_compare:
> > > +	if (fcbs[n]) {
> > > +		printf("FCB block#%d:\n", n);
> > > +		dump_fcb(fcbs[n]);
> > > +	} else {
> > > +		printf("FCB block#%d: NULL\n", n);
> > > +	}
> > > +}
> > > +
> > > +#ifdef CONFIG_ARCH_IMX28
> > 
> > Why this #ifdef? Can't we do this by cpu_is_mx28()?
> 
> i.MX28 is a different architecture in barebox, it's in
> arch/arm/mach-mxs/. We do not have the cpu_is_mx7() and cpu_is_mx6ul()
> macros there.

Argh.. always messing the mxs/mxc stuff up in my head. Got your point,
but shouldn't we add the macros instead of adding the #ifdef here?

Regards,
  Marco

> 
> Sascha
> 
> -- 
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command
  2022-11-02 11:01       ` Marco Felsch
@ 2022-11-02 11:29         ` Sascha Hauer
  0 siblings, 0 replies; 26+ messages in thread
From: Sascha Hauer @ 2022-11-02 11:29 UTC (permalink / raw)
  To: Marco Felsch; +Cc: Barebox List

On Wed, Nov 02, 2022 at 12:01:15PM +0100, Marco Felsch wrote:
> On 22-11-02, Sascha Hauer wrote:
> > On Wed, Nov 02, 2022 at 09:44:41AM +0100, Marco Felsch wrote:
> > > > +static void dump_fcb_n(struct fcb_block **fcbs, int n)
> > > > +{
> > > > +	int i;
> > > > +
> > > > +	if (!n || !fcbs[n])
> > > > +		goto skip_compare;
> > > > +
> > > > +	for (i = 0; i < n; i++) {
> > > > +		if (!fcbs[i] || !fcbs[n])
> > > > +			continue;
> > > > +
> > > > +		if (!memcmp(fcbs[i], fcbs[n], sizeof(struct fcb_block))) {
> > > > +			printf("FCB block#%d: same as FCB block#%d\n", n, i);
> > > > +			return;
> > > > +		}
> > > > +	}
> > > > +
> > > > +skip_compare:
> > > > +	if (fcbs[n]) {
> > > > +		printf("FCB block#%d:\n", n);
> > > > +		dump_fcb(fcbs[n]);
> > > > +	} else {
> > > > +		printf("FCB block#%d: NULL\n", n);
> > > > +	}
> > > > +}
> > > > +
> > > > +#ifdef CONFIG_ARCH_IMX28
> > > 
> > > Why this #ifdef? Can't we do this by cpu_is_mx28()?
> > 
> > i.MX28 is a different architecture in barebox, it's in
> > arch/arm/mach-mxs/. We do not have the cpu_is_mx7() and cpu_is_mx6ul()
> > macros there.
> 
> Argh.. always messing the mxs/mxc stuff up in my head. Got your point,
> but shouldn't we add the macros instead of adding the #ifdef here?

Right. We have several cpu_is_mx* macros there already, so we can just
add the missing ones and avoid the ifdeffery.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2022-11-02 11:31 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-01 15:30 [PATCH 00/14] Add i.MX7 NAND xload support Sascha Hauer
2022-11-01 15:30 ` [PATCH 01/14] mtd: nand: nand-mxs: Move register definitions to separate file Sascha Hauer
2022-11-02  8:08   ` Marco Felsch
2022-11-01 15:30 ` [PATCH 02/14] ARM: i.MX: xload nand: Use common register defines Sascha Hauer
2022-11-02  8:10   ` Marco Felsch
2022-11-01 15:30 ` [PATCH 03/14] ARM: i.MX: xload nand: add common readid Sascha Hauer
2022-11-02  8:23   ` Marco Felsch
2022-11-01 15:30 ` [PATCH 04/14] dma: apbh-dma: Simplify code Sascha Hauer
2022-11-01 15:30 ` [PATCH 05/14] dma: apbh-dma: unify register defines Sascha Hauer
2022-11-01 15:30 ` [PATCH 06/14] ARM: i.MX: xload-gpmi-nand: refactor for more SoC support Sascha Hauer
2022-11-01 15:30 ` [PATCH 07/14] imx-bbu-nand-fcb: pull printing debug info out of get_fcb() Sascha Hauer
2022-11-01 15:30 ` [PATCH 08/14] ARM: i.MX: xload nand: Pull ECC status checking out of read page Sascha Hauer
2022-11-02  8:33   ` Marco Felsch
2022-11-01 15:30 ` [PATCH 09/14] ARM: i.MX: xload nand: Use final page layout from FCB Sascha Hauer
2022-11-01 15:30 ` [PATCH 10/14] imx-bbu-nand-fcb: Fix reading FCB information from BCH registers Sascha Hauer
2022-11-01 15:30 ` [PATCH 11/14] ARM: i.MX: xload nand: reset NAND before accessing it Sascha Hauer
2022-11-01 15:30 ` [PATCH 12/14] ARM: i.MX: xload nand: Move mxs_nand_mode_fcb_62bit() to header file Sascha Hauer
2022-11-02  8:37   ` Marco Felsch
2022-11-01 15:30 ` [PATCH 13/14] ARM: i.MX: xload nand: Implement i.MX7 support Sascha Hauer
2022-11-02  8:41   ` Marco Felsch
2022-11-02  8:46     ` Sascha Hauer
2022-11-01 15:30 ` [PATCH 14/14] imx-bbu-nand-fcb: Add fcb command Sascha Hauer
2022-11-02  8:44   ` Marco Felsch
2022-11-02 10:55     ` Sascha Hauer
2022-11-02 11:01       ` Marco Felsch
2022-11-02 11:29         ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox