aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh')
-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 */