All of lore.kernel.org
 help / color / mirror / Atom feed
From: wmb@firmworks.com (Mitch Bradley)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: vexpress: initial device tree support
Date: Wed, 11 Jan 2012 14:38:45 -1000	[thread overview]
Message-ID: <4F0E2B95.7070402@firmworks.com> (raw)
In-Reply-To: <74CDBE0F657A3D45AFBB94109FB122FF177EE3A848@HQMAIL01.nvidia.com>

On 1/11/2012 2:15 PM, Stephen Warren wrote:
> Mitch Bradley wrote at Wednesday, January 11, 2012 4:16 PM:
>> On 1/11/2012 10:29 AM, Stephen Warren wrote:
>>> Mitch Bradley wrote at Tuesday, January 10, 2012 11:43 PM:
>>>> On 1/10/2012 2:28 PM, Timur Tabi wrote:
>>>>> Mitch Bradley wrote:
>>> ...
>>>>>> That GPIO pin thing is annoying, but not sufficiently complex or common
>>>>>> that it warrants having a separate EDID driver.  You could define a
>>>>>> platform-specific property to tell your framebuffer driver that it needs
>>>>>> to do that GPIO thing.  It's a hack, but the GPIO thing is inherently a
>>>>>> hack, so there will be some ugliness somewhere as a result.
>>>>>
>>>>> I have two platform-specific functions, "enabled_edid" and "disable_edid", that I call
>> before/after
>>>>> calling fb_ddc_read().  This seems to work well, and I already have a mechanism for calling
>> platform-
>>>>> specific functions from the framebuffer driver.
>>>>>
>>>>> However, Stephen Warren said I should be using the I2C mux feature instead.
>>>>
>>>> I2C mux is a plausible solution, as is your enable/disable thing.  At
>>>> some level they are equivalent.  I2C mux is a formalization of your
>>>> solution, in which the mux device's select method must be written to
>>>> perform the function of your enable/disable edid functions.
>>>>
>>>> Either way, you need platform-dependent functions to do the switching,
>>>> and you need to select the appropriate channel.  Personally, I don't see
>>>> the advantage of using the mux device in this case.
>>>
>>> The main advantage I see is that you explicitly don't need any platform-
>>> specific functions to do the switching; you end up with platform-agnostic
>>> code (the I2C GPIO mux driver) and platform-specific configuration for
>>> that driver (the GPIO ID to use).
>>
>>
>> Oh, I didn't know about the I2C GPIO Mux driver.  I was looking at
>> i2c-mux.c .  I now see gpio-i2cmux.c, which indeed seems to do the right
>> thing.
>>
>>> The display driver just talks to the
>>> I2C API for the DDC I2C bus, and doesn't do anything to switch between
>>> the busses; the I2C GPIO mux driver does all that internally. Thus, the
>>> display driver will work fine on boards that don't need this muxing with
>>> zero changes; the board simply wouldn't register the mux driver.
>>>
>>>> It's just adding
>>>> complexity with no payback.  If there were several channels that needed
>>>> to be accessed in an interspersed fashion, the mux device would  be much
>>>> cleaner.  But in this case, there is a single "back channel" that only
>>>> needs to be accessed once and can subsequently be ignored.
>>>
>>> Well, the EDID needs to be read on every hotplug event, so it's certainly
>>> not a one-time thing.
>>>
>>>> The video
>>>> driver can grab a lock, call enable_edid(), read out the EDID data into
>>>> an array, call disable_edid(), release the lock, and that is it.  The
>>>> other users of that I2C bus can ignore the hidden EDID.
>>>
>>> Other I2C users/devices also shouldn't be impacted by the mux; they
>>> would continue to use the existing I2C APIs for the bus their devices
>>> are attached to, and not know about the mux.
>>
>> If other devices that are on the same bus as the EDID don't use the mux,
>> how does one ensure that the GPIO is restored to the non-EDID
>> setting when the display driver is finished?
>
> The I2C busses are set up like this:
>
>                  bus 0        bus 1
> I2C controller ------->  mux ------>  dev a, dev b, dev c, ...
>                             \------>  dev x, dev y, dev z, ...
>                               bus 2
>
> Thus all devices are on a child I2C bus of the mux and none on the raw
> HW bus exposed by the I2C controller itself.
>
> The I2C core will always call gpiomux_select before each transaction,
> which will set the GPIOs appropriately for bus 1 or bus 2, depending
> on which device is being communicated with.
>
>> Perhaps I'm missing something, but it appears to me that the model is to
>> set the correct GPIO state before each use, instead of a
>> save-set-use-restore model.
>
> That's true, but the select action happens implicitly inside the I2C
> core for any and all transactions, AIUI, so the two modes are equivalent.
>
>> In any case, if there is a good way to instantiate the GPIO mux device
>> from the device tree, it certainly provides a ready-made solution.  Each
>> device that is on the bus in question would have a device node that is a
>> child of the GPIO mux node, and the display driver could have a
>> phandle-valued property pointing to the mux node, plus a property
>> declaring the selection value (or perhaps a single 2-cell property with
>> phandle, selection-value).
>
> That's probably the difficult part.
>
> For an I2C mux that is controlled via I2C, you can just add the mux
> node as a child of the I2C controller, since it has an I2C address,
> and so putting it there makes sense.
>
> But for an I2C mux that's controlled using GPIOs or pinmux, there's no
> I2C address so I guess the mux shouldn't be directly underneath the I2C
> controller.
>
> Perhaps the DT binding for such an I2C mux can refer to the parent I2C
> controller by phandle?
>
> Inside the I2C mux DT node, I think we can have a child node for each
> bus, and then use standard I2C child node addressing for all the nodes
> within these bus nodes.
>
> Perhaps:

