All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nishanth Menon <nm@ti.com>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: Tony Lindgren <tony@atomide.com>,
	"linux-gpio@vger.kernel.org" <linux-gpio@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	Linux-OMAP <linux-omap@vger.kernel.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Lokesh Vutla <lokeshvutla@ti.com>
Subject: Re: [PATCH 1/2] pinctrl: bindings: pinctrl: Add support for TI's IODelay configuration
Date: Tue, 10 Mar 2015 10:06:11 -0500	[thread overview]
Message-ID: <54FF0863.7080804@ti.com> (raw)
In-Reply-To: <CACRpkdaLEPzBywMnMrteboK7Q4su8PoB0wjnGvVpgUJ=2czVxQ@mail.gmail.com>

On 03/10/2015 05:39 AM, Linus Walleij wrote:
> On Wed, Mar 4, 2015 at 1:00 AM, Nishanth Menon <nm@ti.com> wrote:
> 
>> +Configuration definition follows similar model as the pinctrl-single:
>> +The groups of pin configuration are defined under "pinctrl-single,pins"
>> +
>> +&dra7_iodelay_core {
>> +       mmc2_iodelay_3v3_conf: mmc2_iodelay_3v3_conf {
>> +               pinctrl-single,pins = <
>> +                       0x18c (A_DELAY(0) | G_DELAY(120))       /* CFG_GPMC_A19_IN */
>> +                       0x1a4 (A_DELAY(265) | G_DELAY(360))     /* CFG_GPMC_A20_IN */
>> +                       0x1b0 (A_DELAY(0) | G_DELAY(120))       /* CFG_GPMC_A21_IN */
>> +                       0x1bc (A_DELAY(0) | G_DELAY(120))       /* CFG_GPMC_A22_IN */
>> +                       0x1c8 (A_DELAY(287) | G_DELAY(420))     /* CFG_GPMC_A23_IN */
>> +                       0x1d4 (A_DELAY(144) | G_DELAY(240))     /* CFG_GPMC_A24_IN */
>> +                       0x1e0 (A_DELAY(0) | G_DELAY(0))         /* CFG_GPMC_A25_IN */
>> +                       0x1ec (A_DELAY(120) | G_DELAY(0))       /* CFG_GPMC_A26_IN */
>> +                       0x1f8 (A_DELAY(120) | G_DELAY(180))     /* CFG_GPMC_A27_IN */
>> +                       0x360 (A_DELAY(0) | G_DELAY(0))         /* CFG_GPMC_CS1_IN */
>> +               >;
>> +       };
>> +};
> 
> But wait.
> 
> The promise when we merged pinctrl-single was that this driver was to be used
> when the system had a one-register-per-pin layout and it was easy to do device
> trees based on that.
> 
> We were very reluctant to accept that even though we didn't even have the
> generic pin control bindings in place, the argument being that the driver
> should know the detailed register layout, it should not be described in the
> device tree. We eventually caved in and accepted it as an exception.
> 
> Since this pin controller is not using pinctrl-single it does not enjoy that
> privilege and you need to explain why this pin controller cannot use the
> generic bindings like so many other pin controllers have since started
> to do. ("It is in the same SoC" is not an acceptable argument.)
> 
> What is wrong with this:
> Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
> 
> We can add generic delay bindings to the list, it even seems like
> a good idea to do so, as it is likely something that will come up in
> other hardware and will be needed for ACPI etc going forward.

Let me try to explain how the hardware works in this instance - it is
a quirk that we had'nt understood as being mandatory until very recently.

Apologies on pointing to TRM. Unfortunately, understanding this kind
of needs us to understand the hardware a little deeper.

http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf
18.5.2 CTRL_MODULE_CORE registers (page 4040) -> mux starts from
CTRL_CORE_PAD_GPMC_AD0 (page 4390)

This is the basic support needed for DRA7 family of SoC
handled by pinctrl-single. a single register for a single pin -> write
the mux mode, internal pull, wakeup capability etc. handled today as
part of pinctrl-single compatible "ti,dra7-padconf".

This works for almost 95%+ of the pins. few pins need tweaking of the
delay parameters to address per die, operational and board(rarely)
characteristics.

Here is where it gets a little complicated.

18.6.1 IODELAYCONFIG Module Instance Summary (page 4798) - starts at
CFG_RMII_MHZ_50_CLK_IN.

