aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2018-02-28 20:51:48 +0100
committerMaxime Ripard <maxime.ripard@bootlin.com>2018-04-03 12:11:07 +0200
commit60fb17913354757d015ade2b5457675a0506903a (patch)
tree486f168ae9e474b6aa83256d8c100b29219091bc
parent28f7a9d375c8bc7a30563b8d995b9baa355c7e41 (diff)
downloadu-boot-60fb17913354757d015ade2b5457675a0506903a.zip
u-boot-60fb17913354757d015ade2b5457675a0506903a.tar.gz
u-boot-60fb17913354757d015ade2b5457675a0506903a.tar.bz2
spl: nand: sunxi: introduce the nand_wait_cmd_fifo_empty() helper
One bit in the control registers indicates if the NAND controller is ready to receive a new command. Otherwise, the command FIFO is full and we should wait for this bit to flip. It then states that the last command has been processed and the FIFO is now free to welcome another command. Add this sanity check before starting any new command. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Acked-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
-rw-r--r--drivers/mtd/nand/sunxi_nand_spl.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c
index c2f4f2c..cd823cd 100644
--- a/drivers/mtd/nand/sunxi_nand_spl.c
+++ b/drivers/mtd/nand/sunxi_nand_spl.c
@@ -155,6 +155,17 @@ static inline int check_value_negated(int offset, int unexpected_bits,
return check_value_inner(offset, unexpected_bits, timeout_us, 1);
}
+static int nand_wait_cmd_fifo_empty(void)
+{
+ if (!check_value_negated(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_FIFO_STAT,
+ DEFAULT_TIMEOUT_US)) {
+ printf("nand: timeout waiting for empty cmd FIFO\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static int nand_wait_int(void)
{
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
@@ -183,6 +194,8 @@ void nand_init(void)
}
/* reset NAND */
+ nand_wait_cmd_fifo_empty();
+
writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
SUNXI_NFC_BASE + NFC_CMD);
@@ -194,6 +207,8 @@ static void nand_apply_config(const struct nfc_config *conf)
{
u32 val;
+ nand_wait_cmd_fifo_empty();
+
val = readl(SUNXI_NFC_BASE + NFC_CTL);
val &= ~NFC_CTL_PAGE_SIZE_MASK;
writel(val | NFC_CTL_RAM_METHOD | NFC_CTL_PAGE_SIZE(conf->page_size),
@@ -206,6 +221,8 @@ static int nand_load_page(const struct nfc_config *conf, u32 offs)
{
int page = offs / conf->page_size;
+ nand_wait_cmd_fifo_empty();
+
writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
(NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
(NFC_CMD_READSTART << NFC_READ_CMD_OFFSET),
@@ -222,6 +239,8 @@ static int nand_load_page(const struct nfc_config *conf, u32 offs)
static int nand_reset_column(void)
{
+ nand_wait_cmd_fifo_empty();
+
writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
(NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
(NFC_CMD_RNDOUTSTART << NFC_READ_CMD_OFFSET),