diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-orion/addr-map.c | 148 | ||||
-rw-r--r-- | arch/arm/mach-orion/common.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-orion/common.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-orion/pci.c | 171 |
4 files changed, 168 insertions, 158 deletions
diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c index ab4484cc14b7..69cd0876f6b9 100644 --- a/arch/arm/mach-orion/addr-map.c +++ b/arch/arm/mach-orion/addr-map.c | |||
@@ -93,56 +93,6 @@ | |||
93 | #define CPU_WIN_DEV_CS2 7 | 93 | #define CPU_WIN_DEV_CS2 7 |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * PCIE Address Decode Windows registers | ||
97 | */ | ||
98 | #define PCIE_BAR_CTRL(n) ORION_PCIE_REG(0x1804 + ((n - 1) * 4)) | ||
99 | #define PCIE_BAR_LO(n) ORION_PCIE_REG(0x0010 + ((n) * 8)) | ||
100 | #define PCIE_BAR_HI(n) ORION_PCIE_REG(0x0014 + ((n) * 8)) | ||
101 | #define PCIE_WIN_CTRL(n) (((n) < 5) ? \ | ||
102 | ORION_PCIE_REG(0x1820 + ((n) << 4)) : \ | ||
103 | ORION_PCIE_REG(0x1880)) | ||
104 | #define PCIE_WIN_BASE(n) (((n) < 5) ? \ | ||
105 | ORION_PCIE_REG(0x1824 + ((n) << 4)) : \ | ||
106 | ORION_PCIE_REG(0x1884)) | ||
107 | #define PCIE_WIN_REMAP(n) (((n) < 5) ? \ | ||
108 | ORION_PCIE_REG(0x182c + ((n) << 4)) : \ | ||
109 | ORION_PCIE_REG(0x188c)) | ||
110 | #define PCIE_DEFWIN_CTRL ORION_PCIE_REG(0x18b0) | ||
111 | #define PCIE_EXPROM_WIN_CTRL ORION_PCIE_REG(0x18c0) | ||
112 | #define PCIE_EXPROM_WIN_REMP ORION_PCIE_REG(0x18c4) | ||
113 | #define PCIE_MAX_BARS 3 | ||
114 | #define PCIE_MAX_WINS 6 | ||
115 | |||
116 | /* | ||
117 | * Use PCIE BAR '1' for all DDR banks | ||
118 | */ | ||
119 | #define PCIE_DRAM_BAR 1 | ||
120 | |||
121 | /* | ||
122 | * PCI Address Decode Windows registers | ||
123 | */ | ||
124 | #define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION_PCI_REG(0xc08) : \ | ||
125 | ((n) == 1) ? ORION_PCI_REG(0xd08) : \ | ||
126 | ((n) == 2) ? ORION_PCI_REG(0xc0c) : \ | ||
127 | ((n) == 3) ? ORION_PCI_REG(0xd0c) : 0) | ||
128 | #define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION_PCI_REG(0xc48) : \ | ||
129 | ((n) == 1) ? ORION_PCI_REG(0xd48) : \ | ||
130 | ((n) == 2) ? ORION_PCI_REG(0xc4c) : \ | ||
131 | ((n) == 3) ? ORION_PCI_REG(0xd4c) : 0) | ||
132 | #define PCI_BAR_ENABLE ORION_PCI_REG(0xc3c) | ||
133 | #define PCI_CTRL_BASE_LO(n) ORION_PCI_REG(0x1e00 | ((n) << 4)) | ||
134 | #define PCI_CTRL_BASE_HI(n) ORION_PCI_REG(0x1e04 | ((n) << 4)) | ||
135 | #define PCI_CTRL_SIZE(n) ORION_PCI_REG(0x1e08 | ((n) << 4)) | ||
136 | #define PCI_ADDR_DECODE_CTRL ORION_PCI_REG(0xd3c) | ||
137 | |||
138 | /* | ||
139 | * PCI configuration heleprs for BAR settings | ||
140 | */ | ||
141 | #define PCI_CONF_FUNC_BAR_CS(n) ((n) >> 1) | ||
142 | #define PCI_CONF_REG_BAR_LO_CS(n) (((n) & 1) ? 0x18 : 0x10) | ||
143 | #define PCI_CONF_REG_BAR_HI_CS(n) (((n) & 1) ? 0x1c : 0x14) | ||
144 | |||
145 | /* | ||
146 | * Gigabit Ethernet Address Decode Windows registers | 96 | * Gigabit Ethernet Address Decode Windows registers |
147 | */ | 97 | */ |
148 | #define ETH_WIN_BASE(win) ORION_ETH_REG(0x200 + ((win) * 8)) | 98 | #define ETH_WIN_BASE(win) ORION_ETH_REG(0x200 + ((win) * 8)) |
@@ -312,104 +262,6 @@ void __init orion_setup_cpu_wins(void) | |||
312 | orion_mbus_dram_info.num_cs = cs; | 262 | orion_mbus_dram_info.num_cs = cs; |
313 | } | 263 | } |
314 | 264 | ||
315 | /* | ||
316 | * Setup PCIE BARs and Address Decode Wins: | ||
317 | * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks | ||
318 | * WIN[0-3] -> DRAM bank[0-3] | ||
319 | */ | ||
320 | void __init orion_setup_pcie_wins(void) | ||
321 | { | ||
322 | u32 base, size, i; | ||
323 | |||
324 | /* | ||
325 | * First, disable and clear BARs and windows | ||
326 | */ | ||
327 | for (i = 1; i < PCIE_MAX_BARS; i++) { | ||
328 | orion_write(PCIE_BAR_CTRL(i), 0); | ||
329 | orion_write(PCIE_BAR_LO(i), 0); | ||
330 | orion_write(PCIE_BAR_HI(i), 0); | ||
331 | } | ||
332 | |||
333 | for (i = 0; i < PCIE_MAX_WINS; i++) { | ||
334 | orion_write(PCIE_WIN_CTRL(i), 0); | ||
335 | orion_write(PCIE_WIN_BASE(i), 0); | ||
336 | orion_write(PCIE_WIN_REMAP(i), 0); | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * Setup windows for DDR banks. Count total DDR size on the fly. | ||
341 | */ | ||
342 | base = DDR_REG_TO_BASE(orion_read(DDR_BASE_CS(0))); | ||
343 | size = 0; | ||
344 | for (i = 0; i < DDR_MAX_CS; i++) { | ||
345 | u32 bank_base, bank_size; | ||
346 | bank_size = orion_read(DDR_SIZE_CS(i)); | ||
347 | bank_base = orion_read(DDR_BASE_CS(i)); | ||
348 | if (bank_size & DDR_BANK_EN) { | ||
349 | bank_size = DDR_REG_TO_SIZE(bank_size); | ||
350 | bank_base = DDR_REG_TO_BASE(bank_base); | ||
351 | orion_write(PCIE_WIN_BASE(i), bank_base & 0xffff0000); | ||
352 | orion_write(PCIE_WIN_REMAP(i), 0); | ||
353 | orion_write(PCIE_WIN_CTRL(i), | ||
354 | ((bank_size-1) & 0xffff0000) | | ||
355 | (ATTR_DDR_CS(i) << 8) | | ||
356 | (TARGET_DDR << 4) | | ||
357 | (PCIE_DRAM_BAR << 1) | WIN_EN); | ||
358 | size += bank_size; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * Setup BAR[1] to all DRAM banks | ||
364 | */ | ||
365 | orion_write(PCIE_BAR_LO(PCIE_DRAM_BAR), base & 0xffff0000); | ||
366 | orion_write(PCIE_BAR_HI(PCIE_DRAM_BAR), 0); | ||
367 | orion_write(PCIE_BAR_CTRL(PCIE_DRAM_BAR), | ||
368 | ((size - 1) & 0xffff0000) | WIN_EN); | ||
369 | } | ||
370 | |||
371 | void __init orion_setup_pci_wins(void) | ||
372 | { | ||
373 | u32 base, size, i; | ||
374 | |||
375 | /* | ||
376 | * First, disable windows | ||
377 | */ | ||
378 | orion_write(PCI_BAR_ENABLE, 0xffffffff); | ||
379 | |||
380 | /* | ||
381 | * Setup windows for DDR banks. | ||
382 | */ | ||
383 | for (i = 0; i < DDR_MAX_CS; i++) { | ||
384 | base = orion_read(DDR_BASE_CS(i)); | ||
385 | size = orion_read(DDR_SIZE_CS(i)); | ||
386 | if (size & DDR_BANK_EN) { | ||
387 | u32 bus, dev, func, reg, val; | ||
388 | size = DDR_REG_TO_SIZE(size); | ||
389 | base = DDR_REG_TO_BASE(base); | ||
390 | bus = orion_pci_local_bus_nr(); | ||
391 | dev = orion_pci_local_dev_nr(); | ||
392 | func = PCI_CONF_FUNC_BAR_CS(i); | ||
393 | reg = PCI_CONF_REG_BAR_LO_CS(i); | ||
394 | orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val); | ||
395 | orion_pci_hw_wr_conf(bus, dev, func, reg, 4, | ||
396 | (base & 0xfffff000) | (val & 0xfff)); | ||
397 | reg = PCI_CONF_REG_BAR_HI_CS(i); | ||
398 | orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0); | ||
399 | orion_write(PCI_BAR_SIZE_DDR_CS(i), | ||
400 | (size - 1) & 0xfffff000); | ||
401 | orion_write(PCI_BAR_REMAP_DDR_CS(i), | ||
402 | base & 0xfffff000); | ||
403 | orion_clrbits(PCI_BAR_ENABLE, (1 << i)); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | /* | ||
408 | * Disable automatic update of address remaping when writing to BARs | ||
409 | */ | ||
410 | orion_setbits(PCI_ADDR_DECODE_CTRL, 1); | ||
411 | } | ||
412 | |||
413 | void __init orion_setup_usb_wins(void) | 265 | void __init orion_setup_usb_wins(void) |
414 | { | 266 | { |
415 | int i; | 267 | int i; |
diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index cd9aa43bb474..cc16588e8c0c 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c | |||
@@ -336,8 +336,6 @@ void __init orion_init(void) | |||
336 | orion_setup_cpu_wins(); | 336 | orion_setup_cpu_wins(); |
337 | orion_setup_usb_wins(); | 337 | orion_setup_usb_wins(); |
338 | orion_setup_eth_wins(); | 338 | orion_setup_eth_wins(); |
339 | orion_setup_pci_wins(); | ||
340 | orion_setup_pcie_wins(); | ||
341 | if (dev == MV88F5182_DEV_ID) | 339 | if (dev == MV88F5182_DEV_ID) |
342 | orion_setup_sata_wins(); | 340 | orion_setup_sata_wins(); |
343 | 341 | ||
diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 2718245ec4ae..961daaa0b91b 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h | |||
@@ -34,8 +34,6 @@ void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap | |||
34 | void orion_setup_cpu_wins(void); | 34 | void orion_setup_cpu_wins(void); |
35 | void orion_setup_eth_wins(void); | 35 | void orion_setup_eth_wins(void); |
36 | void orion_setup_usb_wins(void); | 36 | void orion_setup_usb_wins(void); |
37 | void orion_setup_pci_wins(void); | ||
38 | void orion_setup_pcie_wins(void); | ||
39 | void orion_setup_sata_wins(void); | 37 | void orion_setup_sata_wins(void); |
40 | 38 | ||
41 | /* | 39 | /* |
@@ -49,11 +47,8 @@ struct pci_bus; | |||
49 | void orion_pcie_id(u32 *dev, u32 *rev); | 47 | void orion_pcie_id(u32 *dev, u32 *rev); |
50 | u32 orion_pcie_local_bus_nr(void); | 48 | u32 orion_pcie_local_bus_nr(void); |
51 | u32 orion_pci_local_bus_nr(void); | 49 | u32 orion_pci_local_bus_nr(void); |
52 | u32 orion_pci_local_dev_nr(void); | ||
53 | int orion_pci_sys_setup(int nr, struct pci_sys_data *sys); | 50 | int orion_pci_sys_setup(int nr, struct pci_sys_data *sys); |
54 | struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); | 51 | struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); |
55 | int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 *val); | ||
56 | int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 val); | ||
57 | 52 | ||
58 | /* | 53 | /* |
59 | * Valid GPIO pins according to MPP setup, used by machine-setup. | 54 | * Valid GPIO pins according to MPP setup, used by machine-setup. |
diff --git a/arch/arm/mach-orion/pci.c b/arch/arm/mach-orion/pci.c index b109bb46681e..cfd3d064c209 100644 --- a/arch/arm/mach-orion/pci.c +++ b/arch/arm/mach-orion/pci.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/mbus.h> | ||
15 | #include <asm/mach/pci.h> | 16 | #include <asm/mach/pci.h> |
16 | #include "common.h" | 17 | #include "common.h" |
17 | 18 | ||
@@ -59,6 +60,29 @@ | |||
59 | #define PCIE_CONF_ADDR_EN (1 << 31) | 60 | #define PCIE_CONF_ADDR_EN (1 << 31) |
60 | 61 | ||
61 | /* | 62 | /* |
63 | * PCIE Address Decode Windows registers | ||
64 | */ | ||
65 | #define PCIE_BAR_CTRL(n) ORION_PCIE_REG(0x1804 + ((n - 1) * 4)) | ||
66 | #define PCIE_BAR_LO(n) ORION_PCIE_REG(0x0010 + ((n) * 8)) | ||
67 | #define PCIE_BAR_HI(n) ORION_PCIE_REG(0x0014 + ((n) * 8)) | ||
68 | #define PCIE_WIN_CTRL(n) (((n) < 5) ? \ | ||
69 | ORION_PCIE_REG(0x1820 + ((n) << 4)) : \ | ||
70 | ORION_PCIE_REG(0x1880)) | ||
71 | #define PCIE_WIN_BASE(n) (((n) < 5) ? \ | ||
72 | ORION_PCIE_REG(0x1824 + ((n) << 4)) : \ | ||
73 | ORION_PCIE_REG(0x1884)) | ||
74 | #define PCIE_WIN_REMAP(n) (((n) < 5) ? \ | ||
75 | ORION_PCIE_REG(0x182c + ((n) << 4)) : \ | ||
76 | ORION_PCIE_REG(0x188c)) | ||
77 | #define PCIE_MAX_BARS 3 | ||
78 | #define PCIE_MAX_WINS 6 | ||
79 | |||
80 | /* | ||
81 | * Use PCIE BAR '1' for all DDR banks | ||
82 | */ | ||
83 | #define PCIE_DRAM_BAR 1 | ||
84 | |||
85 | /* | ||
62 | * PCIE config cycles are done by programming the PCIE_CONF_ADDR register | 86 | * PCIE config cycles are done by programming the PCIE_CONF_ADDR register |
63 | * and then reading the PCIE_CONF_DATA register. Need to make sure these | 87 | * and then reading the PCIE_CONF_DATA register. Need to make sure these |
64 | * transactions are atomic. | 88 | * transactions are atomic. |
@@ -95,6 +119,56 @@ static void orion_pcie_set_bus_nr(int nr) | |||
95 | orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS); | 119 | orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS); |
96 | } | 120 | } |
97 | 121 | ||
122 | /* | ||
123 | * Setup PCIE BARs and Address Decode Wins: | ||
124 | * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks | ||
125 | * WIN[0-3] -> DRAM bank[0-3] | ||
126 | */ | ||
127 | static void orion_setup_pcie_wins(struct mbus_dram_target_info *dram) | ||
128 | { | ||
129 | u32 size; | ||
130 | int i; | ||
131 | |||
132 | /* | ||
133 | * First, disable and clear BARs and windows | ||
134 | */ | ||
135 | for (i = 1; i < PCIE_MAX_BARS; i++) { | ||
136 | writel(0, PCIE_BAR_CTRL(i)); | ||
137 | writel(0, PCIE_BAR_LO(i)); | ||
138 | writel(0, PCIE_BAR_HI(i)); | ||
139 | } | ||
140 | |||
141 | for (i = 0; i < PCIE_MAX_WINS; i++) { | ||
142 | writel(0, PCIE_WIN_CTRL(i)); | ||
143 | writel(0, PCIE_WIN_BASE(i)); | ||
144 | writel(0, PCIE_WIN_REMAP(i)); | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Setup windows for DDR banks. Count total DDR size on the fly. | ||
149 | */ | ||
150 | size = 0; | ||
151 | for (i = 0; i < dram->num_cs; i++) { | ||
152 | struct mbus_dram_window *cs = dram->cs + i; | ||
153 | |||
154 | writel(cs->base & 0xffff0000, PCIE_WIN_BASE(i)); | ||
155 | writel(0, PCIE_WIN_REMAP(i)); | ||
156 | writel(((cs->size - 1) & 0xffff0000) | | ||
157 | (cs->mbus_attr << 8) | | ||
158 | (dram->mbus_dram_target_id << 4) | | ||
159 | (PCIE_DRAM_BAR << 1) | 1, PCIE_WIN_CTRL(i)); | ||
160 | |||
161 | size += cs->size; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * Setup BAR[1] to all DRAM banks | ||
166 | */ | ||
167 | writel(dram->cs[0].base, PCIE_BAR_LO(PCIE_DRAM_BAR)); | ||
168 | writel(0, PCIE_BAR_HI(PCIE_DRAM_BAR)); | ||
169 | writel(((size - 1) & 0xffff0000) | 1, PCIE_BAR_CTRL(PCIE_DRAM_BAR)); | ||
170 | } | ||
171 | |||
98 | static void orion_pcie_master_slave_enable(void) | 172 | static void orion_pcie_master_slave_enable(void) |
99 | { | 173 | { |
100 | orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER | | 174 | orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER | |
@@ -220,6 +294,11 @@ static int orion_pcie_setup(struct pci_sys_data *sys) | |||
220 | struct resource *res; | 294 | struct resource *res; |
221 | 295 | ||
222 | /* | 296 | /* |
297 | * Point PCIe unit MBUS decode windows to DRAM space. | ||
298 | */ | ||
299 | orion_setup_pcie_wins(&orion_mbus_dram_info); | ||
300 | |||
301 | /* | ||
223 | * Master + Slave enable | 302 | * Master + Slave enable |
224 | */ | 303 | */ |
225 | orion_pcie_master_slave_enable(); | 304 | orion_pcie_master_slave_enable(); |
@@ -311,6 +390,27 @@ static int orion_pcie_setup(struct pci_sys_data *sys) | |||
311 | #define PCIX_STAT_BUS_MASK (0xff << PCIX_STAT_BUS_OFFS) | 390 | #define PCIX_STAT_BUS_MASK (0xff << PCIX_STAT_BUS_OFFS) |
312 | 391 | ||
313 | /* | 392 | /* |
393 | * PCI Address Decode Windows registers | ||
394 | */ | ||
395 | #define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION_PCI_REG(0xc08) : \ | ||
396 | ((n) == 1) ? ORION_PCI_REG(0xd08) : \ | ||
397 | ((n) == 2) ? ORION_PCI_REG(0xc0c) : \ | ||
398 | ((n) == 3) ? ORION_PCI_REG(0xd0c) : 0) | ||
399 | #define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION_PCI_REG(0xc48) : \ | ||
400 | ((n) == 1) ? ORION_PCI_REG(0xd48) : \ | ||
401 | ((n) == 2) ? ORION_PCI_REG(0xc4c) : \ | ||
402 | ((n) == 3) ? ORION_PCI_REG(0xd4c) : 0) | ||
403 | #define PCI_BAR_ENABLE ORION_PCI_REG(0xc3c) | ||
404 | #define PCI_ADDR_DECODE_CTRL ORION_PCI_REG(0xd3c) | ||
405 | |||
406 | /* | ||
407 | * PCI configuration helpers for BAR settings | ||
408 | */ | ||
409 | #define PCI_CONF_FUNC_BAR_CS(n) ((n) >> 1) | ||
410 | #define PCI_CONF_REG_BAR_LO_CS(n) (((n) & 1) ? 0x18 : 0x10) | ||
411 | #define PCI_CONF_REG_BAR_HI_CS(n) (((n) & 1) ? 0x1c : 0x14) | ||
412 | |||
413 | /* | ||
314 | * PCI config cycles are done by programming the PCI_CONF_ADDR register | 414 | * PCI config cycles are done by programming the PCI_CONF_ADDR register |
315 | * and then reading the PCI_CONF_DATA register. Need to make sure these | 415 | * and then reading the PCI_CONF_DATA register. Need to make sure these |
316 | * transactions are atomic. | 416 | * transactions are atomic. |
@@ -323,13 +423,13 @@ u32 orion_pci_local_bus_nr(void) | |||
323 | return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); | 423 | return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); |
324 | } | 424 | } |
325 | 425 | ||
326 | u32 orion_pci_local_dev_nr(void) | 426 | static u32 orion_pci_local_dev_nr(void) |
327 | { | 427 | { |
328 | u32 conf = orion_read(PCI_P2P_CONF); | 428 | u32 conf = orion_read(PCI_P2P_CONF); |
329 | return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS); | 429 | return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS); |
330 | } | 430 | } |
331 | 431 | ||
332 | int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, | 432 | static int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, |
333 | u32 where, u32 size, u32 *val) | 433 | u32 where, u32 size, u32 *val) |
334 | { | 434 | { |
335 | unsigned long flags; | 435 | unsigned long flags; |
@@ -351,7 +451,7 @@ int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, | |||
351 | return PCIBIOS_SUCCESSFUL; | 451 | return PCIBIOS_SUCCESSFUL; |
352 | } | 452 | } |
353 | 453 | ||
354 | int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, | 454 | static int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, |
355 | u32 where, u32 size, u32 val) | 455 | u32 where, u32 size, u32 val) |
356 | { | 456 | { |
357 | unsigned long flags; | 457 | unsigned long flags; |
@@ -451,11 +551,76 @@ static void orion_pci_master_slave_enable(void) | |||
451 | orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7); | 551 | orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7); |
452 | } | 552 | } |
453 | 553 | ||
554 | static void orion_setup_pci_wins(struct mbus_dram_target_info *dram) | ||
555 | { | ||
556 | u32 win_enable; | ||
557 | u32 bus; | ||
558 | u32 dev; | ||
559 | int i; | ||
560 | |||
561 | /* | ||
562 | * First, disable windows. | ||
563 | */ | ||
564 | win_enable = 0xffffffff; | ||
565 | orion_write(PCI_BAR_ENABLE, win_enable); | ||
566 | |||
567 | /* | ||
568 | * Setup windows for DDR banks. | ||
569 | */ | ||
570 | bus = orion_pci_local_bus_nr(); | ||
571 | dev = orion_pci_local_dev_nr(); | ||
572 | |||
573 | for (i = 0; i < dram->num_cs; i++) { | ||
574 | struct mbus_dram_window *cs = dram->cs + i; | ||
575 | u32 func = PCI_CONF_FUNC_BAR_CS(cs->cs_index); | ||
576 | u32 reg; | ||
577 | u32 val; | ||
578 | |||
579 | /* | ||
580 | * Write DRAM bank base address register. | ||
581 | */ | ||
582 | reg = PCI_CONF_REG_BAR_LO_CS(cs->cs_index); | ||
583 | orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val); | ||
584 | val = (cs->base & 0xfffff000) | (val & 0xfff); | ||
585 | orion_pci_hw_wr_conf(bus, dev, func, reg, 4, val); | ||
586 | |||
587 | /* | ||
588 | * Write DRAM bank size register. | ||
589 | */ | ||
590 | reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index); | ||
591 | orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0); | ||
592 | orion_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index), | ||
593 | (cs->size - 1) & 0xfffff000); | ||
594 | orion_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index), | ||
595 | cs->base & 0xfffff000); | ||
596 | |||
597 | /* | ||
598 | * Enable decode window for this chip select. | ||
599 | */ | ||
600 | win_enable &= ~(1 << cs->cs_index); | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * Re-enable decode windows. | ||
605 | */ | ||
606 | orion_write(PCI_BAR_ENABLE, win_enable); | ||
607 | |||
608 | /* | ||
609 | * Disable automatic update of address remaping when writing to BARs. | ||
610 | */ | ||
611 | orion_setbits(PCI_ADDR_DECODE_CTRL, 1); | ||
612 | } | ||
613 | |||
454 | static int orion_pci_setup(struct pci_sys_data *sys) | 614 | static int orion_pci_setup(struct pci_sys_data *sys) |
455 | { | 615 | { |
456 | struct resource *res; | 616 | struct resource *res; |
457 | 617 | ||
458 | /* | 618 | /* |
619 | * Point PCI unit MBUS decode windows to DRAM space. | ||
620 | */ | ||
621 | orion_setup_pci_wins(&orion_mbus_dram_info); | ||
622 | |||
623 | /* | ||
459 | * Master + Slave enable | 624 | * Master + Slave enable |
460 | */ | 625 | */ |
461 | orion_pci_master_slave_enable(); | 626 | orion_pci_master_slave_enable(); |