1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
10 #include <generic-phy.h>
19 #include <asm/arch/stm32.h>
20 #include <power/regulator.h>
21 #include <usb/dwc2_udc.h>
23 /* SYSCFG registers */
24 #define SYSCFG_BOOTR 0x00
25 #define SYSCFG_PMCSETR 0x04
26 #define SYSCFG_IOCTRLSETR 0x18
27 #define SYSCFG_ICNR 0x1C
28 #define SYSCFG_CMPCR 0x20
29 #define SYSCFG_CMPENSETR 0x24
30 #define SYSCFG_PMCCLRR 0x44
32 #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
33 #define SYSCFG_BOOTR_BOOTPD_SHIFT 4
35 #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0)
36 #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1)
37 #define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2)
38 #define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3)
39 #define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4)
41 #define SYSCFG_CMPCR_SW_CTRL BIT(1)
42 #define SYSCFG_CMPCR_READY BIT(8)
44 #define SYSCFG_CMPENSETR_MPU_EN BIT(0)
46 #define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16)
47 #define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17)
49 #define SYSCFG_PMCSETR_ETH_SELMII BIT(20)
51 #define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21)
52 #define SYSCFG_PMCSETR_ETH_SEL_GMII_MII (0 << 21)
53 #define SYSCFG_PMCSETR_ETH_SEL_RGMII (1 << 21)
54 #define SYSCFG_PMCSETR_ETH_SEL_RMII (4 << 21)
57 * Get a global data pointer
59 DECLARE_GLOBAL_DATA_PTR;
61 #define STM32MP_GUSBCFG 0x40002407
63 #define STM32MP_GGPIO 0x38
64 #define STM32MP_GGPIO_VBUS_SENSING BIT(21)
66 #define USB_WARNING_LOW_THRESHOLD_UV 660000
67 #define USB_START_LOW_THRESHOLD_UV 1230000
68 #define USB_START_HIGH_THRESHOLD_UV 2100000
76 const char *fdt_compat;
79 if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
84 printf("Board: stm32mp1 in %s mode", mode);
85 fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
87 if (fdt_compat && fdt_compat_len)
88 printf(" (%s)", fdt_compat);
91 ret = uclass_get_device_by_driver(UCLASS_MISC,
92 DM_GET_DRIVER(stm32mp_bsec),
96 ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
99 printf("Board: MB%04x Var%d Rev.%c-%02d\n",
102 ((otp >> 8) & 0xF) - 1 + 'A',
109 static void board_key_check(void)
111 #if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
113 struct gpio_desc gpio;
114 enum forced_boot_mode boot_mode = BOOT_NORMAL;
116 node = ofnode_path("/config");
117 if (!ofnode_valid(node)) {
118 debug("%s: no /config node?\n", __func__);
121 #ifdef CONFIG_FASTBOOT
122 if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
123 &gpio, GPIOD_IS_IN)) {
124 debug("%s: could not find a /config/st,fastboot-gpios\n",
127 if (dm_gpio_get_value(&gpio)) {
128 puts("Fastboot key pressed, ");
129 boot_mode = BOOT_FASTBOOT;
132 dm_gpio_free(NULL, &gpio);
135 #ifdef CONFIG_CMD_STM32PROG
136 if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
137 &gpio, GPIOD_IS_IN)) {
138 debug("%s: could not find a /config/st,stm32prog-gpios\n",
141 if (dm_gpio_get_value(&gpio)) {
142 puts("STM32Programmer key pressed, ");
143 boot_mode = BOOT_STM32PROG;
145 dm_gpio_free(NULL, &gpio);
149 if (boot_mode != BOOT_NORMAL) {
150 puts("entering download mode...\n");
151 clrsetbits_le32(TAMP_BOOT_CONTEXT,
152 TAMP_BOOT_FORCED_MASK,
158 static struct dwc2_plat_otg_data stm32mp_otg_data = {
159 .usb_gusbcfg = STM32MP_GUSBCFG,
162 static struct reset_ctl usbotg_reset;
164 int board_usb_init(int index, enum usb_init_type init)
166 struct fdtdec_phandle_args args;
168 const void *blob = gd->fdt_blob;
175 /* find the usb otg node */
176 node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
178 debug("Not found usb_otg device\n");
182 if (!fdtdec_get_is_enabled(blob, node)) {
183 debug("stm32 usbotg is disabled in the device tree\n");
188 ret = fdtdec_parse_phandle_with_args(blob, node, "clocks",
189 "#clock-cells", 0, 0, &args);
191 debug("usbotg has no clocks defined in the device tree\n");
195 ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev);
199 if (args.args_count != 1) {
200 debug("Can't find clock ID in the device tree\n");
205 clk.id = args.args[0];
207 ret = clk_enable(&clk);
209 debug("Failed to enable usbotg clock\n");
214 ret = fdtdec_parse_phandle_with_args(blob, node, "resets",
215 "#reset-cells", 0, 0, &args);
217 debug("usbotg has no resets defined in the device tree\n");
221 ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev);
222 if (ret || args.args_count != 1)
225 usbotg_reset.dev = dev;
226 usbotg_reset.id = args.args[0];
228 reset_assert(&usbotg_reset);
230 reset_deassert(&usbotg_reset);
233 ret = fdtdec_parse_phandle_with_args(blob, node, "phys",
234 "#phy-cells", 0, 0, &args);
236 phy_provider = fdt_parent_offset(blob, args.node);
237 ret = uclass_get_device_by_of_offset(UCLASS_PHY,
243 phy.id = fdtdec_get_uint(blob, args.node, "reg", -1);
245 ret = generic_phy_power_on(&phy);
247 debug("unable to power on the phy\n");
251 ret = generic_phy_init(&phy);
253 debug("failed to init usb phy\n");
258 /* Parse and store data needed for gadget */
259 stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
260 if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) {
261 debug("usbotg: can't get base address\n");
266 stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node,
267 "g-rx-fifo-size", 0);
268 stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node,
269 "g-np-tx-fifo-size", 0);
270 stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node,
271 "g-tx-fifo-size", 0);
272 /* Enable voltage level detector */
273 if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply",
274 NULL, 0, 0, &args))) {
275 if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR,
277 ret = regulator_set_enable(dev, true);
279 debug("Failed to enable usb33d\n");
284 /* Enable vbus sensing */
285 setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO,
286 STM32MP_GGPIO_VBUS_SENSING);
288 return dwc2_udc_probe(&stm32mp_otg_data);
291 generic_phy_exit(&phy);
294 generic_phy_power_off(&phy);
302 static int get_led(struct udevice **dev, char *led_string)
307 led_name = fdtdec_get_config_string(gd->fdt_blob, led_string);
309 pr_debug("%s: could not find %s config string\n",
310 __func__, led_string);
313 ret = led_get_by_label(led_name, dev);
315 debug("%s: get=%d\n", __func__, ret);
322 static int setup_led(enum led_state_t cmd)
327 ret = get_led(&dev, "u-boot,boot-led");
331 ret = led_set_state(dev, cmd);
335 static int board_check_usb_power(void)
337 struct ofnode_phandle_args adc_args;
343 int ret, uV, adc_count;
346 node = ofnode_path("/config");
347 if (!ofnode_valid(node)) {
348 debug("%s: no /config node?\n", __func__);
353 * Retrieve the ADC channels devices and get measurement
356 adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd",
357 "#io-channel-cells");
359 if (adc_count == -ENOENT)
362 pr_err("%s: can't find adc channel (%d)\n", __func__,
368 for (i = 0; i < adc_count; i++) {
369 if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd",
370 "#io-channel-cells", 0, i,
372 pr_debug("%s: can't find /config/st,adc_usb_pd\n",
377 ret = uclass_get_device_by_ofnode(UCLASS_ADC, adc_args.node,
381 pr_err("%s: Can't get adc device(%d)\n", __func__,
386 ret = adc_channel_single_shot(adc->name, adc_args.args[0],
389 pr_err("%s: single shot failed for %s[%d]!\n",
390 __func__, adc->name, adc_args.args[0]);
394 if (!adc_raw_to_uV(adc, raw, &uV)) {
397 pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__,
398 adc->name, adc_args.args[0], raw, uV);
400 pr_err("%s: Can't get uV value for %s[%d]\n",
401 __func__, adc->name, adc_args.args[0]);
406 * If highest value is inside 1.23 Volts and 2.10 Volts, that means
407 * board is plugged on an USB-C 3A power supply and boot process can
410 if (max_uV > USB_START_LOW_THRESHOLD_UV &&
411 max_uV < USB_START_HIGH_THRESHOLD_UV)
414 /* Display warning message and make u-boot,error-led blinking */
415 pr_err("\n*******************************************\n");
417 if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) {
418 pr_err("* WARNING 500mA power supply detected *\n");
421 pr_err("* WARNING 1.5A power supply detected *\n");
425 pr_err("* Current too low, use a 3A power supply! *\n");
426 pr_err("*******************************************\n\n");
428 ret = get_led(&led, "u-boot,error-led");
432 for (i = 0; i < nb_blink * 2; i++) {
433 led_set_state(led, LEDST_TOGGLE);
436 led_set_state(led, LEDST_ON);
441 int board_usb_cleanup(int index, enum usb_init_type init)
444 reset_assert(&usbotg_reset);
446 reset_deassert(&usbotg_reset);
451 static void sysconf_init(void)
453 #ifndef CONFIG_STM32MP1_TRUSTED
455 #ifdef CONFIG_DM_REGULATOR
456 struct udevice *pwr_dev;
457 struct udevice *pwr_reg;
464 syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
466 /* interconnect update : select master using the port 1 */
469 /* today information is hardcoded in U-Boot */
470 writel(BIT(9), syscfg + SYSCFG_ICNR);
472 /* disable Pull-Down for boot pin connected to VDD */
473 bootr = readl(syscfg + SYSCFG_BOOTR);
474 bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
475 bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
476 writel(bootr, syscfg + SYSCFG_BOOTR);
478 #ifdef CONFIG_DM_REGULATOR
479 /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
480 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
481 * The customer will have to disable this for low frequencies
482 * or if AFMUX is selected but the function not used, typically for
483 * TRACE. Otherwise, impact on power consumption.
486 * enabling High Speed mode while VDD>2.7V
487 * with the OTP product_below_2v5 (OTP 18, BIT 13)
488 * erroneously set to 1 can damage the IC!
489 * => U-Boot set the register only if VDD < 2.7V (in DT)
490 * but this value need to be consistent with board design
492 ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev);
494 ret = uclass_get_device_by_driver(UCLASS_MISC,
495 DM_GET_DRIVER(stm32mp_bsec),
498 pr_err("Can't find stm32mp_bsec driver\n");
502 ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
506 /* get VDD = pwr-supply */
507 ret = device_get_supply_regulator(pwr_dev, "pwr-supply",
510 /* check if VDD is Low Voltage */
512 if (regulator_get_value(pwr_reg) < 2700000) {
513 writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
514 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
515 SYSCFG_IOCTRLSETR_HSLVEN_ETH |
516 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
517 SYSCFG_IOCTRLSETR_HSLVEN_SPI,
518 syscfg + SYSCFG_IOCTRLSETR);
521 pr_err("product_below_2v5=0: HSLVEN protected by HW\n");
524 pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
527 debug("VDD unknown");
532 /* activate automatic I/O compensation
533 * warning: need to ensure CSI enabled and ready in clock driver
535 writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
537 while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY))
539 clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
543 /* board dependent setup after realloc */
548 /* address of boot parameters */
549 gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
551 /* probe all PINCTRL for hog */
552 for (uclass_first_device(UCLASS_PINCTRL, &dev);
554 uclass_next_device(&dev)) {
555 pr_debug("probe pincontrol = %s\n", dev->name);
562 if (IS_ENABLED(CONFIG_LED))
568 int board_late_init(void)
570 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
571 const void *fdt_compat;
574 fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
576 if (fdt_compat && fdt_compat_len) {
577 if (strncmp(fdt_compat, "st,", 3) != 0)
578 env_set("board_name", fdt_compat);
580 env_set("board_name", fdt_compat + 3);
584 /* for DK1/DK2 boards */
585 board_check_usb_power();
590 void board_quiesce_devices(void)
592 setup_led(LEDST_OFF);