]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
d8ccbe93 HS |
2 | /* |
3 | * board.c | |
4 | * | |
5 | * (C) Copyright 2016 | |
6 | * Heiko Schocher, DENX Software Engineering, [email protected]. | |
7 | * | |
8 | * Based on: | |
9 | * Board functions for TI AM335X based boards | |
10 | * | |
11 | * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ | |
d8ccbe93 HS |
12 | */ |
13 | ||
14 | #include <common.h> | |
52f24238 | 15 | #include <bootstage.h> |
9a3b4ceb | 16 | #include <cpu_func.h> |
9fb625ce | 17 | #include <env.h> |
d8ccbe93 | 18 | #include <errno.h> |
5255932f | 19 | #include <init.h> |
36bf446b | 20 | #include <irq_func.h> |
90526e9f | 21 | #include <net.h> |
d8ccbe93 HS |
22 | #include <spl.h> |
23 | #include <asm/arch/cpu.h> | |
24 | #include <asm/arch/hardware.h> | |
25 | #include <asm/arch/omap.h> | |
26 | #include <asm/arch/ddr_defs.h> | |
27 | #include <asm/arch/clock.h> | |
28 | #include <asm/arch/gpio.h> | |
29 | #include <asm/arch/mmc_host_def.h> | |
30 | #include <asm/arch/sys_proto.h> | |
31 | #include <asm/arch/mem.h> | |
401d1c4f | 32 | #include <asm/global_data.h> |
d8ccbe93 HS |
33 | #include <asm/io.h> |
34 | #include <asm/emif.h> | |
35 | #include <asm/gpio.h> | |
36 | #include <i2c.h> | |
37 | #include <miiphy.h> | |
38 | #include <cpsw.h> | |
c05ed00a | 39 | #include <linux/delay.h> |
d8ccbe93 | 40 | #include <power/tps65217.h> |
f3998fdc | 41 | #include <env_internal.h> |
d8ccbe93 | 42 | #include <watchdog.h> |
d8ccbe93 HS |
43 | #include "mmc.h" |
44 | #include "board.h" | |
45 | ||
46 | DECLARE_GLOBAL_DATA_PTR; | |
47 | ||
d8ccbe93 HS |
48 | static struct shc_eeprom __attribute__((section(".data"))) header; |
49 | static int shc_eeprom_valid; | |
50 | ||
51 | /* | |
52 | * Read header information from EEPROM into global structure. | |
53 | */ | |
54 | static int read_eeprom(void) | |
55 | { | |
56 | /* Check if baseboard eeprom is available */ | |
57 | if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) { | |
58 | puts("Could not probe the EEPROM; something fundamentally wrong on the I2C bus.\n"); | |
59 | return -ENODEV; | |
60 | } | |
61 | ||
62 | /* read the eeprom using i2c */ | |
63 | if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)&header, | |
64 | sizeof(header))) { | |
65 | puts("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\n"); | |
66 | return -EIO; | |
67 | } | |
68 | ||
69 | if (header.magic != HDR_MAGIC) { | |
70 | printf("Incorrect magic number (0x%x) in EEPROM\n", | |
71 | header.magic); | |
72 | return -EIO; | |
73 | } | |
74 | ||
75 | shc_eeprom_valid = 1; | |
76 | ||
77 | return 0; | |
78 | } | |
79 | ||
80 | static void shc_request_gpio(void) | |
81 | { | |
82 | gpio_request(LED_PWR_BL_GPIO, "LED PWR BL"); | |
83 | gpio_request(LED_PWR_RD_GPIO, "LED PWR RD"); | |
84 | gpio_request(RESET_GPIO, "reset"); | |
85 | gpio_request(WIFI_REGEN_GPIO, "WIFI REGEN"); | |
86 | gpio_request(WIFI_RST_GPIO, "WIFI rst"); | |
87 | gpio_request(ZIGBEE_RST_GPIO, "ZigBee rst"); | |
88 | gpio_request(BIDCOS_RST_GPIO, "BIDCOS rst"); | |
89 | gpio_request(ENOC_RST_GPIO, "ENOC rst"); | |
90 | #if defined CONFIG_B_SAMPLE | |
91 | gpio_request(LED_PWR_GN_GPIO, "LED PWR GN"); | |
92 | gpio_request(LED_CONN_BL_GPIO, "LED CONN BL"); | |
93 | gpio_request(LED_CONN_RD_GPIO, "LED CONN RD"); | |
94 | gpio_request(LED_CONN_GN_GPIO, "LED CONN GN"); | |
95 | #else | |
96 | gpio_request(LED_LAN_BL_GPIO, "LED LAN BL"); | |
97 | gpio_request(LED_LAN_RD_GPIO, "LED LAN RD"); | |
98 | gpio_request(LED_CLOUD_BL_GPIO, "LED CLOUD BL"); | |
99 | gpio_request(LED_CLOUD_RD_GPIO, "LED CLOUD RD"); | |
100 | gpio_request(LED_PWM_GPIO, "LED PWM"); | |
101 | gpio_request(Z_WAVE_RST_GPIO, "Z WAVE rst"); | |
102 | #endif | |
103 | gpio_request(BACK_BUTTON_GPIO, "Back button"); | |
104 | gpio_request(FRONT_BUTTON_GPIO, "Front button"); | |
105 | } | |
106 | ||
107 | /* | |
108 | * Function which forces all installed modules into running state for ICT | |
109 | * testing. Called by SPL. | |
110 | */ | |
111 | static void __maybe_unused force_modules_running(void) | |
112 | { | |
113 | /* Wi-Fi power regulator enable - high = enabled */ | |
114 | gpio_direction_output(WIFI_REGEN_GPIO, 1); | |
115 | /* | |
116 | * Wait for Wi-Fi power regulator to reach a stable voltage | |
117 | * (soft-start time, max. 350 µs) | |
118 | */ | |
119 | __udelay(350); | |
120 | ||
121 | /* Wi-Fi module reset - high = running */ | |
122 | gpio_direction_output(WIFI_RST_GPIO, 1); | |
123 | ||
124 | /* ZigBee reset - high = running */ | |
125 | gpio_direction_output(ZIGBEE_RST_GPIO, 1); | |
126 | ||
127 | /* BidCos reset - high = running */ | |
128 | gpio_direction_output(BIDCOS_RST_GPIO, 1); | |
129 | ||
130 | #if !defined(CONFIG_B_SAMPLE) | |
131 | /* Z-Wave reset - high = running */ | |
132 | gpio_direction_output(Z_WAVE_RST_GPIO, 1); | |
133 | #endif | |
134 | ||
135 | /* EnOcean reset - low = running */ | |
136 | gpio_direction_output(ENOC_RST_GPIO, 0); | |
137 | } | |
138 | ||
139 | /* | |
140 | * Function which forces all installed modules into reset - to be released by | |
141 | * the OS, called by SPL | |
142 | */ | |
143 | static void __maybe_unused force_modules_reset(void) | |
144 | { | |
145 | /* Wi-Fi module reset - low = reset */ | |
146 | gpio_direction_output(WIFI_RST_GPIO, 0); | |
147 | ||
148 | /* Wi-Fi power regulator enable - low = disabled */ | |
149 | gpio_direction_output(WIFI_REGEN_GPIO, 0); | |
150 | ||
151 | /* ZigBee reset - low = reset */ | |
152 | gpio_direction_output(ZIGBEE_RST_GPIO, 0); | |
153 | ||
154 | /* BidCos reset - low = reset */ | |
155 | /*gpio_direction_output(BIDCOS_RST_GPIO, 0);*/ | |
156 | ||
157 | #if !defined(CONFIG_B_SAMPLE) | |
158 | /* Z-Wave reset - low = reset */ | |
159 | gpio_direction_output(Z_WAVE_RST_GPIO, 0); | |
160 | #endif | |
161 | ||
162 | /* EnOcean reset - high = reset*/ | |
163 | gpio_direction_output(ENOC_RST_GPIO, 1); | |
164 | } | |
165 | ||
166 | /* | |
167 | * Function to set the LEDs in the state "Bootloader booting" | |
168 | */ | |
169 | static void __maybe_unused leds_set_booting(void) | |
170 | { | |
171 | #if defined(CONFIG_B_SAMPLE) | |
172 | ||
173 | /* Turn all red LEDs on */ | |
174 | gpio_direction_output(LED_PWR_RD_GPIO, 1); | |
175 | gpio_direction_output(LED_CONN_RD_GPIO, 1); | |
176 | ||
177 | #else /* All other SHCs starting with B2-Sample */ | |
178 | /* Set the PWM GPIO */ | |
179 | gpio_direction_output(LED_PWM_GPIO, 1); | |
180 | /* Turn all red LEDs on */ | |
181 | gpio_direction_output(LED_PWR_RD_GPIO, 1); | |
182 | gpio_direction_output(LED_LAN_RD_GPIO, 1); | |
183 | gpio_direction_output(LED_CLOUD_RD_GPIO, 1); | |
184 | ||
185 | #endif | |
186 | } | |
187 | ||
188 | /* | |
189 | * Function to set the LEDs in the state "Bootloader error" | |
190 | */ | |
191 | static void leds_set_failure(int state) | |
192 | { | |
193 | #if defined(CONFIG_B_SAMPLE) | |
194 | /* Turn all blue and green LEDs off */ | |
195 | gpio_set_value(LED_PWR_BL_GPIO, 0); | |
196 | gpio_set_value(LED_PWR_GN_GPIO, 0); | |
197 | gpio_set_value(LED_CONN_BL_GPIO, 0); | |
198 | gpio_set_value(LED_CONN_GN_GPIO, 0); | |
199 | ||
200 | /* Turn all red LEDs to 'state' */ | |
201 | gpio_set_value(LED_PWR_RD_GPIO, state); | |
202 | gpio_set_value(LED_CONN_RD_GPIO, state); | |
203 | ||
204 | #else /* All other SHCs starting with B2-Sample */ | |
205 | /* Set the PWM GPIO */ | |
206 | gpio_direction_output(LED_PWM_GPIO, 1); | |
207 | ||
208 | /* Turn all blue LEDs off */ | |
209 | gpio_set_value(LED_PWR_BL_GPIO, 0); | |
210 | gpio_set_value(LED_LAN_BL_GPIO, 0); | |
211 | gpio_set_value(LED_CLOUD_BL_GPIO, 0); | |
212 | ||
213 | /* Turn all red LEDs to 'state' */ | |
214 | gpio_set_value(LED_PWR_RD_GPIO, state); | |
215 | gpio_set_value(LED_LAN_RD_GPIO, state); | |
216 | gpio_set_value(LED_CLOUD_RD_GPIO, state); | |
217 | #endif | |
218 | } | |
219 | ||
220 | /* | |
221 | * Function to set the LEDs in the state "Bootloader finished" | |
222 | */ | |
223 | static void leds_set_finish(void) | |
224 | { | |
225 | #if defined(CONFIG_B_SAMPLE) | |
226 | /* Turn all LEDs off */ | |
227 | gpio_set_value(LED_PWR_BL_GPIO, 0); | |
228 | gpio_set_value(LED_PWR_RD_GPIO, 0); | |
229 | gpio_set_value(LED_PWR_GN_GPIO, 0); | |
230 | gpio_set_value(LED_CONN_BL_GPIO, 0); | |
231 | gpio_set_value(LED_CONN_RD_GPIO, 0); | |
232 | gpio_set_value(LED_CONN_GN_GPIO, 0); | |
233 | #else /* All other SHCs starting with B2-Sample */ | |
234 | /* Turn all LEDs off */ | |
235 | gpio_set_value(LED_PWR_BL_GPIO, 0); | |
236 | gpio_set_value(LED_PWR_RD_GPIO, 0); | |
237 | gpio_set_value(LED_LAN_BL_GPIO, 0); | |
238 | gpio_set_value(LED_LAN_RD_GPIO, 0); | |
239 | gpio_set_value(LED_CLOUD_BL_GPIO, 0); | |
240 | gpio_set_value(LED_CLOUD_RD_GPIO, 0); | |
241 | ||
242 | /* Turn off the PWM GPIO and mux it to EHRPWM */ | |
243 | gpio_set_value(LED_PWM_GPIO, 0); | |
244 | enable_shc_board_pwm_pin_mux(); | |
245 | #endif | |
246 | } | |
247 | ||
248 | static void check_button_status(void) | |
249 | { | |
250 | ulong value; | |
251 | gpio_direction_input(FRONT_BUTTON_GPIO); | |
252 | value = gpio_get_value(FRONT_BUTTON_GPIO); | |
253 | ||
254 | if (value == 0) { | |
255 | printf("front button activated !\n"); | |
382bee57 | 256 | env_set("harakiri", "1"); |
d8ccbe93 HS |
257 | } |
258 | } | |
259 | ||
a36c70a3 | 260 | #if defined(CONFIG_SPL_BUILD) |
d8ccbe93 HS |
261 | #ifdef CONFIG_SPL_OS_BOOT |
262 | int spl_start_uboot(void) | |
263 | { | |
264 | return 1; | |
265 | } | |
266 | #endif | |
267 | ||
268 | static void shc_board_early_init(void) | |
269 | { | |
270 | shc_request_gpio(); | |
271 | # ifdef CONFIG_SHC_ICT | |
272 | /* Force all modules into enabled state for ICT testing */ | |
273 | force_modules_running(); | |
274 | # else | |
275 | /* Force all modules to enter Reset state until released by the OS */ | |
276 | force_modules_reset(); | |
277 | # endif | |
278 | leds_set_booting(); | |
279 | } | |
280 | ||
a36c70a3 HS |
281 | static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; |
282 | ||
d8ccbe93 HS |
283 | #define MPU_SPREADING_PERMILLE 18 /* Spread 1.8 percent */ |
284 | #define OSC (V_OSCK/1000000) | |
285 | /* Bosch: Predivider must be fixed to 4, so N = 4-1 */ | |
286 | #define MPUPLL_N (4-1) | |
287 | /* Bosch: Fref = 24 MHz / (N+1) = 24 MHz / 4 = 6 MHz */ | |
288 | #define MPUPLL_FREF (OSC / (MPUPLL_N + 1)) | |
289 | ||
290 | const struct dpll_params dpll_ddr_shc = { | |
291 | 400, OSC-1, 1, -1, -1, -1, -1}; | |
292 | ||
293 | const struct dpll_params *get_dpll_ddr_params(void) | |
294 | { | |
295 | return &dpll_ddr_shc; | |
296 | } | |
297 | ||
298 | /* | |
299 | * As we enabled downspread SSC with 1.8%, the values needed to be corrected | |
300 | * such that the 20% overshoot will not lead to too high frequencies. | |
301 | * In all cases, this is achieved by subtracting one from M (6 MHz less). | |
302 | * Example: 600 MHz CPU | |
303 | * Step size: 24 MHz OSC, N = 4 (fix) --> Fref = 6 MHz | |
304 | * 600 MHz - 6 MHz (1x Fref) = 594 MHz | |
305 | * SSC: 594 MHz * 1.8% = 10.7 MHz SSC | |
306 | * Overshoot: 10.7 MHz * 20 % = 2.2 MHz | |
307 | * --> Fmax = 594 MHz + 2.2 MHz = 596.2 MHz, lower than 600 MHz --> OK! | |
308 | */ | |
309 | const struct dpll_params dpll_mpu_shc_opp100 = { | |
310 | 99, MPUPLL_N, 1, -1, -1, -1, -1}; | |
311 | ||
312 | void am33xx_spl_board_init(void) | |
313 | { | |
314 | int sil_rev; | |
315 | int mpu_vdd; | |
316 | ||
317 | puts(BOARD_ID_STR); | |
318 | ||
319 | /* | |
320 | * Set CORE Frequency to OPP100 | |
321 | * Hint: DCDC3 (CORE) defaults to 1.100V (for OPP100) | |
322 | */ | |
323 | do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); | |
324 | ||
325 | sil_rev = readl(&cdev->deviceid) >> 28; | |
326 | if (sil_rev < 2) { | |
327 | puts("We do not support Silicon Revisions below 2.0!\n"); | |
328 | return; | |
329 | } | |
330 | ||
331 | dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev); | |
332 | if (i2c_probe(TPS65217_CHIP_PM)) | |
333 | return; | |
334 | ||
335 | /* | |
336 | * Retrieve the CPU max frequency by reading the efuse | |
337 | * SHC-Default: 600 MHz | |
338 | */ | |
339 | switch (dpll_mpu_opp100.m) { | |
340 | case MPUPLL_M_1000: | |
341 | mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV; | |
342 | break; | |
343 | case MPUPLL_M_800: | |
344 | mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV; | |
345 | break; | |
346 | case MPUPLL_M_720: | |
347 | mpu_vdd = TPS65217_DCDC_VOLT_SEL_1200MV; | |
348 | break; | |
349 | case MPUPLL_M_600: | |
350 | mpu_vdd = TPS65217_DCDC_VOLT_SEL_1100MV; | |
351 | break; | |
352 | case MPUPLL_M_300: | |
353 | mpu_vdd = TPS65217_DCDC_VOLT_SEL_950MV; | |
354 | break; | |
355 | default: | |
356 | puts("Cannot determine the frequency, failing!\n"); | |
357 | return; | |
358 | } | |
359 | ||
360 | if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) { | |
361 | puts("tps65217_voltage_update failure\n"); | |
362 | return; | |
363 | } | |
364 | ||
365 | /* Set MPU Frequency to what we detected */ | |
366 | printf("MPU reference clock runs at %d MHz\n", MPUPLL_FREF); | |
367 | printf("Setting MPU clock to %d MHz\n", MPUPLL_FREF * | |
368 | dpll_mpu_shc_opp100.m); | |
369 | do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_shc_opp100); | |
370 | ||
371 | /* Enable Spread Spectrum for this freq to be clean on EMI side */ | |
372 | set_mpu_spreadspectrum(MPU_SPREADING_PERMILLE); | |
373 | ||
374 | /* | |
375 | * Using the default voltages for the PMIC (TPS65217D) | |
376 | * LS1 = 1.8V (VDD_1V8) | |
377 | * LS2 = 3.3V (VDD_3V3A) | |
378 | * LDO1 = 1.8V (VIO and VRTC) | |
379 | * LDO2 = 3.3V (VDD_3V3AUX) | |
380 | */ | |
381 | shc_board_early_init(); | |
382 | } | |
383 | ||
384 | void set_uart_mux_conf(void) | |
385 | { | |
386 | enable_uart0_pin_mux(); | |
387 | } | |
388 | ||
389 | void set_mux_conf_regs(void) | |
390 | { | |
391 | enable_shc_board_pin_mux(); | |
392 | } | |
393 | ||
394 | const struct ctrl_ioregs ioregs_evmsk = { | |
395 | .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
396 | .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
397 | .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
398 | .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
399 | .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
400 | }; | |
401 | ||
402 | static const struct ddr_data ddr3_shc_data = { | |
403 | .datardsratio0 = MT41K256M16HA125E_RD_DQS, | |
404 | .datawdsratio0 = MT41K256M16HA125E_WR_DQS, | |
405 | .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, | |
406 | .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, | |
407 | }; | |
408 | ||
409 | static const struct cmd_control ddr3_shc_cmd_ctrl_data = { | |
410 | .cmd0csratio = MT41K256M16HA125E_RATIO, | |
411 | .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, | |
412 | ||
413 | .cmd1csratio = MT41K256M16HA125E_RATIO, | |
414 | .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, | |
415 | ||
416 | .cmd2csratio = MT41K256M16HA125E_RATIO, | |
417 | .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, | |
418 | }; | |
419 | ||
420 | static struct emif_regs ddr3_shc_emif_reg_data = { | |
421 | .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, | |
422 | .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, | |
423 | .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1, | |
424 | .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2, | |
425 | .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3, | |
426 | .zq_config = MT41K256M16HA125E_ZQ_CFG, | |
427 | .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY | | |
428 | PHY_EN_DYN_PWRDN, | |
429 | }; | |
430 | ||
431 | void sdram_init(void) | |
432 | { | |
433 | /* Configure the DDR3 RAM */ | |
434 | config_ddr(400, &ioregs_evmsk, &ddr3_shc_data, | |
435 | &ddr3_shc_cmd_ctrl_data, &ddr3_shc_emif_reg_data, 0); | |
436 | } | |
437 | #endif | |
438 | ||
439 | /* | |
440 | * Basic board specific setup. Pinmux has been handled already. | |
441 | */ | |
442 | int board_init(void) | |
443 | { | |
444 | #if defined(CONFIG_HW_WATCHDOG) | |
445 | hw_watchdog_init(); | |
446 | #endif | |
447 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | |
448 | if (read_eeprom() < 0) | |
449 | puts("EEPROM Content Invalid.\n"); | |
450 | ||
451 | gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; | |
88718be3 | 452 | #if defined(CONFIG_NOR) || defined(CONFIG_MTD_RAW_NAND) |
d8ccbe93 HS |
453 | gpmc_init(); |
454 | #endif | |
455 | shc_request_gpio(); | |
456 | ||
457 | return 0; | |
458 | } | |
459 | ||
460 | #ifdef CONFIG_BOARD_LATE_INIT | |
461 | int board_late_init(void) | |
462 | { | |
463 | check_button_status(); | |
464 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG | |
465 | if (shc_eeprom_valid) | |
466 | if (is_valid_ethaddr(header.mac_addr)) | |
fd1e959e | 467 | eth_env_set_enetaddr("ethaddr", header.mac_addr); |
d8ccbe93 HS |
468 | #endif |
469 | ||
470 | return 0; | |
471 | } | |
472 | #endif | |
473 | ||
d8ccbe93 | 474 | #if defined(CONFIG_USB_ETHER) && \ |
b432b1eb | 475 | (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USB_ETHER)) |
b75d8dc5 | 476 | int board_eth_init(struct bd_info *bis) |
a36c70a3 HS |
477 | { |
478 | return usb_eth_initialize(bis); | |
d8ccbe93 HS |
479 | } |
480 | #endif | |
481 | ||
d8ccbe93 HS |
482 | #ifdef CONFIG_SHOW_BOOT_PROGRESS |
483 | static void bosch_check_reset_pin(void) | |
484 | { | |
485 | if (readl(GPIO1_BASE + OMAP_GPIO_IRQSTATUS_SET_0) & RESET_MASK) { | |
486 | printf("Resetting ...\n"); | |
487 | writel(RESET_MASK, GPIO1_BASE + OMAP_GPIO_IRQSTATUS_SET_0); | |
488 | disable_interrupts(); | |
489 | reset_cpu(0); | |
490 | /*NOTREACHED*/ | |
491 | } | |
492 | } | |
493 | ||
494 | static void hang_bosch(const char *cause, int code) | |
495 | { | |
496 | int lv; | |
497 | ||
498 | gpio_direction_input(RESET_GPIO); | |
499 | ||
500 | /* Enable reset pin interrupt on falling edge */ | |
501 | writel(RESET_MASK, GPIO1_BASE + OMAP_GPIO_IRQSTATUS_SET_0); | |
502 | writel(RESET_MASK, GPIO1_BASE + OMAP_GPIO_FALLINGDETECT); | |
503 | enable_interrupts(); | |
504 | ||
505 | puts(cause); | |
506 | for (;;) { | |
507 | for (lv = 0; lv < code; lv++) { | |
508 | bosch_check_reset_pin(); | |
509 | leds_set_failure(1); | |
510 | __udelay(150 * 1000); | |
511 | leds_set_failure(0); | |
512 | __udelay(150 * 1000); | |
513 | } | |
514 | #if defined(BLINK_CODE) | |
515 | __udelay(300 * 1000); | |
516 | #endif | |
517 | } | |
518 | } | |
519 | ||
520 | void show_boot_progress(int val) | |
521 | { | |
522 | switch (val) { | |
523 | case BOOTSTAGE_ID_NEED_RESET: | |
524 | hang_bosch("need reset", 4); | |
525 | break; | |
526 | } | |
527 | } | |
d8ccbe93 HS |
528 | |
529 | void arch_preboot_os(void) | |
530 | { | |
531 | leds_set_finish(); | |
532 | } | |
d8ccbe93 | 533 | #endif |