Commit 6a943386 authored by Miquel Raynal's avatar Miquel Raynal

mtd: rawnand: add default values for dynamic timings

Some timings like tBERS (block erase time), tCCs (change column setup
time), tPROG (page program time) and tR (page read time) are derived
from the ONFI parameter page. They are set in the SDR interface only
if the chip is ONFI compliant.

It makes these timings unreliable and prevent the driver to use one of
these four values with a non-ONFI chip.

Fix this situation by taking the highest possible value (or a default
one) value for each missing timing (stored as unsigned 16-bit entries in
the parameter page).

This makes tBERS and tPROG being ~65ms while typical values are at most
a few milliseconds. As these are timeouts, it is not impacting at all
the performances in nominal use.

tR maximum time and tCCS minimum time (delay to wait after a change
column) are set, according to the ONFI specification, to default 'slow'
values; respectively 200us and 500ns.
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parent e8b0ac39
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/mtd/rawnand.h> #include <linux/mtd/rawnand.h>
#define ONFI_DYN_TIMING_MAX U16_MAX
static const struct nand_data_interface onfi_sdr_timings[] = { static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 0 */ /* Mode 0 */
{ {
...@@ -303,7 +305,7 @@ int onfi_fill_data_interface(struct nand_chip *chip, ...@@ -303,7 +305,7 @@ int onfi_fill_data_interface(struct nand_chip *chip,
/* /*
* Initialize timings that cannot be deduced from timing mode: * Initialize timings that cannot be deduced from timing mode:
* tR, tPROG, tCCS, ... * tPROG, tBERS, tR and tCCS.
* These information are part of the ONFI parameter page. * These information are part of the ONFI parameter page.
*/ */
if (chip->parameters.onfi.version) { if (chip->parameters.onfi.version) {
...@@ -317,6 +319,22 @@ int onfi_fill_data_interface(struct nand_chip *chip, ...@@ -317,6 +319,22 @@ int onfi_fill_data_interface(struct nand_chip *chip,
/* nanoseconds -> picoseconds */ /* nanoseconds -> picoseconds */
timings->tCCS_min = 1000UL * params->onfi.tCCS; timings->tCCS_min = 1000UL * params->onfi.tCCS;
} else {
struct nand_sdr_timings *timings = &iface->timings.sdr;
/*
* For non-ONFI chips we use the highest possible value for
* tPROG and tBERS. tR and tCCS will take the default values
* precised in the ONFI specification for timing mode 0,
* respectively 200us and 500ns.
*/
/* microseconds -> picoseconds */
timings->tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
timings->tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
timings->tR_max = 1000000ULL * 200000000ULL;
/* nanoseconds -> picoseconds */
timings->tCCS_min = 1000UL * 500000;
} }
return 0; return 0;
......
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