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