summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@bootlin.com>2018-12-20 15:10:47 +0100
committerMiquel Raynal <miquel.raynal@bootlin.com>2019-02-05 15:39:39 +0100
commit511d05e0dadd91d398ed14f043fbcc93d728b98c (patch)
treeb0a7629ced4ccf2d0e409b3a47edcd331c74f0d4 /drivers
parentf4cb4d7b46f6409382fd981eec9556e1f3c1dc5d (diff)
downloadlinux-511d05e0dadd91d398ed14f043fbcc93d728b98c.tar.bz2
mtd: rawnand: sunxi: Handle the tREA > tRC / 2 case
In non-EDO, tREA should be less than tRP to guarantee that the controller does not sample the IO lines too early. Unfortunately, the sunxi NAND controller does not allow us to have different values for tRP and tREH (tRP = tREH = tRW / 2). We have 2 options to overcome this limitation: 1/ Extend tRC to fulfil the tREA <= tRC / 2 constraint 2/ Use EDO mode (only works if timings->tRLOH > 0) Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/raw/sunxi_nand.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index 4fd1f8da6906..4282bc477761 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1442,6 +1442,20 @@ static int sunxi_nfc_setup_data_interface(struct nand_chip *nand, int csline,
if (timings->tRHW_min > (min_clk_period * 20))
min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20);
+ /*
+ * In non-EDO, tREA should be less than tRP to guarantee that the
+ * controller does not sample the IO lines too early. Unfortunately,
+ * the sunxi NAND controller does not allow us to have different
+ * values for tRP and tREH (tRP = tREH = tRW / 2).
+ *
+ * We have 2 options to overcome this limitation:
+ *
+ * 1/ Extend tRC to fulfil the tREA <= tRC / 2 constraint
+ * 2/ Use EDO mode (only works if timings->tRLOH > 0)
+ */
+ if (timings->tREA_max > min_clk_period && !timings->tRLOH_min)
+ min_clk_period = timings->tREA_max;
+
tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
min_clk_period);
if (tWB < 0) {
@@ -1497,14 +1511,16 @@ static int sunxi_nfc_setup_data_interface(struct nand_chip *nand, int csline,
return -EINVAL;
}
+ sunxi_nand->timing_ctl = 0;
+
/*
* ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
* output cycle timings shall be used if the host drives tRC less than
- * 30 ns.
+ * 30 ns. We should also use EDO mode if tREA is bigger than tRP.
*/
min_clk_period = NSEC_PER_SEC / real_clk_rate;
- sunxi_nand->timing_ctl = ((min_clk_period * 2) < 30) ?
- NFC_TIMING_CTL_EDO : 0;
+ if (min_clk_period * 2 < 30 || min_clk_period * 1000 < timings->tREA_max)
+ sunxi_nand->timing_ctl = NFC_TIMING_CTL_EDO;
return 0;
}