blob: 21e4f637bb150fb527c3f01fc641010c1eef5c74 [file] [log] [blame]
Neil Armstrong1f708892019-02-19 13:42:01 +01001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Amlogic G12A DWC3 Glue layer
4 *
5 * Copyright (C) 2019 BayLibre, SAS
6 * Author: Neil Armstrong <narmstrong@baylibre.com>
7 */
8
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Neil Armstrong1f708892019-02-19 13:42:01 +010010#include <dm.h>
11#include <dm/device-internal.h>
12#include <dm/lists.h>
13#include <dwc3-uboot.h>
14#include <generic-phy.h>
Simon Glassdbd79542020-05-10 11:40:11 -060015#include <linux/delay.h>
Igor Prusov89606c02023-11-14 14:02:56 +030016#include <linux/io.h>
Simon Glassbdd5f812023-09-14 18:21:46 -060017#include <linux/printk.h>
Neil Armstrong1f708892019-02-19 13:42:01 +010018#include <linux/usb/ch9.h>
19#include <linux/usb/gadget.h>
20#include <malloc.h>
21#include <regmap.h>
22#include <usb.h>
23#include "core.h"
24#include "gadget.h"
25#include <reset.h>
26#include <clk.h>
27#include <power/regulator.h>
28#include <linux/bitfield.h>
29#include <linux/bitops.h>
30#include <linux/compat.h>
Alexey Romanova9c58e42023-10-05 11:54:28 +030031#include <dt-bindings/clock/amlogic,a1-peripherals-clkc.h>
Neil Armstrong1f708892019-02-19 13:42:01 +010032
33/* USB2 Ports Control Registers */
34
35#define U2P_REG_SIZE 0x20
36
37#define U2P_R0 0x0
38 #define U2P_R0_HOST_DEVICE BIT(0)
39 #define U2P_R0_POWER_OK BIT(1)
40 #define U2P_R0_HAST_MODE BIT(2)
41 #define U2P_R0_POWER_ON_RESET BIT(3)
42 #define U2P_R0_ID_PULLUP BIT(4)
43 #define U2P_R0_DRV_VBUS BIT(5)
44
45#define U2P_R1 0x4
46 #define U2P_R1_PHY_READY BIT(0)
47 #define U2P_R1_ID_DIG BIT(1)
48 #define U2P_R1_OTG_SESSION_VALID BIT(2)
49 #define U2P_R1_VBUS_VALID BIT(3)
50
51/* USB Glue Control Registers */
52
53#define USB_R0 0x80
54 #define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17)
55 #define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18)
56 #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19)
57 #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29)
58 #define USB_R0_U2D_ACT BIT(31)
59
60#define USB_R1 0x84
61 #define USB_R1_U3H_BIGENDIAN_GS BIT(0)
62 #define USB_R1_U3H_PME_ENABLE BIT(1)
63 #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(4, 2)
64 #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK GENMASK(9, 7)
65 #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK GENMASK(13, 12)
66 #define USB_R1_U3H_HOST_U3_PORT_DISABLE BIT(16)
67 #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT BIT(17)
68 #define USB_R1_U3H_HOST_MSI_ENABLE BIT(18)
69 #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19)
70 #define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25)
71
72#define USB_R2 0x88
73 #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20)
74 #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26)
75
76#define USB_R3 0x8c
77 #define USB_R3_P30_SSC_ENABLE BIT(0)
78 #define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1)
79 #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4)
80 #define USB_R3_P30_REF_SSP_EN BIT(13)
81
82#define USB_R4 0x90
83 #define USB_R4_P21_PORT_RESET_0 BIT(0)
84 #define USB_R4_P21_SLEEP_M0 BIT(1)
85 #define USB_R4_MEM_PD_MASK GENMASK(3, 2)
86 #define USB_R4_P21_ONLY BIT(4)
87
88#define USB_R5 0x94
89 #define USB_R5_ID_DIG_SYNC BIT(0)
90 #define USB_R5_ID_DIG_REG BIT(1)
91 #define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2)
92 #define USB_R5_ID_DIG_EN_0 BIT(4)
93 #define USB_R5_ID_DIG_EN_1 BIT(5)
94 #define USB_R5_ID_DIG_CURR BIT(6)
95 #define USB_R5_ID_DIG_IRQ BIT(7)
96 #define USB_R5_ID_DIG_TH_MASK GENMASK(15, 8)
97 #define USB_R5_ID_DIG_CNT_MASK GENMASK(23, 16)
98
99enum {
100 USB2_HOST_PHY = 0,
101 USB2_OTG_PHY,
102 USB3_HOST_PHY,
103 PHY_COUNT,
104};
105
Alexey Romanova9c58e42023-10-05 11:54:28 +0300106static const char *const dwc3_meson_g12a_phy_names[] = {
Neil Armstrong1f708892019-02-19 13:42:01 +0100107 "usb2-phy0", "usb2-phy1", "usb3-phy0",
108};
109
Alexey Romanova9c58e42023-10-05 11:54:28 +0300110static const char *const dwc3_meson_a1_phy_names[] = {
111 "usb2-phy0", "usb2-phy1"
112};
113
114struct dwc3_meson_g12a;
115
116struct dwc3_meson_g12a_drvdata {
117 const char *const *phy_names;
118 unsigned int phy_cnt;
119 int (*clk_init)(struct dwc3_meson_g12a *priv);
120};
121
Neil Armstrong1f708892019-02-19 13:42:01 +0100122struct dwc3_meson_g12a {
123 struct udevice *dev;
124 struct regmap *regmap;
125 struct clk clk;
126 struct reset_ctl reset;
127 struct phy phys[PHY_COUNT];
128 enum usb_dr_mode otg_mode;
129 enum usb_dr_mode otg_phy_mode;
130 unsigned int usb2_ports;
131 unsigned int usb3_ports;
132#if CONFIG_IS_ENABLED(DM_REGULATOR)
133 struct udevice *vbus_supply;
134#endif
Alexey Romanova9c58e42023-10-05 11:54:28 +0300135 struct dwc3_meson_g12a_drvdata *drvdata;
Neil Armstrong1f708892019-02-19 13:42:01 +0100136};
137
138#define U2P_REG_SIZE 0x20
139#define USB_REG_OFFSET 0x80
140
141static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv,
142 int i, enum usb_dr_mode mode)
143{
144 switch (mode) {
145 case USB_DR_MODE_HOST:
146 case USB_DR_MODE_OTG:
147 case USB_DR_MODE_UNKNOWN:
148 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
149 U2P_R0_HOST_DEVICE,
150 U2P_R0_HOST_DEVICE);
151 break;
152
153 case USB_DR_MODE_PERIPHERAL:
154 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
155 U2P_R0_HOST_DEVICE, 0);
156 break;
157 }
158}
159
160static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
161{
162 int i;
163
164 if (priv->otg_mode == USB_DR_MODE_PERIPHERAL)
165 priv->otg_phy_mode = USB_DR_MODE_PERIPHERAL;
166 else
167 priv->otg_phy_mode = USB_DR_MODE_HOST;
168
169 for (i = 0 ; i < USB3_HOST_PHY ; ++i) {
170 if (!priv->phys[i].dev)
171 continue;
172
173 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
174 U2P_R0_POWER_ON_RESET,
175 U2P_R0_POWER_ON_RESET);
176
177 if (i == USB2_OTG_PHY) {
178 regmap_update_bits(priv->regmap,
179 U2P_R0 + (U2P_REG_SIZE * i),
180 U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
181 U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
182
183 dwc3_meson_g12a_usb2_set_mode(priv, i,
184 priv->otg_phy_mode);
185 } else
186 dwc3_meson_g12a_usb2_set_mode(priv, i,
187 USB_DR_MODE_HOST);
188
189 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
190 U2P_R0_POWER_ON_RESET, 0);
191 }
192
193 return 0;
194}
195
196static void dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a *priv)
197{
198 regmap_update_bits(priv->regmap, USB_R3,
199 USB_R3_P30_SSC_RANGE_MASK |
200 USB_R3_P30_REF_SSP_EN,
201 USB_R3_P30_SSC_ENABLE |
202 FIELD_PREP(USB_R3_P30_SSC_RANGE_MASK, 2) |
203 USB_R3_P30_REF_SSP_EN);
204 udelay(2);
205
206 regmap_update_bits(priv->regmap, USB_R2,
207 USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK,
208 FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 0x15));
209
210 regmap_update_bits(priv->regmap, USB_R2,
211 USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK,
212 FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 0x20));
213
214 udelay(2);
215
216 regmap_update_bits(priv->regmap, USB_R1,
217 USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT,
218 USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT);
219
220 regmap_update_bits(priv->regmap, USB_R1,
221 USB_R1_P30_PCS_TX_SWING_FULL_MASK,
222 FIELD_PREP(USB_R1_P30_PCS_TX_SWING_FULL_MASK, 127));
223}
224
225static void dwc3_meson_g12a_usb_init_mode(struct dwc3_meson_g12a *priv)
226{
227 if (priv->otg_phy_mode == USB_DR_MODE_PERIPHERAL) {
228 regmap_update_bits(priv->regmap, USB_R0,
229 USB_R0_U2D_ACT, USB_R0_U2D_ACT);
230 regmap_update_bits(priv->regmap, USB_R0,
231 USB_R0_U2D_SS_SCALEDOWN_MODE_MASK, 0);
232 regmap_update_bits(priv->regmap, USB_R4,
233 USB_R4_P21_SLEEP_M0, USB_R4_P21_SLEEP_M0);
234 } else {
235 regmap_update_bits(priv->regmap, USB_R0,
236 USB_R0_U2D_ACT, 0);
237 regmap_update_bits(priv->regmap, USB_R4,
238 USB_R4_P21_SLEEP_M0, 0);
239 }
240}
241
242static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
243{
244 int ret;
245
246 ret = dwc3_meson_g12a_usb2_init(priv);
247 if (ret)
248 return ret;
249
250 regmap_update_bits(priv->regmap, USB_R1,
251 USB_R1_U3H_FLADJ_30MHZ_REG_MASK,
252 FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20));
253
254 regmap_update_bits(priv->regmap, USB_R5,
255 USB_R5_ID_DIG_EN_0,
256 USB_R5_ID_DIG_EN_0);
257 regmap_update_bits(priv->regmap, USB_R5,
258 USB_R5_ID_DIG_EN_1,
259 USB_R5_ID_DIG_EN_1);
260 regmap_update_bits(priv->regmap, USB_R5,
261 USB_R5_ID_DIG_TH_MASK,
262 FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff));
263
264 /* If we have an actual SuperSpeed port, initialize it */
265 if (priv->usb3_ports)
266 dwc3_meson_g12a_usb3_init(priv);
267
268 dwc3_meson_g12a_usb_init_mode(priv);
269
270 return 0;
271}
272
273int dwc3_meson_g12a_force_mode(struct udevice *dev, enum usb_dr_mode mode)
274{
Simon Glassfa20e932020-12-03 16:55:20 -0700275 struct dwc3_meson_g12a *priv = dev_get_plat(dev);
Neil Armstrong1f708892019-02-19 13:42:01 +0100276
277 if (!priv)
278 return -EINVAL;
279
280 if (mode != USB_DR_MODE_HOST && mode != USB_DR_MODE_PERIPHERAL)
281 return -EINVAL;
282
283 if (!priv->phys[USB2_OTG_PHY].dev)
284 return -EINVAL;
285
Neil Armstrong1f708892019-02-19 13:42:01 +0100286 if (mode == USB_DR_MODE_HOST)
287 debug("%s: switching to Host Mode\n", __func__);
288 else
289 debug("%s: switching to Device Mode\n", __func__);
290
291#if CONFIG_IS_ENABLED(DM_REGULATOR)
292 if (priv->vbus_supply) {
293 int ret = regulator_set_enable(priv->vbus_supply,
294 (mode == USB_DR_MODE_PERIPHERAL));
295 if (ret)
296 return ret;
297 }
298#endif
299 priv->otg_phy_mode = mode;
300
301 dwc3_meson_g12a_usb2_set_mode(priv, USB2_OTG_PHY, mode);
302
303 dwc3_meson_g12a_usb_init_mode(priv);
304
305 return 0;
306}
307
308static int dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a *priv)
309{
Alexey Romanova9c58e42023-10-05 11:54:28 +0300310 struct dwc3_meson_g12a_drvdata *data = priv->drvdata;
Neil Armstrong1f708892019-02-19 13:42:01 +0100311 int i, ret;
312
Alexey Romanova9c58e42023-10-05 11:54:28 +0300313 for (i = 0 ; i < data->phy_cnt; ++i) {
314 ret = generic_phy_get_by_name(priv->dev, data->phy_names[i],
Neil Armstrong1f708892019-02-19 13:42:01 +0100315 &priv->phys[i]);
Neil Armstrongf2a1bed2021-05-05 10:38:57 +0200316 if (ret == -ENOENT || ret == -ENODATA)
Neil Armstrong1f708892019-02-19 13:42:01 +0100317 continue;
318
319 if (ret)
320 return ret;
321
322 if (i == USB3_HOST_PHY)
323 priv->usb3_ports++;
324 else
325 priv->usb2_ports++;
326 }
327
328 debug("%s: usb2 ports: %d\n", __func__, priv->usb2_ports);
329 debug("%s: usb3 ports: %d\n", __func__, priv->usb3_ports);
330
331 return 0;
332}
333
334static int dwc3_meson_g12a_reset_init(struct dwc3_meson_g12a *priv)
335{
336 int ret;
337
338 ret = reset_get_by_index(priv->dev, 0, &priv->reset);
339 if (ret)
340 return ret;
341
342 ret = reset_assert(&priv->reset);
343 udelay(1);
344 ret |= reset_deassert(&priv->reset);
345 if (ret) {
346 reset_free(&priv->reset);
347 return ret;
348 }
349
350 return 0;
351}
352
353static int dwc3_meson_g12a_clk_init(struct dwc3_meson_g12a *priv)
354{
355 int ret;
356
357 ret = clk_get_by_index(priv->dev, 0, &priv->clk);
358 if (ret)
359 return ret;
360
361#if CONFIG_IS_ENABLED(CLK)
362 ret = clk_enable(&priv->clk);
Sean Andersond318eb32023-12-16 14:38:42 -0500363 if (ret)
Neil Armstrong1f708892019-02-19 13:42:01 +0100364 return ret;
Neil Armstrong1f708892019-02-19 13:42:01 +0100365#endif
366
367 return 0;
368}
369
Alexey Romanova9c58e42023-10-05 11:54:28 +0300370static int dwc3_meson_a1_clk_init(struct dwc3_meson_g12a *priv)
371{
372 int ret;
373
374 ret = clk_get_by_name(priv->dev, "usb_bus", &priv->clk);
375 if (ret)
376 return ret;
377
378 ret = clk_enable(&priv->clk);
379 if (ret)
380 return ret;
381
382 return 0;
383}
384
Neil Armstrong1f708892019-02-19 13:42:01 +0100385static int dwc3_meson_g12a_probe(struct udevice *dev)
386{
Simon Glassfa20e932020-12-03 16:55:20 -0700387 struct dwc3_meson_g12a *priv = dev_get_plat(dev);
Alexey Romanova9c58e42023-10-05 11:54:28 +0300388 struct dwc3_meson_g12a_drvdata *data =
389 (struct dwc3_meson_g12a_drvdata *)dev_get_driver_data(dev);
Neil Armstrong1f708892019-02-19 13:42:01 +0100390 int ret, i;
391
Alexey Romanova9c58e42023-10-05 11:54:28 +0300392 priv->drvdata = data;
Neil Armstrong1f708892019-02-19 13:42:01 +0100393 priv->dev = dev;
394
395 ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
396 if (ret)
397 return ret;
398
Alexey Romanova9c58e42023-10-05 11:54:28 +0300399 ret = data->clk_init(priv);
Neil Armstrong1f708892019-02-19 13:42:01 +0100400 if (ret)
401 return ret;
402
403 ret = dwc3_meson_g12a_reset_init(priv);
404 if (ret)
405 return ret;
406
407 ret = dwc3_meson_g12a_get_phys(priv);
408 if (ret)
409 return ret;
410
411#if CONFIG_IS_ENABLED(DM_REGULATOR)
412 ret = device_get_supply_regulator(dev, "vbus-supply",
413 &priv->vbus_supply);
414 if (ret && ret != -ENOENT) {
415 pr_err("Failed to get PHY regulator\n");
416 return ret;
417 }
418
419 if (priv->vbus_supply) {
420 ret = regulator_set_enable(priv->vbus_supply, true);
421 if (ret)
422 return ret;
423 }
424#endif
425
Simon Glassa7ece582020-12-19 10:40:14 -0700426 priv->otg_mode = usb_get_dr_mode(dev_ofnode(dev));
Neil Armstrong1f708892019-02-19 13:42:01 +0100427
428 ret = dwc3_meson_g12a_usb_init(priv);
429 if (ret)
430 return ret;
431
Alexey Romanova9c58e42023-10-05 11:54:28 +0300432 for (i = 0 ; i < data->phy_cnt; ++i) {
Neil Armstrong1f708892019-02-19 13:42:01 +0100433 if (!priv->phys[i].dev)
434 continue;
435
436 ret = generic_phy_init(&priv->phys[i]);
437 if (ret)
438 goto err_phy_init;
439 }
440
Alexey Romanova9c58e42023-10-05 11:54:28 +0300441 for (i = 0; i < data->phy_cnt; ++i) {
Neil Armstronga29def22020-04-21 10:17:42 +0200442 if (!priv->phys[i].dev)
443 continue;
444
445 ret = generic_phy_power_on(&priv->phys[i]);
446 if (ret)
447 goto err_phy_init;
448 }
449
Neil Armstrong1f708892019-02-19 13:42:01 +0100450 return 0;
451
452err_phy_init:
Alexey Romanova9c58e42023-10-05 11:54:28 +0300453 for (i = 0 ; i < data->phy_cnt ; ++i) {
Neil Armstrong1f708892019-02-19 13:42:01 +0100454 if (!priv->phys[i].dev)
455 continue;
456
457 generic_phy_exit(&priv->phys[i]);
458 }
459
460 return ret;
461}
462
463static int dwc3_meson_g12a_remove(struct udevice *dev)
464{
Simon Glassfa20e932020-12-03 16:55:20 -0700465 struct dwc3_meson_g12a *priv = dev_get_plat(dev);
Alexey Romanova9c58e42023-10-05 11:54:28 +0300466 struct dwc3_meson_g12a_drvdata *data = priv->drvdata;
Neil Armstrong1f708892019-02-19 13:42:01 +0100467 int i;
468
469 reset_release_all(&priv->reset, 1);
470
471 clk_release_all(&priv->clk, 1);
472
Alexey Romanova9c58e42023-10-05 11:54:28 +0300473 for (i = 0; i < data->phy_cnt; ++i) {
Neil Armstronga29def22020-04-21 10:17:42 +0200474 if (!priv->phys[i].dev)
475 continue;
476
477 generic_phy_power_off(&priv->phys[i]);
478 }
479
Alexey Romanova9c58e42023-10-05 11:54:28 +0300480 for (i = 0 ; i < data->phy_cnt; ++i) {
Neil Armstrong1f708892019-02-19 13:42:01 +0100481 if (!priv->phys[i].dev)
482 continue;
483
484 generic_phy_exit(&priv->phys[i]);
485 }
486
487 return dm_scan_fdt_dev(dev);
488}
489
Alexey Romanova9c58e42023-10-05 11:54:28 +0300490static const struct dwc3_meson_g12a_drvdata meson_g12a_drvdata = {
491 .phy_names = dwc3_meson_g12a_phy_names,
492 .phy_cnt = ARRAY_SIZE(dwc3_meson_g12a_phy_names),
493 .clk_init = dwc3_meson_g12a_clk_init,
494};
495
496static const struct dwc3_meson_g12a_drvdata meson_a1_drvdata = {
497 .phy_names = dwc3_meson_a1_phy_names,
498 .phy_cnt = ARRAY_SIZE(dwc3_meson_a1_phy_names),
499 .clk_init = dwc3_meson_a1_clk_init,
500};
501
Mattijs Korpershoek9f9828d2022-11-23 16:42:49 +0100502static int dwc3_meson_g12a_child_pre_probe(struct udevice *dev)
503{
504 if (ofnode_device_is_compatible(dev_ofnode(dev), "amlogic,meson-g12a-usb"))
505 return dwc3_meson_g12a_force_mode(dev->parent, USB_DR_MODE_PERIPHERAL);
506
Alexey Romanova9c58e42023-10-05 11:54:28 +0300507 if (ofnode_device_is_compatible(dev_ofnode(dev), "amlogic,meson-a1-usb"))
508 return dwc3_meson_g12a_force_mode(dev->parent, USB_DR_MODE_PERIPHERAL);
509
Mattijs Korpershoek9f9828d2022-11-23 16:42:49 +0100510 return 0;
511}
512
513static int dwc3_meson_g12a_child_post_remove(struct udevice *dev)
514{
515 if (ofnode_device_is_compatible(dev_ofnode(dev), "amlogic,meson-g12a-usb"))
516 return dwc3_meson_g12a_force_mode(dev->parent, USB_DR_MODE_HOST);
517
Alexey Romanova9c58e42023-10-05 11:54:28 +0300518 if (ofnode_device_is_compatible(dev_ofnode(dev), "amlogic,meson-a1-usb"))
519 return dwc3_meson_g12a_force_mode(dev->parent, USB_DR_MODE_HOST);
520
Mattijs Korpershoek9f9828d2022-11-23 16:42:49 +0100521 return 0;
522}
523
Neil Armstrong1f708892019-02-19 13:42:01 +0100524static const struct udevice_id dwc3_meson_g12a_ids[] = {
Alexey Romanova9c58e42023-10-05 11:54:28 +0300525 {
526 .compatible = "amlogic,meson-g12a-usb-ctrl",
527 .data = (ulong)&meson_g12a_drvdata,
528 },
529 {
530 .compatible = "amlogic,meson-a1-usb-ctrl",
531 .data = (ulong)&meson_a1_drvdata,
532 },
Neil Armstrong1f708892019-02-19 13:42:01 +0100533 { }
534};
535
536U_BOOT_DRIVER(dwc3_generic_wrapper) = {
537 .name = "dwc3-meson-g12a",
538 .id = UCLASS_SIMPLE_BUS,
539 .of_match = dwc3_meson_g12a_ids,
540 .probe = dwc3_meson_g12a_probe,
541 .remove = dwc3_meson_g12a_remove,
Mattijs Korpershoek9f9828d2022-11-23 16:42:49 +0100542 .child_pre_probe = dwc3_meson_g12a_child_pre_probe,
543 .child_post_remove = dwc3_meson_g12a_child_post_remove,
Simon Glass71fa5b42020-12-03 16:55:18 -0700544 .plat_auto = sizeof(struct dwc3_meson_g12a),
Neil Armstrong1f708892019-02-19 13:42:01 +0100545
546};