]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * (C) Copyright 2007 | |
3 | * Stefan Roese, DENX Software Engineering, sr@denx.de. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or | |
6 | * modify it under the terms of the GNU General Public License as | |
7 | * published by the Free Software Foundation; either version 2 of | |
8 | * the License, or (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, write to the Free Software | |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
18 | * MA 02111-1307 USA | |
19 | */ | |
20 | ||
21 | #include <common.h> | |
22 | #include <command.h> | |
23 | #include <ppc440.h> | |
24 | #include <asm/processor.h> | |
25 | #include <asm/gpio.h> | |
26 | #include <asm/io.h> | |
27 | ||
28 | DECLARE_GLOBAL_DATA_PTR; | |
29 | ||
30 | extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ | |
31 | ||
32 | ulong flash_get_size(ulong base, int banknum); | |
33 | int misc_init_r_kbd(void); | |
34 | ||
35 | int board_early_init_f(void) | |
36 | { | |
37 | u32 sdr0_pfc1, sdr0_pfc2; | |
38 | u32 reg; | |
39 | ||
40 | /* PLB Write pipelining disabled. Denali Core workaround */ | |
41 | mtdcr(PLB0_ACR, 0xDE000000); | |
42 | mtdcr(PLB1_ACR, 0xDE000000); | |
43 | ||
44 | /*-------------------------------------------------------------------- | |
45 | * Setup the interrupt controller polarities, triggers, etc. | |
46 | *-------------------------------------------------------------------*/ | |
47 | mtdcr(UIC0SR, 0xffffffff); /* clear all. if write with 1 then the status is cleared */ | |
48 | mtdcr(UIC0ER, 0x00000000); /* disable all */ | |
49 | mtdcr(UIC0CR, 0x00000000); /* we have not critical interrupts at the moment */ | |
50 | mtdcr(UIC0PR, 0xFFBFF1EF); /* Adjustment of the polarity */ | |
51 | mtdcr(UIC0TR, 0x00000900); /* per ref-board manual */ | |
52 | mtdcr(UIC0VR, 0x00000000); /* int31 highest, base=0x000 is within DDRAM */ | |
53 | mtdcr(UIC0SR, 0xffffffff); /* clear all */ | |
54 | ||
55 | mtdcr(UIC1SR, 0xffffffff); /* clear all */ | |
56 | mtdcr(UIC1ER, 0x00000000); /* disable all */ | |
57 | mtdcr(UIC1CR, 0x00000000); /* all non-critical */ | |
58 | mtdcr(UIC1PR, 0xFFFFC6A5); /* Adjustment of the polarity */ | |
59 | mtdcr(UIC1TR, 0x60000040); /* per ref-board manual */ | |
60 | mtdcr(UIC1VR, 0x00000000); /* int31 highest, base=0x000 is within DDRAM */ | |
61 | mtdcr(UIC1SR, 0xffffffff); /* clear all */ | |
62 | ||
63 | mtdcr(UIC2SR, 0xffffffff); /* clear all */ | |
64 | mtdcr(UIC2ER, 0x00000000); /* disable all */ | |
65 | mtdcr(UIC2CR, 0x00000000); /* all non-critical */ | |
66 | mtdcr(UIC2PR, 0x27C00000); /* Adjustment of the polarity */ | |
67 | mtdcr(UIC2TR, 0x3C000000); /* per ref-board manual */ | |
68 | mtdcr(UIC2VR, 0x00000000); /* int31 highest, base=0x000 is within DDRAM */ | |
69 | mtdcr(UIC2SR, 0xffffffff); /* clear all */ | |
70 | ||
71 | /* Trace Pins are disabled. SDR0_PFC0 Register */ | |
72 | mtsdr(SDR0_PFC0, 0x0); | |
73 | ||
74 | /* select Ethernet pins */ | |
75 | mfsdr(SDR0_PFC1, sdr0_pfc1); | |
76 | /* SMII via ZMII */ | |
77 | sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SELECT_MASK) | | |
78 | SDR0_PFC1_SELECT_CONFIG_6; | |
79 | mfsdr(SDR0_PFC2, sdr0_pfc2); | |
80 | sdr0_pfc2 = (sdr0_pfc2 & ~SDR0_PFC2_SELECT_MASK) | | |
81 | SDR0_PFC2_SELECT_CONFIG_6; | |
82 | ||
83 | /* enable SPI (SCP) */ | |
84 | sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SIS_MASK) | SDR0_PFC1_SIS_SCP_SEL; | |
85 | ||
86 | mtsdr(SDR0_PFC2, sdr0_pfc2); | |
87 | mtsdr(SDR0_PFC1, sdr0_pfc1); | |
88 | ||
89 | mtsdr(SDR0_PFC4, 0x80000000); | |
90 | ||
91 | /* PCI arbiter disabled */ | |
92 | /* PCI Host Configuration disbaled */ | |
93 | mfsdr(SDR0_PCI0, reg); | |
94 | reg = 0; | |
95 | mtsdr(SDR0_PCI0, 0x00000000 | reg); | |
96 | ||
97 | gpio_write_bit(CONFIG_SYS_GPIO_FLASH_WP, 1); | |
98 | ||
99 | #if CONFIG_POST & CONFIG_SYS_POST_BSPEC1 | |
100 | gpio_write_bit(CONFIG_SYS_GPIO_HIGHSIDE, 1); | |
101 | ||
102 | reg = 0; /* reuse as counter */ | |
103 | out_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR, | |
104 | in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR) | |
105 | & ~CONFIG_SYS_DSPIC_TEST_MASK); | |
106 | while (!gpio_read_in_bit(CONFIG_SYS_GPIO_DSPIC_READY) && reg++ < 1000) { | |
107 | udelay(1000); | |
108 | } | |
109 | gpio_write_bit(CONFIG_SYS_GPIO_HIGHSIDE, 0); | |
110 | if (gpio_read_in_bit(CONFIG_SYS_GPIO_DSPIC_READY)) { | |
111 | /* set "boot error" flag */ | |
112 | out_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR, | |
113 | in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR) | | |
114 | CONFIG_SYS_DSPIC_TEST_MASK); | |
115 | } | |
116 | #endif | |
117 | ||
118 | /* | |
119 | * Reset PHY's: | |
120 | * The PHY's need a 2nd reset pulse, since the MDIO address is latched | |
121 | * upon reset, and with the first reset upon powerup, the addresses are | |
122 | * not latched reliable, since the IRQ line is multiplexed with an | |
123 | * MDIO address. A 2nd reset at this time will make sure, that the | |
124 | * correct address is latched. | |
125 | */ | |
126 | gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 1); | |
127 | gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 1); | |
128 | udelay(1000); | |
129 | gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 0); | |
130 | gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 0); | |
131 | udelay(1000); | |
132 | gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 1); | |
133 | gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 1); | |
134 | ||
135 | return 0; | |
136 | } | |
137 | ||
138 | /*---------------------------------------------------------------------------+ | |
139 | | misc_init_r. | |
140 | +---------------------------------------------------------------------------*/ | |
141 | int misc_init_r(void) | |
142 | { | |
143 | u32 pbcr; | |
144 | int size_val = 0; | |
145 | u32 reg; | |
146 | unsigned long usb2d0cr = 0; | |
147 | unsigned long usb2phy0cr, usb2h0cr = 0; | |
148 | unsigned long sdr0_pfc1; | |
149 | ||
150 | /* | |
151 | * FLASH stuff... | |
152 | */ | |
153 | ||
154 | /* Re-do sizing to get full correct info */ | |
155 | ||
156 | /* adjust flash start and offset */ | |
157 | gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize; | |
158 | gd->bd->bi_flashoffset = 0; | |
159 | ||
160 | mfebc(PB0CR, pbcr); | |
161 | switch (gd->bd->bi_flashsize) { | |
162 | case 1 << 20: | |
163 | size_val = 0; | |
164 | break; | |
165 | case 2 << 20: | |
166 | size_val = 1; | |
167 | break; | |
168 | case 4 << 20: | |
169 | size_val = 2; | |
170 | break; | |
171 | case 8 << 20: | |
172 | size_val = 3; | |
173 | break; | |
174 | case 16 << 20: | |
175 | size_val = 4; | |
176 | break; | |
177 | case 32 << 20: | |
178 | size_val = 5; | |
179 | break; | |
180 | case 64 << 20: | |
181 | size_val = 6; | |
182 | break; | |
183 | case 128 << 20: | |
184 | size_val = 7; | |
185 | break; | |
186 | } | |
187 | pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17); | |
188 | mtebc(PB0CR, pbcr); | |
189 | ||
190 | /* | |
191 | * Re-check to get correct base address | |
192 | */ | |
193 | flash_get_size(gd->bd->bi_flashstart, 0); | |
194 | ||
195 | /* Monitor protection ON by default */ | |
196 | (void)flash_protect(FLAG_PROTECT_SET, | |
197 | -CONFIG_SYS_MONITOR_LEN, | |
198 | 0xffffffff, | |
199 | &flash_info[1]); | |
200 | ||
201 | /* Env protection ON by default */ | |
202 | (void)flash_protect(FLAG_PROTECT_SET, | |
203 | CONFIG_ENV_ADDR_REDUND, | |
204 | CONFIG_ENV_ADDR_REDUND + 2*CONFIG_ENV_SECT_SIZE - 1, | |
205 | &flash_info[1]); | |
206 | ||
207 | /* | |
208 | * USB suff... | |
209 | */ | |
210 | /* SDR Setting */ | |
211 | mfsdr(SDR0_PFC1, sdr0_pfc1); | |
212 | mfsdr(SDR0_USB0, usb2d0cr); | |
213 | mfsdr(SDR0_USB2PHY0CR, usb2phy0cr); | |
214 | mfsdr(SDR0_USB2H0CR, usb2h0cr); | |
215 | ||
216 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK; | |
217 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_XOCLK_EXTERNAL; /*0*/ | |
218 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_WDINT_MASK; | |
219 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_WDINT_16BIT_30MHZ; /*1*/ | |
220 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DVBUS_MASK; | |
221 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DVBUS_PURDIS; /*0*/ | |
222 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_DWNSTR_MASK; | |
223 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_DWNSTR_HOST; /*1*/ | |
224 | usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_UTMICN_MASK; | |
225 | usb2phy0cr = usb2phy0cr | SDR0_USB2PHY0CR_UTMICN_HOST; /*1*/ | |
226 | ||
227 | /* An 8-bit/60MHz interface is the only possible alternative | |
228 | when connecting the Device to the PHY */ | |
229 | usb2h0cr = usb2h0cr &~SDR0_USB2H0CR_WDINT_MASK; | |
230 | usb2h0cr = usb2h0cr | SDR0_USB2H0CR_WDINT_16BIT_30MHZ; /*1*/ | |
231 | ||
232 | mtsdr(SDR0_PFC1, sdr0_pfc1); | |
233 | mtsdr(SDR0_USB0, usb2d0cr); | |
234 | mtsdr(SDR0_USB2PHY0CR, usb2phy0cr); | |
235 | mtsdr(SDR0_USB2H0CR, usb2h0cr); | |
236 | ||
237 | /* | |
238 | * Clear resets | |
239 | */ | |
240 | udelay (1000); | |
241 | mtsdr(SDR0_SRST1, 0x00000000); | |
242 | udelay (1000); | |
243 | mtsdr(SDR0_SRST0, 0x00000000); | |
244 | ||
245 | printf("USB: Host(int phy) Device(ext phy)\n"); | |
246 | ||
247 | /* | |
248 | * Clear PLB4A0_ACR[WRP] | |
249 | * This fix will make the MAL burst disabling patch for the Linux | |
250 | * EMAC driver obsolete. | |
251 | */ | |
252 | reg = mfdcr(PLB4_ACR) & ~PLB4_ACR_WRP; | |
253 | mtdcr(PLB4_ACR, reg); | |
254 | ||
255 | /* | |
256 | * Init matrix keyboard | |
257 | */ | |
258 | misc_init_r_kbd(); | |
259 | ||
260 | return 0; | |
261 | } | |
262 | ||
263 | int checkboard(void) | |
264 | { | |
265 | char *s = getenv("serial#"); | |
266 | ||
267 | printf("Board: lwmon5"); | |
268 | ||
269 | if (s != NULL) { | |
270 | puts(", serial# "); | |
271 | puts(s); | |
272 | } | |
273 | putc('\n'); | |
274 | ||
275 | return (0); | |
276 | } | |
277 | ||
278 | void hw_watchdog_reset(void) | |
279 | { | |
280 | int val; | |
281 | #if defined(CONFIG_WD_MAX_RATE) | |
282 | unsigned long long ct = get_ticks(); | |
283 | ||
284 | /* | |
285 | * Don't allow watch-dog triggering more frequently than | |
286 | * the predefined value CONFIG_WD_MAX_RATE [ticks]. | |
287 | */ | |
288 | if (ct >= gd->wdt_last) { | |
289 | if ((ct - gd->wdt_last) < CONFIG_WD_MAX_RATE) | |
290 | return; | |
291 | } else { | |
292 | /* Time base counter had been reset */ | |
293 | if (((unsigned long long)(-1) - gd->wdt_last + ct) < | |
294 | CONFIG_WD_MAX_RATE) | |
295 | return; | |
296 | } | |
297 | gd->wdt_last = get_ticks(); | |
298 | #endif | |
299 | ||
300 | /* | |
301 | * Toggle watchdog output | |
302 | */ | |
303 | val = gpio_read_out_bit(CONFIG_SYS_GPIO_WATCHDOG) == 0 ? 1 : 0; | |
304 | gpio_write_bit(CONFIG_SYS_GPIO_WATCHDOG, val); | |
305 | } | |
306 | ||
307 | int do_eeprom_wp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
308 | { | |
309 | if (argc < 2) { | |
310 | cmd_usage(cmdtp); | |
311 | return 1; | |
312 | } | |
313 | ||
314 | if ((strcmp(argv[1], "on") == 0)) { | |
315 | gpio_write_bit(CONFIG_SYS_GPIO_EEPROM_EXT_WP, 1); | |
316 | } else if ((strcmp(argv[1], "off") == 0)) { | |
317 | gpio_write_bit(CONFIG_SYS_GPIO_EEPROM_EXT_WP, 0); | |
318 | } else { | |
319 | cmd_usage(cmdtp); | |
320 | return 1; | |
321 | } | |
322 | ||
323 | ||
324 | return 0; | |
325 | } | |
326 | ||
327 | U_BOOT_CMD( | |
328 | eepromwp, 2, 0, do_eeprom_wp, | |
329 | "eeprom write protect off/on", | |
330 | "<on|off> - enable (on) or disable (off) I2C EEPROM write protect" | |
331 | ); | |
332 | ||
333 | #if defined(CONFIG_VIDEO) | |
334 | #include <video_fb.h> | |
335 | #include <mb862xx.h> | |
336 | ||
337 | extern GraphicDevice mb862xx; | |
338 | ||
339 | static const gdc_regs init_regs [] = | |
340 | { | |
341 | {0x0100, 0x00000f00}, | |
342 | {0x0020, 0x801401df}, | |
343 | {0x0024, 0x00000000}, | |
344 | {0x0028, 0x00000000}, | |
345 | {0x002c, 0x00000000}, | |
346 | {0x0110, 0x00000000}, | |
347 | {0x0114, 0x00000000}, | |
348 | {0x0118, 0x01df0280}, | |
349 | {0x0004, 0x031f0000}, | |
350 | {0x0008, 0x027f027f}, | |
351 | {0x000c, 0x015f028f}, | |
352 | {0x0010, 0x020c0000}, | |
353 | {0x0014, 0x01df01ea}, | |
354 | {0x0018, 0x00000000}, | |
355 | {0x001c, 0x01e00280}, | |
356 | {0x0100, 0x80010f00}, | |
357 | {0x0, 0x0} | |
358 | }; | |
359 | ||
360 | const gdc_regs *board_get_regs (void) | |
361 | { | |
362 | return init_regs; | |
363 | } | |
364 | ||
365 | /* Returns Lime base address */ | |
366 | unsigned int board_video_init (void) | |
367 | { | |
368 | /* | |
369 | * Reset Lime controller | |
370 | */ | |
371 | gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1); | |
372 | udelay(500); | |
373 | gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1); | |
374 | ||
375 | mb862xx.winSizeX = 640; | |
376 | mb862xx.winSizeY = 480; | |
377 | mb862xx.gdfBytesPP = 2; | |
378 | mb862xx.gdfIndex = GDF_15BIT_555RGB; | |
379 | ||
380 | return CONFIG_SYS_LIME_BASE_0; | |
381 | } | |
382 | ||
383 | #define DEFAULT_BRIGHTNESS 0x64 | |
384 | ||
385 | static void board_backlight_brightness(int brightness) | |
386 | { | |
387 | if (brightness > 0) { | |
388 | /* pwm duty, lamp on */ | |
389 | out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000024), brightness); | |
390 | out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000020), 0x701); | |
391 | } else { | |
392 | /* lamp off */ | |
393 | out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000024), 0x00); | |
394 | out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000020), 0x00); | |
395 | } | |
396 | } | |
397 | ||
398 | void board_backlight_switch (int flag) | |
399 | { | |
400 | char * param; | |
401 | int rc; | |
402 | ||
403 | if (flag) { | |
404 | param = getenv("brightness"); | |
405 | rc = param ? simple_strtol(param, NULL, 10) : -1; | |
406 | if (rc < 0) | |
407 | rc = DEFAULT_BRIGHTNESS; | |
408 | } else { | |
409 | rc = 0; | |
410 | } | |
411 | board_backlight_brightness(rc); | |
412 | } | |
413 | ||
414 | #if defined(CONFIG_CONSOLE_EXTRA_INFO) | |
415 | /* | |
416 | * Return text to be printed besides the logo. | |
417 | */ | |
418 | void video_get_info_str (int line_number, char *info) | |
419 | { | |
420 | if (line_number == 1) { | |
421 | strcpy (info, " Board: Lwmon5 (Liebherr Elektronik GmbH)"); | |
422 | } else { | |
423 | info [0] = '\0'; | |
424 | } | |
425 | } | |
426 | #endif | |
427 | #endif /* CONFIG_VIDEO */ | |
428 | ||
429 | void board_reset(void) | |
430 | { | |
431 | gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1); | |
432 | } |