mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/7] Add i.MX7 NAND boot support
@ 2022-09-30 12:15 Sascha Hauer
  2022-09-30 12:15 ` [PATCH 1/7] mtd: nand-mxs: refactor flash layout configuration Sascha Hauer
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

NAND boot on i.MX7 is the same as on i.MX6, just a little different.
This series adds a barebox update handler to allow writing barebox
to NAND flash.

Sascha

Johannes Zink (4):
  mtd: nand-mxs: refactor flash layout configuration
  mtd: nand-mxs: add i.MX7 FCB write support
  imx-bbu-nand-fcb: isolate i.MX28 specific parts
  imx-bbu-nand-fcb: extend for i.MX7 support

Sascha Hauer (3):
  mtd: nand-mxs: Factor out a bch read function
  imx-bbu-nand-fcb: pass imx_handler further down
  imx-bbu-nand-fcb: add fcb_read/fcb_write function hooks

 arch/arm/mach-imx/include/mach/imx7-regs.h |   3 +
 common/Kconfig                             |   2 +-
 common/imx-bbu-nand-fcb.c                  | 267 ++++++++++++++----
 drivers/mtd/nand/nand_mxs.c                | 297 ++++++++++++++++++---
 include/bbu.h                              |   5 +
 include/linux/mtd/nand_mxs.h               |   4 +
 include/soc/imx/imx-nand-bcb.h             |  11 +
 7 files changed, 492 insertions(+), 97 deletions(-)

-- 
2.30.2




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

* [PATCH 1/7] mtd: nand-mxs: refactor flash layout configuration
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
@ 2022-09-30 12:15 ` Sascha Hauer
  2022-09-30 12:15 ` [PATCH 2/7] mtd: nand-mxs: Factor out a bch read function Sascha Hauer
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

From: Johannes Zink <j.zink@pengutronix.de>

No functional change.
---
 drivers/mtd/nand/nand_mxs.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 8991758e2b..8fc5105d98 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -732,25 +732,24 @@ static void mxs_nand_config_bch(struct nand_chip *chip, int readlen)
 	struct mxs_nand_info *nand_info = chip->priv;
 	int chunk_size;
 	void __iomem *bch_regs = nand_info->bch_base;
+	u32 fl0, fl1;
 
 	if (mxs_nand_is_imx6(nand_info))
 		chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE >> 2;
 	else
 		chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
 
-	writel((mxs_nand_ecc_chunk_cnt(readlen) - 1)
-			<< BCH_FLASHLAYOUT0_NBLOCKS_OFFSET |
-		MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET |
-		(chip->ecc.strength >> 1)
-			<< IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET |
-		chunk_size,
-		bch_regs + BCH_FLASH0LAYOUT0);
-
-	writel(readlen	<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET |
-		(chip->ecc.strength >> 1)
-			<< IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET |
-		chunk_size,
-		bch_regs + BCH_FLASH0LAYOUT1);
+	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;
+	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;
+	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
 }
 
 /*
-- 
2.30.2




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

* [PATCH 2/7] mtd: nand-mxs: Factor out a bch read function
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
  2022-09-30 12:15 ` [PATCH 1/7] mtd: nand-mxs: refactor flash layout configuration Sascha Hauer
@ 2022-09-30 12:15 ` Sascha Hauer
  2022-09-30 12:15 ` [PATCH 3/7] mtd: nand-mxs: add i.MX7 FCB write support Sascha Hauer
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

We can reuse setting up the DMA descriptors for reading the FCBs in
upcoming i.MX7 FCB support. Factor out a function for it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_mxs.c | 67 ++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 8fc5105d98..1d0a38dc9e 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -752,31 +752,11 @@ static void mxs_nand_config_bch(struct nand_chip *chip, int readlen)
 	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
 }
 
-/*
- * Read a page from NAND.
- */
-static int __mxs_nand_ecc_read_page(struct nand_chip *chip,
-					uint8_t *buf, int oob_required, int page,
-					int readlen)
+static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtotal)
 {
-	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct mxs_nand_info *nand_info = chip->priv;
 	struct mxs_dma_desc *d;
-	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
-	uint32_t corrected = 0, failed = 0;
-	uint8_t	*status;
-	unsigned int  max_bitflips = 0;
-	int i, ret, readtotal, nchunks;
-
-	nand_read_page_op(chip, page, 0, NULL, 0);
-
-	readlen = roundup(readlen, MXS_NAND_CHUNK_DATA_CHUNK_SIZE);
-	nchunks = mxs_nand_ecc_chunk_cnt(readlen);
-	readtotal =  MXS_NAND_METADATA_SIZE;
-	readtotal += MXS_NAND_CHUNK_DATA_CHUNK_SIZE * nchunks;
-	readtotal += DIV_ROUND_UP(13 * chip->ecc.strength * nchunks, 8);
-
-	mxs_nand_config_bch(chip, readtotal);
+	int ret;
 
 	/* Compile the DMA descriptor - wait for ready. */
 	d = mxs_nand_get_dma_desc(nand_info);
@@ -853,16 +833,49 @@ static int __mxs_nand_ecc_read_page(struct nand_chip *chip,
 	/* Execute the DMA chain. */
 	ret = mxs_dma_go(channel);
 	if (ret) {
-		printf("MXS NAND: DMA read error (ecc)\n");
-		goto rtn;
+		dev_err(nand_info->dev, "MXS NAND: DMA read error (ecc)\n");
+		goto out;
 	}
 
 	ret = mxs_nand_wait_for_bch_complete(nand_info);
 	if (ret) {
-		printf("MXS NAND: BCH read timeout\n");
-		goto rtn;
+		dev_err(nand_info->dev, "MXS NAND: BCH read timeout\n");
+		goto out;
 	}
 
+out:
+	mxs_nand_return_dma_descs(nand_info);
+
+	return ret;
+}
+
+/*
+ * Read a page from NAND.
+ */
+static int __mxs_nand_ecc_read_page(struct nand_chip *chip,
+					uint8_t *buf, int oob_required, int page,
+					int readlen)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxs_nand_info *nand_info = chip->priv;
+	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
+	uint32_t corrected = 0, failed = 0;
+	uint8_t	*status;
+	unsigned int  max_bitflips = 0;
+	int i, ret, readtotal, nchunks;
+
+	nand_read_page_op(chip, page, 0, NULL, 0);
+
+	readlen = roundup(readlen, MXS_NAND_CHUNK_DATA_CHUNK_SIZE);
+	nchunks = mxs_nand_ecc_chunk_cnt(readlen);
+	readtotal =  MXS_NAND_METADATA_SIZE;
+	readtotal += MXS_NAND_CHUNK_DATA_CHUNK_SIZE * nchunks;
+	readtotal += DIV_ROUND_UP(13 * chip->ecc.strength * nchunks, 8);
+
+	mxs_nand_config_bch(chip, readtotal);
+
+	mxs_nand_do_bch_read(chip, channel, readtotal);
+
 	/* Read DMA completed, now do the mark swapping. */
 	mxs_nand_swap_block_mark(chip, nand_info->data_buf, nand_info->oob_buf);
 
@@ -942,7 +955,7 @@ static int __mxs_nand_ecc_read_page(struct nand_chip *chip,
 	chip->oob_poi[0] = nand_info->oob_buf[0];
 
 	ret = 0;
-rtn:
+
 	mxs_nand_return_dma_descs(nand_info);
 
 	mxs_nand_config_bch(chip, mtd->writesize + mtd->oobsize);
-- 
2.30.2




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

* [PATCH 3/7] mtd: nand-mxs: add i.MX7 FCB write support
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
  2022-09-30 12:15 ` [PATCH 1/7] mtd: nand-mxs: refactor flash layout configuration Sascha Hauer
  2022-09-30 12:15 ` [PATCH 2/7] mtd: nand-mxs: Factor out a bch read function Sascha Hauer
@ 2022-09-30 12:15 ` Sascha Hauer
  2022-09-30 12:15 ` [PATCH 4/7] imx-bbu-nand-fcb: isolate i.MX28 specific parts Sascha Hauer
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

From: Johannes Zink <j.zink@pengutronix.de>

The FCB on the i.MX7 is written in BCH62 mode and with randomizer
enabled. This needs special FCB read/write functions. Add them to the
driver.

Signed-off-by: Johannes Zink <j.zink@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_mxs.c    | 209 ++++++++++++++++++++++++++++++++-
 include/linux/mtd/nand_mxs.h   |   4 +
 include/soc/imx/imx-nand-bcb.h |  11 ++
 3 files changed, 222 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 1d0a38dc9e..5faa17a4bd 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -108,6 +108,10 @@
 #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
@@ -138,6 +142,9 @@
 #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)
@@ -145,6 +152,9 @@
 #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
 
@@ -752,7 +762,8 @@ static void mxs_nand_config_bch(struct nand_chip *chip, int readlen)
 	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
 }
 
-static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtotal)
+static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtotal,
+				bool randomizer, int page)
 {
 	struct mxs_nand_info *nand_info = chip->priv;
 	struct mxs_dma_desc *d;
@@ -798,6 +809,12 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot
 	d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
 	d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
 
+	if (randomizer) {
+		d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
+				       GPMI_ECCCTRL_RANDOMIZER_TYPE2;
+		d->cmd.pio_words[3] |= (page % 256) << 16;
+	}
+
 	mxs_dma_desc_append(channel, d);
 
 	/* Compile the DMA descriptor - disable the BCH block. */
@@ -874,7 +891,7 @@ static int __mxs_nand_ecc_read_page(struct nand_chip *chip,
 
 	mxs_nand_config_bch(chip, readtotal);
 
-	mxs_nand_do_bch_read(chip, channel, readtotal);
+	mxs_nand_do_bch_read(chip, channel, readtotal, false, page);
 
 	/* Read DMA completed, now do the mark swapping. */
 	mxs_nand_swap_block_mark(chip, nand_info->data_buf, nand_info->oob_buf);
@@ -1247,6 +1264,194 @@ 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 = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
+	/* 32 bytes for metadata */
+	fl0 |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
+	/* using ECC62 level to be performed */
+	fl0 |= 0x1F << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET;
+	/* 0x20 * 4 bytes of the data0 block */
+	fl0 |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET;
+	fl0 |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
+	writel(fl0, bch_regs + BCH_FLASH0LAYOUT0);
+
+	/* 1024 for data + 838 for OOB */
+	fl1 = BCH62_PAGESIZE << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
+	/* using ECC62 level to be performed */
+	fl1 |= 0x1f << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET;
+	/* 0x20 * 4 bytes of the data0 block */
+	fl1 |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET;
+	fl1 |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
+	writel(fl1, bch_regs + BCH_FLASH0LAYOUT1);
+}
+
+int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size)
+{
+	struct nand_chip *chip;
+	struct mxs_nand_info *nand_info;
+	struct mtd_info *mtd = mxs_nand_mtd;
+	int ret;
+	int page;
+	int flips = 0;
+	uint8_t	*status;
+	int i;
+
+	if (!mtd)
+		return -ENODEV;
+
+	chip = mtd_to_nand(mtd);
+	nand_info = chip->priv;
+
+	nand_select_target(chip, 0);
+
+	page = block * (mtd->erasesize / mtd->writesize);
+
+	mxs_nand_mode_fcb_62bit(nand_info);
+
+	nand_read_page_op(chip, page, 0, NULL, 0);
+
+	ret = mxs_nand_do_bch_read(chip, 0, BCH62_PAGESIZE, true, page);
+	if (ret)
+		goto out;
+
+	/* Read DMA completed, now do the mark swapping. */
+	mxs_nand_swap_block_mark(chip, nand_info->data_buf, nand_info->oob_buf);
+
+	/* Loop over status bytes, accumulating ECC status. */
+	status = nand_info->oob_buf + 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(nand_info->data_buf + 0x80 * i, 0xff, 0x80);
+			break;
+		case 0xfe:
+			ret = -EBADMSG;
+			goto out;
+		default:
+			flips += status[0];
+			break;
+		}
+	}
+
+	memcpy(buf, nand_info->data_buf, size);
+
+out:
+	mxs_nand_config_bch(chip, mtd->writesize + mtd->oobsize);
+	nand_deselect_target(chip);
+
+	return ret;
+}
+
+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;
+	uint32_t channel;
+	int ret = 0;
+	int page;
+
+	if (!mtd)
+		return -ENODEV;
+
+	if (size > BCH62_WRITESIZE)
+		return -EINVAL;
+
+	chip = mtd_to_nand(mtd);
+	nand_info = chip->priv;
+	channel = nand_info->dma_channel_base;
+
+	mxs_nand_mode_fcb_62bit(nand_info);
+
+	nand_select_target(chip, 0);
+
+	page = block * (mtd->erasesize / mtd->writesize);
+
+	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+
+	memset(nand_info->data_buf, 0x0, BCH62_WRITESIZE);
+	memcpy(nand_info->data_buf, buf, size);
+
+	/* Handle block mark swapping. */
+	mxs_nand_swap_block_mark(chip, nand_info->data_buf, nand_info->oob_buf);
+
+	/* 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 |
+		      MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
+		      (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+
+	d->cmd.address = 0;
+
+	d->cmd.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 |
+			      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->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
+			       GPMI_ECCCTRL_RANDOMIZER_TYPE2;
+	/*
+	 * Write NAND page number needed to be randomized
+	 * to GPMI_ECCCOUNT register.
+	 *
+	 * 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);
+
+	/* Execute the DMA chain. */
+	ret = mxs_dma_go(channel);
+	if (ret) {
+		dev_err(nand_info->dev, "MXS NAND: DMA write error: %d\n", ret);
+		goto out;
+	}
+
+	ret = mxs_nand_wait_for_bch_complete(nand_info);
+	if (ret) {
+		dev_err(nand_info->dev, "MXS NAND: BCH write timeout\n");
+		goto out;
+	}
+
+out:
+	mxs_nand_return_dma_descs(nand_info);
+
+	if (!ret)
+		ret = nand_prog_page_end_op(chip);
+
+	mxs_nand_config_bch(chip, mtd->writesize + mtd->oobsize);
+	nand_deselect_target(chip);
+
+	return ret;
+}
+
 /*
  * Nominally, the purpose of this function is to look for or create the bad
  * block table. In fact, since the we call this function at the very end of
diff --git a/include/linux/mtd/nand_mxs.h b/include/linux/mtd/nand_mxs.h
index 7eda0b8e63..4c1e90d6f0 100644
--- a/include/linux/mtd/nand_mxs.h
+++ b/include/linux/mtd/nand_mxs.h
@@ -28,5 +28,9 @@
  */
 
 int mxs_nand_get_geo(int *ecc_strength, int *bb_mark_bit_offset);
