xref: /openbmc/u-boot/board/bosch/shc/board.c (revision fd1e959e)
1d8ccbe93SHeiko Schocher /*
2d8ccbe93SHeiko Schocher  * board.c
3d8ccbe93SHeiko Schocher  *
4d8ccbe93SHeiko Schocher  * (C) Copyright 2016
5d8ccbe93SHeiko Schocher  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
6d8ccbe93SHeiko Schocher  *
7d8ccbe93SHeiko Schocher  * Based on:
8d8ccbe93SHeiko Schocher  * Board functions for TI AM335X based boards
9d8ccbe93SHeiko Schocher  *
10d8ccbe93SHeiko Schocher  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
11d8ccbe93SHeiko Schocher  *
12d8ccbe93SHeiko Schocher  * SPDX-License-Identifier:	GPL-2.0+
13d8ccbe93SHeiko Schocher  */
14d8ccbe93SHeiko Schocher 
15d8ccbe93SHeiko Schocher #include <common.h>
16d8ccbe93SHeiko Schocher #include <errno.h>
17d8ccbe93SHeiko Schocher #include <spl.h>
18d8ccbe93SHeiko Schocher #include <asm/arch/cpu.h>
19d8ccbe93SHeiko Schocher #include <asm/arch/hardware.h>
20d8ccbe93SHeiko Schocher #include <asm/arch/omap.h>
21d8ccbe93SHeiko Schocher #include <asm/arch/ddr_defs.h>
22d8ccbe93SHeiko Schocher #include <asm/arch/clock.h>
23d8ccbe93SHeiko Schocher #include <asm/arch/gpio.h>
24d8ccbe93SHeiko Schocher #include <asm/arch/mmc_host_def.h>
25d8ccbe93SHeiko Schocher #include <asm/arch/sys_proto.h>
26d8ccbe93SHeiko Schocher #include <asm/arch/mem.h>
27d8ccbe93SHeiko Schocher #include <asm/io.h>
28d8ccbe93SHeiko Schocher #include <asm/emif.h>
29d8ccbe93SHeiko Schocher #include <asm/gpio.h>
30d8ccbe93SHeiko Schocher #include <i2c.h>
31d8ccbe93SHeiko Schocher #include <miiphy.h>
32d8ccbe93SHeiko Schocher #include <cpsw.h>
33d8ccbe93SHeiko Schocher #include <power/tps65217.h>
34d8ccbe93SHeiko Schocher #include <environment.h>
35d8ccbe93SHeiko Schocher #include <watchdog.h>
36d8ccbe93SHeiko Schocher #include <environment.h>
37d8ccbe93SHeiko Schocher #include "mmc.h"
38d8ccbe93SHeiko Schocher #include "board.h"
39d8ccbe93SHeiko Schocher 
40d8ccbe93SHeiko Schocher DECLARE_GLOBAL_DATA_PTR;
41d8ccbe93SHeiko Schocher 
42d8ccbe93SHeiko Schocher #if defined(CONFIG_SPL_BUILD) || \
43d8ccbe93SHeiko Schocher 	(defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_DM_ETH))
44d8ccbe93SHeiko Schocher static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
45d8ccbe93SHeiko Schocher #endif
46d8ccbe93SHeiko Schocher static struct shc_eeprom __attribute__((section(".data"))) header;
47d8ccbe93SHeiko Schocher static int shc_eeprom_valid;
48d8ccbe93SHeiko Schocher 
49d8ccbe93SHeiko Schocher /*
50d8ccbe93SHeiko Schocher  * Read header information from EEPROM into global structure.
51d8ccbe93SHeiko Schocher  */
52d8ccbe93SHeiko Schocher static int read_eeprom(void)
53d8ccbe93SHeiko Schocher {
54d8ccbe93SHeiko Schocher 	/* Check if baseboard eeprom is available */
55d8ccbe93SHeiko Schocher 	if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
56d8ccbe93SHeiko Schocher 		puts("Could not probe the EEPROM; something fundamentally wrong on the I2C bus.\n");
57d8ccbe93SHeiko Schocher 		return -ENODEV;
58d8ccbe93SHeiko Schocher 	}
59d8ccbe93SHeiko Schocher 
60d8ccbe93SHeiko Schocher 	/* read the eeprom using i2c */
61d8ccbe93SHeiko Schocher 	if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)&header,
62d8ccbe93SHeiko Schocher 		     sizeof(header))) {
63d8ccbe93SHeiko Schocher 		puts("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\n");
64d8ccbe93SHeiko Schocher 		return -EIO;
65d8ccbe93SHeiko Schocher 	}
66d8ccbe93SHeiko Schocher 
67d8ccbe93SHeiko Schocher 	if (header.magic != HDR_MAGIC) {
68d8ccbe93SHeiko Schocher 		printf("Incorrect magic number (0x%x) in EEPROM\n",
69d8ccbe93SHeiko Schocher 		       header.magic);
70d8ccbe93SHeiko Schocher 		return -EIO;
71d8ccbe93SHeiko Schocher 	}
72d8ccbe93SHeiko Schocher 
73d8ccbe93SHeiko Schocher 	shc_eeprom_valid = 1;
74d8ccbe93SHeiko Schocher 
75d8ccbe93SHeiko Schocher 	return 0;
76d8ccbe93SHeiko Schocher }
77d8ccbe93SHeiko Schocher 
78d8ccbe93SHeiko Schocher static void shc_request_gpio(void)
79d8ccbe93SHeiko Schocher {
80d8ccbe93SHeiko Schocher 	gpio_request(LED_PWR_BL_GPIO, "LED PWR BL");
81d8ccbe93SHeiko Schocher 	gpio_request(LED_PWR_RD_GPIO, "LED PWR RD");
82d8ccbe93SHeiko Schocher 	gpio_request(RESET_GPIO, "reset");
83d8ccbe93SHeiko Schocher 	gpio_request(WIFI_REGEN_GPIO, "WIFI REGEN");
84d8ccbe93SHeiko Schocher 	gpio_request(WIFI_RST_GPIO, "WIFI rst");
85d8ccbe93SHeiko Schocher 	gpio_request(ZIGBEE_RST_GPIO, "ZigBee rst");
86d8ccbe93SHeiko Schocher 	gpio_request(BIDCOS_RST_GPIO, "BIDCOS rst");
87d8ccbe93SHeiko Schocher 	gpio_request(ENOC_RST_GPIO, "ENOC rst");
88d8ccbe93SHeiko Schocher #if defined CONFIG_B_SAMPLE
89d8ccbe93SHeiko Schocher 	gpio_request(LED_PWR_GN_GPIO, "LED PWR GN");
90d8ccbe93SHeiko Schocher 	gpio_request(LED_CONN_BL_GPIO, "LED CONN BL");
91d8ccbe93SHeiko Schocher 	gpio_request(LED_CONN_RD_GPIO, "LED CONN RD");
92d8ccbe93SHeiko Schocher 	gpio_request(LED_CONN_GN_GPIO, "LED CONN GN");
93d8ccbe93SHeiko Schocher #else
94d8ccbe93SHeiko Schocher 	gpio_request(LED_LAN_BL_GPIO, "LED LAN BL");
95d8ccbe93SHeiko Schocher 	gpio_request(LED_LAN_RD_GPIO, "LED LAN RD");
96d8ccbe93SHeiko Schocher 	gpio_request(LED_CLOUD_BL_GPIO, "LED CLOUD BL");
97d8ccbe93SHeiko Schocher 	gpio_request(LED_CLOUD_RD_GPIO, "LED CLOUD RD");
98d8ccbe93SHeiko Schocher 	gpio_request(LED_PWM_GPIO, "LED PWM");
99d8ccbe93SHeiko Schocher 	gpio_request(Z_WAVE_RST_GPIO, "Z WAVE rst");
100d8ccbe93SHeiko Schocher #endif
101d8ccbe93SHeiko Schocher 	gpio_request(BACK_BUTTON_GPIO, "Back button");
102d8ccbe93SHeiko Schocher 	gpio_request(FRONT_BUTTON_GPIO, "Front button");
103d8ccbe93SHeiko Schocher }
104d8ccbe93SHeiko Schocher 
105d8ccbe93SHeiko Schocher /*
106d8ccbe93SHeiko Schocher  * Function which forces all installed modules into running state for ICT
107d8ccbe93SHeiko Schocher  * testing. Called by SPL.
108d8ccbe93SHeiko Schocher  */
109d8ccbe93SHeiko Schocher static void __maybe_unused force_modules_running(void)
110d8ccbe93SHeiko Schocher {
111d8ccbe93SHeiko Schocher 	/* Wi-Fi power regulator enable - high = enabled */
112d8ccbe93SHeiko Schocher 	gpio_direction_output(WIFI_REGEN_GPIO, 1);
113d8ccbe93SHeiko Schocher 	/*
114d8ccbe93SHeiko Schocher 	 * Wait for Wi-Fi power regulator to reach a stable voltage
115d8ccbe93SHeiko Schocher 	 * (soft-start time, max. 350 µs)
116d8ccbe93SHeiko Schocher 	 */
117d8ccbe93SHeiko Schocher 	__udelay(350);
118d8ccbe93SHeiko Schocher 
119d8ccbe93SHeiko Schocher 	/* Wi-Fi module reset - high = running */
120d8ccbe93SHeiko Schocher 	gpio_direction_output(WIFI_RST_GPIO, 1);
121d8ccbe93SHeiko Schocher 
122d8ccbe93SHeiko Schocher 	/* ZigBee reset - high = running */
123d8ccbe93SHeiko Schocher 	gpio_direction_output(ZIGBEE_RST_GPIO, 1);
124d8ccbe93SHeiko Schocher 
125d8ccbe93SHeiko Schocher 	/* BidCos reset - high = running */
126d8ccbe93SHeiko Schocher 	gpio_direction_output(BIDCOS_RST_GPIO, 1);
127d8ccbe93SHeiko Schocher 
128d8ccbe93SHeiko Schocher #if !defined(CONFIG_B_SAMPLE)
129d8ccbe93SHeiko Schocher 	/* Z-Wave reset - high = running */
130d8ccbe93SHeiko Schocher 	gpio_direction_output(Z_WAVE_RST_GPIO, 1);
131d8ccbe93SHeiko Schocher #endif
132d8ccbe93SHeiko Schocher 
133d8ccbe93SHeiko Schocher 	/* EnOcean reset - low = running */
134d8ccbe93SHeiko Schocher 	gpio_direction_output(ENOC_RST_GPIO, 0);
135d8ccbe93SHeiko Schocher }
136d8ccbe93SHeiko Schocher 
137d8ccbe93SHeiko Schocher /*
138d8ccbe93SHeiko Schocher  * Function which forces all installed modules into reset - to be released by
139d8ccbe93SHeiko Schocher  * the OS, called by SPL
140d8ccbe93SHeiko Schocher  */
141d8ccbe93SHeiko Schocher static void __maybe_unused force_modules_reset(void)
142d8ccbe93SHeiko Schocher {
143d8ccbe93SHeiko Schocher 	/* Wi-Fi module reset - low = reset */
144d8ccbe93SHeiko Schocher 	gpio_direction_output(WIFI_RST_GPIO, 0);
145d8ccbe93SHeiko Schocher 
146d8ccbe93SHeiko Schocher 	/* Wi-Fi power regulator enable - low = disabled */
147d8ccbe93SHeiko Schocher 	gpio_direction_output(WIFI_REGEN_GPIO, 0);
148d8ccbe93SHeiko Schocher 
149d8ccbe93SHeiko Schocher 	/* ZigBee reset - low = reset */
150d8ccbe93SHeiko Schocher 	gpio_direction_output(ZIGBEE_RST_GPIO, 0);
151d8ccbe93SHeiko Schocher 
152d8ccbe93SHeiko Schocher 	/* BidCos reset - low = reset */
153d8ccbe93SHeiko Schocher 	/*gpio_direction_output(BIDCOS_RST_GPIO, 0);*/
154d8ccbe93SHeiko Schocher 
155d8ccbe93SHeiko Schocher #if !defined(CONFIG_B_SAMPLE)
156d8ccbe93SHeiko Schocher 	/* Z-Wave reset - low = reset */
157d8ccbe93SHeiko Schocher 	gpio_direction_output(Z_WAVE_RST_GPIO, 0);
158d8ccbe93SHeiko Schocher #endif
159d8ccbe93SHeiko Schocher 
160d8ccbe93SHeiko Schocher 	/* EnOcean reset - high = reset*/
161d8ccbe93SHeiko Schocher 	gpio_direction_output(ENOC_RST_GPIO, 1);
162d8ccbe93SHeiko Schocher }
163d8ccbe93SHeiko Schocher 
164d8ccbe93SHeiko Schocher /*
165d8ccbe93SHeiko Schocher  * Function to set the LEDs in the state "Bootloader booting"
166d8ccbe93SHeiko Schocher  */
167d8ccbe93SHeiko Schocher static void __maybe_unused leds_set_booting(void)
168d8ccbe93SHeiko Schocher {
169d8ccbe93SHeiko Schocher #if defined(CONFIG_B_SAMPLE)
170d8ccbe93SHeiko Schocher 
171d8ccbe93SHeiko Schocher 	/* Turn all red LEDs on */
172d8ccbe93SHeiko Schocher 	gpio_direction_output(LED_PWR_RD_GPIO, 1);
173d8ccbe93SHeiko Schocher 	gpio_direction_output(LED_CONN_RD_GPIO, 1);
174d8ccbe93SHeiko Schocher 
175d8ccbe93SHeiko Schocher #else /* All other SHCs starting with B2-Sample */
176d8ccbe93SHeiko Schocher 	/* Set the PWM GPIO */
177d8ccbe93SHeiko Schocher 	gpio_direction_output(LED_PWM_GPIO, 1);
178d8ccbe93SHeiko Schocher 	/* Turn all red LEDs on */
179d8ccbe93SHeiko Schocher 	gpio_direction_output(LED_PWR_RD_GPIO, 1);
180d8ccbe93SHeiko Schocher 	gpio_direction_output(LED_LAN_RD_GPIO, 1);
181d8ccbe93SHeiko Schocher 	gpio_direction_output(LED_CLOUD_RD_GPIO, 1);
182d8ccbe93SHeiko Schocher 
183d8ccbe93SHeiko Schocher #endif
184d8ccbe93SHeiko Schocher }
185d8ccbe93SHeiko Schocher 
186d8ccbe93SHeiko Schocher /*
187d8ccbe93SHeiko Schocher  * Function to set the LEDs in the state "Bootloader error"
188d8ccbe93SHeiko Schocher  */
189d8ccbe93SHeiko Schocher static void leds_set_failure(int state)
190d8ccbe93SHeiko Schocher {
191d8ccbe93SHeiko Schocher #if defined(CONFIG_B_SAMPLE)
192d8ccbe93SHeiko Schocher 	/* Turn all blue and green LEDs off */
193d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_BL_GPIO, 0);
194d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_GN_GPIO, 0);
195d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CONN_BL_GPIO, 0);
196d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CONN_GN_GPIO, 0);
197d8ccbe93SHeiko Schocher 
198d8ccbe93SHeiko Schocher 	/* Turn all red LEDs to 'state' */
199d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_RD_GPIO, state);
200d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CONN_RD_GPIO, state);
201d8ccbe93SHeiko Schocher 
202d8ccbe93SHeiko Schocher #else /* All other SHCs starting with B2-Sample */
203d8ccbe93SHeiko Schocher 	/* Set the PWM GPIO */
204d8ccbe93SHeiko Schocher 	gpio_direction_output(LED_PWM_GPIO, 1);
205d8ccbe93SHeiko Schocher 
206d8ccbe93SHeiko Schocher 	/* Turn all blue LEDs off */
207d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_BL_GPIO, 0);
208d8ccbe93SHeiko Schocher 	gpio_set_value(LED_LAN_BL_GPIO, 0);
209d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CLOUD_BL_GPIO, 0);
210d8ccbe93SHeiko Schocher 
211d8ccbe93SHeiko Schocher 	/* Turn all red LEDs to 'state' */
212d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_RD_GPIO, state);
213d8ccbe93SHeiko Schocher 	gpio_set_value(LED_LAN_RD_GPIO, state);
214d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CLOUD_RD_GPIO, state);
215d8ccbe93SHeiko Schocher #endif
216d8ccbe93SHeiko Schocher }
217d8ccbe93SHeiko Schocher 
218d8ccbe93SHeiko Schocher /*
219d8ccbe93SHeiko Schocher  * Function to set the LEDs in the state "Bootloader finished"
220d8ccbe93SHeiko Schocher  */
221d8ccbe93SHeiko Schocher static void leds_set_finish(void)
222d8ccbe93SHeiko Schocher {
223d8ccbe93SHeiko Schocher #if defined(CONFIG_B_SAMPLE)
224d8ccbe93SHeiko Schocher 	/* Turn all LEDs off */
225d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_BL_GPIO, 0);
226d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_RD_GPIO, 0);
227d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_GN_GPIO, 0);
228d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CONN_BL_GPIO, 0);
229d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CONN_RD_GPIO, 0);
230d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CONN_GN_GPIO, 0);
231d8ccbe93SHeiko Schocher #else /* All other SHCs starting with B2-Sample */
232d8ccbe93SHeiko Schocher 	/* Turn all LEDs off */
233d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_BL_GPIO, 0);
234d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWR_RD_GPIO, 0);
235d8ccbe93SHeiko Schocher 	gpio_set_value(LED_LAN_BL_GPIO, 0);
236d8ccbe93SHeiko Schocher 	gpio_set_value(LED_LAN_RD_GPIO, 0);
237d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CLOUD_BL_GPIO, 0);
238d8ccbe93SHeiko Schocher 	gpio_set_value(LED_CLOUD_RD_GPIO, 0);
239d8ccbe93SHeiko Schocher 
240d8ccbe93SHeiko Schocher 	/* Turn off the PWM GPIO and mux it to EHRPWM */
241d8ccbe93SHeiko Schocher 	gpio_set_value(LED_PWM_GPIO, 0);
242d8ccbe93SHeiko Schocher 	enable_shc_board_pwm_pin_mux();
243d8ccbe93SHeiko Schocher #endif
244d8ccbe93SHeiko Schocher }
245d8ccbe93SHeiko Schocher 
246d8ccbe93SHeiko Schocher static void check_button_status(void)
247d8ccbe93SHeiko Schocher {
248d8ccbe93SHeiko Schocher 	ulong value;
249d8ccbe93SHeiko Schocher 	gpio_direction_input(FRONT_BUTTON_GPIO);
250d8ccbe93SHeiko Schocher 	value = gpio_get_value(FRONT_BUTTON_GPIO);
251d8ccbe93SHeiko Schocher 
252d8ccbe93SHeiko Schocher 	if (value == 0) {
253d8ccbe93SHeiko Schocher 		printf("front button activated !\n");
254382bee57SSimon Glass 		env_set("harakiri", "1");
255d8ccbe93SHeiko Schocher 	}
256d8ccbe93SHeiko Schocher }
257d8ccbe93SHeiko Schocher 
258d8ccbe93SHeiko Schocher #ifndef CONFIG_SKIP_LOWLEVEL_INIT
259d8ccbe93SHeiko Schocher #ifdef CONFIG_SPL_OS_BOOT
260d8ccbe93SHeiko Schocher int spl_start_uboot(void)
261d8ccbe93SHeiko Schocher {
262d8ccbe93SHeiko Schocher 	return 1;
263d8ccbe93SHeiko Schocher }
264d8ccbe93SHeiko Schocher #endif
265d8ccbe93SHeiko Schocher 
266d8ccbe93SHeiko Schocher static void shc_board_early_init(void)
267d8ccbe93SHeiko Schocher {
268d8ccbe93SHeiko Schocher 	shc_request_gpio();
269d8ccbe93SHeiko Schocher # ifdef CONFIG_SHC_ICT
270d8ccbe93SHeiko Schocher 	/* Force all modules into enabled state for ICT testing */
271d8ccbe93SHeiko Schocher 	force_modules_running();
272d8ccbe93SHeiko Schocher # else
273d8ccbe93SHeiko Schocher 	/* Force all modules to enter Reset state until released by the OS */
274d8ccbe93SHeiko Schocher 	force_modules_reset();
275d8ccbe93SHeiko Schocher # endif
276d8ccbe93SHeiko Schocher 	leds_set_booting();
277d8ccbe93SHeiko Schocher }
278d8ccbe93SHeiko Schocher 
279d8ccbe93SHeiko Schocher #define MPU_SPREADING_PERMILLE 18 /* Spread 1.8 percent */
280d8ccbe93SHeiko Schocher #define OSC	(V_OSCK/1000000)
281d8ccbe93SHeiko Schocher /* Bosch: Predivider must be fixed to 4, so N = 4-1 */
282d8ccbe93SHeiko Schocher #define MPUPLL_N        (4-1)
283d8ccbe93SHeiko Schocher /* Bosch: Fref = 24 MHz / (N+1) = 24 MHz / 4 = 6 MHz */
284d8ccbe93SHeiko Schocher #define MPUPLL_FREF (OSC / (MPUPLL_N + 1))
285d8ccbe93SHeiko Schocher 
286d8ccbe93SHeiko Schocher const struct dpll_params dpll_ddr_shc = {
287d8ccbe93SHeiko Schocher 		400, OSC-1, 1, -1, -1, -1, -1};
288d8ccbe93SHeiko Schocher 
289d8ccbe93SHeiko Schocher const struct dpll_params *get_dpll_ddr_params(void)
290d8ccbe93SHeiko Schocher {
291d8ccbe93SHeiko Schocher 	return &dpll_ddr_shc;
292d8ccbe93SHeiko Schocher }
293d8ccbe93SHeiko Schocher 
294d8ccbe93SHeiko Schocher /*
295d8ccbe93SHeiko Schocher  * As we enabled downspread SSC with 1.8%, the values needed to be corrected
296d8ccbe93SHeiko Schocher  * such that the 20% overshoot will not lead to too high frequencies.
297d8ccbe93SHeiko Schocher  * In all cases, this is achieved by subtracting one from M (6 MHz less).
298d8ccbe93SHeiko Schocher  * Example: 600 MHz CPU
299d8ccbe93SHeiko Schocher  *   Step size: 24 MHz OSC, N = 4 (fix) --> Fref = 6 MHz
300d8ccbe93SHeiko Schocher  *   600 MHz - 6 MHz (1x Fref) = 594 MHz
301d8ccbe93SHeiko Schocher  *   SSC: 594 MHz * 1.8% = 10.7 MHz SSC
302d8ccbe93SHeiko Schocher  *   Overshoot: 10.7 MHz * 20 % = 2.2 MHz
303d8ccbe93SHeiko Schocher  *   --> Fmax = 594 MHz + 2.2 MHz = 596.2 MHz, lower than 600 MHz --> OK!
304d8ccbe93SHeiko Schocher  */
305d8ccbe93SHeiko Schocher const struct dpll_params dpll_mpu_shc_opp100 = {
306d8ccbe93SHeiko Schocher 		99, MPUPLL_N, 1, -1, -1, -1, -1};
307d8ccbe93SHeiko Schocher 
308d8ccbe93SHeiko Schocher void am33xx_spl_board_init(void)
309d8ccbe93SHeiko Schocher {
310d8ccbe93SHeiko Schocher 	int sil_rev;
311d8ccbe93SHeiko Schocher 	int mpu_vdd;
312d8ccbe93SHeiko Schocher 
313d8ccbe93SHeiko Schocher 	puts(BOARD_ID_STR);
314d8ccbe93SHeiko Schocher 
315d8ccbe93SHeiko Schocher 	/*
316d8ccbe93SHeiko Schocher 	 * Set CORE Frequency to OPP100
317d8ccbe93SHeiko Schocher 	 * Hint: DCDC3 (CORE) defaults to 1.100V (for OPP100)
318d8ccbe93SHeiko Schocher 	 */
319d8ccbe93SHeiko Schocher 	do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
320d8ccbe93SHeiko Schocher 
321d8ccbe93SHeiko Schocher 	sil_rev = readl(&cdev->deviceid) >> 28;
322d8ccbe93SHeiko Schocher 	if (sil_rev < 2) {
323d8ccbe93SHeiko Schocher 		puts("We do not support Silicon Revisions below 2.0!\n");
324d8ccbe93SHeiko Schocher 		return;
325d8ccbe93SHeiko Schocher 	}
326d8ccbe93SHeiko Schocher 
327d8ccbe93SHeiko Schocher 	dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);
328d8ccbe93SHeiko Schocher 	if (i2c_probe(TPS65217_CHIP_PM))
329d8ccbe93SHeiko Schocher 		return;
330d8ccbe93SHeiko Schocher 
331d8ccbe93SHeiko Schocher 	/*
332d8ccbe93SHeiko Schocher 	 * Retrieve the CPU max frequency by reading the efuse
333d8ccbe93SHeiko Schocher 	 * SHC-Default: 600 MHz
334d8ccbe93SHeiko Schocher 	 */
335d8ccbe93SHeiko Schocher 	switch (dpll_mpu_opp100.m) {
336d8ccbe93SHeiko Schocher 	case MPUPLL_M_1000:
337d8ccbe93SHeiko Schocher 		mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV;
338d8ccbe93SHeiko Schocher 		break;
339d8ccbe93SHeiko Schocher 	case MPUPLL_M_800:
340d8ccbe93SHeiko Schocher 		mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV;
341d8ccbe93SHeiko Schocher 		break;
342d8ccbe93SHeiko Schocher 	case MPUPLL_M_720:
343d8ccbe93SHeiko Schocher 		mpu_vdd = TPS65217_DCDC_VOLT_SEL_1200MV;
344d8ccbe93SHeiko Schocher 		break;
345d8ccbe93SHeiko Schocher 	case MPUPLL_M_600:
346d8ccbe93SHeiko Schocher 		mpu_vdd = TPS65217_DCDC_VOLT_SEL_1100MV;
347d8ccbe93SHeiko Schocher 		break;
348d8ccbe93SHeiko Schocher 	case MPUPLL_M_300:
349d8ccbe93SHeiko Schocher 		mpu_vdd = TPS65217_DCDC_VOLT_SEL_950MV;
350d8ccbe93SHeiko Schocher 		break;
351d8ccbe93SHeiko Schocher 	default:
352d8ccbe93SHeiko Schocher 		puts("Cannot determine the frequency, failing!\n");
353d8ccbe93SHeiko Schocher 		return;
354d8ccbe93SHeiko Schocher 	}
355d8ccbe93SHeiko Schocher 
356d8ccbe93SHeiko Schocher 	if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) {
357d8ccbe93SHeiko Schocher 		puts("tps65217_voltage_update failure\n");
358d8ccbe93SHeiko Schocher 		return;
359d8ccbe93SHeiko Schocher 	}
360d8ccbe93SHeiko Schocher 
361d8ccbe93SHeiko Schocher 	/* Set MPU Frequency to what we detected */
362d8ccbe93SHeiko Schocher 	printf("MPU reference clock runs at %d MHz\n", MPUPLL_FREF);
363d8ccbe93SHeiko Schocher 	printf("Setting MPU clock to %d MHz\n", MPUPLL_FREF *
364d8ccbe93SHeiko Schocher 	       dpll_mpu_shc_opp100.m);
365d8ccbe93SHeiko Schocher 	do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_shc_opp100);
366d8ccbe93SHeiko Schocher 
367d8ccbe93SHeiko Schocher 	/* Enable Spread Spectrum for this freq to be clean on EMI side */
368d8ccbe93SHeiko Schocher 	set_mpu_spreadspectrum(MPU_SPREADING_PERMILLE);
369d8ccbe93SHeiko Schocher 
370d8ccbe93SHeiko Schocher 	/*
371d8ccbe93SHeiko Schocher 	 * Using the default voltages for the PMIC (TPS65217D)
372d8ccbe93SHeiko Schocher 	 * LS1 = 1.8V (VDD_1V8)
373d8ccbe93SHeiko Schocher 	 * LS2 = 3.3V (VDD_3V3A)
374d8ccbe93SHeiko Schocher 	 * LDO1 = 1.8V (VIO and VRTC)
375d8ccbe93SHeiko Schocher 	 * LDO2 = 3.3V (VDD_3V3AUX)
376d8ccbe93SHeiko Schocher 	 */
377d8ccbe93SHeiko Schocher 	shc_board_early_init();
378d8ccbe93SHeiko Schocher }
379d8ccbe93SHeiko Schocher 
380d8ccbe93SHeiko Schocher void set_uart_mux_conf(void)
381d8ccbe93SHeiko Schocher {
382d8ccbe93SHeiko Schocher 	enable_uart0_pin_mux();
383d8ccbe93SHeiko Schocher }
384d8ccbe93SHeiko Schocher 
385d8ccbe93SHeiko Schocher void set_mux_conf_regs(void)
386d8ccbe93SHeiko Schocher {
387d8ccbe93SHeiko Schocher 	enable_shc_board_pin_mux();
388d8ccbe93SHeiko Schocher }
389d8ccbe93SHeiko Schocher 
390d8ccbe93SHeiko Schocher const struct ctrl_ioregs ioregs_evmsk = {
391d8ccbe93SHeiko Schocher 	.cm0ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
392d8ccbe93SHeiko Schocher 	.cm1ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
393d8ccbe93SHeiko Schocher 	.cm2ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
394d8ccbe93SHeiko Schocher 	.dt0ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
395d8ccbe93SHeiko Schocher 	.dt1ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
396d8ccbe93SHeiko Schocher };
397d8ccbe93SHeiko Schocher 
398d8ccbe93SHeiko Schocher static const struct ddr_data ddr3_shc_data = {
399d8ccbe93SHeiko Schocher 	.datardsratio0 = MT41K256M16HA125E_RD_DQS,
400d8ccbe93SHeiko Schocher 	.datawdsratio0 = MT41K256M16HA125E_WR_DQS,
401d8ccbe93SHeiko Schocher 	.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
402d8ccbe93SHeiko Schocher 	.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
403d8ccbe93SHeiko Schocher };
404d8ccbe93SHeiko Schocher 
405d8ccbe93SHeiko Schocher static const struct cmd_control ddr3_shc_cmd_ctrl_data = {
406d8ccbe93SHeiko Schocher 	.cmd0csratio = MT41K256M16HA125E_RATIO,
407d8ccbe93SHeiko Schocher 	.cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
408d8ccbe93SHeiko Schocher 
409d8ccbe93SHeiko Schocher 	.cmd1csratio = MT41K256M16HA125E_RATIO,
410d8ccbe93SHeiko Schocher 	.cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
411d8ccbe93SHeiko Schocher 
412d8ccbe93SHeiko Schocher 	.cmd2csratio = MT41K256M16HA125E_RATIO,
413d8ccbe93SHeiko Schocher 	.cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
414d8ccbe93SHeiko Schocher };
415d8ccbe93SHeiko Schocher 
416d8ccbe93SHeiko Schocher static struct emif_regs ddr3_shc_emif_reg_data = {
417d8ccbe93SHeiko Schocher 	.sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
418d8ccbe93SHeiko Schocher 	.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
419d8ccbe93SHeiko Schocher 	.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
420d8ccbe93SHeiko Schocher 	.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
421d8ccbe93SHeiko Schocher 	.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
422d8ccbe93SHeiko Schocher 	.zq_config = MT41K256M16HA125E_ZQ_CFG,
423d8ccbe93SHeiko Schocher 	.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY |
424d8ccbe93SHeiko Schocher 				PHY_EN_DYN_PWRDN,
425d8ccbe93SHeiko Schocher };
426d8ccbe93SHeiko Schocher 
427d8ccbe93SHeiko Schocher void sdram_init(void)
428d8ccbe93SHeiko Schocher {
429d8ccbe93SHeiko Schocher 	/* Configure the DDR3 RAM */
430d8ccbe93SHeiko Schocher 	config_ddr(400, &ioregs_evmsk, &ddr3_shc_data,
431d8ccbe93SHeiko Schocher 		   &ddr3_shc_cmd_ctrl_data, &ddr3_shc_emif_reg_data, 0);
432d8ccbe93SHeiko Schocher }
433d8ccbe93SHeiko Schocher #endif
434d8ccbe93SHeiko Schocher 
435d8ccbe93SHeiko Schocher /*
436d8ccbe93SHeiko Schocher  * Basic board specific setup.  Pinmux has been handled already.
437d8ccbe93SHeiko Schocher  */
438d8ccbe93SHeiko Schocher int board_init(void)
439d8ccbe93SHeiko Schocher {
440d8ccbe93SHeiko Schocher #if defined(CONFIG_HW_WATCHDOG)
441d8ccbe93SHeiko Schocher 	hw_watchdog_init();
442d8ccbe93SHeiko Schocher #endif
443d8ccbe93SHeiko Schocher 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
444d8ccbe93SHeiko Schocher 	if (read_eeprom() < 0)
445d8ccbe93SHeiko Schocher 		puts("EEPROM Content Invalid.\n");
446d8ccbe93SHeiko Schocher 
447d8ccbe93SHeiko Schocher 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
448d8ccbe93SHeiko Schocher #if defined(CONFIG_NOR) || defined(CONFIG_NAND)
449d8ccbe93SHeiko Schocher 	gpmc_init();
450d8ccbe93SHeiko Schocher #endif
451d8ccbe93SHeiko Schocher 	shc_request_gpio();
452d8ccbe93SHeiko Schocher 
453d8ccbe93SHeiko Schocher 	return 0;
454d8ccbe93SHeiko Schocher }
455d8ccbe93SHeiko Schocher 
456d8ccbe93SHeiko Schocher #ifdef CONFIG_BOARD_LATE_INIT
457d8ccbe93SHeiko Schocher int board_late_init(void)
458d8ccbe93SHeiko Schocher {
459d8ccbe93SHeiko Schocher 	check_button_status();
460d8ccbe93SHeiko Schocher #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
461d8ccbe93SHeiko Schocher 	if (shc_eeprom_valid)
462d8ccbe93SHeiko Schocher 		if (is_valid_ethaddr(header.mac_addr))
463*fd1e959eSSimon Glass 			eth_env_set_enetaddr("ethaddr", header.mac_addr);
464d8ccbe93SHeiko Schocher #endif
465d8ccbe93SHeiko Schocher 
466d8ccbe93SHeiko Schocher 	return 0;
467d8ccbe93SHeiko Schocher }
468d8ccbe93SHeiko Schocher #endif
469d8ccbe93SHeiko Schocher 
470d8ccbe93SHeiko Schocher #ifndef CONFIG_DM_ETH
471d8ccbe93SHeiko Schocher #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
472d8ccbe93SHeiko Schocher 	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
473d8ccbe93SHeiko Schocher static void cpsw_control(int enabled)
474d8ccbe93SHeiko Schocher {
475d8ccbe93SHeiko Schocher 	/* VTP can be added here */
476d8ccbe93SHeiko Schocher 
477d8ccbe93SHeiko Schocher 	return;
478d8ccbe93SHeiko Schocher }
479d8ccbe93SHeiko Schocher 
480d8ccbe93SHeiko Schocher static struct cpsw_slave_data cpsw_slaves[] = {
481d8ccbe93SHeiko Schocher 	{
482d8ccbe93SHeiko Schocher 		.slave_reg_ofs	= 0x208,
483d8ccbe93SHeiko Schocher 		.sliver_reg_ofs	= 0xd80,
484d8ccbe93SHeiko Schocher 		.phy_addr	= 0,
485d8ccbe93SHeiko Schocher 	},
486d8ccbe93SHeiko Schocher 	{
487d8ccbe93SHeiko Schocher 		.slave_reg_ofs	= 0x308,
488d8ccbe93SHeiko Schocher 		.sliver_reg_ofs	= 0xdc0,
489d8ccbe93SHeiko Schocher 		.phy_addr	= 1,
490d8ccbe93SHeiko Schocher 	},
491d8ccbe93SHeiko Schocher };
492d8ccbe93SHeiko Schocher 
493d8ccbe93SHeiko Schocher static struct cpsw_platform_data cpsw_data = {
494d8ccbe93SHeiko Schocher 	.mdio_base		= CPSW_MDIO_BASE,
495d8ccbe93SHeiko Schocher 	.cpsw_base		= CPSW_BASE,
496d8ccbe93SHeiko Schocher 	.mdio_div		= 0xff,
497d8ccbe93SHeiko Schocher 	.channels		= 8,
498d8ccbe93SHeiko Schocher 	.cpdma_reg_ofs		= 0x800,
499d8ccbe93SHeiko Schocher 	.slaves			= 1,
500d8ccbe93SHeiko Schocher 	.slave_data		= cpsw_slaves,
501d8ccbe93SHeiko Schocher 	.ale_reg_ofs		= 0xd00,
502d8ccbe93SHeiko Schocher 	.ale_entries		= 1024,
503d8ccbe93SHeiko Schocher 	.host_port_reg_ofs	= 0x108,
504d8ccbe93SHeiko Schocher 	.hw_stats_reg_ofs	= 0x900,
505d8ccbe93SHeiko Schocher 	.bd_ram_ofs		= 0x2000,
506d8ccbe93SHeiko Schocher 	.mac_control		= (1 << 5),
507d8ccbe93SHeiko Schocher 	.control		= cpsw_control,
508d8ccbe93SHeiko Schocher 	.host_port_num		= 0,
509d8ccbe93SHeiko Schocher 	.version		= CPSW_CTRL_VERSION_2,
510d8ccbe93SHeiko Schocher };
511d8ccbe93SHeiko Schocher #endif
512d8ccbe93SHeiko Schocher 
513d8ccbe93SHeiko Schocher /*
514d8ccbe93SHeiko Schocher  * This function will:
515d8ccbe93SHeiko Schocher  * Read the eFuse for MAC addresses, and set ethaddr/eth1addr/usbnet_devaddr
516d8ccbe93SHeiko Schocher  * in the environment
517d8ccbe93SHeiko Schocher  * Perform fixups to the PHY present on certain boards.  We only need this
518d8ccbe93SHeiko Schocher  * function in:
519d8ccbe93SHeiko Schocher  * - SPL with either CPSW or USB ethernet support
520d8ccbe93SHeiko Schocher  * - Full U-Boot, with either CPSW or USB ethernet
521d8ccbe93SHeiko Schocher  * Build in only these cases to avoid warnings about unused variables
522d8ccbe93SHeiko Schocher  * when we build an SPL that has neither option but full U-Boot will.
523d8ccbe93SHeiko Schocher  */
524d8ccbe93SHeiko Schocher #if ((defined(CONFIG_SPL_ETH_SUPPORT) || \
525d8ccbe93SHeiko Schocher 	defined(CONFIG_SPL_USBETH_SUPPORT)) && \
526d8ccbe93SHeiko Schocher 	defined(CONFIG_SPL_BUILD)) || \
527d8ccbe93SHeiko Schocher 	((defined(CONFIG_DRIVER_TI_CPSW) || \
528d8ccbe93SHeiko Schocher 	  defined(CONFIG_USB_ETHER) && defined(CONFIG_USB_MUSB_GADGET)) && \
529d8ccbe93SHeiko Schocher 	 !defined(CONFIG_SPL_BUILD))
530d8ccbe93SHeiko Schocher int board_eth_init(bd_t *bis)
531d8ccbe93SHeiko Schocher {
532d8ccbe93SHeiko Schocher 	int rv, n = 0;
533d8ccbe93SHeiko Schocher 	uint8_t mac_addr[6];
534d8ccbe93SHeiko Schocher 	uint32_t mac_hi, mac_lo;
535d8ccbe93SHeiko Schocher 
536d8ccbe93SHeiko Schocher 	/* try reading mac address from efuse */
537d8ccbe93SHeiko Schocher 	mac_lo = readl(&cdev->macid0l);
538d8ccbe93SHeiko Schocher 	mac_hi = readl(&cdev->macid0h);
539d8ccbe93SHeiko Schocher 	mac_addr[0] = mac_hi & 0xFF;
540d8ccbe93SHeiko Schocher 	mac_addr[1] = (mac_hi & 0xFF00) >> 8;
541d8ccbe93SHeiko Schocher 	mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
542d8ccbe93SHeiko Schocher 	mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
543d8ccbe93SHeiko Schocher 	mac_addr[4] = mac_lo & 0xFF;
544d8ccbe93SHeiko Schocher 	mac_addr[5] = (mac_lo & 0xFF00) >> 8;
545d8ccbe93SHeiko Schocher 
546d8ccbe93SHeiko Schocher #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
547d8ccbe93SHeiko Schocher 	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
548d8ccbe93SHeiko Schocher 	if (!getenv("ethaddr")) {
549d8ccbe93SHeiko Schocher 		printf("<ethaddr> not set. Validating first E-fuse MAC\n");
550d8ccbe93SHeiko Schocher 
551d8ccbe93SHeiko Schocher 		if (is_valid_ethaddr(mac_addr))
552*fd1e959eSSimon Glass 			eth_env_set_enetaddr("ethaddr", mac_addr);
553d8ccbe93SHeiko Schocher 	}
554d8ccbe93SHeiko Schocher 
555d8ccbe93SHeiko Schocher 	writel(MII_MODE_ENABLE, &cdev->miisel);
556d8ccbe93SHeiko Schocher 	cpsw_slaves[0].phy_if =	PHY_INTERFACE_MODE_MII;
557d8ccbe93SHeiko Schocher 	cpsw_slaves[1].phy_if = cpsw_slaves[0].phy_if;
558d8ccbe93SHeiko Schocher 	rv = cpsw_register(&cpsw_data);
559d8ccbe93SHeiko Schocher 	if (rv < 0)
560d8ccbe93SHeiko Schocher 		printf("Error %d registering CPSW switch\n", rv);
561d8ccbe93SHeiko Schocher 	else
562d8ccbe93SHeiko Schocher 		n += rv;
563d8ccbe93SHeiko Schocher #endif
564d8ccbe93SHeiko Schocher 
565d8ccbe93SHeiko Schocher #if defined(CONFIG_USB_ETHER) && \
566d8ccbe93SHeiko Schocher 	(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT))
567d8ccbe93SHeiko Schocher 	if (is_valid_ethaddr(mac_addr))
568*fd1e959eSSimon Glass 		eth_env_set_enetaddr("usbnet_devaddr", mac_addr);
569d8ccbe93SHeiko Schocher 
570d8ccbe93SHeiko Schocher 	rv = usb_eth_initialize(bis);
571d8ccbe93SHeiko Schocher 	if (rv < 0)
572d8ccbe93SHeiko Schocher 		printf("Error %d registering USB_ETHER\n", rv);
573d8ccbe93SHeiko Schocher 	else
574d8ccbe93SHeiko Schocher 		n += rv;
575d8ccbe93SHeiko Schocher #endif
576d8ccbe93SHeiko Schocher 	return n;
577d8ccbe93SHeiko Schocher }
578d8ccbe93SHeiko Schocher #endif
579d8ccbe93SHeiko Schocher 
580d8ccbe93SHeiko Schocher #endif /* CONFIG_DM_ETH */
581d8ccbe93SHeiko Schocher 
582d8ccbe93SHeiko Schocher #ifdef CONFIG_SHOW_BOOT_PROGRESS
583d8ccbe93SHeiko Schocher static void bosch_check_reset_pin(void)
584d8ccbe93SHeiko Schocher {
585d8ccbe93SHeiko Schocher 	if (readl(GPIO1_BASE + OMAP_GPIO_IRQSTATUS_SET_0) & RESET_MASK) {
586d8ccbe93SHeiko Schocher 		printf("Resetting ...\n");
587d8ccbe93SHeiko Schocher 		writel(RESET_MASK, GPIO1_BASE + OMAP_GPIO_IRQSTATUS_SET_0);
588d8ccbe93SHeiko Schocher 		disable_interrupts();
589d8ccbe93SHeiko Schocher 		reset_cpu(0);
590d8ccbe93SHeiko Schocher 		/*NOTREACHED*/
591d8ccbe93SHeiko Schocher 	}
592d8ccbe93SHeiko Schocher }
593d8ccbe93SHeiko Schocher 
594d8ccbe93SHeiko Schocher static void hang_bosch(const char *cause, int code)
595d8ccbe93SHeiko Schocher {
596d8ccbe93SHeiko Schocher 	int lv;
597d8ccbe93SHeiko Schocher 
598d8ccbe93SHeiko Schocher 	gpio_direction_input(RESET_GPIO);
599d8ccbe93SHeiko Schocher 
600d8ccbe93SHeiko Schocher 	/* Enable reset pin interrupt on falling edge */
601d8ccbe93SHeiko Schocher 	writel(RESET_MASK, GPIO1_BASE + OMAP_GPIO_IRQSTATUS_SET_0);
602d8ccbe93SHeiko Schocher 	writel(RESET_MASK, GPIO1_BASE + OMAP_GPIO_FALLINGDETECT);
603d8ccbe93SHeiko Schocher 	enable_interrupts();
604d8ccbe93SHeiko Schocher 
605d8ccbe93SHeiko Schocher 	puts(cause);
606d8ccbe93SHeiko Schocher 	for (;;) {
607d8ccbe93SHeiko Schocher 		for (lv = 0; lv < code; lv++) {
608d8ccbe93SHeiko Schocher 			bosch_check_reset_pin();
609d8ccbe93SHeiko Schocher 			leds_set_failure(1);
610d8ccbe93SHeiko Schocher 			__udelay(150 * 1000);
611d8ccbe93SHeiko Schocher 			leds_set_failure(0);
612d8ccbe93SHeiko Schocher 			__udelay(150 * 1000);
613d8ccbe93SHeiko Schocher 		}
614d8ccbe93SHeiko Schocher #if defined(BLINK_CODE)
615d8ccbe93SHeiko Schocher 		__udelay(300 * 1000);
616d8ccbe93SHeiko Schocher #endif
617d8ccbe93SHeiko Schocher 	}
618d8ccbe93SHeiko Schocher }
619d8ccbe93SHeiko Schocher 
620d8ccbe93SHeiko Schocher void show_boot_progress(int val)
621d8ccbe93SHeiko Schocher {
622d8ccbe93SHeiko Schocher 	switch (val) {
623d8ccbe93SHeiko Schocher 	case BOOTSTAGE_ID_NEED_RESET:
624d8ccbe93SHeiko Schocher 		hang_bosch("need reset", 4);
625d8ccbe93SHeiko Schocher 		break;
626d8ccbe93SHeiko Schocher 	}
627d8ccbe93SHeiko Schocher }
628d8ccbe93SHeiko Schocher #endif
629d8ccbe93SHeiko Schocher 
630d8ccbe93SHeiko Schocher void arch_preboot_os(void)
631d8ccbe93SHeiko Schocher {
632d8ccbe93SHeiko Schocher 	leds_set_finish();
633d8ccbe93SHeiko Schocher }
634d8ccbe93SHeiko Schocher 
6354aa2ba3aSMasahiro Yamada #if defined(CONFIG_MMC)
636d8ccbe93SHeiko Schocher int board_mmc_init(bd_t *bis)
637d8ccbe93SHeiko Schocher {
638d8ccbe93SHeiko Schocher 	int ret;
639d8ccbe93SHeiko Schocher 
640d8ccbe93SHeiko Schocher 	/* Bosch: Do not enable 52MHz for eMMC device to avoid EMI */
641d8ccbe93SHeiko Schocher 	ret = omap_mmc_init(0, MMC_MODE_HS_52MHz, 26000000, -1, -1);
642d8ccbe93SHeiko Schocher 	if (ret)
643d8ccbe93SHeiko Schocher 		return ret;
644d8ccbe93SHeiko Schocher 
645d8ccbe93SHeiko Schocher 	ret = omap_mmc_init(1, MMC_MODE_HS_52MHz, 26000000, -1, -1);
646d8ccbe93SHeiko Schocher 	return ret;
647d8ccbe93SHeiko Schocher }
648d8ccbe93SHeiko Schocher #endif
649