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