aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers/pci
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-01-31 21:33:22 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-01-31 21:33:22 -0500
commitaee4467b5ce5047401efb4175b1360ec1734affc (patch)
treec7c8a02b0c07c44cdf3b823e7ccd7b2fc2434cc8 /arch/sh/drivers/pci
parent31a090ae0693af189fc7a8ad16cece4878acad33 (diff)
sh: Fix up large system memory handling for SH7780 PCI.
For systems that have more than 512MB we need to set up an additional mapping, this fixes up the rounding to the next power of two and splits out the mapping accordingly between the two local bus mapping windows. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers/pci')
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c34
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 */