]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/usb/dwc3/dwc3-meson-g12a.c
usb: cdns3: remove redundant assignment to pointer trb
[mirror_ubuntu-jammy-kernel.git] / drivers / usb / dwc3 / dwc3-meson-g12a.c
CommitLineData
c9999337
NA
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * USB Glue for Amlogic G12A SoCs
4 *
5 * Copyright (c) 2019 BayLibre, SAS
6 * Author: Neil Armstrong <narmstrong@baylibre.com>
7 */
8
9/*
10 * The USB is organized with a glue around the DWC3 Controller IP as :
11 * - Control registers for each USB2 Ports
12 * - Control registers for the USB PHY layer
13 * - SuperSpeed PHY can be enabled only if port is used
f90db107 14 * - Dynamic OTG switching with ID change interrupt
c9999337
NA
15 */
16
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/platform_device.h>
20#include <linux/clk.h>
21#include <linux/of.h>
22#include <linux/of_platform.h>
23#include <linux/pm_runtime.h>
24#include <linux/regmap.h>
25#include <linux/bitfield.h>
26#include <linux/bitops.h>
27#include <linux/reset.h>
28#include <linux/phy/phy.h>
29#include <linux/usb/otg.h>
30#include <linux/usb/role.h>
31#include <linux/regulator/consumer.h>
32
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
106static const char *phy_names[PHY_COUNT] = {
107 "usb2-phy0", "usb2-phy1", "usb3-phy0",
108};
109
1e355f21
HL
110static struct clk_bulk_data meson_g12a_clocks[] = {
111 { .id = NULL },
112};
113
114static struct clk_bulk_data meson_a1_clocks[] = {
115 { .id = "usb_ctrl" },
116 { .id = "usb_bus" },
117 { .id = "xtal_usb_ctrl" },
118};
119
120struct dwc3_meson_g12a_drvdata {
121 bool otg_switch_supported;
122 struct clk_bulk_data *clks;
123 int num_clks;
124};
125
126static struct dwc3_meson_g12a_drvdata g12a_drvdata = {
127 .otg_switch_supported = true,
128 .clks = meson_g12a_clocks,
129 .num_clks = ARRAY_SIZE(meson_g12a_clocks),
130};
131
132static struct dwc3_meson_g12a_drvdata a1_drvdata = {
133 .otg_switch_supported = false,
134 .clks = meson_a1_clocks,
135 .num_clks = ARRAY_SIZE(meson_a1_clocks),
136};
137
c9999337
NA
138struct dwc3_meson_g12a {
139 struct device *dev;
140 struct regmap *regmap;
c9999337
NA
141 struct reset_control *reset;
142 struct phy *phys[PHY_COUNT];
143 enum usb_dr_mode otg_mode;
144 enum phy_mode otg_phy_mode;
145 unsigned int usb2_ports;
146 unsigned int usb3_ports;
147 struct regulator *vbus;
148 struct usb_role_switch_desc switch_desc;
149 struct usb_role_switch *role_switch;
1e355f21 150 const struct dwc3_meson_g12a_drvdata *drvdata;
c9999337
NA
151};
152
153static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv,
154 int i, enum phy_mode mode)
155{
156 if (mode == PHY_MODE_USB_HOST)
157 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
158 U2P_R0_HOST_DEVICE,
159 U2P_R0_HOST_DEVICE);
160 else
161 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
162 U2P_R0_HOST_DEVICE, 0);
163}
164
165static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
166{
167 int i;
168
169 if (priv->otg_mode == USB_DR_MODE_PERIPHERAL)
170 priv->otg_phy_mode = PHY_MODE_USB_DEVICE;
171 else
172 priv->otg_phy_mode = PHY_MODE_USB_HOST;
173
174 for (i = 0 ; i < USB3_HOST_PHY ; ++i) {
175 if (!priv->phys[i])
176 continue;
177
178 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
179 U2P_R0_POWER_ON_RESET,
180 U2P_R0_POWER_ON_RESET);
181
1e355f21 182 if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) {
c9999337
NA
183 regmap_update_bits(priv->regmap,
184 U2P_R0 + (U2P_REG_SIZE * i),
185 U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
186 U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
187
188 dwc3_meson_g12a_usb2_set_mode(priv, i,
189 priv->otg_phy_mode);
190 } else
191 dwc3_meson_g12a_usb2_set_mode(priv, i,
192 PHY_MODE_USB_HOST);
193
194 regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
195 U2P_R0_POWER_ON_RESET, 0);
196 }
197
198 return 0;
199}
200
201static void dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a *priv)
202{
203 regmap_update_bits(priv->regmap, USB_R3,
204 USB_R3_P30_SSC_RANGE_MASK |
205 USB_R3_P30_REF_SSP_EN,
206 USB_R3_P30_SSC_ENABLE |
207 FIELD_PREP(USB_R3_P30_SSC_RANGE_MASK, 2) |
208 USB_R3_P30_REF_SSP_EN);
209 udelay(2);
210
211 regmap_update_bits(priv->regmap, USB_R2,
212 USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK,
213 FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 0x15));
214
215 regmap_update_bits(priv->regmap, USB_R2,
216 USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK,
217 FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 0x20));
218
219 udelay(2);
220
221 regmap_update_bits(priv->regmap, USB_R1,
222 USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT,
223 USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT);
224
225 regmap_update_bits(priv->regmap, USB_R1,
226 USB_R1_P30_PCS_TX_SWING_FULL_MASK,
227 FIELD_PREP(USB_R1_P30_PCS_TX_SWING_FULL_MASK, 127));
228}
229
230static void dwc3_meson_g12a_usb_otg_apply_mode(struct dwc3_meson_g12a *priv)
231{
232 if (priv->otg_phy_mode == PHY_MODE_USB_DEVICE) {
233 regmap_update_bits(priv->regmap, USB_R0,
234 USB_R0_U2D_ACT, USB_R0_U2D_ACT);
235 regmap_update_bits(priv->regmap, USB_R0,
236 USB_R0_U2D_SS_SCALEDOWN_MODE_MASK, 0);
237 regmap_update_bits(priv->regmap, USB_R4,
238 USB_R4_P21_SLEEP_M0, USB_R4_P21_SLEEP_M0);
239 } else {
240 regmap_update_bits(priv->regmap, USB_R0,
241 USB_R0_U2D_ACT, 0);
242 regmap_update_bits(priv->regmap, USB_R4,
243 USB_R4_P21_SLEEP_M0, 0);
244 }
245}
246
247static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
248{
249 int ret;
250
251 ret = dwc3_meson_g12a_usb2_init(priv);
252 if (ret)
253 return ret;
254
255 regmap_update_bits(priv->regmap, USB_R1,
256 USB_R1_U3H_FLADJ_30MHZ_REG_MASK,
257 FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20));
258
259 regmap_update_bits(priv->regmap, USB_R5,
260 USB_R5_ID_DIG_EN_0,
261 USB_R5_ID_DIG_EN_0);
262 regmap_update_bits(priv->regmap, USB_R5,
263 USB_R5_ID_DIG_EN_1,
264 USB_R5_ID_DIG_EN_1);
265 regmap_update_bits(priv->regmap, USB_R5,
266 USB_R5_ID_DIG_TH_MASK,
267 FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff));
268
269 /* If we have an actual SuperSpeed port, initialize it */
270 if (priv->usb3_ports)
271 dwc3_meson_g12a_usb3_init(priv);
272
273 dwc3_meson_g12a_usb_otg_apply_mode(priv);
274
275 return 0;
276}
277
278static const struct regmap_config phy_meson_g12a_usb3_regmap_conf = {
279 .reg_bits = 8,
280 .val_bits = 32,
281 .reg_stride = 4,
282 .max_register = USB_R5,
283};
284
285static int dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a *priv)
286{
287 int i;
288
289 for (i = 0 ; i < PHY_COUNT ; ++i) {
290 priv->phys[i] = devm_phy_optional_get(priv->dev, phy_names[i]);
291 if (!priv->phys[i])
292 continue;
293
294 if (IS_ERR(priv->phys[i]))
295 return PTR_ERR(priv->phys[i]);
296
297 if (i == USB3_HOST_PHY)
298 priv->usb3_ports++;
299 else
300 priv->usb2_ports++;
301 }
302
303 dev_info(priv->dev, "USB2 ports: %d\n", priv->usb2_ports);
304 dev_info(priv->dev, "USB3 ports: %d\n", priv->usb3_ports);
305
306 return 0;
307}
308
309static enum phy_mode dwc3_meson_g12a_get_id(struct dwc3_meson_g12a *priv)
310{
311 u32 reg;
312
313 regmap_read(priv->regmap, USB_R5, &reg);
314
315 if (reg & (USB_R5_ID_DIG_SYNC | USB_R5_ID_DIG_REG))
316 return PHY_MODE_USB_DEVICE;
317
318 return PHY_MODE_USB_HOST;
319}
320
321static int dwc3_meson_g12a_otg_mode_set(struct dwc3_meson_g12a *priv,
322 enum phy_mode mode)
323{
324 int ret;
325
1e355f21 326 if (!priv->drvdata->otg_switch_supported || !priv->phys[USB2_OTG_PHY])
c9999337
NA
327 return -EINVAL;
328
329 if (mode == PHY_MODE_USB_HOST)
330 dev_info(priv->dev, "switching to Host Mode\n");
331 else
332 dev_info(priv->dev, "switching to Device Mode\n");
333
334 if (priv->vbus) {
335 if (mode == PHY_MODE_USB_DEVICE)
336 ret = regulator_disable(priv->vbus);
337 else
338 ret = regulator_enable(priv->vbus);
339 if (ret)
340 return ret;
341 }
342
343 priv->otg_phy_mode = mode;
344
345 dwc3_meson_g12a_usb2_set_mode(priv, USB2_OTG_PHY, mode);
346
347 dwc3_meson_g12a_usb_otg_apply_mode(priv);
348
349 return 0;
350}
351
352static int dwc3_meson_g12a_role_set(struct device *dev, enum usb_role role)
353{
354 struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
355 enum phy_mode mode;
356
357 if (role == USB_ROLE_NONE)
358 return 0;
359
360 mode = (role == USB_ROLE_HOST) ? PHY_MODE_USB_HOST
361 : PHY_MODE_USB_DEVICE;
362
363 if (mode == priv->otg_phy_mode)
364 return 0;
365
366 return dwc3_meson_g12a_otg_mode_set(priv, mode);
367}
368
369static enum usb_role dwc3_meson_g12a_role_get(struct device *dev)
370{
371 struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
372
373 return priv->otg_phy_mode == PHY_MODE_USB_HOST ?
374 USB_ROLE_HOST : USB_ROLE_DEVICE;
375}
376
f90db107
NA
377static irqreturn_t dwc3_meson_g12a_irq_thread(int irq, void *data)
378{
379 struct dwc3_meson_g12a *priv = data;
380 enum phy_mode otg_id;
381
382 otg_id = dwc3_meson_g12a_get_id(priv);
383 if (otg_id != priv->otg_phy_mode) {
384 if (dwc3_meson_g12a_otg_mode_set(priv, otg_id))
385 dev_warn(priv->dev, "Failed to switch OTG mode\n");
386 }
387
388 regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_IRQ, 0);
389
390 return IRQ_HANDLED;
391}
392
c9999337
NA
393static struct device *dwc3_meson_g12_find_child(struct device *dev,
394 const char *compatible)
395{
396 struct platform_device *pdev;
397 struct device_node *np;
398
399 np = of_get_compatible_child(dev->of_node, compatible);
400 if (!np)
401 return NULL;
402
403 pdev = of_find_device_by_node(np);
404 of_node_put(np);
405 if (!pdev)
406 return NULL;
407
408 return &pdev->dev;
409}
410
1e355f21
HL
411static int dwc3_meson_g12a_otg_init(struct platform_device *pdev,
412 struct dwc3_meson_g12a *priv)
413{
414 enum phy_mode otg_id;
415 int ret, irq;
416 struct device *dev = &pdev->dev;
417
418 if (!priv->drvdata->otg_switch_supported)
419 return 0;
420
421 if (priv->otg_mode == USB_DR_MODE_OTG) {
422 /* Ack irq before registering */
423 regmap_update_bits(priv->regmap, USB_R5,
424 USB_R5_ID_DIG_IRQ, 0);
425
426 irq = platform_get_irq(pdev, 0);
427 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
428 dwc3_meson_g12a_irq_thread,
429 IRQF_ONESHOT, pdev->name, priv);
430 if (ret)
431 return ret;
432 }
433
434 /* Setup OTG mode corresponding to the ID pin */
435 if (priv->otg_mode == USB_DR_MODE_OTG) {
436 otg_id = dwc3_meson_g12a_get_id(priv);
437 if (otg_id != priv->otg_phy_mode) {
438 if (dwc3_meson_g12a_otg_mode_set(priv, otg_id))
439 dev_warn(dev, "Failed to switch OTG mode\n");
440 }
441 }
442
443 /* Setup role switcher */
444 priv->switch_desc.usb2_port = dwc3_meson_g12_find_child(dev,
445 "snps,dwc3");
446 priv->switch_desc.udc = dwc3_meson_g12_find_child(dev, "snps,dwc2");
447 priv->switch_desc.allow_userspace_control = true;
448 priv->switch_desc.set = dwc3_meson_g12a_role_set;
449 priv->switch_desc.get = dwc3_meson_g12a_role_get;
450
451 priv->role_switch = usb_role_switch_register(dev, &priv->switch_desc);
452 if (IS_ERR(priv->role_switch))
453 dev_warn(dev, "Unable to register Role Switch\n");
454
455 return ret;
456}
457
c9999337
NA
458static int dwc3_meson_g12a_probe(struct platform_device *pdev)
459{
460 struct dwc3_meson_g12a *priv;
461 struct device *dev = &pdev->dev;
462 struct device_node *np = dev->of_node;
463 void __iomem *base;
1e355f21 464 int ret, i;
c9999337
NA
465
466 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
467 if (!priv)
468 return -ENOMEM;
469
c6e4999c 470 base = devm_platform_ioremap_resource(pdev, 0);
c9999337
NA
471 if (IS_ERR(base))
472 return PTR_ERR(base);
473
474 priv->regmap = devm_regmap_init_mmio(dev, base,
475 &phy_meson_g12a_usb3_regmap_conf);
476 if (IS_ERR(priv->regmap))
477 return PTR_ERR(priv->regmap);
478
479 priv->vbus = devm_regulator_get_optional(dev, "vbus");
480 if (IS_ERR(priv->vbus)) {
481 if (PTR_ERR(priv->vbus) == -EPROBE_DEFER)
482 return PTR_ERR(priv->vbus);
483 priv->vbus = NULL;
484 }
485
1e355f21 486 priv->drvdata = of_device_get_match_data(&pdev->dev);
c9999337 487
1e355f21
HL
488 ret = devm_clk_bulk_get(dev,
489 priv->drvdata->num_clks,
490 priv->drvdata->clks);
c9999337
NA
491 if (ret)
492 return ret;
493
1e355f21
HL
494 ret = clk_bulk_prepare_enable(priv->drvdata->num_clks,
495 priv->drvdata->clks);
496 if (ret)
497 return ret;
c9999337
NA
498
499 platform_set_drvdata(pdev, priv);
500 priv->dev = dev;
501
502 priv->reset = devm_reset_control_get(dev, NULL);
503 if (IS_ERR(priv->reset)) {
504 ret = PTR_ERR(priv->reset);
505 dev_err(dev, "failed to get device reset, err=%d\n", ret);
506 return ret;
507 }
508
509 ret = reset_control_reset(priv->reset);
510 if (ret)
1e355f21 511 goto err_disable_clks;
c9999337
NA
512
513 ret = dwc3_meson_g12a_get_phys(priv);
514 if (ret)
1e355f21 515 goto err_disable_clks;
c9999337
NA
516
517 if (priv->vbus) {
518 ret = regulator_enable(priv->vbus);
519 if (ret)
1e355f21 520 goto err_disable_clks;
c9999337
NA
521 }
522
523 /* Get dr_mode */
524 priv->otg_mode = usb_get_dr_mode(dev);
525
526 dwc3_meson_g12a_usb_init(priv);
527
528 /* Init PHYs */
529 for (i = 0 ; i < PHY_COUNT ; ++i) {
530 ret = phy_init(priv->phys[i]);
531 if (ret)
1e355f21 532 goto err_disable_clks;
c9999337
NA
533 }
534
535 /* Set PHY Power */
536 for (i = 0 ; i < PHY_COUNT ; ++i) {
537 ret = phy_power_on(priv->phys[i]);
538 if (ret)
539 goto err_phys_exit;
540 }
541
542 ret = of_platform_populate(np, NULL, NULL, dev);
1e355f21 543 if (ret)
c9999337 544 goto err_phys_power;
c9999337 545
1e355f21
HL
546 ret = dwc3_meson_g12a_otg_init(pdev, priv);
547 if (ret)
548 goto err_phys_power;
c9999337
NA
549
550 pm_runtime_set_active(dev);
551 pm_runtime_enable(dev);
552 pm_runtime_get_sync(dev);
553
554 return 0;
555
556err_phys_power:
557 for (i = 0 ; i < PHY_COUNT ; ++i)
558 phy_power_off(priv->phys[i]);
559
560err_phys_exit:
561 for (i = 0 ; i < PHY_COUNT ; ++i)
562 phy_exit(priv->phys[i]);
563
1e355f21
HL
564err_disable_clks:
565 clk_bulk_disable_unprepare(priv->drvdata->num_clks,
566 priv->drvdata->clks);
567
c9999337
NA
568 return ret;
569}
570
571static int dwc3_meson_g12a_remove(struct platform_device *pdev)
572{
573 struct dwc3_meson_g12a *priv = platform_get_drvdata(pdev);
574 struct device *dev = &pdev->dev;
575 int i;
576
1e355f21
HL
577 if (priv->drvdata->otg_switch_supported)
578 usb_role_switch_unregister(priv->role_switch);
c9999337
NA
579
580 of_platform_depopulate(dev);
581
582 for (i = 0 ; i < PHY_COUNT ; ++i) {
583 phy_power_off(priv->phys[i]);
584 phy_exit(priv->phys[i]);
585 }
586
587 pm_runtime_disable(dev);
588 pm_runtime_put_noidle(dev);
589 pm_runtime_set_suspended(dev);
590
1e355f21
HL
591 clk_bulk_disable_unprepare(priv->drvdata->num_clks,
592 priv->drvdata->clks);
593
c9999337
NA
594 return 0;
595}
596
597static int __maybe_unused dwc3_meson_g12a_runtime_suspend(struct device *dev)
598{
599 struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
600
1e355f21
HL
601 clk_bulk_disable_unprepare(priv->drvdata->num_clks,
602 priv->drvdata->clks);
c9999337
NA
603
604 return 0;
605}
606
607static int __maybe_unused dwc3_meson_g12a_runtime_resume(struct device *dev)
608{
609 struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
610
1e355f21
HL
611 return clk_bulk_prepare_enable(priv->drvdata->num_clks,
612 priv->drvdata->clks);
c9999337
NA
613}
614
615static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev)
616{
617 struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
1cf084d1
NA
618 int i, ret;
619
620 if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) {
621 ret = regulator_disable(priv->vbus);
622 if (ret)
623 return ret;
624 }
c9999337
NA
625
626 for (i = 0 ; i < PHY_COUNT ; ++i) {
627 phy_power_off(priv->phys[i]);
628 phy_exit(priv->phys[i]);
629 }
630
631 reset_control_assert(priv->reset);
632
633 return 0;
634}
635
636static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
637{
638 struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
639 int i, ret;
640
641 reset_control_deassert(priv->reset);
642
643 dwc3_meson_g12a_usb_init(priv);
644
645 /* Init PHYs */
646 for (i = 0 ; i < PHY_COUNT ; ++i) {
647 ret = phy_init(priv->phys[i]);
648 if (ret)
649 return ret;
650 }
651
652 /* Set PHY Power */
653 for (i = 0 ; i < PHY_COUNT ; ++i) {
654 ret = phy_power_on(priv->phys[i]);
655 if (ret)
656 return ret;
657 }
658
1cf084d1
NA
659 if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) {
660 ret = regulator_enable(priv->vbus);
661 if (ret)
662 return ret;
663 }
664
c9999337
NA
665 return 0;
666}
667
668static const struct dev_pm_ops dwc3_meson_g12a_dev_pm_ops = {
669 SET_SYSTEM_SLEEP_PM_OPS(dwc3_meson_g12a_suspend, dwc3_meson_g12a_resume)
670 SET_RUNTIME_PM_OPS(dwc3_meson_g12a_runtime_suspend,
671 dwc3_meson_g12a_runtime_resume, NULL)
672};
673
674static const struct of_device_id dwc3_meson_g12a_match[] = {
1e355f21
HL
675 {
676 .compatible = "amlogic,meson-g12a-usb-ctrl",
677 .data = &g12a_drvdata,
678 },
679 {
680 .compatible = "amlogic,meson-a1-usb-ctrl",
681 .data = &a1_drvdata,
682 },
c9999337
NA
683 { /* Sentinel */ }
684};
685MODULE_DEVICE_TABLE(of, dwc3_meson_g12a_match);
686
687static struct platform_driver dwc3_meson_g12a_driver = {
688 .probe = dwc3_meson_g12a_probe,
689 .remove = dwc3_meson_g12a_remove,
690 .driver = {
691 .name = "dwc3-meson-g12a",
692 .of_match_table = dwc3_meson_g12a_match,
693 .pm = &dwc3_meson_g12a_dev_pm_ops,
694 },
695};
696
697module_platform_driver(dwc3_meson_g12a_driver);
698MODULE_LICENSE("GPL v2");
699MODULE_DESCRIPTION("Amlogic Meson G12A USB Glue Layer");
700MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");