It appears that we wrongly calculate dev_base for type1 config cycles.
The thing is: we shouldn't subtract hose->first_busno because PCI core
sets PCI primary, secondary and subordinate bus numbers, and PCIe
controller actually takes the registers into account. So we should use
just bus->number.

Also, according to MPC8315 reference manual, primary bus number should
always remain 0. We have PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS quirk
in indirect_pci.c, but since 83xx is somewhat special, it doesn't use
indirect_pci.c routines, so we have to implement the quirk specifically
for 83xx PCIe controllers.

Signed-off-by: Anton Vorontsov <avoront...@ru.mvista.com>
---

This fixes the issue similar to http://www.pubbs.net/linuxppc/200908/22024/
i.e. lspci reports:

0000:00:00.0 Power PC: Freescale Semiconductor Inc Device 00b4 (rev 11)
0002:02:00.0 PCI bridge: Freescale Semiconductor Inc Device 00b4 (rev 11)
0002:03:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI 
Express-to-PCI Bridge (rev 03)
0002:04:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI 
Express-to-PCI Bridge (rev 03)
0002:04:01.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI 
Express-to-PCI Bridge (rev 03)
0002:04:02.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI 
Express-to-PCI Bridge (rev 03)
...

While it should be:

0000:00:00.0 Power PC: Freescale Semiconductor Inc Device 00b4 (rev 11)
0002:02:00.0 PCI bridge: Freescale Semiconductor Inc Device 00b4 (rev 11)
0002:03:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI 
Express-to-PCI Bridge (rev 03)
0002:04:00.0 VGA compatible controller: Matrox Graphics, Inc. MGA G550 AGP (rev 
01)

 arch/powerpc/sysdev/fsl_pci.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ae88b14..0c11aa6 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -450,8 +450,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus 
*bus,
 {
        struct pci_controller *hose = pci_bus_to_host(bus);
        struct mpc83xx_pcie_priv *pcie = hose->dn->data;
-       u8 bus_no = bus->number - hose->first_busno;
-       u32 dev_base = bus_no << 24 | devfn << 16;
+       u32 dev_base = bus->number << 24 | devfn << 16;
        int ret;
 
        ret = mpc83xx_pcie_exclude_device(bus, devfn);
@@ -501,12 +500,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, 
unsigned int devfn,
 static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
+       struct pci_controller *hose = pci_bus_to_host(bus);
        void __iomem *cfg_addr;
 
        cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
        if (!cfg_addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
+       /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
+       if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
+               val &= 0xffffff00;
+
        switch (len) {
        case 1:
                out_8(cfg_addr, val);
-- 
1.6.3.3
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to