diff options
Diffstat (limited to 'drivers/pci/pcie_fsl.c')
-rw-r--r-- | drivers/pci/pcie_fsl.c | 121 |
1 files changed, 82 insertions, 39 deletions
diff --git a/drivers/pci/pcie_fsl.c b/drivers/pci/pcie_fsl.c index 4d61a46cefb..ab25aeee731 100644 --- a/drivers/pci/pcie_fsl.c +++ b/drivers/pci/pcie_fsl.c @@ -299,8 +299,9 @@ static int fsl_pcie_setup_inbound_win(struct fsl_pcie *pcie, int idx, out_be32(&pi->piwbear, 0); #endif - if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_A005434)) - flag = 0; +#ifdef CONFIG_SYS_FSL_ERRATUM_A005434 + flag = 0; +#endif flag |= PIWAR_EN | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; if (pf) @@ -401,47 +402,47 @@ static int fsl_pcie_init_port(struct fsl_pcie *pcie) fsl_pcie_init_atmu(pcie); - if (IS_ENABLED(CONFIG_FSL_PCIE_DISABLE_ASPM)) { - val_32 = 0; - fsl_pcie_hose_read_config_dword(pcie, PCI_LCR, &val_32); - val_32 &= ~0x03; - fsl_pcie_hose_write_config_dword(pcie, PCI_LCR, val_32); - udelay(1); - } +#ifdef CONFIG_FSL_PCIE_DISABLE_ASPM + val_32 = 0; + fsl_pcie_hose_read_config_dword(pcie, PCI_LCR, &val_32); + val_32 &= ~0x03; + fsl_pcie_hose_write_config_dword(pcie, PCI_LCR, val_32); + udelay(1); +#endif - if (IS_ENABLED(CONFIG_FSL_PCIE_RESET)) { - u16 ltssm; - int i; +#ifdef CONFIG_FSL_PCIE_RESET + u16 ltssm; + int i; - if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) { + if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) { + /* assert PCIe reset */ + setbits_be32(®s->pdb_stat, 0x08000000); + (void)in_be32(®s->pdb_stat); + udelay(1000); + /* clear PCIe reset */ + clrbits_be32(®s->pdb_stat, 0x08000000); + asm("sync;isync"); + for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++) + udelay(1000); + } else { + fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, <ssm); + if (ltssm == 1) { /* assert PCIe reset */ setbits_be32(®s->pdb_stat, 0x08000000); (void)in_be32(®s->pdb_stat); - udelay(1000); + udelay(100); /* clear PCIe reset */ clrbits_be32(®s->pdb_stat, 0x08000000); asm("sync;isync"); - for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++) + for (i = 0; i < 100 && + !fsl_pcie_link_up(pcie); i++) udelay(1000); - } else { - fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, <ssm); - if (ltssm == 1) { - /* assert PCIe reset */ - setbits_be32(®s->pdb_stat, 0x08000000); - (void)in_be32(®s->pdb_stat); - udelay(100); - /* clear PCIe reset */ - clrbits_be32(®s->pdb_stat, 0x08000000); - asm("sync;isync"); - for (i = 0; i < 100 && - !fsl_pcie_link_up(pcie); i++) - udelay(1000); - } } } +#endif - if (IS_ENABLED(CONFIG_SYS_P4080_ERRATUM_PCIE_A003) && - !fsl_pcie_link_up(pcie)) { +#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003 + if (!fsl_pcie_link_up(pcie)) { serdes_corenet_t *srds_regs; srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; @@ -460,13 +461,15 @@ static int fsl_pcie_init_port(struct fsl_pcie *pcie) udelay(1000); } } +#endif /* * The Read-Only Write Enable bit defaults to 1 instead of 0. * Set to 0 to protect the read-only registers. */ - if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_A007815)) - clrbits_be32(®s->dbi_ro_wr_en, 0x01); +#ifdef CONFIG_SYS_FSL_ERRATUM_A007815 + clrbits_be32(®s->dbi_ro_wr_en, 0x01); +#endif /* * Enable All Error Interrupts except @@ -500,14 +503,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; - setbits_be32(®s->dbi_ro_wr_en, 0x01); - fsl_pcie_hose_read_config_dword(pcie, PCI_CLASS_REVISION, &val); + if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) { + classcode_reg = PCI_CLASS_REVISION; + setbits_be32(®s->dbi_ro_wr_en, 0x01); + } else { + classcode_reg = CSR_CLASSCODE; + } + + fsl_pcie_hose_read_config_dword(pcie, classcode_reg, &val); val &= 0xff; val |= PCI_CLASS_BRIDGE_PCI << 16; - fsl_pcie_hose_write_config_dword(pcie, PCI_CLASS_REVISION, val); - clrbits_be32(®s->dbi_ro_wr_en, 0x01); + fsl_pcie_hose_write_config_dword(pcie, classcode_reg, val); + + if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) + clrbits_be32(®s->dbi_ro_wr_en, 0x01); return 0; } @@ -570,6 +582,7 @@ static int fsl_pcie_probe(struct udevice *dev) static int fsl_pcie_ofdata_to_platdata(struct udevice *dev) { struct fsl_pcie *pcie = dev_get_priv(dev); + struct fsl_pcie_data *info; int ret; pcie->regs = dev_remap_addr(dev); @@ -584,7 +597,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; } @@ -594,8 +610,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,pcie-mpc8548", .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 }, { } }; |