Commit a4742d51 authored by Vipin Kumar's avatar Vipin Kumar Committed by Artem Bityutskiy

mtd: fsmc_nand: use relaxed variants of io accessors

Use relaxed variants of readl/writel accessors. readl/writel io accessors use
explicit dsb instruction which causes stalls in the processor core resulting
several cycles of delay for each access

Use relaxed variants where ever possible. This also results in an improved
read/write performance.
Signed-off-by: default avatarVipin Kumar <vipin.kumar@st.com>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
parent 928aa2ae
...@@ -383,13 +383,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) ...@@ -383,13 +383,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
pc |= FSMC_ENABLE; pc |= FSMC_ENABLE;
else else
pc &= ~FSMC_ENABLE; pc &= ~FSMC_ENABLE;
writel(pc, FSMC_NAND_REG(regs, bank, PC)); writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC));
} }
mb(); mb();
if (cmd != NAND_CMD_NONE) if (cmd != NAND_CMD_NONE)
writeb(cmd, this->IO_ADDR_W); writeb_relaxed(cmd, this->IO_ADDR_W);
} }
/* /*
...@@ -426,14 +426,18 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, ...@@ -426,14 +426,18 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
if (busw) if (busw)
writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC)); writel_relaxed(value | FSMC_DEVWID_16,
FSMC_NAND_REG(regs, bank, PC));
else else
writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC)); writel_relaxed(value | FSMC_DEVWID_8,
FSMC_NAND_REG(regs, bank, PC));
writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,
FSMC_NAND_REG(regs, bank, PC)); FSMC_NAND_REG(regs, bank, PC));
writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM)); writel_relaxed(thiz | thold | twait | tset,
writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB)); FSMC_NAND_REG(regs, bank, COMM));
writel_relaxed(thiz | thold | twait | tset,
FSMC_NAND_REG(regs, bank, ATTRIB));
} }
/* /*
...@@ -446,11 +450,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) ...@@ -446,11 +450,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
void __iomem *regs = host->regs_va; void __iomem *regs = host->regs_va;
uint32_t bank = host->bank; uint32_t bank = host->bank;
writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,
FSMC_NAND_REG(regs, bank, PC)); FSMC_NAND_REG(regs, bank, PC));
writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,
FSMC_NAND_REG(regs, bank, PC)); FSMC_NAND_REG(regs, bank, PC));
writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,
FSMC_NAND_REG(regs, bank, PC)); FSMC_NAND_REG(regs, bank, PC));
} }
...@@ -470,7 +474,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, ...@@ -470,7 +474,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT; unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
do { do {
if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)
break; break;
else else
cond_resched(); cond_resched();
...@@ -481,25 +485,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, ...@@ -481,25 +485,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
return -ETIMEDOUT; return -ETIMEDOUT;
} }
ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[0] = (uint8_t) (ecc_tmp >> 0);
ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[1] = (uint8_t) (ecc_tmp >> 8);
ecc[2] = (uint8_t) (ecc_tmp >> 16); ecc[2] = (uint8_t) (ecc_tmp >> 16);
ecc[3] = (uint8_t) (ecc_tmp >> 24); ecc[3] = (uint8_t) (ecc_tmp >> 24);
ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2)); ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
ecc[4] = (uint8_t) (ecc_tmp >> 0); ecc[4] = (uint8_t) (ecc_tmp >> 0);
ecc[5] = (uint8_t) (ecc_tmp >> 8); ecc[5] = (uint8_t) (ecc_tmp >> 8);
ecc[6] = (uint8_t) (ecc_tmp >> 16); ecc[6] = (uint8_t) (ecc_tmp >> 16);
ecc[7] = (uint8_t) (ecc_tmp >> 24); ecc[7] = (uint8_t) (ecc_tmp >> 24);
ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3)); ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
ecc[8] = (uint8_t) (ecc_tmp >> 0); ecc[8] = (uint8_t) (ecc_tmp >> 0);
ecc[9] = (uint8_t) (ecc_tmp >> 8); ecc[9] = (uint8_t) (ecc_tmp >> 8);
ecc[10] = (uint8_t) (ecc_tmp >> 16); ecc[10] = (uint8_t) (ecc_tmp >> 16);
ecc[11] = (uint8_t) (ecc_tmp >> 24); ecc[11] = (uint8_t) (ecc_tmp >> 24);
ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS)); ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
ecc[12] = (uint8_t) (ecc_tmp >> 16); ecc[12] = (uint8_t) (ecc_tmp >> 16);
return 0; return 0;
...@@ -519,7 +523,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, ...@@ -519,7 +523,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,
uint32_t bank = host->bank; uint32_t bank = host->bank;
uint32_t ecc_tmp; uint32_t ecc_tmp;
ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[0] = (uint8_t) (ecc_tmp >> 0);
ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[1] = (uint8_t) (ecc_tmp >> 8);
ecc[2] = (uint8_t) (ecc_tmp >> 16); ecc[2] = (uint8_t) (ecc_tmp >> 16);
...@@ -628,10 +632,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) ...@@ -628,10 +632,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
uint32_t *p = (uint32_t *)buf; uint32_t *p = (uint32_t *)buf;
len = len >> 2; len = len >> 2;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
writel(p[i], chip->IO_ADDR_W); writel_relaxed(p[i], chip->IO_ADDR_W);
} else { } else {
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
writeb(buf[i], chip->IO_ADDR_W); writeb_relaxed(buf[i], chip->IO_ADDR_W);
} }
} }
...@@ -651,10 +655,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ...@@ -651,10 +655,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
uint32_t *p = (uint32_t *)buf; uint32_t *p = (uint32_t *)buf;
len = len >> 2; len = len >> 2;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
p[i] = readl(chip->IO_ADDR_R); p[i] = readl_relaxed(chip->IO_ADDR_R);
} else { } else {
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
buf[i] = readb(chip->IO_ADDR_R); buf[i] = readb_relaxed(chip->IO_ADDR_R);
} }
} }
...@@ -783,7 +787,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, ...@@ -783,7 +787,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
uint32_t num_err, i; uint32_t num_err, i;
uint32_t ecc1, ecc2, ecc3, ecc4; uint32_t ecc1, ecc2, ecc3, ecc4;
num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;
/* no bit flipping */ /* no bit flipping */
if (likely(num_err == 0)) if (likely(num_err == 0))
...@@ -826,10 +830,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, ...@@ -826,10 +830,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
* uint64_t array and error offset indexes are populated in err_idx * uint64_t array and error offset indexes are populated in err_idx
* array * array
*/ */
ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1)); ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2)); ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3)); ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
ecc4 = readl(FSMC_NAND_REG(regs, bank, STS)); ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
err_idx[0] = (ecc1 >> 0) & 0x1FFF; err_idx[0] = (ecc1 >> 0) & 0x1FFF;
err_idx[1] = (ecc1 >> 13) & 0x1FFF; err_idx[1] = (ecc1 >> 13) & 0x1FFF;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment