public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Maxime Ripard <maxime@cerno.tech>
To: u-boot@lists.denx.de, Andre Przywara <andre.przywara@arm.com>
Cc: Peng Fan <peng.fan@nxp.com>, Li Jun <jun.li@nxp.com>,
	Marek Vasut <marex@denx.de>, Tom Rini <trini@konsulko.com>,
	Miquel Raynal <miquel.raynal@bootlin.com>,
	Jagan Teki <jagan@amarulasolutions.com>,
	Maxime Ripard <maxime@cerno.tech>
Subject: [PATCH 02/12] Revert "spl: nand: sunxi: use PIO instead of DMA"
Date: Fri, 25 Jun 2021 15:05:37 +0200	[thread overview]
Message-ID: <20210625130547.2177920-3-maxime@cerno.tech> (raw)
In-Reply-To: <20210625130547.2177920-1-maxime@cerno.tech>

This reverts commit 6ddbb1e936c78cdef1e7395039fa7020c5c75326.
---
 drivers/mtd/nand/raw/sunxi_nand_spl.c | 141 ++++++++++++++++----------
 1 file changed, 85 insertions(+), 56 deletions(-)

diff --git a/drivers/mtd/nand/raw/sunxi_nand_spl.c b/drivers/mtd/nand/raw/sunxi_nand_spl.c
index 85d8013b1a6b..c097a2b8b94d 100644
--- a/drivers/mtd/nand/raw/sunxi_nand_spl.c
+++ b/drivers/mtd/nand/raw/sunxi_nand_spl.c
@@ -8,10 +8,12 @@
 #include <asm/io.h>
 #include <common.h>
 #include <config.h>
+#include <cpu_func.h>
 #include <nand.h>
 #include <linux/bitops.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
+#include <linux/ctype.h>
 
 /* registers */
 #define NFC_CTL                    0x00000000
@@ -69,7 +71,6 @@
 #define NFC_SEND_CMD3              (1 << 28)
 #define NFC_SEND_CMD4              (1 << 29)
 #define NFC_RAW_CMD                (0 << 30)
-#define NFC_ECC_CMD                (1 << 30)
 #define NFC_PAGE_CMD               (2 << 30)
 
 #define NFC_ST_CMD_INT_FLAG        (1 << 1)
@@ -84,6 +85,22 @@
 #define NFC_CMD_RNDOUT             0x05
 #define NFC_CMD_READSTART          0x30
 
+#define SUNXI_DMA_CFG_REG0              0x300
+#define SUNXI_DMA_SRC_START_ADDR_REG0   0x304
+#define SUNXI_DMA_DEST_START_ADDRR_REG0 0x308
+#define SUNXI_DMA_DDMA_BC_REG0          0x30C
+#define SUNXI_DMA_DDMA_PARA_REG0        0x318
+
+#define SUNXI_DMA_DDMA_CFG_REG_LOADING  (1 << 31)
+#define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
+#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16)
+#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
+#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
+#define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
+
+#define SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC (0x0F << 0)
+#define SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE (0x7F << 8)
+
 struct nfc_config {
 	int page_size;
 	int ecc_strength;
@@ -256,74 +273,86 @@ static const int ecc_bytes[] = {32, 46, 54, 60, 74, 88, 102, 110, 116};
 static int nand_read_page(const struct nfc_config *conf, u32 offs,
 			  void *dest, int len)
 {
+	dma_addr_t dst = (dma_addr_t)dest;
 	int nsectors = len / conf->ecc_size;
 	u16 rand_seed = 0;
-	int oob_chunk_sz = ecc_bytes[conf->ecc_strength];
-	int page = offs / conf->page_size;
-	u32 ecc_st;
-	int i;
+	u32 val;
+	int page;
+
+	page = offs / conf->page_size;
 
 	if (offs % conf->page_size || len % conf->ecc_size ||
 	    len > conf->page_size || len < 0)
 		return -EINVAL;
 
+	/* clear ecc status */
+	writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
+
 	/* Choose correct seed if randomized */
 	if (conf->randomize)
 		rand_seed = random_seed[page % conf->nseeds];
 
-	/* Retrieve data from SRAM (PIO) */
-	for (i = 0; i < nsectors; i++) {
-		int data_off = i * conf->ecc_size;
-		int oob_off = conf->page_size + (i * oob_chunk_sz);
-		u8 *data = dest + data_off;
-
-		/* Clear ECC status and restart ECC engine */
-		writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
-		writel((rand_seed << 16) | (conf->ecc_strength << 12) |
-		       (conf->randomize ? NFC_ECC_RANDOM_EN : 0) |
-		       (conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) |
-		       NFC_ECC_EN | NFC_ECC_EXCEPTION,
-		       SUNXI_NFC_BASE + NFC_ECC_CTL);
-
-		/* Move the data in SRAM */
-		nand_change_column(data_off);
-		writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT);
-		nand_exec_cmd(NFC_DATA_TRANS);
-
-		/*
-		 * Let the ECC engine consume the ECC bytes and possibly correct
-		 * the data.
-		 */
-		nand_change_column(oob_off);
-		nand_exec_cmd(NFC_DATA_TRANS | NFC_ECC_CMD);
-
-		/* Get the ECC status */
-		ecc_st = readl(SUNXI_NFC_BASE + NFC_ECC_ST);
-
-		/* ECC error detected. */
-		if (ecc_st & 0xffff)
-			return -EIO;
-
-		/*
-		 * Return 1 if the first chunk is empty (needed for
-		 * configuration detection).
-		 */
-		if (!i && (ecc_st & 0x10000))
-			return 1;
-
-		/* Retrieve the data from SRAM */
-		memcpy_fromio(data, SUNXI_NFC_BASE + NFC_RAM0_BASE,
-			      conf->ecc_size);
-
-		/* Stop the ECC engine */
-		writel(readl(SUNXI_NFC_BASE + NFC_ECC_CTL) & ~NFC_ECC_EN,
-		       SUNXI_NFC_BASE + NFC_ECC_CTL);
-
-		if (data_off + conf->ecc_size >= len)
-			break;
+	writel((rand_seed << 16) | (conf->ecc_strength << 12) |
+		(conf->randomize ? NFC_ECC_RANDOM_EN : 0) |
+		(conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) |
+		NFC_ECC_EN | NFC_ECC_PIPELINE | NFC_ECC_EXCEPTION,
+		SUNXI_NFC_BASE + NFC_ECC_CTL);
+
+	flush_dcache_range(dst, ALIGN(dst + conf->ecc_size, ARCH_DMA_MINALIGN));
+
+	/* SUNXI_DMA */
+	writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
+	/* read from REG_IO_DATA */
+	writel(SUNXI_NFC_BASE + NFC_IO_DATA,
+	       SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
+	/* read to RAM */
+	writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
+	writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC |
+	       SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
+	       SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
+	writel(len, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0);
+	writel(SUNXI_DMA_DDMA_CFG_REG_LOADING |
+	       SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 |
+	       SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM |
+	       SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 |
+	       SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO |
+	       SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
+	       SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0);
+
+	writel(nsectors, SUNXI_NFC_BASE + NFC_SECTOR_NUM);
+	writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
+	writel(NFC_DATA_TRANS |	NFC_PAGE_CMD | NFC_DATA_SWAP_METHOD,
+	       SUNXI_NFC_BASE + NFC_CMD);
+
+	if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_DMA_INT_FLAG,
+			 DEFAULT_TIMEOUT_US)) {
+		printf("Error while initializing dma interrupt\n");
+		return -EIO;
 	}
+	writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
 
-	return 0;
+	if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0,
+				 SUNXI_DMA_DDMA_CFG_REG_LOADING,
+				 DEFAULT_TIMEOUT_US)) {
+		printf("Error while waiting for dma transfer to finish\n");
+		return -EIO;
+	}
+
+	invalidate_dcache_range(dst,
+				ALIGN(dst + conf->ecc_size, ARCH_DMA_MINALIGN));
+
+	val = readl(SUNXI_NFC_BASE + NFC_ECC_ST);
+
+	/* ECC error detected. */
+	if (val & 0xffff)
+		return -EIO;
+
+	/*
+	 * Return 1 if the page is empty.
+	 * We consider the page as empty if the first ECC block is marked
+	 * empty.
+	 */
+	return (val & 0x10000) ? 1 : 0;
 }
 
 static int nand_max_ecc_strength(struct nfc_config *conf)
