]>
Commit | Line | Data |
---|---|---|
d9b94f28 | 1 | /* |
b813cbe9 | 2 | * Copyright 2004, 2007, 2009-2011 Freescale Semiconductor, Inc. |
d9b94f28 JL |
3 | * |
4 | * (C) Copyright 2002 Scott McNutt <[email protected]> | |
5 | * | |
3765b3e7 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
d9b94f28 JL |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | #include <pci.h> | |
11 | #include <asm/processor.h> | |
e31d2c1e | 12 | #include <asm/mmu.h> |
d9b94f28 | 13 | #include <asm/immap_85xx.h> |
c8514622 | 14 | #include <asm/fsl_pci.h> |
e31d2c1e | 15 | #include <asm/fsl_ddr_sdram.h> |
5d27e02c | 16 | #include <asm/fsl_serdes.h> |
09f3e09e | 17 | #include <miiphy.h> |
b90d2549 KG |
18 | #include <libfdt.h> |
19 | #include <fdt_support.h> | |
d3701228 | 20 | #include <tsec.h> |
21 | #include <fsl_mdio.h> | |
22 | #include <netdev.h> | |
d9b94f28 JL |
23 | |
24 | #include "../common/cadmus.h" | |
25 | #include "../common/eeprom.h" | |
bf1dfffd | 26 | #include "../common/via.h" |
d9b94f28 | 27 | |
d9b94f28 | 28 | void local_bus_init(void); |
d9b94f28 | 29 | |
d9b94f28 JL |
30 | int checkboard (void) |
31 | { | |
6d0f6bcf JCPV |
32 | volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
33 | volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); | |
d9b94f28 JL |
34 | |
35 | /* PCI slot in USER bits CSR[6:7] by convention. */ | |
36 | uint pci_slot = get_pci_slot (); | |
37 | ||
d9b94f28 JL |
38 | uint cpu_board_rev = get_cpu_board_revision (); |
39 | ||
fff80975 | 40 | puts("Board: MPC8548CDS"); |
41 | printf(" Carrier Rev: 0x%02x, PCI Slot %d\n", | |
42 | get_board_version(), pci_slot); | |
43 | printf(" Daughtercard Rev: %d.%d (0x%04x)\n", | |
d9b94f28 JL |
44 | MPC85XX_CPU_BOARD_MAJOR (cpu_board_rev), |
45 | MPC85XX_CPU_BOARD_MINOR (cpu_board_rev), cpu_board_rev); | |
d9b94f28 JL |
46 | /* |
47 | * Initialize local bus. | |
48 | */ | |
49 | local_bus_init (); | |
50 | ||
d9b94f28 JL |
51 | /* |
52 | * Hack TSEC 3 and 4 IO voltages. | |
53 | */ | |
54 | gur->tsec34ioovcr = 0xe7e0; /* 1110 0111 1110 0xxx */ | |
55 | ||
f2cff6b1 ES |
56 | ecm->eedr = 0xffffffff; /* clear ecm errors */ |
57 | ecm->eeer = 0xffffffff; /* enable ecm errors */ | |
d9b94f28 JL |
58 | return 0; |
59 | } | |
60 | ||
d9b94f28 JL |
61 | /* |
62 | * Initialize Local Bus | |
63 | */ | |
64 | void | |
65 | local_bus_init(void) | |
66 | { | |
6d0f6bcf | 67 | volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
f51cdaf1 | 68 | volatile fsl_lbc_t *lbc = LBC_BASE_ADDR; |
d9b94f28 JL |
69 | |
70 | uint clkdiv; | |
d9b94f28 JL |
71 | sys_info_t sysinfo; |
72 | ||
73 | get_sys_info(&sysinfo); | |
a5d212a2 | 74 | clkdiv = (lbc->lcrr & LCRR_CLKDIV) * 2; |
d9b94f28 JL |
75 | |
76 | gur->lbiuiplldcr1 = 0x00078080; | |
77 | if (clkdiv == 16) { | |
78 | gur->lbiuiplldcr0 = 0x7c0f1bf0; | |
79 | } else if (clkdiv == 8) { | |
80 | gur->lbiuiplldcr0 = 0x6c0f1bf0; | |
81 | } else if (clkdiv == 4) { | |
82 | gur->lbiuiplldcr0 = 0x5c0f1bf0; | |
83 | } | |
84 | ||
85 | lbc->lcrr |= 0x00030000; | |
86 | ||
87 | asm("sync;isync;msync"); | |
f2cff6b1 ES |
88 | |
89 | lbc->ltesr = 0xffffffff; /* Clear LBC error interrupts */ | |
90 | lbc->lteir = 0xffffffff; /* Enable LBC error interrupts */ | |
d9b94f28 JL |
91 | } |
92 | ||
93 | /* | |
94 | * Initialize SDRAM memory on the Local Bus. | |
95 | */ | |
70961ba4 | 96 | void lbc_sdram_init(void) |
d9b94f28 | 97 | { |
6d0f6bcf | 98 | #if defined(CONFIG_SYS_OR2_PRELIM) && defined(CONFIG_SYS_BR2_PRELIM) |
d9b94f28 JL |
99 | |
100 | uint idx; | |
f51cdaf1 | 101 | volatile fsl_lbc_t *lbc = LBC_BASE_ADDR; |
6d0f6bcf | 102 | uint *sdram_addr = (uint *)CONFIG_SYS_LBC_SDRAM_BASE; |
d9b94f28 JL |
103 | uint lsdmr_common; |
104 | ||
7ea3871e BB |
105 | puts("LBC SDRAM: "); |
106 | print_size(CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024, | |
a6d0bfa8 | 107 | "\n"); |
d9b94f28 JL |
108 | |
109 | /* | |
110 | * Setup SDRAM Base and Option Registers | |
111 | */ | |
f51cdaf1 BB |
112 | set_lbc_or(2, CONFIG_SYS_OR2_PRELIM); |
113 | set_lbc_br(2, CONFIG_SYS_BR2_PRELIM); | |
6d0f6bcf | 114 | lbc->lbcr = CONFIG_SYS_LBC_LBCR; |
d9b94f28 JL |
115 | asm("msync"); |
116 | ||
6d0f6bcf JCPV |
117 | lbc->lsrt = CONFIG_SYS_LBC_LSRT; |
118 | lbc->mrtpr = CONFIG_SYS_LBC_MRTPR; | |
d9b94f28 JL |
119 | asm("msync"); |
120 | ||
121 | /* | |
122 | * MPC8548 uses "new" 15-16 style addressing. | |
123 | */ | |
6d0f6bcf | 124 | lsdmr_common = CONFIG_SYS_LBC_LSDMR_COMMON; |
b0fe93ed | 125 | lsdmr_common |= LSDMR_BSMA1516; |
d9b94f28 JL |
126 | |
127 | /* | |
128 | * Issue PRECHARGE ALL command. | |
129 | */ | |
b0fe93ed | 130 | lbc->lsdmr = lsdmr_common | LSDMR_OP_PCHALL; |
d9b94f28 JL |
131 | asm("sync;msync"); |
132 | *sdram_addr = 0xff; | |
133 | ppcDcbf((unsigned long) sdram_addr); | |
134 | udelay(100); | |
135 | ||
136 | /* | |
137 | * Issue 8 AUTO REFRESH commands. | |
138 | */ | |
139 | for (idx = 0; idx < 8; idx++) { | |
b0fe93ed | 140 | lbc->lsdmr = lsdmr_common | LSDMR_OP_ARFRSH; |
d9b94f28 JL |
141 | asm("sync;msync"); |
142 | *sdram_addr = 0xff; | |
143 | ppcDcbf((unsigned long) sdram_addr); | |
144 | udelay(100); | |
145 | } | |
146 | ||
147 | /* | |
148 | * Issue 8 MODE-set command. | |
149 | */ | |
b0fe93ed | 150 | lbc->lsdmr = lsdmr_common | LSDMR_OP_MRW; |
d9b94f28 JL |
151 | asm("sync;msync"); |
152 | *sdram_addr = 0xff; | |
153 | ppcDcbf((unsigned long) sdram_addr); | |
154 | udelay(100); | |
155 | ||
156 | /* | |
157 | * Issue NORMAL OP command. | |
158 | */ | |
b0fe93ed | 159 | lbc->lsdmr = lsdmr_common | LSDMR_OP_NORMAL; |
d9b94f28 JL |
160 | asm("sync;msync"); |
161 | *sdram_addr = 0xff; | |
162 | ppcDcbf((unsigned long) sdram_addr); | |
163 | udelay(200); /* Overkill. Must wait > 200 bus cycles */ | |
164 | ||
165 | #endif /* enable SDRAM init */ | |
166 | } | |
167 | ||
f2cff6b1 | 168 | #if defined(CONFIG_PCI) || defined(CONFIG_PCI1) |
bf1dfffd MM |
169 | /* For some reason the Tundra PCI bridge shows up on itself as a |
170 | * different device. Work around that by refusing to configure it. | |
d9b94f28 | 171 | */ |
bf1dfffd | 172 | void dummy_func(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab) { } |
d9b94f28 | 173 | |
d9b94f28 | 174 | static struct pci_config_table pci_mpc85xxcds_config_table[] = { |
bf1dfffd | 175 | {0x10e3, 0x0513, PCI_ANY_ID, 1, 3, PCI_ANY_ID, dummy_func, {0,0,0}}, |
7f3f2bd2 RV |
176 | {0x1106, 0x0686, PCI_ANY_ID, 1, VIA_ID, 0, mpc85xx_config_via, {0,0,0}}, |
177 | {0x1106, 0x0571, PCI_ANY_ID, 1, VIA_ID, 1, | |
ffa621a0 | 178 | mpc85xx_config_via_usbide, {0,0,0}}, |
7f3f2bd2 RV |
179 | {0x1105, 0x3038, PCI_ANY_ID, 1, VIA_ID, 2, |
180 | mpc85xx_config_via_usb, {0,0,0}}, | |
181 | {0x1106, 0x3038, PCI_ANY_ID, 1, VIA_ID, 3, | |
182 | mpc85xx_config_via_usb2, {0,0,0}}, | |
183 | {0x1106, 0x3058, PCI_ANY_ID, 1, VIA_ID, 5, | |
ffa621a0 | 184 | mpc85xx_config_via_power, {0,0,0}}, |
7f3f2bd2 RV |
185 | {0x1106, 0x3068, PCI_ANY_ID, 1, VIA_ID, 6, |
186 | mpc85xx_config_via_ac97, {0,0,0}}, | |
ffa621a0 | 187 | {}, |
d9b94f28 | 188 | }; |
d9b94f28 | 189 | |
b813cbe9 | 190 | static struct pci_controller pci1_hose; |
d9b94f28 JL |
191 | #endif /* CONFIG_PCI */ |
192 | ||
7b626880 | 193 | void pci_init_board(void) |
d9b94f28 | 194 | { |
6d0f6bcf | 195 | volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
f5fa8f36 | 196 | struct fsl_pci_info pci_info; |
7b626880 KG |
197 | u32 devdisr, pordevsr, io_sel; |
198 | u32 porpllsr, pci_agent, pci_speed, pci_32, pci_arb, pci_clk_sel; | |
199 | int first_free_busno = 0; | |
568336ec | 200 | char buf[32]; |
f2cff6b1 | 201 | |
7b626880 KG |
202 | devdisr = in_be32(&gur->devdisr); |
203 | pordevsr = in_be32(&gur->pordevsr); | |
204 | porpllsr = in_be32(&gur->porpllsr); | |
205 | io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19; | |
f2cff6b1 | 206 | |
7b626880 | 207 | debug (" pci_init_board: devdisr=%x, io_sel=%x\n", devdisr, io_sel); |
f2cff6b1 | 208 | |
7b626880 KG |
209 | #ifdef CONFIG_PCI1 |
210 | pci_speed = get_clock_freq (); /* PCI PSPEED in [4:5] */ | |
211 | pci_32 = pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32; /* PORDEVSR[15] */ | |
212 | pci_arb = pordevsr & MPC85xx_PORDEVSR_PCI1_ARB; | |
213 | pci_clk_sel = porpllsr & MPC85xx_PORDEVSR_PCI1_SPD; | |
214 | ||
215 | if (!(devdisr & MPC85xx_DEVDISR_PCI1)) { | |
f5fa8f36 KG |
216 | SET_STD_PCI_INFO(pci_info, 1); |
217 | set_next_law(pci_info.mem_phys, | |
218 | law_size_bits(pci_info.mem_size), pci_info.law); | |
219 | set_next_law(pci_info.io_phys, | |
220 | law_size_bits(pci_info.io_size), pci_info.law); | |
221 | ||
222 | pci_agent = fsl_setup_hose(&pci1_hose, pci_info.regs); | |
a6d0bfa8 | 223 | printf("PCI1: %d bit, %s MHz, %s, %s, %s (base address %lx)\n", |
f2cff6b1 | 224 | (pci_32) ? 32 : 64, |
568336ec | 225 | strmhz(buf, pci_speed), |
f2cff6b1 ES |
226 | pci_clk_sel ? "sync" : "async", |
227 | pci_agent ? "agent" : "host", | |
7b626880 | 228 | pci_arb ? "arbiter" : "external-arbiter", |
f5fa8f36 | 229 | pci_info.regs); |
7b626880 | 230 | |
b813cbe9 | 231 | pci1_hose.config_table = pci_mpc85xxcds_config_table; |
f5fa8f36 | 232 | first_free_busno = fsl_pci_init_port(&pci_info, |
7b626880 KG |
233 | &pci1_hose, first_free_busno); |
234 | ||
f2cff6b1 | 235 | #ifdef CONFIG_PCIX_CHECK |
7b626880 | 236 | if (!(pordevsr & MPC85xx_PORDEVSR_PCI1)) { |
f2cff6b1 ES |
237 | /* PCI-X init */ |
238 | if (CONFIG_SYS_CLK_FREQ < 66000000) | |
239 | printf("PCI-X will only work at 66 MHz\n"); | |
240 | ||
241 | reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ | |
242 | | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E; | |
243 | pci_hose_write_config_word(hose, bus, PCIX_COMMAND, reg16); | |
244 | } | |
d9b94f28 | 245 | #endif |
f2cff6b1 | 246 | } else { |
a6d0bfa8 | 247 | printf("PCI1: disabled\n"); |
f2cff6b1 | 248 | } |
7b626880 KG |
249 | |
250 | puts("\n"); | |
f2cff6b1 | 251 | #else |
7b626880 | 252 | setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1); /* disable */ |
f2cff6b1 ES |
253 | #endif |
254 | ||
255 | #ifdef CONFIG_PCI2 | |
256 | { | |
7b626880 | 257 | uint pci2_clk_sel = porpllsr & 0x4000; /* PORPLLSR[17] */ |
f2cff6b1 ES |
258 | uint pci_dual = get_pci_dual (); /* PCI DUAL in CM_PCI[3] */ |
259 | if (pci_dual) { | |
8ca78f2c | 260 | printf("PCI2: 32 bit, 66 MHz, %s\n", |
f2cff6b1 ES |
261 | pci2_clk_sel ? "sync" : "async"); |
262 | } else { | |
8ca78f2c | 263 | printf("PCI2: disabled\n"); |
f2cff6b1 ES |
264 | } |
265 | } | |
266 | #else | |
7b626880 | 267 | setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI2); /* disable */ |
f2cff6b1 ES |
268 | #endif /* CONFIG_PCI2 */ |
269 | ||
f5fa8f36 | 270 | fsl_pcie_init_board(first_free_busno); |
d9b94f28 | 271 | } |
09f3e09e | 272 | |
d3701228 | 273 | void configure_rgmii(void) |
09f3e09e | 274 | { |
f5012827 | 275 | unsigned short temp; |
09f3e09e AF |
276 | |
277 | /* Change the resistors for the PHY */ | |
278 | /* This is needed to get the RGMII working for the 1.3+ | |
279 | * CDS cards */ | |
280 | if (get_board_version() == 0x13) { | |
d3701228 | 281 | miiphy_write(DEFAULT_MII_NAME, |
09f3e09e AF |
282 | TSEC1_PHY_ADDR, 29, 18); |
283 | ||
d3701228 | 284 | miiphy_read(DEFAULT_MII_NAME, |
09f3e09e AF |
285 | TSEC1_PHY_ADDR, 30, &temp); |
286 | ||
287 | temp = (temp & 0xf03f); | |
288 | temp |= 2 << 9; /* 36 ohm */ | |
289 | temp |= 2 << 6; /* 39 ohm */ | |
290 | ||
d3701228 | 291 | miiphy_write(DEFAULT_MII_NAME, |
09f3e09e AF |
292 | TSEC1_PHY_ADDR, 30, temp); |
293 | ||
d3701228 | 294 | miiphy_write(DEFAULT_MII_NAME, |
09f3e09e AF |
295 | TSEC1_PHY_ADDR, 29, 3); |
296 | ||
d3701228 | 297 | miiphy_write(DEFAULT_MII_NAME, |
09f3e09e AF |
298 | TSEC1_PHY_ADDR, 30, 0x8000); |
299 | } | |
300 | ||
d3701228 | 301 | return; |
09f3e09e | 302 | } |
f2cff6b1 | 303 | |
d3701228 | 304 | #ifdef CONFIG_TSEC_ENET |
305 | int board_eth_init(bd_t *bis) | |
306 | { | |
307 | struct fsl_pq_mdio_info mdio_info; | |
308 | struct tsec_info_struct tsec_info[4]; | |
309 | int num = 0; | |
310 | ||
311 | #ifdef CONFIG_TSEC1 | |
312 | SET_STD_TSEC_INFO(tsec_info[num], 1); | |
313 | num++; | |
314 | #endif | |
315 | #ifdef CONFIG_TSEC2 | |
316 | SET_STD_TSEC_INFO(tsec_info[num], 2); | |
317 | num++; | |
318 | #endif | |
319 | #ifdef CONFIG_TSEC3 | |
320 | /* initialize TSEC3 only if Carrier is 1.3 or above on CDS */ | |
321 | if (get_board_version() >= 0x13) { | |
322 | SET_STD_TSEC_INFO(tsec_info[num], 3); | |
323 | tsec_info[num].interface = PHY_INTERFACE_MODE_RGMII_ID; | |
324 | num++; | |
325 | } | |
326 | #endif | |
327 | #ifdef CONFIG_TSEC4 | |
328 | /* initialize TSEC4 only if Carrier is 1.3 or above on CDS */ | |
329 | if (get_board_version() >= 0x13) { | |
330 | SET_STD_TSEC_INFO(tsec_info[num], 4); | |
331 | tsec_info[num].interface = PHY_INTERFACE_MODE_RGMII_ID; | |
332 | num++; | |
333 | } | |
334 | #endif | |
335 | ||
336 | if (!num) { | |
337 | printf("No TSECs initialized\n"); | |
338 | ||
339 | return 0; | |
340 | } | |
341 | ||
342 | mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; | |
343 | mdio_info.name = DEFAULT_MII_NAME; | |
344 | fsl_pq_mdio_init(bis, &mdio_info); | |
345 | ||
346 | tsec_eth_init(bis, tsec_info, num); | |
347 | configure_rgmii(); | |
348 | ||
349 | return pci_eth_init(bis); | |
350 | } | |
351 | #endif | |
f2cff6b1 | 352 | |
b90d2549 | 353 | #if defined(CONFIG_OF_BOARD_SETUP) |
2dba0dea KG |
354 | void ft_pci_setup(void *blob, bd_t *bd) |
355 | { | |
6525d51f | 356 | FT_FSL_PCI_SETUP; |
f2cff6b1 ES |
357 | } |
358 | #endif |