+int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size);
+int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size);
+
+struct mtd_info;
 
 #endif /* __NAND_MXS_H */
diff --git a/include/soc/imx/imx-nand-bcb.h b/include/soc/imx/imx-nand-bcb.h
index 6c42d80428..c5481e602e 100644
--- a/include/soc/imx/imx-nand-bcb.h
+++ b/include/soc/imx/imx-nand-bcb.h
@@ -77,6 +77,17 @@ struct fcb_block {
 
 	uint32_t DISBBM;	/* the flag to enable (1)/disable(0) bi swap */
 	uint32_t BBMarkerPhysicalOffsetInSpareData; /* The swap position of main area in spare area */
+
+	/* iMX7 only */
+	uint32_t onfi_sync_enable; /* enable Onfi nand sync support */
+	uint32_t onfi_sync_speed;  /* Speed for Onfi nand sync mode */
+	uint32_t onfi_sync_nand_data; /* parameters for Onfi nand sync mode timing */
+	uint32_t reserved[6];
+	uint32_t disbbm_search; /* disable bad block search function when reading the firmware, only using DBBT */
+	uint32_t disbbm_search_limit; /* ???randomizer type 2 enable ???*/
+	uint32_t reserved1[15]; /* reserved for future use */
+	uint32_t read_retry_enable; /* enable read retry for DBBT and firmware */
+	uint32_t reserved2[1]; /*reserved, keep at 0 */
 };
 
 #endif /* __MACH_IMX_NAND_BCB_H */
-- 
2.30.2




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

* [PATCH 4/7] imx-bbu-nand-fcb: isolate i.MX28 specific parts
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
                   ` (2 preceding siblings ...)
  2022-09-30 12:15 ` [PATCH 3/7] mtd: nand-mxs: add i.MX7 FCB write support Sascha Hauer
@ 2022-09-30 12:15 ` Sascha Hauer
  2022-09-30 12:15 ` [PATCH 5/7] imx-bbu-nand-fcb: pass imx_handler further down Sascha Hauer
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

From: Johannes Zink <j.zink@pengutronix.de>

imx28_fcb_create() reads back some parameters from the BCH and GPMI
unlike imx6_fcb_create() which has same parameters hardcoded.

For i.MX7, we will need a mixture of both: Some values are hardcoded
(albeit differently than i.MX6), while some others need be read from the
BCH. In preparation for adding i.MX7 support, move common defines out of
the #ifdef CONFIG_ARCH_IMX28 and prefix constants that are not
applicable to i.MX6 and later with an IMX28_ prefix. No such constants
are currently in use.

Signed-off-by: Johannes Zink <j.zink@pengutronix.de>
---
 common/imx-bbu-nand-fcb.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
index bde0b227f8..f268503f38 100644
--- a/common/imx-bbu-nand-fcb.c
+++ b/common/imx-bbu-nand-fcb.c
@@ -1393,9 +1393,6 @@ int imx6_bbu_nand_register_handler(const char *name, unsigned long flags)
 	return ret;
 }
 
