summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2018-03-19 16:47:27 +0300
committerBoris Brezillon <boris.brezillon@bootlin.com>2018-03-20 13:59:54 +0300
commita97421c7532d382ab560ca153bdf9450f97c7e41 (patch)
tree89567f86b754de576c35bb6dd9574d62eb47bcce /drivers/mtd
parentf4531b2b1929806d2bec1a2f19805031d8bc0806 (diff)
downloadlinux-a97421c7532d382ab560ca153bdf9450f97c7e41.tar.xz
mtd: rawnand: prepare the removal of the ONFI parameter page
The NAND chip parameter page is statically allocated within the nand_chip structure, which reserves a lot of space. Even not ONFI nor JEDEC chips have it embedded. Also, only a few parameters are actually read from the parameter page after the detection. ONFI-related parameters that will be used outside from the identification function are stored in a separate onfi_parameters structure embedded in nand_parameters, this small structure that already hold generic parameters. For now, the onfi_parameters structure is allocated statically. However, after some deep rework in the NAND framework, it will be possible to do dynamic allocations from the NAND identification phase, and this strcuture will then be dynamically allocated when needed. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c2
-rw-r--r--drivers/mtd/nand/raw/nand_base.c30
-rw-r--r--drivers/mtd/nand/raw/nand_micron.c19
-rw-r--r--drivers/mtd/nand/raw/nand_timings.c12
4 files changed, 35 insertions, 28 deletions
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
index 039f2795617f..f3cc38372d79 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c
@@ -971,7 +971,7 @@ int gpmi_extra_init(struct gpmi_nand_data *this)
struct nand_chip *chip = &this->nand;
/* Enable the asynchronous EDO feature. */
- if (GPMI_IS_MX6(this) && chip->onfi_version) {
+ if (GPMI_IS_MX6(this) && chip->parameters.onfi.version) {
int mode = onfi_get_async_timing_mode(chip);
/* We only support the timing mode 4 and mode 5. */
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 0f1f45526c7f..789c11e0925e 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5126,17 +5126,17 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
/* Check version */
val = le16_to_cpu(p->revision);
if (val & (1 << 5))
- chip->onfi_version = 23;
+ chip->parameters.onfi.version = 23;
else if (val & (1 << 4))
- chip->onfi_version = 22;
+ chip->parameters.onfi.version = 22;
else if (val & (1 << 3))
- chip->onfi_version = 21;
+ chip->parameters.onfi.version = 21;
else if (val & (1 << 2))
- chip->onfi_version = 20;
+ chip->parameters.onfi.version = 20;
else if (val & (1 << 1))
- chip->onfi_version = 10;
+ chip->parameters.onfi.version = 10;
- if (!chip->onfi_version) {
+ if (!chip->parameters.onfi.version) {
pr_info("unsupported ONFI version: %d\n", val);
return 0;
}
@@ -5166,14 +5166,14 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
- if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
+ if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
chip->options |= NAND_BUSWIDTH_16;
if (p->ecc_bits != 0xff) {
chip->ecc_strength_ds = p->ecc_bits;
chip->ecc_step_ds = 512;
- } else if (chip->onfi_version >= 21 &&
- (onfi_feature(chip) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
+ } else if (chip->parameters.onfi.version >= 21 &&
+ (le16_to_cpu(p->features) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
/*
* The nand_flash_detect_ext_param_page() uses the
@@ -5194,6 +5194,16 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
/* Save some parameters from the parameter page for future use */
if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_SET_GET_FEATURES)
chip->parameters.supports_set_get_features = true;
+ chip->parameters.onfi.tPROG = le16_to_cpu(p->t_prog);
+ chip->parameters.onfi.tBERS = le16_to_cpu(p->t_bers);
+ chip->parameters.onfi.tR = le16_to_cpu(p->t_r);
+ chip->parameters.onfi.tCCS = le16_to_cpu(p->t_ccs);
+ chip->parameters.onfi.async_timing_mode =
+ le16_to_cpu(p->async_timing_mode);
+ chip->parameters.onfi.vendor_revision =
+ le16_to_cpu(p->vendor_revision);
+ memcpy(chip->parameters.onfi.vendor, p->vendor,
+ sizeof(p->vendor));
return 1;
}
@@ -5575,7 +5585,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
}
}
- chip->onfi_version = 0;
+ chip->parameters.onfi.version = 0;
if (!type->name || !type->pagesize) {
/* Check if the chip is ONFI compliant */
if (nand_flash_detect_onfi(chip))
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
index b825656f6284..c5974d8313e7 100644
--- a/drivers/mtd/nand/raw/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -56,17 +56,14 @@ static int micron_nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
*/
static int micron_nand_onfi_init(struct nand_chip *chip)
{
- struct nand_onfi_params *p = &chip->onfi_params;
- struct nand_onfi_vendor_micron *micron = (void *)p->vendor;
+ struct nand_parameters *p = &chip->parameters;
+ struct nand_onfi_vendor_micron *micron = (void *)p->onfi.vendor;
- if (!chip->onfi_version)
- return 0;
-
- if (le16_to_cpu(p->vendor_revision) < 1)
- return 0;
+ if (chip->parameters.onfi.version && p->onfi.vendor_revision) {
+ chip->read_retries = micron->read_retry_options;
+ chip->setup_read_retry = micron_nand_setup_read_retry;
+ }
- chip->read_retries = micron->read_retry_options;
- chip->setup_read_retry = micron_nand_setup_read_retry;
return 0;
}
@@ -207,7 +204,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
u8 feature[ONFI_SUBFEATURE_PARAM_LEN] = { 0, };
int ret;
- if (chip->onfi_version == 0)
+ if (!chip->parameters.onfi.version)
return MICRON_ON_DIE_UNSUPPORTED;
if (chip->bits_per_cell != 1)
@@ -239,7 +236,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
* Some Micron NANDs have an on-die ECC of 4/512, some other
* 8/512. We only support the former.
*/
- if (chip->onfi_params.ecc_bits != 4)
+ if (chip->ecc_strength_ds != 4)
return MICRON_ON_DIE_UNSUPPORTED;
return MICRON_ON_DIE_SUPPORTED;
diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c
index 9400d039ddbd..7c4e4a371bbc 100644
--- a/drivers/mtd/nand/raw/nand_timings.c
+++ b/drivers/mtd/nand/raw/nand_timings.c
@@ -306,17 +306,17 @@ int onfi_fill_data_interface(struct nand_chip *chip,
* tR, tPROG, tCCS, ...
* These information are part of the ONFI parameter page.
*/
- if (chip->onfi_version) {
- struct nand_onfi_params *params = &chip->onfi_params;
+ if (chip->parameters.onfi.version) {
+ struct nand_parameters *params = &chip->parameters;
struct nand_sdr_timings *timings = &iface->timings.sdr;
/* microseconds -> picoseconds */
- timings->tPROG_max = 1000000ULL * le16_to_cpu(params->t_prog);
- timings->tBERS_max = 1000000ULL * le16_to_cpu(params->t_bers);
- timings->tR_max = 1000000ULL * le16_to_cpu(params->t_r);
+ timings->tPROG_max = 1000000ULL * params->onfi.tPROG;
+ timings->tBERS_max = 1000000ULL * params->onfi.tBERS;
+ timings->tR_max = 1000000ULL * params->onfi.tR;
/* nanoseconds -> picoseconds */
- timings->tCCS_min = 1000UL * le16_to_cpu(params->t_ccs);
+ timings->tCCS_min = 1000UL * params->onfi.tCCS;
}
return 0;