The scheme below looks good to me, with minor nits picked...

>
> i2c1: i2c at 7000c000 {
>      #address-cells =<1>;
>      #size-cells =<0>;
>      compatible = "nvidia,tegra20-i2c";
>      reg =<0x7000C000 0x100>;
>      interrupts =<0 38 0x04>;
> };
>
> mux at 0 {
>      #address-cells =<1>;
>      #size-cells =<0>;
>      compatible = "nvidia,tegra20-i2c";

Shouldn't this compatible value be set up to bind to gpio_i2cmux?  The 
node doesn't seem to be hardware-specific.

>      parent-bus =<&i2c1>;
>      gpios =<&gpio 100 0&gpio 101 0>;
>      gpio-values-idle =<0>; /* bitmask of values */
>
>      bus at 0 {
>          #address-cells =<1>;
>          #size-cells =<0>;
>          /*
>           * The GPIO values to set as a bitmask.
>           * Formatted like gpio-i2cmux.c's mux->data.values[i].
>           * Or name this gpio-values?
>           */

Did you mean for the comment above to be associated with the 
"gpio-values-idle" property?  It seems out of place here.

>          reg =<1>;

reg =<0>  because this is bus at 0

>
>          wm8903: wm8903 at 1a {
>              compatible = "wlf,wm8903";
>              reg =<0x1a>;
>              ...
>          };
>      };
>
>      bus at 1 {
>          #address-cells =<1>;
>          #size-cells =<0>;
>          reg =<2>;

reg =<1> because this is bus at 1

>
>          light-sensor at 44 {
>              compatible = "isil,isl29018";
>              reg =<0x44>;
>              ...
>          };
>      };
> };
>

WARNING: multiple messages have this Message-ID (diff)
From: Mitch Bradley <wmb-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
To: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: "Paweł Moll" <Pawel.Moll-5wv7dgnIgG8@public.gmane.org>,
	"patches-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org"
	<patches-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	"devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org"
	<devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org>,
	"Jamie Lokier" <jamie-yetKDKU6eevNLxjTenLetw@public.gmane.org>,
	"Rob Herring"
	<rob.herring-CfjtxxwdHycX+EX/Zwu52A@public.gmane.org>,
	"Timur Tabi" <timur-KZfg59tc24xl57MIdRCFDg@public.gmane.org>,
	"linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org"
	<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>
