aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers/pci/pci-sh7780.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-02-01 06:01:50 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-01 06:01:50 -0500
commitb6c58b1d987a5795086c5c2babd8c7367d2fdb8c (patch)
tree3ec992af50f44dd09ff125165ea1c4ef41b2aecc /arch/sh/drivers/pci/pci-sh7780.c
parentef407beefbd9928792ccc93857e408e0057bc17b (diff)
sh: Improved multi-resource handling for SH7780 PCI.
The SH7780 PCI controller supports 3 different ranges of PCI memory in addition to its PCI I/O window. In the case of 29-bit mode, only 2 memory windows are supported, while in 32-bit mode all 3 are visible. This attempts to make the resource handling completely dynamic and to permit platforms to map in as many apertures as they can handle. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers/pci/pci-sh7780.c')
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c86
1 files changed, 64 insertions, 22 deletions
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 86373314f458..472f67aec337 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -21,27 +21,40 @@
21#include <asm/mmu.h> 21#include <asm/mmu.h>
22#include <asm/sizes.h> 22#include <asm/sizes.h>
23 23
24static struct resource sh7785_io_resource = { 24static struct resource sh7785_pci_resources[] = {
25 .name = "SH7785_IO", 25 {
26 .start = 0x1000, 26 .name = "SH7785_IO",
27 .end = SH7780_PCI_IO_SIZE - 1, 27 .start = 0x1000,
28 .flags = IORESOURCE_IO 28 .end = SZ_4M - 1,
29}; 29 .flags = IORESOURCE_IO,
30 30 }, {
31static struct resource sh7785_mem_resource = { 31 .name = "PCI MEM 0",
32 .name = "SH7785_mem", 32 .start = 0xfd000000,
33 .start = SH7780_PCI_MEMORY_BASE, 33 .end = 0xfd000000 + SZ_16M - 1,
34 .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, 34 .flags = IORESOURCE_MEM,
35 .flags = IORESOURCE_MEM 35 }, {
36 .name = "PCI MEM 1",
37 .start = 0x10000000,
38 .end = 0x10000000 + SZ_64M - 1,
39 .flags = IORESOURCE_MEM,
40 }, {
41 /*
42 * 32-bit only resources must be last.
43 */
44 .name = "PCI MEM 2",
45 .start = 0xc0000000,
46 .end = 0xc0000000 + SZ_512M - 1,
47 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
48 },
36}; 49};
37 50
38static struct pci_channel sh7780_pci_controller = { 51static struct pci_channel sh7780_pci_controller = {
39 .pci_ops = &sh4_pci_ops, 52 .pci_ops = &sh4_pci_ops,
40 .mem_resource = &sh7785_mem_resource, 53 .resources = sh7785_pci_resources,
41 .mem_offset = 0x00000000, 54 .nr_resources = ARRAY_SIZE(sh7785_pci_resources),
42 .io_resource = &sh7785_io_resource, 55 .io_offset = 0,
43 .io_offset = 0x00000000, 56 .mem_offset = 0,
44 .io_map_base = SH7780_PCI_IO_BASE, 57 .io_map_base = 0xfe200000,
45 .serr_irq = evt2irq(0xa00), 58 .serr_irq = evt2irq(0xa00),
46 .err_irq = evt2irq(0xaa0), 59 .err_irq = evt2irq(0xaa0),
47}; 60};
@@ -231,7 +244,7 @@ static int __init sh7780_pci_init(void)
231 size_t memsize; 244 size_t memsize;
232 unsigned int id; 245 unsigned int id;
233 const char *type; 246 const char *type;
234 int ret; 247 int ret, i;
235 248
236 printk(KERN_NOTICE "PCI: Starting intialization.\n"); 249 printk(KERN_NOTICE "PCI: Starting intialization.\n");
237 250
@@ -279,8 +292,6 @@ static int __init sh7780_pci_init(void)
279 */ 292 */
280 __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); 293 __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR);
281 294
282 __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0);
283
284 memphys = __pa(memory_start); 295 memphys = __pa(memory_start);
285 memsize = roundup_pow_of_two(memory_end - memory_start); 296 memsize = roundup_pow_of_two(memory_end - memory_start);
286 297
@@ -324,9 +335,40 @@ static int __init sh7780_pci_init(void)
324 __raw_writel(0, chan->reg_base + SH7780_PCICSCR1); 335 __raw_writel(0, chan->reg_base + SH7780_PCICSCR1);
325 __raw_writel(0, chan->reg_base + SH7780_PCICSAR1); 336 __raw_writel(0, chan->reg_base + SH7780_PCICSAR1);
326 337
327 __raw_writel(0xfd000000, chan->reg_base + SH7780_PCIMBR0); 338 /*
328 __raw_writel(0x00fc0000, chan->reg_base + SH7780_PCIMBMR0); 339 * Setup the memory BARs
340 */
341 for (i = 0; i < chan->nr_resources; i++) {
342 struct resource *res = chan->resources + (i + 1);
343 resource_size_t size;
344
345 if (unlikely(res->flags & IORESOURCE_IO))
346 continue;
347
348 /*
349 * Make sure we're in the right physical addressing mode
350 * for dealing with the resource.
351 */
352 if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) {
353 chan->nr_resources--;
354 continue;
355 }
329 356
357 size = resource_size(res);
358
359 /*
360 * The MBMR mask is calculated in units of 256kB, which
361 * keeps things pretty simple.
362 */
363 __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
364 chan->reg_base + SH7780_PCIMBMR(i));
365 __raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i));
366 }
367
368 /*
369 * And I/O.
370 */
371 __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0);
330 __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); 372 __raw_writel(0, chan->reg_base + SH7780_PCIIOBR);
331 __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); 373 __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR);
332 374