[U-Boot] [PATCH 06/57] x86: ivybridge: Set up the LPC device using driver model
Simon Glass
sjg at chromium.org
Fri Dec 18 03:49:00 CET 2015
Hi Bin,
On 17 December 2015 at 03:00, Bin Meng <bmeng.cn at gmail.com> wrote:
> Hi Simon,
>
> On Wed, Dec 16, 2015 at 2:57 AM, Simon Glass <sjg at chromium.org> wrote:
>> Hi Bin,
>>
>> On 13 December 2015 at 05:52, Bin Meng <bmeng.cn at gmail.com> wrote:
>>> Hi Simon,
>>>
>>> On Tue, Dec 8, 2015 at 11:38 AM, Simon Glass <sjg at chromium.org> wrote:
>>>> Find the LPC device in arch_cpu_init_dm() as a first step to converting
>>>> this code to use driver model. Probing the LPC will probe its parent (the
>>>> PCH) automatically, so make sure that probing the PCH does nothing before
>>>> relocation.
>>>>
>>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>>> ---
>>>>
>>>> arch/x86/cpu/ivybridge/bd82x6x.c | 3 +++
>>>> arch/x86/cpu/ivybridge/cpu.c | 6 +++++-
>>>> arch/x86/cpu/ivybridge/lpc.c | 6 ++++++
>>>> arch/x86/dts/chromebook_link.dts | 1 +
>>>> 4 files changed, 15 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
>>>> index abd59da..be39bcd 100644
>>>> --- a/arch/x86/cpu/ivybridge/bd82x6x.c
>>>> +++ b/arch/x86/cpu/ivybridge/bd82x6x.c
>>>> @@ -64,6 +64,9 @@ static int bd82x6x_probe(struct udevice *dev)
>>>> int sata_node, gma_node;
>>>> int ret;
>>>>
>>>> + if (!(gd->flags & GD_FLG_RELOC))
>>>> + return 0;
>>>> +
>>>> hose = pci_bus_to_hose(0);
>>>> lpc_enable(PCH_LPC_DEV);
>>>> lpc_init(hose, PCH_LPC_DEV);
>>>> diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
>>>> index 0387444..fd7e1fc 100644
>>>> --- a/arch/x86/cpu/ivybridge/cpu.c
>>>> +++ b/arch/x86/cpu/ivybridge/cpu.c
>>>> @@ -126,7 +126,7 @@ int arch_cpu_init_dm(void)
>>>> {
>>>> const void *blob = gd->fdt_blob;
>>>> struct pci_controller *hose;
>>>> - struct udevice *bus;
>>>> + struct udevice *bus, *dev;
>>>> int node;
>>>> int ret;
>>>>
>>>> @@ -141,6 +141,10 @@ int arch_cpu_init_dm(void)
>>>> /* TODO(sjg at chromium.org): Get rid of gd->hose */
>>>> gd->hose = hose;
>>>>
>>>> + ret = uclass_first_device(UCLASS_LPC, &dev);
>>>> + if (!dev)
>>>> + return -ENODEV;
>>>> +
>>>> node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
>>>> if (node < 0)
>>>> return -ENOENT;
>>>> diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
>>>> index 3efd3e8..04a7451 100644
>>>> --- a/arch/x86/cpu/ivybridge/lpc.c
>>>> +++ b/arch/x86/cpu/ivybridge/lpc.c
>>>> @@ -568,6 +568,11 @@ void lpc_enable(pci_dev_t dev)
>>>> setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF);
>>>> }
>>>>
>>>> +static int bd82x6x_lpc_probe(struct udevice *dev)
>>>> +{
>>>> + return 0;
>>>> +}
>>>> +
>>>> static const struct udevice_id bd82x6x_lpc_ids[] = {
>>>> { .compatible = "intel,bd82x6x-lpc" },
>>>> { }
>>>> @@ -577,4 +582,5 @@ U_BOOT_DRIVER(bd82x6x_lpc_drv) = {
>>>> .name = "lpc",
>>>> .id = UCLASS_LPC,
>>>> .of_match = bd82x6x_lpc_ids,
>>>> + .probe = bd82x6x_lpc_probe,
>>>> };
>>>> diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
>>>> index 4d158da..7a009db 100644
>>>> --- a/arch/x86/dts/chromebook_link.dts
>>>> +++ b/arch/x86/dts/chromebook_link.dts
>>>> @@ -223,6 +223,7 @@
>>>> compatible = "intel,bd82x6x-lpc";
>>>> #address-cells = <1>;
>>>> #size-cells = <0>;
>>>> + u-boot,dm-pre-reloc;
>>>> cros-ec at 200 {
>>>> compatible = "google,cros-ec";
>>>> reg = <0x204 1 0x200 1 0x880 0x80>;
>>>> --
>>>
>>> The codes look good to me, but I have one question: what is the LPC
>>> uclass for? My understanding is that we already have the PCH uclass,
>>> which is for the bridge. LPC uclass seems to be duplicated. We can
>>> have cros-ec directly attached to the PCH node in the device tree.
>>
>> I was going to mention that in the cover letter.
>>
>> At present I have the northbridge as 0,0,0 device. The PCH is at
>> 0,1f,0. Looking at the Intel datasheets the LPC is one of the pieces
>> in the PCH. SPI is another piece. So I came up with having the PCH as
>> the parent device and LPC and SPI as children.
>>
>
> But LPC is using the same PCI configuration space registers (b.d.f =
> 0.1f.0) as PCH for the programming interface, not like SPI which is
> I/O space. With LPC uclass, we put LPC as the child node of the PCH
> node, so if we access LPC configuration space registers, we end up
> using LPC's parent device as the parameter for the DM PCI APIs. This
> looks odd to me.
>
> This unfortunately affects IRQ router as well, if we put IRQ router as
> the child node under PCH. Can we just merge all of these into one PCH
> uclass?
Conceptually I think we should have different devices in their own
uclass. It seems wrong to put several drivers in together just because
they are addressed in the same place.
I too have struggled with the idea of a device that appears on
multiple PCI addresses - it does not fit well with driver model, where
we assume that one driver is at one device. But IMO we should model
the PCH as a collection of child devices - using dev->parent is easy
enough and it's pretty clear what is going on. We could implement PCI
access as methods in the PCH uclass but I don't think it is worth it
for now.
Regards,
Simon
More information about the U-Boot
mailing list