[PATCH] Add MPC837xEMDS PCIE RC mode support

Kumar Gala kumar.gala at freescale.com
Sat Dec 1 01:57:33 EST 2007


On Nov 30, 2007, at 3:37 AM, Li Li wrote:

> On Fri, 2007-11-30 at 17:05 +0800, Gala Kumar wrote:
>>>>> +
>>>>> +     pci2 at e0009000 {
>>>>
>>>> I agree w/Olof.  This should be pcie at e0009000
>>>>>
>>>>> +             interrupt-map-mask = <f800 0 0 7>;
>>>>> +             msi-available-ranges = <43 4 51 52 56 57 58 59>;
>>>>> +             interrupt-map = <
>>>>> +                     0000 0 0 1 &ipic 1 8
>>>>> +                     0000 0 0 2 &ipic 1 8
>>>>> +                     0000 0 0 3 &ipic 1 8
>>>>> +                     0000 0 0 4 &ipic 1 8
>>>>> +             >;
>>>>> +             interrupt-parent = < &ipic >;
>>>>> +             interrupts = <1 8>;
>>>>> +             bus-range = <0 0>;
>>>>> +             ranges = <02000000 0 A8000000 A8000000 0 10000000
>>>>> +                       01000000 0 00000000 B8000000 0 00800000>;
>>>>> +             clock-frequency = <0>;
>>>>> +             #interrupt-cells = <1>;
>>>>> +             #size-cells = <2>;
>>>>> +             #address-cells = <3>;
>>>>> +             reg = <e0009000 00001000
>>>>> +                    a0000000 08000000>;
>>>>
>>>> Shouldn't the reg size for the cfg space be 256M?
>>>
>>> 256M is a little too big for kernel.
>>
>> what do you mean too big?  Aren't you losing access to some
>> bus/dev/fn
>> than?
>
> If do it standard, a 256M config space, at least 256M mem space and  
> 16M
> io space are needed for each PCIE controller.
> To allocate PCIE window, the window size only can be 512M or 1G.
> If we choose 1G space, two PCIE controller needs 2G space.
> We do not have 2G free physical space now. Usually, we use upper 128M
> configure space. So, we have to cut down the config space.

We'll cutting config space is problematic in that its a bug since you  
might not be able to talk to a given device.

Is it possible to make the outbound window for cfg space 4k and change  
the region of config space its looking at?

>>>>> diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/
>>>>> platforms/83xx/Kconfig
>>>>> index 0c61e7a..00154c5 100644
>>>>> --- a/arch/powerpc/platforms/83xx/Kconfig
>>>>> +++ b/arch/powerpc/platforms/83xx/Kconfig
>>>>> @@ -87,3 +87,10 @@ config PPC_MPC837x
>>>>>     select PPC_INDIRECT_PCI
>>>>>     select FSL_SERDES
>>>>>     default y if MPC837x_MDS
>>>>> +
>>>>> +config PPC_MPC83XX_PCIE
>>>>> +     bool "MPC837X PCI Express support"
>>>>> +     depends on PCIEPORTBUS && PPC_MPC837x
>>>>> +     default n
>>>>> +     help
>>>>> +       Enables MPC837x PCI express RC mode
>>>>
>>>> This should be a hidden config that is just selected by
>> PPC_MPC837x
>>>> instead of a choice.  Also drop the depends on.
>>>>
>>>
>>> In the dts file, the PCIE is default enabled. So, we should provide
>>> another way to disable the PCIE.
>>> Modify and recompile the dts is a little unkind to user.
>>
>> Why do you something beyond CONFIG_PCI.  if you don't want PCIe but
>> do
>> want PCI the extra code for PCIe isn't going to kill you.
>>
>
> Here is a little complex. The MPC837xE board needs a carrier board to
> extend PCIE slot. If user does not populate carrier board onto  
> MPC837xE
> board and do PCIE scan, the system will halt.
> I just want to provide a easy way to disable the PCIe other than  
> modify
> and recompile the dts.

So I have to recompile the kernel for this case, that seems even more  
painful to the user.  Can we not detect if this board isn't there and  
not hang?

>>>>> diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h
>> b/arch/powerpc/
>>>>> platforms/83xx/mpc83xx.h
>>>>> index b778cb4..2078da7 100644
>>>>> --- a/arch/powerpc/platforms/83xx/mpc83xx.h
>>>>> +++ b/arch/powerpc/platforms/83xx/mpc83xx.h
>>>>> @@ -43,12 +43,18 @@
>>>>> #define PORTSCX_PTS_UTMI           0x00000000
>>>>> #define PORTSCX_PTS_ULPI           0x80000000
>>>>>
>>>>> +/* PCIE Registers */
>>>>> +#define PEX_LTSSM_STAT               0x404
>>>>> +#define PEX_LTSSM_STAT_L0    0x16
>>>>> +#define PEX_GCLK_RATIO               0x440
>>>>> +
>>>>
>>>> just move these into the .c file.
>
> ok.
>
>>>>
>>>>>
>>>>> /*
>>>>> * Declaration for the various functions exported by the
>>>>> * mpc83xx_* files. Mostly for use by mpc83xx_setup
>>>>> */
>>>>> -
>>>>> -extern int mpc83xx_add_bridge(struct device_node *dev);
>>>>> +#define PPC_83XX_PCI 0x1
>>>>> +#define PPC_83XX_PCIE        0x2
>>>>> +extern int mpc83xx_add_bridge(struct device_node *dev, int
>> flags);
>>>>> extern void mpc83xx_restart(char *cmd);
>>>>> extern long mpc83xx_time_init(void);
>>>>> extern int mpc834x_usb_cfg(void);
>>>>> diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/
>>>>> platforms/83xx/pci.c
>>>>> index 80425d7..0b52b2e 100644
>>>>> --- a/arch/powerpc/platforms/83xx/pci.c
>>>>> +++ b/arch/powerpc/platforms/83xx/pci.c
>>>>> @@ -25,6 +25,8 @@
>>>>> #include <asm/prom.h>
>>>>> #include <sysdev/fsl_soc.h>
>>>>>
>>>>> +#include "mpc83xx.h"
>>>>> +
>>>>> #undef DEBUG
>>>>>
>>>>> #ifdef DEBUG
>>>>> @@ -33,13 +35,157 @@
>>>>> #define DBG(x...)
>>>>> #endif
>>>>>
>>>>> -int __init mpc83xx_add_bridge(struct device_node *dev)
>>>>> +#if defined(CONFIG_PPC_MPC83XX_PCIE)
>>>>> +
>>>>> +/* PCIE config space Read/Write routines */
>>>>
>>>> should really be called something like mpc83xx_pciex_read_config
>>>>>
>>>>> +static int direct_read_config_pcie(struct pci_bus *bus,
>>>>> +                     uint devfn, int offset, int len, u32 *val)
>>>>> +{
>>>>> +     struct pci_controller *hose = bus->sysdata;
>>>>> +     void __iomem *cfg_addr;
>>>>> +     u32 bus_no;
>>>>> +
>>>>> +     if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
>>>>> +             return PCIBIOS_DEVICE_NOT_FOUND;
>>>>> +
>>>>> +     if (ppc_md.pci_exclude_device)
>>>>> +             if (ppc_md.pci_exclude_device(hose, bus->number,
>>>> devfn))
>>>>> +                     return PCIBIOS_DEVICE_NOT_FOUND;
>>>>> +
>>>>> +     switch (len) {
>>>>> +     case 2:
>>>>> +             if (offset & 1)
>>>>> +                     return -EINVAL;
>>>>> +             break;
>>>>> +     case 4:
>>>>> +     if (offset & 3)
>>>>> +             return -EINVAL;
>>>>> +             break;
>>>>> +     }
>>>>
>>>> fix formatting.
>>>>
>>>>>
>>>>> +
>>>>> +     pr_debug("_read_cfg_pcie: bus=%d devfn=%x off=%x len=%x\n",
>>>>> +             bus->number, devfn, offset, len);
>>>>> +
>>>>> +     if (bus->number == hose->first_busno) {
>>>>> +             if (devfn & 0xf8)
>>>>> +                     return PCIBIOS_DEVICE_NOT_FOUND;
>>>>
>>>> what is the 0xf8 all about?
>>>>
>>>
>>> The pcie only have one link, so the dev number only can be 0, as
>> well
>>> the function number can be 0 ~ 7.
>>
>> I don't follow what the number of links has to do with dev number.
>
> The PCIE only have one link that mean one PCIE bus only can have one
> device populate on it. The dev number of this device must be 0. If the
> device number is not 0, we consider it is a error.

we should add a comment about that.

>>>>> +     addr = mbase + (cfg_addr & ~PAGE_MASK);
>>>>> +     hose->cfg_addr = addr;
>>>>> +     hose->ops = &direct_pcie_ops;
>>>>
>>>> what's the point of this function, why not just fold it into
>>>> mpc83xx_setup_pcie
>>>>
>>>>>
>>>>> +}
>>>>> +
>>>>> +static void __init mpc83xx_setup_pcie(struct pci_controller
>> *hose,
>>>>> +                     struct resource *reg, struct resource
>>>> *cfg_space)
>>>>> +{
>>>>> +     void __iomem *hose_cfg_base;
>>>>> +     u32 val;
>>>>> +
>>>>> +     hose_cfg_base = ioremap(reg->start, reg->end - reg->start +
>>>> 1);
>>>>> +
>>>>> +     val = in_le32(hose_cfg_base + PEX_LTSSM_STAT);
>>>>> +     if (val < PEX_LTSSM_STAT_L0)
>>>>> +             hose->indirect_type |=
>>>> PPC_INDIRECT_TYPE_NO_PCIE_LINK;
>>>>> +
>>>>> +     setup_direct_pcie(hose, cfg_space->start,
>>>>> +                     cfg_space->end - cfg_space->start + 1);
>>>>> +}
>>>>> +#endif /* CONFIG_PPC_MPC83XX_PCIE */
>>>>> +
>>>>
>>>> We should do the same think fsl_pci does for primary, its passed
>>>> into
>>>> _add_bridge.  Also, can we not do what fsl_pci does and use PCI
>>>> capabilities to determine we are a PCIe controller (and drop
>> passing
>>>> it in via flags).
>>>>
>>>
>>> The mpc837x PCIE controller is a little different from mpc85xx.
>>> It can not be access via PCI configure read/write. It only can be
>>> accessed via memory-mapped read/write from core.
>>
>> You don't have access to your own config space?
>>
>
> I can access it but can not via standard pci configure routine.
> So, we use different way to access PCI and PCIE. If we want access PCI
> capabilities, we must know it is PCI controller or PCIE controller
> first.

Duh, your right..  we should than expand flags to also have a  
PPC_83XX_PCI_IS_PRIMARY and let that get set by the caller.

- k



More information about the Linuxppc-dev mailing list