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