global: Migrate CONFIG_SYS_FSL* symbols to the CFG_SYS namespace
[platform/kernel/u-boot.git] / drivers / pci / pcie_fsl.c
index 1be5063..a8f8c31 100644 (file)
 #include <pci.h>
 #include <asm/fsl_pci.h>
 #include <asm/fsl_serdes.h>
+#include <asm/global_data.h>
 #include <asm/io.h>
+#include <linux/delay.h>
 #include "pcie_fsl.h"
+#include <dm/device_compat.h>
 
 LIST_HEAD(fsl_pcie_list);
 
@@ -27,22 +30,22 @@ static int fsl_pcie_addr_valid(struct fsl_pcie *pcie, pci_dev_t bdf)
        if (!pcie->enabled)
                return -ENXIO;
 
-       if (PCI_BUS(bdf) < bus->seq)
+       if (PCI_BUS(bdf) < dev_seq(bus))
                return -EINVAL;
 
-       if (PCI_BUS(bdf) > bus->seq && (!fsl_pcie_link_up(pcie) || pcie->mode))
+       if (PCI_BUS(bdf) > dev_seq(bus) && (!fsl_pcie_link_up(pcie) || pcie->mode))
                return -EINVAL;
 
-       if (PCI_BUS(bdf) == bus->seq && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
+       if (PCI_BUS(bdf) == dev_seq(bus) && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
                return -EINVAL;
 
-       if (PCI_BUS(bdf) == (bus->seq + 1) && (PCI_DEV(bdf) > 0))
+       if (PCI_BUS(bdf) == (dev_seq(bus) + 1) && (PCI_DEV(bdf) > 0))
                return -EINVAL;
 
        return 0;
 }
 
-static int fsl_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
+static int fsl_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
                                uint offset, ulong *valuep,
                                enum pci_size_t size)
 {
@@ -55,8 +58,9 @@ static int fsl_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
                return 0;
        }
 
-       bdf = bdf - PCI_BDF(bus->seq, 0, 0);
-       val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
+       val = PCI_CONF1_EXT_ADDRESS(PCI_BUS(bdf) - dev_seq(bus),
+                                   PCI_DEV(bdf), PCI_FUNC(bdf),
+                                   offset);
        out_be32(&regs->cfg_addr, val);
 
        sync();
@@ -91,8 +95,9 @@ static int fsl_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
        if (fsl_pcie_addr_valid(pcie, bdf))
                return 0;
 
-       bdf = bdf - PCI_BDF(bus->seq, 0, 0);
-       val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
+       val = PCI_CONF1_EXT_ADDRESS(PCI_BUS(bdf) - dev_seq(bus),
+                                   PCI_DEV(bdf), PCI_FUNC(bdf),
+                                   offset);
        out_be32(&regs->cfg_addr, val);
 
        sync();
