]>
Commit | Line | Data |
---|---|---|
8ac27327 JH |
1 | /* |
2 | * Copyright 2007 Wind River Systemes, Inc. <www.windriver.com> | |
3 | * Copyright 2007 Embedded Specialties, Inc. | |
4 | * Joe Hamman joe.hamman@embeddedspecialties.com | |
5 | * | |
6 | * Copyright 2004 Freescale Semiconductor. | |
7 | * Jeff Brown | |
8 | * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) | |
9 | * | |
10 | * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com> | |
11 | * | |
12 | * See file CREDITS for list of people who contributed to this | |
13 | * project. | |
14 | * | |
15 | * This program is free software; you can redistribute it and/or | |
16 | * modify it under the terms of the GNU General Public License as | |
17 | * published by the Free Software Foundation; either version 2 of | |
18 | * the License, or (at your option) any later version. | |
19 | * | |
20 | * This program is distributed in the hope that it will be useful, | |
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23 | * GNU General Public License for more details. | |
24 | * | |
25 | * You should have received a copy of the GNU General Public License | |
26 | * along with this program; if not, write to the Free Software | |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
28 | * MA 02111-1307 USA | |
29 | */ | |
30 | ||
31 | #include <common.h> | |
32 | #include <command.h> | |
33 | #include <pci.h> | |
34 | #include <asm/processor.h> | |
35 | #include <asm/immap_86xx.h> | |
cca34967 | 36 | #include <asm/immap_fsl_pci.h> |
a30a549a | 37 | #include <spd_sdram.h> |
13f5433f JL |
38 | #include <libfdt.h> |
39 | #include <fdt_support.h> | |
8ac27327 JH |
40 | |
41 | #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) | |
42 | extern void ddr_enable_ecc (unsigned int dram_size); | |
43 | #endif | |
44 | ||
8ac27327 JH |
45 | void sdram_init (void); |
46 | long int fixed_sdram (void); | |
47 | ||
48 | int board_early_init_f (void) | |
49 | { | |
50 | return 0; | |
51 | } | |
52 | ||
53 | int checkboard (void) | |
54 | { | |
55 | puts ("Board: Wind River SBC8641D\n"); | |
56 | ||
8ac27327 JH |
57 | return 0; |
58 | } | |
59 | ||
9973e3c6 | 60 | phys_size_t initdram (int board_type) |
8ac27327 JH |
61 | { |
62 | long dram_size = 0; | |
63 | ||
64 | #if defined(CONFIG_SPD_EEPROM) | |
65 | dram_size = spd_sdram (); | |
66 | #else | |
67 | dram_size = fixed_sdram (); | |
68 | #endif | |
69 | ||
70 | #if defined(CFG_RAMBOOT) | |
71 | puts (" DDR: "); | |
72 | return dram_size; | |
73 | #endif | |
74 | ||
75 | #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) | |
76 | /* | |
77 | * Initialize and enable DDR ECC. | |
78 | */ | |
79 | ddr_enable_ecc (dram_size); | |
80 | #endif | |
81 | ||
82 | puts (" DDR: "); | |
83 | return dram_size; | |
84 | } | |
85 | ||
86 | #if defined(CFG_DRAM_TEST) | |
87 | int testdram (void) | |
88 | { | |
89 | uint *pstart = (uint *) CFG_MEMTEST_START; | |
90 | uint *pend = (uint *) CFG_MEMTEST_END; | |
91 | uint *p; | |
92 | ||
93 | puts ("SDRAM test phase 1:\n"); | |
94 | for (p = pstart; p < pend; p++) | |
95 | *p = 0xaaaaaaaa; | |
96 | ||
97 | for (p = pstart; p < pend; p++) { | |
98 | if (*p != 0xaaaaaaaa) { | |
99 | printf ("SDRAM test fails at: %08x\n", (uint) p); | |
100 | return 1; | |
101 | } | |
102 | } | |
103 | ||
104 | puts ("SDRAM test phase 2:\n"); | |
105 | for (p = pstart; p < pend; p++) | |
106 | *p = 0x55555555; | |
107 | ||
108 | for (p = pstart; p < pend; p++) { | |
109 | if (*p != 0x55555555) { | |
110 | printf ("SDRAM test fails at: %08x\n", (uint) p); | |
111 | return 1; | |
112 | } | |
113 | } | |
114 | ||
115 | puts ("SDRAM test passed.\n"); | |
116 | return 0; | |
117 | } | |
118 | #endif | |
119 | ||
120 | #if !defined(CONFIG_SPD_EEPROM) | |
121 | /* | |
122 | * Fixed sdram init -- doesn't use serial presence detect. | |
123 | */ | |
124 | long int fixed_sdram (void) | |
125 | { | |
126 | #if !defined(CFG_RAMBOOT) | |
127 | volatile immap_t *immap = (immap_t *) CFG_IMMR; | |
128 | volatile ccsr_ddr_t *ddr = &immap->im_ddr1; | |
129 | ||
130 | ddr->cs0_bnds = CFG_DDR_CS0_BNDS; | |
131 | ddr->cs1_bnds = CFG_DDR_CS1_BNDS; | |
132 | ddr->cs2_bnds = CFG_DDR_CS2_BNDS; | |
133 | ddr->cs3_bnds = CFG_DDR_CS3_BNDS; | |
134 | ddr->cs0_config = CFG_DDR_CS0_CONFIG; | |
135 | ddr->cs1_config = CFG_DDR_CS1_CONFIG; | |
136 | ddr->cs2_config = CFG_DDR_CS2_CONFIG; | |
137 | ddr->cs3_config = CFG_DDR_CS3_CONFIG; | |
45239cf4 | 138 | ddr->timing_cfg_3 = CFG_DDR_TIMING_3; |
8ac27327 JH |
139 | ddr->timing_cfg_0 = CFG_DDR_TIMING_0; |
140 | ddr->timing_cfg_1 = CFG_DDR_TIMING_1; | |
141 | ddr->timing_cfg_2 = CFG_DDR_TIMING_2; | |
142 | ddr->sdram_cfg_1 = CFG_DDR_CFG_1A; | |
143 | ddr->sdram_cfg_2 = CFG_DDR_CFG_2; | |
144 | ddr->sdram_mode_1 = CFG_DDR_MODE_1; | |
145 | ddr->sdram_mode_2 = CFG_DDR_MODE_2; | |
146 | ddr->sdram_mode_cntl = CFG_DDR_MODE_CTL; | |
147 | ddr->sdram_interval = CFG_DDR_INTERVAL; | |
148 | ddr->sdram_data_init = CFG_DDR_DATA_INIT; | |
149 | ddr->sdram_clk_cntl = CFG_DDR_CLK_CTRL; | |
150 | ||
151 | asm ("sync;isync"); | |
152 | ||
153 | udelay (500); | |
154 | ||
155 | ddr->sdram_cfg_1 = CFG_DDR_CFG_1B; | |
156 | asm ("sync; isync"); | |
157 | ||
158 | udelay (500); | |
159 | ddr = &immap->im_ddr2; | |
160 | ||
161 | ddr->cs0_bnds = CFG_DDR2_CS0_BNDS; | |
162 | ddr->cs1_bnds = CFG_DDR2_CS1_BNDS; | |
163 | ddr->cs2_bnds = CFG_DDR2_CS2_BNDS; | |
164 | ddr->cs3_bnds = CFG_DDR2_CS3_BNDS; | |
165 | ddr->cs0_config = CFG_DDR2_CS0_CONFIG; | |
166 | ddr->cs1_config = CFG_DDR2_CS1_CONFIG; | |
167 | ddr->cs2_config = CFG_DDR2_CS2_CONFIG; | |
168 | ddr->cs3_config = CFG_DDR2_CS3_CONFIG; | |
45239cf4 | 169 | ddr->timing_cfg_3 = CFG_DDR2_EXT_REFRESH; |
8ac27327 JH |
170 | ddr->timing_cfg_0 = CFG_DDR2_TIMING_0; |
171 | ddr->timing_cfg_1 = CFG_DDR2_TIMING_1; | |
172 | ddr->timing_cfg_2 = CFG_DDR2_TIMING_2; | |
173 | ddr->sdram_cfg_1 = CFG_DDR2_CFG_1A; | |
174 | ddr->sdram_cfg_2 = CFG_DDR2_CFG_2; | |
175 | ddr->sdram_mode_1 = CFG_DDR2_MODE_1; | |
176 | ddr->sdram_mode_2 = CFG_DDR2_MODE_2; | |
177 | ddr->sdram_mode_cntl = CFG_DDR2_MODE_CTL; | |
178 | ddr->sdram_interval = CFG_DDR2_INTERVAL; | |
179 | ddr->sdram_data_init = CFG_DDR2_DATA_INIT; | |
180 | ddr->sdram_clk_cntl = CFG_DDR2_CLK_CTRL; | |
181 | ||
182 | asm ("sync;isync"); | |
183 | ||
184 | udelay (500); | |
185 | ||
186 | ddr->sdram_cfg_1 = CFG_DDR2_CFG_1B; | |
187 | asm ("sync; isync"); | |
188 | ||
189 | udelay (500); | |
190 | #endif | |
191 | return CFG_SDRAM_SIZE * 1024 * 1024; | |
192 | } | |
193 | #endif /* !defined(CONFIG_SPD_EEPROM) */ | |
194 | ||
195 | #if defined(CONFIG_PCI) | |
196 | /* | |
197 | * Initialize PCI Devices, report devices found. | |
198 | */ | |
199 | ||
200 | #ifndef CONFIG_PCI_PNP | |
201 | static struct pci_config_table pci_fsl86xxads_config_table[] = { | |
202 | {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | |
203 | PCI_IDSEL_NUMBER, PCI_ANY_ID, | |
204 | pci_cfgfunc_config_device, {PCI_ENET0_IOADDR, | |
205 | PCI_ENET0_MEMADDR, | |
206 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}}, | |
207 | {} | |
208 | }; | |
209 | #endif | |
210 | ||
cca34967 | 211 | static struct pci_controller pci1_hose = { |
8ac27327 | 212 | #ifndef CONFIG_PCI_PNP |
cca34967 | 213 | config_table:pci_mpc86xxcts_config_table |
8ac27327 JH |
214 | #endif |
215 | }; | |
cca34967 | 216 | #endif /* CONFIG_PCI */ |
8ac27327 | 217 | |
cca34967 JH |
218 | #ifdef CONFIG_PCI2 |
219 | static struct pci_controller pci2_hose; | |
220 | #endif /* CONFIG_PCI2 */ | |
8ac27327 | 221 | |
cca34967 JH |
222 | int first_free_busno = 0; |
223 | ||
224 | void pci_init_board(void) | |
8ac27327 | 225 | { |
cca34967 JH |
226 | volatile immap_t *immap = (immap_t *) CFG_CCSRBAR; |
227 | volatile ccsr_gur_t *gur = &immap->im_gur; | |
228 | uint devdisr = gur->devdisr; | |
33fa5c0b JL |
229 | uint io_sel = (gur->pordevsr & MPC8641_PORDEVSR_IO_SEL) |
230 | >> MPC8641_PORDEVSR_IO_SEL_SHIFT; | |
cca34967 JH |
231 | |
232 | #ifdef CONFIG_PCI1 | |
233 | { | |
234 | volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCI1_ADDR; | |
235 | extern void fsl_pci_init(struct pci_controller *hose); | |
236 | struct pci_controller *hose = &pci1_hose; | |
237 | #ifdef DEBUG | |
33fa5c0b JL |
238 | uint host1_agent = (gur->porbmsr & MPC8641_PORBMSR_HA) |
239 | >> MPC8641_PORBMSR_HA_SHIFT; | |
cca34967 JH |
240 | uint pex1_agent = (host1_agent == 0) || (host1_agent == 1); |
241 | #endif | |
242 | if ((io_sel == 2 || io_sel == 3 || io_sel == 5 | |
243 | || io_sel == 6 || io_sel == 7 || io_sel == 0xF) | |
244 | && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) { | |
245 | debug("PCI-EXPRESS 1: %s \n", pex1_agent ? "Agent" : "Host"); | |
246 | debug("0x%08x=0x%08x ", &pci->pme_msg_det, pci->pme_msg_det); | |
247 | if (pci->pme_msg_det) { | |
248 | pci->pme_msg_det = 0xffffffff; | |
249 | debug(" with errors. Clearing. Now 0x%08x", | |
250 | pci->pme_msg_det); | |
251 | } | |
252 | debug("\n"); | |
253 | ||
254 | /* inbound */ | |
255 | pci_set_region(hose->regions + 0, | |
256 | CFG_PCI_MEMORY_BUS, | |
257 | CFG_PCI_MEMORY_PHYS, | |
258 | CFG_PCI_MEMORY_SIZE, | |
259 | PCI_REGION_MEM | PCI_REGION_MEMORY); | |
260 | ||
261 | /* outbound memory */ | |
262 | pci_set_region(hose->regions + 1, | |
263 | CFG_PCI1_MEM_BASE, | |
264 | CFG_PCI1_MEM_PHYS, | |
265 | CFG_PCI1_MEM_SIZE, | |
266 | PCI_REGION_MEM); | |
267 | ||
268 | /* outbound io */ | |
269 | pci_set_region(hose->regions + 2, | |
270 | CFG_PCI1_IO_BASE, | |
271 | CFG_PCI1_IO_PHYS, | |
272 | CFG_PCI1_IO_SIZE, | |
273 | PCI_REGION_IO); | |
274 | ||
275 | hose->region_count = 3; | |
276 | ||
277 | hose->first_busno=first_free_busno; | |
278 | pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); | |
279 | ||
280 | fsl_pci_init(hose); | |
281 | ||
282 | first_free_busno=hose->last_busno+1; | |
283 | printf (" PCI-EXPRESS 1 on bus %02x - %02x\n", | |
284 | hose->first_busno,hose->last_busno); | |
285 | ||
286 | } else { | |
287 | puts("PCI-EXPRESS 1: Disabled\n"); | |
288 | } | |
289 | } | |
290 | #else | |
291 | puts("PCI-EXPRESS1: Disabled\n"); | |
292 | #endif /* CONFIG_PCI1 */ | |
293 | ||
294 | #ifdef CONFIG_PCI2 | |
295 | { | |
296 | volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCI2_ADDR; | |
297 | extern void fsl_pci_init(struct pci_controller *hose); | |
298 | struct pci_controller *hose = &pci2_hose; | |
299 | ||
300 | ||
301 | /* inbound */ | |
302 | pci_set_region(hose->regions + 0, | |
303 | CFG_PCI_MEMORY_BUS, | |
304 | CFG_PCI_MEMORY_PHYS, | |
305 | CFG_PCI_MEMORY_SIZE, | |
306 | PCI_REGION_MEM | PCI_REGION_MEMORY); | |
307 | ||
308 | /* outbound memory */ | |
309 | pci_set_region(hose->regions + 1, | |
310 | CFG_PCI2_MEM_BASE, | |
311 | CFG_PCI2_MEM_PHYS, | |
312 | CFG_PCI2_MEM_SIZE, | |
313 | PCI_REGION_MEM); | |
314 | ||
315 | /* outbound io */ | |
316 | pci_set_region(hose->regions + 2, | |
317 | CFG_PCI2_IO_BASE, | |
318 | CFG_PCI2_IO_PHYS, | |
319 | CFG_PCI2_IO_SIZE, | |
320 | PCI_REGION_IO); | |
321 | ||
322 | hose->region_count = 3; | |
323 | ||
324 | hose->first_busno=first_free_busno; | |
325 | pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); | |
326 | ||
327 | fsl_pci_init(hose); | |
328 | ||
329 | first_free_busno=hose->last_busno+1; | |
330 | printf (" PCI-EXPRESS 2 on bus %02x - %02x\n", | |
331 | hose->first_busno,hose->last_busno); | |
332 | } | |
333 | #else | |
334 | puts("PCI-EXPRESS 2: Disabled\n"); | |
335 | #endif /* CONFIG_PCI2 */ | |
8ac27327 | 336 | |
8ac27327 JH |
337 | } |
338 | ||
13f5433f JL |
339 | |
340 | #if defined(CONFIG_OF_BOARD_SETUP) | |
341 | ||
342 | void | |
343 | ft_board_setup (void *blob, bd_t *bd) | |
8ac27327 | 344 | { |
13f5433f JL |
345 | int node, tmp[2]; |
346 | const char *path; | |
8ac27327 | 347 | |
13f5433f | 348 | ft_cpu_setup(blob, bd); |
8ac27327 | 349 | |
13f5433f JL |
350 | node = fdt_path_offset(blob, "/aliases"); |
351 | tmp[0] = 0; | |
352 | if (node >= 0) { | |
353 | #ifdef CONFIG_PCI1 | |
354 | path = fdt_getprop(blob, node, "pci0", NULL); | |
355 | if (path) { | |
356 | tmp[1] = pci1_hose.last_busno - pci1_hose.first_busno; | |
357 | do_fixup_by_path(blob, path, "bus-range", &tmp, 8, 1); | |
358 | } | |
359 | #endif | |
360 | #ifdef CONFIG_PCI2 | |
361 | path = fdt_getprop(blob, node, "pci1", NULL); | |
362 | if (path) { | |
363 | tmp[1] = pci2_hose.last_busno - pci2_hose.first_busno; | |
364 | do_fixup_by_path(blob, path, "bus-range", &tmp, 8, 1); | |
365 | } | |
366 | #endif | |
8ac27327 JH |
367 | } |
368 | } | |
369 | #endif | |
370 | ||
371 | void sbc8641d_reset_board (void) | |
372 | { | |
373 | puts ("Resetting board....\n"); | |
374 | } | |
375 | ||
376 | /* | |
377 | * get_board_sys_clk | |
378 | * Clock is fixed at 1GHz on this board. Used for CONFIG_SYS_CLK_FREQ | |
379 | */ | |
380 | ||
381 | unsigned long get_board_sys_clk (ulong dummy) | |
382 | { | |
383 | int i; | |
384 | ulong val = 0; | |
385 | ||
386 | i = 5; | |
387 | i &= 0x07; | |
388 | ||
389 | switch (i) { | |
390 | case 0: | |
391 | val = 33000000; | |
392 | break; | |
393 | case 1: | |
394 | val = 40000000; | |
395 | break; | |
396 | case 2: | |
397 | val = 50000000; | |
398 | break; | |
399 | case 3: | |
400 | val = 66000000; | |
401 | break; | |
402 | case 4: | |
403 | val = 83000000; | |
404 | break; | |
405 | case 5: | |
406 | val = 100000000; | |
407 | break; | |
408 | case 6: | |
409 | val = 134000000; | |
410 | break; | |
411 | case 7: | |
412 | val = 166000000; | |
413 | break; | |
414 | } | |
415 | ||
416 | return val; | |
417 | } |