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