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
next prev 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