]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm/mach-cns3xxx/pcie.c
Merge remote-tracking branch 'samsung/for-next'
[karo-tx-linux.git] / arch / arm / mach-cns3xxx / pcie.c
index c622c306c390719f95cfac1eb8b3eff46f38c340..47905a50e0757e94c1300ec98a3924d9a51b7a5b 100644 (file)
@@ -65,8 +65,9 @@ static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus,
 
        /*
         * The CNS PCI bridge doesn't fit into the PCI hierarchy, though
-        * we still want to access it. For this to work, we must place
-        * the first device on the same bus as the CNS PCI bridge.
+        * we still want to access it.
+        * We place the host bridge on bus 0, and the directly connected
+        * device on bus 1, slot 0.
         */
        if (busno == 0) { /* internal PCIe bus, host bridge device */
                if (devfn == 0) /* device# and function# are ignored by hw */
@@ -211,58 +212,46 @@ static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
        }
 }
 
+static void cns3xxx_write_config(struct cns3xxx_pcie *cnspci,
+                                        int where, int size, u32 val)
+{
+       void __iomem *base = cnspci->host_regs + (where & 0xffc);
+       u32 v;
+       u32 mask = (0x1ull << (size * 8)) - 1;
+       int shift = (where % 4) * 8;
+
+       v = readl_relaxed(base + (where & 0xffc));
+
+       v &= ~(mask << shift);
+       v |= (val & mask) << shift;
+
+       writel_relaxed(v, base + (where & 0xffc));
+       readl_relaxed(base + (where & 0xffc));
+}
+
 static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
 {
-       int port = cnspci->port;
-       struct pci_sys_data sd = {
-               .private_data = cnspci,
-       };
-       struct pci_bus bus = {
-               .number = 0,
-               .ops = &cns3xxx_pcie_ops,
-               .sysdata = &sd,
-       };
        u16 mem_base  = cnspci->res_mem.start >> 16;
        u16 mem_limit = cnspci->res_mem.end   >> 16;
        u16 io_base   = cnspci->res_io.start  >> 16;
        u16 io_limit  = cnspci->res_io.end    >> 16;
-       u32 devfn = 0;
-       u8 tmp8;
-       u16 pos;
-       u16 dc;
-
-       pci_bus_write_config_byte(&bus, devfn, PCI_PRIMARY_BUS, 0);
-       pci_bus_write_config_byte(&bus, devfn, PCI_SECONDARY_BUS, 1);
-       pci_bus_write_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, 1);
 
-       pci_bus_read_config_byte(&bus, devfn, PCI_PRIMARY_BUS, &tmp8);
-       pci_bus_read_config_byte(&bus, devfn, PCI_SECONDARY_BUS, &tmp8);
-       pci_bus_read_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, &tmp8);
-
-       pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_BASE, mem_base);
-       pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, mem_limit);
-       pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base);
-       pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, io_limit);
+       cns3xxx_write_config(cnspci, PCI_PRIMARY_BUS, 1, 0);
+       cns3xxx_write_config(cnspci, PCI_SECONDARY_BUS, 1, 1);
+       cns3xxx_write_config(cnspci, PCI_SUBORDINATE_BUS, 1, 1);
+       cns3xxx_write_config(cnspci, PCI_MEMORY_BASE, 2, mem_base);
+       cns3xxx_write_config(cnspci, PCI_MEMORY_LIMIT, 2, mem_limit);
+       cns3xxx_write_config(cnspci, PCI_IO_BASE_UPPER16, 2, io_base);
+       cns3xxx_write_config(cnspci, PCI_IO_LIMIT_UPPER16, 2, io_limit);
 
        if (!cnspci->linked)
                return;
 
        /* Set Device Max_Read_Request_Size to 128 byte */
-       bus.number = 1; /* directly connected PCIe device */
-       devfn = PCI_DEVFN(0, 0);
-       pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
-       pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
-       if (dc & PCI_EXP_DEVCTL_READRQ) {
-               dc &= ~PCI_EXP_DEVCTL_READRQ;
-               pci_bus_write_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, dc);
-               pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
-               if (dc & PCI_EXP_DEVCTL_READRQ)
-                       pr_warn("PCIe: Unable to set device Max_Read_Request_Size\n");
-               else
-                       pr_info("PCIe: Max_Read_Request_Size set to 128 bytes\n");
-       }
+       pcie_bus_config = PCIE_BUS_PEER2PEER;
+
        /* Disable PCIe0 Interrupt Mask INTA to INTD */
-       __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(port));
+       __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(cnspci->port));
 }
 
 static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,