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