Subject: Re: [PATCH] ARM: vexpress: initial device tree support
Date: Wed, 11 Jan 2012 14:38:45 -1000	[thread overview]
Message-ID: <4F0E2B95.7070402@firmworks.com> (raw)
In-Reply-To: <74CDBE0F657A3D45AFBB94109FB122FF177EE3A848-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>

On 1/11/2012 2:15 PM, Stephen Warren wrote:
> Mitch Bradley wrote at Wednesday, January 11, 2012 4:16 PM:
>> On 1/11/2012 10:29 AM, Stephen Warren wrote:
>>> Mitch Bradley wrote at Tuesday, January 10, 2012 11:43 PM:
>>>> On 1/10/2012 2:28 PM, Timur Tabi wrote:
>>>>> Mitch Bradley wrote:
>>> ...
>>>>>> That GPIO pin thing is annoying, but not sufficiently complex or common
>>>>>> that it warrants having a separate EDID driver.  You could define a
>>>>>> platform-specific property to tell your framebuffer driver that it needs
>>>>>> to do that GPIO thing.  It's a hack, but the GPIO thing is inherently a
>>>>>> hack, so there will be some ugliness somewhere as a result.
>>>>>
>>>>> I have two platform-specific functions, "enabled_edid" and "disable_edid", that I call
>> before/after
>>>>> calling fb_ddc_read().  This seems to work well, and I already have a mechanism for calling
>> platform-
>>>>> specific functions from the framebuffer driver.
>>>>>
>>>>> However, Stephen Warren said I should be using the I2C mux feature instead.
>>>>
>>>> I2C mux is a plausible solution, as is your enable/disable thing.  At
>>>> some level they are equivalent.  I2C mux is a formalization of your
>>>> solution, in which the mux device's select method must be written to
>>>> perform the function of your enable/disable edid functions.
>>>>
>>>> Either way, you need platform-dependent functions to do the switching,
>>>> and you need to select the appropriate channel.  Personally, I don't see
>>>> the advantage of using the mux device in this case.
>>>
>>> The main advantage I see is that you explicitly don't need any platform-
>>> specific functions to do the switching; you end up with platform-agnostic
>>> code (the I2C GPIO mux driver) and platform-specific configuration for
>>> that driver (the GPIO ID to use).
>>
>>
>> Oh, I didn't know about the I2C GPIO Mux driver.  I was looking at
>> i2c-mux.c .  I now see gpio-i2cmux.c, which indeed seems to do the right
>> thing.
>>
>>> The display driver just talks to the
>>> I2C API for the DDC I2C bus, and doesn't do anything to switch between
>>> the busses; the I2C GPIO mux driver does all that internally. Thus, the
>>> display driver will work fine on boards that don't need this muxing with
>>> zero changes; the board simply wouldn't register the mux driver.
>>>
>>>> It's just adding
>>>> complexity with no payback.  If there were several channels that needed
>>>> to be accessed in an interspersed fashion, the mux device would  be much
>>>> cleaner.  But in this case, there is a single "back channel" that only
>>>> needs to be accessed once and can subsequently be ignored.
>>>
>>> Well, the EDID needs to be read on every hotplug event, so it's certainly
>>> not a one-time thing.
>>>
>>>> The video
>>>> driver can grab a lock, call enable_edid(), read out the EDID data into
>>>> an array, call disable_edid(), release the lock, and that is it.  The
>>>> other users of that I2C bus can ignore the hidden EDID.
>>>
>>> Other I2C users/devices also shouldn't be impacted by the mux; they
>>> would continue to use the existing I2C APIs for the bus their devices
>>> are attached to, and not know about the mux.
>>
>> If other devices that are on the same bus as the EDID don't use the mux,
>> how does one ensure that the GPIO is restored to the non-EDID
>> setting when the display driver is finished?
>
> The I2C busses are set up like this:
>
>                  bus 0        bus 1
> I2C controller ------->  mux ------>  dev a, dev b, dev c, ...
>                             \------>  dev x, dev y, dev z, ...
>                               bus 2
>
> Thus all devices are on a child I2C bus of the mux and none on the raw
> HW bus exposed by the I2C controller itself.
>
> The I2C core will always call gpiomux_select before each transaction,
> which will set the GPIOs appropriately for bus 1 or bus 2, depending
> on which device is being communicated with.
>
>> Perhaps I'm missing something, but it appears to me that the model is to
>> set the correct GPIO state before each use, instead of a
>> save-set-use-restore model.
>
> That's true, but the select action happens implicitly inside the I2C
> core for any and all transactions, AIUI, so the two modes are equivalent.
>
>> In any case, if there is a good way to instantiate the GPIO mux device
>> from the device tree, it certainly provides a ready-made solution.  Each
>> device that is on the bus in question would have a device node that is a
>> child of the GPIO mux node, and the display driver could have a
>> phandle-valued property pointing to the mux node, plus a property
>> declaring the selection value (or perhaps a single 2-cell property with
>> phandle, selection-value).
>
> That's probably the difficult part.
>
> For an I2C mux that is controlled via I2C, you can just add the mux
> node as a child of the I2C controller, since it has an I2C address,
> and so putting it there makes sense.
>
> But for an I2C mux that's controlled using GPIOs or pinmux, there's no
> I2C address so I guess the mux shouldn't be directly underneath the I2C
> controller.
>
> Perhaps the DT binding for such an I2C mux can refer to the parent I2C
> controller by phandle?
>
> Inside the I2C mux DT node, I think we can have a child node for each
> bus, and then use standard I2C child node addressing for all the nodes
> within these bus nodes.
>
> Perhaps:

