diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-09-07 04:03:10 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-09-07 04:03:10 -0400 |
commit | da03a63ac843711887a85e5d90dd69399b1b9164 (patch) | |
tree | 47bf395f811a1fb8cb486f530f2cbac5d6ddf270 /arch/sh/drivers/pci/pcie-sh7786.c | |
parent | 2c5f674339d5e4c02cca7af13ec02bd9b5a96b60 (diff) |
sh: Ignore 32-bit windows in 29-bit mode for SH7786 PCIe.
Certain memory windows are only available for 32-bit space, so skip over
these in 29-bit mode. This will severely restrict the amount of memory
that can be mapped, but since a boot loader bug makes booting in 29-bit
mode close to impossible anyways, everything is ok.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers/pci/pcie-sh7786.c')
-rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 4cd83140579b..4f79fd9059e0 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
@@ -220,7 +220,7 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
220 | unsigned int data; | 220 | unsigned int data; |
221 | phys_addr_t memphys; | 221 | phys_addr_t memphys; |
222 | size_t memsize; | 222 | size_t memsize; |
223 | int ret, i; | 223 | int ret, i, win; |
224 | 224 | ||
225 | /* Begin initialization */ | 225 | /* Begin initialization */ |
226 | pcie_reset(port); | 226 | pcie_reset(port); |
@@ -337,13 +337,19 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
337 | printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n", | 337 | printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n", |
338 | port->index, (data >> 20) & 0x3f); | 338 | port->index, (data >> 20) & 0x3f); |
339 | 339 | ||
340 | 340 | for (i = win = 0; i < chan->nr_resources; i++) { | |
341 | for (i = 0; i < chan->nr_resources; i++) { | ||
342 | struct resource *res = chan->resources + i; | 341 | struct resource *res = chan->resources + i; |
343 | resource_size_t size; | 342 | resource_size_t size; |
344 | u32 enable_mask; | 343 | u32 enable_mask; |
345 | 344 | ||
346 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i)); | 345 | /* |
346 | * We can't use the 32-bit mode windows in legacy 29-bit | ||
347 | * mode, so just skip them entirely. | ||
348 | */ | ||
349 | if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) | ||
350 | continue; | ||
351 | |||
352 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win)); | ||
347 | 353 | ||
348 | size = resource_size(res); | 354 | size = resource_size(res); |
349 | 355 | ||
@@ -352,16 +358,18 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
352 | * keeps things pretty simple. | 358 | * keeps things pretty simple. |
353 | */ | 359 | */ |
354 | __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, | 360 | __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, |
355 | chan->reg_base + SH4A_PCIEPAMR(i)); | 361 | chan->reg_base + SH4A_PCIEPAMR(win)); |
356 | 362 | ||
357 | pci_write_reg(chan, res->start, SH4A_PCIEPARL(i)); | 363 | pci_write_reg(chan, res->start, SH4A_PCIEPARL(win)); |
358 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i)); | 364 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(win)); |
359 | 365 | ||
360 | enable_mask = MASK_PARE; | 366 | enable_mask = MASK_PARE; |
361 | if (res->flags & IORESOURCE_IO) | 367 | if (res->flags & IORESOURCE_IO) |
362 | enable_mask |= MASK_SPC; | 368 | enable_mask |= MASK_SPC; |
363 | 369 | ||
364 | pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i)); | 370 | pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(win)); |
371 | |||
372 | win++; | ||
365 | } | 373 | } |
366 | 374 | ||
367 | return 0; | 375 | return 0; |