-#ifdef CONFIG_ARCH_IMX28
-#include <mach/imx28-regs.h>
-
 #define GPMI_TIMING0				0x00000070
 #define	GPMI_TIMING0_ADDRESS_SETUP_MASK			(0xff << 16)
 #define	GPMI_TIMING0_ADDRESS_SETUP_OFFSET		16
@@ -1413,19 +1410,28 @@ int imx6_bbu_nand_register_handler(const char *name, unsigned long flags)
 #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	BCH_FLASHLAYOUT0_DATA0_SIZE_MASK		0xfff
+#define	MX28_BCH_FLASHLAYOUT0_ECC0_MASK			(0xf << 12)
+#define	MX28_BCH_FLASHLAYOUT0_ECC0_OFFSET		12
+#define	BCH_FLASHLAYOUT0_ECC0_MASK			(0x1f << 11)
+#define	BCH_FLASHLAYOUT0_ECC0_OFFSET			11
+#define	BCH_FLASHLAYOUT0_DATA0_SIZE_MASK		0x3ff
+#define	MX28_BCH_FLASHLAYOUT0_DATA0_SIZE_MASK		0xfff
 #define	BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET		0
 
 #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	BCH_FLASHLAYOUT1_DATAN_SIZE_MASK		0xfff
+#define	BCH_FLASHLAYOUT1_ECCN_MASK			(0x1f << 11)
+#define	BCH_FLASHLAYOUT1_ECCN_OFFSET			11
+#define	MX28_BCH_FLASHLAYOUT1_ECCN_MASK			(0xf << 12)
+#define	MX28_BCH_FLASHLAYOUT1_ECCN_OFFSET		12
+#define	BCH_FLASHLAYOUT1_DATAN_SIZE_MASK		0x3ff
+#define	MX28_BCH_FLASHLAYOUT1_DATAN_SIZE_MASK		0xfff
 #define	BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET		0
 
