1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
9 #include <generic-phy.h>
18 #include <asm/arch/stm32.h>
19 #include <power/regulator.h>
20 #include <usb/dwc2_udc.h>
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
31 #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
32 #define SYSCFG_BOOTR_BOOTPD_SHIFT 4
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)
40 #define SYSCFG_CMPCR_SW_CTRL BIT(1)
41 #define SYSCFG_CMPCR_READY BIT(8)
43 #define SYSCFG_CMPENSETR_MPU_EN BIT(0)
45 #define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16)
46 #define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17)
48 #define SYSCFG_PMCSETR_ETH_SELMII BIT(20)
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)
56 * Get a global data pointer
58 DECLARE_GLOBAL_DATA_PTR;
60 #define STM32MP_GUSBCFG 0x40002407
62 #define STM32MP_GGPIO 0x38
63 #define STM32MP_GGPIO_VBUS_SENSING BIT(21)
71 const char *fdt_compat;
74 if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
79 printf("Board: stm32mp1 in %s mode", mode);
80 fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
82 if (fdt_compat && fdt_compat_len)
83 printf(" (%s)", fdt_compat);
86 ret = uclass_get_device_by_driver(UCLASS_MISC,
87 DM_GET_DRIVER(stm32mp_bsec),
91 ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
94 printf("Board: MB%04x Var%d Rev.%c-%02d\n",
97 ((otp >> 8) & 0xF) - 1 + 'A',
104 static void board_key_check(void)
106 #if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
108 struct gpio_desc gpio;
109 enum forced_boot_mode boot_mode = BOOT_NORMAL;
111 node = ofnode_path("/config");
112 if (!ofnode_valid(node)) {
113 debug("%s: no /config node?\n", __func__);
116 #ifdef CONFIG_FASTBOOT
117 if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
118 &gpio, GPIOD_IS_IN)) {
119 debug("%s: could not find a /config/st,fastboot-gpios\n",
122 if (dm_gpio_get_value(&gpio)) {
123 puts("Fastboot key pressed, ");
124 boot_mode = BOOT_FASTBOOT;
127 dm_gpio_free(NULL, &gpio);
130 #ifdef CONFIG_CMD_STM32PROG
131 if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
132 &gpio, GPIOD_IS_IN)) {
133 debug("%s: could not find a /config/st,stm32prog-gpios\n",
136 if (dm_gpio_get_value(&gpio)) {
137 puts("STM32Programmer key pressed, ");
138 boot_mode = BOOT_STM32PROG;
140 dm_gpio_free(NULL, &gpio);
144 if (boot_mode != BOOT_NORMAL) {
145 puts("entering download mode...\n");
146 clrsetbits_le32(TAMP_BOOT_CONTEXT,
147 TAMP_BOOT_FORCED_MASK,
153 static struct dwc2_plat_otg_data stm32mp_otg_data = {
154 .usb_gusbcfg = STM32MP_GUSBCFG,
157 static struct reset_ctl usbotg_reset;
159 int board_usb_init(int index, enum usb_init_type init)
161 struct fdtdec_phandle_args args;
163 const void *blob = gd->fdt_blob;
170 /* find the usb otg node */
171 node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
173 debug("Not found usb_otg device\n");
177 if (!fdtdec_get_is_enabled(blob, node)) {
178 debug("stm32 usbotg is disabled in the device tree\n");
183 ret = fdtdec_parse_phandle_with_args(blob, node, "clocks",
184 "#clock-cells", 0, 0, &args);
186 debug("usbotg has no clocks defined in the device tree\n");
190 ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev);
194 if (args.args_count != 1) {
195 debug("Can't find clock ID in the device tree\n");
200 clk.id = args.args[0];
202 ret = clk_enable(&clk);
204 debug("Failed to enable usbotg clock\n");
209 ret = fdtdec_parse_phandle_with_args(blob, node, "resets",
210 "#reset-cells", 0, 0, &args);
212 debug("usbotg has no resets defined in the device tree\n");
216 ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev);
217 if (ret || args.args_count != 1)
220 usbotg_reset.dev = dev;
221 usbotg_reset.id = args.args[0];
223 reset_assert(&usbotg_reset);
225 reset_deassert(&usbotg_reset);
228 ret = fdtdec_parse_phandle_with_args(blob, node, "phys",
229 "#phy-cells", 0, 0, &args);
231 phy_provider = fdt_parent_offset(blob, args.node);
232 ret = uclass_get_device_by_of_offset(UCLASS_PHY,
238 phy.id = fdtdec_get_uint(blob, args.node, "reg", -1);
240 ret = generic_phy_power_on(&phy);
242 debug("unable to power on the phy\n");
246 ret = generic_phy_init(&phy);
248 debug("failed to init usb phy\n");
253 /* Parse and store data needed for gadget */
254 stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
255 if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) {
256 debug("usbotg: can't get base address\n");
261 stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node,
262 "g-rx-fifo-size", 0);
263 stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node,
264 "g-np-tx-fifo-size", 0);
265 stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node,
266 "g-tx-fifo-size", 0);
267 /* Enable voltage level detector */
268 if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply",
269 NULL, 0, 0, &args))) {
270 if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR,
272 ret = regulator_set_enable(dev, true);
274 debug("Failed to enable usb33d\n");
279 /* Enable vbus sensing */
280 setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO,
281 STM32MP_GGPIO_VBUS_SENSING);
283 return dwc2_udc_probe(&stm32mp_otg_data);
286 generic_phy_exit(&phy);
289 generic_phy_power_off(&phy);
297 int board_usb_cleanup(int index, enum usb_init_type init)
300 reset_assert(&usbotg_reset);
302 reset_deassert(&usbotg_reset);
307 static void sysconf_init(void)
309 #ifndef CONFIG_STM32MP1_TRUSTED
311 #ifdef CONFIG_DM_REGULATOR
312 struct udevice *pwr_dev;
313 struct udevice *pwr_reg;
320 syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
322 /* interconnect update : select master using the port 1 */
325 /* today information is hardcoded in U-Boot */
326 writel(BIT(9), syscfg + SYSCFG_ICNR);
328 /* disable Pull-Down for boot pin connected to VDD */
329 bootr = readl(syscfg + SYSCFG_BOOTR);
330 bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
331 bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
332 writel(bootr, syscfg + SYSCFG_BOOTR);
334 #ifdef CONFIG_DM_REGULATOR
335 /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
336 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
337 * The customer will have to disable this for low frequencies
338 * or if AFMUX is selected but the function not used, typically for
339 * TRACE. Otherwise, impact on power consumption.
342 * enabling High Speed mode while VDD>2.7V
343 * with the OTP product_below_2v5 (OTP 18, BIT 13)
344 * erroneously set to 1 can damage the IC!
345 * => U-Boot set the register only if VDD < 2.7V (in DT)
346 * but this value need to be consistent with board design
348 ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev);
350 ret = uclass_get_device_by_driver(UCLASS_MISC,
351 DM_GET_DRIVER(stm32mp_bsec),
354 pr_err("Can't find stm32mp_bsec driver\n");
358 ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
362 /* get VDD = pwr-supply */
363 ret = device_get_supply_regulator(pwr_dev, "pwr-supply",
366 /* check if VDD is Low Voltage */
368 if (regulator_get_value(pwr_reg) < 2700000) {
369 writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
370 SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
371 SYSCFG_IOCTRLSETR_HSLVEN_ETH |
372 SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
373 SYSCFG_IOCTRLSETR_HSLVEN_SPI,
374 syscfg + SYSCFG_IOCTRLSETR);
377 pr_err("product_below_2v5=0: HSLVEN protected by HW\n");
380 pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
383 debug("VDD unknown");
388 /* activate automatic I/O compensation
389 * warning: need to ensure CSI enabled and ready in clock driver
391 writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
393 while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY))
395 clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
399 /* board dependent setup after realloc */
402 /* address of boot parameters */
403 gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
409 if (IS_ENABLED(CONFIG_LED))
415 int board_late_init(void)
417 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
418 const void *fdt_compat;
421 fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
423 if (fdt_compat && fdt_compat_len) {
424 if (strncmp(fdt_compat, "st,", 3) != 0)
425 env_set("board_name", fdt_compat);
427 env_set("board_name", fdt_compat + 3);