powerpc/fsl-pci: Keep PCI SoC controller registers in pci_controller
Move to keeping the SoC registers that control and config the PCI controllers on FSL SoCs in the pci_controller struct. This allows us to not need to ioremap() the registers in multiple different places that use them. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
parent
9f4c350d52
commit
34642bbb3d
|
@ -70,6 +70,8 @@ struct pci_controller {
|
||||||
* BIG_ENDIAN - cfg_addr is a big endian register
|
* BIG_ENDIAN - cfg_addr is a big endian register
|
||||||
* BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
|
* BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
|
||||||
* the PLB4. Effectively disable MRM commands by setting this.
|
* the PLB4. Effectively disable MRM commands by setting this.
|
||||||
|
* FSL_CFG_REG_LINK - Freescale controller version in which the PCIe
|
||||||
|
* link status is in a RC PCIe cfg register (vs being a SoC register)
|
||||||
*/
|
*/
|
||||||
#define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
|
#define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
|
||||||
#define PPC_INDIRECT_TYPE_EXT_REG 0x00000002
|
#define PPC_INDIRECT_TYPE_EXT_REG 0x00000002
|
||||||
|
@ -77,6 +79,7 @@ struct pci_controller {
|
||||||
#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
|
#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
|
||||||
#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
|
#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
|
||||||
#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020
|
#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020
|
||||||
|
#define PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK 0x00000040
|
||||||
u32 indirect_type;
|
u32 indirect_type;
|
||||||
/* Currently, we limit ourselves to 1 IO range and 3 mem
|
/* Currently, we limit ourselves to 1 IO range and 3 mem
|
||||||
* ranges since the common pci_bus structure can't handle more
|
* ranges since the common pci_bus structure can't handle more
|
||||||
|
@ -90,9 +93,9 @@ struct pci_controller {
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
unsigned long buid;
|
unsigned long buid;
|
||||||
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
void *private_data;
|
void *private_data;
|
||||||
#endif /* CONFIG_PPC64 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These are used for config access before all the PCI probing
|
/* These are used for config access before all the PCI probing
|
||||||
|
|
|
@ -54,34 +54,22 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init fsl_pcie_check_link(struct pci_controller *hose,
|
static int __init fsl_pcie_check_link(struct pci_controller *hose)
|
||||||
struct resource *rsrc)
|
|
||||||
{
|
{
|
||||||
struct ccsr_pci __iomem *pci = NULL;
|
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
if (hose->indirect_type & PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
|
||||||
|
early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
|
||||||
|
if (val < PCIE_LTSSM_L0)
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
struct ccsr_pci __iomem *pci = hose->private_data;
|
||||||
/* for PCIe IP rev 3.0 or greater use CSR0 for link state */
|
/* for PCIe IP rev 3.0 or greater use CSR0 for link state */
|
||||||
if (rsrc) {
|
|
||||||
pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
|
|
||||||
(u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
|
|
||||||
pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
|
|
||||||
if (!pci) {
|
|
||||||
dev_err(hose->parent, "Unable to map PCIe registers\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_3_0) {
|
|
||||||
val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK)
|
val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK)
|
||||||
>> PEX_CSR0_LTSSM_SHIFT;
|
>> PEX_CSR0_LTSSM_SHIFT;
|
||||||
if (val != PEX_CSR0_LTSSM_L0)
|
if (val != PEX_CSR0_LTSSM_L0)
|
||||||
return 1;
|
return 1;
|
||||||
iounmap(pci);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
iounmap(pci);
|
|
||||||
}
|
|
||||||
early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
|
|
||||||
if (val < PCIE_LTSSM_L0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -148,10 +136,9 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* atmu setup for fsl pci/pcie controller */
|
/* atmu setup for fsl pci/pcie controller */
|
||||||
static void setup_pci_atmu(struct pci_controller *hose,
|
static void setup_pci_atmu(struct pci_controller *hose)
|
||||||
struct resource *rsrc)
|
|
||||||
{
|
{
|
||||||
struct ccsr_pci __iomem *pci;
|
struct ccsr_pci __iomem *pci = hose->private_data;
|
||||||
int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
|
int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
|
||||||
u64 mem, sz, paddr_hi = 0;
|
u64 mem, sz, paddr_hi = 0;
|
||||||
u64 paddr_lo = ULLONG_MAX;
|
u64 paddr_lo = ULLONG_MAX;
|
||||||
|
@ -162,15 +149,6 @@ static void setup_pci_atmu(struct pci_controller *hose,
|
||||||
const u64 *reg;
|
const u64 *reg;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
|
|
||||||
(u64)rsrc->start, (u64)resource_size(rsrc));
|
|
||||||
|
|
||||||
pci = ioremap(rsrc->start, resource_size(rsrc));
|
|
||||||
if (!pci) {
|
|
||||||
dev_err(hose->parent, "Unable to map ATMU registers\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
||||||
if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
|
if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
|
||||||
win_idx = 2;
|
win_idx = 2;
|
||||||
|
@ -451,6 +429,7 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
|
||||||
const int *bus_range;
|
const int *bus_range;
|
||||||
u8 hdr_type, progif;
|
u8 hdr_type, progif;
|
||||||
struct device_node *dev;
|
struct device_node *dev;
|
||||||
|
struct ccsr_pci __iomem *pci;
|
||||||
|
|
||||||
dev = pdev->dev.of_node;
|
dev = pdev->dev.of_node;
|
||||||
|
|
||||||
|
@ -483,9 +462,19 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
|
||||||
hose->first_busno = bus_range ? bus_range[0] : 0x0;
|
hose->first_busno = bus_range ? bus_range[0] : 0x0;
|
||||||
hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||||
|
|
||||||
|
pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
|
||||||
|
(u64)rsrc.start, (u64)resource_size(&rsrc));
|
||||||
|
|
||||||
|
pci = hose->private_data = ioremap(rsrc.start, resource_size(&rsrc));
|
||||||
|
if (!hose->private_data)
|
||||||
|
goto no_bridge;
|
||||||
|
|
||||||
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
|
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
|
||||||
PPC_INDIRECT_TYPE_BIG_ENDIAN);
|
PPC_INDIRECT_TYPE_BIG_ENDIAN);
|
||||||
|
|
||||||
|
if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0)
|
||||||
|
hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK;
|
||||||
|
|
||||||
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
||||||
/* For PCIE read HEADER_TYPE to identify controler mode */
|
/* For PCIE read HEADER_TYPE to identify controler mode */
|
||||||
early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
|
early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
|
||||||
|
@ -505,7 +494,7 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
|
||||||
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
||||||
hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
|
hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
|
||||||
PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
|
PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
|
||||||
if (fsl_pcie_check_link(hose, &rsrc))
|
if (fsl_pcie_check_link(hose))
|
||||||
hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
|
hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,11 +511,12 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
|
||||||
pci_process_bridge_OF_ranges(hose, dev, is_primary);
|
pci_process_bridge_OF_ranges(hose, dev, is_primary);
|
||||||
|
|
||||||
/* Setup PEX window registers */
|
/* Setup PEX window registers */
|
||||||
setup_pci_atmu(hose, &rsrc);
|
setup_pci_atmu(hose);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
no_bridge:
|
no_bridge:
|
||||||
|
iounmap(hose->private_data);
|
||||||
/* unmap cfg_data & cfg_addr separately if not on same page */
|
/* unmap cfg_data & cfg_addr separately if not on same page */
|
||||||
if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
|
if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
|
||||||
((unsigned long)hose->cfg_addr & PAGE_MASK))
|
((unsigned long)hose->cfg_addr & PAGE_MASK))
|
||||||
|
@ -703,11 +693,12 @@ static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
|
||||||
WARN_ON(hose->dn->data);
|
WARN_ON(hose->dn->data);
|
||||||
hose->dn->data = pcie;
|
hose->dn->data = pcie;
|
||||||
hose->ops = &mpc83xx_pcie_ops;
|
hose->ops = &mpc83xx_pcie_ops;
|
||||||
|
hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK;
|
||||||
|
|
||||||
out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0);
|
out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0);
|
||||||
out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);
|
out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);
|
||||||
|
|
||||||
if (fsl_pcie_check_link(hose, NULL))
|
if (fsl_pcie_check_link(hose))
|
||||||
hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
|
hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue