1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * dwc3-of-simple.c - OF glue layer for simple integrations
4 *
5 * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
6 *
7 * Author: Felipe Balbi <balbi@ti.com>
8 *
9 * Copyright (C) 2018 BayLibre, SAS
10 * Author: Neil Armstrong <narmstron@baylibre.com>
11 */
12
13 #include <common.h>
14 #include <dm.h>
15 #include <reset.h>
16 #include <clk.h>
17
18 struct dwc3_of_simple {
19 struct clk_bulk clks;
20 struct reset_ctl_bulk resets;
21 };
22
dwc3_of_simple_reset_init(struct udevice * dev,struct dwc3_of_simple * simple)23 static int dwc3_of_simple_reset_init(struct udevice *dev,
24 struct dwc3_of_simple *simple)
25 {
26 int ret;
27
28 ret = reset_get_bulk(dev, &simple->resets);
29 if (ret == -ENOTSUPP)
30 return 0;
31 else if (ret)
32 return ret;
33
34 ret = reset_deassert_bulk(&simple->resets);
35 if (ret) {
36 reset_release_bulk(&simple->resets);
37 return ret;
38 }
39
40 return 0;
41 }
42
dwc3_of_simple_clk_init(struct udevice * dev,struct dwc3_of_simple * simple)43 static int dwc3_of_simple_clk_init(struct udevice *dev,
44 struct dwc3_of_simple *simple)
45 {
46 int ret;
47
48 ret = clk_get_bulk(dev, &simple->clks);
49 if (ret == -ENOSYS)
50 return 0;
51 if (ret)
52 return ret;
53
54 #if CONFIG_IS_ENABLED(CLK)
55 ret = clk_enable_bulk(&simple->clks);
56 if (ret) {
57 clk_release_bulk(&simple->clks);
58 return ret;
59 }
60 #endif
61
62 return 0;
63 }
64
dwc3_of_simple_probe(struct udevice * dev)65 static int dwc3_of_simple_probe(struct udevice *dev)
66 {
67 struct dwc3_of_simple *simple = dev_get_plat(dev);
68 int ret;
69
70 ret = dwc3_of_simple_clk_init(dev, simple);
71 if (ret)
72 return ret;
73
74 ret = dwc3_of_simple_reset_init(dev, simple);
75 if (ret)
76 return ret;
77
78 return 0;
79 }
80
dwc3_of_simple_remove(struct udevice * dev)81 static int dwc3_of_simple_remove(struct udevice *dev)
82 {
83 struct dwc3_of_simple *simple = dev_get_plat(dev);
84
85 reset_release_bulk(&simple->resets);
86
87 clk_release_bulk(&simple->clks);
88
89 return dm_scan_fdt_dev(dev);
90 }
91
92 static const struct udevice_id dwc3_of_simple_ids[] = {
93 { .compatible = "amlogic,meson-gxl-dwc3" },
94 { .compatible = "rockchip,rk3399-dwc3" },
95 { .compatible = "ti,dwc3" },
96 { }
97 };
98
99 U_BOOT_DRIVER(dwc3_of_simple) = {
100 .name = "dwc3-of-simple",
101 .id = UCLASS_SIMPLE_BUS,
102 .of_match = dwc3_of_simple_ids,
103 .probe = dwc3_of_simple_probe,
104 .remove = dwc3_of_simple_remove,
105 .plat_auto = sizeof(struct dwc3_of_simple),
106 .flags = DM_FLAG_ALLOC_PRIV_DMA,
107 };
108