@@ -121,7 +126,7 @@ static int fsl_pcie_hose_read_config(struct fsl_pcie *pcie, uint offset,
        int ret;
        struct udevice *bus = pcie->bus;
 
-       ret = fsl_pcie_read_config(bus, PCI_BDF(bus->seq, 0, 0),
+       ret = fsl_pcie_read_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
                                   offset, valuep, size);
 
        return ret;
@@ -132,7 +137,7 @@ static int fsl_pcie_hose_write_config(struct fsl_pcie *pcie, uint offset,
 {
        struct udevice *bus = pcie->bus;
 
-       return fsl_pcie_write_config(bus, PCI_BDF(bus->seq, 0, 0),
+       return fsl_pcie_write_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
                                     offset, value, size);
 }
 
@@ -394,6 +399,19 @@ static int fsl_pcie_init_atmu(struct fsl_pcie *pcie)
        return 0;
 }
 
+static void fsl_pcie_dbi_read_only_reg_write_enable(struct fsl_pcie *pcie,
+                                                   bool enable)
+{
+       u32 val;
+
+       fsl_pcie_hose_read_config_dword(pcie, DBI_RO_WR_EN, &val);
+       if (enable)
+               val |= 1;
+       else
+               val &= ~1;
+       fsl_pcie_hose_write_config_dword(pcie, DBI_RO_WR_EN, val);
+}
+
 static int fsl_pcie_init_port(struct fsl_pcie *pcie)
 {
        ccsr_fsl_pci_t *regs = pcie->regs;
@@ -445,7 +463,7 @@ static int fsl_pcie_init_port(struct fsl_pcie *pcie)
        if (!fsl_pcie_link_up(pcie)) {
                serdes_corenet_t *srds_regs;
 
-               srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
+               srds_regs = (void *)CFG_SYS_FSL_CORENET_SERDES_ADDR;
                val_32 = in_be32(&srds_regs->srdspccr0);
 
                if ((val_32 >> 28) == 3) {
@@ -468,7 +486,7 @@ static int fsl_pcie_init_port(struct fsl_pcie *pcie)
         * Set to 0 to protect the read-only registers.
         */
 #ifdef CONFIG_SYS_FSL_ERRATUM_A007815
-       clrbits_be32(&regs->dbi_ro_wr_en, 0x01);
+       fsl_pcie_dbi_read_only_reg_write_enable(pcie, false);
 #endif
 
        /*
@@ -502,24 +520,23 @@ static int fsl_pcie_init_port(struct fsl_pcie *pcie)
 
 static int fsl_pcie_fixup_classcode(struct fsl_pcie *pcie)
 {
-       ccsr_fsl_pci_t *regs = pcie->regs;
        u32 classcode_reg;
        u32 val;
 
        if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
                classcode_reg = PCI_CLASS_REVISION;
-               setbits_be32(&regs->dbi_ro_wr_en, 0x01);
+               fsl_pcie_dbi_read_only_reg_write_enable(pcie, true);
        } else {
                classcode_reg = CSR_CLASSCODE;
        }
 
        fsl_pcie_hose_read_config_dword(pcie, classcode_reg, &val);
        val &= 0xff;
-       val |= PCI_CLASS_BRIDGE_PCI << 16;
+       val |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8;
        fsl_pcie_hose_write_config_dword(pcie, classcode_reg, val);
 
        if (pcie->block_rev >= PEX_IP_BLK_REV_3_0)
-               clrbits_be32(&regs->dbi_ro_wr_en, 0x01);
+               fsl_pcie_dbi_read_only_reg_write_enable(pcie, false);
 
        return 0;
 }
@@ -579,9 +596,10 @@ static int fsl_pcie_probe(struct udevice *dev)
        return 0;
 }
 
-static int fsl_pcie_ofdata_to_platdata(struct udevice *dev)
+static int fsl_pcie_of_to_plat(struct udevice *dev)
 {
        struct fsl_pcie *pcie = dev_get_priv(dev);
+       struct fsl_pcie_data *info;
        int ret;
 
        pcie->regs = dev_remap_addr(dev);
@@ -596,7 +614,10 @@ static int fsl_pcie_ofdata_to_platdata(struct udevice *dev)
                return ret;
        }
 
-       pcie->idx = (dev_read_addr(dev) - 0xffe240000) / 0x10000;
+       info = (struct fsl_pcie_data *)dev_get_driver_data(dev);
+       pcie->info = info;
+       pcie->idx = abs((u32)(dev_read_addr(dev) & info->block_offset_mask) -
+                   info->block_offset) / info->stride;
 
        return 0;
 }
@@ -606,8 +627,35 @@ static const struct dm_pci_ops fsl_pcie_ops = {
        .write_config   = fsl_pcie_write_config,
 };
 
+static struct fsl_pcie_data p1_p2_data = {
+       .block_offset = 0xa000,
+       .block_offset_mask = 0xffff,
+       .stride = 0x1000,
+};
+
+static struct fsl_pcie_data p2041_data = {
+       .block_offset = 0x200000,
+       .block_offset_mask = 0x3fffff,
+       .stride = 0x1000,
+};
+
+static struct fsl_pcie_data t2080_data = {
+       .block_offset = 0x240000,
+       .block_offset_mask = 0x3fffff,
+       .stride = 0x10000,
+};
+
 static const struct udevice_id fsl_pcie_ids[] = {
-       { .compatible = "fsl,pcie-t2080" },
+       { .compatible = "fsl,mpc8548-pcie", .data = (ulong)&p1_p2_data },
+       { .compatible = "fsl,pcie-p1_p2", .data = (ulong)&p1_p2_data },
+       { .compatible = "fsl,pcie-p2041", .data = (ulong)&p2041_data },
+       { .compatible = "fsl,pcie-p3041", .data = (ulong)&p2041_data },
+       { .compatible = "fsl,pcie-p4080", .data = (ulong)&p2041_data },
+       { .compatible = "fsl,pcie-p5040", .data = (ulong)&p2041_data },
+       { .compatible = "fsl,pcie-t102x", .data = (ulong)&t2080_data },
+       { .compatible = "fsl,pcie-t104x", .data = (ulong)&t2080_data },
+       { .compatible = "fsl,pcie-t2080", .data = (ulong)&t2080_data },
+       { .compatible = "fsl,pcie-t4240", .data = (ulong)&t2080_data },
        { }
 };
 
@@ -616,7 +664,7 @@ U_BOOT_DRIVER(fsl_pcie) = {
        .id = UCLASS_PCI,
        .of_match = fsl_pcie_ids,
        .ops = &fsl_pcie_ops,
-       .ofdata_to_platdata = fsl_pcie_ofdata_to_platdata,
+       .of_to_plat = fsl_pcie_of_to_plat,
        .probe = fsl_pcie_probe,
-       .priv_auto_alloc_size = sizeof(struct fsl_pcie),
+       .priv_auto      = sizeof(struct fsl_pcie),
 };