diff options
-rw-r--r-- | arch/sh/drivers/pci/pci-sh7780.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 40531cd367b7..8405c8fded6f 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/log2.h> | ||
16 | #include "pci-sh4.h" | 17 | #include "pci-sh4.h" |
17 | #include <asm/mmu.h> | 18 | #include <asm/mmu.h> |
18 | #include <asm/sizes.h> | 19 | #include <asm/sizes.h> |
@@ -59,7 +60,11 @@ static int __init sh7780_pci_init(void) | |||
59 | __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, | 60 | __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, |
60 | chan->reg_base + SH4_PCICR); | 61 | chan->reg_base + SH4_PCICR); |
61 | 62 | ||
62 | /* Wait for it to come back up.. */ | 63 | /* |
64 | * Wait for it to come back up. The spec says to allow for up to | ||
65 | * 1 second after toggling the reset pin, but in practice 100ms | ||
66 | * is more than enough. | ||
67 | */ | ||
63 | mdelay(100); | 68 | mdelay(100); |
64 | 69 | ||
65 | id = __raw_readw(chan->reg_base + PCI_VENDOR_ID); | 70 | id = __raw_readw(chan->reg_base + PCI_VENDOR_ID); |
@@ -90,17 +95,34 @@ static int __init sh7780_pci_init(void) | |||
90 | */ | 95 | */ |
91 | __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); | 96 | __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); |
92 | 97 | ||
98 | __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); | ||
99 | |||
93 | memphys = __pa(memory_start); | 100 | memphys = __pa(memory_start); |
94 | memsize = memory_end - memory_start; | 101 | memsize = roundup_pow_of_two(memory_end - memory_start); |
95 | 102 | ||
96 | /* | 103 | /* |
97 | * Set IO and Mem windows to local address | 104 | * If there's more than 512MB of memory, we need to roll over to |
98 | * Make PCI and local address the same for easy 1 to 1 mapping | 105 | * LAR1/LSR1. |
99 | */ | 106 | */ |
100 | __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); | 107 | if (memsize > SZ_512M) { |
108 | __raw_writel(memphys + SZ_512M, chan->reg_base + SH4_PCILAR1); | ||
109 | __raw_writel((((memsize - SZ_512M) - SZ_1M) & 0x1ff00000) | 1, | ||
110 | chan->reg_base + SH4_PCILSR1); | ||
111 | memsize = SZ_512M; | ||
112 | } else { | ||
113 | /* | ||
114 | * Otherwise just zero it out and disable it. | ||
115 | */ | ||
116 | __raw_writel(0, chan->reg_base + SH4_PCILAR1); | ||
117 | __raw_writel(0, chan->reg_base + SH4_PCILSR1); | ||
118 | } | ||
101 | 119 | ||
120 | /* | ||
121 | * LAR0/LSR0 covers up to the first 512MB, which is enough to | ||
122 | * cover all of lowmem on most platforms. | ||
123 | */ | ||
102 | __raw_writel(memphys, chan->reg_base + SH4_PCILAR0); | 124 | __raw_writel(memphys, chan->reg_base + SH4_PCILAR0); |
103 | __raw_writel((memsize - 1) << 9 | 1, | 125 | __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1, |
104 | chan->reg_base + SH4_PCILSR0); | 126 | chan->reg_base + SH4_PCILSR0); |
105 | 127 | ||
106 | /* Clear out PCI arbiter IRQs */ | 128 | /* Clear out PCI arbiter IRQs */ |