These registers are programmed per "18.4.6.1.4 Manual IO Timing Modes"
(page 4004).

Initial sequence of recalibration involves IO isolation - process
involving isolating every DRA7 pin from the external world - The only
logical place to do this is obviously as part of bootloader. Doing
this from kernel can be more than rationally complicated (IO isolation
for doing recalibration while a video playback or coprocessor like DSP
is active is just plain ridiculous in complexity).

The calibrated values then are read for programming these iodelay
registers per pin as described in the Section "18.4.6.1.4 Manual IO
Timing Modes" (page 4005).


In summary:
- This does not really control traditional points of pinctrl control
such as mux mode, pull direction etc. It is, in short, a tweaking of
delay paths from the IP to the external pin.

- Most pins do not need iodelay register programming. The ones that do
may have upto 3 other registers that may need programming (IN, OUT, OUTEN)

- Unlike pinctrl-single where a value is read from dts and programmed
straight to the register, programming iodelay involves taking two
parameter(a_delay and g_delay) per iodelay register, value for the
registers computed based on two other parameters(cdpe, fdpe). Where
cdpe and fdpe are computed based on "recalibration sequence" generated
values programmed in register fields for ref_count, delay_count and
ref_clk_period.
	- This is also why pinctrl-single wont work here - it is not
	  a copy from dts to register sequence, it is a compute from
	  dts to register sequence.

- The recalibration parameters ref_count, delay_count and
ref_clk_period are die dependent (hence the need of recalibration
sequence).

- The parameters a_delay, g_delay are dependent on operational
mode/board properties.
	- This is why such a data in kernel may not scale with
	  multitude of board variations and operational needs of
	  certain pins.
	- The values themselves come from some automated tool/data
	  sheet with per-board tweaking done under simulation.

Considering this was a "configuration of per pin iodelay", i chose
pinconf-like model here. Unfortunately, The traditional pinconf is a
set of properties for a pin, but it does not give information as to
which register those properties belong to. since these registers do
not form the same pattern of offsets as padconf register, that iodelay
register information will need to be encoded in some form.

The traditional pinctrl does not fit this hardware either. it does not
control mux, rather given that pinctrl has selected a specific mux
mode, it tweaks the delay parameters corresponding to that mux.


This is one of those modules that I cant seem to fit neatly in any of
the existing frameworks, I am most happy to understand if there are
alternatives that can be proposed..

-- 
Regards,
Nishanth Menon

WARNING: multiple messages have this Message-ID (diff)
From: nm@ti.com (Nishanth Menon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] pinctrl: bindings: pinctrl: Add support for TI's IODelay configuration
Date: Tue, 10 Mar 2015 10:06:11 -0500	[thread overview]
Message-ID: <54FF0863.7080804@ti.com> (raw)
In-Reply-To: <CACRpkdaLEPzBywMnMrteboK7Q4su8PoB0wjnGvVpgUJ=2czVxQ@mail.gmail.com>

On 03/10/2015 05:39 AM, Linus Walleij wrote:
> On Wed, Mar 4, 2015 at 1:00 AM, Nishanth Menon <nm@ti.com> wrote:
> 
>> +Configuration definition follows similar model as the pinctrl-single:
>> +The groups of pin configuration are defined under "pinctrl-single,pins"
>> +
>> +&dra7_iodelay_core {
>> +       mmc2_iodelay_3v3_conf: mmc2_iodelay_3v3_conf {
>> +               pinctrl-single,pins = <
>> +                       0x18c (A_DELAY(0) | G_DELAY(120))       /* CFG_GPMC_A19_IN */
>> +                       0x1a4 (A_DELAY(265) | G_DELAY(360))     /* CFG_GPMC_A20_IN */
>> +                       0x1b0 (A_DELAY(0) | G_DELAY(120))       /* CFG_GPMC_A21_IN */
>> +                       0x1bc (A_DELAY(0) | G_DELAY(120))       /* CFG_GPMC_A22_IN */
>> +                       0x1c8 (A_DELAY(287) | G_DELAY(420))     /* CFG_GPMC_A23_IN */
>> +                       0x1d4 (A_DELAY(144) | G_DELAY(240))     /* CFG_GPMC_A24_IN */
>> +                       0x1e0 (A_DELAY(0) | G_DELAY(0))         /* CFG_GPMC_A25_IN */
>> +                       0x1ec (A_DELAY(120) | G_DELAY(0))       /* CFG_GPMC_A26_IN */
>> +                       0x1f8 (A_DELAY(120) | G_DELAY(180))     /* CFG_GPMC_A27_IN */
>> +                       0x360 (A_DELAY(0) | G_DELAY(0))         /* CFG_GPMC_CS1_IN */
>> +               >;
>> +       };
>> +};
> 
> But wait.
> 
> The promise when we merged pinctrl-single was that this driver was to be used
> when the system had a one-register-per-pin layout and it was easy to do device
> trees based on that.
> 
> We were very reluctant to accept that even though we didn't even have the
> generic pin control bindings in place, the argument being that the driver
> should know the detailed register layout, it should not be described in the
> device tree. We eventually caved in and accepted it as an exception.
> 
> Since this pin controller is not using pinctrl-single it does not enjoy that
> privilege and you need to explain why this pin controller cannot use the
> generic bindings like so many other pin controllers have since started
> to do. ("It is in the same SoC" is not an acceptable argument.)
> 
> What is wrong with this:
> Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
> 
> We can add generic delay bindings to the list, it even seems like
> a good idea to do so, as it is likely something that will come up in
> other hardware and will be needed for ACPI etc going forward.

