summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/raw/atmel/nand-controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/raw/atmel/nand-controller.c')
-rw-r--r--drivers/mtd/nand/raw/atmel/nand-controller.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index db94d14a3807..83ba4ebd02d4 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1240,7 +1240,7 @@ static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
const struct nand_interface_config *conf,
struct atmel_smc_cs_conf *smcconf)
{
- u32 ncycles, totalcycles, timeps, mckperiodps;
+ u32 ncycles, totalcycles, timeps, mckperiodps, pulse;
struct atmel_nand_controller *nc;
int ret;
@@ -1366,11 +1366,16 @@ static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
ATMEL_SMC_MODE_TDFMODE_OPTIMIZED;
/*
- * Read pulse timing directly matches tRP:
+ * Read pulse timing would directly match tRP,
+ * but some NAND flash chips (S34ML01G2 and W29N02KVxxAF)
+ * do not work properly in timing mode 3.
+ * The workaround is to extend the SMC NRD pulse to meet tREA
+ * timing.
*
- * NRD_PULSE = tRP
+ * NRD_PULSE = max(tRP, tREA)
*/
- ncycles = DIV_ROUND_UP(conf->timings.sdr.tRP_min, mckperiodps);
+ pulse = max(conf->timings.sdr.tRP_min, conf->timings.sdr.tREA_max);
+ ncycles = DIV_ROUND_UP(pulse, mckperiodps);
totalcycles += ncycles;
ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NRD_SHIFT,
ncycles);
@@ -1858,7 +1863,7 @@ atmel_nand_controller_legacy_add_nands(struct atmel_nand_controller *nc)
static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc)
{
- struct device_node *np, *nand_np;
+ struct device_node *np;
struct device *dev = nc->dev;
int ret, reg_cells;
u32 val;
@@ -1885,7 +1890,7 @@ static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc)
reg_cells += val;
- for_each_child_of_node(np, nand_np) {
+ for_each_child_of_node_scoped(np, nand_np) {
struct atmel_nand *nand;
nand = atmel_nand_create(nc, nand_np, reg_cells);