1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
9 #include <generic-phy.h>
15 #include <asm/arch/stm32.h>
18 #include <power/regulator.h>
19 #include <usb/dwc2_udc.h>
22 * Get a global data pointer
24 DECLARE_GLOBAL_DATA_PTR;
26 #define STM32MP_GUSBCFG 0x40002407
28 #define STM32MP_GGPIO 0x38
29 #define STM32MP_GGPIO_VBUS_SENSING BIT(21)
37 const char *fdt_compat;
40 if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
45 printf("Board: stm32mp1 in %s mode", mode);
46 fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
48 if (fdt_compat && fdt_compat_len)
49 printf(" (%s)", fdt_compat);
52 ret = uclass_get_device_by_driver(UCLASS_MISC,
53 DM_GET_DRIVER(stm32mp_bsec),
57 ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
60 printf("Board: MB%04x Var%d Rev.%c-%02d\n",
63 ((otp >> 8) & 0xF) - 1 + 'A',
70 static void board_key_check(void)
72 #if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
74 struct gpio_desc gpio;
75 enum forced_boot_mode boot_mode = BOOT_NORMAL;
77 node = ofnode_path("/config");
78 if (!ofnode_valid(node)) {
79 debug("%s: no /config node?\n", __func__);
82 #ifdef CONFIG_FASTBOOT
83 if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
84 &gpio, GPIOD_IS_IN)) {
85 debug("%s: could not find a /config/st,fastboot-gpios\n",
88 if (dm_gpio_get_value(&gpio)) {
89 puts("Fastboot key pressed, ");
90 boot_mode = BOOT_FASTBOOT;
93 dm_gpio_free(NULL, &gpio);
96 #ifdef CONFIG_CMD_STM32PROG
97 if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
98 &gpio, GPIOD_IS_IN)) {
99 debug("%s: could not find a /config/st,stm32prog-gpios\n",
102 if (dm_gpio_get_value(&gpio)) {
103 puts("STM32Programmer key pressed, ");
104 boot_mode = BOOT_STM32PROG;
106 dm_gpio_free(NULL, &gpio);
110 if (boot_mode != BOOT_NORMAL) {
111 puts("entering download mode...\n");
112 clrsetbits_le32(TAMP_BOOT_CONTEXT,
113 TAMP_BOOT_FORCED_MASK,
119 static struct dwc2_plat_otg_data stm32mp_otg_data = {
120 .usb_gusbcfg = STM32MP_GUSBCFG,
123 static struct reset_ctl usbotg_reset;
125 int board_usb_init(int index, enum usb_init_type init)
127 struct fdtdec_phandle_args args;
129 const void *blob = gd->fdt_blob;
136 /* find the usb otg node */
137 node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
139 debug("Not found usb_otg device\n");
143 if (!fdtdec_get_is_enabled(blob, node)) {
144 debug("stm32 usbotg is disabled in the device tree\n");
149 ret = fdtdec_parse_phandle_with_args(blob, node, "clocks",
150 "#clock-cells", 0, 0, &args);
152 debug("usbotg has no clocks defined in the device tree\n");
156 ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev);
160 if (args.args_count != 1) {
161 debug("Can't find clock ID in the device tree\n");
166 clk.id = args.args[0];
168 ret = clk_enable(&clk);
170 debug("Failed to enable usbotg clock\n");
175 ret = fdtdec_parse_phandle_with_args(blob, node, "resets",
176 "#reset-cells", 0, 0, &args);
178 debug("usbotg has no resets defined in the device tree\n");
182 ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev);
183 if (ret || args.args_count != 1)
186 usbotg_reset.dev = dev;
187 usbotg_reset.id = args.args[0];
189 reset_assert(&usbotg_reset);
191 reset_deassert(&usbotg_reset);
194 ret = fdtdec_parse_phandle_with_args(blob, node, "phys",
195 "#phy-cells", 0, 0, &args);
197 phy_provider = fdt_parent_offset(blob, args.node);
198 ret = uclass_get_device_by_of_offset(UCLASS_PHY,
204 phy.id = fdtdec_get_uint(blob, args.node, "reg", -1);
206 ret = generic_phy_power_on(&phy);
208 debug("unable to power on the phy\n");
212 ret = generic_phy_init(&phy);
214 debug("failed to init usb phy\n");
219 /* Parse and store data needed for gadget */
220 stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
221 if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) {
222 debug("usbotg: can't get base address\n");
227 stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node,
228 "g-rx-fifo-size", 0);
229 stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node,
230 "g-np-tx-fifo-size", 0);
231 stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node,
232 "g-tx-fifo-size", 0);
233 /* Enable voltage level detector */
234 if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply",
235 NULL, 0, 0, &args))) {
236 if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR,
238 ret = regulator_set_enable(dev, true);
240 debug("Failed to enable usb33d\n");
245 /* Enable vbus sensing */
246 setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO,
247 STM32MP_GGPIO_VBUS_SENSING);
249 return dwc2_udc_probe(&stm32mp_otg_data);
252 generic_phy_exit(&phy);
255 generic_phy_power_off(&phy);
263 int board_usb_cleanup(int index, enum usb_init_type init)
266 reset_assert(&usbotg_reset);
268 reset_deassert(&usbotg_reset);
273 /* board dependent setup after realloc */
276 /* address of boot parameters */
277 gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
281 if (IS_ENABLED(CONFIG_LED))
287 int board_late_init(void)
289 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
290 const void *fdt_compat;
293 fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
295 if (fdt_compat && fdt_compat_len) {
296 if (strncmp(fdt_compat, "st,", 3) != 0)
297 env_set("board_name", fdt_compat);
299 env_set("board_name", fdt_compat + 3);