Let me try to explain how the hardware works in this instance - it is
a quirk that we had'nt understood as being mandatory until very recently.

Apologies on pointing to TRM. Unfortunately, understanding this kind
of needs us to understand the hardware a little deeper.

http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf
18.5.2 CTRL_MODULE_CORE registers (page 4040) -> mux starts from
CTRL_CORE_PAD_GPMC_AD0 (page 4390)

This is the basic support needed for DRA7 family of SoC
handled by pinctrl-single. a single register for a single pin -> write
the mux mode, internal pull, wakeup capability etc. handled today as
part of pinctrl-single compatible "ti,dra7-padconf".

This works for almost 95%+ of the pins. few pins need tweaking of the
delay parameters to address per die, operational and board(rarely)
characteristics.

Here is where it gets a little complicated.

18.6.1 IODELAYCONFIG Module Instance Summary (page 4798) - starts at
CFG_RMII_MHZ_50_CLK_IN.

These registers are programmed per "18.4.6.1.4 Manual IO Timing Modes"
(page 4004).

Initial sequence of recalibration involves IO isolation - process
involving isolating every DRA7 pin from the external world - The only
logical place to do this is obviously as part of bootloader. Doing
this from kernel can be more than rationally complicated (IO isolation
for doing recalibration while a video playback or coprocessor like DSP
is active is just plain ridiculous in complexity).

The calibrated values then are read for programming these iodelay
registers per pin as described in the Section "18.4.6.1.4 Manual IO
Timing Modes" (page 4005).


In summary:
- This does not really control traditional points of pinctrl control
such as mux mode, pull direction etc. It is, in short, a tweaking of
delay paths from the IP to the external pin.

- Most pins do not need iodelay register programming. The ones that do
may have upto 3 other registers that may need programming (IN, OUT, OUTEN)

- Unlike pinctrl-single where a value is read from dts and programmed
straight to the register, programming iodelay involves taking two
parameter(a_delay and g_delay) per iodelay register, value for the
registers computed based on two other parameters(cdpe, fdpe). Where
cdpe and fdpe are computed based on "recalibration sequence" generated
values programmed in register fields for ref_count, delay_count and
ref_clk_period.
	- This is also why pinctrl-single wont work here - it is not
	  a copy from dts to register sequence, it is a compute from
	  dts to register sequence.

- The recalibration parameters ref_count, delay_count and
ref_clk_period are die dependent (hence the need of recalibration
sequence).

- The parameters a_delay, g_delay are dependent on operational
mode/board properties.
	- This is why such a data in kernel may not scale with
	  multitude of board variations and operational needs of
	  certain pins.
	- The values themselves come from some automated tool/data
	  sheet with per-board tweaking done under simulation.

Considering this was a "configuration of per pin iodelay", i chose
pinconf-like model here. Unfortunately, The traditional pinconf is a
set of properties for a pin, but it does not give information as to
which register those properties belong to. since these registers do
not form the same pattern of offsets as padconf register, that iodelay
register information will need to be encoded in some form.

The traditional pinctrl does not fit this hardware either. it does not
control mux, rather given that pinctrl has selected a specific mux
mode, it tweaks the delay parameters corresponding to that mux.


This is one of those modules that I cant seem to fit neatly in any of
the existing frameworks, I am most happy to understand if there are
alternatives that can be proposed..

-- 
Regards,
Nishanth Menon

  reply	other threads:[~2015-03-10 15:06 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-04  0:00 [PATCH 0/2] pinctrl: Introduce support for iodelay module in TI SoCs Nishanth Menon
2015-03-04  0:00 ` Nishanth Menon
2015-03-04  0:00 ` Nishanth Menon
2015-03-04  0:00 ` [PATCH 1/2] pinctrl: bindings: pinctrl: Add support for TI's IODelay configuration Nishanth Menon
2015-03-04  0:00   ` Nishanth Menon
2015-03-04  0:00   ` Nishanth Menon
2015-03-10 10:39   ` Linus Walleij
2015-03-10 10:39     ` Linus Walleij
2015-03-10 10:39     ` Linus Walleij
2015-03-10 15:06     ` Nishanth Menon [this message]
2015-03-10 15:06       ` Nishanth Menon
2015-03-10 15:06       ` Nishanth Menon
2015-03-10 15:33     ` Tony Lindgren
2015-03-10 15:33       ` Tony Lindgren
2015-03-10 15:33       ` Tony Lindgren
2015-03-10 17:25       ` Nishanth Menon
2015-03-10 17:25         ` Nishanth Menon
2015-03-10 17:25         ` Nishanth Menon
2015-03-10 17:31         ` Tony Lindgren
2015-03-10 17:31           ` Tony Lindgren
2015-03-10 17:31           ` Tony Lindgren
2015-03-10 18:33           ` Nishanth Menon
2015-03-10 18:33             ` Nishanth Menon
2015-03-10 18:33             ` Nishanth Menon
2015-03-10 19:20             ` Nishanth Menon
2015-03-10 19:20               ` Nishanth Menon
2015-03-10 19:20               ` Nishanth Menon
2015-03-18  1:30             ` Linus Walleij
2015-03-18  1:30               ` Linus Walleij
2015-03-18  1:30               ` Linus Walleij
2015-03-18  1:41               ` Tony Lindgren
2015-03-18  1:41                 ` Tony Lindgren
2015-03-18  1:41                 ` Tony Lindgren
2015-04-15  1:29                 ` Lennart Sorensen
2015-04-15  1:29                   ` Lennart Sorensen
2015-04-15  1:29                   ` Lennart Sorensen
     [not found]                   ` <20150415012910.GA29560-1wCw9BSqJbv44Nm34jS7GywD8/FfD2ys@public.gmane.org>
2015-04-15 16:51                     ` Nishanth Menon
2015-04-15 16:51                       ` Nishanth Menon
2015-04-15 16:51                       ` Nishanth Menon
2015-04-15 18:44                       ` Lennart Sorensen
2015-04-15 18:44                         ` Lennart Sorensen
2015-04-15 18:44                         ` Lennart Sorensen
2015-04-15 18:53                         ` Nishanth Menon
2015-04-15 18:53                           ` Nishanth Menon
2015-04-15 18:53                           ` Nishanth Menon
2015-03-04  0:00 ` [PATCH 2/2] pinctrl: Introduce TI IOdelay configuration driver Nishanth Menon
2015-03-04  0:00   ` Nishanth Menon
2015-03-04  0:00   ` Nishanth Menon
2015-03-04 22:58   ` Paul Bolle
2015-03-04 22:58     ` Paul Bolle
2015-03-04 22:58     ` Tony Lindgren
2015-03-04 22:58       ` Tony Lindgren
2015-03-05  2:22       ` Nishanth Menon
2015-03-05  2:22         ` Nishanth Menon
2015-03-05  2:22         ` Nishanth Menon
2015-03-10 11:03   ` Linus Walleij
2015-03-10 11:03     ` Linus Walleij
2015-03-10 11:03     ` Linus Walleij
2015-03-11 12:39     ` Nishanth Menon
2015-03-11 12:39       ` Nishanth Menon
2015-03-11 12:39       ` Nishanth Menon

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=54FF0863.7080804@ti.com \
    --to=nm@ti.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=lokeshvutla@ti.com \
    --cc=tony@atomide.com \
    /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.