diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2013-03-13 15:07:15 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2013-04-10 11:15:27 -0400 |
commit | 34642bbb3d12121333efcf4ea7dfe66685e403a1 (patch) | |
tree | 0ce90004cd360711bb8b7e7eac9c7f54e3e154e6 | |
parent | 9f4c350d520e848b122dce3eb5b566ca635b98ca (diff) |
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>
-rw-r--r-- | arch/powerpc/include/asm/pci-bridge.h | 5 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 69 |
2 files changed, 34 insertions, 40 deletions
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 025a130729bc..c0278f009504 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -70,6 +70,8 @@ struct pci_controller { | |||
70 | * BIG_ENDIAN - cfg_addr is a big endian register | 70 | * BIG_ENDIAN - cfg_addr is a big endian register |
71 | * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on | 71 | * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on |
72 | * the PLB4. Effectively disable MRM commands by setting this. | 72 | * the PLB4. Effectively disable MRM commands by setting this. |
73 | * FSL_CFG_REG_LINK - Freescale controller version in which the PCIe | ||
74 | * link status is in a RC PCIe cfg register (vs being a SoC register) | ||
73 | */ | 75 | */ |
74 | #define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001 | 76 | #define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001 |
75 | #define PPC_INDIRECT_TYPE_EXT_REG 0x00000002 | 77 | #define PPC_INDIRECT_TYPE_EXT_REG 0x00000002 |
@@ -77,6 +79,7 @@ struct pci_controller { | |||
77 | #define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008 | 79 | #define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008 |
78 | #define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010 | 80 | #define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010 |
79 | #define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 | 81 | #define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 |
82 | #define PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK 0x00000040 | ||
80 | u32 indirect_type; | 83 | u32 indirect_type; |
81 | /* Currently, we limit ourselves to 1 IO range and 3 mem | 84 | /* Currently, we limit ourselves to 1 IO range and 3 mem |
82 | * ranges since the common pci_bus structure can't handle more | 85 | * ranges since the common pci_bus structure can't handle more |
@@ -90,9 +93,9 @@ struct pci_controller { | |||
90 | 93 | ||
91 | #ifdef CONFIG_PPC64 | 94 | #ifdef CONFIG_PPC64 |
92 | unsigned long buid; | 95 | unsigned long buid; |
96 | #endif /* CONFIG_PPC64 */ | ||
93 | 97 | ||
94 | void *private_data; | 98 | void *private_data; |
95 | #endif /* CONFIG_PPC64 */ | ||
96 | }; | 99 | }; |
97 | 100 | ||
98 | /* These are used for config access before all the PCI probing | 101 | /* These are used for config access before all the PCI probing |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index e7ec337f03fd..83918c3e665a 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -54,34 +54,22 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev) | |||
54 | return; | 54 | return; |
55 | } | 55 | } |
56 | 56 | ||
57 | static int __init fsl_pcie_check_link(struct pci_controller *hose, | 57 | static int __init fsl_pcie_check_link(struct pci_controller *hose) |
58 | struct resource *rsrc) | ||
59 | { | 58 | { |
60 | struct ccsr_pci __iomem *pci = NULL; | ||
61 | u32 val; | 59 | u32 val; |
62 | 60 | ||
63 | /* for PCIe IP rev 3.0 or greater use CSR0 for link state */ | 61 | if (hose->indirect_type & PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) { |
64 | if (rsrc) { | 62 | early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); |
65 | pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", | 63 | if (val < PCIE_LTSSM_L0) |
66 | (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1); | 64 | return 1; |
67 | pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); | 65 | } else { |
68 | if (!pci) { | 66 | struct ccsr_pci __iomem *pci = hose->private_data; |
69 | dev_err(hose->parent, "Unable to map PCIe registers\n"); | 67 | /* for PCIe IP rev 3.0 or greater use CSR0 for link state */ |
70 | return -ENOMEM; | 68 | val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK) |
71 | } | 69 | >> PEX_CSR0_LTSSM_SHIFT; |
72 | if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_3_0) { | 70 | if (val != PEX_CSR0_LTSSM_L0) |
73 | val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK) | 71 | return 1; |
74 | >> PEX_CSR0_LTSSM_SHIFT; | ||
75 | if (val != PEX_CSR0_LTSSM_L0) | ||
76 | return 1; | ||
77 | iounmap(pci); | ||
78 | return 0; | ||
79 | } | ||
80 | iounmap(pci); | ||
81 | } | 72 | } |
82 | early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); | ||
83 | if (val < PCIE_LTSSM_L0) | ||
84 | return 1; | ||
85 | 73 | ||
86 | return 0; | 74 | return 0; |
87 | } | 75 | } |
@@ -148,10 +136,9 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci, | |||
148 | } | 136 | } |
149 | 137 | ||
150 | /* atmu setup for fsl pci/pcie controller */ | 138 | /* atmu setup for fsl pci/pcie controller */ |
151 | static void setup_pci_atmu(struct pci_controller *hose, | 139 | static void setup_pci_atmu(struct pci_controller *hose) |
152 | struct resource *rsrc) | ||
153 | { | 140 | { |
154 | struct ccsr_pci __iomem *pci; | 141 | struct ccsr_pci __iomem *pci = hose->private_data; |
155 | int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4; | 142 | int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4; |
156 | u64 mem, sz, paddr_hi = 0; | 143 | u64 mem, sz, paddr_hi = 0; |
157 | u64 paddr_lo = ULLONG_MAX; | 144 | u64 paddr_lo = ULLONG_MAX; |
@@ -162,15 +149,6 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
162 | const u64 *reg; | 149 | const u64 *reg; |
163 | int len; | 150 | int len; |
164 | 151 | ||
165 | pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", | ||
166 | (u64)rsrc->start, (u64)resource_size(rsrc)); | ||
167 | |||
168 | pci = ioremap(rsrc->start, resource_size(rsrc)); | ||
169 | if (!pci) { | ||
170 | dev_err(hose->parent, "Unable to map ATMU registers\n"); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 152 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
175 | if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { | 153 | if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { |
176 | win_idx = 2; | 154 | win_idx = 2; |
@@ -451,6 +429,7 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
451 | const int *bus_range; | 429 | const int *bus_range; |
452 | u8 hdr_type, progif; | 430 | u8 hdr_type, progif; |
453 | struct device_node *dev; | 431 | struct device_node *dev; |
432 | struct ccsr_pci __iomem *pci; | ||
454 | 433 | ||
455 | dev = pdev->dev.of_node; | 434 | dev = pdev->dev.of_node; |
456 | 435 | ||
@@ -483,9 +462,19 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
483 | hose->first_busno = bus_range ? bus_range[0] : 0x0; | 462 | hose->first_busno = bus_range ? bus_range[0] : 0x0; |
484 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 463 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
485 | 464 | ||
465 | pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", | ||
466 | (u64)rsrc.start, (u64)resource_size(&rsrc)); | ||
467 | |||
468 | pci = hose->private_data = ioremap(rsrc.start, resource_size(&rsrc)); | ||
469 | if (!hose->private_data) | ||
470 | goto no_bridge; | ||
471 | |||
486 | setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, | 472 | setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, |
487 | PPC_INDIRECT_TYPE_BIG_ENDIAN); | 473 | PPC_INDIRECT_TYPE_BIG_ENDIAN); |
488 | 474 | ||
475 | if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) | ||
476 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; | ||
477 | |||
489 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 478 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
490 | /* For PCIE read HEADER_TYPE to identify controler mode */ | 479 | /* For PCIE read HEADER_TYPE to identify controler mode */ |
491 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); | 480 | 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) | |||
505 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 494 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
506 | hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG | | 495 | hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG | |
507 | PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS; | 496 | PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS; |
508 | if (fsl_pcie_check_link(hose, &rsrc)) | 497 | if (fsl_pcie_check_link(hose)) |
509 | hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; | 498 | hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; |
510 | } | 499 | } |
511 | 500 | ||
@@ -522,11 +511,12 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
522 | pci_process_bridge_OF_ranges(hose, dev, is_primary); | 511 | pci_process_bridge_OF_ranges(hose, dev, is_primary); |
523 | 512 | ||
524 | /* Setup PEX window registers */ | 513 | /* Setup PEX window registers */ |
525 | setup_pci_atmu(hose, &rsrc); | 514 | setup_pci_atmu(hose); |
526 | 515 | ||
527 | return 0; | 516 | return 0; |
528 | 517 | ||
529 | no_bridge: | 518 | no_bridge: |
519 | iounmap(hose->private_data); | ||
530 | /* unmap cfg_data & cfg_addr separately if not on same page */ | 520 | /* unmap cfg_data & cfg_addr separately if not on same page */ |
531 | if (((unsigned long)hose->cfg_data & PAGE_MASK) != | 521 | if (((unsigned long)hose->cfg_data & PAGE_MASK) != |
532 | ((unsigned long)hose->cfg_addr & PAGE_MASK)) | 522 | ((unsigned long)hose->cfg_addr & PAGE_MASK)) |
@@ -703,11 +693,12 @@ static int __init mpc83xx_pcie_setup(struct pci_controller *hose, | |||
703 | WARN_ON(hose->dn->data); | 693 | WARN_ON(hose->dn->data); |
704 | hose->dn->data = pcie; | 694 | hose->dn->data = pcie; |
705 | hose->ops = &mpc83xx_pcie_ops; | 695 | hose->ops = &mpc83xx_pcie_ops; |
696 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; | ||
706 | 697 | ||
707 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0); | 698 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0); |
708 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0); | 699 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0); |
709 | 700 | ||
710 | if (fsl_pcie_check_link(hose, NULL)) | 701 | if (fsl_pcie_check_link(hose)) |
711 | hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; | 702 | hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; |
712 | 703 | ||
713 | return 0; | 704 | return 0; |