Skip to content

Commit 789157e

Browse files
miquelraynalBoris Brezillon
authored andcommitted
mtd: rawnand: allow vendors to declare (un)supported features
If SET/GET_FEATURES is available (from the parameter page), use a bitmap to declare what feature is actually supported. Initialize the bitmap in the core to support timing changes (only feature used by the core), also add support for Micron specific features used in Micron initialization code (in the init routine). Signed-off-by: Miquel Raynal <[email protected]> Signed-off-by: Boris Brezillon <[email protected]>
1 parent a97421c commit 789157e

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

drivers/mtd/nand/raw/nand_base.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,9 +1160,16 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
11601160
return status;
11611161
}
11621162

1163-
static bool nand_supports_set_get_features(struct nand_chip *chip)
1163+
static bool nand_supports_get_features(struct nand_chip *chip, int addr)
11641164
{
1165-
return chip->parameters.supports_set_get_features;
1165+
return (chip->parameters.supports_set_get_features &&
1166+
test_bit(addr, chip->parameters.get_feature_list));
1167+
}
1168+
1169+
static bool nand_supports_set_features(struct nand_chip *chip, int addr)
1170+
{
1171+
return (chip->parameters.supports_set_get_features &&
1172+
test_bit(addr, chip->parameters.set_feature_list));
11661173
}
11671174

11681175
/**
@@ -1179,7 +1186,7 @@ int nand_get_features(struct nand_chip *chip, int addr,
11791186
{
11801187
struct mtd_info *mtd = nand_to_mtd(chip);
11811188

1182-
if (!nand_supports_set_get_features(chip))
1189+
if (!nand_supports_get_features(chip, addr))
11831190
return -ENOTSUPP;
11841191

11851192
return chip->get_features(mtd, chip, addr, subfeature_param);
@@ -1200,7 +1207,7 @@ int nand_set_features(struct nand_chip *chip, int addr,
12001207
{
12011208
struct mtd_info *mtd = nand_to_mtd(chip);
12021209

1203-
if (!nand_supports_set_get_features(chip))
1210+
if (!nand_supports_set_features(chip, addr))
12041211
return -ENOTSUPP;
12051212

12061213
return chip->set_features(mtd, chip, addr, subfeature_param);
@@ -1271,7 +1278,7 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
12711278
return 0;
12721279

12731280
/* Change the mode on the chip side (if supported by the NAND chip) */
1274-
if (nand_supports_set_get_features(chip)) {
1281+
if (nand_supports_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) {
12751282
chip->select_chip(mtd, chipnr);
12761283
ret = nand_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE,
12771284
tmode_param);
@@ -1286,7 +1293,7 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
12861293
return ret;
12871294

12881295
/* Check the mode has been accepted by the chip, if supported */
1289-
if (!nand_supports_set_get_features(chip))
1296+
if (!nand_supports_get_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE))
12901297
return 0;
12911298

12921299
memset(tmode_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
@@ -5192,8 +5199,13 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
51925199
}
51935200

51945201
/* Save some parameters from the parameter page for future use */
5195-
if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_SET_GET_FEATURES)
5202+
if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_SET_GET_FEATURES) {
51965203
chip->parameters.supports_set_get_features = true;
5204+
bitmap_set(chip->parameters.get_feature_list,
5205+
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
5206+
bitmap_set(chip->parameters.set_feature_list,
5207+
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
5208+
}
51975209
chip->parameters.onfi.tPROG = le16_to_cpu(p->t_prog);
51985210
chip->parameters.onfi.tBERS = le16_to_cpu(p->t_bers);
51995211
chip->parameters.onfi.tR = le16_to_cpu(p->t_r);

drivers/mtd/nand/raw/nand_micron.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ static int micron_nand_onfi_init(struct nand_chip *chip)
6464
chip->setup_read_retry = micron_nand_setup_read_retry;
6565
}
6666

67+
if (p->supports_set_get_features) {
68+
set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->set_feature_list);
69+
set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->get_feature_list);
70+
}
6771

6872
return 0;
6973
}

include/linux/mtd/rawnand.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/mtd/mtd.h>
2222
#include <linux/mtd/flashchip.h>
2323
#include <linux/mtd/bbm.h>
24+
#include <linux/types.h>
2425

2526
struct mtd_info;
2627
struct nand_flash_dev;
@@ -235,7 +236,8 @@ struct nand_chip;
235236
#define ONFI_TIMING_MODE_5 (1 << 5)
236237
#define ONFI_TIMING_MODE_UNKNOWN (1 << 6)
237238

238-
/* ONFI feature address */
239+
/* ONFI feature number/address */
240+
#define ONFI_FEATURE_NUMBER 256
239241
#define ONFI_FEATURE_ADDR_TIMING_MODE 0x1
240242

241243
/* Vendor-specific feature address (Micron) */
@@ -455,12 +457,16 @@ struct onfi_params {
455457
* struct nand_parameters - NAND generic parameters from the parameter page
456458
* @model: Model name
457459
* @supports_set_get_features: The NAND chip supports setting/getting features
460+
* @set_feature_list: Bitmap of features that can be set
461+
* @get_feature_list: Bitmap of features that can be get
458462
* @onfi: ONFI specific parameters
459463
*/
460464
struct nand_parameters {
461465
/* Generic parameters */
462466
char model[100];
463467
bool supports_set_get_features;
468+
DECLARE_BITMAP(set_feature_list, ONFI_FEATURE_NUMBER);
469+
DECLARE_BITMAP(get_feature_list, ONFI_FEATURE_NUMBER);
464470

465471
/* ONFI parameters */
466472
struct onfi_params onfi;

0 commit comments

Comments
 (0)