* [PATCH 7/9] mtd: nand: sunxi: switch from manual to automated timing config
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473928373-8680-1-git-send-email-s.hauer@pengutronix.de>
The NAND framework is now able to select the best NAND timings for us.
All we have to do is implement a ->setup_data_interface() function to
apply those timings and remove the timing selection code from the sunxi
driver.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/sunxi_nand.c | 76 ++++++++-----------------------------------
1 file changed, 14 insertions(+), 62 deletions(-)
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index e414b31..8c59a10 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1572,14 +1572,22 @@ static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
#define sunxi_nand_lookup_timing(l, p, c) \
_sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
-static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
- const struct nand_sdr_timings *timings)
+static int sunxi_nfc_setup_data_interface(struct mtd_info *mtd,
+ const struct nand_data_interface *conf,
+ bool check_only)
{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct sunxi_nand_chip *chip = to_sunxi_nand(nand);
struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
+ const struct nand_sdr_timings *timings;
u32 min_clk_period = 0;
s32 tWB, tADL, tWHR, tRHW, tCAD;
long real_clk_rate;
+ timings = nand_get_sdr_timings(conf);
+ if (IS_ERR(timings))
+ return -ENOTSUPP;
+
/* T1 <=> tCLS */
if (timings->tCLS_min > min_clk_period)
min_clk_period = timings->tCLS_min;
@@ -1679,6 +1687,9 @@ static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
return tRHW;
}
+ if (check_only)
+ return 0;
+
/*
* TODO: according to ONFI specs this value only applies for DDR NAND,
* but Allwinner seems to set this to 0x7. Mimic them for now.
@@ -1712,44 +1723,6 @@ static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
return 0;
}
-static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
- struct device_node *np)
-{
- struct mtd_info *mtd = nand_to_mtd(&chip->nand);
- const struct nand_sdr_timings *timings;
- int ret;
- int mode;
-
- mode = onfi_get_async_timing_mode(&chip->nand);
- if (mode == ONFI_TIMING_MODE_UNKNOWN) {
- mode = chip->nand.onfi_timing_mode_default;
- } else {
- uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
- int i;
-
- mode = fls(mode) - 1;
- if (mode < 0)
- mode = 0;
-
- feature[0] = mode;
- for (i = 0; i < chip->nsels; i++) {
- chip->nand.select_chip(mtd, i);
- ret = chip->nand.onfi_set_features(mtd, &chip->nand,
- ONFI_FEATURE_ADDR_TIMING_MODE,
- feature);
- chip->nand.select_chip(mtd, -1);
- if (ret)
- return ret;
- }
- }
-
- timings = onfi_async_timing_mode_to_sdr_timings(mode);
- if (IS_ERR(timings))
- return PTR_ERR(timings);
-
- return sunxi_nand_chip_set_timings(chip, timings);
-}
-
static int sunxi_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
@@ -1975,7 +1948,6 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
struct device_node *np)
{
- const struct nand_sdr_timings *timings;
struct sunxi_nand_chip *chip;
struct mtd_info *mtd;
struct nand_chip *nand;
@@ -2065,25 +2037,11 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
nand->read_buf = sunxi_nfc_read_buf;
nand->write_buf = sunxi_nfc_write_buf;
nand->read_byte = sunxi_nfc_read_byte;
+ nand->setup_data_interface = sunxi_nfc_setup_data_interface;
mtd = nand_to_mtd(nand);
mtd->dev.parent = dev;
- timings = onfi_async_timing_mode_to_sdr_timings(0);
- if (IS_ERR(timings)) {
- ret = PTR_ERR(timings);
- dev_err(dev,
- "could not retrieve timings for ONFI mode 0: %d\n",
- ret);
- return ret;
- }
-
- ret = sunxi_nand_chip_set_timings(chip, timings);
- if (ret) {
- dev_err(dev, "could not configure chip timings: %d\n", ret);
- return ret;
- }
-
ret = nand_scan_ident(mtd, nsels, NULL);
if (ret)
return ret;
@@ -2096,12 +2054,6 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
nand->options |= NAND_SUBPAGE_READ;
- ret = sunxi_nand_chip_init_timings(chip, np);
- if (ret) {
- dev_err(dev, "could not configure chip timings: %d\n", ret);
- return ret;
- }
-
ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np);
if (ret) {
dev_err(dev, "ECC init failed: %d\n", ret);
--
2.8.1
^ permalink raw reply related
* [PATCH 6/9] mtd: nand: automate NAND timings selection
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473928373-8680-1-git-send-email-s.hauer@pengutronix.de>
From: Boris Brezillon <boris.brezillon@free-electrons.com>
The NAND framework provides several helpers to query timing modes supported
by a NAND chip, but this implies that all NAND controller drivers have
to implement the same timings selection dance. Also currently NAND
devices can be resetted at arbitrary places which also resets the timing
for ONFI chips to timing mode 0.
Provide a common logic to select the best timings based on ONFI or
->onfi_timing_mode_default information. Hook this into nand_reset()
to make sure the new timing is applied each time during a reset.
NAND controller willing to support timings adjustment should just
implement the ->setup_data_interface() method.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_base.c | 156 +++++++++++++++++++++++++++++++++++++++++++
include/linux/mtd/nand.h | 14 ++--
2 files changed, 166 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1f704cc..c7d500ea 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -948,6 +948,146 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
}
/**
+ * nand_reset_data_interface - Reset data interface and timings
+ * @chip: The NAND chip
+ *
+ * Reset the Data interface and timings to ONFI mode 0.
+ *
+ * Returns 0 for success or negative error code otherwise.
+ */
+static int nand_reset_data_interface(struct nand_chip *chip)
+{
+ struct mtd_info *mtd = &chip->mtd;
+ const struct nand_data_interface *conf;
+ int ret;
+
+ if (!chip->setup_data_interface)
+ return 0;
+
+ /*
+ * The ONFI specification says:
+ * "
+ * To transition from NV-DDR or NV-DDR2 to the SDR data
+ * interface, the host shall use the Reset (FFh) command
+ * using SDR timing mode 0. A device in any timing mode is
+ * required to recognize Reset (FFh) command issued in SDR
+ * timing mode 0.
+ * "
+ *
+ * Configure the data interface in SDR mode and set the
+ * timings to timing mode 0.
+ */
+
+ conf = nand_get_default_data_interface();
+ ret = chip->setup_data_interface(mtd, conf, false);
+ if (ret)
+ pr_err("Failed to configure data interface to SDR timing mode 0\n");
+
+ return ret;
+}
+
+/**
+ * nand_setup_data_interface - Setup the best data interface and timings
+ * @chip: The NAND chip
+ *
+ * Find and configure the best data interface and NAND timings supported by
+ * the chip and the driver.
+ * First tries to retrieve supported timing modes from ONFI information,
+ * and if the NAND chip does not support ONFI, relies on the
+ * ->onfi_timing_mode_default specified in the nand_ids table.
+ *
+ * Returns 0 for success or negative error code otherwise.
+ */
+static int nand_setup_data_interface(struct nand_chip *chip)
+{
+ struct mtd_info *mtd = &chip->mtd;
+ int ret;
+
+ if (!chip->setup_data_interface || !chip->data_interface)
+ return 0;
+
+ /*
+ * Ensure the timing mode has been changed on the chip side
+ * before changing timings on the controller side.
+ */
+ if (chip->onfi_version) {
+ uint8_t tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {
+ chip->onfi_timing_mode_default,
+ };
+
+ ret = chip->onfi_set_features(mtd, chip,
+ ONFI_FEATURE_ADDR_TIMING_MODE,
+ tmode_param);
+ if (ret)
+ goto err;
+ }
+
+ ret = chip->setup_data_interface(mtd, chip->data_interface, false);
+err:
+ return ret;
+}
+
+/**
+ * nand_init_data_interface - find the best data interface and timings
+ * @chip: The NAND chip
+ *
+ * Find the best data interface and NAND timings supported by the chip
+ * and the driver.
+ * First tries to retrieve supported timing modes from ONFI information,
+ * and if the NAND chip does not support ONFI, relies on the
+ * ->onfi_timing_mode_default specified in the nand_ids table. After this
+ * function nand_chip->data_interface is initialized with the best timing mode
+ * available.
+ *
+ * Returns 0 for success or negative error code otherwise.
+ */
+static int nand_init_data_interface(struct nand_chip *chip)
+{
+ struct mtd_info *mtd = &chip->mtd;
+ int modes, mode, ret;
+
+ if (!chip->setup_data_interface)
+ return 0;
+
+ /*
+ * First try to identify the best timings from ONFI parameters and
+ * if the NAND does not support ONFI, fallback to the default ONFI
+ * timing mode.
+ */
+ modes = onfi_get_async_timing_mode(chip);
+ if (modes == ONFI_TIMING_MODE_UNKNOWN) {
+ if (!chip->onfi_timing_mode_default)
+ return 0;
+
+ modes = GENMASK(chip->onfi_timing_mode_default, 0);
+ }
+
+ chip->data_interface = kzalloc(sizeof(*chip->data_interface), GFP_KERNEL);
+ if (!chip->data_interface)
+ return -ENOMEM;
+
+ for (mode = fls(modes) - 1; mode >= 0; mode--) {
+ ret = onfi_init_data_interface(chip, chip->data_interface,
+ NAND_SDR_IFACE, mode);
+ if (ret)
+ continue;
+
+ ret = chip->setup_data_interface(mtd, chip->data_interface, true);
+ if (!ret) {
+ chip->onfi_timing_mode_default = mode;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void nand_release_data_interface(struct nand_chip *chip)
+{
+ kfree(chip->data_interface);
+}
+
+/**
* nand_reset - Reset and initialize a NAND device
* @chip: The NAND chip
*
@@ -955,8 +1095,18 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
*/
int nand_reset(struct nand_chip *chip)
{
+ int ret;
+
+ ret = nand_reset_data_interface(chip);
+ if (ret)
+ return ret;
+
chip->cmdfunc(&chip->mtd, NAND_CMD_RESET, -1, -1);
+ ret = nand_setup_data_interface(chip);
+ if (ret)
+ return ret;
+
return 0;
}
@@ -4168,6 +4318,10 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
return PTR_ERR(type);
}
+ ret = nand_init_data_interface(chip);
+ if (ret)
+ return ret;
+
chip->select_chip(mtd, -1);
/* Check for a chip array */
@@ -4627,6 +4781,8 @@ void nand_release(struct mtd_info *mtd)
mtd_device_unregister(mtd);
+ nand_release_data_interface(chip);
+
/* Free bad block table memory */
kfree(chip->bbt);
if (!(chip->options & NAND_OWN_BUFFERS))
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 29ae324..24b4190 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -743,10 +743,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
* also from the datasheet. It is the recommended ECC step
* size, if known; if unknown, set to zero.
* @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is
- * either deduced from the datasheet if the NAND
- * chip is not ONFI compliant or set to 0 if it is
- * (an ONFI chip is always configured in mode 0
- * after a NAND reset)
+ * set to the actually used ONFI mode if the chip is
+ * ONFI compliant or deduced from the datasheet if
+ * the NAND chip is not ONFI compliant.
* @numchips: [INTERN] number of physical chips
* @chipsize: [INTERN] the size of one chip for multichip arrays
* @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
@@ -766,6 +765,7 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
* @read_retries: [INTERN] the number of read retry modes supported
* @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
* @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
+ * @setup_data_interface: [OPTIONAL] setup the data interface and timing
* @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash
* lookup.
@@ -812,6 +812,10 @@ struct nand_chip {
int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
int feature_addr, uint8_t *subfeature_para);
int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
+ int (*setup_data_interface)(struct mtd_info *mtd,
+ const struct nand_data_interface *conf,
+ bool check_only);
+
int chip_delay;
unsigned int options;
@@ -841,6 +845,8 @@ struct nand_chip {
struct nand_jedec_params jedec_params;
};
+ struct nand_data_interface *data_interface;
+
int read_retries;
flstate_t state;
--
2.8.1
^ permalink raw reply related
* [PATCH 5/9] mtd: nand: Expose data interface for ONFI mode 0
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473928373-8680-1-git-send-email-s.hauer@pengutronix.de>
The nand layer will need ONFI mode 0 to use it as timing mode
before and right after reset.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_timings.c | 11 +++++++++++
include/linux/mtd/nand.h | 2 ++
2 files changed, 13 insertions(+)
diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c
index 608d098..9cdbc16 100644
--- a/drivers/mtd/nand/nand_timings.c
+++ b/drivers/mtd/nand/nand_timings.c
@@ -297,3 +297,14 @@ int onfi_init_data_interface(struct nand_chip *chip,
return 0;
}
+
+/**
+ * nand_get_default_data_interface - [NAND Interface] Retrieve NAND
+ * data interface for mode 0. This is used as default timing after
+ * reset.
+ */
+const struct nand_data_interface *nand_get_default_data_interface(void)
+{
+ return &onfi_sdr_timings[0];
+}
+EXPORT_SYMBOL(nand_get_default_data_interface);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 7216f54..29ae324 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -1146,6 +1146,8 @@ static inline int jedec_feature(struct nand_chip *chip)
/* get timing characteristics from ONFI timing mode. */
const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
+/* get data interface from ONFI timing mode 0, used after reset. */
+const struct nand_data_interface *nand_get_default_data_interface(void);
int nand_check_erased_ecc_chunk(void *data, int datalen,
void *ecc, int ecclen,
--
2.8.1
^ permalink raw reply related
* [PATCH 4/9] mtd: nand: Add function to convert ONFI mode to data_interface
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473928373-8680-1-git-send-email-s.hauer@pengutronix.de>
onfi_init_data_interface() initializes a data interface with
values from a given ONFI mode.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_timings.c | 28 ++++++++++++++++++++++++++++
include/linux/mtd/nand.h | 5 +++++
2 files changed, 33 insertions(+)
diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c
index 9af2ebc..608d098 100644
--- a/drivers/mtd/nand/nand_timings.c
+++ b/drivers/mtd/nand/nand_timings.c
@@ -269,3 +269,31 @@ const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode)
return &onfi_sdr_timings[mode].timings.sdr;
}
EXPORT_SYMBOL(onfi_async_timing_mode_to_sdr_timings);
+
+/**
+ * onfi_init_data_interface - [NAND Interface] Initialize a data interface from
+ * given ONFI mode
+ * @iface: The data interface to be initialized
+ * @mode: The ONFI timing mode
+ */
+int onfi_init_data_interface(struct nand_chip *chip,
+ struct nand_data_interface *iface,
+ enum nand_data_interface_type type,
+ int timing_mode)
+{
+ if (type != NAND_SDR_IFACE)
+ return -EINVAL;
+
+ if (timing_mode < 0 || timing_mode >= ARRAY_SIZE(onfi_sdr_timings))
+ return -EINVAL;
+
+ *iface = onfi_sdr_timings[timing_mode];
+
+ /*
+ * TODO: initialize timings that cannot be deduced from timing mode:
+ * tR, tPROG, tCCS, ...
+ * These information are part of the ONFI parameter page.
+ */
+
+ return 0;
+}
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index f305bed..7216f54 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -1104,6 +1104,11 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
}
+int onfi_init_data_interface(struct nand_chip *chip,
+ struct nand_data_interface *iface,
+ enum nand_data_interface_type type,
+ int timing_mode);
+
/*
* Check if it is a SLC nand.
* The !nand_is_slc() can be used to check the MLC/TLC nand chips.
--
2.8.1
^ permalink raw reply related
* [PATCH 3/9] mtd: nand: convert ONFI mode into data interface
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473928373-8680-1-git-send-email-s.hauer@pengutronix.de>
struct nand_data_interface is the designated type to pass to
the NAND drivers to configure the timing. To simplify further
patches convert the onfi_sdr_timings array from type struct
nand_sdr_timings nand_data_interface.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_timings.c | 430 +++++++++++++++++++++-------------------
1 file changed, 224 insertions(+), 206 deletions(-)
diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c
index e81470a..9af2ebc 100644
--- a/drivers/mtd/nand/nand_timings.c
+++ b/drivers/mtd/nand/nand_timings.c
@@ -13,228 +13,246 @@
#include <linux/export.h>
#include <linux/mtd/nand.h>
-static const struct nand_sdr_timings onfi_sdr_timings[] = {
+static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 0 */
{
- .tADL_min = 200000,
- .tALH_min = 20000,
- .tALS_min = 50000,
- .tAR_min = 25000,
- .tCEA_max = 100000,
- .tCEH_min = 20000,
- .tCH_min = 20000,
- .tCHZ_max = 100000,
- .tCLH_min = 20000,
- .tCLR_min = 20000,
- .tCLS_min = 50000,
- .tCOH_min = 0,
- .tCS_min = 70000,
- .tDH_min = 20000,
- .tDS_min = 40000,
- .tFEAT_max = 1000000,
- .tIR_min = 10000,
- .tITC_max = 1000000,
- .tRC_min = 100000,
- .tREA_max = 40000,
- .tREH_min = 30000,
- .tRHOH_min = 0,
- .tRHW_min = 200000,
- .tRHZ_max = 200000,
- .tRLOH_min = 0,
- .tRP_min = 50000,
- .tRST_max = 250000000000ULL,
- .tWB_max = 200000,
- .tRR_min = 40000,
- .tWC_min = 100000,
- .tWH_min = 30000,
- .tWHR_min = 120000,
- .tWP_min = 50000,
- .tWW_min = 100000,
+ .type = NAND_SDR_IFACE,
+ .timings.sdr = {
+ .tADL_min = 200000,
+ .tALH_min = 20000,
+ .tALS_min = 50000,
+ .tAR_min = 25000,
+ .tCEA_max = 100000,
+ .tCEH_min = 20000,
+ .tCH_min = 20000,
+ .tCHZ_max = 100000,
+ .tCLH_min = 20000,
+ .tCLR_min = 20000,
+ .tCLS_min = 50000,
+ .tCOH_min = 0,
+ .tCS_min = 70000,
+ .tDH_min = 20000,
+ .tDS_min = 40000,
+ .tFEAT_max = 1000000,
+ .tIR_min = 10000,
+ .tITC_max = 1000000,
+ .tRC_min = 100000,
+ .tREA_max = 40000,
+ .tREH_min = 30000,
+ .tRHOH_min = 0,
+ .tRHW_min = 200000,
+ .tRHZ_max = 200000,
+ .tRLOH_min = 0,
+ .tRP_min = 50000,
+ .tRST_max = 250000000000ULL,
+ .tWB_max = 200000,
+ .tRR_min = 40000,
+ .tWC_min = 100000,
+ .tWH_min = 30000,
+ .tWHR_min = 120000,
+ .tWP_min = 50000,
+ .tWW_min = 100000,
+ },
},
/* Mode 1 */
{
- .tADL_min = 100000,
- .tALH_min = 10000,
- .tALS_min = 25000,
- .tAR_min = 10000,
- .tCEA_max = 45000,
- .tCEH_min = 20000,
- .tCH_min = 10000,
- .tCHZ_max = 50000,
- .tCLH_min = 10000,
- .tCLR_min = 10000,
- .tCLS_min = 25000,
- .tCOH_min = 15000,
- .tCS_min = 35000,
- .tDH_min = 10000,
- .tDS_min = 20000,
- .tFEAT_max = 1000000,
- .tIR_min = 0,
- .tITC_max = 1000000,
- .tRC_min = 50000,
- .tREA_max = 30000,
- .tREH_min = 15000,
- .tRHOH_min = 15000,
- .tRHW_min = 100000,
- .tRHZ_max = 100000,
- .tRLOH_min = 0,
- .tRP_min = 25000,
- .tRR_min = 20000,
- .tRST_max = 500000000,
- .tWB_max = 100000,
- .tWC_min = 45000,
- .tWH_min = 15000,
- .tWHR_min = 80000,
- .tWP_min = 25000,
- .tWW_min = 100000,
+ .type = NAND_SDR_IFACE,
+ .timings.sdr = {
+ .tADL_min = 100000,
+ .tALH_min = 10000,
+ .tALS_min = 25000,
+ .tAR_min = 10000,
+ .tCEA_max = 45000,
+ .tCEH_min = 20000,
+ .tCH_min = 10000,
+ .tCHZ_max = 50000,
+ .tCLH_min = 10000,
+ .tCLR_min = 10000,
+ .tCLS_min = 25000,
+ .tCOH_min = 15000,
+ .tCS_min = 35000,
+ .tDH_min = 10000,
+ .tDS_min = 20000,
+ .tFEAT_max = 1000000,
+ .tIR_min = 0,
+ .tITC_max = 1000000,
+ .tRC_min = 50000,
+ .tREA_max = 30000,
+ .tREH_min = 15000,
+ .tRHOH_min = 15000,
+ .tRHW_min = 100000,
+ .tRHZ_max = 100000,
+ .tRLOH_min = 0,
+ .tRP_min = 25000,
+ .tRR_min = 20000,
+ .tRST_max = 500000000,
+ .tWB_max = 100000,
+ .tWC_min = 45000,
+ .tWH_min = 15000,
+ .tWHR_min = 80000,
+ .tWP_min = 25000,
+ .tWW_min = 100000,
+ },
},
/* Mode 2 */
{
- .tADL_min = 100000,
- .tALH_min = 10000,
- .tALS_min = 15000,
- .tAR_min = 10000,
- .tCEA_max = 30000,
- .tCEH_min = 20000,
- .tCH_min = 10000,
- .tCHZ_max = 50000,
- .tCLH_min = 10000,
- .tCLR_min = 10000,
- .tCLS_min = 15000,
- .tCOH_min = 15000,
- .tCS_min = 25000,
- .tDH_min = 5000,
- .tDS_min = 15000,
- .tFEAT_max = 1000000,
- .tIR_min = 0,
- .tITC_max = 1000000,
- .tRC_min = 35000,
- .tREA_max = 25000,
- .tREH_min = 15000,
- .tRHOH_min = 15000,
- .tRHW_min = 100000,
- .tRHZ_max = 100000,
- .tRLOH_min = 0,
- .tRR_min = 20000,
- .tRST_max = 500000000,
- .tWB_max = 100000,
- .tRP_min = 17000,
- .tWC_min = 35000,
- .tWH_min = 15000,
- .tWHR_min = 80000,
- .tWP_min = 17000,
- .tWW_min = 100000,
+ .type = NAND_SDR_IFACE,
+ .timings.sdr = {
+ .tADL_min = 100000,
+ .tALH_min = 10000,
+ .tALS_min = 15000,
+ .tAR_min = 10000,
+ .tCEA_max = 30000,
+ .tCEH_min = 20000,
+ .tCH_min = 10000,
+ .tCHZ_max = 50000,
+ .tCLH_min = 10000,
+ .tCLR_min = 10000,
+ .tCLS_min = 15000,
+ .tCOH_min = 15000,
+ .tCS_min = 25000,
+ .tDH_min = 5000,
+ .tDS_min = 15000,
+ .tFEAT_max = 1000000,
+ .tIR_min = 0,
+ .tITC_max = 1000000,
+ .tRC_min = 35000,
+ .tREA_max = 25000,
+ .tREH_min = 15000,
+ .tRHOH_min = 15000,
+ .tRHW_min = 100000,
+ .tRHZ_max = 100000,
+ .tRLOH_min = 0,
+ .tRR_min = 20000,
+ .tRST_max = 500000000,
+ .tWB_max = 100000,
+ .tRP_min = 17000,
+ .tWC_min = 35000,
+ .tWH_min = 15000,
+ .tWHR_min = 80000,
+ .tWP_min = 17000,
+ .tWW_min = 100000,
+ },
},
/* Mode 3 */
{
- .tADL_min = 100000,
- .tALH_min = 5000,
- .tALS_min = 10000,
- .tAR_min = 10000,
- .tCEA_max = 25000,
- .tCEH_min = 20000,
- .tCH_min = 5000,
- .tCHZ_max = 50000,
- .tCLH_min = 5000,
- .tCLR_min = 10000,
- .tCLS_min = 10000,
- .tCOH_min = 15000,
- .tCS_min = 25000,
- .tDH_min = 5000,
- .tDS_min = 10000,
- .tFEAT_max = 1000000,
- .tIR_min = 0,
- .tITC_max = 1000000,
- .tRC_min = 30000,
- .tREA_max = 20000,
- .tREH_min = 10000,
- .tRHOH_min = 15000,
- .tRHW_min = 100000,
- .tRHZ_max = 100000,
- .tRLOH_min = 0,
- .tRP_min = 15000,
- .tRR_min = 20000,
- .tRST_max = 500000000,
- .tWB_max = 100000,
- .tWC_min = 30000,
- .tWH_min = 10000,
- .tWHR_min = 80000,
- .tWP_min = 15000,
- .tWW_min = 100000,
+ .type = NAND_SDR_IFACE,
+ .timings.sdr = {
+ .tADL_min = 100000,
+ .tALH_min = 5000,
+ .tALS_min = 10000,
+ .tAR_min = 10000,
+ .tCEA_max = 25000,
+ .tCEH_min = 20000,
+ .tCH_min = 5000,
+ .tCHZ_max = 50000,
+ .tCLH_min = 5000,
+ .tCLR_min = 10000,
+ .tCLS_min = 10000,
+ .tCOH_min = 15000,
+ .tCS_min = 25000,
+ .tDH_min = 5000,
+ .tDS_min = 10000,
+ .tFEAT_max = 1000000,
+ .tIR_min = 0,
+ .tITC_max = 1000000,
+ .tRC_min = 30000,
+ .tREA_max = 20000,
+ .tREH_min = 10000,
+ .tRHOH_min = 15000,
+ .tRHW_min = 100000,
+ .tRHZ_max = 100000,
+ .tRLOH_min = 0,
+ .tRP_min = 15000,
+ .tRR_min = 20000,
+ .tRST_max = 500000000,
+ .tWB_max = 100000,
+ .tWC_min = 30000,
+ .tWH_min = 10000,
+ .tWHR_min = 80000,
+ .tWP_min = 15000,
+ .tWW_min = 100000,
+ },
},
/* Mode 4 */
{
- .tADL_min = 70000,
- .tALH_min = 5000,
- .tALS_min = 10000,
- .tAR_min = 10000,
- .tCEA_max = 25000,
- .tCEH_min = 20000,
- .tCH_min = 5000,
- .tCHZ_max = 30000,
- .tCLH_min = 5000,
- .tCLR_min = 10000,
- .tCLS_min = 10000,
- .tCOH_min = 15000,
- .tCS_min = 20000,
- .tDH_min = 5000,
- .tDS_min = 10000,
- .tFEAT_max = 1000000,
- .tIR_min = 0,
- .tITC_max = 1000000,
- .tRC_min = 25000,
- .tREA_max = 20000,
- .tREH_min = 10000,
- .tRHOH_min = 15000,
- .tRHW_min = 100000,
- .tRHZ_max = 100000,
- .tRLOH_min = 5000,
- .tRP_min = 12000,
- .tRR_min = 20000,
- .tRST_max = 500000000,
- .tWB_max = 100000,
- .tWC_min = 25000,
- .tWH_min = 10000,
- .tWHR_min = 80000,
- .tWP_min = 12000,
- .tWW_min = 100000,
+ .type = NAND_SDR_IFACE,
+ .timings.sdr = {
+ .tADL_min = 70000,
+ .tALH_min = 5000,
+ .tALS_min = 10000,
+ .tAR_min = 10000,
+ .tCEA_max = 25000,
+ .tCEH_min = 20000,
+ .tCH_min = 5000,
+ .tCHZ_max = 30000,
+ .tCLH_min = 5000,
+ .tCLR_min = 10000,
+ .tCLS_min = 10000,
+ .tCOH_min = 15000,
+ .tCS_min = 20000,
+ .tDH_min = 5000,
+ .tDS_min = 10000,
+ .tFEAT_max = 1000000,
+ .tIR_min = 0,
+ .tITC_max = 1000000,
+ .tRC_min = 25000,
+ .tREA_max = 20000,
+ .tREH_min = 10000,
+ .tRHOH_min = 15000,
+ .tRHW_min = 100000,
+ .tRHZ_max = 100000,
+ .tRLOH_min = 5000,
+ .tRP_min = 12000,
+ .tRR_min = 20000,
+ .tRST_max = 500000000,
+ .tWB_max = 100000,
+ .tWC_min = 25000,
+ .tWH_min = 10000,
+ .tWHR_min = 80000,
+ .tWP_min = 12000,
+ .tWW_min = 100000,
+ },
},
/* Mode 5 */
{
- .tADL_min = 70000,
- .tALH_min = 5000,
- .tALS_min = 10000,
- .tAR_min = 10000,
- .tCEA_max = 25000,
- .tCEH_min = 20000,
- .tCH_min = 5000,
- .tCHZ_max = 30000,
- .tCLH_min = 5000,
- .tCLR_min = 10000,
- .tCLS_min = 10000,
- .tCOH_min = 15000,
- .tCS_min = 15000,
- .tDH_min = 5000,
- .tDS_min = 7000,
- .tFEAT_max = 1000000,
- .tIR_min = 0,
- .tITC_max = 1000000,
- .tRC_min = 20000,
- .tREA_max = 16000,
- .tREH_min = 7000,
- .tRHOH_min = 15000,
- .tRHW_min = 100000,
- .tRHZ_max = 100000,
- .tRLOH_min = 5000,
- .tRP_min = 10000,
- .tRR_min = 20000,
- .tRST_max = 500000000,
- .tWB_max = 100000,
- .tWC_min = 20000,
- .tWH_min = 7000,
- .tWHR_min = 80000,
- .tWP_min = 10000,
- .tWW_min = 100000,
+ .type = NAND_SDR_IFACE,
+ .timings.sdr = {
+ .tADL_min = 70000,
+ .tALH_min = 5000,
+ .tALS_min = 10000,
+ .tAR_min = 10000,
+ .tCEA_max = 25000,
+ .tCEH_min = 20000,
+ .tCH_min = 5000,
+ .tCHZ_max = 30000,
+ .tCLH_min = 5000,
+ .tCLR_min = 10000,
+ .tCLS_min = 10000,
+ .tCOH_min = 15000,
+ .tCS_min = 15000,
+ .tDH_min = 5000,
+ .tDS_min = 7000,
+ .tFEAT_max = 1000000,
+ .tIR_min = 0,
+ .tITC_max = 1000000,
+ .tRC_min = 20000,
+ .tREA_max = 16000,
+ .tREH_min = 7000,
+ .tRHOH_min = 15000,
+ .tRHW_min = 100000,
+ .tRHZ_max = 100000,
+ .tRLOH_min = 5000,
+ .tRP_min = 10000,
+ .tRR_min = 20000,
+ .tRST_max = 500000000,
+ .tWB_max = 100000,
+ .tWC_min = 20000,
+ .tWH_min = 7000,
+ .tWHR_min = 80000,
+ .tWP_min = 10000,
+ .tWW_min = 100000,
+ },
},
};
@@ -248,6 +266,6 @@ const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode)
if (mode < 0 || mode >= ARRAY_SIZE(onfi_sdr_timings))
return ERR_PTR(-EINVAL);
- return &onfi_sdr_timings[mode];
+ return &onfi_sdr_timings[mode].timings.sdr;
}
EXPORT_SYMBOL(onfi_async_timing_mode_to_sdr_timings);
--
2.8.1
^ permalink raw reply related
* [PATCH 2/9] mtd: nand: Introduce nand_data_interface
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473928373-8680-1-git-send-email-s.hauer@pengutronix.de>
Currently we have no data structure to fully describe a NAND timing.
We only have struct nand_sdr_timings for NAND timings in SDR mode,
but nothing for DDR mode and also no container to store both types
of timing.
This patch adds struct nand_data_interface which stores the timing
type and a union of different timings. This can be used to pass to
drivers in order to configure the timing.
Add kerneldoc for struct nand_sdr_timings while touching it anyway.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
include/linux/mtd/nand.h | 165 +++++++++++++++++++++++++++++++++--------------
1 file changed, 116 insertions(+), 49 deletions(-)
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9890df2..f305bed 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -566,6 +566,122 @@ struct nand_buffers {
};
/**
+ * struct nand_sdr_timings - SDR NAND chip timings
+ *
+ * This struct defines the timing requirements of a SDR NAND chip.
+ * These information can be found in every NAND datasheets and the timings
+ * meaning are described in the ONFI specifications:
+ * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
+ * Parameters)
+ *
+ * All these timings are expressed in picoseconds.
+ *
+ * @tALH_min: ALE hold time
+ * @tADL_min: ALE to data loading time
+ * @tALS_min: ALE setup time
+ * @tAR_min: ALE to RE# delay
+ * @tCEA_max: CE# access time
+ * @tCEH_min:
+ * @tCH_min: CE# hold time
+ * @tCHZ_max: CE# high to output hi-Z
+ * @tCLH_min: CLE hold time
+ * @tCLR_min: CLE to RE# delay
+ * @tCLS_min: CLE setup time
+ * @tCOH_min: CE# high to output hold
+ * @tCS_min: CE# setup time
+ * @tDH_min: Data hold time
+ * @tDS_min: Data setup time
+ * @tFEAT_max: Busy time for Set Features and Get Features
+ * @tIR_min: Output hi-Z to RE# low
+ * @tITC_max: Interface and Timing Mode Change time
+ * @tRC_min: RE# cycle time
+ * @tREA_max: RE# access time
+ * @tREH_min: RE# high hold time
+ * @tRHOH_min: RE# high to output hold
+ * @tRHW_min: RE# high to WE# low
+ * @tRHZ_max: RE# high to output hi-Z
+ * @tRLOH_min: RE# low to output hold
+ * @tRP_min: RE# pulse width
+ * @tRR_min: Ready to RE# low (data only)
+ * @tRST_max: Device reset time, measured from the falling edge of R/B# to the rising edge of R/B#.
+ * @tWB_max: WE# high to SR[6] low
+ * @tWC_min: WE# cycle time
+ * @tWH_min: WE# high hold time
+ * @tWHR_min: WE# high to RE# low
+ * @tWP_min: WE# pulse width
+ * @tWW_min: WP# transition to WE# low
+ */
+struct nand_sdr_timings {
+ u32 tALH_min;
+ u32 tADL_min;
+ u32 tALS_min;
+ u32 tAR_min;
+ u32 tCEA_max;
+ u32 tCEH_min;
+ u32 tCH_min;
+ u32 tCHZ_max;
+ u32 tCLH_min;
+ u32 tCLR_min;
+ u32 tCLS_min;
+ u32 tCOH_min;
+ u32 tCS_min;
+ u32 tDH_min;
+ u32 tDS_min;
+ u32 tFEAT_max;
+ u32 tIR_min;
+ u32 tITC_max;
+ u32 tRC_min;
+ u32 tREA_max;
+ u32 tREH_min;
+ u32 tRHOH_min;
+ u32 tRHW_min;
+ u32 tRHZ_max;
+ u32 tRLOH_min;
+ u32 tRP_min;
+ u32 tRR_min;
+ u64 tRST_max;
+ u32 tWB_max;
+ u32 tWC_min;
+ u32 tWH_min;
+ u32 tWHR_min;
+ u32 tWP_min;
+ u32 tWW_min;
+};
+
+/**
+ * enum nand_data_interface_type - NAND interface timing type
+ * @NAND_SDR_IFACE: Single Data Rate interface
+ */
+enum nand_data_interface_type {
+ NAND_SDR_IFACE,
+};
+
+/**
+ * struct nand_data_interface - NAND interface timing
+ * @type: type of the timing
+ * @timings: The timing, type according to @type
+ */
+struct nand_data_interface {
+ enum nand_data_interface_type type;
+ union {
+ struct nand_sdr_timings sdr;
+ } timings;
+};
+
+/**
+ * nand_get_sdr_timings - get SDR timing from data interface
+ * @conf: The data interface
+ */
+static inline const struct nand_sdr_timings *
+nand_get_sdr_timings(const struct nand_data_interface *conf)
+{
+ if (conf->type != NAND_SDR_IFACE)
+ return ERR_PTR(-EINVAL);
+
+ return &conf->timings.sdr;
+}
+
+/**
* struct nand_chip - NAND Private Flash Chip Data
* @mtd: MTD device registered to the MTD framework
* @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
@@ -1023,55 +1139,6 @@ static inline int jedec_feature(struct nand_chip *chip)
: 0;
}
-/*
- * struct nand_sdr_timings - SDR NAND chip timings
- *
- * This struct defines the timing requirements of a SDR NAND chip.
- * These informations can be found in every NAND datasheets and the timings
- * meaning are described in the ONFI specifications:
- * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
- * Parameters)
- *
- * All these timings are expressed in picoseconds.
- */
-
-struct nand_sdr_timings {
- u32 tALH_min;
- u32 tADL_min;
- u32 tALS_min;
- u32 tAR_min;
- u32 tCEA_max;
- u32 tCEH_min;
- u32 tCH_min;
- u32 tCHZ_max;
- u32 tCLH_min;
- u32 tCLR_min;
- u32 tCLS_min;
- u32 tCOH_min;
- u32 tCS_min;
- u32 tDH_min;
- u32 tDS_min;
- u32 tFEAT_max;
- u32 tIR_min;
- u32 tITC_max;
- u32 tRC_min;
- u32 tREA_max;
- u32 tREH_min;
- u32 tRHOH_min;
- u32 tRHW_min;
- u32 tRHZ_max;
- u32 tRLOH_min;
- u32 tRP_min;
- u32 tRR_min;
- u64 tRST_max;
- u32 tWB_max;
- u32 tWC_min;
- u32 tWH_min;
- u32 tWHR_min;
- u32 tWP_min;
- u32 tWW_min;
-};
-
/* get timing characteristics from ONFI timing mode. */
const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
--
2.8.1
^ permalink raw reply related
* [PATCH 1/9] mtd: nand: Create a NAND reset function
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473928373-8680-1-git-send-email-s.hauer@pengutronix.de>
When NAND devices are resetted some initialization may have to be done,
like for example they have to be configured for the timing mode that
shall be used. To get a common place where this initialization can be
implemented create a nand_reset() function. This currently only issues
a NAND_CMD_RESET to the NAND device. The places issuing this command
manually are replaced with a call to nand_reset().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_base.c | 23 ++++++++++++++++++-----
include/linux/mtd/nand.h | 4 ++++
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 77533f7..1f704cc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -948,6 +948,19 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
}
/**
+ * nand_reset - Reset and initialize a NAND device
+ * @chip: The NAND chip
+ *
+ * Returns 0 for success or negative error code otherwise
+ */
+int nand_reset(struct nand_chip *chip)
+{
+ chip->cmdfunc(&chip->mtd, NAND_CMD_RESET, -1, -1);
+
+ return 0;
+}
+
+/**
* __nand_unlock - [REPLACEABLE] unlocks specified locked blocks
* @mtd: mtd info
* @ofs: offset to start unlock from
@@ -1025,7 +1038,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
* some operation can also clear the bit 7 of status register
* eg. erase/program a locked block
*/
- chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+ nand_reset(chip);
/* Check, if it is write protected */
if (nand_check_wp(mtd)) {
@@ -1084,7 +1097,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
* some operation can also clear the bit 7 of status register
* eg. erase/program a locked block
*/
- chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+ nand_reset(chip);
/* Check, if it is write protected */
if (nand_check_wp(mtd)) {
@@ -2788,7 +2801,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
* if we don't do this. I have no clue why, but I seem to have 'fixed'
* it in the doc2000 driver in August 1999. dwmw2.
*/
- chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+ nand_reset(chip);
/* Check, if it is write protected */
if (nand_check_wp(mtd)) {
@@ -3829,7 +3842,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
* Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
* after power-up.
*/
- chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+ nand_reset(chip);
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
@@ -4161,7 +4174,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
for (i = 1; i < maxchips; i++) {
chip->select_chip(mtd, i);
/* See comment in nand_get_flash_type for reset */
- chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+ nand_reset(chip);
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
/* Read manufacturer and device IDs */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 8dd6e01..9890df2 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -1093,4 +1093,8 @@ int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page);
/* Default read_oob syndrome implementation */
int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
int page);
+
+/* Reset and initialize a NAND device */
+int nand_reset(struct nand_chip *chip);
+
#endif /* __LINUX_MTD_NAND_H */
--
2.8.1
^ permalink raw reply related
* [PATCH v4] mtd: nand: automate NAND timings selection
From: Sascha Hauer @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
This series aims at automating the NAND timings selection which is
currently supposed to be done in each NAND controller driver, thus
simplifying drivers implementation.
As suggested by Boris this version of the series introduces a nand_reset()
function which replaces the several open coded NAND_CMD_RESET commands
in the code. This makes sure we can apply the timing each time after
after reset.
Also I have brought back the conversion patch for teh sunxi driver whic
was part of Boris initial posting. It's untested due to the lack of hardware,
so please test before applying.
Sascha
Changes since v4:
- Change onfi_init_data_interface() prototype to be more future proof as
requested by Boris
Changes since v3:
- Bring back patch dropped in v3
- Use statically allocated default timing for all chips and store one
optimized timing in struct nand_chip
Changes since v2:
- Add accessor function to get the SDR timing from struct nand_data_interface
- Change nand_reset() argument to struct nand_chip
- Drop conversion of nand_timing array to struct nand_data_interface
- Recalculate timing whenever needed instead of storing a pointer in struct
nand_chip
- some more refactoring
Changes since v1:
- create a nand_reset() function to create a single place to reset NAND
chips and to apply timings
- Add patch to convert sunxi driver for automated timing setup
- split into more patches
Changes since the initial posting from Boris:
- Integrate Feedback from Ezequiel Garcia
- When iterating over the chips calling onfi_set_features() for each
bail out when any of the calls fail, not only the last one.
- When one of the onfi_set_features() calls fail then reset the chipi
afterwards.
- Drop Sunxi example, add patch for the mxc_nand controller instead.
----------------------------------------------------------------
Boris Brezillon (1):
mtd: nand: automate NAND timings selection
Sascha Hauer (8):
mtd: nand: Create a NAND reset function
mtd: nand: Introduce nand_data_interface
mtd: nand: convert ONFI mode into data interface
mtd: nand: Add function to convert ONFI mode to data_interface
mtd: nand: Expose data interface for ONFI mode 0
mtd: nand: sunxi: switch from manual to automated timing config
mtd: nand: mxc: implement onfi get/set features
mtd: nand: mxc: Add timing setup for v2 controllers
drivers/mtd/nand/mxc_nand.c | 133 ++++++++++++
drivers/mtd/nand/nand_base.c | 179 ++++++++++++++-
drivers/mtd/nand/nand_timings.c | 469 ++++++++++++++++++++++------------------
drivers/mtd/nand/sunxi_nand.c | 76 ++-----
include/linux/mtd/nand.h | 190 +++++++++++-----
5 files changed, 721 insertions(+), 326 deletions(-)
^ permalink raw reply
* [PATCH 1/5] clk: add support for runtime pm
From: Marek Szyprowski @ 2016-09-15 8:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160914213903.GG7243@codeaurora.org>
Hi Stephen,
On 2016-09-14 23:39, Stephen Boyd wrote:
> On 09/13, Marek Szyprowski wrote:
>> On 2016-09-13 00:31, Stephen Boyd wrote:
>>> Great! So you have runtime PM callbacks that are calling
>>> clk_prepare/unprepare?
>> Well, not really. clock controller's runtime pm functions must not call
>> clk_prepare/unprepare yet.
>>
>> I didn't get your question. I thought that you are asking if my change
>> won't introduce any deadlock related to prepare and dev->pm locks. My
>> runtime pm functions doesn't do any call to clk_prepare/unprepare.
>> Although global clock prepare lock is re-entrant from the same process, it
>> would cause deadlock if called from runtime pm functions, because runtime
>> pm functions might be called from the worker running on the different
>> cpu/process.
> I mean non-clk controller driver based runtime PM callbacks that
> call clk_prepare/unprepare in them. For example, some i2c or spi
> device driver that has clk operations in the runtime PM
> callbacks. That would allow lockdep to see any potential deadlock
> because of aliasing lock classes for the device power lock and
> the global prepare lock.
This works perfectly fine. Runtime pm callbacks are called with power lock
released, so there is no deadlock possible related to dev->power.lock.
See __rpm_callback() function in drivers/base/power/runtime.c
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply
* [PATCH V3 2/4] ARM64 LPC: LPC driver implementation on Hip06
From: Arnd Bergmann @ 2016-09-15 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E1F871B01@lhreml507-mbx>
On Thursday, September 15, 2016 8:02:27 AM CEST Gabriele Paoloni wrote:
>
> From <<3.1.1. Open Firmware Properties for Bus Nodes>> in
> http://www.firmware.org/1275/bindings/isa/isa0_4d.ps
>
> I quote:
> "There shall be an entry in the "ranges" property for each
> of the Memory and/or I/O spaces if that address space is
> mapped through the bridge."
>
> It seems to me that it is ok to have 1:1 address mapping and that
> therefore of_translate_address() should fail if "ranges" is not
> present.
The key here is the definition of "mapped through the bridge".
I can only understand this as "directly mapped", i.e. an I/O
port of the child bus corresponds directly to a memory address
on the parent bus, but this is not the case here.
The problem with adding the mapping here is that it looks
like it should be valid to create a page table entry for
the address returned from the translation and access it through
a pointer dereference, but that is clearly not possible.
> This is also explained quite well in
> http://lxr.free-electrons.com/source/drivers/of/address.c#L490
>
> what do you think?
This is a separate issue, and only relevant for Apple Macintosh
machines as well as the PA-Semi sdc.
Arnd
^ permalink raw reply
* [PATCH v26 2/7] arm64: kdump: implement machine_crash_shutdown()
From: Marc Zyngier @ 2016-09-15 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <57D9925D.5000508@arm.com>
Hi James,
Thanks for cc-ing me.
On 14/09/16 19:09, James Morse wrote:
> Hi Akashi,
>
> (CC: Marc who knows how this irqchip wizardry works
> Cover letter: https://www.spinics.net/lists/arm-kernel/msg529520.html )
>
> On 07/09/16 05:29, AKASHI Takahiro wrote:
>> Primary kernel calls machine_crash_shutdown() to shut down non-boot cpus
>> and save registers' status in per-cpu ELF notes before starting crash
>> dump kernel. See kernel_kexec().
>> Even if not all secondary cpus have shut down, we do kdump anyway.
>>
>> As we don't have to make non-boot(crashed) cpus offline (to preserve
>> correct status of cpus at crash dump) before shutting down, this patch
>> also adds a variant of smp_send_stop().
>>
>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
>> ---
>> arch/arm64/include/asm/hardirq.h | 2 +-
>> arch/arm64/include/asm/kexec.h | 41 ++++++++++++++++++++++++-
>> arch/arm64/include/asm/smp.h | 2 ++
>> arch/arm64/kernel/machine_kexec.c | 56 ++++++++++++++++++++++++++++++++--
>> arch/arm64/kernel/smp.c | 63 +++++++++++++++++++++++++++++++++++++++
>> 5 files changed, 159 insertions(+), 5 deletions(-)
[...]
>> +static void machine_kexec_mask_interrupts(void)
>> +{
>> + unsigned int i;
>> + struct irq_desc *desc;
>> +
>> + for_each_irq_desc(i, desc) {
>> + struct irq_chip *chip;
>> + int ret;
>> +
>> + chip = irq_desc_get_chip(desc);
>> + if (!chip)
>> + continue;
>> +
>> + /*
>> + * First try to remove the active state. If this
>> + * fails, try to EOI the interrupt.
>> + */
>> + ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
>> +
>> + if (ret && irqd_irq_inprogress(&desc->irq_data) &&
>> + chip->irq_eoi)
>> + chip->irq_eoi(&desc->irq_data);
>> +
>> + if (chip->irq_mask)
>> + chip->irq_mask(&desc->irq_data);
>> +
>> + if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
>> + chip->irq_disable(&desc->irq_data);
>> + }
>> +}
>
> This function is over my head ... I have no idea how this works, I can only
> comment that its different to the version under arch/arm
>
> /me adds Marc Z to CC.
I wrote the damn code! ;-)
The main idea is that simply EOIing an interrupt is not good enough if
the interrupt has been offloaded to a VM. It needs to be actively
deactivated for the state machine to be reset.
But realistically, even that is not enough. What we need is a way to
completely shut off the GIC, irrespective of the state of the various
interrupts. A "panic button" of some sort, with no return.
That would probably work for GICv3 (assuming that we don't need to
involve the secure side of things), but anything GICv2 based would be
difficult to deal with (you cannot access the other CPU private
interrupt configuration). Maybe that'd be enough, maybe not. Trying to
boot a crash kernel is like buying a lottery ticket anyway (and with
similar odds...).
I'll have a look.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH V3 2/4] ARM64 LPC: LPC driver implementation on Hip06
From: Gabriele Paoloni @ 2016-09-15 8:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5869118.UilSPY9Sai@wuerfel>
Hi Arnd
> -----Original Message-----
> From: Arnd Bergmann [mailto:arnd at arndb.de]
> Sent: 14 September 2016 22:32
> To: linux-arm-kernel at lists.infradead.org
> Cc: Yuanzhichang; devicetree at vger.kernel.org;
> lorenzo.pieralisi at arm.com; Gabriele Paoloni; minyard at acm.org;
> gregkh at linuxfoundation.org; benh at kernel.crashing.org; John Garry;
> will.deacon at arm.com; linux-kernel at vger.kernel.org; xuwei (O); Linuxarm;
> linux-serial at vger.kernel.org; linux-pci at vger.kernel.org;
> zourongrong at gmail.com; liviu.dudau at arm.com; kantyzc at 163.com;
> zhichang.yuan02 at gmail.com
> Subject: Re: [PATCH V3 2/4] ARM64 LPC: LPC driver implementation on
> Hip06
>
> On Wednesday, September 14, 2016 10:50:44 PM CEST zhichang.yuan wrote:
> >
> > On 2016/9/14 20:33, Arnd Bergmann wrote:
> > > On Wednesday, September 14, 2016 8:15:52 PM CEST Zhichang Yuan
> wrote:
> > >
> > >> +Required properties:
> > >> +- compatible: should be "hisilicon,low-pin-count"
> > >> +- #address-cells: must be 2 which stick to the ISA/EISA binding
> doc.
> > >> +- #size-cells: must be 1 which stick to the ISA/EISA binding doc.
> > >> +- reg: base address and length of the register set for the
> device.
> > >> +- ranges: define a 1:1 mapping between the I/O space of the child
> device and
> > >> + the parent.
> > >
> > > Do we still need the "ranges" here? The property in your example
> seems
> > > wrong.
> >
> > I think "ranges" is needed.
> > without this, of_translate_address --> __of_translate_address -->
> of_translate_one will fail when translating the child's IO resource.
> >
> > >
> > >> + ranges = <0x01 0xe4 0x0 0xe4 0x1000>;
> > >
> > > You translate I/O port 0x00e4 through 0x10e4 to CPU address 0x0e4?
> > The hip06 LPC is defined as isa type.
> > So, 0x01 0xe4 is the local IO address of 0xe4. With this ranges, 0xe4
> of child will be 1:1 mapped as 0xe4.
> > It means no translation.
>
> No, "no translation" would be leaving out the ranges, we should
> fix the code so it handles this case according to the specification
> of the ISA DT binding, rather than adding an incorrect ranges
> property to make it work with the incorrect Linux implementation.
>
> of_translate_address() should fail here, and whichever code calls
> it should try something else, possibly something we have to
> implement that can return the correct IORESOURCE_* type.
>From <<3.1.1. Open Firmware Properties for Bus Nodes>> in
http://www.firmware.org/1275/bindings/isa/isa0_4d.ps
I quote:
"There shall be an entry in the "ranges" property for each
of the Memory and/or I/O spaces if that address space is
mapped through the bridge."
It seems to me that it is ok to have 1:1 address mapping and that
therefore of_translate_address() should fail if "ranges" is not
present.
This is also explained quite well in
http://lxr.free-electrons.com/source/drivers/of/address.c#L490
what do you think?
Thanks
Gab
>
> > >
> > > I don't get this part. The bus driver should not care what its
> > > children are, just register and PIO ranges that the bus can handle
> > > in theory, i.e. from 0x000 to 0xfff.
> >
> > Just as we discussed in V2, the legacy PIO range is specific to some
> > device, such as for ipmi bt, 0xe4 - 0xe7 will be populated.
> > I don't want to occupy a larger PIO range in which only small part
> PIOs
> > are used by our LPC. At this moment, two PIO ranges are using
> > through the device property configuration, 0xe4-0xe7, 0x2f8-0x2ff.
> >
> > If we configure 0-0x1000 for the LPC to cover those two ranges, most
> > PIO are wasted and other PIO device on other buses lose the chance to
> > use the PIO below 0x1000.
> > Otherwise, PIO conflict will happen. So, My idea is only occupied
> > the PIO ranges which are really needed for the children.
>
> The only thing it can realistically conflict with would be another
> LPC bus behind on a PCI host bridge. On ARM64, all regular PCI
> devices that have IORESOURCE_IO ports are intentionally moved
> to (bus) port numbers above 0x1000.
>
> > And there are probably multiple child devices under LPC, the global
> arm64_extio_ops only can cover one PIO range. It is fortunate only ipmi
> driver can not support I/O
> > operation registering, serial driver has serial_in/serial_out to
> > be registered. So, only the PIO range for ipmi device is stored
> > in arm64_extio_ops and the indirect-IO
> > works well for ipmi device.
>
> You should not do that in the serial driver, please just use the
> normal 8250 driver that works fine once you handle the entire
> port range.
>
>
> Arnd
^ permalink raw reply
* [GIT PULL] arm64: X-Gene platforms DTS changes queued for 4.9 - part1
From: Arnd Bergmann @ 2016-09-15 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160915072709.GA3380@arm.com>
On Thursday, September 15, 2016 8:30:30 AM CEST Will Deacon wrote:
> On Wed, Sep 14, 2016 at 06:57:59PM -0700, Duc Dang wrote:
> > On Wed, Sep 14, 2016 at 7:59 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> > > On Friday, September 2, 2016 11:46:31 AM CEST Duc Dang wrote:
> > > Please send this again as two pull requests, one for the dts changes, and
> > > one for the rest (pmu driver, binding and MAINTAINERS file). Please
> > > also include an explanation in the tag description about why this gets
> > > merged through arm-soc. I see that Will suggested doing it that way,
> > > but I don't see what the reason is. We normally don't touch that directory.
> > Hi Arnd,
> >
> > I am not clear about the reason either. Probably we don't have a
> > dedicated tree for SoC PMU?
>
> That's right, there isn't a dedicated tree for SoC PMUs. I tend to handle
> the architected PMUs (e.g. the ones in the CPUs), but other PMUs have
> been ad-hoc in the past. That said, Mark and I do tend to review PMU
> drivers, because the internal perf interface is pretty easy to get wrong.
>
> Arnd -- what would you like to see here? I could collect SoC PMU patches
> together and send you a pull request, or would you like me to take them via
> the arm64 tree? It's worth noting that we have PMU drivers under drivers/bus
> and drivers/hwtracing too, and I *think* arm-soc has handled those in the
> past.
I (and I suspect the same of Olof) don't understand enough about PMU drivers
to be a good gatekeeper for PMU drivers, so I've had to rely on platform
maintainers to know what they are doing when they sent me a driver in
the past. I had not realized that we already have those drivers in multiple
places, and that seems reason enough to get a maintainer for them who
can review and apply the patches, as well as possibly consolidate them
in once place.
I don't mind forwarding the drivers to Linus in the next/drivers branch
of arm-soc, like we do for drivers/reset which also has its own maintainer
who picks up the patches to forward them to us.
It would certainly help us if you can collect the changes and forward them,
thanks a lot for the offer! Since I know you have a lot on your plate
already, how about finding another co-maintainer who doesn't already
own a subsystem but understands PMUs and could use some on-the-job
training for this?
For v4.9, I'd just take the pull request once Duc resends separate
branches, and then we start a more formal procedure for v4.10 (or
late if there are no PMU patches during that time).
Arnd
^ permalink raw reply
* [RESEND PATCH] arm64: kgdb: fix single stepping
From: AKASHI Takahiro @ 2016-09-15 7:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160914145850.GE19622@arm.com>
On Wed, Sep 14, 2016 at 03:58:51PM +0100, Will Deacon wrote:
> Hi Akashi,
>
> On Tue, Apr 21, 2015 at 02:13:13AM +0100, AKASHI Takahiro wrote:
> > Could you please review my patch below?
> > See also arm64 maintainer's comment:
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/313712.html
>
> -ETIMEDOUT waiting for the kdgb folk to comment. Ppeople have reported
> that this patch is required for kgdb to work correctly on arm64, so I'm
> happy to merge it.
I'm happy, too.
> However, as detailed in your comment log:
>
> > This patch
> > (1) moves kgdb_disable_single_step() from 'c' command handling to single
> > step handler.
> > This makes sure that single stepping gets effective at every 's' command.
> > Please note that, under the current implementation, single step bit in
> > spsr, which is cleared by the first single stepping, will not be set
> > again for the consecutive 's' commands because single step bit in mdscr
> > is still kept on (that is, kernel_active_single_step() in
> > kgdb_arch_handle_exception() is true).
> > (2) re-implements kgdb_roundup_cpus() because the current implementation
> > enabled interrupts naively. See below.
> > (3) removes 'enable_dbg' in el1_dbg.
> > Single step bit in mdscr is turned on in do_handle_exception()->
> > kgdb_handle_expection() before returning to debugged context, and if
> > debug exception is enabled in el1_dbg, we will see unexpected single-
> > stepping in el1_dbg.
> > Since v3.18, the following patch does the same:
> > commit 1059c6bf8534 ("arm64: debug: don't re-enable debug exceptions
> > on return from el1_dbg)
> > (4) masks interrupts while single-stepping one instruction.
> > If an interrupt is caught during processing a single-stepping, debug
> > exception is unintentionally enabled by el1_irq's 'enable_dbg' before
> > returning to debugged context.
> > Thus, like in (2), we will see unexpected single-stepping in el1_irq.
>
> this patch is doing *far* too much in one go. Could you please repost it
> as a series of self-contained fixes with clear commit messages, so I can
> queue them and cc stable where appropriate?
Sure, but I need to refresh my memory here.
-Takahiro AKASHI
> Thanks,
>
> Will
^ permalink raw reply
* [GIT PULL] arm64: X-Gene platforms DTS changes queued for 4.9 - part1
From: Olof Johansson @ 2016-09-15 7:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160915072709.GA3380@arm.com>
On Thu, Sep 15, 2016 at 12:30 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, Sep 14, 2016 at 06:57:59PM -0700, Duc Dang wrote:
>> On Wed, Sep 14, 2016 at 7:59 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>> > On Friday, September 2, 2016 11:46:31 AM CEST Duc Dang wrote:
>> >> Hi Arnd, Olof,
>> >>
>> >> This is the first part of DTS changes for X-Gene platforms targeted for 4.9.
>> >>
>> >> The changes include:
>> >> + X-Gene Soc PMU support patch set from Tai Nguyen (v10 reviewed by
>> >> Mark, DT binding document acked by Rob [1] and was suggested to merge
>> >> via am-soc tree by Will [2])
>> >> + Follow up patch to enable DT entry for SoC PMU on X-Gene v2
>> >> + Correct PCIe legacy interrupt mode to level-active high
>> >> + DTS entry for X-Gene hwmon (v4 acked by Guenter, DT binding document
>> >> and driver is in linux-next now [3])
>> >>
>> >> Regards,
>> >> Duc Dang.
>> >
>> > Sorry for the long delay, I've just now started looking at the dts changes
>> > for arm64. The changes to arch/arm64/boot/dts look fine, but I don't
>> > want to mix driver changes with dts changes, as we use separate
>> > branches for those.
>> >
>> > Please send this again as two pull requests, one for the dts changes, and
>> > one for the rest (pmu driver, binding and MAINTAINERS file). Please
>> > also include an explanation in the tag description about why this gets
>> > merged through arm-soc. I see that Will suggested doing it that way,
>> > but I don't see what the reason is. We normally don't touch that directory.
>> Hi Arnd,
>>
>> I am not clear about the reason either. Probably we don't have a
>> dedicated tree for SoC PMU?
>
> That's right, there isn't a dedicated tree for SoC PMUs. I tend to handle
> the architected PMUs (e.g. the ones in the CPUs), but other PMUs have
> been ad-hoc in the past. That said, Mark and I do tend to review PMU
> drivers, because the internal perf interface is pretty easy to get wrong.
>
> Arnd -- what would you like to see here? I could collect SoC PMU patches
> together and send you a pull request, or would you like me to take them via
> the arm64 tree? It's worth noting that we have PMU drivers under drivers/bus
> and drivers/hwtracing too, and I *think* arm-soc has handled those in the
> past.
We're fine taking the code, we just don't want the driver changes in
the same branch as the DTS changes.
-Olof
^ permalink raw reply
* [PATCH v3 14/14] ARM: DT: STi: STiH410: clock configuration to address 720p and 1080p
From: Patrice Chotard @ 2016-09-15 7:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-15-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:27 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> It is necessary to properly configure these clocks in order
> to address 720p and 1080p HDMI resolution.
>
> Signed-off-by: Vincent Abriou <vincent.abriou@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih410.dtsi | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
> index 18ed1ad..7eec729 100644
> --- a/arch/arm/boot/dts/stih410.dtsi
> +++ b/arch/arm/boot/dts/stih410.dtsi
> @@ -103,7 +103,10 @@
> #size-cells = <1>;
>
> assigned-clocks = <&clk_s_d2_quadfs 0>,
> - <&clk_s_d2_quadfs 0>,
> + <&clk_s_d2_quadfs 1>,
> + <&clk_s_c0_pll1 0>,
> + <&clk_s_c0_flexgen CLK_COMPO_DVP>,
> + <&clk_s_c0_flexgen CLK_MAIN_DISP>,
> <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
> <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
> <&clk_s_d2_flexgen CLK_PIX_GDP1>,
> @@ -113,14 +116,21 @@
>
> assigned-clock-parents = <0>,
> <0>,
> + <0>,
> + <&clk_s_c0_pll1 0>,
> + <&clk_s_c0_pll1 0>,
> <&clk_s_d2_quadfs 0>,
> - <&clk_s_d2_quadfs 0>,
> + <&clk_s_d2_quadfs 1>,
> <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 0>;
>
> - assigned-clock-rates = <297000000>, <297000000>;
> + assigned-clock-rates = <297000000>,
> + <108000000>,
> + <0>,
> + <400000000>,
> + <400000000>;
>
> ranges;
>
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 13/14] ARM: DT: STi: STiH407: clock configuration to address 720p and 1080p
From: Patrice Chotard @ 2016-09-15 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-14-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:27 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> It is necessary to properly configure these clocks in order
> to address 720p and 1080p HDMI resolution.
>
> Signed-off-by: Vincent Abriou <vincent.abriou@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih407.dtsi | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/boot/dts/stih407.dtsi b/arch/arm/boot/dts/stih407.dtsi
> index d60f0d8..291ffac 100644
> --- a/arch/arm/boot/dts/stih407.dtsi
> +++ b/arch/arm/boot/dts/stih407.dtsi
> @@ -16,7 +16,10 @@
> #size-cells = <1>;
>
> assigned-clocks = <&clk_s_d2_quadfs 0>,
> - <&clk_s_d2_quadfs 0>,
> + <&clk_s_d2_quadfs 1>,
> + <&clk_s_c0_pll1 0>,
> + <&clk_s_c0_flexgen CLK_COMPO_DVP>,
> + <&clk_s_c0_flexgen CLK_MAIN_DISP>,
> <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
> <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
> <&clk_s_d2_flexgen CLK_PIX_GDP1>,
> @@ -26,14 +29,21 @@
>
> assigned-clock-parents = <0>,
> <0>,
> + <0>,
> + <&clk_s_c0_pll1 0>,
> + <&clk_s_c0_pll1 0>,
> <&clk_s_d2_quadfs 0>,
> - <&clk_s_d2_quadfs 0>,
> + <&clk_s_d2_quadfs 1>,
> <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 0>;
>
> - assigned-clock-rates = <297000000>, <297000000>;
> + assigned-clock-rates = <297000000>,
> + <108000000>,
> + <0>,
> + <400000000>,
> + <400000000>;
>
> ranges;
>
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 12/14] ARM: DT: STiH418: Enable synchronous clock mode for video clocks
From: Patrice Chotard @ 2016-09-15 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-13-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:27 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch enables the synchronous clock mode for video clocks
> on STiH418 board.
>
> Signed-off-by: Olivier Bideau <olivier.bideau@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih418-clock.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
> index a183583..ee6614b7 100644
> --- a/arch/arm/boot/dts/stih418-clock.dtsi
> +++ b/arch/arm/boot/dts/stih418-clock.dtsi
> @@ -271,7 +271,7 @@
>
> clk_s_d2_flexgen: clk-s-d2-flexgen {
> #clock-cells = <1>;
> - compatible = "st,flexgen";
> + compatible = "st,flexgen-video", "st,flexgen";
>
> clocks = <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 1>,
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 11/14] ARM: DT: STiH410: Enable synchronous clock mode for video clocks
From: Patrice Chotard @ 2016-09-15 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-12-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:27 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch enables the synchronous clock mode for video clocks
> on STiH410 board.
>
> Signed-off-by: Olivier Bideau <olivier.bideau@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih410-clock.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
> index aec2aa7..8598eff 100644
> --- a/arch/arm/boot/dts/stih410-clock.dtsi
> +++ b/arch/arm/boot/dts/stih410-clock.dtsi
> @@ -277,7 +277,7 @@
>
> clk_s_d2_flexgen: clk-s-d2-flexgen {
> #clock-cells = <1>;
> - compatible = "st,flexgen";
> + compatible = "st,flexgen-video", "st,flexgen";
>
> clocks = <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 1>,
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 10/14] ARM: DT: STiH407: Enable synchronous clock mode for video clocks
From: Patrice Chotard @ 2016-09-15 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-11-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:27 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch enables the synchronous clock mode for video clocks
> on STiH407 board.
>
> Signed-off-by: Olivier Bideau <olivier.bideau@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih407-clock.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
> index c4a8f1c..13029c0 100644
> --- a/arch/arm/boot/dts/stih407-clock.dtsi
> +++ b/arch/arm/boot/dts/stih407-clock.dtsi
> @@ -256,7 +256,7 @@
>
> clk_s_d2_flexgen: clk-s-d2-flexgen {
> #clock-cells = <1>;
> - compatible = "st,flexgen";
> + compatible = "st,flexgen-video", "st,flexgen";
>
> clocks = <&clk_s_d2_quadfs 0>,
> <&clk_s_d2_quadfs 1>,
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 09/14] ARM: DT: STiH418: Enable clock propagation for audio clocks
From: Patrice Chotard @ 2016-09-15 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-10-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:27 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch is used in the clock driver to apply a clock propagation
> flag on the audio clocks of STiH418
>
> Signed-off-by: Olivier Bideau <olivier.bideau@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih418-clock.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
> index 0fd0fa5..a183583 100644
> --- a/arch/arm/boot/dts/stih418-clock.dtsi
> +++ b/arch/arm/boot/dts/stih418-clock.dtsi
> @@ -229,7 +229,7 @@
>
> clk_s_d0_flexgen: clk-s-d0-flexgen {
> #clock-cells = <1>;
> - compatible = "st,flexgen";
> + compatible = "st,flexgen-audio", "st,flexgen";
>
> clocks = <&clk_s_d0_quadfs 0>,
> <&clk_s_d0_quadfs 1>,
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 08/14] ARM: DT: STiH410: Enable clock propagation for audio clocks
From: Patrice Chotard @ 2016-09-15 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-9-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:27 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch is used in the clock driver to apply a clock propagation
> flag on the audio clocks of STiH410
>
> Signed-off-by: Olivier Bideau <olivier.bideau@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih410-clock.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
> index e8f4d44..aec2aa7 100644
> --- a/arch/arm/boot/dts/stih410-clock.dtsi
> +++ b/arch/arm/boot/dts/stih410-clock.dtsi
> @@ -235,7 +235,7 @@
>
> clk_s_d0_flexgen: clk-s-d0-flexgen {
> #clock-cells = <1>;
> - compatible = "st,flexgen";
> + compatible = "st,flexgen-audio", "st,flexgen";
>
> clocks = <&clk_s_d0_quadfs 0>,
> <&clk_s_d0_quadfs 1>,
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 00/14] Clock improvement for video playback
From: Gabriel Fernandez @ 2016-09-15 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160914183620.GV7243@codeaurora.org>
On 09/14/2016 08:36 PM, Stephen Boyd wrote:
> On 08/29, gabriel.fernandez at st.com wrote:
>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> v3:
>> - Rebase to v4.8-rc1
>> - Tipo fix in st,clkgen-pll.txt
>> - Add Ack of Peter for the series
>> - Add missed patch: "ARM: DT: STiH4xx: Simplify clock binding of STiH4xx platforms"
>>
>> v2:
>> - Simpliflication of clock binding
>> remark from Rob https://lkml.org/lkml/2016/5/25/492
>> - Suppression of stih415-416 support for the clocks (in order
>> to help simplification of clock binding)
>> (others patchs for the machine and drivers will come)
>>
>> This serie allows to increase video resolutions and make audio
>> adjustment during a video playback.
>>
>> Gabriel Fernandez (14):
>> drivers: clk: st: Remove stih415-416 clock support
>> drivers: clk: st: Simplify clock binding of STiH4xx platforms
>> ARM: DT: STiH4xx: Simplify clock binding of STiH4xx platforms
>> drivers: clk: st: Add fs660c32 synthesizer algorithm
>> drivers: clk: st: Add clock propagation for audio clocks
>> drivers: clk: st: Handle clk synchronous mode for video clocks
>> ARM: DT: STiH407: Enable clock propagation for audio clocks
>> ARM: DT: STiH410: Enable clock propagation for audio clocks
>> ARM: DT: STiH418: Enable clock propagation for audio clocks
>> ARM: DT: STiH407: Enable synchronous clock mode for video clocks
>> ARM: DT: STiH410: Enable synchronous clock mode for video clocks
>> ARM: DT: STiH418: Enable synchronous clock mode for video clocks
>> ARM: DT: STi: STiH407: clock configuration to address 720p and 1080p
>> ARM: DT: STi: STiH410: clock configuration to address 720p and 1080p
> The order of patches intermingles clk changes and dts changes.
> I'd prefer to not take any patches for dts through the clk tree,
> so can those be deferred to an arm-soc PR? Assuming that works,
> I'd just pick 1-2, and 4-6 into the clk tree and the rest can go
> on top through arm-soc.
Hi Stephen,
Many thanks !
BR
Gabriel
^ permalink raw reply
* [PATCH v3 07/14] ARM: DT: STiH407: Enable clock propagation for audio clocks
From: Patrice Chotard @ 2016-09-15 7:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-8-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:26 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch is used in the clock driver to apply a clock propagation
> flag on the audio clocks of STiH407
>
> Signed-off-by: Olivier Bideau <olivier.bideau@st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih407-clock.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
> index 38a56d7..c4a8f1c 100644
> --- a/arch/arm/boot/dts/stih407-clock.dtsi
> +++ b/arch/arm/boot/dts/stih407-clock.dtsi
> @@ -216,7 +216,7 @@
>
> clk_s_d0_flexgen: clk-s-d0-flexgen {
> #clock-cells = <1>;
> - compatible = "st,flexgen";
> + compatible = "st,flexgen-audio", "st,flexgen";
>
> clocks = <&clk_s_d0_quadfs 0>,
> <&clk_s_d0_quadfs 1>,
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
* [PATCH v3 03/14] ARM: DT: STiH4xx: Simplify clock binding of STiH4xx platforms
From: Patrice Chotard @ 2016-09-15 7:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472473626-15398-4-git-send-email-gabriel.fernandez@st.com>
On 08/29/2016 02:26 PM, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch simplifies the clock binding because we had too much detail.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
> arch/arm/boot/dts/stih407-clock.dtsi | 18 +++++++++---------
> arch/arm/boot/dts/stih410-clock.dtsi | 16 ++++++++--------
> arch/arm/boot/dts/stih418-clock.dtsi | 16 ++++++++--------
> 3 files changed, 25 insertions(+), 25 deletions(-)
>
> diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
> index ad45f5e..38a56d7 100644
> --- a/arch/arm/boot/dts/stih407-clock.dtsi
> +++ b/arch/arm/boot/dts/stih407-clock.dtsi
> @@ -42,7 +42,7 @@
[...]
> @@ -309,7 +309,7 @@
>
> clk_s_d3_quadfs: clk-s-d3-quadfs at 9107000 {
> #clock-cells = <1>;
> - compatible = "st,stih407-quadfs660-D", "st,quadfs";
> + compatible = "st,quadfs";
> reg = <0x9107000 0x1000>;
>
> clocks = <&clk_sysin>;
>
Hi Gabriel
Applied on STi tree for v4.9
Thanks
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox