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>
17 #include <power/regulator.h>
18 #include <usb/dwc2_udc.h>
21 * Get a global data pointer
23 DECLARE_GLOBAL_DATA_PTR;
25 #define STM32MP_GUSBCFG 0x40002407
27 #define STM32MP_GGPIO 0x38
28 #define STM32MP_GGPIO_VBUS_SENSING BIT(21)
36 const char *fdt_compat;
39 if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
44 printf("Board: stm32mp1 in %s mode", mode);
45 fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
47 if (fdt_compat && fdt_compat_len)
48 printf(" (%s)", fdt_compat);
51 ret = uclass_get_device_by_driver(UCLASS_MISC,
52 DM_GET_DRIVER(stm32mp_bsec),
56 ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
59 printf("Board: MB%04x Var%d Rev.%c-%02d\n",
62 ((otp >> 8) & 0xF) - 1 + 'A',
69 static struct dwc2_plat_otg_data stm32mp_otg_data = {
70 .usb_gusbcfg = STM32MP_GUSBCFG,
73 static struct reset_ctl usbotg_reset;
75 int board_usb_init(int index, enum usb_init_type init)
77 struct fdtdec_phandle_args args;
79 const void *blob = gd->fdt_blob;
86 /* find the usb otg node */
87 node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
89 debug("Not found usb_otg device\n");
93 if (!fdtdec_get_is_enabled(blob, node)) {
94 debug("stm32 usbotg is disabled in the device tree\n");
99 ret = fdtdec_parse_phandle_with_args(blob, node, "clocks",
100 "#clock-cells", 0, 0, &args);
102 debug("usbotg has no clocks defined in the device tree\n");
106 ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev);
110 if (args.args_count != 1) {
111 debug("Can't find clock ID in the device tree\n");
116 clk.id = args.args[0];
118 ret = clk_enable(&clk);
120 debug("Failed to enable usbotg clock\n");
125 ret = fdtdec_parse_phandle_with_args(blob, node, "resets",
126 "#reset-cells", 0, 0, &args);
128 debug("usbotg has no resets defined in the device tree\n");
132 ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev);
133 if (ret || args.args_count != 1)
136 usbotg_reset.dev = dev;
137 usbotg_reset.id = args.args[0];
139 reset_assert(&usbotg_reset);
141 reset_deassert(&usbotg_reset);
144 ret = fdtdec_parse_phandle_with_args(blob, node, "phys",
145 "#phy-cells", 0, 0, &args);
147 phy_provider = fdt_parent_offset(blob, args.node);
148 ret = uclass_get_device_by_of_offset(UCLASS_PHY,
154 phy.id = fdtdec_get_uint(blob, args.node, "reg", -1);
156 ret = generic_phy_power_on(&phy);
158 debug("unable to power on the phy\n");
162 ret = generic_phy_init(&phy);
164 debug("failed to init usb phy\n");
169 /* Parse and store data needed for gadget */
170 stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
171 if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) {
172 debug("usbotg: can't get base address\n");
177 stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node,
178 "g-rx-fifo-size", 0);
179 stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node,
180 "g-np-tx-fifo-size", 0);
181 stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node,
182 "g-tx-fifo-size", 0);
183 /* Enable voltage level detector */
184 if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply",
185 NULL, 0, 0, &args))) {
186 if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR,
188 ret = regulator_set_enable(dev, true);
190 debug("Failed to enable usb33d\n");
195 /* Enable vbus sensing */
196 setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO,
197 STM32MP_GGPIO_VBUS_SENSING);
199 return dwc2_udc_probe(&stm32mp_otg_data);
202 generic_phy_exit(&phy);
205 generic_phy_power_off(&phy);
213 int board_usb_cleanup(int index, enum usb_init_type init)
216 reset_assert(&usbotg_reset);
218 reset_deassert(&usbotg_reset);
223 int board_late_init(void)
228 /* board dependent setup after realloc */
231 /* address of boot parameters */
232 gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
234 if (IS_ENABLED(CONFIG_LED))