+#ifdef CONFIG_ARCH_IMX28
+#include <mach/imx28-regs.h>
+
 static void imx28_fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
 		struct fcb_block *fcb, struct mtd_info *mtd)
 {
-- 
2.30.2




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

* [PATCH 5/7] imx-bbu-nand-fcb: pass imx_handler further down
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
                   ` (3 preceding siblings ...)
  2022-09-30 12:15 ` [PATCH 4/7] imx-bbu-nand-fcb: isolate i.MX28 specific parts Sascha Hauer
@ 2022-09-30 12:15 ` Sascha Hauer
  2022-09-30 12:15 ` [PATCH 6/7] imx-bbu-nand-fcb: add fcb_read/fcb_write function hooks Sascha Hauer
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

Pass the struct bbu_handler *handler context pointer further down the
road. We'll need that in the next patches. No functional change.

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

diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
index f268503f38..002e35bde9 100644
--- a/common/imx-bbu-nand-fcb.c
+++ b/common/imx-bbu-nand-fcb.c
@@ -843,7 +843,8 @@ out:
  *
  * return: 0 if the FCB/DBBT are valid, a negative error code otherwise
  */
-static int fcb_dbbt_check(struct mtd_info *mtd, int num, struct fcb_block *fcb)
+static int fcb_dbbt_check(struct imx_nand_fcb_bbu_handler *imx_handler,
+			  struct mtd_info *mtd, int num, struct fcb_block *fcb)
 {
 	int ret;
 	struct fcb_block *f;
@@ -885,7 +886,8 @@ out:
  *
  * return: 0 for success or a negative error code otherwise.
  */
-static int imx_bbu_write_fcbs_dbbts(struct mtd_info *mtd, struct fcb_block *fcb)
+static int imx_bbu_write_fcbs_dbbts(struct imx_nand_fcb_bbu_handler *imx_handler,
+				    struct mtd_info *mtd, struct fcb_block *fcb)
 {
 	void *dbbt = NULL;
 	int i, ret, valid = 0;
@@ -928,7 +930,7 @@ static int imx_bbu_write_fcbs_dbbts(struct mtd_info *mtd, struct fcb_block *fcb)
 		if (mtd_peb_is_bad(mtd, i))
 			continue;
 
-		if (!fcb_dbbt_check(mtd, i, fcb)) {
+		if (!fcb_dbbt_check(imx_handler, mtd, i, fcb)) {
 			valid++;
 			pr_info("FCB/DBBT on block %d still valid\n", i);
 			continue;
@@ -1326,7 +1328,7 @@ static int imx_bbu_nand_update(struct bbu_handler *handler, struct bbu_data *dat
 	 * just written as primary firmware. From now on the new
 	 * firmware will be booted.
 	 */
-	ret = imx_bbu_write_fcbs_dbbts(mtd, fcb);
+	ret = imx_bbu_write_fcbs_dbbts(imx_handler, mtd, fcb);
 	if (ret < 0)
 		goto out;
 
@@ -1347,7 +1349,7 @@ static int imx_bbu_nand_update(struct bbu_handler *handler, struct bbu_data *dat
 	 */
 	if (ret > 0) {
 		pr_info("New bad blocks detected, writing FCBs/DBBTs again\n");
-		ret = imx_bbu_write_fcbs_dbbts(mtd, fcb);
+		ret = imx_bbu_write_fcbs_dbbts(imx_handler, mtd, fcb);
 		if (ret < 0)
 			goto out;
 	}
-- 
2.30.2




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

* [PATCH 6/7] imx-bbu-nand-fcb: add fcb_read/fcb_write function hooks
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
                   ` (4 preceding siblings ...)
  2022-09-30 12:15 ` [PATCH 5/7] imx-bbu-nand-fcb: pass imx_handler further down Sascha Hauer
@ 2022-09-30 12:15 ` Sascha Hauer
  2022-09-30 12:15 ` [PATCH 7/7] imx-bbu-nand-fcb: extend for i.MX7 support Sascha Hauer
  2022-09-30 13:21 ` [PATCH 0/7] Add i.MX7 NAND boot support Johannes Zink
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

Reading the FCB on i.MX7 needs special tweaks. As we already have two
different variants of how the the FCB is read/written already, make
function hooks from it.

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

diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
index 002e35bde9..5d4841a554 100644
--- a/common/imx-bbu-nand-fcb.c
+++ b/common/imx-bbu-nand-fcb.c
@@ -45,6 +45,8 @@ struct imx_nand_fcb_bbu_handler {
 
 	void (*fcb_create)(struct imx_nand_fcb_bbu_handler *imx_handler,
 		struct fcb_block *fcb, struct mtd_info *mtd);
+	int (*fcb_read)(struct mtd_info *mtd, int block, struct fcb_block **retfcb);
+	int (*fcb_write)(struct mtd_info *mtd, int block, struct fcb_block *fcb);
 	enum filetype filetype;
 };
 
@@ -123,7 +125,7 @@ static void encode_bch_ecc(void *buf, struct fcb_block *fcb, int eccbits)
 	free_bch(bch);
 }
 
-static struct fcb_block *read_fcb_bch(void *rawpage, int eccbits)
+static struct fcb_block *fcb_decode_bch(void *rawpage, int eccbits)
 {
 	int i, j, ret, errbit, m = 13;
 	int blocksize = 128;
@@ -227,7 +229,7 @@ static uint32_t calc_chksum(void *buf, size_t size)
 	return ~chksum;
 }
 
-static struct fcb_block *read_fcb_hamming_13_8(void *rawpage)
+static struct fcb_block *fcb_decode_hamming_13_8(void *rawpage)
 {
 	int i;
 	int bitflips = 0, bit_to_flip;
@@ -367,7 +369,7 @@ static ssize_t raw_write_page(struct mtd_info *mtd, void *buf, loff_t offset)
         return ret;
 }
 
-static int read_fcb(struct mtd_info *mtd, int num, struct fcb_block **retfcb)
+static int fcb_read_hamming_13_8(struct mtd_info *mtd, int block, struct fcb_block **retfcb)
 {
 	int ret;
 	struct fcb_block *fcb;
@@ -377,19 +379,71 @@ static int read_fcb(struct mtd_info *mtd, int num, struct fcb_block **retfcb)
 
 	rawpage = xmalloc(mtd->writesize + mtd->oobsize);
 
-	ret = raw_read_page(mtd, rawpage, mtd->erasesize * num);
+	ret = raw_read_page(mtd, rawpage, mtd->erasesize * block);
 	if (ret) {
-		pr_err("Cannot read block %d\n", num);
+		pr_err("Cannot read block %d\n", block);
 		goto err;
 	}
 
-	if (fcb_is_bch_encoded())
-		fcb = read_fcb_bch(rawpage, 40);
-	else
-		fcb = read_fcb_hamming_13_8(rawpage);
+	fcb = fcb_decode_hamming_13_8(rawpage);
+	if (IS_ERR(fcb)) {
+		pr_err("Cannot decode fcb on block %d\n", block);
+		ret = PTR_ERR(fcb);
+		goto err;
+	}
+
+	*retfcb = fcb;
+	ret = 0;
+err:
+	free(rawpage);
+
+	return ret;
+}
+
+static int fcb_write_hamming_13_8(struct mtd_info *mtd, int block, struct fcb_block *fcb)
+{
+	void *fcb_raw_page = xzalloc(mtd->writesize + mtd->oobsize);
+	int ret;
+
+	memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
+
+	/*
+	 * Set the first and second byte of OOB data to 0xFF, not 0x00. These
+	 * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since
+	 * the FCB is mostly written to the first page in a block, a scan for
+	 * factory bad blocks will detect these blocks as bad, e.g. when
+	 * function nand_scan_bbt() is executed to build a new bad block table.
+	 */
+	memset(fcb_raw_page + mtd->writesize, 0xFF, 2);
+
+	encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512);
+
+	ret = raw_write_page(mtd, fcb_raw_page, block * mtd->erasesize);
+
+	free(fcb_raw_page);
+
+	return ret;
+}
 
+static int fcb_read_bch(struct mtd_info *mtd, int block, struct fcb_block **retfcb)
+{
+	int ret;
+	struct fcb_block *fcb;
+	void *rawpage;
+
+	*retfcb = NULL;
+
+	rawpage = xmalloc(mtd->writesize + mtd->oobsize);
+
+	ret = raw_read_page(mtd, rawpage, mtd->erasesize * block);
+	if (ret) {
+		pr_err("Cannot read block %d\n", block);
+		goto err;
+	}
+
+	fcb = fcb_decode_bch(rawpage, 40);
 	if (IS_ERR(fcb)) {
-		pr_err("Cannot read fcb on block %d\n", num);
+		pr_err("Cannot decode fcb on block %d\n", block);
 		ret = PTR_ERR(fcb);
 		goto err;
 	}
@@ -402,6 +456,31 @@ err:
 	return ret;
 }
 
+static int fcb_write_bch(struct mtd_info *mtd, int block, struct fcb_block *fcb)
+{
+	void *fcb_raw_page = xzalloc(mtd->writesize + mtd->oobsize);
+	int ret;
+
+	/* 40 bit BCH, for i.MX6UL(L) */
+	encode_bch_ecc(fcb_raw_page + 32, fcb, 40);
+
+	/*
+	 * Set the first and second byte of OOB data to 0xFF, not 0x00. These
+	 * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since
+	 * the FCB is mostly written to the first page in a block, a scan for
+	 * factory bad blocks will detect these blocks as bad, e.g. when
+	 * function nand_scan_bbt() is executed to build a new bad block table.
+	 */
+	memset(fcb_raw_page + mtd->writesize, 0xFF, 2);
+
+	ret = raw_write_page(mtd, fcb_raw_page, block * mtd->erasesize);
+
+	free(fcb_raw_page);
+
+	return ret;
+}
+
+
 static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
 		struct fcb_block *fcb, struct mtd_info *mtd)
 {
@@ -651,7 +730,7 @@ static void imx28_dbbt_create(struct dbbt_block *dbbt, int num_bad_blocks)
  * imx_bbu_write_fcb - Write FCB and DBBT raw data to the device
  * @mtd: The mtd Nand device
  * @block: The block to write to
- * @fcb_raw_page: The raw FCB data
+ * @fcb: FCB
  * @dbbt_data_page: The DBBT data
  *
  * This function writes the FCB/DBBT data to the block given in @block
@@ -660,7 +739,8 @@ static void imx28_dbbt_create(struct dbbt_block *dbbt, int num_bad_blocks)
  *
  * return: 0 on success or a negative error code otherwise.
  */
-static int imx_bbu_write_fcb(struct mtd_info *mtd, int block, void *fcb_raw_page,
+static int imx_bbu_write_fcb(struct imx_nand_fcb_bbu_handler *imx_handler,
+			     struct mtd_info *mtd, int block, struct fcb_block *fcb,
 			     void *dbbt_data_page)
 {
 	struct dbbt_block *dbbt;
@@ -682,7 +762,7 @@ again:
 	if (ret)
 		return ret;
 
-	ret = raw_write_page(mtd, fcb_raw_page, block * mtd->erasesize);
+	ret = imx_handler->fcb_write(mtd, block, fcb);
 	if (ret) {
 		pr_err("Writing FCB on block %d failed with %s\n",
 		       block, strerror(-ret));
@@ -850,7 +930,7 @@ static int fcb_dbbt_check(struct imx_nand_fcb_bbu_handler *imx_handler,
 	struct fcb_block *f;
 	int pages_per_block = mtd->erasesize / mtd->writesize;
 
-	ret = read_fcb(mtd, num, &f);
+	ret = imx_handler->fcb_read(mtd, num, &f);
 	if (ret)
 		return ret;
 
@@ -891,7 +971,6 @@ static int imx_bbu_write_fcbs_dbbts(struct imx_nand_fcb_bbu_handler *imx_handler
 {
 	void *dbbt = NULL;
 	int i, ret, valid = 0;
-	void *fcb_raw_page;
 
 	/*
 	 * The DBBT search start page is configurable in the FCB block.
@@ -901,28 +980,8 @@ static int imx_bbu_write_fcbs_dbbts(struct imx_nand_fcb_bbu_handler *imx_handler
 	if (fcb->DBBTSearchAreaStartAddress != 1)
 		return -EINVAL;
 
-	fcb_raw_page = xzalloc(mtd->writesize + mtd->oobsize);
-
-	if (fcb_is_bch_encoded()) {
-		/* 40 bit BCH, for i.MX6UL(L) */
-		encode_bch_ecc(fcb_raw_page + 32, fcb, 40);
-	} else {
-		memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
-		encode_hamming_13_8(fcb_raw_page + 12,
-				    fcb_raw_page + 12 + 512, 512);
-	}
-
 	dbbt = dbbt_data_create(mtd);
 
-	/*
-	 * Set the first and second byte of OOB data to 0xFF, not 0x00. These
-	 * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since
-	 * the FCB is mostly written to the first page in a block, a scan for
-	 * factory bad blocks will detect these blocks as bad, e.g. when
-	 * function nand_scan_bbt() is executed to build a new bad block table.
-	 */
-	memset(fcb_raw_page + mtd->writesize, 0xFF, 2);
-
 	pr_info("Writing FCBs/DBBTs with primary/secondary Firmwares at pages %d/%d\n",
 		fcb->Firmware1_startingPage, fcb->Firmware2_startingPage);
 
@@ -938,14 +997,13 @@ static int imx_bbu_write_fcbs_dbbts(struct imx_nand_fcb_bbu_handler *imx_handler
 
 		pr_info("Writing FCB/DBBT on block %d\n", i);
 
-		ret = imx_bbu_write_fcb(mtd, i, fcb_raw_page, dbbt);
+		ret = imx_bbu_write_fcb(imx_handler, mtd, i, fcb, dbbt);
 		if (ret)
 			pr_err("Writing FCB/DBBT %d failed with: %s\n", i, strerror(-ret));
 		else
 			valid++;
 	}
 
-	free(fcb_raw_page);
 	free(dbbt);
 
 	if (!valid)
@@ -1185,7 +1243,7 @@ static int imx_bbu_nand_update(struct bbu_handler *handler, struct bbu_data *dat
 	}
 
 	for (i = 0; i < 4; i++) {
-		read_fcb(mtd, i, &fcb);
+		imx_handler->fcb_read(mtd, i, &fcb);
 		if (fcb)
 			break;
 	}
@@ -1382,6 +1440,14 @@ int imx6_bbu_nand_register_handler(const char *name, unsigned long flags)
 	imx_handler->fcb_create = imx6_fcb_create;
 	imx_handler->filetype = filetype_arm_barebox;
 
+	if (fcb_is_bch_encoded()) {
+		imx_handler->fcb_read = fcb_read_bch;
+		imx_handler->fcb_write = fcb_write_bch;
+	} else {
+		imx_handler->fcb_read = fcb_read_hamming_13_8;
+		imx_handler->fcb_write = fcb_write_hamming_13_8;
+	}
+
 	handler = &imx_handler->handler;
 	handler->devicefile = "nand0.barebox";
 	handler->name = name;
@@ -1462,6 +1528,8 @@ int imx28_bbu_nand_register_handler(const char *name, unsigned long flags)
 
 	imx_handler = xzalloc(sizeof(*imx_handler));
 	imx_handler->fcb_create = imx28_fcb_create;
+	imx_handler->fcb_read = fcb_read_hamming_13_8;
+	imx_handler->fcb_write = fcb_write_hamming_13_8;
 
 	imx_handler->filetype = filetype_mxs_bootstream;
 
-- 
2.30.2




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

* [PATCH 7/7] imx-bbu-nand-fcb: extend for i.MX7 support
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
                   ` (5 preceding siblings ...)
  2022-09-30 12:15 ` [PATCH 6/7] imx-bbu-nand-fcb: add fcb_read/fcb_write function hooks Sascha Hauer
@ 2022-09-30 12:15 ` Sascha Hauer
  2022-09-30 13:21 ` [PATCH 0/7] Add i.MX7 NAND boot support Johannes Zink
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2022-09-30 12:15 UTC (permalink / raw)
  To: Barebox List; +Cc: Johannes Zink

From: Johannes Zink <j.zink@pengutronix.de>

This adds a barebox update handler for i.MX7 NAND

Signed-off-by: Johannes Zink <j.zink@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/include/mach/imx7-regs.h |  3 +
 common/Kconfig                             |  2 +-
 common/imx-bbu-nand-fcb.c                  | 91 ++++++++++++++++++++--
 include/bbu.h                              |  5 ++
 4 files changed, 94 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/imx7-regs.h b/arch/arm/mach-imx/include/mach/imx7-regs.h
index f116916717..1ee7d86e0e 100644
--- a/arch/arm/mach-imx/include/mach/imx7-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx7-regs.h
@@ -118,6 +118,9 @@
 #define MX7_ENET1_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3E0000)
 #define MX7_ENET2_BASE_ADDR		(MX7_AIPS3_BASE_ADDR + 0x3F0000)
 
+#define MX7_GPMI_BASE			0x33002000
+#define MX7_BCH_BASE			0x33004000
+
 #define MX7_DDR_BASE_ADDR		0x80000000
 
 #endif /* __MACH_IMX7_REGS_H */
diff --git a/common/Kconfig b/common/Kconfig
index 43dd92b08a..350e6aeea7 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -78,7 +78,7 @@ config ARCH_DMA_ADDR_T_64BIT
 
 config BAREBOX_UPDATE_IMX_NAND_FCB
 	bool
-	depends on ARCH_IMX6 || ARCH_IMX28
+	depends on ARCH_IMX7 || ARCH_IMX6 || ARCH_IMX28
 	depends on BAREBOX_UPDATE
 	depends on MTD_WRITE
 	depends on NAND_MXS
diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
index 5d4841a554..63c81e4ed6 100644
--- a/common/imx-bbu-nand-fcb.c
+++ b/common/imx-bbu-nand-fcb.c
@@ -27,16 +27,16 @@
 #include <mtd/mtd-peb.h>
 #include <soc/imx/imx-nand-bcb.h>
 
-#ifdef CONFIG_ARCH_IMX6
-#include <mach/imx6.h>
+#ifdef CONFIG_ARCH_IMX28
 static inline int fcb_is_bch_encoded(void)
 {
-       return cpu_is_mx6ul() || cpu_is_mx6ull();
+       return 0;
 }
 #else
+#include <mach/imx6.h>
 static inline int fcb_is_bch_encoded(void)
 {
-       return 0;
+       return cpu_is_mx6ul() || cpu_is_mx6ull();
 }
 #endif
 
@@ -517,6 +517,9 @@ static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
 
 	imx_handler->fcb_create(imx_handler, fcb, mtd);
 
+	fcb->DISBBM = 0;
+	fcb->disbbm_search = 0;
+
 	fcb->Checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4);
 
 	return 0;
@@ -1482,9 +1485,11 @@ int imx6_bbu_nand_register_handler(const char *name, unsigned long flags)
 #define	MX28_BCH_FLASHLAYOUT0_ECC0_OFFSET		12
 #define	BCH_FLASHLAYOUT0_ECC0_MASK			(0x1f << 11)
 #define	BCH_FLASHLAYOUT0_ECC0_OFFSET			11
+#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1_MASK		BIT(10)
+#define	BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET		10
 #define	BCH_FLASHLAYOUT0_DATA0_SIZE_MASK		0x3ff
-#define	MX28_BCH_FLASHLAYOUT0_DATA0_SIZE_MASK		0xfff
 #define	BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET		0
+#define	MX28_BCH_FLASHLAYOUT0_DATA0_SIZE_MASK		0xfff
 
 #define BCH_FLASH0LAYOUT1			0x00000090
 #define	BCH_FLASHLAYOUT1_PAGE_SIZE_MASK			(0xffff << 16)
@@ -1493,9 +1498,11 @@ int imx6_bbu_nand_register_handler(const char *name, unsigned long flags)
 #define	BCH_FLASHLAYOUT1_ECCN_OFFSET			11
 #define	MX28_BCH_FLASHLAYOUT1_ECCN_MASK			(0xf << 12)
 #define	MX28_BCH_FLASHLAYOUT1_ECCN_OFFSET		12
+#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	BCH_FLASHLAYOUT1_DATAN_SIZE_MASK		0x3ff
 #define	MX28_BCH_FLASHLAYOUT1_DATAN_SIZE_MASK		0xfff
-#define	BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET		0
 
 #ifdef CONFIG_ARCH_IMX28
 #include <mach/imx28-regs.h>
@@ -1546,3 +1553,75 @@ int imx28_bbu_nand_register_handler(const char *name, unsigned long flags)
 	return ret;
 }
 #endif
+
+#ifdef CONFIG_ARCH_IMX7
+#include <mach/imx7-regs.h>
+
+static void imx7_fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
+		struct fcb_block *fcb, struct mtd_info *mtd)
+{
+	void __iomem *bch_regs = IOMEM(MX7_BCH_BASE);
+	u32 fl0, fl1;
+
+	/* Also hardcoded in kobs-ng */
+	fcb->DataSetup = 10;
+	fcb->DataHold = 7;
+	fcb->AddressSetup = 15;
+	fcb->DSAMPLE_TIME = 6;
+
+	fl0 = readl(bch_regs + BCH_FLASH0LAYOUT0);
+	fcb->MetadataBytes = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+	fcb->NumEccBlocksPerPage = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS);
+
+	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);
+}
+
+static int imx7_fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb)
+{
+	struct fcb_block *fcb = xzalloc(mtd->writesize);
+	int ret;
+
+	ret = mxs_nand_read_fcb_bch62(block, fcb, sizeof(*fcb));
+	if (ret)
+		free(fcb);
+	else
+		*retfcb = fcb;
+
+	return ret;
+}
+
+static int imx7_fcb_write(struct mtd_info *mtd, int block, struct fcb_block *fcb)
+{
+	return mxs_nand_write_fcb_bch62(block, fcb, sizeof(*fcb));
+}
+
+int imx7_bbu_nand_register_handler(const char *name, unsigned long flags)
+{
+	struct imx_nand_fcb_bbu_handler *imx_handler;
+	struct bbu_handler *handler;
+	int ret;
+
+	imx_handler = xzalloc(sizeof(*imx_handler));
+	imx_handler->fcb_create = imx7_fcb_create;
+	imx_handler->fcb_read = imx7_fcb_read;
+	imx_handler->fcb_write = imx7_fcb_write;
+	imx_handler->filetype = filetype_arm_barebox;
+
+	handler = &imx_handler->handler;
+	handler->devicefile = "nand0.barebox";
+	handler->name = name;
+	handler->flags = flags | BBU_HANDLER_CAN_REFRESH;
+	handler->handler = imx_bbu_nand_update;
+
+	ret = bbu_register_handler(handler);
+	if (ret)
+		free(handler);
+
+	return ret;
+}
+#endif
diff --git a/include/bbu.h b/include/bbu.h
index 2dad26a127..cec7e22d4d 100644
--- a/include/bbu.h
+++ b/include/bbu.h
@@ -88,12 +88,17 @@ static inline void bbu_append_handlers_to_file_list(struct file_list *files)
 
 #if defined(CONFIG_BAREBOX_UPDATE_IMX_NAND_FCB)
 int imx6_bbu_nand_register_handler(const char *name, unsigned long flags);
+int imx7_bbu_nand_register_handler(const char *name, unsigned long flags);
 int imx28_bbu_nand_register_handler(const char *name, unsigned long flags);
 #else
 static inline int imx6_bbu_nand_register_handler(const char *name, unsigned long flags)
 {
 	return -ENOSYS;
 }
+static inline int imx7_bbu_nand_register_handler(const char *name, unsigned long flags)
+{
+	return -ENOSYS;
+}
 static inline int imx28_bbu_nand_register_handler(const char *name, unsigned long flags)
 {
 	return -ENOSYS;
-- 
2.30.2




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

* Re: [PATCH 0/7] Add i.MX7 NAND boot support
  2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
                   ` (6 preceding siblings ...)
  2022-09-30 12:15 ` [PATCH 7/7] imx-bbu-nand-fcb: extend for i.MX7 support Sascha Hauer
@ 2022-09-30 13:21 ` Johannes Zink
  7 siblings, 0 replies; 9+ messages in thread
From: Johannes Zink @ 2022-09-30 13:21 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List

On Fri, 2022-09-30 at 14:15 +0200, Sascha Hauer wrote:
> NAND boot on i.MX7 is the same as on i.MX6, just a little different.
> This series adds a barebox update handler to allow writing barebox
> to NAND flash.
> 
> Sascha
> 
> Johannes Zink (4):
>   mtd: nand-mxs: refactor flash layout configuration
>   mtd: nand-mxs: add i.MX7 FCB write support
>   imx-bbu-nand-fcb: isolate i.MX28 specific parts
>   imx-bbu-nand-fcb: extend for i.MX7 support
> 
> Sascha Hauer (3):
>   mtd: nand-mxs: Factor out a bch read function
>   imx-bbu-nand-fcb: pass imx_handler further down
>   imx-bbu-nand-fcb: add fcb_read/fcb_write function hooks
> 
>  arch/arm/mach-imx/include/mach/imx7-regs.h |   3 +
>  common/Kconfig                             |   2 +-
>  common/imx-bbu-nand-fcb.c                  | 267 ++++++++++++++----
>  drivers/mtd/nand/nand_mxs.c                | 297 ++++++++++++++++++-
> --
>  include/bbu.h                              |   5 +
>  include/linux/mtd/nand_mxs.h               |   4 +
>  include/soc/imx/imx-nand-bcb.h             |  11 +
>  7 files changed, 492 insertions(+), 97 deletions(-)
> 

Tested-by: Johannes Zink <j.zink@pengutronix.de> # innocomm S810
(i.MX7D)

-- 
Pengutronix e.K.                | Johannes Zink                  |
Steuerwalder Str. 21            | https://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] 9+ messages in thread

end of thread, other threads:[~2022-09-30 13:24 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-30 12:15 [PATCH 0/7] Add i.MX7 NAND boot support Sascha Hauer
2022-09-30 12:15 ` [PATCH 1/7] mtd: nand-mxs: refactor flash layout configuration Sascha Hauer
2022-09-30 12:15 ` [PATCH 2/7] mtd: nand-mxs: Factor out a bch read function Sascha Hauer
2022-09-30 12:15 ` [PATCH 3/7] mtd: nand-mxs: add i.MX7 FCB write support Sascha Hauer
2022-09-30 12:15 ` [PATCH 4/7] imx-bbu-nand-fcb: isolate i.MX28 specific parts Sascha Hauer
2022-09-30 12:15 ` [PATCH 5/7] imx-bbu-nand-fcb: pass imx_handler further down Sascha Hauer
2022-09-30 12:15 ` [PATCH 6/7] imx-bbu-nand-fcb: add fcb_read/fcb_write function hooks Sascha Hauer
2022-09-30 12:15 ` [PATCH 7/7] imx-bbu-nand-fcb: extend for i.MX7 support Sascha Hauer
2022-09-30 13:21 ` [PATCH 0/7] Add i.MX7 NAND boot support Johannes Zink

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