All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: linux-mtd@lists.infradead.org, kernel@pengutronix.de,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 5/7] mtd: nand: sunxi: switch from manual to automated timing config
Date: Tue, 6 Sep 2016 14:01:24 +0200	[thread overview]
Message-ID: <20160906140124.6414c855@bbrezillon> (raw)
In-Reply-To: <1473158355-22451-6-git-send-email-s.hauer@pengutronix.de>

On Tue,  6 Sep 2016 12:39:13 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> 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 | 77 +++++++++----------------------------------
>  1 file changed, 15 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
> index e414b31..ee42b8c 100644
> --- a/drivers/mtd/nand/sunxi_nand.c
> +++ b/drivers/mtd/nand/sunxi_nand.c
> @@ -1572,14 +1572,23 @@ 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;
>  
> +	if (conf->type != NAND_SDR_IFACE)
> +		return -ENOTSUPP;
> +
> +	timings = &conf->timings.sdr;

Can we hide this behind an accessor (nand_get_sdr_timings())? I know I'm
picky, but I've had so many drivers to patch in the past because of
internal reorganization, and I'd like to avoid that in the future.

> +
>  	/* T1 <=> tCLS */
>  	if (timings->tCLS_min > min_clk_period)
>  		min_clk_period = timings->tCLS_min;
> @@ -1679,6 +1688,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 +1724,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 +1949,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 +2038,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 +2055,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);

WARNING: multiple messages have this Message-ID (diff)
From: boris.brezillon@free-electrons.com (Boris Brezillon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 5/7] mtd: nand: sunxi: switch from manual to automated timing config
Date: Tue, 6 Sep 2016 14:01:24 +0200	[thread overview]
Message-ID: <20160906140124.6414c855@bbrezillon> (raw)
In-Reply-To: <1473158355-22451-6-git-send-email-s.hauer@pengutronix.de>

On Tue,  6 Sep 2016 12:39:13 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> 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 | 77 +++++++++----------------------------------
>  1 file changed, 15 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
> index e414b31..ee42b8c 100644
> --- a/drivers/mtd/nand/sunxi_nand.c
> +++ b/drivers/mtd/nand/sunxi_nand.c
> @@ -1572,14 +1572,23 @@ 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;
>  
> +	if (conf->type != NAND_SDR_IFACE)
> +		return -ENOTSUPP;
> +
> +	timings = &conf->timings.sdr;

Can we hide this behind an accessor (nand_get_sdr_timings())? I know I'm
picky, but I've had so many drivers to patch in the past because of
internal reorganization, and I'd like to avoid that in the future.

> +
>  	/* T1 <=> tCLS */
>  	if (timings->tCLS_min > min_clk_period)
>  		min_clk_period = timings->tCLS_min;
> @@ -1679,6 +1688,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 +1724,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 +1949,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 +2038,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 +2055,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);

  reply	other threads:[~2016-09-06 12:01 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-06 10:39 [PATCH v2] mtd: nand: automate NAND timings selection Sascha Hauer
2016-09-06 10:39 ` Sascha Hauer
2016-09-06 10:39 ` [PATCH 1/7] mtd: nand: Create a NAND reset function Sascha Hauer
2016-09-06 10:39   ` Sascha Hauer
2016-09-06 11:18   ` Boris Brezillon
2016-09-06 11:18     ` Boris Brezillon
2016-09-06 13:02     ` Sascha Hauer
2016-09-06 13:02       ` Sascha Hauer
2016-09-06 13:06       ` Boris Brezillon
2016-09-06 13:06         ` Boris Brezillon
2016-09-06 10:39 ` [PATCH 2/7] mtd: nand: Introduce nand_data_interface Sascha Hauer
2016-09-06 10:39   ` Sascha Hauer
2016-09-06 11:21   ` Boris Brezillon
2016-09-06 11:21     ` Boris Brezillon
2016-09-06 13:34     ` Sascha Hauer
2016-09-06 13:34       ` Sascha Hauer
2016-09-06 13:46       ` Boris Brezillon
2016-09-06 13:46         ` Boris Brezillon
2016-09-06 14:09         ` Sascha Hauer
2016-09-06 14:09           ` Sascha Hauer
2016-09-06 10:39 ` [PATCH 3/7] mtd: nand: convert ONFI mode into data interface Sascha Hauer
2016-09-06 10:39   ` Sascha Hauer
2016-09-06 11:27   ` Boris Brezillon
2016-09-06 11:27     ` Boris Brezillon
2016-09-06 12:15   ` Boris Brezillon
2016-09-06 12:15     ` Boris Brezillon
2016-09-06 10:39 ` [PATCH 4/7] mtd: nand: automate NAND timings selection Sascha Hauer
2016-09-06 10:39   ` Sascha Hauer
2016-09-06 11:58   ` Boris Brezillon
2016-09-06 11:58     ` Boris Brezillon
2016-09-06 14:08     ` Sascha Hauer
2016-09-06 14:08       ` Sascha Hauer
2016-09-06 14:50       ` Boris Brezillon
2016-09-06 14:50         ` Boris Brezillon
2016-09-06 15:04         ` Sascha Hauer
2016-09-06 15:04           ` Sascha Hauer
2016-09-06 15:15           ` Boris Brezillon
2016-09-06 15:15             ` Boris Brezillon
2016-09-06 10:39 ` [PATCH 5/7] mtd: nand: sunxi: switch from manual to automated timing config Sascha Hauer
2016-09-06 10:39   ` Sascha Hauer
2016-09-06 12:01   ` Boris Brezillon [this message]
2016-09-06 12:01     ` Boris Brezillon
2016-09-06 10:39 ` [PATCH 6/7] mtd: nand: mxc: implement onfi get/set features Sascha Hauer
2016-09-06 10:39   ` Sascha Hauer
2016-09-06 12:05   ` Boris Brezillon
2016-09-06 12:05     ` Boris Brezillon
2016-09-06 12:47     ` Sascha Hauer
2016-09-06 12:47       ` Sascha Hauer
2016-09-06 12:52       ` Boris Brezillon
2016-09-06 12:52         ` Boris Brezillon
2016-09-06 10:39 ` [PATCH 7/7] mtd: nand: mxc: Add timing setup for v2 controllers Sascha Hauer
2016-09-06 10:39   ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160906140124.6414c855@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=s.hauer@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.