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 4/7] mtd: nand: automate NAND timings selection
Date: Tue, 6 Sep 2016 17:15:46 +0200 [thread overview]
Message-ID: <20160906171546.1c0e2a51@bbrezillon> (raw)
In-Reply-To: <20160906150458.hg32bkozupz3mvhu@pengutronix.de>
On Tue, 6 Sep 2016 17:04:58 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > >
> > > > > +{
> > > > > + struct nand_chip *chip = mtd_to_nand(mtd);
> > > > > + int modes, mode, ret;
> > > > > + const struct nand_data_interface *conf;
> > > > > +
> > > > > + /*
> > > > > + * 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)
> > > > > + modes = GENMASK(chip->onfi_timing_mode_default, 0);
> > > > > +
> > > > > + ret = -EINVAL;
> > > > > + for (mode = fls(modes) - 1; mode >= 0; mode--) {
> > > > > + conf = onfi_async_timing_mode_to_data_interface(mode);
> > > >
> > > > I'd still prefer to have conf allocated at the beginning of the
> > > > function and timings copied from
> > > > onfi_async_timing_mode_to_sdr_timings(mode), but maybe you can convince
> > > > me otherwise.
> > >
> > > Let me ask the other way round: If we need struct nand_data_interface to
> > > fully describe a timing, why don't we keep an array of these in the
> > > kernel? Having an array of struct nand_sdr_timings() means we always
> > > have to copy it to a bigger struct to make it usable.
> >
> > Actually, the plan is to let vendor specific code tweak the timings if
> > needed.
> > Some NANDs that do not support ONFI have to pick timing mode 0 because
> > one of their timing is not matching the ONFI spec. I'd like to let
> > the door to fined-grained timing tweaking open, and this is only
> > possible if the chip has its own nand_data_interface object (not the
> > const one defined in nand_timings.c).
> >
> > Also note that some timings are not statically defined (like tPROG),
> > and are extracted from another ONFI field, and I'd like to add them to
> > the nand_sdr_timings struct, which again, is only possible if the
> > nand_chip has its own nand_data_interface instance.
>
> Hm, in the current series the nand_chip has it's own nand_data_interface
> instance, it's allocated in nand_find_data_interface().
Yes, but I thought you were suggesting to drop the allocation and
directly point to the static declaration returned by
onfi_async_timing_mode_to_data_interface().
>
> >
> > >
> > > > > @@ -759,6 +759,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;
> > > > > @@ -788,6 +792,8 @@ struct nand_chip {
> > > > > struct nand_jedec_params jedec_params;
> > > > > };
> > > > >
> > > > > + const struct nand_data_interface *data_iface;
> > > > > +
> > > >
> > > > How about making this field non-const so that you only allocate it once
> > > > and modify it when you switch from one mode to another.
> > >
> > > As said above, I need two different timings. If we modify this
> > > nand_data_interface instance twice during reset there's not much point
> > > in storing it in struct nand_chip at all. That was one variant I tried:
> > > Always calculcate the timing from the supported ONFI modes when we need
> > > it in nand_reset(). I stepped away from this variant because of the
> > > overhead.
> >
> > Yes, your device will be configured twice (first mode 0, then the
> > highest supported timing mode), but that does not mean you need to have
> > 2 instances of nand_data_interface.
> >
> > ->data_iface should always be assigned to the current data interface
> > config. If you reset the chip and go back to timing 0, then
> > chip->data_iface should be set to sdr mode timing zero, and once a
> > new timing mode is applied, it should be updated.
> >
> > And yes, there's a small overhead (copying the nand_sdr_timings data
> > twice), but I'm pretty sure it's negligible compared to the whole NAND
> > chip init overhead.
> > And it's not like nand_reset() is called so regularly that it's useful
> > to optimize this kind of things.
>
> I haven't really thought about overhead in terms of burnt CPU cycles but
> more about how easy it is to follow the code.
Ok.
> Anyway, I do as you wish, expect a new series tomorrow ;)
Let's see how it looks like.
Thanks,
Boris
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 4/7] mtd: nand: automate NAND timings selection
Date: Tue, 6 Sep 2016 17:15:46 +0200 [thread overview]
Message-ID: <20160906171546.1c0e2a51@bbrezillon> (raw)
In-Reply-To: <20160906150458.hg32bkozupz3mvhu@pengutronix.de>
On Tue, 6 Sep 2016 17:04:58 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > >
> > > > > +{
> > > > > + struct nand_chip *chip = mtd_to_nand(mtd);
> > > > > + int modes, mode, ret;
> > > > > + const struct nand_data_interface *conf;
> > > > > +
> > > > > + /*
> > > > > + * 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)
> > > > > + modes = GENMASK(chip->onfi_timing_mode_default, 0);
> > > > > +
> > > > > + ret = -EINVAL;
> > > > > + for (mode = fls(modes) - 1; mode >= 0; mode--) {
> > > > > + conf = onfi_async_timing_mode_to_data_interface(mode);
> > > >
> > > > I'd still prefer to have conf allocated at the beginning of the
> > > > function and timings copied from
> > > > onfi_async_timing_mode_to_sdr_timings(mode), but maybe you can convince
> > > > me otherwise.
> > >
> > > Let me ask the other way round: If we need struct nand_data_interface to
> > > fully describe a timing, why don't we keep an array of these in the
> > > kernel? Having an array of struct nand_sdr_timings() means we always
> > > have to copy it to a bigger struct to make it usable.
> >
> > Actually, the plan is to let vendor specific code tweak the timings if
> > needed.
> > Some NANDs that do not support ONFI have to pick timing mode 0 because
> > one of their timing is not matching the ONFI spec. I'd like to let
> > the door to fined-grained timing tweaking open, and this is only
> > possible if the chip has its own nand_data_interface object (not the
> > const one defined in nand_timings.c).
> >
> > Also note that some timings are not statically defined (like tPROG),
> > and are extracted from another ONFI field, and I'd like to add them to
> > the nand_sdr_timings struct, which again, is only possible if the
> > nand_chip has its own nand_data_interface instance.
>
> Hm, in the current series the nand_chip has it's own nand_data_interface
> instance, it's allocated in nand_find_data_interface().
Yes, but I thought you were suggesting to drop the allocation and
directly point to the static declaration returned by
onfi_async_timing_mode_to_data_interface().
>
> >
> > >
> > > > > @@ -759,6 +759,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;
> > > > > @@ -788,6 +792,8 @@ struct nand_chip {
> > > > > struct nand_jedec_params jedec_params;
> > > > > };
> > > > >
> > > > > + const struct nand_data_interface *data_iface;
> > > > > +
> > > >
> > > > How about making this field non-const so that you only allocate it once
> > > > and modify it when you switch from one mode to another.
> > >
> > > As said above, I need two different timings. If we modify this
> > > nand_data_interface instance twice during reset there's not much point
> > > in storing it in struct nand_chip at all. That was one variant I tried:
> > > Always calculcate the timing from the supported ONFI modes when we need
> > > it in nand_reset(). I stepped away from this variant because of the
> > > overhead.
> >
> > Yes, your device will be configured twice (first mode 0, then the
> > highest supported timing mode), but that does not mean you need to have
> > 2 instances of nand_data_interface.
> >
> > ->data_iface should always be assigned to the current data interface
> > config. If you reset the chip and go back to timing 0, then
> > chip->data_iface should be set to sdr mode timing zero, and once a
> > new timing mode is applied, it should be updated.
> >
> > And yes, there's a small overhead (copying the nand_sdr_timings data
> > twice), but I'm pretty sure it's negligible compared to the whole NAND
> > chip init overhead.
> > And it's not like nand_reset() is called so regularly that it's useful
> > to optimize this kind of things.
>
> I haven't really thought about overhead in terms of burnt CPU cycles but
> more about how easy it is to follow the code.
Ok.
> Anyway, I do as you wish, expect a new series tomorrow ;)
Let's see how it looks like.
Thanks,
Boris
next prev parent reply other threads:[~2016-09-06 15:15 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 [this message]
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
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=20160906171546.1c0e2a51@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.