powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support
PATCH 3/4 powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support
This patch adds support for PCI-Express controllers as found on the newer MPC83xx chips.
The work is losely based on the Tony Li's patch[1], but unlike the original patch, this patch implements sliding window for the Type 1 configuration transactions, so we don't have to ioremap the whole PCI-E configuration space.
Since we have to remap the config space in the atomic context, and as ioremap() function might sleep, we use the fixmap API. With fixmap we can map the page-sized areas in the atomic context. The approch is similar to the x86 implementation (arch/x86/pci/mmconfig_32.c).
[1] http://ozlabs.org/pipermail/linuxppc-dev/2008-January/049028.html
--- arch/powerpc/include/asm/fixmap.h | 4 + arch/powerpc/include/asm/pci-bridge.h | 1 + arch/powerpc/sysdev/fsl_pci.c | 200 ++++++++++++++++++++++++++++++++- include/linux/pci_ids.h | 8 ++ 4 files changed, 209 insertions(+), 4 deletions(-)
arch/powerpc/include/asm/fixmap.h +4 -0
@@ -48,6 +48,10 @@ enum fixed_addresses {FIX_KMAP_BEGIN ,/* reserved pte's for temporary kernel mappings */ FIX_KMAP_END =FIX_KMAP_BEGIN +(KM_TYPE_NR *NR_CPUS )-1 , #endif +#if (defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)) && \ + defined(CONFIG_PCI) +FIX_MPC83XX_PCIE_CFG , +#endif/* FIX_PCIE_MCFG, */ __end_of_fixed_addresses };
arch/powerpc/include/asm/pci-bridge.h +1 -0
@@ -132,6 +132,7 @@ struct pci_controller {#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 +#define PPC_INDIRECT_TYPE_MPC83XX_PCIE 0x00000040u32 indirect_type;#endif /* !CONFIG_PPC64 */ /* Currently, we limit ourselves to 1 IO range and 3 mem
arch/powerpc/sysdev/fsl_pci.c +196 -4
251 lines not on this page · raw message
include/linux/pci_ids.h +8 -0
@@ -2209,6 +2209,14 @@#define PCI_DEVICE_ID_TDI_EHCI 0x0101#define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_DEVICE_ID_MPC8315E 0x00b4 +#define PCI_DEVICE_ID_MPC8315 0x00b5 +#define PCI_DEVICE_ID_MPC8314E 0x00b6 +#define PCI_DEVICE_ID_MPC8314 0x00b7 +#define PCI_DEVICE_ID_MPC8378E 0x00c4 +#define PCI_DEVICE_ID_MPC8378 0x00c5 +#define PCI_DEVICE_ID_MPC8377E 0x00c6 +#define PCI_DEVICE_ID_MPC8377 0x00c7#define PCI_DEVICE_ID_MPC8548E 0x0012#define PCI_DEVICE_ID_MPC8548 0x0013#define PCI_DEVICE_ID_MPC8543E 0x0014
Signature · 1 line
1.5.6.5
Quoted 8 lines · Anton Vorontsov
This patch adds support for PCI-Express controllers as found on the newer MPC83xx chips.
The work is losely based on the Tony Li's patch[1], but unlike the original patch, this patch implements sliding window for the Type 1 configuration transactions, so we don't have to ioremap the whole PCI-E configuration space.
Quoted 6 lines
Since we have to remap the config space in the atomic context, and as
ioremap()function might sleep, we use the fixmap API. With fixmap we can map the page-sized areas in the atomic context. The approch is similar to the x86 implementation (arch/x86/pci/mmconfig_32.c).[1] http://ozlabs.org/pipermail/linuxppc-dev/2008-January/049028.html
thanks for looking at cleaning this up. Have you looked at moving the outbound window as well? Its not a critical issue but something I was thinking about.
Quoted 17 lines
Signed-off-by Tony Li <[email protected]>Signed-off-by Anton Vorontsov <[email protected]>---
arch/powerpc/include/asm/fixmap.h | 4 + arch/powerpc/include/asm/pci-bridge.h | 1 + arch/powerpc/sysdev/fsl_pci.c | 200 ++++++++++++++++++++++++ ++++++++- include/linux/pci_ids.h | 8 ++ 4 files changed, 209 insertions(+), 4 deletions(-)arch/powerpc/include/asm/fixmap.h +0
-0
arch/powerpc/include/asm/fixmap.h enum fixed_addresses { · line 54
Quoted 7 lines
arch/powerpc/include/asm/fixmap.h +4
-0@@ -48,6 +48,10 @@ enum fixed_addresses {FIX_KMAP_BEGIN ,/* reserved pte's for temporary kernel mappings */ FIX_KMAP_END =FIX_KMAP_BEGIN +(KM_TYPE_NR *NR_CPUS )-1 , #endif +#if (defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)) && \ + defined(CONFIG_PCI) + FIX_MPC83XX_PCIE_CFG, +#endif
Just use FIX_PCIE_MCFG that was the purpose and no big reason to ifdef this.
Quoted 302 lines
arch/powerpc/include/asm/fixmap.h +0
-0/* FIX_PCIE_MCFG, */ __end_of_fixed_addresses };arch/powerpc/include/asm/pci-bridge.h +1
-0@@ -132,6 +132,7 @@ struct pci_controller {#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 +#define PPC_INDIRECT_TYPE_MPC83XX_PCIE 0x00000040u32 indirect_type;#endif /* !CONFIG_PPC64 */ /* Currently, we limit ourselves to 1 IO range and 3 mem arch/powerpc/sysdev/fsl_pci.c +5
-1@@ -1,12 +1,16 @@/* * MPC83xx/85xx/86xx PCI/PCIE support routing. * -* Copyright 2007,2008 Freescale Semiconductor, Inc +* Copyright 2007-2009 Freescale Semiconductor, Inc. +* Copyright 2008-2009 MontaVista Software, Inc. * * Initial author: Xianghua Xiao <[email protected]> * Recode: ZHANG WEI <[email protected]> * Rewrite the routing for Frescale PCI and PCI Express * Roy Zang <[email protected]> +* MPC83xx PCI-Express support: +* Tony Li <[email protected]> +* Anton Vorontsov <[email protected]> * * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published
by thearch/powerpc/sysdev/fsl_pci.c +4
-1@@ -24,10 +28,10 @@#include <asm/prom.h> #include <asm/pci-bridge.h> #include <asm/machdep.h> +#include <asm/fixmap.h> #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> -#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)/* atmu setup for fsl pci/pcie controller */ static void __init setup_pci_atmu (struct pci_controller *hose,struct resource *rsrc)@@ -228,6 +232,14 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)return 0 ; } +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8314E , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8314 , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E,
quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8315,quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8377E,quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8377,quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8378E,quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8378,quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_header);arch/powerpc/sysdev/fsl_pci.c +102
-1@@ -250,9 +262,173 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8641 , quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8641D , quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8610 , quirk_fsl_pcie_header); -#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */ #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) +struct mpc83xx_pcie { +struct resource cfg_res; +void __iomem *cfg_map; +int mapped_bus; +unsigned int mapped_devfn; +}; + +/* +* With the convention of u-boot, the PCIE outbound window 0 serves +* as configuration transactions outbound. +*/ +#define PEX_OUTWIN0_TAL 0xCA8 +#define PEX_OUTWIN0_TAH 0xCAC + +static int mpc83xx_pcie_exclude_device (struct pci_bus *bus,unsigned int devfn) +{ +struct pci_controller *hose = bus->sysdata; + +if (hose->indirect_type &PPC_INDIRECT_TYPE_NO_PCIE_LINK ) +return PCIBIOS_DEVICE_NOT_FOUND ; +/* +* Workaround for the HW bug: for Type 0 configure transactions the +* PCI-E controller does not check the device number bits and just +* assumes that the device number bits are 0. +*/ +if (hose->indirect_type &PPC_INDIRECT_TYPE_MPC83XX_PCIE ) { +if (bus->number == hose->first_busno || + bus->primary == hose->first_busno) { +if (devfn &0xf8 ) +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 ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static void __iomem *mpc83xx_pcie_remap_cfg (struct pci_bus *bus, +unsigned int devfn,int offset) +{ +struct pci_controller *hose = bus->sysdata; +struct mpc83xx_pcie *pcie = hose->dn->data; +u32 bus_no = bus->number - hose->first_busno; +int ret; + + ret =mpc83xx_pcie_exclude_device (bus, devfn); +if (ret) +return NULL ; + + offset &=0xfff ; + +if (hose->indirect_type &PPC_INDIRECT_TYPE_MPC83XX_PCIE ) { +/* Type 0 */ +if (bus->number == hose->first_busno) +return hose->cfg_data + offset; + } + +if (pcie->mapped_bus == bus_no && pcie->mapped_devfn == devfn) + goto mapped; + +clear_fixmap (FIX_MPC83XX_PCIE_CFG ); +set_fixmap_nocache (FIX_MPC83XX_PCIE_CFG , + pcie->cfg_res.start + (devfn <<16 )); + +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAL , bus_no); +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAH ,0 ); + + pcie->mapped_devfn = devfn; + pcie->mapped_bus = bus_no; +mapped: +return pcie->cfg_map + offset; +} + +static int mpc83xx_pcie_read_config (struct pci_bus *bus,unsigned int devfn, +int offset,int len,u32 *val) +{ +void __iomem *cfg_addr; + + cfg_addr =mpc83xx_pcie_remap_cfg (bus, devfn, offset); +if (!cfg_addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +switch (len) { +case 1 : + *val =in_8 (cfg_addr); +break ; +case 2 : + *val =in_le16 (cfg_addr); +break ; +default : + *val =in_le32 (cfg_addr); +break ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsignedint devfn,
arch/powerpc/sysdev/fsl_pci.c +63
-0+ int offset, int len, u32 val) +{ + void __iomem *cfg_addr; + + cfg_addr =mpc83xx_pcie_remap_cfg (bus, devfn, offset); +if (!cfg_addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +switch (len) { +case 1 : +out_8 (cfg_addr, val); +break ; +case 2 : +out_le16 (cfg_addr, val); +break ; +default : +out_le32 (cfg_addr, val); +break ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static struct pci_ops mpc83xx_pcie_ops = { + mpc83xx_pcie_read_config, + mpc83xx_pcie_write_config, +}; + +static int __init mpc83xx_pcie_setup (struct pci_controller *hose, +struct resource *reg, +struct resource *cfg) +{ +struct mpc83xx_pcie *pcie; + + pcie =zalloc_maybe_bootmem (sizeof (*pcie),GFP_KERNEL ); +if (!pcie) +return -ENOMEM ; + + pcie->cfg_res = *cfg; + pcie->cfg_map = (void __iomem *)fix_to_virt (FIX_MPC83XX_PCIE_CFG ); + pcie->mapped_devfn = ~0 ; + pcie->mapped_bus = ~0 ; + +WARN_ON (hose->dn->data); + hose->dn->data = pcie; + + hose->cfg_data =ioremap (reg->start,resource_size (reg)); +if (!hose->cfg_data) + goto err; + + hose->indirect_type |=PPC_INDIRECT_TYPE_MPC83XX_PCIE ; + hose->ops = &mpc83xx_pcie_ops; + +if (fsl_pcie_check_link (hose)) + hose->indirect_type |=PPC_INDIRECT_TYPE_NO_PCIE_LINK ; + +return 0 ; +err: +kfree (pcie); +return -ENOMEM ; + +} +int
__initmpc83xx_add_bridge(struct device_node *dev){ int len;arch/powerpc/sysdev/fsl_pci.c +4
-0@@ -262,6 +438,10 @@ int __init mpc83xx_add_bridge(struct device_node *dev)const int *bus_range;int primary; +if (!of_device_is_available (dev)) { +pr_warning ("%s: disabled by the firmware.\n" , dev->full_name); +return -ENODEV ; + }pr_debug ("Adding PCI host bridge %s\n" , dev->full_name);/* Fetch host bridge registers address */arch/powerpc/sysdev/fsl_pci.c +10
-1@@ -309,7 +489,16 @@ int __init mpc83xx_add_bridge(struct device_node *dev) hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1 ] :0xff ; -setup_indirect_pci (hose, rsrc_cfg.start, rsrc_cfg.start +4 ,0 ); +if (of_device_is_compatible (dev,"fsl,mpc8314-pcie" )) { +int ret; + + ret =mpc83xx_pcie_setup (hose, &rsrc_reg, &rsrc_cfg); +if (ret) + goto err; + }else { +setup_indirect_pci (hose, rsrc_cfg.start, + rsrc_cfg.start +4 ,0 ); + } printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. ""Firmware bus number: %d->%d\n",arch/powerpc/sysdev/fsl_pci.c +3
-0@@ -324,5 +513,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)pci_process_bridge_OF_ranges (hose, dev, primary);return 0 ; +err: +pcibios_free_controller (hose); +return -ENOMEM ; }#endif /*
CONFIG_PPC_83xx*/include/linux/pci_ids.h +0
-0@@ -2209,6 +2209,14 @@#define PCI_DEVICE_ID_TDI_EHCI 0x0101
include/linux/pci_ids.h line 2219
Quoted 10 lines
include/linux/pci_ids.h +8
-0#define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_DEVICE_ID_MPC8315E 0x00b4 +#define PCI_DEVICE_ID_MPC8315 0x00b5 +#define PCI_DEVICE_ID_MPC8314E 0x00b6 +#define PCI_DEVICE_ID_MPC8314 0x00b7 +#define PCI_DEVICE_ID_MPC8378E 0x00c4 +#define PCI_DEVICE_ID_MPC8378 0x00c5 +#define PCI_DEVICE_ID_MPC8377E 0x00c6 +#define PCI_DEVICE_ID_MPC8377 0x00c7
Please make sure these get added to http://pci-ids.ucw.cz/
Quoted 6 lines
include/linux/pci_ids.h +0
-0#define PCI_DEVICE_ID_MPC8548E 0x0012#define PCI_DEVICE_ID_MPC8548 0x0013#define PCI_DEVICE_ID_MPC8543E 0x0014Signature · 1 line
1.5.6.5
PATCH v2 3/4 powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support
This patch adds support for PCI-Express controllers as found on the newer MPC83xx chips.
The work is loosely based on the Tony Li's patch[1], but unlike the original patch, this patch implements sliding window for the Type 1 transactions using outbound window translations, so we don't have to ioremap the whole PCI-E configuration space.
[1] http://ozlabs.org/pipermail/linuxppc-dev/2008-January/049028.html
---
Quoted 16 lines · Kumar Gala
Quoted 13 lines · Anton Vorontsov
This patch adds support for PCI-Express controllers as found on the newer MPC83xx chips.
The work is losely based on the Tony Li's patch[1], but unlike the original patch, this patch implements sliding window for the Type 1 configuration transactions, so we don't have to ioremap the whole PCI-E configuration space.
Since we have to remap the config space in the atomic context, and as
ioremap()function might sleep, we use the fixmap API. With fixmap we can map the page-sized areas in the atomic context. The approch is similar to the x86 implementation (arch/x86/pci/mmconfig_32.c).
Quoted 5 lines
Quoted 1 line
[1] http://ozlabs.org/pipermail/linuxppc-dev/2008-January/049028.html
thanks for looking at cleaning this up. Have you looked at moving the outbound window as well? Its not a critical issue but something I was thinking about.
Ah, I think we can indeed slide the outbound window instead. That way we don't need the fixmap at all.
See how I change the PEX_OUTWIN0_TAL register in the new mpc83xx_pcie_remap_cfg:
According to specs, bits 7:2 are used to offset the register, bits 14:12 are used to denote a function, 19:15 are used for device number, 20:27 should specify bus number (original code was writing the bus number to the wrong bit field, I think).
So, we ioremap the first 4kb of the config space at the setup time, and then just changing the TAL to read/write config space of the needed BDF.
[...]
Quoted 3 lines
Quoted 1 line
+#define
PCI_DEVICE_ID_MPC83770x00c7Please make sure these get added to http://pci-ids.ucw.cz/
Will do.
How about this patch? It works for me using SKY2 NIC, though I don't have any PCI-E switch or multi-function device to fully test the sliding window behaviour...
Thanks,
arch/powerpc/include/asm/pci-bridge.h | 1 + arch/powerpc/sysdev/fsl_pci.c | 195 ++++++++++++++++++++++++++++++++- include/linux/pci_ids.h | 8 ++ 3 files changed, 200 insertions(+), 4 deletions(-)
arch/powerpc/include/asm/pci-bridge.h +1 -0
@@ -132,6 +132,7 @@ struct pci_controller {#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 +#define PPC_INDIRECT_TYPE_MPC83XX_PCIE 0x00000040u32 indirect_type;#endif /* !CONFIG_PPC64 */ /* Currently, we limit ourselves to 1 IO range and 3 mem
arch/powerpc/sysdev/fsl_pci.c +191 -4
243 lines not on this page · raw message
include/linux/pci_ids.h +8 -0
@@ -2209,6 +2209,14 @@#define PCI_DEVICE_ID_TDI_EHCI 0x0101#define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_DEVICE_ID_MPC8315E 0x00b4 +#define PCI_DEVICE_ID_MPC8315 0x00b5 +#define PCI_DEVICE_ID_MPC8314E 0x00b6 +#define PCI_DEVICE_ID_MPC8314 0x00b7 +#define PCI_DEVICE_ID_MPC8378E 0x00c4 +#define PCI_DEVICE_ID_MPC8378 0x00c5 +#define PCI_DEVICE_ID_MPC8377E 0x00c6 +#define PCI_DEVICE_ID_MPC8377 0x00c7#define PCI_DEVICE_ID_MPC8548E 0x0012#define PCI_DEVICE_ID_MPC8548 0x0013#define PCI_DEVICE_ID_MPC8543E 0x0014
Signature · 1 line
1.5.6.5
Quoted 3 lines
How about this patch? It works for me using SKY2 NIC, though I don't have any PCI-E switch or multi-function device to fully test the sliding window behaviour...
I'd prefer we tested under these scenarios but will not hold up the patch on it.
Quoted 13 lines
Thanks,
arch/powerpc/include/asm/pci-bridge.h| 1 +arch/powerpc/sysdev/fsl_pci.c| 195 ++++++++++++++++++++++++
++++++++-include/linux/pci_ids.h| 8 ++3 files changed, 200 insertions(+), 4 deletions(-)arch/powerpc/include/asm/pci-bridge.h +0
-0
arch/powerpc/include/asm/pci-bridge.h struct pci_controller { · line 135
Quoted 4 lines
arch/powerpc/include/asm/pci-bridge.h +1
-0@@ -132,6 +132,7 @@ struct pci_controller {#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 +#define PPC_INDIRECT_TYPE_MPC83XX_PCIE 0x00000040
we are bastardizing indirect_type w/this.
1. we just possibly rename this flags and have it generally available.
2. we should rename PPC_INDIRECT_TYPE_MPC83XX_PCIE to _BROKEN_....
3. add a comment about what the new type is for.
Quoted 37 lines
arch/powerpc/include/asm/pci-bridge.h +0
-0u32 indirect_type;#endif /* !CONFIG_PPC64 */ /* Currently, we limit ourselves to 1 IO range and 3 mem arch/powerpc/sysdev/fsl_pci.c +5
-1@@ -1,12 +1,16 @@/* * MPC83xx/85xx/86xx PCI/PCIE support routing. * -* Copyright 2007,2008 Freescale Semiconductor, Inc +* Copyright 2007-2009 Freescale Semiconductor, Inc. +* Copyright 2008-2009 MontaVista Software, Inc. * * Initial author: Xianghua Xiao <[email protected]> * Recode: ZHANG WEI <[email protected]> * Rewrite the routing for Frescale PCI and PCI Express * Roy Zang <[email protected]> +* MPC83xx PCI-Express support: +* Tony Li <[email protected]> +* Anton Vorontsov <[email protected]> * * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published
by thearch/powerpc/sysdev/fsl_pci.c +0
-1@@ -27,7 +31,6 @@#include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> -#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)/* atmu setup for fsl pci/pcie controller */ static void __init setup_pci_atmu (struct pci_controller *hose,struct resource *rsrc)
arch/powerpc/sysdev/fsl_pci.c int __init fsl_add_bridge(struct device_node · line 233
Quoted 3 lines
arch/powerpc/sysdev/fsl_pci.c +0
-0@@ -228,6 +231,14 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)return 0 ; }
I might just be missing the ctx in the patch, but is there a reason to expose setup_pci_atmu() on 83xx?
Quoted 20 lines
arch/powerpc/sysdev/fsl_pci.c +4
-0+DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8314E , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8314 , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8315E , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315,
quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8377E,quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8377,quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8378E,quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957,PCI_DEVICE_ID_MPC8378,quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_header);
arch/powerpc/sysdev/fsl_pci.c DECLARE_PCI_FIXUP_HEADER(0x1957, · line 267
Quoted 8 lines
arch/powerpc/sysdev/fsl_pci.c +1
-1@@ -250,9 +261,169 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8641 , quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8641D , quirk_fsl_pcie_header);DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8610 , quirk_fsl_pcie_header); -#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */ #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) +struct mpc83xx_pcie {
should probably be something like struct pcie_window {
Quoted 229 lines
arch/powerpc/sysdev/fsl_pci.c +94
-0+void __iomem *cfg_map; +u32 dev_base; +}; + +/* +* With the convention of u-boot, the PCIE outbound window 0 serves +* as configuration transactions outbound. +*/ +#define PEX_OUTWIN0_TAL 0xCA8 +#define PEX_OUTWIN0_TAH 0xCAC + +static int mpc83xx_pcie_exclude_device (struct pci_bus *bus,unsigned int devfn) +{ +struct pci_controller *hose = bus->sysdata; + +if (hose->indirect_type &PPC_INDIRECT_TYPE_NO_PCIE_LINK ) +return PCIBIOS_DEVICE_NOT_FOUND ; +/* +* Workaround for the HW bug: for Type 0 configure transactions the +* PCI-E controller does not check the device number bits and just +* assumes that the device number bits are 0. +*/ +if (hose->indirect_type &PPC_INDIRECT_TYPE_MPC83XX_PCIE ) { +if (bus->number == hose->first_busno || + bus->primary == hose->first_busno) { +if (devfn &0xf8 ) +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 ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static void __iomem *mpc83xx_pcie_remap_cfg (struct pci_bus *bus, +unsigned int devfn,int offset) +{ +struct pci_controller *hose = bus->sysdata; +struct mpc83xx_pcie *pcie = hose->dn->data; +u8 bus_no = bus->number - hose->first_busno; +u32 dev_base = bus_no <<20 | devfn <<12 ; +int ret; + + ret =mpc83xx_pcie_exclude_device (bus, devfn); +if (ret) +return NULL ; + + offset &=0xfff ; + +if (hose->indirect_type &PPC_INDIRECT_TYPE_MPC83XX_PCIE ) { +/* Type 0 */ +if (bus->number == hose->first_busno) +return hose->cfg_data + offset; + } + +if (pcie->dev_base == dev_base) + goto mapped; + +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAL , dev_base); + + pcie->dev_base = dev_base; +mapped: +return pcie->cfg_map + offset; +} + +static int mpc83xx_pcie_read_config (struct pci_bus *bus,unsigned int devfn, +int offset,int len,u32 *val) +{ +void __iomem *cfg_addr; + + cfg_addr =mpc83xx_pcie_remap_cfg (bus, devfn, offset); +if (!cfg_addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +switch (len) { +case 1 : + *val =in_8 (cfg_addr); +break ; +case 2 : + *val =in_le16 (cfg_addr); +break ; +default : + *val =in_le32 (cfg_addr); +break ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsignedint devfn,
arch/powerpc/sysdev/fsl_pci.c +66
-0+ int offset, int len, u32 val) +{ + void __iomem *cfg_addr; + + cfg_addr =mpc83xx_pcie_remap_cfg (bus, devfn, offset); +if (!cfg_addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +switch (len) { +case 1 : +out_8 (cfg_addr, val); +break ; +case 2 : +out_le16 (cfg_addr, val); +break ; +default : +out_le32 (cfg_addr, val); +break ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static struct pci_ops mpc83xx_pcie_ops = { + mpc83xx_pcie_read_config, + mpc83xx_pcie_write_config, +}; + +static int __init mpc83xx_pcie_setup (struct pci_controller *hose, +struct resource *reg, +struct resource *cfg) +{ +struct mpc83xx_pcie *pcie; + + pcie =zalloc_maybe_bootmem (sizeof (*pcie),GFP_KERNEL ); +if (!pcie) +return -ENOMEM ; + + pcie->cfg_map =ioremap (cfg->start,0x1000 ); +if (!pcie->cfg_map) + goto err_cfg_map; + + hose->cfg_data =ioremap (reg->start,resource_size (reg)); +if (!hose->cfg_data) + goto err_cfg_data; + +WARN_ON (hose->dn->data); + hose->dn->data = pcie; + hose->indirect_type |=PPC_INDIRECT_TYPE_MPC83XX_PCIE ; + hose->ops = &mpc83xx_pcie_ops; + +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAH ,0 ); +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAL ,0 ); + +if (fsl_pcie_check_link (hose)) + hose->indirect_type |=PPC_INDIRECT_TYPE_NO_PCIE_LINK ; + +return 0 ; +err_cfg_data: +iounmap (pcie->cfg_map); +err_cfg_map: +kfree (pcie); +return -ENOMEM ; + +} +int
__initmpc83xx_add_bridge(struct device_node *dev){ int len;arch/powerpc/sysdev/fsl_pci.c +4
-0@@ -262,6 +433,10 @@ int __init mpc83xx_add_bridge(struct device_node *dev)const int *bus_range;int primary; +if (!of_device_is_available (dev)) { +pr_warning ("%s: disabled by the firmware.\n" , dev->full_name); +return -ENODEV ; + }pr_debug ("Adding PCI host bridge %s\n" , dev->full_name);/* Fetch host bridge registers address */arch/powerpc/sysdev/fsl_pci.c +10
-1@@ -309,7 +484,16 @@ int __init mpc83xx_add_bridge(struct device_node *dev) hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1 ] :0xff ; -setup_indirect_pci (hose, rsrc_cfg.start, rsrc_cfg.start +4 ,0 ); +if (of_device_is_compatible (dev,"fsl,mpc8314-pcie" )) { +int ret; + + ret =mpc83xx_pcie_setup (hose, &rsrc_reg, &rsrc_cfg); +if (ret) + goto err; + }else { +setup_indirect_pci (hose, rsrc_cfg.start, + rsrc_cfg.start +4 ,0 ); + } printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. ""Firmware bus number: %d->%d\n",arch/powerpc/sysdev/fsl_pci.c +3
-0@@ -324,5 +508,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)pci_process_bridge_OF_ranges (hose, dev, primary);return 0 ; +err: +pcibios_free_controller (hose); +return -ENOMEM ; }#endif /*
CONFIG_PPC_83xx*/include/linux/pci_ids.h +8
-0@@ -2209,6 +2209,14 @@#define PCI_DEVICE_ID_TDI_EHCI 0x0101#define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_DEVICE_ID_MPC8315E 0x00b4 +#define PCI_DEVICE_ID_MPC8315 0x00b5 +#define PCI_DEVICE_ID_MPC8314E 0x00b6 +#define PCI_DEVICE_ID_MPC8314 0x00b7 +#define PCI_DEVICE_ID_MPC8378E 0x00c4 +#define PCI_DEVICE_ID_MPC8378 0x00c5 +#define PCI_DEVICE_ID_MPC8377E 0x00c6 +#define PCI_DEVICE_ID_MPC8377 0x00c7#define PCI_DEVICE_ID_MPC8548E 0x0012#define PCI_DEVICE_ID_MPC8548 0x0013#define PCI_DEVICE_ID_MPC8543E 0x0014Signature · 1 line
1.5.6.5
PATCH v3 3/4 powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support
This patch adds support for PCI-Express controllers as found on the newer MPC83xx chips.
The work is loosely based on the Tony Li's patch[1], but unlike the original patch, this patch implements sliding window for the Type 1 transactions using outbound window translations, so we don't have to ioremap the whole PCI-E configuration space.
[1] http://ozlabs.org/pipermail/linuxppc-dev/2008-January/049028.html
---
On Tue, Dec 30, 2008 at 12:07:08PM -0600, Kumar Gala wrote:
[...]
Quoted 10 lines
arch/powerpc/include/asm/pci-bridge.h struct pci_controller { · line 135
Quoted 7 lines
arch/powerpc/include/asm/pci-bridge.h +1
-0@@ -132,6 +132,7 @@ struct pci_controller {#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 +#define PPC_INDIRECT_TYPE_MPC83XX_PCIE 0x00000040we are bastardizing
indirect_typew/this.
Quoted 3 lines
1. we just possibly rename this flags and have it generally available.
2. we should renamePPC_INDIRECT_TYPE_MPC83XX_PCIEto _BROKEN_....
3. add a comment about what the new type is for.
Ugh, the PPC_INDIRECT_TYPE_MPC83XX_PCIE is a relic from the original patch, when HW bug workaround was in the board file(s). Now we don't need it as raw read/write pci ops are per phb, thus we already know that this is mpc83xx pcie controller.
Even if we'll need this information at some point in the board files, we can just use of_device_is_compatible().
Thanks for catching this.
[...]
Quoted 11 lines
arch/powerpc/include/asm/pci-bridge.h int __init fsl_add_bridge(struct device_node · line 233
Quoted 8 lines
arch/powerpc/include/asm/pci-bridge.h +0
-1-#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)/* atmu setup for fsl pci/pcie controller */ static void __init setup_pci_atmu(struct pci_controller *hose,struct resource *rsrc)
arch/powerpc/include/asm/pci-bridge.h +0
-0@@ -228,6 +231,14 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)return 0 ; }I might just be missing the ctx in the patch, but is there a reason to expose
setup_pci_atmu()on 83xx?
No, we only need the fixups and fsl_pcie_check_link(). Though, I'll need to rearange the code to avoid new #ifdefs.
[...]
Quoted 4 lines
arch/powerpc/include/asm/pci-bridge.h int __init fsl_add_bridge(struct device_node · line 235
Quoted 2 lines
arch/powerpc/include/asm/pci-bridge.h +1
-0#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) +struct mpc83xx_pcie {should probably be something like struct
pcie_window{
Well, I'd like to avoid _window, this struct might not neccesary describe only cfg window. It's just a private struct for mpc83xx pcie nodes, alike to driver_data for full fledged devices.
But I agree that "mpc83xx_pcie" name might be confusing (i.e. it might look like the struct describes mpc83xx pcie registers). Let's call it struct mpc83xx_pcie_priv?
Thanks for review, new version is down below.
arch/powerpc/sysdev/fsl_pci.c | 234 ++++++++++++++++++++++++++++++++++++---- include/linux/pci_ids.h | 8 ++ 2 files changed, 218 insertions(+), 24 deletions(-)
arch/powerpc/sysdev/fsl_pci.c +210 -24
@@ -1,12 +1,16 @@/* * MPC83xx/85xx/86xx PCI/PCIE support routing. * -* Copyright 2007,2008 Freescale Semiconductor, Inc +* Copyright 2007-2009 Freescale Semiconductor, Inc. +* Copyright 2008-2009 MontaVista Software, Inc. * * Initial author: Xianghua Xiao <[email protected]> * Recode: ZHANG WEI <[email protected]> * Rewrite the routing for Frescale PCI and PCI Express * Roy Zang <[email protected]> +* MPC83xx PCI-Express support: +* Tony Li <[email protected]> +* Anton Vorontsov <[email protected]> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the
@@ -27,6 +31,29 @@#include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> +static int fsl_pcie_bus_fixup; + +static void __init quirk_fsl_pcie_header (struct pci_dev *dev) +{ +/* if we aren't a PCIe don't bother */ +if (!pci_find_capability (dev,PCI_CAP_ID_EXP )) +return ; + + dev->class =PCI_CLASS_BRIDGE_PCI <<8 ; + fsl_pcie_bus_fixup =1 ; +return ; +} + +static int __init fsl_pcie_check_link (struct pci_controller *hose) +{ +u32 val; + +early_read_config_dword (hose,0 ,0 ,PCIE_LTSSM , &val); +if (val <PCIE_LTSSM_L0 ) +return 1 ; +return 0 ; +} +#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)/* atmu setup for fsl pci/pcie controller */ static void __init setup_pci_atmu(struct pci_controller *hose,
@@ -118,28 +145,6 @@ static void __init setup_pci_pcsrbar(struct pci_controller *hose)#endif } -static int fsl_pcie_bus_fixup; - -static void __init quirk_fsl_pcie_header (struct pci_dev *dev) -{ -/* if we aren't a PCIe don't bother */ -if (!pci_find_capability (dev,PCI_CAP_ID_EXP )) -return ; - - dev->class =PCI_CLASS_BRIDGE_PCI <<8 ; - fsl_pcie_bus_fixup =1 ; -return ; -} - -static int __init fsl_pcie_check_link (struct pci_controller *hose) -{ -u32 val; -early_read_config_dword (hose,0 ,0 ,PCIE_LTSSM , &val); -if (val <PCIE_LTSSM_L0 ) -return 1 ; -return 0 ; -} -void fsl_pcibios_fixup_bus (struct pci_bus *bus) {struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
@@ -253,6 +258,171 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */ #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8314E , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8314 , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8315E , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8315 , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8377E , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8377 , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8378E , quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER (0x1957 ,PCI_DEVICE_ID_MPC8378 , quirk_fsl_pcie_header); + +struct mpc83xx_pcie_priv { +void __iomem *cfg_map; +u32 dev_base; +}; + +/* +* With the convention of u-boot, the PCIE outbound window 0 serves +* as configuration transactions outbound. +*/ +#define PEX_OUTWIN0_TAL 0xCA8 +#define PEX_OUTWIN0_TAH 0xCAC + +static int mpc83xx_pcie_exclude_device (struct pci_bus *bus,unsigned int devfn) +{ +struct pci_controller *hose = bus->sysdata; + +if (hose->indirect_type &PPC_INDIRECT_TYPE_NO_PCIE_LINK ) +return PCIBIOS_DEVICE_NOT_FOUND ; +/* +* Workaround for the HW bug: for Type 0 configure transactions the +* PCI-E controller does not check the device number bits and just +* assumes that the device number bits are 0. +*/ +if (bus->number == hose->first_busno || + bus->primary == hose->first_busno) { +if (devfn &0xf8 ) +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 ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static void __iomem *mpc83xx_pcie_remap_cfg (struct pci_bus *bus, +unsigned int devfn,int offset) +{ +struct pci_controller *hose = bus->sysdata; +struct mpc83xx_pcie_priv *pcie = hose->dn->data; +u8 bus_no = bus->number - hose->first_busno; +u32 dev_base = bus_no <<20 | devfn <<12 ; +int ret; + + ret =mpc83xx_pcie_exclude_device (bus, devfn); +if (ret) +return NULL ; + + offset &=0xfff ; + +/* Type 0 */ +if (bus->number == hose->first_busno) +return hose->cfg_data + offset; + +if (pcie->dev_base == dev_base) + goto mapped; + +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAL , dev_base); + + pcie->dev_base = dev_base; +mapped: +return pcie->cfg_map + offset; +} + +static int mpc83xx_pcie_read_config (struct pci_bus *bus,unsigned int devfn, +int offset,int len,u32 *val) +{ +void __iomem *cfg_addr; + + cfg_addr =mpc83xx_pcie_remap_cfg (bus, devfn, offset); +if (!cfg_addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +switch (len) { +case 1 : + *val =in_8 (cfg_addr); +break ; +case 2 : + *val =in_le16 (cfg_addr); +break ; +default : + *val =in_le32 (cfg_addr); +break ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static int mpc83xx_pcie_write_config (struct pci_bus *bus,unsigned int devfn, +int offset,int len,u32 val) +{ +void __iomem *cfg_addr; + + cfg_addr =mpc83xx_pcie_remap_cfg (bus, devfn, offset); +if (!cfg_addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +switch (len) { +case 1 : +out_8 (cfg_addr, val); +break ; +case 2 : +out_le16 (cfg_addr, val); +break ; +default : +out_le32 (cfg_addr, val); +break ; + } + +return PCIBIOS_SUCCESSFUL ; +} + +static struct pci_ops mpc83xx_pcie_ops = { + .read = mpc83xx_pcie_read_config, + .write = mpc83xx_pcie_write_config, +}; + +static int __init mpc83xx_pcie_setup (struct pci_controller *hose, +struct resource *reg, +struct resource *cfg) +{ +struct mpc83xx_pcie_priv *pcie; + + pcie =zalloc_maybe_bootmem (sizeof (*pcie),GFP_KERNEL ); +if (!pcie) +return -ENOMEM ; + + pcie->cfg_map =ioremap (cfg->start,0x1000 ); +if (!pcie->cfg_map) + goto err_cfg_map; + + hose->cfg_data =ioremap (reg->start,resource_size (reg)); +if (!hose->cfg_data) + goto err_cfg_data; + +WARN_ON (hose->dn->data); + hose->dn->data = pcie; + hose->ops = &mpc83xx_pcie_ops; + +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAH ,0 ); +out_le32 (hose->cfg_data +PEX_OUTWIN0_TAL ,0 ); + +if (fsl_pcie_check_link (hose)) + hose->indirect_type |=PPC_INDIRECT_TYPE_NO_PCIE_LINK ; + +return 0 ; +err_cfg_data: +iounmap (pcie->cfg_map); +err_cfg_map: +kfree (pcie); +return -ENOMEM ; + +} +int __init mpc83xx_add_bridge (struct device_node *dev) {int len;
@@ -262,6 +432,10 @@ int __init mpc83xx_add_bridge(struct device_node *dev)const int *bus_range;int primary; +if (!of_device_is_available (dev)) { +pr_warning ("%s: disabled by the firmware.\n" , dev->full_name); +return -ENODEV ; + }pr_debug ("Adding PCI host bridge %s\n" , dev->full_name);/* Fetch host bridge registers address */
@@ -309,7 +483,16 @@ int __init mpc83xx_add_bridge(struct device_node *dev) hose->first_busno = bus_range ? bus_range[0 ] :0 ; hose->last_busno = bus_range ? bus_range[1 ] :0xff ; -setup_indirect_pci (hose, rsrc_cfg.start, rsrc_cfg.start +4 ,0 ); +if (of_device_is_compatible (dev,"fsl,mpc8314-pcie" )) { +int ret; + + ret =mpc83xx_pcie_setup (hose, &rsrc_reg, &rsrc_cfg); +if (ret) + goto err; + }else { +setup_indirect_pci (hose, rsrc_cfg.start, + rsrc_cfg.start +4 ,0 ); + } printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n",
@@ -324,5 +507,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)pci_process_bridge_OF_ranges (hose, dev, primary);return 0 ; +err: +pcibios_free_controller (hose); + return -ENOMEM; }#endif /* CONFIG_PPC_83xx */
include/linux/pci_ids.h +8 -0
@@ -2209,6 +2209,14 @@#define PCI_DEVICE_ID_TDI_EHCI 0x0101#define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_DEVICE_ID_MPC8315E 0x00b4 +#define PCI_DEVICE_ID_MPC8315 0x00b5 +#define PCI_DEVICE_ID_MPC8314E 0x00b6 +#define PCI_DEVICE_ID_MPC8314 0x00b7 +#define PCI_DEVICE_ID_MPC8378E 0x00c4 +#define PCI_DEVICE_ID_MPC8378 0x00c5 +#define PCI_DEVICE_ID_MPC8377E 0x00c6 +#define PCI_DEVICE_ID_MPC8377 0x00c7#define PCI_DEVICE_ID_MPC8548E 0x0012#define PCI_DEVICE_ID_MPC8548 0x0013#define PCI_DEVICE_ID_MPC8543E 0x0014
Signature · 1 line
1.5.6.5
RE: [PATCH v2 3/4] powerpc/fsl_pci: Add MPC83xx PCI-E controller RCmode support
In reply to Anton VorontsovReview
Quoted 7 lines
(quoted diff) +7
-0+static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, + unsigned int devfn, int offset) +{ + struct pci_controller *hose =3D bus->sysdata; + struct mpc83xx_pcie *pcie =3D hose->dn->data; + u8 bus_no =3D bus->number - hose->first_busno; + u32 dev_base =3D bus_no << 20 | devfn << 12;
Hello Anton,
There is one bug for the bus/device number shift according to the latest 83xx UM. The shift should be
dev_base =3D (bus_no << 24) | (devfn << 16);
You can download the latest MPC8315 UM as reference from
http://www.freescale.com.
AFAIK, you will work on the u-boot for 83xx PEX, Any question forward to Jerry Huang (in cc). I think he should have some update for PEX.
Thanks,
Dave
Re: [PATCH v2 3/4] powerpc/fsl_pci: Add MPC83xx PCI-E controller RCmode support
kindly unsubscribe me from this mailing list.
Re: [PATCH v2 3/4] powerpc/fsl_pci: Add MPC83xx PCI-E controller RCmode support
In reply to Liu DaveQuoted 10 lines · Liu Dave
arch/powerpc/sysdev/fsl_pci.c DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header); · line 311
Quoted 7 lines
arch/powerpc/sysdev/fsl_pci.c +7
-0+static void __iomem *mpc83xx_pcie_remap_cfg (struct pci_bus *bus, +unsigned int devfn,int offset) +{ +struct pci_controller *hose = bus->sysdata; +struct mpc83xx_pcie *pcie = hose->dn->data; +u8 bus_no = bus->number - hose->first_busno; +u32 dev_base = bus_no <<20 | devfn <<12 ;Hello Anton,
Quoted 7 lines
There is one bug for the bus/device number shift according to the latest 83xx UM. The shift should be
dev_base= (bus_no<< 24) | (devfn << 16);You can download the latest MPC8315 UM as reference from
http://www.freescale.com.
Ah! Thanks a lot, that explains a lot.
I was quite puzzled why FSL u-boots are using "wrong" shifts, so I "corrected" them. And indeed, I was looking at the old reference
manual: MPC8315ERM Rev. 0 09/2007. The new manual (MPC8315ERM
Rev. 1 2/2008) specifies other bits, the same as used in the FSL
U-Boot, i.e. 31:24 for bus no, 23:19 and 18:16 for device and func.
Quoted 2 lines
AFAIK, you will work on the u-boot for 83xx PEX, Any question forward to Jerry Huang (in cc). I think he should have some update for PEX.
Much thanks for the information,
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2