* [PATCH v5 0/2] MPC83xx PCI-E support @ 2009-01-08 1:30 Anton Vorontsov 2009-01-08 1:31 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support Anton Vorontsov 2009-01-08 1:31 ` [PATCH 2/2] powerpc/83xx: Add PCI-E support for all MPC83xx boards with PCI-E Anton Vorontsov 0 siblings, 2 replies; 12+ messages in thread From: Anton Vorontsov @ 2009-01-08 1:30 UTC (permalink / raw) To: Kumar Gala; +Cc: Huang Changming, Liu Dave, linuxppc-dev Hi all, Here comes another revision... Changes since v4: - Corrected PCI-E ranges for MPC837x boards; - On MPC837XE-MDS boards PCIE2 can be disabled in favour of PCIE1 x2 mode, in that case U-Boot disables PCIE2 via status property. So, of_device_is_available() check is placed into mpc83xx_add_bridge(); - Rebased on top of galak/powerpc.git next. Changes since v3: - TAL register programming changed per new reference manual for 83xx processors; - dts files no longer specify config window in regs = <>. Instead, PCI-E code reads cfg window BAR to determine config space area; - dts files no longer disable pcie nodes, now Linux detects unconfigured PCI-E controllers at run-time. -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support 2009-01-08 1:30 [PATCH v5 0/2] MPC83xx PCI-E support Anton Vorontsov @ 2009-01-08 1:31 ` Anton Vorontsov 2009-01-08 6:50 ` Kumar Gala 2009-01-08 7:27 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC modesupport Liu Dave 2009-01-08 1:31 ` [PATCH 2/2] powerpc/83xx: Add PCI-E support for all MPC83xx boards with PCI-E Anton Vorontsov 1 sibling, 2 replies; 12+ messages in thread From: Anton Vorontsov @ 2009-01-08 1:31 UTC (permalink / raw) To: Kumar Gala; +Cc: Huang Changming, Liu Dave, linuxppc-dev 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 Signed-off-by: Tony Li <tony.li@freescale.com> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- arch/powerpc/sysdev/fsl_pci.c | 243 +++++++++++++++++++++++++++++++++++++---- include/linux/pci_ids.h | 8 ++ 2 files changed, 227 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 9817f63..68f8529 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -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 <x.xiao@freescale.com> * Recode: ZHANG WEI <wei.zhang@freescale.com> * Rewrite the routing for Frescale PCI and PCI Express * Roy Zang <tie-fei.zang@freescale.com> + * MPC83xx PCI-Express support: + * Tony Li <tony.li@freescale.com> + * Anton Vorontsov <avorontsov@ru.mvista.com> * * 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) static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, unsigned int index, const struct resource *res, @@ -159,28 +186,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; @@ -294,8 +299,183 @@ 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_BAR 0xCA4 +#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 << 24 | devfn << 16; + 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 mpc83xx_pcie_priv *pcie; + u32 cfg_bar; + int ret = -ENOMEM; + + pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return ret; + + hose->cfg_data = ioremap(reg->start, resource_size(reg)); + if (!hose->cfg_data) + goto err0; + + cfg_bar = in_le32(hose->cfg_data + PEX_OUTWIN0_BAR); + if (!cfg_bar) { + /* PCI-E isn't configured. */ + ret = -ENODEV; + goto err1; + } + + pcie->cfg_map = ioremap(cfg_bar, 0x1000); + if (!pcie->cfg_map) + goto err1; + + 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; +err1: + iounmap(hose->cfg_data); +err0: + kfree(pcie); + return ret; + +} + int __init mpc83xx_add_bridge(struct device_node *dev) { + int ret; int len; struct pci_controller *hose; struct resource rsrc_reg; @@ -303,6 +483,11 @@ 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 */ @@ -350,7 +535,14 @@ 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")) { + ret = mpc83xx_pcie_setup(hose, &rsrc_reg); + if (ret) + goto err0; + } 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", @@ -365,5 +557,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) pci_process_bridge_OF_ranges(hose, dev, primary); return 0; +err0: + pcibios_free_controller(hose); + return ret; } #endif /* CONFIG_PPC_83xx */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b6e6944..008c90d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -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 -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support 2009-01-08 1:31 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support Anton Vorontsov @ 2009-01-08 6:50 ` Kumar Gala 2009-01-08 19:10 ` Anton Vorontsov 2009-01-08 7:27 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC modesupport Liu Dave 1 sibling, 1 reply; 12+ messages in thread From: Kumar Gala @ 2009-01-08 6:50 UTC (permalink / raw) To: Anton Vorontsov; +Cc: Huang Changming, Liu Dave, linuxppc-dev > > +struct mpc83xx_pcie_priv { > + void __iomem *cfg_map; > + u32 dev_base; > +}; So was thinking about this and was wondering about doing the following: hose->cfg_addr /* use instead of dev_base to cache pci bus/dev/fn */ hose->cfg_data /* should be the outbound window used for pci cfg cycles */ hose->dn->data /* for IMMR regs to tweak window */ thoughts? Doing this means we should be able to get rid of struct mpc83xx_pcie_priv - k ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support 2009-01-08 6:50 ` Kumar Gala @ 2009-01-08 19:10 ` Anton Vorontsov 2009-01-08 19:24 ` Kumar Gala 0 siblings, 1 reply; 12+ messages in thread From: Anton Vorontsov @ 2009-01-08 19:10 UTC (permalink / raw) To: Kumar Gala; +Cc: Huang Changming, Liu Dave, linuxppc-dev On Thu, Jan 08, 2009 at 12:50:22AM -0600, Kumar Gala wrote: >> >> +struct mpc83xx_pcie_priv { >> + void __iomem *cfg_map; >> + u32 dev_base; >> +}; > > So was thinking about this and was wondering about doing the following: > > hose->cfg_addr /* use instead of dev_base to cache pci bus/dev/fn */ > hose->cfg_data /* should be the outbound window used for pci cfg cycles > */ > hose->dn->data /* for IMMR regs to tweak window */ > > thoughts? I don't quite like the casts that we'll need to do this. > Doing this means we should be able to get rid of struct > mpc83xx_pcie_priv Not sure what benefits this would bring? Saving few bytes of code and data at the cost of losing clean, cast-less, self documented code?.. I was actually thinking of getting rid of hose->cfg_data usage, and replacing it with mpc83xx_pci_priv->cfg_type0 (and rename mpc83xx_pci_priv->cfg_map to cfg_type1). OTOH, I can surely do that what you described, but to me it doesn't look like a great idea (i.e. using irrelevant struct members for hooking our data)... -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support 2009-01-08 19:10 ` Anton Vorontsov @ 2009-01-08 19:24 ` Kumar Gala 2009-01-08 21:55 ` [PATCH v6 " Anton Vorontsov 0 siblings, 1 reply; 12+ messages in thread From: Kumar Gala @ 2009-01-08 19:24 UTC (permalink / raw) To: avorontsov; +Cc: Huang Changming, Liu Dave, linuxppc-dev On Jan 8, 2009, at 1:10 PM, Anton Vorontsov wrote: > On Thu, Jan 08, 2009 at 12:50:22AM -0600, Kumar Gala wrote: >>> >>> +struct mpc83xx_pcie_priv { >>> + void __iomem *cfg_map; >>> + u32 dev_base; >>> +}; >> >> So was thinking about this and was wondering about doing the >> following: >> >> hose->cfg_addr /* use instead of dev_base to cache pci bus/dev/fn */ >> hose->cfg_data /* should be the outbound window used for pci cfg >> cycles >> */ >> hose->dn->data /* for IMMR regs to tweak window */ >> >> thoughts? > > I don't quite like the casts that we'll need to do this. > >> Doing this means we should be able to get rid of struct >> mpc83xx_pcie_priv > > Not sure what benefits this would bring? Saving few bytes of code and > data at the cost of losing clean, cast-less, self documented code?.. > > I was actually thinking of getting rid of hose->cfg_data usage, and > replacing it with mpc83xx_pci_priv->cfg_type0 (and rename > mpc83xx_pci_priv->cfg_map to cfg_type1). > > OTOH, I can surely do that what you described, but to me it doesn't > look like a great idea (i.e. using irrelevant struct members for > hooking our data)... I'm ok if you get rid of cfg_data usage.. than we aren't overloading the indirect variables for 83xx pci cfg cycles - k ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v6 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support 2009-01-08 19:24 ` Kumar Gala @ 2009-01-08 21:55 ` Anton Vorontsov 2009-01-09 0:17 ` Kumar Gala 0 siblings, 1 reply; 12+ messages in thread From: Anton Vorontsov @ 2009-01-08 21:55 UTC (permalink / raw) To: Kumar Gala; +Cc: Huang Changming, Liu Dave, linuxppc-dev 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 Signed-off-by: Tony Li <tony.li@freescale.com> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- On Thu, Jan 08, 2009 at 01:24:27PM -0600, Kumar Gala wrote: [...] > I'm ok if you get rid of cfg_data usage.. than we aren't overloading the > indirect variables for 83xx pci cfg cycles Here it is. Thanks, arch/powerpc/sysdev/fsl_pci.c | 244 +++++++++++++++++++++++++++++++++++++---- include/linux/pci_ids.h | 8 ++ 2 files changed, 228 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 9817f63..78021d8 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -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 <x.xiao@freescale.com> * Recode: ZHANG WEI <wei.zhang@freescale.com> * Rewrite the routing for Frescale PCI and PCI Express * Roy Zang <tie-fei.zang@freescale.com> + * MPC83xx PCI-Express support: + * Tony Li <tony.li@freescale.com> + * Anton Vorontsov <avorontsov@ru.mvista.com> * * 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) static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, unsigned int index, const struct resource *res, @@ -159,28 +186,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; @@ -294,8 +299,184 @@ 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_type0; + void __iomem *cfg_type1; + u32 dev_base; +}; + +/* + * With the convention of u-boot, the PCIE outbound window 0 serves + * as configuration transactions outbound. + */ +#define PEX_OUTWIN0_BAR 0xCA4 +#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 << 24 | devfn << 16; + int ret; + + ret = mpc83xx_pcie_exclude_device(bus, devfn); + if (ret) + return NULL; + + offset &= 0xfff; + + /* Type 0 */ + if (bus->number == hose->first_busno) + return pcie->cfg_type0 + offset; + + if (pcie->dev_base == dev_base) + goto mapped; + + out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, dev_base); + + pcie->dev_base = dev_base; +mapped: + return pcie->cfg_type1 + 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 mpc83xx_pcie_priv *pcie; + u32 cfg_bar; + int ret = -ENOMEM; + + pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return ret; + + pcie->cfg_type0 = ioremap(reg->start, resource_size(reg)); + if (!pcie->cfg_type0) + goto err0; + + cfg_bar = in_le32(pcie->cfg_type0 + PEX_OUTWIN0_BAR); + if (!cfg_bar) { + /* PCI-E isn't configured. */ + ret = -ENODEV; + goto err1; + } + + pcie->cfg_type1 = ioremap(cfg_bar, 0x1000); + if (!pcie->cfg_type1) + goto err1; + + WARN_ON(hose->dn->data); + hose->dn->data = pcie; + hose->ops = &mpc83xx_pcie_ops; + + out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0); + out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0); + + if (fsl_pcie_check_link(hose)) + hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; + + return 0; +err1: + iounmap(pcie->cfg_type0); +err0: + kfree(pcie); + return ret; + +} + int __init mpc83xx_add_bridge(struct device_node *dev) { + int ret; int len; struct pci_controller *hose; struct resource rsrc_reg; @@ -303,6 +484,11 @@ 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 */ @@ -350,7 +536,14 @@ 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")) { + ret = mpc83xx_pcie_setup(hose, &rsrc_reg); + if (ret) + goto err0; + } 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", @@ -365,5 +558,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) pci_process_bridge_OF_ranges(hose, dev, primary); return 0; +err0: + pcibios_free_controller(hose); + return ret; } #endif /* CONFIG_PPC_83xx */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b6e6944..008c90d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -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 -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v6 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support 2009-01-08 21:55 ` [PATCH v6 " Anton Vorontsov @ 2009-01-09 0:17 ` Kumar Gala 0 siblings, 0 replies; 12+ messages in thread From: Kumar Gala @ 2009-01-09 0:17 UTC (permalink / raw) To: avorontsov; +Cc: Huang Changming, Liu Dave, linuxppc-dev On Jan 8, 2009, at 3:55 PM, Anton Vorontsov wrote: > 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 > > Signed-off-by: Tony Li <tony.li@freescale.com> > Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> > --- > > On Thu, Jan 08, 2009 at 01:24:27PM -0600, Kumar Gala wrote: > [...] >> I'm ok if you get rid of cfg_data usage.. than we aren't >> overloading the >> indirect variables for 83xx pci cfg cycles > > Here it is. > > Thanks, > > arch/powerpc/sysdev/fsl_pci.c | 244 ++++++++++++++++++++++++++++++++ > +++++---- > include/linux/pci_ids.h | 8 ++ > 2 files changed, 228 insertions(+), 24 deletions(-) applied - k ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC modesupport 2009-01-08 1:31 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support Anton Vorontsov 2009-01-08 6:50 ` Kumar Gala @ 2009-01-08 7:27 ` Liu Dave 2009-01-08 20:59 ` Anton Vorontsov 1 sibling, 1 reply; 12+ messages in thread From: Liu Dave @ 2009-01-08 7:27 UTC (permalink / raw) To: Anton Vorontsov, Kumar Gala Cc: Huang Changming-R66093, Phillips Kim-R1AAHA, linuxppc-dev > +static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, > + unsigned int devfn,=20 [snip] > + if (pcie->dev_base =3D=3D dev_base) > + goto mapped; > + > + out_le32(hose->cfg_data + PEX_OUTWIN0_TAL, dev_base); > + > + pcie->dev_base =3D dev_base; Do we need local_irq_save/local_irq_restore between them? out_le32(PEX_OUTWIN0_TAL,...) and pcie->dev_base =3D dev_base; > +mapped: > + return pcie->cfg_map + offset; > +} ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC modesupport 2009-01-08 7:27 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC modesupport Liu Dave @ 2009-01-08 20:59 ` Anton Vorontsov 0 siblings, 0 replies; 12+ messages in thread From: Anton Vorontsov @ 2009-01-08 20:59 UTC (permalink / raw) To: Liu Dave; +Cc: Huang Changming-R66093, Phillips Kim-R1AAHA, linuxppc-dev On Thu, Jan 08, 2009 at 03:27:10PM +0800, Liu Dave wrote: > > +static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, > > + unsigned int devfn, > > [snip] > > > + if (pcie->dev_base == dev_base) > > + goto mapped; > > + > > + out_le32(hose->cfg_data + PEX_OUTWIN0_TAL, dev_base); > > + > > + pcie->dev_base = dev_base; > > Do we need local_irq_save/local_irq_restore between them? No, I don't think we need it. drivers/pci/access.c hold an irqsave spinlock for ->read and ->write callbacks. > out_le32(PEX_OUTWIN0_TAL,...) and pcie->dev_base = dev_base; > > +mapped: > > + return pcie->cfg_map + offset; > > +} Thanks, -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/2] powerpc/83xx: Add PCI-E support for all MPC83xx boards with PCI-E 2009-01-08 1:30 [PATCH v5 0/2] MPC83xx PCI-E support Anton Vorontsov 2009-01-08 1:31 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support Anton Vorontsov @ 2009-01-08 1:31 ` Anton Vorontsov 2009-01-09 0:17 ` Kumar Gala 1 sibling, 1 reply; 12+ messages in thread From: Anton Vorontsov @ 2009-01-08 1:31 UTC (permalink / raw) To: Kumar Gala; +Cc: Huang Changming, Liu Dave, linuxppc-dev This patch adds pcie nodes to the appropriate dts files, plus adds some probing code for the boards. Also, remove of_device_is_avaliable() check from the mpc837x_mds.c board file, as mpc83xx_add_bridge() has the same check now. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- arch/powerpc/boot/dts/mpc8315erdb.dts | 64 +++++++++++++++++++++++++++++ arch/powerpc/boot/dts/mpc8377_mds.dts | 64 +++++++++++++++++++++++++++++ arch/powerpc/boot/dts/mpc8377_rdb.dts | 64 +++++++++++++++++++++++++++++ arch/powerpc/boot/dts/mpc8378_mds.dts | 64 +++++++++++++++++++++++++++++ arch/powerpc/boot/dts/mpc8378_rdb.dts | 64 +++++++++++++++++++++++++++++ arch/powerpc/platforms/83xx/mpc831x_rdb.c | 2 + arch/powerpc/platforms/83xx/mpc837x_mds.c | 10 +--- arch/powerpc/platforms/83xx/mpc837x_rdb.c | 2 + 8 files changed, 327 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 072c9b0..9a4fa2a 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -22,6 +22,8 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; }; cpus { @@ -349,4 +351,66 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; + + pci1: pcie@e0009000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie"; + reg = <0xe0009000 0x00001000>; + ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 + 0x01000000 0 0x00000000 0xb1000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 1 8 + 0 0 0 2 &ipic 1 8 + 0 0 0 3 &ipic 1 8 + 0 0 0 4 &ipic 1 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xa0000000 + 0x02000000 0 0xa0000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; + + pci2: pcie@e000a000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie"; + reg = <0xe000a000 0x00001000>; + ranges = <0x02000000 0 0xc0000000 0xc0000000 0 0x10000000 + 0x01000000 0 0x00000000 0xd1000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 2 8 + 0 0 0 2 &ipic 2 8 + 0 0 0 3 &ipic 2 8 + 0 0 0 4 &ipic 2 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xc0000000 + 0x02000000 0 0xc0000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; }; diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts index 1d14d70..a519e85 100644 --- a/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -23,6 +23,8 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; }; cpus { @@ -409,4 +411,66 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; + + pci1: pcie@e0009000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; + reg = <0xe0009000 0x00001000>; + ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 1 8 + 0 0 0 2 &ipic 1 8 + 0 0 0 3 &ipic 1 8 + 0 0 0 4 &ipic 1 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xa8000000 + 0x02000000 0 0xa8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; + + pci2: pcie@e000a000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; + reg = <0xe000a000 0x00001000>; + ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 2 8 + 0 0 0 2 &ipic 2 8 + 0 0 0 3 &ipic 2 8 + 0 0 0 4 &ipic 2 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xc8000000 + 0x02000000 0 0xc8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; }; diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 9413af3..b4ab3d0 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -22,6 +22,8 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; }; cpus { @@ -350,4 +352,66 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; + + pci1: pcie@e0009000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; + reg = <0xe0009000 0x00001000>; + ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 1 8 + 0 0 0 2 &ipic 1 8 + 0 0 0 3 &ipic 1 8 + 0 0 0 4 &ipic 1 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xa8000000 + 0x02000000 0 0xa8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; + + pci2: pcie@e000a000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; + reg = <0xe000a000 0x00001000>; + ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 2 8 + 0 0 0 2 &ipic 2 8 + 0 0 0 3 &ipic 2 8 + 0 0 0 4 &ipic 2 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xc8000000 + 0x02000000 0 0xc8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; }; diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts index b85fc02..6bbee49 100644 --- a/arch/powerpc/boot/dts/mpc8378_mds.dts +++ b/arch/powerpc/boot/dts/mpc8378_mds.dts @@ -23,6 +23,8 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; }; cpus { @@ -395,4 +397,66 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; + + pci1: pcie@e0009000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; + reg = <0xe0009000 0x00001000>; + ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 1 8 + 0 0 0 2 &ipic 1 8 + 0 0 0 3 &ipic 1 8 + 0 0 0 4 &ipic 1 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xa8000000 + 0x02000000 0 0xa8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; + + pci2: pcie@e000a000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; + reg = <0xe000a000 0x00001000>; + ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 2 8 + 0 0 0 2 &ipic 2 8 + 0 0 0 3 &ipic 2 8 + 0 0 0 4 &ipic 2 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xc8000000 + 0x02000000 0 0xc8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; }; diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index 23c10ce..1b05fb0 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -22,6 +22,8 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; }; cpus { @@ -334,4 +336,66 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; + + pci1: pcie@e0009000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; + reg = <0xe0009000 0x00001000>; + ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 1 8 + 0 0 0 2 &ipic 1 8 + 0 0 0 3 &ipic 1 8 + 0 0 0 4 &ipic 1 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xa8000000 + 0x02000000 0 0xa8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; + + pci2: pcie@e000a000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; + reg = <0xe000a000 0x00001000>; + ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 + 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; + bus-range = <0 255>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0 0 0 1 &ipic 2 8 + 0 0 0 2 &ipic 2 8 + 0 0 0 3 &ipic 2 8 + 0 0 0 4 &ipic 2 8>; + clock-frequency = <0>; + + pcie@0 { + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + reg = <0 0 0 0 0>; + ranges = <0x02000000 0 0xc8000000 + 0x02000000 0 0xc8000000 + 0 0x10000000 + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00800000>; + }; + }; }; diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index 5177bdd..b690fd7 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -38,6 +38,8 @@ static void __init mpc831x_rdb_setup_arch(void) #ifdef CONFIG_PCI for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") mpc83xx_add_bridge(np); + for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") + mpc83xx_add_bridge(np); #endif mpc831x_usb_cfg(); } diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 530ef99..634785c 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -84,14 +84,10 @@ static void __init mpc837x_mds_setup_arch(void) ppc_md.progress("mpc837x_mds_setup_arch()", 0); #ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") { - if (!of_device_is_available(np)) { - pr_warning("%s: disabled by the firmware.\n", - np->full_name); - continue; - } + for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") + mpc83xx_add_bridge(np); + for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") mpc83xx_add_bridge(np); - } #endif mpc837xmds_usb_cfg(); } diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 1d09654..3d7b953 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -38,6 +38,8 @@ static void __init mpc837x_rdb_setup_arch(void) #ifdef CONFIG_PCI for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") mpc83xx_add_bridge(np); + for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") + mpc83xx_add_bridge(np); #endif mpc837x_usb_cfg(); } -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] powerpc/83xx: Add PCI-E support for all MPC83xx boards with PCI-E 2009-01-08 1:31 ` [PATCH 2/2] powerpc/83xx: Add PCI-E support for all MPC83xx boards with PCI-E Anton Vorontsov @ 2009-01-09 0:17 ` Kumar Gala 0 siblings, 0 replies; 12+ messages in thread From: Kumar Gala @ 2009-01-09 0:17 UTC (permalink / raw) To: Anton Vorontsov; +Cc: Huang Changming, Liu Dave, linuxppc-dev On Jan 7, 2009, at 7:31 PM, Anton Vorontsov wrote: > This patch adds pcie nodes to the appropriate dts files, plus adds > some probing code for the boards. > > Also, remove of_device_is_avaliable() check from the mpc837x_mds.c > board file, as mpc83xx_add_bridge() has the same check now. > > Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> > --- > arch/powerpc/boot/dts/mpc8315erdb.dts | 64 ++++++++++++++++++++ > +++++++++ > arch/powerpc/boot/dts/mpc8377_mds.dts | 64 ++++++++++++++++++++ > +++++++++ > arch/powerpc/boot/dts/mpc8377_rdb.dts | 64 ++++++++++++++++++++ > +++++++++ > arch/powerpc/boot/dts/mpc8378_mds.dts | 64 ++++++++++++++++++++ > +++++++++ > arch/powerpc/boot/dts/mpc8378_rdb.dts | 64 ++++++++++++++++++++ > +++++++++ > arch/powerpc/platforms/83xx/mpc831x_rdb.c | 2 + > arch/powerpc/platforms/83xx/mpc837x_mds.c | 10 +--- > arch/powerpc/platforms/83xx/mpc837x_rdb.c | 2 + > 8 files changed, 327 insertions(+), 7 deletions(-) applied - k ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 0/2] MPC83xx PCI-E support @ 2009-01-05 17:40 Anton Vorontsov 2009-01-05 17:41 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support Anton Vorontsov 0 siblings, 1 reply; 12+ messages in thread From: Anton Vorontsov @ 2009-01-05 17:40 UTC (permalink / raw) To: Kumar Gala; +Cc: Huang Changming, Liu Dave, linuxppc-dev Hi all, Thanks for the comments on the previous versions, and here is the updated patch set to support PCI-E on MPC83xx boards. Changes since v3: - TAL register programming changed per new reference manual for 83xx processors; - dts files no longer specify config window in regs = <>. Instead, PCI-E code reads cfg window BAR to determine config space area; - dts files no longer disable pcie nodes, now Linux detects unconfigured PCI-E controllers at run-time. -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support 2009-01-05 17:40 [PATCH v4 0/2] MPC83xx PCI-E support Anton Vorontsov @ 2009-01-05 17:41 ` Anton Vorontsov 0 siblings, 0 replies; 12+ messages in thread From: Anton Vorontsov @ 2009-01-05 17:41 UTC (permalink / raw) To: Kumar Gala; +Cc: Huang Changming, Liu Dave, linuxppc-dev 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 Signed-off-by: Tony Li <tony.li@freescale.com> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- arch/powerpc/sysdev/fsl_pci.c | 238 ++++++++++++++++++++++++++++++++++++---- include/linux/pci_ids.h | 8 ++ 2 files changed, 222 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index f611d03..c934485 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -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 <x.xiao@freescale.com> * Recode: ZHANG WEI <wei.zhang@freescale.com> * Rewrite the routing for Frescale PCI and PCI Express * Roy Zang <tie-fei.zang@freescale.com> + * MPC83xx PCI-Express support: + * Tony Li <tony.li@freescale.com> + * Anton Vorontsov <avorontsov@ru.mvista.com> * * 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,8 +258,183 @@ 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_BAR 0xCA4 +#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 << 24 | devfn << 16; + 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 mpc83xx_pcie_priv *pcie; + u32 cfg_bar; + int ret = -ENOMEM; + + pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return ret; + + hose->cfg_data = ioremap(reg->start, resource_size(reg)); + if (!hose->cfg_data) + goto err0; + + cfg_bar = in_le32(hose->cfg_data + PEX_OUTWIN0_BAR); + if (!cfg_bar) { + /* PCI-E isn't configured. */ + ret = -ENODEV; + goto err1; + } + + pcie->cfg_map = ioremap(cfg_bar, 0x1000); + if (!pcie->cfg_map) + goto err1; + + 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; +err1: + iounmap(hose->cfg_data); +err0: + kfree(pcie); + return ret; + +} + int __init mpc83xx_add_bridge(struct device_node *dev) { + int ret; int len; struct pci_controller *hose; struct resource rsrc_reg; @@ -309,7 +489,14 @@ 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")) { + ret = mpc83xx_pcie_setup(hose, &rsrc_reg); + if (ret) + goto err0; + } 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 +511,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) pci_process_bridge_OF_ranges(hose, dev, primary); return 0; +err0: + pcibios_free_controller(hose); + return ret; } #endif /* CONFIG_PPC_83xx */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b6e6944..008c90d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -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 -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2009-01-09 0:19 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-01-08 1:30 [PATCH v5 0/2] MPC83xx PCI-E support Anton Vorontsov 2009-01-08 1:31 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support Anton Vorontsov 2009-01-08 6:50 ` Kumar Gala 2009-01-08 19:10 ` Anton Vorontsov 2009-01-08 19:24 ` Kumar Gala 2009-01-08 21:55 ` [PATCH v6 " Anton Vorontsov 2009-01-09 0:17 ` Kumar Gala 2009-01-08 7:27 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC modesupport Liu Dave 2009-01-08 20:59 ` Anton Vorontsov 2009-01-08 1:31 ` [PATCH 2/2] powerpc/83xx: Add PCI-E support for all MPC83xx boards with PCI-E Anton Vorontsov 2009-01-09 0:17 ` Kumar Gala -- strict thread matches above, loose matches on Subject: below -- 2009-01-05 17:40 [PATCH v4 0/2] MPC83xx PCI-E support Anton Vorontsov 2009-01-05 17:41 ` [PATCH 1/2] powerpc/fsl_pci: Add MPC83xx PCI-E controller RC mode support Anton Vorontsov
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.