stm32mp1: migrate USBOTG device to driver model
[platform/kernel/u-boot.git] / board / st / stm32mp1 / stm32mp1.c
1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4  */
5 #include <common.h>
6 #include <adc.h>
7 #include <config.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <g_dnl.h>
11 #include <generic-phy.h>
12 #include <led.h>
13 #include <misc.h>
14 #include <phy.h>
15 #include <reset.h>
16 #include <syscon.h>
17 #include <asm/io.h>
18 #include <asm/gpio.h>
19 #include <asm/arch/stm32.h>
20 #include <power/regulator.h>
21
22 /* SYSCFG registers */
23 #define SYSCFG_BOOTR            0x00
24 #define SYSCFG_PMCSETR          0x04
25 #define SYSCFG_IOCTRLSETR       0x18
26 #define SYSCFG_ICNR             0x1C
27 #define SYSCFG_CMPCR            0x20
28 #define SYSCFG_CMPENSETR        0x24
29 #define SYSCFG_PMCCLRR          0x44
30
31 #define SYSCFG_BOOTR_BOOT_MASK          GENMASK(2, 0)
32 #define SYSCFG_BOOTR_BOOTPD_SHIFT       4
33
34 #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE          BIT(0)
35 #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI        BIT(1)
36 #define SYSCFG_IOCTRLSETR_HSLVEN_ETH            BIT(2)
37 #define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC          BIT(3)
38 #define SYSCFG_IOCTRLSETR_HSLVEN_SPI            BIT(4)
39
40 #define SYSCFG_CMPCR_SW_CTRL            BIT(1)
41 #define SYSCFG_CMPCR_READY              BIT(8)
42
43 #define SYSCFG_CMPENSETR_MPU_EN         BIT(0)
44
45 #define SYSCFG_PMCSETR_ETH_CLK_SEL      BIT(16)
46 #define SYSCFG_PMCSETR_ETH_REF_CLK_SEL  BIT(17)
47
48 #define SYSCFG_PMCSETR_ETH_SELMII       BIT(20)
49
50 #define SYSCFG_PMCSETR_ETH_SEL_MASK     GENMASK(23, 21)
51 #define SYSCFG_PMCSETR_ETH_SEL_GMII_MII (0 << 21)
52 #define SYSCFG_PMCSETR_ETH_SEL_RGMII    (1 << 21)
53 #define SYSCFG_PMCSETR_ETH_SEL_RMII     (4 << 21)
54
55 /*
56  * Get a global data pointer
57  */
58 DECLARE_GLOBAL_DATA_PTR;
59
60 #define USB_WARNING_LOW_THRESHOLD_UV    660000
61 #define USB_START_LOW_THRESHOLD_UV      1230000
62 #define USB_START_HIGH_THRESHOLD_UV     2100000
63
64 int checkboard(void)
65 {
66         int ret;
67         char *mode;
68         u32 otp;
69         struct udevice *dev;
70         const char *fdt_compat;
71         int fdt_compat_len;
72
73         if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
74                 mode = "trusted";
75         else
76                 mode = "basic";
77
78         printf("Board: stm32mp1 in %s mode", mode);
79         fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
80                                  &fdt_compat_len);
81         if (fdt_compat && fdt_compat_len)
82                 printf(" (%s)", fdt_compat);
83         puts("\n");
84
85         ret = uclass_get_device_by_driver(UCLASS_MISC,
86                                           DM_GET_DRIVER(stm32mp_bsec),
87                                           &dev);
88
89         if (!ret)
90                 ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
91                                 &otp, sizeof(otp));
92         if (!ret && otp) {
93                 printf("Board: MB%04x Var%d Rev.%c-%02d\n",
94                        otp >> 16,
95                        (otp >> 12) & 0xF,
96                        ((otp >> 8) & 0xF) - 1 + 'A',
97                        otp & 0xF);
98         }
99
100         return 0;
101 }
102
103 static void board_key_check(void)
104 {
105 #if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
106         ofnode node;
107         struct gpio_desc gpio;
108         enum forced_boot_mode boot_mode = BOOT_NORMAL;
109
110         node = ofnode_path("/config");
111         if (!ofnode_valid(node)) {
112                 debug("%s: no /config node?\n", __func__);
113                 return;
114         }
115 #ifdef CONFIG_FASTBOOT
116         if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
117                                        &gpio, GPIOD_IS_IN)) {
118                 debug("%s: could not find a /config/st,fastboot-gpios\n",
119                       __func__);
120         } else {
121                 if (dm_gpio_get_value(&gpio)) {
122                         puts("Fastboot key pressed, ");
123                         boot_mode = BOOT_FASTBOOT;
124                 }
125
126                 dm_gpio_free(NULL, &gpio);
127         }
128 #endif
129 #ifdef CONFIG_CMD_STM32PROG
130         if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
131                                        &gpio, GPIOD_IS_IN)) {
132                 debug("%s: could not find a /config/st,stm32prog-gpios\n",
133                       __func__);
134         } else {
135                 if (dm_gpio_get_value(&gpio)) {
136                         puts("STM32Programmer key pressed, ");
137                         boot_mode = BOOT_STM32PROG;
138                 }
139                 dm_gpio_free(NULL, &gpio);
140         }
141 #endif
142
143         if (boot_mode != BOOT_NORMAL) {
144                 puts("entering download mode...\n");
145                 clrsetbits_le32(TAMP_BOOT_CONTEXT,
146                                 TAMP_BOOT_FORCED_MASK,
147                                 boot_mode);
148         }
149 #endif
150 }
151
152 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
153
154 int g_dnl_board_usb_cable_connected(void)
155 {
156         struct udevice *dwc2_udc_otg;
157         int ret;
158
159         ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC,
160                                           DM_GET_DRIVER(dwc2_udc_otg),
161                                           &dwc2_udc_otg);
162         if (!ret)
163                 debug("dwc2_udc_otg init failed\n");
164
165         return dwc2_udc_B_session_valid(dwc2_udc_otg);
166 }
167 #endif /* CONFIG_USB_GADGET */
168
169 static int get_led(struct udevice **dev, char *led_string)
170 {
171         char *led_name;
172         int ret;
173
174         led_name = fdtdec_get_config_string(gd->fdt_blob, led_string);
175         if (!led_name) {
176                 pr_debug("%s: could not find %s config string\n",
177                          __func__, led_string);
178                 return -ENOENT;
179         }
180         ret = led_get_by_label(led_name, dev);
181         if (ret) {
182                 debug("%s: get=%d\n", __func__, ret);
183                 return ret;
184         }
185
186         return 0;
187 }
188
189 static int setup_led(enum led_state_t cmd)
190 {
191         struct udevice *dev;
192         int ret;
193
194         ret = get_led(&dev, "u-boot,boot-led");
195         if (ret)
196                 return ret;
197
198         ret = led_set_state(dev, cmd);
199         return ret;
200 }
201
202 static int board_check_usb_power(void)
203 {
204         struct ofnode_phandle_args adc_args;
205         struct udevice *adc;
206         struct udevice *led;
207         ofnode node;
208         unsigned int raw;
209         int max_uV = 0;
210         int ret, uV, adc_count;
211         u8 i, nb_blink;
212
213         node = ofnode_path("/config");
214         if (!ofnode_valid(node)) {
215                 debug("%s: no /config node?\n", __func__);
216                 return -ENOENT;
217         }
218
219         /*
220          * Retrieve the ADC channels devices and get measurement
221          * for each of them
222          */
223         adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd",
224                                                    "#io-channel-cells");
225         if (adc_count < 0) {
226                 if (adc_count == -ENOENT)
227                         return 0;
228
229                 pr_err("%s: can't find adc channel (%d)\n", __func__,
230                        adc_count);
231
232                 return adc_count;
233         }
234
235         for (i = 0; i < adc_count; i++) {
236                 if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd",
237                                                    "#io-channel-cells", 0, i,
238                                                    &adc_args)) {
239                         pr_debug("%s: can't find /config/st,adc_usb_pd\n",
240                                  __func__);
241                         return 0;
242                 }
243
244                 ret = uclass_get_device_by_ofnode(UCLASS_ADC, adc_args.node,
245                                                   &adc);
246
247                 if (ret) {
248                         pr_err("%s: Can't get adc device(%d)\n", __func__,
249                                ret);
250                         return ret;
251                 }
252
253                 ret = adc_channel_single_shot(adc->name, adc_args.args[0],
254                                               &raw);
255                 if (ret) {
256                         pr_err("%s: single shot failed for %s[%d]!\n",
257                                __func__, adc->name, adc_args.args[0]);
258                         return ret;
259                 }
260                 /* Convert to uV */
261                 if (!adc_raw_to_uV(adc, raw, &uV)) {
262                         if (uV > max_uV)
263                                 max_uV = uV;
264                         pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__,
265                                  adc->name, adc_args.args[0], raw, uV);
266                 } else {
267                         pr_err("%s: Can't get uV value for %s[%d]\n",
268                                __func__, adc->name, adc_args.args[0]);
269                 }
270         }
271
272         /*
273          * If highest value is inside 1.23 Volts and 2.10 Volts, that means
274          * board is plugged on an USB-C 3A power supply and boot process can
275          * continue.
276          */
277         if (max_uV > USB_START_LOW_THRESHOLD_UV &&
278             max_uV < USB_START_HIGH_THRESHOLD_UV)
279                 return 0;
280
281         /* Display warning message and make u-boot,error-led blinking */
282         pr_err("\n*******************************************\n");
283
284         if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) {
285                 pr_err("*   WARNING 500mA power supply detected   *\n");
286                 nb_blink = 2;
287         } else {
288                 pr_err("* WARNING 1.5A power supply detected      *\n");
289                 nb_blink = 3;
290         }
291
292         pr_err("* Current too low, use a 3A power supply! *\n");
293         pr_err("*******************************************\n\n");
294
295         ret = get_led(&led, "u-boot,error-led");
296         if (ret)
297                 return ret;
298
299         for (i = 0; i < nb_blink * 2; i++) {
300                 led_set_state(led, LEDST_TOGGLE);
301                 mdelay(125);
302         }
303         led_set_state(led, LEDST_ON);
304
305         return 0;
306 }
307
308 static void sysconf_init(void)
309 {
310 #ifndef CONFIG_STM32MP1_TRUSTED
311         u8 *syscfg;
312 #ifdef CONFIG_DM_REGULATOR
313         struct udevice *pwr_dev;
314         struct udevice *pwr_reg;
315         struct udevice *dev;
316         int ret;
317         u32 otp = 0;
318 #endif
319         u32 bootr;
320
321         syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
322
323         /* interconnect update : select master using the port 1 */
324         /* LTDC = AXI_M9 */
325         /* GPU  = AXI_M8 */
326         /* today information is hardcoded in U-Boot */
327         writel(BIT(9), syscfg + SYSCFG_ICNR);
328
329         /* disable Pull-Down for boot pin connected to VDD */
330         bootr = readl(syscfg + SYSCFG_BOOTR);
331         bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
332         bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
333         writel(bootr, syscfg + SYSCFG_BOOTR);
334
335 #ifdef CONFIG_DM_REGULATOR
336         /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
337          * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
338          * The customer will have to disable this for low frequencies
339          * or if AFMUX is selected but the function not used, typically for
340          * TRACE. Otherwise, impact on power consumption.
341          *
342          * WARNING:
343          *   enabling High Speed mode while VDD>2.7V
344          *   with the OTP product_below_2v5 (OTP 18, BIT 13)
345          *   erroneously set to 1 can damage the IC!
346          *   => U-Boot set the register only if VDD < 2.7V (in DT)
347          *      but this value need to be consistent with board design
348          */
349         ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev);
350         if (!ret) {
351                 ret = uclass_get_device_by_driver(UCLASS_MISC,
352                                                   DM_GET_DRIVER(stm32mp_bsec),
353                                                   &dev);
354                 if (ret) {
355                         pr_err("Can't find stm32mp_bsec driver\n");
356                         return;
357                 }
358
359                 ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
360                 if (!ret)
361                         otp = otp & BIT(13);
362
363                 /* get VDD = pwr-supply */
364                 ret = device_get_supply_regulator(pwr_dev, "pwr-supply",
365                                                   &pwr_reg);
366
367                 /* check if VDD is Low Voltage */
368                 if (!ret) {
369                         if (regulator_get_value(pwr_reg) < 2700000) {
370                                 writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
371                                        SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
372                                        SYSCFG_IOCTRLSETR_HSLVEN_ETH |
373                                        SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
374                                        SYSCFG_IOCTRLSETR_HSLVEN_SPI,
375                                        syscfg + SYSCFG_IOCTRLSETR);
376
377                                 if (!otp)
378                                         pr_err("product_below_2v5=0: HSLVEN protected by HW\n");
379                         } else {
380                                 if (otp)
381                                         pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
382                         }
383                 } else {
384                         debug("VDD unknown");
385                 }
386         }
387 #endif
388
389         /* activate automatic I/O compensation
390          * warning: need to ensure CSI enabled and ready in clock driver
391          */
392         writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
393
394         while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY))
395                 ;
396         clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
397 #endif
398 }
399
400 /* board dependent setup after realloc */
401 int board_init(void)
402 {
403         struct udevice *dev;
404
405         /* address of boot parameters */
406         gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
407
408         /* probe all PINCTRL for hog */
409         for (uclass_first_device(UCLASS_PINCTRL, &dev);
410              dev;
411              uclass_next_device(&dev)) {
412                 pr_debug("probe pincontrol = %s\n", dev->name);
413         }
414
415         board_key_check();
416
417         sysconf_init();
418
419         if (IS_ENABLED(CONFIG_LED))
420                 led_default_state();
421
422         return 0;
423 }
424
425 int board_late_init(void)
426 {
427 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
428         const void *fdt_compat;
429         int fdt_compat_len;
430
431         fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
432                                  &fdt_compat_len);
433         if (fdt_compat && fdt_compat_len) {
434                 if (strncmp(fdt_compat, "st,", 3) != 0)
435                         env_set("board_name", fdt_compat);
436                 else
437                         env_set("board_name", fdt_compat + 3);
438         }
439 #endif
440
441         /* for DK1/DK2 boards */
442         board_check_usb_power();
443
444         return 0;
445 }
446
447 void board_quiesce_devices(void)
448 {
449         setup_led(LEDST_OFF);
450 }