2 * PCI / PCI-X / PCI-Express support for 4xx parts
4 * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
8 #include <linux/kernel.h>
10 #include <linux/init.h>
14 #include <asm/pci-bridge.h>
15 #include <asm/machdep.h>
17 #include "ppc4xx_pci.h"
19 static int dma_offset_set
;
21 /* Move that to a useable header */
22 extern unsigned long total_memory
;
24 static void fixup_ppc4xx_pci_bridge(struct pci_dev
*dev
)
26 struct pci_controller
*hose
;
29 if (dev
->devfn
!= 0 || dev
->bus
->self
!= NULL
)
32 hose
= pci_bus_to_host(dev
->bus
);
36 if (!of_device_is_compatible(hose
->dn
, "ibm,plb-pciex") &&
37 !of_device_is_compatible(hose
->dn
, "ibm,plb-pcix") &&
38 !of_device_is_compatible(hose
->dn
, "ibm,plb-pci"))
41 /* Hide the PCI host BARs from the kernel as their content doesn't
42 * fit well in the resource management
44 for (i
= 0; i
< DEVICE_COUNT_RESOURCE
; i
++) {
45 dev
->resource
[i
].start
= dev
->resource
[i
].end
= 0;
46 dev
->resource
[i
].flags
= 0;
49 printk(KERN_INFO
"PCI: Hiding 4xx host bridge resources %s\n",
52 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID
, PCI_ANY_ID
, fixup_ppc4xx_pci_bridge
);
54 static int __init
ppc4xx_parse_dma_ranges(struct pci_controller
*hose
,
61 int pna
= of_n_addr_cells(hose
->dn
);
66 res
->end
= size
= 0x80000000;
67 res
->flags
= IORESOURCE_MEM
| IORESOURCE_PREFETCH
;
69 /* Get dma-ranges property */
70 ranges
= of_get_property(hose
->dn
, "dma-ranges", &rlen
);
75 while ((rlen
-= np
* 4) >= 0) {
76 u32 pci_space
= ranges
[0];
77 u64 pci_addr
= of_read_number(ranges
+ 1, 2);
78 u64 cpu_addr
= of_translate_dma_address(hose
->dn
, ranges
+ 3);
79 size
= of_read_number(ranges
+ pna
+ 3, 2);
81 if (cpu_addr
== OF_BAD_ADDR
|| size
== 0)
84 /* We only care about memory */
85 if ((pci_space
& 0x03000000) != 0x02000000)
88 /* We currently only support memory at 0, and pci_addr
89 * within 32 bits space
91 if (cpu_addr
!= 0 || pci_addr
> 0xffffffff) {
92 printk(KERN_WARNING
"%s: Ignored unsupported dma range"
93 " 0x%016llx...0x%016llx -> 0x%016llx\n",
95 pci_addr
, pci_addr
+ size
- 1, cpu_addr
);
99 /* Check if not prefetchable */
100 if (!(pci_space
& 0x40000000))
101 res
->flags
&= ~IORESOURCE_PREFETCH
;
105 res
->start
= pci_addr
;
106 #ifndef CONFIG_RESOURCES_64BIT
107 /* Beware of 32 bits resources */
108 if ((pci_addr
+ size
) > 0x100000000ull
)
109 res
->end
= 0xffffffff;
112 res
->end
= res
->start
+ size
- 1;
116 /* We only support one global DMA offset */
117 if (dma_offset_set
&& pci_dram_offset
!= res
->start
) {
118 printk(KERN_ERR
"%s: dma-ranges(s) mismatch\n",
119 hose
->dn
->full_name
);
123 /* Check that we can fit all of memory as we don't support
126 if (size
< total_memory
) {
127 printk(KERN_ERR
"%s: dma-ranges too small "
128 "(size=%llx total_memory=%lx)\n",
129 hose
->dn
->full_name
, size
, total_memory
);
133 /* Check we are a power of 2 size and that base is a multiple of size*/
134 if (!is_power_of_2(size
) ||
135 (res
->start
& (size
- 1)) != 0) {
136 printk(KERN_ERR
"%s: dma-ranges unaligned\n",
137 hose
->dn
->full_name
);
141 /* Check that we are fully contained within 32 bits space */
142 if (res
->end
> 0xffffffff) {
143 printk(KERN_ERR
"%s: dma-ranges outside of 32 bits space\n",
144 hose
->dn
->full_name
);
149 pci_dram_offset
= res
->start
;
151 printk(KERN_INFO
"4xx PCI DMA offset set to 0x%08lx\n",
160 static void __init
ppc4xx_configure_pci_PMMs(struct pci_controller
*hose
,
163 u32 la
, ma
, pcila
, pciha
;
166 /* Setup outbound memory windows */
167 for (i
= j
= 0; i
< 3; i
++) {
168 struct resource
*res
= &hose
->mem_resources
[i
];
170 /* we only care about memory windows */
171 if (!(res
->flags
& IORESOURCE_MEM
))
174 printk(KERN_WARNING
"%s: Too many ranges\n",
175 hose
->dn
->full_name
);
179 /* Calculate register values */
181 #ifdef CONFIG_RESOURCES_64BIT
182 pciha
= (res
->start
- hose
->pci_mem_offset
) >> 32;
183 pcila
= (res
->start
- hose
->pci_mem_offset
) & 0xffffffffu
;
186 pcila
= res
->start
- hose
->pci_mem_offset
;
189 ma
= res
->end
+ 1 - res
->start
;
190 if (!is_power_of_2(ma
) || ma
< 0x1000 || ma
> 0xffffffffu
) {
191 printk(KERN_WARNING
"%s: Resource out of range\n",
192 hose
->dn
->full_name
);
195 ma
= (0xffffffffu
<< ilog2(ma
)) | 0x1;
196 if (res
->flags
& IORESOURCE_PREFETCH
)
199 /* Program register values */
200 writel(la
, reg
+ PCIL0_PMM0LA
+ (0x10 * j
));
201 writel(pcila
, reg
+ PCIL0_PMM0PCILA
+ (0x10 * j
));
202 writel(pciha
, reg
+ PCIL0_PMM0PCIHA
+ (0x10 * j
));
203 writel(ma
, reg
+ PCIL0_PMM0MA
+ (0x10 * j
));
208 static void __init
ppc4xx_configure_pci_PTMs(struct pci_controller
*hose
,
210 const struct resource
*res
)
212 resource_size_t size
= res
->end
- res
->start
+ 1;
215 /* Calculate window size */
216 sa
= (0xffffffffu
<< ilog2(size
)) | 1;
219 /* RAM is always at 0 local for now */
220 writel(0, reg
+ PCIL0_PTM1LA
);
221 writel(sa
, reg
+ PCIL0_PTM1MS
);
223 /* Map on PCI side */
224 early_write_config_dword(hose
, hose
->first_busno
, 0,
225 PCI_BASE_ADDRESS_1
, res
->start
);
226 early_write_config_dword(hose
, hose
->first_busno
, 0,
227 PCI_BASE_ADDRESS_2
, 0x00000000);
228 early_write_config_word(hose
, hose
->first_busno
, 0,
229 PCI_COMMAND
, 0x0006);
232 static void __init
ppc4xx_probe_pci_bridge(struct device_node
*np
)
235 struct resource rsrc_cfg
;
236 struct resource rsrc_reg
;
237 struct resource dma_window
;
238 struct pci_controller
*hose
= NULL
;
239 void __iomem
*reg
= NULL
;
240 const int *bus_range
;
243 /* Fetch config space registers address */
244 if (of_address_to_resource(np
, 0, &rsrc_cfg
)) {
245 printk(KERN_ERR
"%s:Can't get PCI config register base !",
249 /* Fetch host bridge internal registers address */
250 if (of_address_to_resource(np
, 3, &rsrc_reg
)) {
251 printk(KERN_ERR
"%s: Can't get PCI internal register base !",
256 /* Check if primary bridge */
257 if (of_get_property(np
, "primary", NULL
))
260 /* Get bus range if any */
261 bus_range
= of_get_property(np
, "bus-range", NULL
);
264 reg
= ioremap(rsrc_reg
.start
, rsrc_reg
.end
+ 1 - rsrc_reg
.start
);
266 printk(KERN_ERR
"%s: Can't map registers !", np
->full_name
);
270 /* Allocate the host controller data structure */
271 hose
= pcibios_alloc_controller(np
);
275 hose
->first_busno
= bus_range
? bus_range
[0] : 0x0;
276 hose
->last_busno
= bus_range
? bus_range
[1] : 0xff;
278 /* Setup config space */
279 setup_indirect_pci(hose
, rsrc_cfg
.start
, rsrc_cfg
.start
+ 0x4, 0);
281 /* Disable all windows */
282 writel(0, reg
+ PCIL0_PMM0MA
);
283 writel(0, reg
+ PCIL0_PMM1MA
);
284 writel(0, reg
+ PCIL0_PMM2MA
);
285 writel(0, reg
+ PCIL0_PTM1MS
);
286 writel(0, reg
+ PCIL0_PTM2MS
);
288 /* Parse outbound mapping resources */
289 pci_process_bridge_OF_ranges(hose
, np
, primary
);
291 /* Parse inbound mapping resources */
292 if (ppc4xx_parse_dma_ranges(hose
, reg
, &dma_window
) != 0)
295 /* Configure outbound ranges POMs */
296 ppc4xx_configure_pci_PMMs(hose
, reg
);
298 /* Configure inbound ranges PIMs */
299 ppc4xx_configure_pci_PTMs(hose
, reg
, &dma_window
);
301 /* We don't need the registers anymore */
307 pcibios_free_controller(hose
);
316 static void __init
ppc4xx_configure_pcix_POMs(struct pci_controller
*hose
,
319 u32 lah
, lal
, pciah
, pcial
, sa
;
322 /* Setup outbound memory windows */
323 for (i
= j
= 0; i
< 3; i
++) {
324 struct resource
*res
= &hose
->mem_resources
[i
];
326 /* we only care about memory windows */
327 if (!(res
->flags
& IORESOURCE_MEM
))
330 printk(KERN_WARNING
"%s: Too many ranges\n",
331 hose
->dn
->full_name
);
335 /* Calculate register values */
336 #ifdef CONFIG_RESOURCES_64BIT
337 lah
= res
->start
>> 32;
338 lal
= res
->start
& 0xffffffffu
;
339 pciah
= (res
->start
- hose
->pci_mem_offset
) >> 32;
340 pcial
= (res
->start
- hose
->pci_mem_offset
) & 0xffffffffu
;
344 pcial
= res
->start
- hose
->pci_mem_offset
;
346 sa
= res
->end
+ 1 - res
->start
;
347 if (!is_power_of_2(sa
) || sa
< 0x100000 ||
349 printk(KERN_WARNING
"%s: Resource out of range\n",
350 hose
->dn
->full_name
);
353 sa
= (0xffffffffu
<< ilog2(sa
)) | 0x1;
355 /* Program register values */
357 writel(lah
, reg
+ PCIX0_POM0LAH
);
358 writel(lal
, reg
+ PCIX0_POM0LAL
);
359 writel(pciah
, reg
+ PCIX0_POM0PCIAH
);
360 writel(pcial
, reg
+ PCIX0_POM0PCIAL
);
361 writel(sa
, reg
+ PCIX0_POM0SA
);
363 writel(lah
, reg
+ PCIX0_POM1LAH
);
364 writel(lal
, reg
+ PCIX0_POM1LAL
);
365 writel(pciah
, reg
+ PCIX0_POM1PCIAH
);
366 writel(pcial
, reg
+ PCIX0_POM1PCIAL
);
367 writel(sa
, reg
+ PCIX0_POM1SA
);
373 static void __init
ppc4xx_configure_pcix_PIMs(struct pci_controller
*hose
,
375 const struct resource
*res
,
379 resource_size_t size
= res
->end
- res
->start
+ 1;
382 /* RAM is always at 0 */
383 writel(0x00000000, reg
+ PCIX0_PIM0LAH
);
384 writel(0x00000000, reg
+ PCIX0_PIM0LAL
);
386 /* Calculate window size */
387 sa
= (0xffffffffu
<< ilog2(size
)) | 1;
389 if (res
->flags
& IORESOURCE_PREFETCH
)
393 writel(sa
, reg
+ PCIX0_PIM0SA
);
395 writel(0xffffffff, reg
+ PCIX0_PIM0SAH
);
397 /* Map on PCI side */
398 writel(0x00000000, reg
+ PCIX0_BAR0H
);
399 writel(res
->start
, reg
+ PCIX0_BAR0L
);
400 writew(0x0006, reg
+ PCIX0_COMMAND
);
403 static void __init
ppc4xx_probe_pcix_bridge(struct device_node
*np
)
405 struct resource rsrc_cfg
;
406 struct resource rsrc_reg
;
407 struct resource dma_window
;
408 struct pci_controller
*hose
= NULL
;
409 void __iomem
*reg
= NULL
;
410 const int *bus_range
;
411 int big_pim
= 0, msi
= 0, primary
= 0;
413 /* Fetch config space registers address */
414 if (of_address_to_resource(np
, 0, &rsrc_cfg
)) {
415 printk(KERN_ERR
"%s:Can't get PCI-X config register base !",
419 /* Fetch host bridge internal registers address */
420 if (of_address_to_resource(np
, 3, &rsrc_reg
)) {
421 printk(KERN_ERR
"%s: Can't get PCI-X internal register base !",
426 /* Check if it supports large PIMs (440GX) */
427 if (of_get_property(np
, "large-inbound-windows", NULL
))
430 /* Check if we should enable MSIs inbound hole */
431 if (of_get_property(np
, "enable-msi-hole", NULL
))
434 /* Check if primary bridge */
435 if (of_get_property(np
, "primary", NULL
))
438 /* Get bus range if any */
439 bus_range
= of_get_property(np
, "bus-range", NULL
);
442 reg
= ioremap(rsrc_reg
.start
, rsrc_reg
.end
+ 1 - rsrc_reg
.start
);
444 printk(KERN_ERR
"%s: Can't map registers !", np
->full_name
);
448 /* Allocate the host controller data structure */
449 hose
= pcibios_alloc_controller(np
);
453 hose
->first_busno
= bus_range
? bus_range
[0] : 0x0;
454 hose
->last_busno
= bus_range
? bus_range
[1] : 0xff;
456 /* Setup config space */
457 setup_indirect_pci(hose
, rsrc_cfg
.start
, rsrc_cfg
.start
+ 0x4, 0);
459 /* Disable all windows */
460 writel(0, reg
+ PCIX0_POM0SA
);
461 writel(0, reg
+ PCIX0_POM1SA
);
462 writel(0, reg
+ PCIX0_POM2SA
);
463 writel(0, reg
+ PCIX0_PIM0SA
);
464 writel(0, reg
+ PCIX0_PIM1SA
);
465 writel(0, reg
+ PCIX0_PIM2SA
);
467 writel(0, reg
+ PCIX0_PIM0SAH
);
468 writel(0, reg
+ PCIX0_PIM2SAH
);
471 /* Parse outbound mapping resources */
472 pci_process_bridge_OF_ranges(hose
, np
, primary
);
474 /* Parse inbound mapping resources */
475 if (ppc4xx_parse_dma_ranges(hose
, reg
, &dma_window
) != 0)
478 /* Configure outbound ranges POMs */
479 ppc4xx_configure_pcix_POMs(hose
, reg
);
481 /* Configure inbound ranges PIMs */
482 ppc4xx_configure_pcix_PIMs(hose
, reg
, &dma_window
, big_pim
, msi
);
484 /* We don't need the registers anymore */
490 pcibios_free_controller(hose
);
496 * 4xx PCI-Express part
498 static void __init
ppc4xx_probe_pciex_bridge(struct device_node
*np
)
503 static int __init
ppc4xx_pci_find_bridges(void)
505 struct device_node
*np
;
507 for_each_compatible_node(np
, NULL
, "ibm,plb-pciex")
508 ppc4xx_probe_pciex_bridge(np
);
509 for_each_compatible_node(np
, NULL
, "ibm,plb-pcix")
510 ppc4xx_probe_pcix_bridge(np
);
511 for_each_compatible_node(np
, NULL
, "ibm,plb-pci")
512 ppc4xx_probe_pci_bridge(np
);
516 arch_initcall(ppc4xx_pci_find_bridges
);