All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.