lkml.org 
[lkml]   [2015]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [RESEND PATCH 1/2] pinctrl: change function behavior for per pin muxing controllers
On Tue, Jul 14, 2015 at 07:57:49AM +0200, Sascha Hauer wrote:
> On Thu, Jun 18, 2015 at 02:33:48PM +0200, Ludovic Desroches wrote:
> > On Wed, Jun 17, 2015 at 09:55:56AM -0600, Stephen Warren wrote:
> > > On 06/17/2015 06:38 AM, Ludovic Desroches wrote:
> > > >Hi Stephen,
> > > >
> > > >On Mon, Jun 15, 2015 at 09:58:05AM -0600, Stephen Warren wrote:
> > > >>On 06/10/2015 09:04 AM, Ludovic Desroches wrote:
> > > >>>When having a controller which allows per pin muxing, declaring with
> > > >>>which groups a function can be used is a useless constraint since groups
> > > >>>are something virtual.
> > > >>
> > > >>This isn't true.
> > > >>
> > > >>Irrespective of whether a particular piece of pinmux HW can control the mux
> > > >>function for each pin individually, or only in groups, it's quite likely
> > > >>that each function can only be selected onto a subset of those pins or
> > > >>groups. Requiring the pinctrl driver to inform the core which set of
> > > >>pins/groups particular functions can be selected onto seems quite
> > > >>reasonable.
> > > >>
> > > >>In my opinion at least, for HW that can select the mux function at the
> > > >>per-pin level, the only sensible set of groups is one group per pin with
> > > >>each group containing a single pin. Any other use of groups is a
> > > >>SW/user-level construct, and is something unrelated to why the pinctrl
> > > >>subsystem supports groups. If we want to represent those groups in pinctrl,
> > > >>there should be two separate sets of groups; one to represent the actual HW
> > > >>capabilities, and one to represent the SW/user-level convenience
> > > >>abstractions.
> > > >
> > > >Groups that I would like to use are not something related to the user or
> > > >software. It's an hardware reality but they would be more flexibles.
> > > >
> > > >Usually the muxing is done by selecting a function (which seems to be
> > > >device related: usart, spi, etc.), then you select on which pins you
> > > >want this function.
> > > >
> > > >In my case, I can't select a function only by choosing a mux. It is a
> > > >combination of the mux and the pin on which it is applied. So my
> > > >functions will be GPIO, A, B, C, etc. If I use function A on pin 12, I
> > > >will have my i2c clock signal but I can have this signal on pin 58 if I
> > > >use function C. Do you understand what I mean? It's not very easy to
> > > >explain... So here is a real example:
> > > >
> > > > --------------------------------------------------
> > > >| | pio peripheral |
> > > > --------------------------------------------------
> > > >| signal | dir | func | signal | dir | ioset |
> > > > --------------------------------------------------
> > > >| PA8 | I/O | A | SDMMC0_DAT6 | I/O | 1 |
> > > >| | | B | QSPI1_IO1 | I/O | 1 |
> > > >| | | D | TCLK5 | I | 1 |
> > > >| | | E | FLEXCOM2_IO2 | I/O | 1 |
> > > >| | | F | NWE/NANDWE | O | 2 |
> > > > --------------------------------------------------
> > > >| PD28 | I/O | A | SPI1_NPCS0 | I/O | 3 |
> > > >| | | B | TDI | I/O | 3 |
> > > >| | | C | FLEXCOM2_IO2 | I | 2 |
> > > > --------------------------------------------------
> > > >
> > > >
> > > >You are right that having a group per pin is a solution.
> > > >
> > > >If I follow your proposal (tell me if I'm wrong):
> > > >- I will have 128 groups since I have 128 pins.
> > >
> > > Yes.
> > >
> > > >- I will have functions GPIO, A, B, C, D, E, F.
> > >
> > > You could have functions A..F, and require the user to determine what option
> > > they want for each pin, find the pin-specific mux function value for each
> > > pin, and put that into the DT (or other pinmux data source). For example,
> > > the bcm2835 pinctrl driver works this way.
> > >
> > > In that case, each of the functions A..F could be selected on each pin, so
> > > you'd have a very simple "get pins for function" implementation.
> > >
> > > Alternatively, you could define a logic function per IO controller or signal
> > > that gets pinmuxed. In the example above, FLEXCOM2_IO2 is one such example.
> > > Given that set of functions, you'd need a mapping table to convert from the
> > > logical functions seen by the pinctrl subsystem to the HW values that need
> > > to be written into registers. For example, the Tegra pinctrl drivers work
> > > this way.
> > >
> > > In that case, each (pinctrl) function could only be selected on a specific
> > > subset of all pins/groups, and so you'd probably need a table-based
> > > implementation of "get pins for function".
> >
> > Thanks for giving me some examples. Let's take a look at these drivers.
> > My concern is that I didnn't want to have many and/or big tables in my
> > driver. I will have to update it for a new SoC even if the pin
> > controller is the same. I prefer to have it in the device as we did
> > before and as some drivers continue to do.
> >
> > >
> > > >- I have to give the groups which can achieve a function so I will have
> > > >128 groups for each function. It means 128 x 7 = 896 groups.
> > >
> > > I don't think so no. I'm not sure why you'd consider multiplying 128 and 7
> > > here. I'd expect 128 groups since you have 128 pins[1].
> > >
> >
> > Sorry my mistake, I mean 896 possibilites since I have 128 groups for a
> > function.
> >
> > > Well, it's possible to have slightly more groups if, say, mux function is
> > > selectable per pin, whereas something else like drive strength is configured
> > > by a register that affects multiple pins at once. You'd need separate sets
> > > of groups for muxing and for drive strength configuration. Some Tegra SoCs
> > > are like this. Still, we just add the different sets of groups together
> > > here, not multiply. The overall set of groups is not that much larger than
> > > the set of pins.
> > >
> > > >Does it seems to be something reasonable and intelligible? From my point
> > > >of view no. And what about the sysfs readability?
> > > >
> > > >With my current implementation, I have something quite understandable
> > > >for the user if he needs to check the pinmuxing:
> > > >
> > > > # cat /sys/kernel/debug/pinctrl/ahb\:apb\:pinctrl@fc038000/pinmux-pins
> > > > pin 17 (PA17): (MUX UNCLAIMED) (GPIO UNCLAIMED)
> > > > pin 18 (PA18): b0000000.sdio-host (GPIO UNCLAIMED) function E group sdmmc1_0
> > > > pin 19 (PA19): b0000000.sdio-host (GPIO UNCLAIMED) function E group sdmmc1_0
> > > >
> > > > # cat /sys/kernel/debug/pinctrl/pinctrl-maps
> > > > Pinctrl maps:
> > > >
> > > > device b0000000.sdio-host
> > > > state default
> > > > type MUX_GROUP (2)
> > > > controlling device ahb:apb:pinctrl@fc038000
> > > > group sdmmc1_0
> > > > function E
> > > >
> > > > device b0000000.sdio-host
> > > > state default
> > > > type CONFIGS_PIN (3)
> > > > controlling device ahb:apb:pinctrl@fc038000
> > > > pin PA28
> > > > config 00010003
> > > >
> > > > device b0000000.sdio-host
> > > > state default
> > > > type CONFIGS_PIN (3)
> > > > controlling device ahb:apb:pinctrl@fc038000
> > > > pin PA18
> > > > config 00010003
> > > >
> > > >
> > > >Doing as you propose, I assume the result should be:
> > > >
> > > > # cat /sys/kernel/debug/pinctrl/ahb\:apb\:pinctrl@fc038000/pinmux-pins
> > > > pin 17 (PA17): (MUX UNCLAIMED) (GPIO UNCLAIMED)
> > > > pin 18 (PA18): b0000000.sdio-host (GPIO UNCLAIMED) function E group PA18
> > > > pin 19 (PA19): b0000000.sdio-host (GPIO UNCLAIMED) function E group PA19
> > > >
> > > > # cat /sys/kernel/debug/pinctrl/pinctrl-maps
> > > > Pinctrl maps:
> > > >
> > > > device b0000000.sdio-host
> > > > state default
> > > > type MUX_GROUP (2)
> > > > controlling device ahb:apb:pinctrl@fc038000
> > > > group PA28
> > > > function E
> > > >
> > > > device b0000000.sdio-host
> > > > state default
> > > > type CONFIGS_PIN (3)
> > > > controlling device ahb:apb:pinctrl@fc038000
> > > > pin PA28
> > > > config 00010003
> > > >
> > > > device b0000000.sdio-host
> > > > state default
> > > > type MUX_GROUP (2)
> > > > controlling device ahb:apb:pinctrl@fc038000
> > > > group PA18
> > > > function E
> > > >
> > > > device b0000000.sdio-host
> > > > state default
> > > > type CONFIGS_PIN (3)
> > > > controlling device ahb:apb:pinctrl@fc038000
> > > > pin PA18
> > > > config 00010003
> > > >
> > > >I think it is more difficult to understand what is done here.
> > >
> > > I don't think I agree. The HW level groups are the individual pins, so I
> > > think the second option is clearer and more correct. What is the "sdmmc1_0"
> > > group in the first example? Does any such thing even exist in HW?
> >
> > If a user see this, I will have to take the datasheet to undersand what
> > using function E on this pin really means.
> >
> > sdmmc1_0 group doesn't really exists as a group but a collection of
> > pins. The minimum requirement is to have CK, CMD and DAT0 signals. The
> > user can choose if he wants to use DAT1,2,3,4,5,6,7 and CD. Maybe he
> > would like to keep this pins available for another function.
> >
> > This is what I have in my device tree.
> >
> > pinctrl@fc038000 {
> > group_defs {
> > sdmmc1_0 {
> > pins = <PIN_PA22__SDMMC1_CK>,
> > <PIN_PA28__SDMMC1_CMD>,
> > <PIN_PA18__SDMMC1_DAT0>,
> > <PIN_PA19__SDMMC1_DAT1>,
> > <PIN_PA20__SDMMC1_DAT2>,
> > <PIN_PA21__SDMMC1_DAT3>,
> > <PIN_PA30__SDMMC1_CD>;
> > };
> > };
> >
> > pinctrl_sdmmc1_default: sdmmc1_default {
> > mux {
> > function = "E";
> > groups = "sdmmc1_0";
> > };
> >
> > conf-cmd_data {
> > pins = <PIN_PA28__SDMMC1_CMD>,
> > <PIN_PA18__SDMMC1_DAT0>,
> > <PIN_PA19__SDMMC1_DAT1>,
> > <PIN_PA20__SDMMC1_DAT2>,
> > <PIN_PA21__SDMMC1_DAT3>;
> > bias-pull-up;
> > };
> >
> > conf-ck_cd {
> > pins = <PIN_PA22__SDMMC1_CK>,
> > <PIN_PA30__SDMMC1_CD>;
> > bias-disable;
> > };
> > };
> > }
> >
> > From my point of view, it is not so far from what generic pinconf does.
> > The only addition is the group_defs node because I don't want SoC
> > dependant tables in my driver.
>
> +1 for not having SoC dependent tables in the driver. This additional
> indirection makes the pinctrl drivers quite big and hard to follow.
>
> However, I don't understand why you need the group_defs node. I can
> understand why having this may be helpful in the code, but otherwise it
> doesn't contain any new information. It basically collects all pins also
> contained in the sdmmc1_default node, so this information can be
> retrieved there.

You are right, I don't really need the group_defs node, I did it in this way
because I wanted to split pinmux and pinconf and I didn't want to
implement my own dt_node_to_map() function but to use the
pinconf_generic_dt_node_to_map_all() one.

> The "Function E" seems rather uninteresting since not
> all pins have to be configured in function E. I bet it's possible to
> implement card detection as gpio and then you'll have PIN_PA30__GPIO_X_Y
> which is not function E.

No with our new sdhci device, card detection is not a gpio. Groups
definition has to be done in order to have the same function for all the
pins of the group.

A full example here:
https://github.com/linux4sam/linux-at91/blob/master/arch/arm/boot/dts/at91-sama5d2_xplained.dts

>
> So my take is: remove the group_defs node.
>
> Note that in the recently introduced Mediatek pinctrl driver we used
> 'pinmux' for the property that you name 'pins' here. We probably want to
> use the same name.

This driver fits most of my needs but I didn't do it in this way for the
two previous reasons. If it is not an issue to add a new
dt_node_to_map() implementation which should be quite close to the
mediatek one, let's do it.

Regards

Ludovic


\
 
 \ /
  Last update: 2015-07-15 10:01    [W:0.089 / U:0.280 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site