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