summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/raw/nand_base.c18
-rw-r--r--include/linux/mtd/onfi.h5
2 files changed, 18 insertions, 5 deletions
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index b8a515a74379..cfe8257bf175 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -832,7 +832,7 @@ static int nand_reset_interface(struct nand_chip *chip, int chipnr)
static int nand_setup_interface(struct nand_chip *chip, int chipnr)
{
const struct nand_controller_ops *ops = chip->controller->ops;
- u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { };
+ u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { }, request;
int ret;
if (!nand_controller_can_setup_interface(chip))
@@ -848,7 +848,12 @@ static int nand_setup_interface(struct nand_chip *chip, int chipnr)
if (!chip->best_interface_config)
return 0;
- tmode_param[0] = chip->best_interface_config->timings.mode;
+ request = chip->best_interface_config->timings.mode;
+ if (nand_interface_is_sdr(chip->best_interface_config))
+ request |= ONFI_DATA_INTERFACE_SDR;
+ else
+ request |= ONFI_DATA_INTERFACE_NVDDR;
+ tmode_param[0] = request;
/* Change the mode on the chip side (if supported by the NAND chip) */
if (nand_supports_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) {
@@ -877,10 +882,13 @@ static int nand_setup_interface(struct nand_chip *chip, int chipnr)
if (ret)
goto err_reset_chip;
- if (tmode_param[0] != chip->best_interface_config->timings.mode) {
- pr_warn("timing mode %d not acknowledged by the NAND chip\n",
+ if (request != tmode_param[0]) {
+ pr_warn("%s timing mode %d not acknowledged by the NAND chip\n",
+ nand_interface_is_nvddr(chip->best_interface_config) ? "NV-DDR" : "SDR",
chip->best_interface_config->timings.mode);
- ret = 0;
+ pr_debug("NAND chip would work in %s timing mode %d\n",
+ tmode_param[0] & ONFI_DATA_INTERFACE_NVDDR ? "NV-DDR" : "SDR",
+ (unsigned int)ONFI_TIMING_MODE_PARAM(tmode_param[0]));
goto err_reset_chip;
}
diff --git a/include/linux/mtd/onfi.h b/include/linux/mtd/onfi.h
index a9677bf1e47e..a7376f9beddf 100644
--- a/include/linux/mtd/onfi.h
+++ b/include/linux/mtd/onfi.h
@@ -11,6 +11,7 @@
#define __LINUX_MTD_ONFI_H
#include <linux/types.h>
+#include <linux/bitfield.h>
/* ONFI version bits */
#define ONFI_VERSION_1_0 BIT(1)
@@ -29,6 +30,9 @@
#define ONFI_FEATURE_EXT_PARAM_PAGE BIT(7)
/* ONFI timing mode, used in both asynchronous and synchronous mode */
+#define ONFI_DATA_INTERFACE_SDR 0
+#define ONFI_DATA_INTERFACE_NVDDR BIT(4)
+#define ONFI_DATA_INTERFACE_NVDDR2 BIT(5)
#define ONFI_TIMING_MODE_0 BIT(0)
#define ONFI_TIMING_MODE_1 BIT(1)
#define ONFI_TIMING_MODE_2 BIT(2)
@@ -36,6 +40,7 @@
#define ONFI_TIMING_MODE_4 BIT(4)
#define ONFI_TIMING_MODE_5 BIT(5)
#define ONFI_TIMING_MODE_UNKNOWN BIT(6)
+#define ONFI_TIMING_MODE_PARAM(x) FIELD_GET(GENMASK(3, 0), (x))
/* ONFI feature number/address */
#define ONFI_FEATURE_NUMBER 256