]>
Commit | Line | Data |
---|---|---|
72c5d52a | 1 | /* |
be270798 | 2 | * (Cg) Copyright 2007-2008 |
72c5d52a MF |
3 | * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com. |
4 | * Based on board/amcc/sequoia/sequoia.c | |
5 | * | |
6 | * (C) Copyright 2006 | |
7 | * Stefan Roese, DENX Software Engineering, sr@denx.de. | |
8 | * | |
9 | * (C) Copyright 2006 | |
10 | * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com | |
11 | * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com | |
12 | * | |
13 | * This program is free software; you can redistribute it and/or | |
14 | * modify it under the terms of the GNU General Public License as | |
15 | * published by the Free Software Foundation; either version 2 of | |
16 | * the License, or (at your option) any later version. | |
17 | * | |
18 | * This program is distributed in the hope that it will be useful, | |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | * GNU General Public License for more details. | |
22 | * | |
23 | * You should have received a copy of the GNU General Public License | |
24 | * along with this program; if not, write to the Free Software | |
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
26 | * MA 02111-1307 USA | |
27 | */ | |
28 | ||
29 | #include <common.h> | |
30 | #include <libfdt.h> | |
31 | #include <fdt_support.h> | |
32 | #include <ppc440.h> | |
33 | #include <asm/processor.h> | |
34 | #include <asm/io.h> | |
034394ab | 35 | #include <asm/bitops.h> |
72c5d52a MF |
36 | #include <command.h> |
37 | #include <i2c.h> | |
38 | #ifdef CONFIG_RESET_PHY_R | |
39 | #include <miiphy.h> | |
40 | #endif | |
41 | #include <serial.h> | |
42 | #include "fpga.h" | |
43 | #include "pmc440.h" | |
44 | ||
45 | DECLARE_GLOBAL_DATA_PTR; | |
46 | ||
6d0f6bcf | 47 | extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ |
be270798 | 48 | extern void __ft_board_setup(void *blob, bd_t *bd); |
72c5d52a MF |
49 | |
50 | ulong flash_get_size(ulong base, int banknum); | |
51 | int pci_is_66mhz(void); | |
be270798 | 52 | int is_monarch(void); |
034394ab MF |
53 | int bootstrap_eeprom_read(unsigned dev_addr, unsigned offset, |
54 | uchar *buffer, unsigned cnt); | |
72c5d52a MF |
55 | |
56 | struct serial_device *default_serial_console(void) | |
57 | { | |
58 | uchar buf[4]; | |
59 | ulong delay; | |
60 | int i; | |
61 | ulong val; | |
62 | ||
63 | /* | |
64 | * Use default console on P4 when strapping jumper | |
65 | * is installed (bootstrap option != 'H'). | |
66 | */ | |
67 | mfsdr(SDR_PINSTP, val); | |
68 | if (((val & 0xf0000000) >> 29) != 7) | |
69 | return &serial1_device; | |
70 | ||
71 | ulong scratchreg = in_be32((void*)GPIO0_ISR3L); | |
72 | if (!(scratchreg & 0x80)) { | |
73 | /* mark scratchreg valid */ | |
74 | scratchreg = (scratchreg & 0xffffff00) | 0x80; | |
75 | ||
6d0f6bcf | 76 | i = bootstrap_eeprom_read(CONFIG_SYS_I2C_BOOT_EEPROM_ADDR, |
034394ab | 77 | 0x10, buf, 4); |
72c5d52a MF |
78 | if ((i != -1) && (buf[0] == 0x19) && (buf[1] == 0x75)) { |
79 | scratchreg |= buf[2]; | |
80 | ||
81 | /* bringup delay for console */ | |
82 | for (delay=0; delay<(1000 * (ulong)buf[3]); delay++) { | |
83 | udelay(1000); | |
84 | } | |
85 | } else | |
86 | scratchreg |= 0x01; | |
87 | out_be32((void*)GPIO0_ISR3L, scratchreg); | |
88 | } | |
89 | ||
90 | if (scratchreg & 0x01) | |
91 | return &serial1_device; | |
92 | else | |
93 | return &serial0_device; | |
94 | } | |
95 | ||
96 | int board_early_init_f(void) | |
97 | { | |
98 | u32 sdr0_cust0; | |
99 | u32 sdr0_pfc1, sdr0_pfc2; | |
100 | u32 reg; | |
101 | ||
102 | /* general EBC configuration (disable EBC timeouts) */ | |
103 | mtdcr(ebccfga, xbcfg); | |
104 | mtdcr(ebccfgd, 0xf8400000); | |
105 | ||
034394ab | 106 | /* |
72c5d52a | 107 | * Setup the GPIO pins |
6d0f6bcf | 108 | * TODO: setup GPIOs via CONFIG_SYS_4xx_GPIO_TABLE in board's config file |
034394ab | 109 | */ |
bb57ad4b MF |
110 | out_be32((void *)GPIO0_OR, 0x40000102); |
111 | out_be32((void *)GPIO0_TCR, 0x4c90011f); | |
112 | out_be32((void *)GPIO0_OSRL, 0x28051400); | |
113 | out_be32((void *)GPIO0_OSRH, 0x55005000); | |
114 | out_be32((void *)GPIO0_TSRL, 0x08051400); | |
115 | out_be32((void *)GPIO0_TSRH, 0x55005000); | |
116 | out_be32((void *)GPIO0_ISR1L, 0x54000000); | |
117 | out_be32((void *)GPIO0_ISR1H, 0x00000000); | |
118 | out_be32((void *)GPIO0_ISR2L, 0x44000000); | |
119 | out_be32((void *)GPIO0_ISR2H, 0x00000100); | |
120 | out_be32((void *)GPIO0_ISR3L, 0x00000000); | |
121 | out_be32((void *)GPIO0_ISR3H, 0x00000000); | |
122 | ||
123 | out_be32((void *)GPIO1_OR, 0x80002408); | |
124 | out_be32((void *)GPIO1_TCR, 0xd6003c08); | |
125 | out_be32((void *)GPIO1_OSRL, 0x0a5a0000); | |
126 | out_be32((void *)GPIO1_OSRH, 0x00000000); | |
127 | out_be32((void *)GPIO1_TSRL, 0x00000000); | |
128 | out_be32((void *)GPIO1_TSRH, 0x00000000); | |
129 | out_be32((void *)GPIO1_ISR1L, 0x00005555); | |
130 | out_be32((void *)GPIO1_ISR1H, 0x40000000); | |
131 | out_be32((void *)GPIO1_ISR2L, 0x04010000); | |
132 | out_be32((void *)GPIO1_ISR2H, 0x00000000); | |
133 | out_be32((void *)GPIO1_ISR3L, 0x01400000); | |
134 | out_be32((void *)GPIO1_ISR3H, 0x00000000); | |
72c5d52a MF |
135 | |
136 | /* patch PLB:PCI divider for 66MHz PCI */ | |
137 | mfcpr(clk_spcid, reg); | |
138 | if (pci_is_66mhz() && (reg != 0x02000000)) { | |
139 | mtcpr(clk_spcid, 0x02000000); /* 133MHZ : 2 for 66MHz PCI */ | |
140 | ||
141 | mfcpr(clk_icfg, reg); | |
142 | reg |= CPR0_ICFG_RLI_MASK; | |
143 | mtcpr(clk_icfg, reg); | |
144 | ||
145 | mtspr(dbcr0, 0x20000000); /* do chip reset */ | |
146 | } | |
147 | ||
034394ab | 148 | /* |
72c5d52a | 149 | * Setup the interrupt controller polarities, triggers, etc. |
034394ab | 150 | */ |
72c5d52a MF |
151 | mtdcr(uic0sr, 0xffffffff); /* clear all */ |
152 | mtdcr(uic0er, 0x00000000); /* disable all */ | |
153 | mtdcr(uic0cr, 0x00000005); /* ATI & UIC1 crit are critical */ | |
154 | mtdcr(uic0pr, 0xfffff7ef); | |
155 | mtdcr(uic0tr, 0x00000000); | |
156 | mtdcr(uic0vr, 0x00000000); /* int31 highest, base=0x000 */ | |
157 | mtdcr(uic0sr, 0xffffffff); /* clear all */ | |
158 | ||
159 | mtdcr(uic1sr, 0xffffffff); /* clear all */ | |
160 | mtdcr(uic1er, 0x00000000); /* disable all */ | |
161 | mtdcr(uic1cr, 0x00000000); /* all non-critical */ | |
162 | mtdcr(uic1pr, 0xffffc7f5); | |
163 | mtdcr(uic1tr, 0x00000000); | |
164 | mtdcr(uic1vr, 0x00000000); /* int31 highest, base=0x000 */ | |
165 | mtdcr(uic1sr, 0xffffffff); /* clear all */ | |
166 | ||
167 | mtdcr(uic2sr, 0xffffffff); /* clear all */ | |
168 | mtdcr(uic2er, 0x00000000); /* disable all */ | |
169 | mtdcr(uic2cr, 0x00000000); /* all non-critical */ | |
170 | mtdcr(uic2pr, 0x27ffffff); | |
171 | mtdcr(uic2tr, 0x00000000); | |
172 | mtdcr(uic2vr, 0x00000000); /* int31 highest, base=0x000 */ | |
173 | mtdcr(uic2sr, 0xffffffff); /* clear all */ | |
174 | ||
175 | /* select Ethernet pins */ | |
176 | mfsdr(SDR0_PFC1, sdr0_pfc1); | |
034394ab MF |
177 | sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SELECT_MASK) | |
178 | SDR0_PFC1_SELECT_CONFIG_4; | |
72c5d52a | 179 | mfsdr(SDR0_PFC2, sdr0_pfc2); |
034394ab MF |
180 | sdr0_pfc2 = (sdr0_pfc2 & ~SDR0_PFC2_SELECT_MASK) | |
181 | SDR0_PFC2_SELECT_CONFIG_4; | |
72c5d52a MF |
182 | |
183 | /* enable 2nd IIC */ | |
184 | sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SIS_MASK) | SDR0_PFC1_SIS_IIC1_SEL; | |
185 | ||
186 | mtsdr(SDR0_PFC2, sdr0_pfc2); | |
187 | mtsdr(SDR0_PFC1, sdr0_pfc1); | |
188 | ||
189 | /* setup NAND FLASH */ | |
190 | mfsdr(SDR0_CUST0, sdr0_cust0); | |
191 | sdr0_cust0 = SDR0_CUST0_MUX_NDFC_SEL | | |
192 | SDR0_CUST0_NDFC_ENABLE | | |
193 | SDR0_CUST0_NDFC_BW_8_BIT | | |
194 | SDR0_CUST0_NDFC_ARE_MASK | | |
6d0f6bcf | 195 | (0x80000000 >> (28 + CONFIG_SYS_NAND_CS)); |
72c5d52a MF |
196 | mtsdr(SDR0_CUST0, sdr0_cust0); |
197 | ||
198 | return 0; | |
199 | } | |
200 | ||
be270798 MF |
201 | #if defined(CONFIG_MISC_INIT_F) |
202 | int misc_init_f(void) | |
203 | { | |
204 | struct pci_controller hose; | |
205 | hose.first_busno = 0; | |
206 | hose.last_busno = 0; | |
207 | hose.region_count = 0; | |
208 | ||
209 | if (getenv("pciearly") && (!is_monarch())) { | |
210 | printf("PCI: early target init\n"); | |
211 | pci_setup_indirect(&hose, PCIX0_CFGADR, PCIX0_CFGDATA); | |
212 | pci_target_init(&hose); | |
213 | } | |
214 | return 0; | |
215 | } | |
216 | #endif | |
217 | ||
034394ab MF |
218 | /* |
219 | * misc_init_r. | |
220 | */ | |
72c5d52a MF |
221 | int misc_init_r(void) |
222 | { | |
223 | uint pbcr; | |
224 | int size_val = 0; | |
225 | u32 reg; | |
226 | unsigned long usb2d0cr = 0; | |
227 | unsigned long usb2phy0cr, usb2h0cr = 0; | |
228 | unsigned long sdr0_pfc1; | |
be270798 | 229 | unsigned long sdr0_srst0, sdr0_srst1; |
72c5d52a MF |
230 | char *act = getenv("usbact"); |
231 | ||
232 | /* | |
233 | * FLASH stuff... | |
234 | */ | |
235 | ||
236 | /* Re-do sizing to get full correct info */ | |
237 | ||
238 | /* adjust flash start and offset */ | |
239 | gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize; | |
240 | gd->bd->bi_flashoffset = 0; | |
241 | ||
242 | #if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) | |
243 | mtdcr(ebccfga, pb2cr); | |
244 | #else | |
245 | mtdcr(ebccfga, pb0cr); | |
246 | #endif | |
247 | pbcr = mfdcr(ebccfgd); | |
034394ab | 248 | size_val = ffs(gd->bd->bi_flashsize) - 21; |
72c5d52a MF |
249 | pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17); |
250 | #if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) | |
251 | mtdcr(ebccfga, pb2cr); | |
252 | #else | |
253 | mtdcr(ebccfga, pb0cr); | |
254 | #endif | |
255 | mtdcr(ebccfgd, pbcr); | |
256 | ||
257 | /* | |
258 | * Re-check to get correct base address | |
259 | */ | |
260 | flash_get_size(gd->bd->bi_flashstart, 0); | |
261 | ||
5a1aceb0 | 262 | #ifdef CONFIG_ENV_IS_IN_FLASH |
72c5d52a MF |
263 | /* Monitor protection ON by default */ |
264 | (void)flash_protect(FLAG_PROTECT_SET, | |
6d0f6bcf | 265 | -CONFIG_SYS_MONITOR_LEN, |
72c5d52a MF |
266 | 0xffffffff, |
267 | &flash_info[0]); | |
268 | ||
269 | /* Env protection ON by default */ | |
270 | (void)flash_protect(FLAG_PROTECT_SET, | |
0e8d1586 JCPV |
271 | CONFIG_ENV_ADDR_REDUND, |
272 | CONFIG_ENV_ADDR_REDUND + 2*CONFIG_ENV_SECT_SIZE - 1, | |
72c5d52a MF |
273 | &flash_info[0]); |
274 | #endif | |
275 | ||
276 | /* | |
277 | * USB suff... | |
278 | */ | |
be270798 | 279 | if ((act == NULL || strcmp(act, "host") == 0) && |
72c5d52a MF |
280 | !(in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)){ |
281 | /* SDR Setting */ | |
282 | mfsdr(SDR0_PFC1, sdr0_pfc1); | |
283 | mfsdr(SDR0_USB2D0CR, usb2d0cr); | |
284 | mfsdr(SDR0_USB2PHY0CR, usb2phy0cr); | |
285 | mfsdr(SDR0_USB2H0CR, usb2h0cr); | |
286 | ||
287 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK; | |
034394ab | 288 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_XOCLK_EXTERNAL; |
72c5d52a | 289 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_WDINT_MASK; |
034394ab | 290 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_WDINT_16BIT_30MHZ; |
72c5d52a | 291 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DVBUS_MASK; |
034394ab | 292 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DVBUS_PURDIS; |
72c5d52a | 293 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DWNSTR_MASK; |
034394ab | 294 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DWNSTR_HOST; |
72c5d52a | 295 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_UTMICN_MASK; |
034394ab | 296 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_UTMICN_HOST; |
72c5d52a | 297 | |
034394ab MF |
298 | /* |
299 | * An 8-bit/60MHz interface is the only possible alternative | |
300 | * when connecting the Device to the PHY | |
301 | */ | |
72c5d52a | 302 | usb2h0cr = usb2h0cr &~SDR0_USB2H0CR_WDINT_MASK; |
034394ab | 303 | usb2h0cr = usb2h0cr | SDR0_USB2H0CR_WDINT_16BIT_30MHZ; |
72c5d52a MF |
304 | |
305 | usb2d0cr = usb2d0cr &~SDR0_USB2D0CR_USB2DEV_EBC_SEL_MASK; | |
306 | sdr0_pfc1 = sdr0_pfc1 &~SDR0_PFC1_UES_MASK; | |
307 | ||
308 | mtsdr(SDR0_PFC1, sdr0_pfc1); | |
309 | mtsdr(SDR0_USB2D0CR, usb2d0cr); | |
310 | mtsdr(SDR0_USB2PHY0CR, usb2phy0cr); | |
311 | mtsdr(SDR0_USB2H0CR, usb2h0cr); | |
312 | ||
be270798 MF |
313 | /* |
314 | * Take USB out of reset: | |
315 | * -Initial status = all cores are in reset | |
316 | * -deassert reset to OPB1, P4OPB0, OPB2, PLB42OPB1 OPB2PLB40 cores | |
317 | * -wait 1 ms | |
318 | * -deassert reset to PHY | |
319 | * -wait 1 ms | |
320 | * -deassert reset to HOST | |
321 | * -wait 4 ms | |
322 | * -deassert all other resets | |
323 | */ | |
324 | mfsdr(SDR0_SRST1, sdr0_srst1); | |
325 | sdr0_srst1 &= ~(SDR0_SRST1_OPBA1 | \ | |
326 | SDR0_SRST1_P4OPB0 | \ | |
327 | SDR0_SRST1_OPBA2 | \ | |
328 | SDR0_SRST1_PLB42OPB1 | \ | |
329 | SDR0_SRST1_OPB2PLB40); | |
330 | mtsdr(SDR0_SRST1, sdr0_srst1); | |
331 | udelay(1000); | |
332 | ||
333 | mfsdr(SDR0_SRST1, sdr0_srst1); | |
334 | sdr0_srst1 &= ~SDR0_SRST1_USB20PHY; | |
335 | mtsdr(SDR0_SRST1, sdr0_srst1); | |
72c5d52a | 336 | udelay(1000); |
be270798 MF |
337 | |
338 | mfsdr(SDR0_SRST0, sdr0_srst0); | |
339 | sdr0_srst0 &= ~SDR0_SRST0_USB2H; | |
340 | mtsdr(SDR0_SRST0, sdr0_srst0); | |
341 | udelay(4000); | |
342 | ||
343 | /* finally all the other resets */ | |
72c5d52a | 344 | mtsdr(SDR0_SRST1, 0x00000000); |
72c5d52a MF |
345 | mtsdr(SDR0_SRST0, 0x00000000); |
346 | ||
be270798 MF |
347 | if (!(in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)) { |
348 | /* enable power on USB socket */ | |
349 | out_be32((void*)GPIO1_OR, | |
350 | in_be32((void*)GPIO1_OR) & ~GPIO1_USB_PWR_N); | |
351 | } | |
352 | ||
72c5d52a MF |
353 | printf("USB: Host\n"); |
354 | ||
034394ab MF |
355 | } else if ((strcmp(act, "dev") == 0) || |
356 | (in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)) { | |
72c5d52a MF |
357 | mfsdr(SDR0_USB2PHY0CR, usb2phy0cr); |
358 | ||
359 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK; | |
034394ab | 360 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_XOCLK_EXTERNAL; |
72c5d52a | 361 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DVBUS_MASK; |
034394ab | 362 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DVBUS_PURDIS; |
72c5d52a | 363 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DWNSTR_MASK; |
034394ab | 364 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DWNSTR_HOST; |
72c5d52a | 365 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_UTMICN_MASK; |
034394ab | 366 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_UTMICN_HOST; |
72c5d52a MF |
367 | mtsdr(SDR0_USB2PHY0CR, usb2phy0cr); |
368 | ||
369 | udelay (1000); | |
370 | mtsdr(SDR0_SRST1, 0x672c6000); | |
371 | ||
372 | udelay (1000); | |
373 | mtsdr(SDR0_SRST0, 0x00000080); | |
374 | ||
375 | udelay (1000); | |
376 | mtsdr(SDR0_SRST1, 0x60206000); | |
377 | ||
378 | *(unsigned int *)(0xe0000350) = 0x00000001; | |
379 | ||
380 | udelay (1000); | |
381 | mtsdr(SDR0_SRST1, 0x60306000); | |
72c5d52a MF |
382 | |
383 | /* SDR Setting */ | |
384 | mfsdr(SDR0_USB2PHY0CR, usb2phy0cr); | |
385 | mfsdr(SDR0_USB2H0CR, usb2h0cr); | |
386 | mfsdr(SDR0_USB2D0CR, usb2d0cr); | |
387 | mfsdr(SDR0_PFC1, sdr0_pfc1); | |
388 | ||
389 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK; | |
034394ab | 390 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_XOCLK_EXTERNAL; |
72c5d52a | 391 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_WDINT_MASK; |
034394ab | 392 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_WDINT_8BIT_60MHZ; |
72c5d52a | 393 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DVBUS_MASK; |
034394ab | 394 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DVBUS_PUREN; |
72c5d52a | 395 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DWNSTR_MASK; |
034394ab | 396 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DWNSTR_DEV; |
72c5d52a | 397 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_UTMICN_MASK; |
034394ab | 398 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_UTMICN_DEV; |
72c5d52a MF |
399 | |
400 | usb2h0cr = usb2h0cr &~SDR0_USB2H0CR_WDINT_MASK; | |
034394ab | 401 | usb2h0cr = usb2h0cr | SDR0_USB2H0CR_WDINT_8BIT_60MHZ; |
72c5d52a MF |
402 | |
403 | usb2d0cr = usb2d0cr &~SDR0_USB2D0CR_USB2DEV_EBC_SEL_MASK; | |
404 | ||
405 | sdr0_pfc1 = sdr0_pfc1 &~SDR0_PFC1_UES_MASK; | |
034394ab | 406 | sdr0_pfc1 = sdr0_pfc1 | SDR0_PFC1_UES_EBCHR_SEL; |
72c5d52a MF |
407 | |
408 | mtsdr(SDR0_USB2H0CR, usb2h0cr); | |
409 | mtsdr(SDR0_USB2PHY0CR, usb2phy0cr); | |
410 | mtsdr(SDR0_USB2D0CR, usb2d0cr); | |
411 | mtsdr(SDR0_PFC1, sdr0_pfc1); | |
412 | ||
413 | /*clear resets*/ | |
414 | udelay(1000); | |
415 | mtsdr(SDR0_SRST1, 0x00000000); | |
416 | udelay(1000); | |
417 | mtsdr(SDR0_SRST0, 0x00000000); | |
418 | ||
419 | printf("USB: Device\n"); | |
420 | } | |
421 | ||
422 | /* | |
423 | * Clear PLB4A0_ACR[WRP] | |
424 | * This fix will make the MAL burst disabling patch for the Linux | |
425 | * EMAC driver obsolete. | |
426 | */ | |
427 | reg = mfdcr(plb4_acr) & ~PLB4_ACR_WRP; | |
428 | mtdcr(plb4_acr, reg); | |
429 | ||
430 | #ifdef CONFIG_FPGA | |
431 | pmc440_init_fpga(); | |
432 | #endif | |
433 | ||
434 | /* turn off POST LED */ | |
435 | out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_POST_N); | |
436 | /* turn on RUN LED */ | |
437 | out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) & ~GPIO0_LED_RUN_N); | |
438 | return 0; | |
439 | } | |
440 | ||
441 | int is_monarch(void) | |
442 | { | |
443 | if (in_be32((void*)GPIO1_IR) & GPIO1_NONMONARCH) | |
444 | return 0; | |
445 | ||
446 | return 1; | |
447 | } | |
448 | ||
449 | int pci_is_66mhz(void) | |
450 | { | |
451 | if (in_be32((void*)GPIO1_IR) & GPIO1_M66EN) | |
452 | return 1; | |
453 | return 0; | |
454 | } | |
455 | ||
456 | int board_revision(void) | |
457 | { | |
458 | return (int)((in_be32((void*)GPIO1_IR) & GPIO1_HWID_MASK) >> 4); | |
459 | } | |
460 | ||
461 | int checkboard(void) | |
462 | { | |
463 | puts("Board: esd GmbH - PMC440"); | |
464 | ||
465 | gd->board_type = board_revision(); | |
466 | printf(", Rev 1.%ld, ", gd->board_type); | |
467 | ||
468 | if (!is_monarch()) { | |
469 | puts("non-"); | |
470 | } | |
471 | ||
472 | printf("monarch, PCI=%s MHz\n", pci_is_66mhz() ? "66" : "33"); | |
473 | return (0); | |
474 | } | |
475 | ||
476 | ||
477 | #if defined(CONFIG_PCI) && defined(CONFIG_PCI_PNP) | |
478 | /* | |
479 | * Assign interrupts to PCI devices. Some OSs rely on this. | |
480 | */ | |
481 | void pmc440_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev) | |
482 | { | |
483 | unsigned char int_line[] = {IRQ_PCIC, IRQ_PCID, IRQ_PCIA, IRQ_PCIB}; | |
484 | ||
485 | pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, | |
486 | int_line[PCI_DEV(dev) & 0x03]); | |
487 | } | |
488 | #endif | |
489 | ||
034394ab MF |
490 | /* |
491 | * pci_pre_init | |
72c5d52a | 492 | * |
034394ab MF |
493 | * This routine is called just prior to registering the hose and gives |
494 | * the board the opportunity to check things. Returning a value of zero | |
495 | * indicates that things are bad & PCI initialization should be aborted. | |
72c5d52a | 496 | * |
034394ab MF |
497 | * Different boards may wish to customize the pci controller structure |
498 | * (add regions, override default access routines, etc) or perform | |
499 | * certain pre-initialization actions. | |
500 | */ | |
72c5d52a MF |
501 | #if defined(CONFIG_PCI) |
502 | int pci_pre_init(struct pci_controller *hose) | |
503 | { | |
504 | unsigned long addr; | |
505 | ||
034394ab MF |
506 | /* |
507 | * Set priority for all PLB3 devices to 0. | |
508 | * Set PLB3 arbiter to fair mode. | |
509 | */ | |
72c5d52a MF |
510 | mfsdr(sdr_amp1, addr); |
511 | mtsdr(sdr_amp1, (addr & 0x000000FF) | 0x0000FF00); | |
512 | addr = mfdcr(plb3_acr); | |
513 | mtdcr(plb3_acr, addr | 0x80000000); | |
514 | ||
034394ab MF |
515 | /* |
516 | * Set priority for all PLB4 devices to 0. | |
517 | */ | |
72c5d52a MF |
518 | mfsdr(sdr_amp0, addr); |
519 | mtsdr(sdr_amp0, (addr & 0x000000FF) | 0x0000FF00); | |
520 | addr = mfdcr(plb4_acr) | 0xa0000000; /* Was 0x8---- */ | |
521 | mtdcr(plb4_acr, addr); | |
522 | ||
034394ab MF |
523 | /* |
524 | * Set Nebula PLB4 arbiter to fair mode. | |
525 | */ | |
72c5d52a MF |
526 | /* Segment0 */ |
527 | addr = (mfdcr(plb0_acr) & ~plb0_acr_ppm_mask) | plb0_acr_ppm_fair; | |
528 | addr = (addr & ~plb0_acr_hbu_mask) | plb0_acr_hbu_enabled; | |
529 | addr = (addr & ~plb0_acr_rdp_mask) | plb0_acr_rdp_4deep; | |
530 | addr = (addr & ~plb0_acr_wrp_mask) | plb0_acr_wrp_2deep; | |
531 | mtdcr(plb0_acr, addr); | |
532 | ||
533 | /* Segment1 */ | |
534 | addr = (mfdcr(plb1_acr) & ~plb1_acr_ppm_mask) | plb1_acr_ppm_fair; | |
535 | addr = (addr & ~plb1_acr_hbu_mask) | plb1_acr_hbu_enabled; | |
536 | addr = (addr & ~plb1_acr_rdp_mask) | plb1_acr_rdp_4deep; | |
537 | addr = (addr & ~plb1_acr_wrp_mask) | plb1_acr_wrp_2deep; | |
538 | mtdcr(plb1_acr, addr); | |
539 | ||
540 | #ifdef CONFIG_PCI_PNP | |
541 | hose->fixup_irq = pmc440_pci_fixup_irq; | |
542 | #endif | |
543 | ||
544 | return 1; | |
545 | } | |
546 | #endif /* defined(CONFIG_PCI) */ | |
547 | ||
a6cc6c37 MF |
548 | /* |
549 | * pci_target_init | |
72c5d52a | 550 | * |
a6cc6c37 MF |
551 | * The bootstrap configuration provides default settings for the pci |
552 | * inbound map (PIM). But the bootstrap config choices are limited and | |
553 | * may not be sufficient for a given board. | |
554 | */ | |
6d0f6bcf | 555 | #if defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT) |
72c5d52a MF |
556 | void pci_target_init(struct pci_controller *hose) |
557 | { | |
a6cc6c37 MF |
558 | char *ptmla_str, *ptmms_str; |
559 | ||
560 | /* | |
72c5d52a | 561 | * Set up Direct MMIO registers |
a6cc6c37 MF |
562 | */ |
563 | /* | |
564 | * PowerPC440EPX PCI Master configuration. | |
565 | * Map one 1Gig range of PLB/processor addresses to PCI memory space. | |
566 | * PLB address 0x80000000-0xBFFFFFFF | |
567 | * ==> PCI address 0x80000000-0xBFFFFFFF | |
568 | * Use byte reversed out routines to handle endianess. | |
569 | * Make this region non-prefetchable. | |
570 | */ | |
571 | out32r(PCIX0_PMM0MA, 0x00000000); /* PMM0 Mask/Attribute */ | |
572 | /* - disabled b4 setting */ | |
6d0f6bcf JCPV |
573 | out32r(PCIX0_PMM0LA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 Local Address */ |
574 | out32r(PCIX0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 PCI Low Address */ | |
72c5d52a | 575 | out32r(PCIX0_PMM0PCIHA, 0x00000000); /* PMM0 PCI High Address */ |
a6cc6c37 MF |
576 | out32r(PCIX0_PMM0MA, 0xc0000001); /* 1G + No prefetching, */ |
577 | /* and enable region */ | |
72c5d52a MF |
578 | |
579 | if (!is_monarch()) { | |
a6cc6c37 MF |
580 | ptmla_str = getenv("ptm1la"); |
581 | ptmms_str = getenv("ptm1ms"); | |
582 | if(NULL != ptmla_str && NULL != ptmms_str ) { | |
583 | out32r(PCIX0_PTM1MS, | |
584 | simple_strtoul(ptmms_str, NULL, 16)); | |
585 | out32r(PCIX0_PTM1LA, | |
586 | simple_strtoul(ptmla_str, NULL, 16)); | |
587 | } else { | |
588 | /* BAR1: default top 64MB of RAM */ | |
589 | out32r(PCIX0_PTM1MS, 0xfc000001); | |
590 | out32r(PCIX0_PTM1LA, 0x0c000000); | |
591 | } | |
72c5d52a | 592 | } else { |
a6cc6c37 MF |
593 | /* BAR1: default: complete 256MB RAM */ |
594 | out32r(PCIX0_PTM1MS, 0xf0000001); | |
595 | out32r(PCIX0_PTM1LA, 0x00000000); | |
72c5d52a MF |
596 | } |
597 | ||
a6cc6c37 MF |
598 | ptmla_str = getenv("ptm2la"); /* Local Addr. Reg */ |
599 | ptmms_str = getenv("ptm2ms"); /* Memory Size/Attribute */ | |
600 | if(NULL != ptmla_str && NULL != ptmms_str ) { | |
601 | out32r(PCIX0_PTM2MS, simple_strtoul(ptmms_str, NULL, 16)); | |
602 | out32r(PCIX0_PTM2LA, simple_strtoul(ptmla_str, NULL, 16)); | |
603 | } else { | |
be270798 MF |
604 | /* BAR2: default: 4MB FPGA */ |
605 | out32r(PCIX0_PTM2MS, 0xffc00001); /* Memory Size/Attribute */ | |
a6cc6c37 MF |
606 | out32r(PCIX0_PTM2LA, 0xef000000); /* Local Addr. Reg */ |
607 | } | |
72c5d52a MF |
608 | |
609 | if (is_monarch()) { | |
610 | /* BAR2: map FPGA registers behind system memory at 1GB */ | |
be270798 | 611 | pci_hose_write_config_dword(hose, 0, PCI_BASE_ADDRESS_2, 0x40000008); |
72c5d52a MF |
612 | } |
613 | ||
a6cc6c37 | 614 | /* |
72c5d52a | 615 | * Set up Configuration registers |
a6cc6c37 | 616 | */ |
72c5d52a MF |
617 | |
618 | /* Program the board's vendor id */ | |
be270798 MF |
619 | pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_VENDOR_ID, |
620 | CONFIG_SYS_PCI_SUBSYS_VENDORID); | |
72c5d52a | 621 | |
02e38920 | 622 | /* disabled for PMC405 backward compatibility */ |
72c5d52a | 623 | /* Configure command register as bus master */ |
034394ab MF |
624 | /* pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER); */ |
625 | ||
72c5d52a MF |
626 | |
627 | /* 240nS PCI clock */ | |
be270798 | 628 | pci_hose_write_config_word(hose, 0, PCI_LATENCY_TIMER, 1); |
72c5d52a MF |
629 | |
630 | /* No error reporting */ | |
be270798 | 631 | pci_hose_write_config_word(hose, 0, PCI_ERREN, 0); |
72c5d52a MF |
632 | |
633 | pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101); | |
634 | ||
635 | if (!is_monarch()) { | |
636 | /* Program the board's subsystem id/classcode */ | |
be270798 MF |
637 | pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_ID, |
638 | CONFIG_SYS_PCI_SUBSYS_ID_NONMONARCH); | |
639 | pci_hose_write_config_word(hose, 0, PCI_CLASS_SUB_CODE, | |
640 | CONFIG_SYS_PCI_CLASSCODE_NONMONARCH); | |
72c5d52a MF |
641 | |
642 | /* PCI configuration done: release ERREADY */ | |
a6cc6c37 MF |
643 | out_be32((void*)GPIO1_OR, |
644 | in_be32((void*)GPIO1_OR) | GPIO1_PPC_EREADY); | |
645 | out_be32((void*)GPIO1_TCR, | |
646 | in_be32((void*)GPIO1_TCR) | GPIO1_PPC_EREADY); | |
72c5d52a MF |
647 | } else { |
648 | /* Program the board's subsystem id/classcode */ | |
be270798 MF |
649 | pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_ID, |
650 | CONFIG_SYS_PCI_SUBSYS_ID_MONARCH); | |
651 | pci_hose_write_config_word(hose, 0, PCI_CLASS_SUB_CODE, | |
652 | CONFIG_SYS_PCI_CLASSCODE_MONARCH); | |
72c5d52a | 653 | } |
be270798 MF |
654 | |
655 | /* enable host configuration */ | |
656 | pci_hose_write_config_dword(hose, 0, PCI_BRDGOPT2, 0x00000101); | |
72c5d52a | 657 | } |
6d0f6bcf | 658 | #endif /* defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT) */ |
72c5d52a | 659 | |
034394ab MF |
660 | /* |
661 | * pci_master_init | |
662 | */ | |
6d0f6bcf | 663 | #if defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_MASTER_INIT) |
72c5d52a MF |
664 | void pci_master_init(struct pci_controller *hose) |
665 | { | |
666 | unsigned short temp_short; | |
667 | ||
034394ab MF |
668 | /* |
669 | * Write the PowerPC440 EP PCI Configuration regs. | |
670 | * Enable PowerPC440 EP to be a master on the PCI bus (PMM). | |
671 | * Enable PowerPC440 EP to act as a PCI memory target (PTM). | |
672 | */ | |
72c5d52a MF |
673 | if (is_monarch()) { |
674 | pci_read_config_word(0, PCI_COMMAND, &temp_short); | |
675 | pci_write_config_word(0, PCI_COMMAND, | |
676 | temp_short | PCI_COMMAND_MASTER | | |
677 | PCI_COMMAND_MEMORY); | |
678 | } | |
679 | } | |
6d0f6bcf | 680 | #endif /* defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_MASTER_INIT) */ |
72c5d52a | 681 | |
72c5d52a MF |
682 | static void wait_for_pci_ready(void) |
683 | { | |
684 | int i; | |
685 | char *s = getenv("pcidelay"); | |
be270798 MF |
686 | /* |
687 | * We have our own handling of the pcidelay variable. | |
688 | * Using CONFIG_PCI_BOOTDELAY enables pausing for host | |
689 | * and adapter devices. For adapter devices we do not | |
690 | * want this. | |
691 | */ | |
72c5d52a MF |
692 | if (s) { |
693 | int ms = simple_strtoul(s, NULL, 10); | |
694 | printf("PCI: Waiting for %d ms\n", ms); | |
695 | for (i=0; i<ms; i++) | |
696 | udelay(1000); | |
697 | } | |
698 | ||
699 | if (!(in_be32((void*)GPIO1_IR) & GPIO1_PPC_EREADY)) { | |
700 | printf("PCI: Waiting for EREADY (CTRL-C to skip) ... "); | |
701 | while (1) { | |
702 | if (ctrlc()) { | |
703 | puts("abort\n"); | |
704 | break; | |
705 | } | |
706 | if (in_be32((void*)GPIO1_IR) & GPIO1_PPC_EREADY) { | |
707 | printf("done\n"); | |
708 | break; | |
709 | } | |
710 | } | |
711 | } | |
712 | } | |
713 | ||
034394ab MF |
714 | /* |
715 | * is_pci_host | |
72c5d52a | 716 | * |
034394ab MF |
717 | * This routine is called to determine if a pci scan should be |
718 | * performed. With various hardware environments (especially cPCI and | |
719 | * PPMC) it's insufficient to depend on the state of the arbiter enable | |
720 | * bit in the strap register, or generic host/adapter assumptions. | |
72c5d52a | 721 | * |
034394ab MF |
722 | * Rather than hard-code a bad assumption in the general 440 code, the |
723 | * 440 pci code requires the board to decide at runtime. | |
72c5d52a | 724 | * |
034394ab MF |
725 | * Return 0 for adapter mode, non-zero for host (monarch) mode. |
726 | */ | |
72c5d52a MF |
727 | #if defined(CONFIG_PCI) |
728 | int is_pci_host(struct pci_controller *hose) | |
729 | { | |
730 | char *s = getenv("pciscan"); | |
731 | if (s == NULL) | |
732 | if (is_monarch()) { | |
733 | wait_for_pci_ready(); | |
734 | return 1; | |
735 | } else | |
736 | return 0; | |
737 | else if (!strcmp(s, "yes")) | |
738 | return 1; | |
739 | ||
740 | return 0; | |
741 | } | |
742 | #endif /* defined(CONFIG_PCI) */ | |
034394ab | 743 | |
72c5d52a MF |
744 | #if defined(CONFIG_POST) |
745 | /* | |
746 | * Returns 1 if keys pressed to start the power-on long-running tests | |
747 | * Called from board_init_f(). | |
748 | */ | |
749 | int post_hotkeys_pressed(void) | |
750 | { | |
751 | return 0; /* No hotkeys supported */ | |
752 | } | |
753 | #endif /* CONFIG_POST */ | |
754 | ||
72c5d52a MF |
755 | #ifdef CONFIG_RESET_PHY_R |
756 | void reset_phy(void) | |
757 | { | |
5b67a143 MF |
758 | char *s; |
759 | unsigned short val_method, val_behavior; | |
760 | ||
761 | /* special LED setup for NGCC/CANDES */ | |
762 | if ((s = getenv("bd_type")) && | |
763 | ((!strcmp(s, "ngcc")) || (!strcmp(s, "candes")))) { | |
764 | val_method = 0x0e0a; | |
765 | val_behavior = 0x0cf2; | |
766 | } else { | |
767 | /* PMC440 standard type */ | |
768 | val_method = 0x0e10; | |
769 | val_behavior = 0x0cf0; | |
770 | } | |
771 | ||
72c5d52a MF |
772 | if (miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0001) == 0) { |
773 | miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, 0x0010); | |
5b67a143 MF |
774 | miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, val_behavior); |
775 | miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, val_method); | |
72c5d52a MF |
776 | miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0000); |
777 | } | |
778 | ||
779 | if (miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0001) == 0) { | |
780 | miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, 0x0010); | |
5b67a143 MF |
781 | miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, val_behavior); |
782 | miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x10, val_method); | |
72c5d52a MF |
783 | miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0000); |
784 | } | |
785 | } | |
786 | #endif | |
787 | ||
6d0f6bcf | 788 | #if defined(CONFIG_SYS_EEPROM_WREN) |
034394ab MF |
789 | /* |
790 | * Input: <dev_addr> I2C address of EEPROM device to enable. | |
791 | * <state> -1: deliver current state | |
72c5d52a MF |
792 | * 0: disable write |
793 | * 1: enable write | |
034394ab MF |
794 | * Returns: -1: wrong device address |
795 | * 0: dis-/en- able done | |
72c5d52a MF |
796 | * 0/1: current state if <state> was -1. |
797 | */ | |
798 | int eeprom_write_enable(unsigned dev_addr, int state) | |
799 | { | |
6d0f6bcf JCPV |
800 | if ((CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) && |
801 | (CONFIG_SYS_I2C_BOOT_EEPROM_ADDR != dev_addr)) { | |
72c5d52a MF |
802 | return -1; |
803 | } else { | |
804 | switch (state) { | |
805 | case 1: | |
806 | /* Enable write access, clear bit GPIO_SINT2. */ | |
bb57ad4b MF |
807 | out_be32((void *)GPIO0_OR, |
808 | in_be32((void *)GPIO0_OR) & ~GPIO0_EP_EEP); | |
72c5d52a MF |
809 | state = 0; |
810 | break; | |
811 | case 0: | |
812 | /* Disable write access, set bit GPIO_SINT2. */ | |
bb57ad4b MF |
813 | out_be32((void *)GPIO0_OR, |
814 | in_be32((void *)GPIO0_OR) | GPIO0_EP_EEP); | |
72c5d52a MF |
815 | state = 0; |
816 | break; | |
817 | default: | |
818 | /* Read current status back. */ | |
bb57ad4b MF |
819 | state = (0 == (in_be32((void *)GPIO0_OR) |
820 | & GPIO0_EP_EEP)); | |
72c5d52a MF |
821 | break; |
822 | } | |
823 | } | |
824 | return state; | |
825 | } | |
6d0f6bcf | 826 | #endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */ |
72c5d52a | 827 | |
6d0f6bcf | 828 | #define CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS 3 |
034394ab MF |
829 | int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset, |
830 | uchar *buffer, unsigned cnt) | |
72c5d52a MF |
831 | { |
832 | unsigned end = offset + cnt; | |
833 | unsigned blk_off; | |
834 | int rcode = 0; | |
835 | ||
6d0f6bcf | 836 | #if defined(CONFIG_SYS_EEPROM_WREN) |
72c5d52a MF |
837 | eeprom_write_enable(dev_addr, 1); |
838 | #endif | |
034394ab MF |
839 | /* |
840 | * Write data until done or would cross a write page boundary. | |
72c5d52a MF |
841 | * We must write the address again when changing pages |
842 | * because the address counter only increments within a page. | |
843 | */ | |
844 | ||
845 | while (offset < end) { | |
846 | unsigned alen, len; | |
847 | unsigned maxlen; | |
848 | uchar addr[2]; | |
849 | ||
850 | blk_off = offset & 0xFF; /* block offset */ | |
851 | ||
852 | addr[0] = offset >> 8; /* block number */ | |
853 | addr[1] = blk_off; /* block offset */ | |
854 | alen = 2; | |
855 | addr[0] |= dev_addr; /* insert device address */ | |
856 | ||
857 | len = end - offset; | |
858 | ||
6d0f6bcf | 859 | #define BOOT_EEPROM_PAGE_SIZE (1 << CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS) |
72c5d52a MF |
860 | #define BOOT_EEPROM_PAGE_OFFSET(x) ((x) & (BOOT_EEPROM_PAGE_SIZE - 1)) |
861 | ||
034394ab MF |
862 | maxlen = BOOT_EEPROM_PAGE_SIZE - |
863 | BOOT_EEPROM_PAGE_OFFSET(blk_off); | |
72c5d52a MF |
864 | if (maxlen > I2C_RXTX_LEN) |
865 | maxlen = I2C_RXTX_LEN; | |
866 | ||
867 | if (len > maxlen) | |
868 | len = maxlen; | |
869 | ||
870 | if (i2c_write (addr[0], offset, alen-1, buffer, len) != 0) | |
871 | rcode = 1; | |
872 | ||
873 | buffer += len; | |
874 | offset += len; | |
875 | ||
6d0f6bcf JCPV |
876 | #if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS) |
877 | udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); | |
72c5d52a MF |
878 | #endif |
879 | } | |
6d0f6bcf | 880 | #if defined(CONFIG_SYS_EEPROM_WREN) |
72c5d52a MF |
881 | eeprom_write_enable(dev_addr, 0); |
882 | #endif | |
883 | return rcode; | |
884 | } | |
885 | ||
034394ab MF |
886 | int bootstrap_eeprom_read (unsigned dev_addr, unsigned offset, |
887 | uchar *buffer, unsigned cnt) | |
72c5d52a MF |
888 | { |
889 | unsigned end = offset + cnt; | |
890 | unsigned blk_off; | |
891 | int rcode = 0; | |
892 | ||
034394ab MF |
893 | /* |
894 | * Read data until done or would cross a page boundary. | |
72c5d52a MF |
895 | * We must write the address again when changing pages |
896 | * because the next page may be in a different device. | |
897 | */ | |
898 | while (offset < end) { | |
899 | unsigned alen, len; | |
900 | unsigned maxlen; | |
901 | uchar addr[2]; | |
902 | ||
903 | blk_off = offset & 0xFF; /* block offset */ | |
904 | ||
905 | addr[0] = offset >> 8; /* block number */ | |
906 | addr[1] = blk_off; /* block offset */ | |
907 | alen = 2; | |
908 | ||
909 | addr[0] |= dev_addr; /* insert device address */ | |
910 | ||
911 | len = end - offset; | |
912 | ||
913 | maxlen = 0x100 - blk_off; | |
914 | if (maxlen > I2C_RXTX_LEN) | |
915 | maxlen = I2C_RXTX_LEN; | |
916 | if (len > maxlen) | |
917 | len = maxlen; | |
918 | ||
919 | if (i2c_read (addr[0], offset, alen-1, buffer, len) != 0) | |
920 | rcode = 1; | |
921 | buffer += len; | |
922 | offset += len; | |
923 | } | |
924 | ||
925 | return rcode; | |
926 | } | |
927 | ||
6d0f6bcf | 928 | #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT) |
72c5d52a MF |
929 | int usb_board_init(void) |
930 | { | |
931 | char *act = getenv("usbact"); | |
932 | int i; | |
933 | ||
be270798 | 934 | if ((act == NULL || strcmp(act, "host") == 0) && |
72c5d52a MF |
935 | !(in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)) |
936 | /* enable power on USB socket */ | |
034394ab MF |
937 | out_be32((void*)GPIO1_OR, |
938 | in_be32((void*)GPIO1_OR) & ~GPIO1_USB_PWR_N); | |
72c5d52a MF |
939 | |
940 | for (i=0; i<1000; i++) | |
941 | udelay(1000); | |
942 | ||
943 | return 0; | |
944 | } | |
945 | ||
946 | int usb_board_stop(void) | |
947 | { | |
948 | /* disable power on USB socket */ | |
949 | out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_USB_PWR_N); | |
950 | return 0; | |
951 | } | |
952 | ||
953 | int usb_board_init_fail(void) | |
954 | { | |
955 | usb_board_stop(); | |
956 | return 0; | |
957 | } | |
6d0f6bcf | 958 | #endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT) */ |
be270798 MF |
959 | |
960 | #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) | |
961 | void ft_board_setup(void *blob, bd_t *bd) | |
962 | { | |
963 | int rc; | |
964 | ||
965 | __ft_board_setup(blob, bd); | |
966 | ||
967 | /* | |
968 | * Disable PCI in non-monarch mode. | |
969 | */ | |
970 | if (!is_monarch()) { | |
971 | rc = fdt_find_and_setprop(blob, "/plb/pci@1ec000000", "status", | |
972 | "disabled", sizeof("disabled"), 1); | |
973 | if (rc) { | |
974 | printf("Unable to update property status in PCI node, err=%s\n", | |
975 | fdt_strerror(rc)); | |
976 | } | |
977 | } | |
978 | } | |
979 | #endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ |