aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c104
1 files changed, 71 insertions, 33 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index f611d0369cc8..44bc903ead74 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -28,63 +28,101 @@
28#include <sysdev/fsl_pci.h> 28#include <sysdev/fsl_pci.h>
29 29
30#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) 30#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
31static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
32 unsigned int index, const struct resource *res,
33 resource_size_t offset)
34{
35 resource_size_t pci_addr = res->start - offset;
36 resource_size_t phys_addr = res->start;
37 resource_size_t size = res->end - res->start + 1;
38 u32 flags = 0x80044000; /* enable & mem R/W */
39 unsigned int i;
40
41 pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n",
42 (u64)res->start, (u64)size);
43
44 for (i = 0; size > 0; i++) {
45 unsigned int bits = min(__ilog2(size),
46 __ffs(pci_addr | phys_addr));
47
48 if (index + i >= 5)
49 return -1;
50
51 out_be32(&pci->pow[index + i].potar, pci_addr >> 12);
52 out_be32(&pci->pow[index + i].potear, (u64)pci_addr >> 44);
53 out_be32(&pci->pow[index + i].powbar, phys_addr >> 12);
54 out_be32(&pci->pow[index + i].powar, flags | (bits - 1));
55
56 pci_addr += (resource_size_t)1U << bits;
57 phys_addr += (resource_size_t)1U << bits;
58 size -= (resource_size_t)1U << bits;
59 }
60
61 return i;
62}
63
31/* atmu setup for fsl pci/pcie controller */ 64/* atmu setup for fsl pci/pcie controller */
32static void __init setup_pci_atmu(struct pci_controller *hose, 65static void __init setup_pci_atmu(struct pci_controller *hose,
33 struct resource *rsrc) 66 struct resource *rsrc)
34{ 67{
35 struct ccsr_pci __iomem *pci; 68 struct ccsr_pci __iomem *pci;
36 int i; 69 int i, j, n;
37 70
38 pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", 71 pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
39 (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1); 72 (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
40 pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); 73 pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
74 if (!pci) {
75 dev_err(hose->parent, "Unable to map ATMU registers\n");
76 return;
77 }
41 78
42 /* Disable all windows (except powar0 since its ignored) */ 79 /* Disable all windows (except powar0 since it's ignored) */
43 for(i = 1; i < 5; i++) 80 for(i = 1; i < 5; i++)
44 out_be32(&pci->pow[i].powar, 0); 81 out_be32(&pci->pow[i].powar, 0);
45 for(i = 0; i < 3; i++) 82 for(i = 0; i < 3; i++)
46 out_be32(&pci->piw[i].piwar, 0); 83 out_be32(&pci->piw[i].piwar, 0);
47 84
48 /* Setup outbound MEM window */ 85 /* Setup outbound MEM window */
49 for(i = 0; i < 3; i++) 86 for(i = 0, j = 1; i < 3; i++) {
50 if (hose->mem_resources[i].flags & IORESOURCE_MEM){ 87 if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
51 resource_size_t pci_addr_start = 88 continue;
52 hose->mem_resources[i].start - 89
53 hose->pci_mem_offset; 90 n = setup_one_atmu(pci, j, &hose->mem_resources[i],
54 pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", 91 hose->pci_mem_offset);
55 (u64)hose->mem_resources[i].start, 92
56 (u64)hose->mem_resources[i].end 93 if (n < 0 || j >= 5) {
57 - (u64)hose->mem_resources[i].start + 1); 94 pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i);
58 out_be32(&pci->pow[i+1].potar, (pci_addr_start >> 12)); 95 hose->mem_resources[i].flags |= IORESOURCE_DISABLED;
59 out_be32(&pci->pow[i+1].potear, 0); 96 } else
60 out_be32(&pci->pow[i+1].powbar, 97 j += n;
61 (hose->mem_resources[i].start >> 12)); 98 }
62 /* Enable, Mem R/W */
63 out_be32(&pci->pow[i+1].powar, 0x80044000
64 | (__ilog2(hose->mem_resources[i].end
65 - hose->mem_resources[i].start + 1) - 1));
66 }
67 99
68 /* Setup outbound IO window */ 100 /* Setup outbound IO window */
69 if (hose->io_resource.flags & IORESOURCE_IO){ 101 if (hose->io_resource.flags & IORESOURCE_IO) {
70 pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, " 102 if (j >= 5) {
71 "phy base 0x%016llx.\n", 103 pr_err("Ran out of outbound PCI ATMUs for IO resource\n");
72 (u64)hose->io_resource.start, 104 } else {
73 (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1, 105 pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, "
74 (u64)hose->io_base_phys); 106 "phy base 0x%016llx.\n",
75 out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12)); 107 (u64)hose->io_resource.start,
76 out_be32(&pci->pow[i+1].potear, 0); 108 (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1,
77 out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12)); 109 (u64)hose->io_base_phys);
78 /* Enable, IO R/W */ 110 out_be32(&pci->pow[j].potar, (hose->io_resource.start >> 12));
79 out_be32(&pci->pow[i+1].powar, 0x80088000 111 out_be32(&pci->pow[j].potear, 0);
80 | (__ilog2(hose->io_resource.end 112 out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12));
81 - hose->io_resource.start + 1) - 1)); 113 /* Enable, IO R/W */
114 out_be32(&pci->pow[j].powar, 0x80088000
115 | (__ilog2(hose->io_resource.end
116 - hose->io_resource.start + 1) - 1));
117 }
82 } 118 }
83 119
84 /* Setup 2G inbound Memory Window @ 1 */ 120 /* Setup 2G inbound Memory Window @ 1 */
85 out_be32(&pci->piw[2].pitar, 0x00000000); 121 out_be32(&pci->piw[2].pitar, 0x00000000);
86 out_be32(&pci->piw[2].piwbar,0x00000000); 122 out_be32(&pci->piw[2].piwbar,0x00000000);
87 out_be32(&pci->piw[2].piwar, PIWAR_2G); 123 out_be32(&pci->piw[2].piwar, PIWAR_2G);
124
125 iounmap(pci);
88} 126}
89 127
90static void __init setup_pci_cmd(struct pci_controller *hose) 128static void __init setup_pci_cmd(struct pci_controller *hose)