The scheme below looks good to me, with minor nits picked...

>
> i2c1: i2c@7000c000 {
>      #address-cells =<1>;
>      #size-cells =<0>;
>      compatible = "nvidia,tegra20-i2c";
>      reg =<0x7000C000 0x100>;
>      interrupts =<0 38 0x04>;
> };
>
> mux@0 {
>      #address-cells =<1>;
>      #size-cells =<0>;
>      compatible = "nvidia,tegra20-i2c";

Shouldn't this compatible value be set up to bind to gpio_i2cmux?  The 
node doesn't seem to be hardware-specific.

>      parent-bus =<&i2c1>;
>      gpios =<&gpio 100 0&gpio 101 0>;
>      gpio-values-idle =<0>; /* bitmask of values */
>
>      bus@0 {
>          #address-cells =<1>;
>          #size-cells =<0>;
>          /*
>           * The GPIO values to set as a bitmask.
>           * Formatted like gpio-i2cmux.c's mux->data.values[i].
>           * Or name this gpio-values?
>           */

Did you mean for the comment above to be associated with the 
"gpio-values-idle" property?  It seems out of place here.

>          reg =<1>;

reg =<0>  because this is bus@0

>
>          wm8903: wm8903@1a {
>              compatible = "wlf,wm8903";
>              reg =<0x1a>;
>              ...
>          };
>      };
>
>      bus@1 {
>          #address-cells =<1>;
>          #size-cells =<0>;
>          reg =<2>;

reg =<1> because this is bus@1

>
>          light-sensor@44 {
>              compatible = "isil,isl29018";
>              reg =<0x44>;
>              ...
>          };
>      };
> };
>

  reply	other threads:[~2012-01-12  0:38 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-21  9:19 [PATCH] ARM: vexpress: initial device tree support Dave Martin
2011-09-21  9:19 ` Dave Martin
2011-09-21 13:24 ` Rob Herring
2011-09-21 13:24   ` Rob Herring
2011-09-21 14:24   ` Dave Martin
2011-09-21 14:24     ` Dave Martin
2011-09-21 14:33     ` Pawel Moll
2011-09-21 14:33       ` Pawel Moll
2011-09-21 15:49       ` Dave Martin
2011-09-21 15:49         ` Dave Martin
2011-09-21 14:57   ` Grant Likely
2011-09-21 14:57     ` Grant Likely
2011-09-21 16:01     ` Pawel Moll
2011-09-21 16:01       ` Pawel Moll
2011-09-21 16:17       ` Dave Martin
2011-09-21 16:17         ` Dave Martin
2011-09-21 16:28         ` Pawel Moll
2011-09-21 16:28           ` Pawel Moll
2011-09-21 16:37     ` Rob Herring
2011-09-21 16:37       ` Rob Herring
2011-09-21 17:15       ` Dave Martin
2011-09-21 17:15         ` Dave Martin
2011-09-21 17:47         ` Mitch Bradley
2011-09-21 17:47           ` Mitch Bradley
2011-09-22 12:19           ` Dave Martin
2011-09-22 12:19             ` Dave Martin
2012-01-09 23:26 ` Tabi Timur-B04825
2012-01-09 23:26   ` Tabi Timur-B04825
2012-01-10  0:42   ` Mitch Bradley
2012-01-10  0:42     ` Mitch Bradley
2012-01-10  2:24     ` Tabi Timur-B04825
2012-01-10  2:24       ` Tabi Timur-B04825
2012-01-10 12:22     ` Jamie Lokier
2012-01-10 12:22       ` Jamie Lokier
2012-01-10 21:58       ` Timur Tabi
2012-01-10 21:58         ` Timur Tabi
2012-01-10 22:35         ` Mitch Bradley
2012-01-10 22:35           ` Mitch Bradley
2012-01-10 23:55           ` Stephen Warren
2012-01-10 23:55             ` Stephen Warren
2012-01-11  0:02             ` Timur Tabi
2012-01-11  0:02               ` Timur Tabi
2012-01-11  0:28           ` Timur Tabi
2012-01-11  0:28             ` Timur Tabi
2012-01-11  6:43             ` Mitch Bradley
2012-01-11  6:43               ` Mitch Bradley
2012-01-11 20:17               ` Timur Tabi
2012-01-11 20:17                 ` Timur Tabi
2012-01-11 23:20                 ` Mitch Bradley
2012-01-11 23:20                   ` Mitch Bradley
2012-01-11 23:32                   ` Timur Tabi
2012-01-11 23:32                     ` Timur Tabi
2012-01-11 20:29               ` Stephen Warren
2012-01-11 20:29                 ` Stephen Warren
2012-01-11 20:32                 ` Timur Tabi
2012-01-11 20:32                   ` Timur Tabi
2012-01-11 20:36                   ` Stephen Warren
2012-01-11 20:36                     ` Stephen Warren
2012-01-11 21:37                     ` Timur Tabi
2012-01-11 21:37                       ` Timur Tabi
2012-01-11 21:57                       ` Stephen Warren
2012-01-11 21:57                         ` Stephen Warren
2012-01-12 12:24                     ` Jamie Lokier
2012-01-12 12:24                       ` Jamie Lokier
2012-01-12 16:49                       ` Stephen Warren
2012-01-12 16:49                         ` Stephen Warren
2012-01-11 23:16                 ` Mitch Bradley
2012-01-11 23:16                   ` Mitch Bradley
2012-01-12  0:15                   ` Stephen Warren
2012-01-12  0:15                     ` Stephen Warren
2012-01-12  0:38                     ` Mitch Bradley [this message]
2012-01-12  0:38                       ` Mitch Bradley
2012-01-12  0:47                       ` Mitch Bradley
2012-01-12  0:47                         ` Mitch Bradley
2012-01-12 16:45                       ` Stephen Warren
2012-01-12 16:45                         ` Stephen Warren
2012-01-12 12:09                     ` Jamie Lokier
2012-01-12 12:09                       ` Jamie Lokier
2012-01-12 16:52                       ` Stephen Warren
2012-01-12 16:52                         ` Stephen Warren
2012-01-10 11:04   ` Dave Martin
2012-01-10 11:04     ` Dave Martin

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=4F0E2B95.7070402@firmworks.com \
    --to=wmb@firmworks.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 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.