From: jon-hunter@TI.COM (Jon Hunter)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation
Date: Wed, 22 Aug 2012 21:58:44 -0500 [thread overview]
Message-ID: <50359C64.40603@ti.com> (raw)
In-Reply-To: <83b963e4ebcc1009a26a8c6419c785ac6d742c0b.1345524670.git.afzal@ti.com>
Hi Afzal,
On 08/21/2012 05:45 AM, Afzal Mohammed wrote:
> Presently there are three peripherals that gets it timing
> by runtime calculation. Those peripherals can work with
> frequency scaling that affects gpmc clock. But timing
> calculation for them are in different ways.
>
> Here a generic runtime calculation method is proposed. Input
> to this function were selected so that they represent timing
> variables that are present in peripheral datasheets. Motive
> behind this was to achieve DT bindings for the inputs as is.
> Even though a few of the tusb6010 timings could not be made
> directly related to timings normally found on peripherals,
> expressions used were translated to those that could be
> justified.
>
> There are possibilities of improving the calculations, like
> calculating timing for read & write operations in a more
> similar way. Expressions derived here were tested for async
> onenand on omap3evm (as vanilla Kernel does not have omap3evm
> onenand support, local patch was used). Other peripherals,
> tusb6010, smc91x calculations were validated by simulating
> on omap3evm.
>
> Regarding "we_on" for onenand async, it was found that even
> for muxed address/data, it need not be greater than
> "adv_wr_off", but rather could be derived from write setup
> time for peripheral from start of access time, hence would
> more be in line with peripheral timings. With this method
> it was working fine. If it is required in some cases to
> have "we_on" same as "wr_data_mux_bus" (i.e. greater than
> "adv_wr_off"), another variable could be added to indicate
> it. But such a requirement is not expected though.
>
> Whole of this exercise is being done to achieve driver and
> DT conversion. If timings could not be calculated in a
> peripheral agnostic way, either gpmc driver would have to
> be peripheral gnostic or a wrapper arrangement over gpmc
> driver would be required.
>
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
> arch/arm/mach-omap2/gpmc.c | 302 ++++++++++++++++++++++++++++++++
> arch/arm/plat-omap/include/plat/gpmc.h | 61 +++++++
> 2 files changed, 363 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index d005b3a..d8e5b08 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -233,6 +233,18 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
> return ticks * gpmc_get_fclk_period() / 1000;
> }
>
> +unsigned int gpmc_ticks_to_ps(unsigned int ticks)
> +{
> + return ticks * gpmc_get_fclk_period();
> +}
> +
> +unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
> +{
> + unsigned long ticks = gpmc_ps_to_ticks(time_ps);
> +
> + return ticks * gpmc_get_fclk_period();
> +}
> +
> static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
> {
> u32 l;
> @@ -884,6 +896,296 @@ static void __init gpmc_mem_init(void)
> }
> }
>
> +static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
> +{
> + u32 temp;
> + int div;
> +
> + div = gpmc_calc_divider(sync_clk);
> + temp = gpmc_ps_to_ticks(time_ps);
> + temp = (temp + div - 1) / div;
> + return gpmc_ticks_to_ps(temp * div);
> +}
> +
> +/* can the cycles be avoided ? */
What is the above comment referring too?
> +static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
> + struct gpmc_device_timings *dev_t)
> +{
> + bool mux = dev_t->mux;
> + u32 temp;
> +
> + /* adv_rd_off */
> + temp = dev_t->t_avdp_r;
> + /* mux check required ? */
> + if (mux) {
> + /* t_avdp not to be required for sync, only added for tusb this
> + * indirectly necessitates requirement of t_avdp_r & t_avdp_w
> + * instead of having a single t_avdp
> + */
> + temp = max_t(u32, temp, gpmc_t->clk_activation * 1000 +
> + dev_t->t_avdh);
> + temp = max_t(u32,
> + (gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
> + }
> + gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> + /* oe_on */
> + temp = dev_t->t_oeasu; /* remove this ? */
> + if (mux) {
> + temp = max_t(u32, temp,
> + gpmc_t->clk_activation * 1000 + dev_t->t_ach);
> + temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
> + gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
> + }
> + gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> + /* access */
> + /* any scope for improvement ?, by combining oe_on & clk_activation,
> + * need to check whether access = clk_activation + round to sync clk ?
> + */
> + temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk);
> + temp += gpmc_t->clk_activation * 1000;
> + if (dev_t->cyc_oe)
> + temp = max_t(u32, temp, (gpmc_t->oe_on +
> + gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
> + gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> + gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
> + gpmc_t->cs_rd_off = gpmc_t->oe_off;
> +
> + /* rd_cycle */
> + temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
> + temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
> + gpmc_t->access * 1000;
> + /* barter t_ce_rdyz with t_cez_r ? */
> + if (dev_t->t_ce_rdyz)
> + temp = max_t(u32, temp,
> + gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
> + gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
> +
> + return 0;
> +}
[...]
> diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
> index 1cafbfd..e59a932 100644
> --- a/arch/arm/plat-omap/include/plat/gpmc.h
> +++ b/arch/arm/plat-omap/include/plat/gpmc.h
> @@ -152,6 +152,67 @@ struct gpmc_timings {
> struct gpmc_bool_timings bool_timings;
> };
>
> +/* Device timings in picoseconds */
Why pico seconds and not nanoseconds? I understand you may need to
temporarily convert to pico-secs for rounding, but when providing timing
it seems nano-secs is more suitable.
> +struct gpmc_device_timings {
> + u32 t_ceasu; /* address setup to CS valid */
> + u32 t_avdasu; /* address setup to ADV valid */
> + /* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
> + * of tusb using these timings even for sync whilst
> + * ideally for adv_rd/(wr)_off it should have considered
> + * t_avdh instead. This indirectly necessitates r/w
> + * variations of t_avdp as it is possible to have one
> + * sync & other async
> + */
> + u32 t_avdp_r; /* ADV low time (what about t_cer ?) */
> + u32 t_avdp_w;
> + u32 t_aavdh; /* address hold time */
> + u32 t_oeasu; /* address setup to OE valid */
> + u32 t_aa; /* access time from ADV assertion */
> + u32 t_iaa; /* initial access time */
> + u32 t_oe; /* access time from OE assertion */
> + u32 t_ce; /* access time from CS asertion */
> + u32 t_rd_cycle; /* read cycle time */
> + u32 t_cez_r; /* read CS deassertion to high Z */
> + u32 t_cez_w; /* write CS deassertion to high Z */
> + u32 t_oez; /* OE deassertion to high Z */
> + u32 t_weasu; /* address setup to WE valid */
> + u32 t_wpl; /* write assertion time */
> + u32 t_wph; /* write deassertion time */
> + u32 t_wr_cycle; /* write cycle time */
> +
> + u32 clk;
> + u32 t_bacc; /* burst access valid clock to output delay */
> + u32 t_ces; /* CS setup time to clk */
> + u32 t_avds; /* ADV setup time to clk */
> + u32 t_avdh; /* ADV hold time from clk */
> + u32 t_ach; /* address hold time from clk */
> + u32 t_rdyo; /* clk to ready valid */
> +
> + u32 t_ce_rdyz; /* XXX: description ?, or use t_cez instead */
> + u32 t_ce_avd; /* CS on to ADV on delay */
> +
> + /* XXX: check the possibility of combining
> + * cyc_aavhd_oe & cyc_aavdh_we
> + */
> + u8 cyc_aavdh_oe;
> + u8 cyc_aavdh_we;
> + u8 cyc_oe;
> + u8 cyc_wpl;
> + u32 cyc_iaa;
> +
> + bool mux; /* address & data muxed */
> + bool sync_write; /* synchronous write */
> + bool sync_read; /* synchronous read */
> +
> + bool ce_xdelay;
> + bool avd_xdelay;
> + bool oe_xdelay;
> + bool we_xdelay;
> +};
I am a little concerned about the above timings structure. For example,
if I am adding support for a new devices it is not clear ...
1. Which are required
2. Which are applicable for async, sync, address-data multiplexed etc.
3. Exactly how these relate to the fields in the gpmc registers.
I understand that this is based upon how timings for onenand and tusb
are being calculated today, but I am not sure that this is the way to go
for all devices. Personally, I would like to see us get away from how
those devices are calculating timings for any new device.
In general, I am concerned that we are abstracting the timings further
from the actual register fields. For example, the timings parameter
"t_ceasu" is described "address setup to CS valid" which is not
incorrect but this value is really just programming the CSONTIME field
and so why not call this cs_on?
So although this may consolidate how the timings are calculated today, I
am concerned it will be confusing to add timings for a new device. At
least if I am calculating timings, I am taking the timing information
for the device and translating that to the how I need to program the
gpmc register fields.
Cheers
Jon
next prev parent reply other threads:[~2012-08-23 2:58 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-21 10:41 [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 01/10] ARM: OMAP2+: nand: unify init functions Afzal Mohammed
2012-08-21 11:37 ` Igor Grinberg
2012-08-21 10:45 ` [PATCH v6 02/10] ARM: OMAP2+: gpmc: handle additional timings Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 03/10] ARM: OMAP2+: onenand: refactor for clarity Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 04/10] ARM: OMAP2+: GPMC: Remove unused OneNAND get_freq() platform function Afzal Mohammed
2012-08-21 10:45 ` [PATCH v6 05/10] ARM: OMAP2+: gpmc: find features by ip rev check Afzal Mohammed
2012-08-22 2:08 ` Jon Hunter
2012-08-21 10:45 ` [PATCH v6 06/10] ARM: OMAP2+: gpmc: remove cs# in sync clk div calc Afzal Mohammed
2012-08-22 2:11 ` Jon Hunter
2012-08-21 10:45 ` [PATCH v6 07/10] ARM: OMAP2+: gpmc: generic timing calculation Afzal Mohammed
2012-08-23 2:58 ` Jon Hunter [this message]
2012-08-24 19:54 ` Tony Lindgren
2012-08-27 11:46 ` Mohammed, Afzal
2012-08-27 10:37 ` Mohammed, Afzal
2012-08-27 20:30 ` Jon Hunter
2012-08-28 12:21 ` Mohammed, Afzal
2012-08-21 10:45 ` [PATCH v6 08/10] ARM: OMAP2+: onenand: " Afzal Mohammed
2012-08-21 10:46 ` [PATCH v6 09/10] ARM: OMAP2+: smc91x: " Afzal Mohammed
2012-08-21 10:46 ` [PATCH v6 10/10] ARM: OMAP2+: tusb6010: " Afzal Mohammed
2012-08-24 19:46 ` Tony Lindgren
2012-08-27 8:34 ` Mohammed, Afzal
2012-09-03 5:34 ` Mohammed, Afzal
2012-09-06 7:39 ` Mohammed, Afzal
2012-09-06 20:43 ` Tony Lindgren
2012-09-11 18:46 ` Tony Lindgren
2012-09-12 9:50 ` Mohammed, Afzal
2012-09-14 10:20 ` Mohammed, Afzal
2012-09-17 8:39 ` Mohammed, Afzal
2012-09-17 22:50 ` Tony Lindgren
2012-09-17 23:10 ` Tony Lindgren
2012-09-19 13:43 ` Mohammed, Afzal
2012-09-07 0:15 ` Paul Walmsley
2012-08-27 12:16 ` [PATCH v6 00/10] OMAP-GPMC: generic time calc, prepare for driver Daniel Mack
2012-08-27 12:38 ` Mohammed, Afzal
2012-08-27 13:30 ` Daniel Mack
2012-08-27 14:01 ` Mohammed, Afzal
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=50359C64.40603@ti.com \
--to=jon-hunter@ti.com \
--cc=linux-arm-kernel@lists.infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).