diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-09-07 17:03:10 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-09-07 17:03:10 +0900 |
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 4cd83140579..4f79fd9059e 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) unsigned int data; phys_addr_t memphys; size_t memsize; - int ret, i; + int ret, i, win; /* Begin initialization */ pcie_reset(port); @@ -337,13 +337,19 @@ static int pcie_init(struct sh7786_pcie_port *port) printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n", port->index, (data >> 20) & 0x3f); - - for (i = 0; i < chan->nr_resources; i++) { + for (i = win = 0; i < chan->nr_resources; i++) { struct resource *res = chan->resources + i; resource_size_t size; u32 enable_mask; - pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i)); + /* + * We can't use the 32-bit mode windows in legacy 29-bit + * mode, so just skip them entirely. + */ + if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) + continue; + + pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win)); size = resource_size(res); @@ -352,16 +358,18 @@ static int pcie_init(struct sh7786_pcie_port *port) * keeps things pretty simple. */ __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, - chan->reg_base + SH4A_PCIEPAMR(i)); + chan->reg_base + SH4A_PCIEPAMR(win)); - pci_write_reg(chan, res->start, SH4A_PCIEPARL(i)); - pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i)); + pci_write_reg(chan, res->start, SH4A_PCIEPARL(win)); + pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(win)); enable_mask = MASK_PARE; if (res->flags & IORESOURCE_IO) enable_mask |= MASK_SPC; - pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i)); + pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(win)); + + win++; } return 0; |