stm32mp1: Update env_get_location for NOR support
[oweals/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 <environment.h>
11 #include <g_dnl.h>
12 #include <generic-phy.h>
13 #include <i2c.h>
14 #include <led.h>
15 #include <misc.h>
16 #include <phy.h>
17 #include <reset.h>
18 #include <syscon.h>
19 #include <usb.h>
20 #include <asm/io.h>
21 #include <asm/gpio.h>
22 #include <asm/arch/stm32.h>
23 #include <asm/arch/sys_proto.h>
24 #include <power/regulator.h>
25 #include <usb/dwc2_udc.h>
26
27 /* SYSCFG registers */
28 #define SYSCFG_BOOTR            0x00
29 #define SYSCFG_PMCSETR          0x04
30 #define SYSCFG_IOCTRLSETR       0x18
31 #define SYSCFG_ICNR             0x1C
32 #define SYSCFG_CMPCR            0x20
33 #define SYSCFG_CMPENSETR        0x24
34 #define SYSCFG_PMCCLRR          0x44
35
36 #define SYSCFG_BOOTR_BOOT_MASK          GENMASK(2, 0)
37 #define SYSCFG_BOOTR_BOOTPD_SHIFT       4
38
39 #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE          BIT(0)
40 #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI        BIT(1)
41 #define SYSCFG_IOCTRLSETR_HSLVEN_ETH            BIT(2)
42 #define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC          BIT(3)
43 #define SYSCFG_IOCTRLSETR_HSLVEN_SPI            BIT(4)
44
45 #define SYSCFG_CMPCR_SW_CTRL            BIT(1)
46 #define SYSCFG_CMPCR_READY              BIT(8)
47
48 #define SYSCFG_CMPENSETR_MPU_EN         BIT(0)
49
50 #define SYSCFG_PMCSETR_ETH_CLK_SEL      BIT(16)
51 #define SYSCFG_PMCSETR_ETH_REF_CLK_SEL  BIT(17)
52
53 #define SYSCFG_PMCSETR_ETH_SELMII       BIT(20)
54
55 #define SYSCFG_PMCSETR_ETH_SEL_MASK     GENMASK(23, 21)
56 #define SYSCFG_PMCSETR_ETH_SEL_GMII_MII (0 << 21)
57 #define SYSCFG_PMCSETR_ETH_SEL_RGMII    (1 << 21)
58 #define SYSCFG_PMCSETR_ETH_SEL_RMII     (4 << 21)
59
60 /*
61  * Get a global data pointer
62  */
63 DECLARE_GLOBAL_DATA_PTR;
64
65 #define USB_WARNING_LOW_THRESHOLD_UV    660000
66 #define USB_START_LOW_THRESHOLD_UV      1230000
67 #define USB_START_HIGH_THRESHOLD_UV     2100000
68
69 int checkboard(void)
70 {
71         int ret;
72         char *mode;
73         u32 otp;
74         struct udevice *dev;
75         const char *fdt_compat;
76         int fdt_compat_len;
77
78         if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
79                 mode = "trusted";
80         else
81                 mode = "basic";
82
83         printf("Board: stm32mp1 in %s mode", mode);
84         fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
85                                  &fdt_compat_len);
86         if (fdt_compat && fdt_compat_len)
87                 printf(" (%s)", fdt_compat);
88         puts("\n");
89
90         ret = uclass_get_device_by_driver(UCLASS_MISC,
91                                           DM_GET_DRIVER(stm32mp_bsec),
92                                           &dev);
93
94         if (!ret)
95                 ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
96                                 &otp, sizeof(otp));
97         if (!ret && otp) {
98                 printf("Board: MB%04x Var%d Rev.%c-%02d\n",
99                        otp >> 16,
100                        (otp >> 12) & 0xF,
101                        ((otp >> 8) & 0xF) - 1 + 'A',
102                        otp & 0xF);
103         }
104
105         return 0;
106 }
107
108 static void board_key_check(void)
109 {
110 #if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
111         ofnode node;
112         struct gpio_desc gpio;
113         enum forced_boot_mode boot_mode = BOOT_NORMAL;
114
115         node = ofnode_path("/config");
116         if (!ofnode_valid(node)) {
117                 debug("%s: no /config node?\n", __func__);
118                 return;
119         }
120 #ifdef CONFIG_FASTBOOT
121         if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
122                                        &gpio, GPIOD_IS_IN)) {
123                 debug("%s: could not find a /config/st,fastboot-gpios\n",
124                       __func__);
125         } else {
126                 if (dm_gpio_get_value(&gpio)) {
127                         puts("Fastboot key pressed, ");
128                         boot_mode = BOOT_FASTBOOT;
129                 }
130
131                 dm_gpio_free(NULL, &gpio);
132         }
133 #endif
134 #ifdef CONFIG_CMD_STM32PROG
135         if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
136                                        &gpio, GPIOD_IS_IN)) {
137                 debug("%s: could not find a /config/st,stm32prog-gpios\n",
138                       __func__);
139         } else {
140                 if (dm_gpio_get_value(&gpio)) {
141                         puts("STM32Programmer key pressed, ");
142                         boot_mode = BOOT_STM32PROG;
143                 }
144                 dm_gpio_free(NULL, &gpio);
145         }
146 #endif
147
148         if (boot_mode != BOOT_NORMAL) {
149                 puts("entering download mode...\n");
150                 clrsetbits_le32(TAMP_BOOT_CONTEXT,
151                                 TAMP_BOOT_FORCED_MASK,
152                                 boot_mode);
153         }
154 #endif
155 }
156
157 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
158
159 /* STMicroelectronics STUSB1600 Type-C controller */
160 #define STUSB1600_CC_CONNECTION_STATUS          0x0E
161
162 /* STUSB1600_CC_CONNECTION_STATUS bitfields */
163 #define STUSB1600_CC_ATTACH                     BIT(0)
164
165 static int stusb1600_init(struct udevice **dev_stusb1600)
166 {
167         ofnode node;
168         struct udevice *dev, *bus;
169         int ret;
170         u32 chip_addr;
171
172         *dev_stusb1600 = NULL;
173
174         /* if node stusb1600 is present, means DK1 or DK2 board */
175         node = ofnode_by_compatible(ofnode_null(), "st,stusb1600");
176         if (!ofnode_valid(node))
177                 return -ENODEV;
178
179         ret = ofnode_read_u32(node, "reg", &chip_addr);
180         if (ret)
181                 return -EINVAL;
182
183         ret = uclass_get_device_by_ofnode(UCLASS_I2C, ofnode_get_parent(node),
184                                           &bus);
185         if (ret) {
186                 printf("bus for stusb1600 not found\n");
187                 return -ENODEV;
188         }
189
190         ret = dm_i2c_probe(bus, chip_addr, 0, &dev);
191         if (!ret)
192                 *dev_stusb1600 = dev;
193
194         return ret;
195 }
196
197 static int stusb1600_cable_connected(struct udevice *dev)
198 {
199         u8 status;
200
201         if (dm_i2c_read(dev, STUSB1600_CC_CONNECTION_STATUS, &status, 1))
202                 return 0;
203
204         return status & STUSB1600_CC_ATTACH;
205 }
206
207 #include <usb/dwc2_udc.h>
208 int g_dnl_board_usb_cable_connected(void)
209 {
210         struct udevice *stusb1600;
211         struct udevice *dwc2_udc_otg;
212         int ret;
213
214         if (!stusb1600_init(&stusb1600))
215                 return stusb1600_cable_connected(stusb1600);
216
217         ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC,
218                                           DM_GET_DRIVER(dwc2_udc_otg),
219                                           &dwc2_udc_otg);
220         if (!ret)
221                 debug("dwc2_udc_otg init failed\n");
222
223         return dwc2_udc_B_session_valid(dwc2_udc_otg);
224 }
225 #endif /* CONFIG_USB_GADGET */
226
227 static int get_led(struct udevice **dev, char *led_string)
228 {
229         char *led_name;
230         int ret;
231
232         led_name = fdtdec_get_config_string(gd->fdt_blob, led_string);
233         if (!led_name) {
234                 pr_debug("%s: could not find %s config string\n",
235                          __func__, led_string);
236                 return -ENOENT;
237         }
238         ret = led_get_by_label(led_name, dev);
239         if (ret) {
240                 debug("%s: get=%d\n", __func__, ret);
241                 return ret;
242         }
243
244         return 0;
245 }
246
247 static int setup_led(enum led_state_t cmd)
248 {
249         struct udevice *dev;
250         int ret;
251
252         ret = get_led(&dev, "u-boot,boot-led");
253         if (ret)
254                 return ret;
255
256         ret = led_set_state(dev, cmd);
257         return ret;
258 }
259
260 static int board_check_usb_power(void)
261 {
262         struct ofnode_phandle_args adc_args;
263         struct udevice *adc;
264         struct udevice *led;
265         ofnode node;
266         unsigned int raw;
267         int max_uV = 0;
268         int ret, uV, adc_count;
269         u8 i, nb_blink;
270
271         node = ofnode_path("/config");
272         if (!ofnode_valid(node)) {
273                 debug("%s: no /config node?\n", __func__);
274                 return -ENOENT;
275         }
276
277         /*
278          * Retrieve the ADC channels devices and get measurement
279          * for each of them
280          */
281         adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd",
282                                                    "#io-channel-cells");
283         if (adc_count < 0) {
284                 if (adc_count == -ENOENT)
285                         return 0;
286
287                 pr_err("%s: can't find adc channel (%d)\n", __func__,
288                        adc_count);
289
290                 return adc_count;
291         }
292
293         for (i = 0; i < adc_count; i++) {
294                 if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd",
295                                                    "#io-channel-cells", 0, i,
296                                                    &adc_args)) {
297                         pr_debug("%s: can't find /config/st,adc_usb_pd\n",
298                                  __func__);
299                         return 0;
300                 }
301
302                 ret = uclass_get_device_by_ofnode(UCLASS_ADC, adc_args.node,
303                                                   &adc);
304
305                 if (ret) {
306                         pr_err("%s: Can't get adc device(%d)\n", __func__,
307                                ret);
308                         return ret;
309                 }
310
311                 ret = adc_channel_single_shot(adc->name, adc_args.args[0],
312                                               &raw);
313                 if (ret) {
314                         pr_err("%s: single shot failed for %s[%d]!\n",
315                                __func__, adc->name, adc_args.args[0]);
316                         return ret;
317                 }
318                 /* Convert to uV */
319                 if (!adc_raw_to_uV(adc, raw, &uV)) {
320                         if (uV > max_uV)
321                                 max_uV = uV;
322                         pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__,
323                                  adc->name, adc_args.args[0], raw, uV);
324                 } else {
325                         pr_err("%s: Can't get uV value for %s[%d]\n",
326                                __func__, adc->name, adc_args.args[0]);
327                 }
328         }
329
330         /*
331          * If highest value is inside 1.23 Volts and 2.10 Volts, that means
332          * board is plugged on an USB-C 3A power supply and boot process can
333          * continue.
334          */
335         if (max_uV > USB_START_LOW_THRESHOLD_UV &&
336             max_uV < USB_START_HIGH_THRESHOLD_UV)
337                 return 0;
338
339         /* Display warning message and make u-boot,error-led blinking */
340         pr_err("\n*******************************************\n");
341
342         if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) {
343                 pr_err("*   WARNING 500mA power supply detected   *\n");
344                 nb_blink = 2;
345         } else {
346                 pr_err("* WARNING 1.5A power supply detected      *\n");
347                 nb_blink = 3;
348         }
349
350         pr_err("* Current too low, use a 3A power supply! *\n");
351         pr_err("*******************************************\n\n");
352
353         ret = get_led(&led, "u-boot,error-led");
354         if (ret)
355                 return ret;
356
357         for (i = 0; i < nb_blink * 2; i++) {
358                 led_set_state(led, LEDST_TOGGLE);
359                 mdelay(125);
360         }
361         led_set_state(led, LEDST_ON);
362
363         return 0;
364 }
365
366 static void sysconf_init(void)
367 {
368 #ifndef CONFIG_STM32MP1_TRUSTED
369         u8 *syscfg;
370 #ifdef CONFIG_DM_REGULATOR
371         struct udevice *pwr_dev;
372         struct udevice *pwr_reg;
373         struct udevice *dev;
374         int ret;
375         u32 otp = 0;
376 #endif
377         u32 bootr;
378
379         syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
380
381         /* interconnect update : select master using the port 1 */
382         /* LTDC = AXI_M9 */
383         /* GPU  = AXI_M8 */
384         /* today information is hardcoded in U-Boot */
385         writel(BIT(9), syscfg + SYSCFG_ICNR);
386
387         /* disable Pull-Down for boot pin connected to VDD */
388         bootr = readl(syscfg + SYSCFG_BOOTR);
389         bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
390         bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
391         writel(bootr, syscfg + SYSCFG_BOOTR);
392
393 #ifdef CONFIG_DM_REGULATOR
394         /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
395          * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
396          * The customer will have to disable this for low frequencies
397          * or if AFMUX is selected but the function not used, typically for
398          * TRACE. Otherwise, impact on power consumption.
399          *
400          * WARNING:
401          *   enabling High Speed mode while VDD>2.7V
402          *   with the OTP product_below_2v5 (OTP 18, BIT 13)
403          *   erroneously set to 1 can damage the IC!
404          *   => U-Boot set the register only if VDD < 2.7V (in DT)
405          *      but this value need to be consistent with board design
406          */
407         ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev);
408         if (!ret) {
409                 ret = uclass_get_device_by_driver(UCLASS_MISC,
410                                                   DM_GET_DRIVER(stm32mp_bsec),
411                                                   &dev);
412                 if (ret) {
413                         pr_err("Can't find stm32mp_bsec driver\n");
414                         return;
415                 }
416
417                 ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
418                 if (!ret)
419                         otp = otp & BIT(13);
420
421                 /* get VDD = pwr-supply */
422                 ret = device_get_supply_regulator(pwr_dev, "pwr-supply",
423                                                   &pwr_reg);
424
425                 /* check if VDD is Low Voltage */
426                 if (!ret) {
427                         if (regulator_get_value(pwr_reg) < 2700000) {
428                                 writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
429                                        SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
430                                        SYSCFG_IOCTRLSETR_HSLVEN_ETH |
431                                        SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
432                                        SYSCFG_IOCTRLSETR_HSLVEN_SPI,
433                                        syscfg + SYSCFG_IOCTRLSETR);
434
435                                 if (!otp)
436                                         pr_err("product_below_2v5=0: HSLVEN protected by HW\n");
437                         } else {
438                                 if (otp)
439                                         pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
440                         }
441                 } else {
442                         debug("VDD unknown");
443                 }
444         }
445 #endif
446
447         /* activate automatic I/O compensation
448          * warning: need to ensure CSI enabled and ready in clock driver
449          */
450         writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
451
452         while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY))
453                 ;
454         clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
455 #endif
456 }
457
458 /* board dependent setup after realloc */
459 int board_init(void)
460 {
461         struct udevice *dev;
462
463         /* address of boot parameters */
464         gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
465
466         /* probe all PINCTRL for hog */
467         for (uclass_first_device(UCLASS_PINCTRL, &dev);
468              dev;
469              uclass_next_device(&dev)) {
470                 pr_debug("probe pincontrol = %s\n", dev->name);
471         }
472
473         board_key_check();
474
475         sysconf_init();
476
477         if (IS_ENABLED(CONFIG_LED))
478                 led_default_state();
479
480         return 0;
481 }
482
483 int board_late_init(void)
484 {
485 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
486         const void *fdt_compat;
487         int fdt_compat_len;
488
489         fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
490                                  &fdt_compat_len);
491         if (fdt_compat && fdt_compat_len) {
492                 if (strncmp(fdt_compat, "st,", 3) != 0)
493                         env_set("board_name", fdt_compat);
494                 else
495                         env_set("board_name", fdt_compat + 3);
496         }
497 #endif
498
499         /* for DK1/DK2 boards */
500         board_check_usb_power();
501
502         return 0;
503 }
504
505 void board_quiesce_devices(void)
506 {
507         setup_led(LEDST_OFF);
508 }
509
510 enum env_location env_get_location(enum env_operation op, int prio)
511 {
512         u32 bootmode = get_bootmode();
513
514         if (prio)
515                 return ENVL_UNKNOWN;
516
517         switch (bootmode & TAMP_BOOT_DEVICE_MASK) {
518 #ifdef CONFIG_ENV_IS_IN_EXT4
519         case BOOT_FLASH_SD:
520         case BOOT_FLASH_EMMC:
521                 return ENVL_EXT4;
522 #endif
523 #ifdef CONFIG_ENV_IS_IN_UBI
524         case BOOT_FLASH_NAND:
525                 return ENVL_UBI;
526 #endif
527 #ifdef CONFIG_ENV_IS_IN_SPI_FLASH
528         case BOOT_FLASH_NOR:
529                 return ENVL_SPI_FLASH;
530 #endif
531         default:
532                 return ENVL_NOWHERE;
533         }
534 }
535
536 #if defined(CONFIG_ENV_IS_IN_EXT4)
537 const char *env_ext4_get_intf(void)
538 {
539         u32 bootmode = get_bootmode();
540
541         switch (bootmode & TAMP_BOOT_DEVICE_MASK) {
542         case BOOT_FLASH_SD:
543         case BOOT_FLASH_EMMC:
544                 return "mmc";
545         default:
546                 return "";
547         }
548 }
549
550 const char *env_ext4_get_dev_part(void)
551 {
552         static char *const dev_part[] = {"0:auto", "1:auto", "2:auto"};
553         u32 bootmode = get_bootmode();
554
555         return dev_part[(bootmode & TAMP_BOOT_INSTANCE_MASK) - 1];
556 }
557 #endif
558
559 #ifdef CONFIG_SYS_MTDPARTS_RUNTIME
560
561 #define MTDPARTS_LEN            256
562 #define MTDIDS_LEN              128
563
564 /**
565  * The mtdparts_nand0 and mtdparts_nor0 variable tends to be long.
566  * If we need to access it before the env is relocated, then we need
567  * to use our own stack buffer. gd->env_buf will be too small.
568  *
569  * @param buf temporary buffer pointer MTDPARTS_LEN long
570  * @return mtdparts variable string, NULL if not found
571  */
572 static const char *env_get_mtdparts(const char *str, char *buf)
573 {
574         if (gd->flags & GD_FLG_ENV_READY)
575                 return env_get(str);
576         if (env_get_f(str, buf, MTDPARTS_LEN) != -1)
577                 return buf;
578
579         return NULL;
580 }
581
582 /**
583  * update the variables "mtdids" and "mtdparts" with content of mtdparts_<dev>
584  */
585 static void board_get_mtdparts(const char *dev,
586                                char *mtdids,
587                                char *mtdparts)
588 {
589         char env_name[32] = "mtdparts_";
590         char tmp_mtdparts[MTDPARTS_LEN];
591         const char *tmp;
592
593         /* name of env variable to read = mtdparts_<dev> */
594         strcat(env_name, dev);
595         tmp = env_get_mtdparts(env_name, tmp_mtdparts);
596         if (tmp) {
597                 /* mtdids: "<dev>=<dev>, ...." */
598                 if (mtdids[0] != '\0')
599                         strcat(mtdids, ",");
600                 strcat(mtdids, dev);
601                 strcat(mtdids, "=");
602                 strcat(mtdids, dev);
603
604                 /* mtdparts: "mtdparts=<dev>:<mtdparts_<dev>>;..." */
605                 if (mtdparts[0] != '\0')
606                         strncat(mtdparts, ";", MTDPARTS_LEN);
607                 else
608                         strcat(mtdparts, "mtdparts=");
609                 strncat(mtdparts, dev, MTDPARTS_LEN);
610                 strncat(mtdparts, ":", MTDPARTS_LEN);
611                 strncat(mtdparts, tmp, MTDPARTS_LEN);
612         }
613 }
614
615 void board_mtdparts_default(const char **mtdids, const char **mtdparts)
616 {
617         struct udevice *dev;
618         static char parts[2 * MTDPARTS_LEN + 1];
619         static char ids[MTDIDS_LEN + 1];
620         static bool mtd_initialized;
621
622         if (mtd_initialized) {
623                 *mtdids = ids;
624                 *mtdparts = parts;
625                 return;
626         }
627
628         memset(parts, 0, sizeof(parts));
629         memset(ids, 0, sizeof(ids));
630
631         if (!uclass_get_device(UCLASS_MTD, 0, &dev))
632                 board_get_mtdparts("nand0", ids, parts);
633
634         if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev))
635                 board_get_mtdparts("nor0", ids, parts);
636
637         mtd_initialized = true;
638         *mtdids = ids;
639         *mtdparts = parts;
640         debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts);
641 }
642 #endif