xref: /openbmc/u-boot/board/buffalo/lsxl/lsxl.c (revision c346e466)
1 /*
2  * Copyright (c) 2012 Michael Walle
3  * Michael Walle <michael@walle.cc>
4  *
5  * Based on sheevaplug/sheevaplug.c by
6  *   Marvell Semiconductor <www.marvell.com>
7  *
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 
11 #include <common.h>
12 #include <net.h>
13 #include <malloc.h>
14 #include <netdev.h>
15 #include <miiphy.h>
16 #include <asm/arch/kirkwood.h>
17 #include <asm/arch/cpu.h>
18 #include <asm/arch/mpp.h>
19 #include <asm/arch/gpio.h>
20 #include <spi_flash.h>
21 
22 #include "lsxl.h"
23 
24 /*
25  * Rescue mode
26  *
27  * Selected by holding the push button for 3 seconds, while powering on
28  * the device.
29  *
30  * These linkstations don't have a (populated) serial port. There is no
31  * way to access an (unmodified) board other than using the netconsole. If
32  * you want to recover from a bad environment setting or an empty environment,
33  * you can do this only with a working network connection. Therefore, a random
34  * ethernet address is generated if none is set and a DHCP request is sent.
35  * After a successful DHCP response is received, the network settings are
36  * configured and the ncip is unset. Therefore, all netconsole packets are
37  * broadcasted.
38  * Additionally, the bootsource is set to 'rescue'.
39  */
40 
41 #ifndef CONFIG_ENV_OVERWRITE
42 # error "You need to set CONFIG_ENV_OVERWRITE"
43 #endif
44 
45 DECLARE_GLOBAL_DATA_PTR;
46 
47 int board_early_init_f(void)
48 {
49 	/*
50 	 * default gpio configuration
51 	 * There are maximum 64 gpios controlled through 2 sets of registers
52 	 * the below configuration configures mainly initial LED status
53 	 */
54 	kw_config_gpio(LSXL_OE_VAL_LOW,
55 			LSXL_OE_VAL_HIGH,
56 			LSXL_OE_LOW, LSXL_OE_HIGH);
57 
58 	/*
59 	 * Multi-Purpose Pins Functionality configuration
60 	 * These strappings are taken from the original vendor uboot port.
61 	 */
62 	static const u32 kwmpp_config[] = {
63 		MPP0_SPI_SCn,
64 		MPP1_SPI_MOSI,
65 		MPP2_SPI_SCK,
66 		MPP3_SPI_MISO,
67 		MPP4_UART0_RXD,
68 		MPP5_UART0_TXD,
69 		MPP6_SYSRST_OUTn,
70 		MPP7_GPO,
71 		MPP8_GPIO,
72 		MPP9_GPIO,
73 		MPP10_GPO,		/* HDD power */
74 		MPP11_GPIO,		/* USB Vbus enable */
75 		MPP12_SD_CLK,
76 		MPP13_SD_CMD,
77 		MPP14_SD_D0,
78 		MPP15_SD_D1,
79 		MPP16_SD_D2,
80 		MPP17_SD_D3,
81 		MPP18_GPO,		/* fan speed high */
82 		MPP19_GPO,		/* fan speed low */
83 		MPP20_GE1_0,
84 		MPP21_GE1_1,
85 		MPP22_GE1_2,
86 		MPP23_GE1_3,
87 		MPP24_GE1_4,
88 		MPP25_GE1_5,
89 		MPP26_GE1_6,
90 		MPP27_GE1_7,
91 		MPP28_GPIO,
92 		MPP29_GPIO,
93 		MPP30_GE1_10,
94 		MPP31_GE1_11,
95 		MPP32_GE1_12,
96 		MPP33_GE1_13,
97 		MPP34_GPIO,
98 		MPP35_GPIO,
99 		MPP36_GPIO,		/* function LED */
100 		MPP37_GPIO,		/* alarm LED */
101 		MPP38_GPIO,		/* info LED */
102 		MPP39_GPIO,		/* power LED */
103 		MPP40_GPIO,		/* fan alarm */
104 		MPP41_GPIO,		/* funtion button */
105 		MPP42_GPIO,		/* power switch */
106 		MPP43_GPIO,		/* power auto switch */
107 		MPP44_GPIO,
108 		MPP45_GPIO,
109 		MPP46_GPIO,
110 		MPP47_GPIO,
111 		MPP48_GPIO,		/* function red LED */
112 		MPP49_GPIO,
113 		0
114 	};
115 
116 	kirkwood_mpp_conf(kwmpp_config, NULL);
117 
118 	return 0;
119 }
120 
121 #define LED_OFF             0
122 #define LED_ALARM_ON        1
123 #define LED_ALARM_BLINKING  2
124 #define LED_POWER_ON        3
125 #define LED_POWER_BLINKING  4
126 #define LED_INFO_ON         5
127 #define LED_INFO_BLINKING   6
128 
129 static void __set_led(int blink_alarm, int blink_info, int blink_power,
130 		int value_alarm, int value_info, int value_power)
131 {
132 	kw_gpio_set_blink(GPIO_ALARM_LED, blink_alarm);
133 	kw_gpio_set_blink(GPIO_INFO_LED, blink_info);
134 	kw_gpio_set_blink(GPIO_POWER_LED, blink_power);
135 	kw_gpio_set_value(GPIO_ALARM_LED, value_alarm);
136 	kw_gpio_set_value(GPIO_INFO_LED, value_info);
137 	kw_gpio_set_value(GPIO_POWER_LED, value_power);
138 }
139 
140 static void set_led(int state)
141 {
142 	switch (state) {
143 	case LED_OFF:
144 		__set_led(0, 0, 0, 1, 1, 1);
145 		break;
146 	case LED_ALARM_ON:
147 		__set_led(0, 0, 0, 0, 1, 1);
148 		break;
149 	case LED_ALARM_BLINKING:
150 		__set_led(1, 0, 0, 1, 1, 1);
151 		break;
152 	case LED_INFO_ON:
153 		__set_led(0, 0, 0, 1, 0, 1);
154 		break;
155 	case LED_INFO_BLINKING:
156 		__set_led(0, 1, 0, 1, 1, 1);
157 		break;
158 	case LED_POWER_ON:
159 		__set_led(0, 0, 0, 1, 1, 0);
160 		break;
161 	case LED_POWER_BLINKING:
162 		__set_led(0, 0, 1, 1, 1, 1);
163 		break;
164 	}
165 }
166 
167 int board_init(void)
168 {
169 	/* address of boot parameters */
170 	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
171 
172 	set_led(LED_POWER_BLINKING);
173 
174 	return 0;
175 }
176 
177 #ifdef CONFIG_MISC_INIT_R
178 static void check_power_switch(void)
179 {
180 	if (kw_gpio_get_value(GPIO_POWER_SWITCH)) {
181 		/* turn off fan, HDD and USB power */
182 		kw_gpio_set_value(GPIO_HDD_POWER, 0);
183 		kw_gpio_set_value(GPIO_USB_VBUS, 0);
184 		kw_gpio_set_value(GPIO_FAN_HIGH, 1);
185 		kw_gpio_set_value(GPIO_FAN_LOW, 1);
186 		set_led(LED_OFF);
187 
188 		/* loop until released */
189 		while (kw_gpio_get_value(GPIO_POWER_SWITCH))
190 			;
191 
192 		/* turn power on again */
193 		kw_gpio_set_value(GPIO_HDD_POWER, 1);
194 		kw_gpio_set_value(GPIO_USB_VBUS, 1);
195 		kw_gpio_set_value(GPIO_FAN_HIGH, 0);
196 		kw_gpio_set_value(GPIO_FAN_LOW, 0);
197 		set_led(LED_POWER_BLINKING);
198 	}
199 }
200 
201 void check_enetaddr(void)
202 {
203 	uchar enetaddr[6];
204 
205 	if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
206 		/* signal unset/invalid ethaddr to user */
207 		set_led(LED_INFO_BLINKING);
208 	}
209 }
210 
211 static void erase_environment(void)
212 {
213 	struct spi_flash *flash;
214 
215 	printf("Erasing environment..\n");
216 	flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
217 	if (!flash) {
218 		printf("Erasing flash failed\n");
219 		return;
220 	}
221 
222 	spi_flash_erase(flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE);
223 	spi_flash_free(flash);
224 	do_reset(NULL, 0, 0, NULL);
225 }
226 
227 static void rescue_mode(void)
228 {
229 	uchar enetaddr[6];
230 
231 	printf("Entering rescue mode..\n");
232 #ifdef CONFIG_RANDOM_MACADDR
233 	if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
234 		eth_random_addr(enetaddr);
235 		if (eth_setenv_enetaddr("ethaddr", enetaddr)) {
236 			printf("Failed to set ethernet address\n");
237 				set_led(LED_ALARM_BLINKING);
238 			return;
239 		}
240 	}
241 #endif
242 	setenv("bootsource", "rescue");
243 }
244 
245 static void check_push_button(void)
246 {
247 	int i = 0;
248 
249 	while (!kw_gpio_get_value(GPIO_FUNC_BUTTON)) {
250 		udelay(100000);
251 		i++;
252 
253 		if (i == 10)
254 			set_led(LED_INFO_ON);
255 
256 		if (i >= 100) {
257 			set_led(LED_INFO_BLINKING);
258 			break;
259 		}
260 	}
261 
262 	if (i >= 100)
263 		erase_environment();
264 	else if (i >= 10)
265 		rescue_mode();
266 }
267 
268 int misc_init_r(void)
269 {
270 	check_power_switch();
271 	check_enetaddr();
272 	check_push_button();
273 
274 	return 0;
275 }
276 #endif
277 
278 #ifdef CONFIG_SHOW_BOOT_PROGRESS
279 void show_boot_progress(int progress)
280 {
281 	if (progress > 0)
282 		return;
283 
284 	/* this is not an error, eg. bootp with autoload=no will trigger this */
285 	if (progress == -BOOTSTAGE_ID_NET_LOADED)
286 		return;
287 
288 	set_led(LED_ALARM_BLINKING);
289 }
290 #endif
291