]>
Commit | Line | Data |
---|---|---|
4d75a504 WD |
1 | /* |
2 | * (C) Copyright 2003 | |
3 | * Wolfgang Denk, DENX Software Engineering, [email protected]. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <common.h> | |
25 | ||
26 | #ifdef CONFIG_PCI | |
27 | ||
28 | #include <pci.h> | |
5d232d0e | 29 | #include <mpc8260.h> |
4d75a504 WD |
30 | #include <asm/m8260_pci.h> |
31 | ||
32 | /* | |
33 | * Local->PCI map (from CPU) controlled by | |
34 | * MPC826x master window | |
35 | * | |
5d232d0e WD |
36 | * 0x80000000 - 0xBFFFFFFF CPU2PCI space PCIBR0 |
37 | * 0xF4000000 - 0xF7FFFFFF CPU2PCI space PCIBR1 | |
8bde7f77 | 38 | * |
5d232d0e WD |
39 | * 0x80000000 - 0x9FFFFFFF 0x80000000 - 0x9FFFFFFF (Outbound ATU #1) |
40 | * PCI Mem with prefetch | |
41 | * | |
42 | * 0xA0000000 - 0xBFFFFFFF 0xA0000000 - 0xBFFFFFFF (Outbound ATU #2) | |
43 | * PCI Mem w/o prefetch | |
44 | * | |
45 | * 0xF4000000 - 0xF7FFFFFF 0x00000000 - 0x03FFFFFF (Outbound ATU #3) | |
46 | * 32-bit PCI IO | |
8bde7f77 | 47 | * |
4d75a504 WD |
48 | * PCI->Local map (from PCI) |
49 | * MPC826x slave window controlled by | |
50 | * | |
5d232d0e WD |
51 | * 0x00000000 - 0x1FFFFFFF 0x00000000 - 0x1FFFFFFF (Inbound ATU #1) |
52 | * MPC826x local memory | |
4d75a504 WD |
53 | */ |
54 | ||
8bde7f77 WD |
55 | /* |
56 | * Slave window that allows PCI masters to access MPC826x local memory. | |
4d75a504 WD |
57 | * This window is set up using the first set of Inbound ATU registers |
58 | */ | |
59 | ||
8bde7f77 WD |
60 | #ifndef CFG_PCI_SLV_MEM_LOCAL |
61 | #define PCI_SLV_MEM_LOCAL CFG_SDRAM_BASE /* Local base */ | |
62 | #else | |
63 | #define PCI_SLV_MEM_LOCAL CFG_PCI_SLV_MEM_LOCAL | |
5d232d0e WD |
64 | #endif |
65 | ||
66 | #ifndef CFG_PCI_SLV_MEM_BUS | |
67 | #define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */ | |
68 | #else | |
69 | #define PCI_SLV_MEM_BUS CFG_PCI_SLV_MEM_BUS | |
70 | #endif | |
71 | ||
72 | #ifndef CFG_PICMR0_MASK_ATTRIB | |
4d75a504 | 73 | #define PICMR0_MASK_ATTRIB (PICMR_MASK_512MB | PICMR_ENABLE | \ |
8bde7f77 | 74 | PICMR_PREFETCH_EN) |
5d232d0e WD |
75 | #else |
76 | #define PICMR0_MASK_ATTRIB CFG_PICMR0_MASK_ATTRIB | |
77 | #endif | |
4d75a504 | 78 | |
8bde7f77 | 79 | /* |
5d232d0e | 80 | * These are the windows that allow the CPU to access PCI address space. |
8bde7f77 WD |
81 | * All three PCI master windows, which allow the CPU to access PCI |
82 | * prefetch, non prefetch, and IO space (see below), must all fit within | |
5d232d0e | 83 | * these windows. |
4d75a504 WD |
84 | */ |
85 | ||
5d232d0e WD |
86 | /* PCIBR0 */ |
87 | #ifndef CFG_PCI_MSTR0_LOCAL | |
8bde7f77 WD |
88 | #define PCI_MSTR0_LOCAL 0x80000000 /* Local base */ |
89 | #else | |
5d232d0e WD |
90 | #define PCI_MSTR0_LOCAL CFG_PCI_MSTR0_LOCAL |
91 | #endif | |
92 | ||
93 | #ifndef CFG_PCIMSK0_MASK | |
4d75a504 | 94 | #define PCIMSK0_MASK PCIMSK_1GB /* Size of window */ |
5d232d0e WD |
95 | #else |
96 | #define PCIMSK0_MASK CFG_PCIMSK0_MASK | |
97 | #endif | |
98 | ||
99 | /* PCIBR1 */ | |
100 | #ifndef CFG_PCI_MSTR1_LOCAL | |
8bde7f77 WD |
101 | #define PCI_MSTR1_LOCAL 0xF4000000 /* Local base */ |
102 | #else | |
103 | #define PCI_MSTR1_LOCAL CFG_PCI_MSTR1_LOCAL | |
5d232d0e WD |
104 | #endif |
105 | ||
106 | #ifndef CFG_PCIMSK1_MASK | |
107 | #define PCIMSK1_MASK PCIMSK_64MB /* Size of window */ | |
108 | #else | |
109 | #define PCIMSK1_MASK CFG_PCIMSK1_MASK | |
110 | #endif | |
4d75a504 | 111 | |
8bde7f77 | 112 | /* |
4d75a504 WD |
113 | * Master window that allows the CPU to access PCI Memory (prefetch). |
114 | * This window will be setup with the first set of Outbound ATU registers | |
115 | * in the bridge. | |
116 | */ | |
117 | ||
5d232d0e WD |
118 | #ifndef CFG_PCI_MSTR_MEM_LOCAL |
119 | #define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */ | |
120 | #else | |
121 | #define PCI_MSTR_MEM_LOCAL CFG_PCI_MSTR_MEM_LOCAL | |
122 | #endif | |
123 | ||
124 | #ifndef CFG_PCI_MSTR_MEM_BUS | |
125 | #define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */ | |
126 | #else | |
127 | #define PCI_MSTR_MEM_BUS CFG_PCI_MSTR_MEM_BUS | |
128 | #endif | |
129 | ||
130 | #ifndef CFG_CPU_PCI_MEM_START | |
131 | #define CPU_PCI_MEM_START PCI_MSTR_MEM_LOCAL | |
132 | #else | |
133 | #define CPU_PCI_MEM_START CFG_CPU_PCI_MEM_START | |
134 | #endif | |
135 | ||
136 | #ifndef CFG_PCI_MSTR_MEM_SIZE | |
137 | #define PCI_MSTR_MEM_SIZE 0x10000000 /* 256MB */ | |
138 | #else | |
139 | #define PCI_MSTR_MEM_SIZE CFG_PCI_MSTR_MEM_SIZE | |
140 | #endif | |
141 | ||
142 | #ifndef CFG_POCMR0_MASK_ATTRIB | |
4d75a504 | 143 | #define POCMR0_MASK_ATTRIB (POCMR_MASK_256MB | POCMR_ENABLE | POCMR_PREFETCH_EN) |
5d232d0e WD |
144 | #else |
145 | #define POCMR0_MASK_ATTRIB CFG_POCMR0_MASK_ATTRIB | |
146 | #endif | |
4d75a504 | 147 | |
8bde7f77 | 148 | /* |
4d75a504 WD |
149 | * Master window that allows the CPU to access PCI Memory (non-prefetch). |
150 | * This window will be setup with the second set of Outbound ATU registers | |
151 | * in the bridge. | |
152 | */ | |
153 | ||
8bde7f77 WD |
154 | #ifndef CFG_PCI_MSTR_MEMIO_LOCAL |
155 | #define PCI_MSTR_MEMIO_LOCAL 0x90000000 /* Local base */ | |
156 | #else | |
157 | #define PCI_MSTR_MEMIO_LOCAL CFG_PCI_MSTR_MEMIO_LOCAL | |
5d232d0e WD |
158 | #endif |
159 | ||
8bde7f77 WD |
160 | #ifndef CFG_PCI_MSTR_MEMIO_BUS |
161 | #define PCI_MSTR_MEMIO_BUS 0x90000000 /* PCI base */ | |
162 | #else | |
163 | #define PCI_MSTR_MEMIO_BUS CFG_PCI_MSTR_MEMIO_BUS | |
5d232d0e WD |
164 | #endif |
165 | ||
8bde7f77 WD |
166 | #ifndef CFG_CPU_PCI_MEMIO_START |
167 | #define CPU_PCI_MEMIO_START PCI_MSTR_MEMIO_LOCAL | |
168 | #else | |
169 | #define CPU_PCI_MEMIO_START CFG_CPU_PCI_MEMIO_START | |
5d232d0e WD |
170 | #endif |
171 | ||
8bde7f77 WD |
172 | #ifndef CFG_PCI_MSTR_MEMIO_SIZE |
173 | #define PCI_MSTR_MEMIO_SIZE 0x10000000 /* 256 MB */ | |
174 | #else | |
175 | #define PCI_MSTR_MEMIO_SIZE CFG_PCI_MSTR_MEMIO_SIZE | |
5d232d0e WD |
176 | #endif |
177 | ||
178 | #ifndef CFG_POCMR1_MASK_ATTRIB | |
179 | #define POCMR1_MASK_ATTRIB (POCMR_MASK_512MB | POCMR_ENABLE) | |
180 | #else | |
181 | #define POCMR1_MASK_ATTRIB CFG_POCMR1_MASK_ATTRIB | |
182 | #endif | |
4d75a504 | 183 | |
8bde7f77 | 184 | /* |
4d75a504 WD |
185 | * Master window that allows the CPU to access PCI IO space. |
186 | * This window will be setup with the third set of Outbound ATU registers | |
187 | * in the bridge. | |
188 | */ | |
189 | ||
8bde7f77 WD |
190 | #ifndef CFG_PCI_MSTR_IO_LOCAL |
191 | #define PCI_MSTR_IO_LOCAL 0xA0000000 /* Local base */ | |
192 | #else | |
193 | #define PCI_MSTR_IO_LOCAL CFG_PCI_MSTR_IO_LOCAL | |
5d232d0e WD |
194 | #endif |
195 | ||
8bde7f77 WD |
196 | #ifndef CFG_PCI_MSTR_IO_BUS |
197 | #define PCI_MSTR_IO_BUS 0xA0000000 /* PCI base */ | |
198 | #else | |
199 | #define PCI_MSTR_IO_BUS CFG_PCI_MSTR_IO_BUS | |
5d232d0e WD |
200 | #endif |
201 | ||
8bde7f77 WD |
202 | #ifndef CFG_CPU_PCI_IO_START |
203 | #define CPU_PCI_IO_START PCI_MSTR_IO_LOCAL | |
204 | #else | |
205 | #define CPU_PCI_IO_START CFG_CPU_PCI_IO_START | |
5d232d0e WD |
206 | #endif |
207 | ||
8bde7f77 WD |
208 | #ifndef CFG_PCI_MSTR_IO_SIZE |
209 | #define PCI_MSTR_IO_SIZE 0x10000000 /* 256MB */ | |
210 | #else | |
211 | #define PCI_MSTR_IO_SIZE CFG_PCI_MSTR_IO_SIZE | |
66fd3d1c | 212 | #endif |
5d232d0e WD |
213 | |
214 | #ifndef CFG_POCMR2_MASK_ATTRIB | |
4d75a504 | 215 | #define POCMR2_MASK_ATTRIB (POCMR_MASK_256MB | POCMR_ENABLE | POCMR_PCI_IO) |
5d232d0e WD |
216 | #else |
217 | #define POCMR2_MASK_ATTRIB CFG_POCMR2_MASK_ATTRIB | |
218 | #endif | |
4d75a504 WD |
219 | |
220 | /* PCI bus configuration registers. | |
221 | */ | |
222 | ||
223 | #define PCI_CLASS_BRIDGE_CTLR 0x06 | |
224 | ||
225 | ||
226 | static inline void pci_outl(u32 addr, u32 data) | |
227 | { | |
228 | *(volatile u32 *) addr = cpu_to_le32(data); | |
229 | } | |
230 | ||
231 | void pci_mpc8250_init(struct pci_controller *hose) | |
232 | { | |
5d232d0e WD |
233 | #ifdef CONFIG_MPC8266ADS |
234 | DECLARE_GLOBAL_DATA_PTR; | |
235 | #endif | |
4d75a504 WD |
236 | u16 tempShort; |
237 | u32 immr_addr = CFG_IMMR; | |
238 | volatile immap_t *immap = (immap_t *) CFG_IMMR; | |
239 | pci_dev_t host_devno = PCI_BDF(0, 0, 0); | |
240 | ||
241 | pci_setup_indirect(hose, CFG_IMMR + PCI_CFG_ADDR_REG, | |
8bde7f77 | 242 | CFG_IMMR + PCI_CFG_DATA_REG); |
4d75a504 | 243 | |
5d232d0e WD |
244 | /* |
245 | * Setting required to enable local bus for PCI (SIUMCR [LBPC]). | |
246 | */ | |
247 | #ifdef CONFIG_MPC8266ADS | |
248 | immap->im_siu_conf.sc_siumcr = (immap->im_siu_conf.sc_siumcr & ~SIUMCR_LBPC11) | |
249 | | SIUMCR_LBPC01; | |
250 | #else | |
8bde7f77 WD |
251 | /* |
252 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | |
4d75a504 WD |
253 | * and local bus for PCI (SIUMCR [LBPC]). |
254 | */ | |
8bde7f77 WD |
255 | immap->im_siu_conf.sc_siumcr = (immap->im_siu_conf.sc_siumcr & |
256 | ~SIUMCR_LBPC11 & | |
257 | ~SIUMCR_CS10PC11 & | |
15ef8a5d | 258 | ~SIUMCR_LBPC11) | |
8bde7f77 WD |
259 | SIUMCR_LBPC01 | |
260 | SIUMCR_CS10PC01 | | |
15ef8a5d | 261 | SIUMCR_LBPC01; |
5d232d0e | 262 | #endif |
4d75a504 WD |
263 | |
264 | /* Make PCI lowest priority */ | |
8bde7f77 | 265 | /* Each 4 bits is a device bus request and the MS 4bits |
4d75a504 | 266 | is highest priority */ |
8bde7f77 | 267 | /* Bus 4bit value |
4d75a504 WD |
268 | --- ---------- |
269 | CPM high 0b0000 | |
270 | CPM middle 0b0001 | |
271 | CPM low 0b0010 | |
272 | PCI reguest 0b0011 | |
273 | Reserved 0b0100 | |
274 | Reserved 0b0101 | |
275 | Internal Core 0b0110 | |
276 | External Master 1 0b0111 | |
277 | External Master 2 0b1000 | |
278 | External Master 3 0b1001 | |
279 | The rest are reserved */ | |
280 | immap->im_siu_conf.sc_ppc_alrh = 0x61207893; | |
281 | ||
282 | /* Park bus on core while modifying PCI Bus accesses */ | |
283 | immap->im_siu_conf.sc_ppc_acr = 0x6; | |
284 | ||
8bde7f77 WD |
285 | /* |
286 | * Set up master windows that allow the CPU to access PCI space. These | |
5d232d0e | 287 | * windows are set up using the two SIU PCIBR registers. |
4d75a504 WD |
288 | */ |
289 | *(volatile unsigned long*)(immr_addr + M8265_PCIMSK0) = PCIMSK0_MASK; | |
290 | *(volatile unsigned long*)(immr_addr + M8265_PCIBR0) = | |
5d232d0e WD |
291 | PCI_MSTR0_LOCAL | PCIBR_ENABLE; |
292 | ||
293 | #ifdef CONFIG_MPC8266ADS | |
294 | *(volatile unsigned long*)(immr_addr + M8265_PCIMSK1) = PCIMSK1_MASK; | |
295 | *(volatile unsigned long*)(immr_addr + M8265_PCIBR1) = | |
296 | PCI_MSTR1_LOCAL | PCIBR_ENABLE; | |
8bde7f77 | 297 | #endif |
4d75a504 WD |
298 | |
299 | /* Release PCI RST (by default the PCI RST signal is held low) */ | |
300 | pci_outl (immr_addr | PCI_GCR_REG, PCIGCR_PCI_BUS_EN); | |
301 | ||
302 | /* give it some time */ | |
5d232d0e | 303 | { |
8bde7f77 WD |
304 | #ifdef CONFIG_MPC8266ADS |
305 | /* Give the PCI cards more time to initialize before query | |
5d232d0e WD |
306 | This might be good for other boards also |
307 | */ | |
8bde7f77 WD |
308 | int i; |
309 | for (i = 0; i < 1000; ++i) | |
5d232d0e | 310 | #endif |
8bde7f77 | 311 | udelay(1000); |
5d232d0e | 312 | } |
4d75a504 | 313 | |
8bde7f77 WD |
314 | /* |
315 | * Set up master window that allows the CPU to access PCI Memory (prefetch) | |
4d75a504 WD |
316 | * space. This window is set up using the first set of Outbound ATU registers. |
317 | */ | |
318 | pci_outl (immr_addr | POTAR_REG0, PCI_MSTR_MEM_BUS >> 12); /* PCI base */ | |
319 | pci_outl (immr_addr | POBAR_REG0, PCI_MSTR_MEM_LOCAL >> 12); /* Local base */ | |
320 | pci_outl (immr_addr | POCMR_REG0, POCMR0_MASK_ATTRIB); /* Size & attribute */ | |
321 | ||
8bde7f77 WD |
322 | /* |
323 | * Set up master window that allows the CPU to access PCI Memory (non-prefetch) | |
4d75a504 WD |
324 | * space. This window is set up using the second set of Outbound ATU registers. |
325 | */ | |
326 | pci_outl (immr_addr | POTAR_REG1, PCI_MSTR_MEMIO_BUS >> 12); /* PCI base */ | |
327 | pci_outl (immr_addr | POBAR_REG1, PCI_MSTR_MEMIO_LOCAL >> 12); /* Local base */ | |
328 | pci_outl (immr_addr | POCMR_REG1, POCMR1_MASK_ATTRIB); /* Size & attribute */ | |
8bde7f77 WD |
329 | |
330 | /* | |
4d75a504 WD |
331 | * Set up master window that allows the CPU to access PCI IO space. This window |
332 | * is set up using the third set of Outbound ATU registers. | |
333 | */ | |
334 | pci_outl (immr_addr | POTAR_REG2, PCI_MSTR_IO_BUS >> 12); /* PCI base */ | |
335 | pci_outl (immr_addr | POBAR_REG2, PCI_MSTR_IO_LOCAL >> 12); /* Local base */ | |
336 | pci_outl (immr_addr | POCMR_REG2, POCMR2_MASK_ATTRIB); /* Size & attribute */ | |
337 | ||
8bde7f77 WD |
338 | /* |
339 | * Set up slave window that allows PCI masters to access MPC826x local memory. | |
4d75a504 WD |
340 | * This window is set up using the first set of Inbound ATU registers |
341 | */ | |
342 | pci_outl (immr_addr | PITAR_REG0, PCI_SLV_MEM_LOCAL >> 12); /* Local base */ | |
343 | pci_outl (immr_addr | PIBAR_REG0, PCI_SLV_MEM_BUS >> 12); /* PCI base */ | |
344 | pci_outl (immr_addr | PICMR_REG0, PICMR0_MASK_ATTRIB); /* Size & attribute */ | |
345 | ||
346 | /* See above for description - puts PCI request as highest priority */ | |
347 | immap->im_siu_conf.sc_ppc_alrh = 0x03124567; | |
348 | ||
349 | /* Park the bus on the PCI */ | |
350 | immap->im_siu_conf.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | |
351 | ||
352 | /* Host mode - specify the bridge as a host-PCI bridge */ | |
353 | ||
354 | pci_hose_write_config_byte(hose, host_devno, PCI_CLASS_CODE, | |
8bde7f77 | 355 | PCI_CLASS_BRIDGE_CTLR); |
4d75a504 WD |
356 | |
357 | /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */ | |
358 | pci_hose_read_config_word(hose, host_devno, PCI_COMMAND, &tempShort); | |
359 | pci_hose_write_config_word(hose, host_devno, PCI_COMMAND, | |
8bde7f77 | 360 | tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); |
4d75a504 | 361 | |
7a8e9bed WD |
362 | #ifdef CONFIG_MPC8266ADS |
363 | /* do some bridge init, should be done on all 8260 based bridges */ | |
364 | pci_hose_write_config_byte(hose, host_devno, PCI_CACHE_LINE_SIZE, 0x08); | |
365 | pci_hose_write_config_byte(hose, host_devno, PCI_LATENCY_TIMER, 0xF8); | |
8bde7f77 | 366 | #endif |
7a8e9bed | 367 | |
4d75a504 WD |
368 | hose->first_busno = 0; |
369 | hose->last_busno = 0xff; | |
370 | ||
371 | /* System memory space */ | |
5d232d0e WD |
372 | #ifdef CONFIG_MPC8266ADS |
373 | pci_set_region(hose->regions + 0, | |
374 | PCI_SLV_MEM_BUS, | |
375 | PCI_SLV_MEM_LOCAL, | |
376 | gd->ram_size, | |
377 | PCI_REGION_MEM | PCI_REGION_MEMORY); | |
378 | #else | |
4d75a504 WD |
379 | pci_set_region(hose->regions + 0, |
380 | CFG_SDRAM_BASE, | |
381 | CFG_SDRAM_BASE, | |
382 | 0x4000000, | |
383 | PCI_REGION_MEM | PCI_REGION_MEMORY); | |
5d232d0e | 384 | #endif |
4d75a504 WD |
385 | |
386 | /* PCI memory space */ | |
5d232d0e | 387 | #ifdef CONFIG_MPC8266ADS |
7a8e9bed WD |
388 | pci_set_region(hose->regions + 1, |
389 | PCI_MSTR_MEMIO_BUS, | |
390 | PCI_MSTR_MEMIO_LOCAL, | |
391 | PCI_MSTR_MEMIO_SIZE, | |
392 | PCI_REGION_MEM); | |
5d232d0e | 393 | #else |
4d75a504 WD |
394 | pci_set_region(hose->regions + 1, |
395 | PCI_MSTR_MEM_BUS, | |
396 | PCI_MSTR_MEM_LOCAL, | |
397 | PCI_MSTR_MEM_SIZE, | |
398 | PCI_REGION_MEM); | |
5d232d0e | 399 | #endif |
4d75a504 WD |
400 | |
401 | /* PCI I/O space */ | |
402 | pci_set_region(hose->regions + 2, | |
403 | PCI_MSTR_IO_BUS, | |
404 | PCI_MSTR_IO_LOCAL, | |
405 | PCI_MSTR_IO_SIZE, | |
406 | PCI_REGION_IO); | |
407 | ||
408 | hose->region_count = 3; | |
409 | ||
410 | pci_register_hose(hose); | |
411 | ||
412 | hose->last_busno = pci_hose_scan(hose); | |
413 | } | |
414 | ||
415 | #endif /* CONFIG_PCI */ |