-- 
2.31.1


  parent reply	other threads:[~2021-06-25 13:06 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-25 13:05 [PATCH 00/12] Random Fixes for the CHIP Pro Maxime Ripard
2021-06-25 13:05 ` [PATCH 01/12] Revert "sunxi: spl: remove DMA related settings of the NAND controller" Maxime Ripard
2021-06-25 13:05 ` Maxime Ripard [this message]
2021-06-25 13:05 ` [PATCH 03/12] Revert "usb: gadget: fastboot: use correct max packet size" Maxime Ripard
2021-06-25 13:47   ` Sean Anderson
2021-06-25 14:14     ` Maxime Ripard
2021-06-29  2:27   ` Peng Fan (OSS)
2021-07-03 13:47     ` Maxime Ripard
2021-06-25 13:05 ` [PATCH 04/12] Kconfig: Migrate SPL_PANIC_ON_RAW_IMAGE Maxime Ripard
2021-06-25 13:05 ` [PATCH 05/12] mtd: Allow for a longer mtdparts table Maxime Ripard
2021-06-25 13:05 ` [PATCH 06/12] fastboot: Add missing newlines Maxime Ripard
2021-06-25 13:40   ` Andre Przywara
2021-06-25 13:05 ` [PATCH 07/12] configs: chip pro: Disable video output Maxime Ripard
2021-06-25 13:38   ` Andre Przywara
2021-06-25 13:05 ` [PATCH 08/12] clk: sunxi: Add missing clock compatible Maxime Ripard
2021-06-25 13:38   ` Andre Przywara
2021-06-25 13:05 ` [PATCH 09/12] fastboot: nand: Fix return error code Maxime Ripard
2021-06-25 14:08   ` Andre Przywara
2021-06-25 13:05 ` [PATCH 10/12] configs: chip pro: Disable UMS Maxime Ripard
2021-06-25 13:05 ` [PATCH 11/12] configs: chip pro: fix the offsets Maxime Ripard
2021-06-25 13:05 ` [PATCH 12/12] configs: chip pro: Fix NAND Controller name Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210625130547.2177920-3-maxime@cerno.tech \
    --to=maxime@cerno.tech \
    --cc=andre.przywara@arm.com \
    --cc=jagan@amarulasolutions.com \
    --cc=jun.li@nxp.com \
    --cc=marex@denx.de \
    --cc=miquel.raynal@bootlin.com \
    --cc=peng.fan@nxp.com \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox