1 /*
2 * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <common.h>
8 #include <clk.h>
9 #include <dm/ofnode.h>
10 #include <generic-phy.h>
11 #include <reset.h>
12 #include <asm/io.h>
13 #include <dm.h>
14 #include "ehci.h"
15 #include <power/regulator.h>
16
17 /*
18 * Even though here we don't explicitly use "struct ehci_ctrl"
19 * ehci_register() expects it to be the first thing that resides in
20 * device's private data.
21 */
22 struct generic_ehci {
23 struct ehci_ctrl ctrl;
24 struct clk *clocks;
25 struct reset_ctl *resets;
26 struct phy phy;
27 #ifdef CONFIG_DM_REGULATOR
28 struct udevice *vbus_supply;
29 #endif
30 int clock_count;
31 int reset_count;
32 };
33
34 #ifdef CONFIG_DM_REGULATOR
ehci_enable_vbus_supply(struct udevice * dev)35 static int ehci_enable_vbus_supply(struct udevice *dev)
36 {
37 struct generic_ehci *priv = dev_get_priv(dev);
38 int ret;
39
40 ret = device_get_supply_regulator(dev, "vbus-supply",
41 &priv->vbus_supply);
42 if (ret && ret != -ENOENT)
43 return ret;
44
45 if (priv->vbus_supply) {
46 ret = regulator_set_enable(priv->vbus_supply, true);
47 if (ret) {
48 dev_err(dev, "Error enabling VBUS supply\n");
49 return ret;
50 }
51 } else {
52 dev_dbg(dev, "No vbus supply\n");
53 }
54
55 return 0;
56 }
57
ehci_disable_vbus_supply(struct generic_ehci * priv)58 static int ehci_disable_vbus_supply(struct generic_ehci *priv)
59 {
60 if (priv->vbus_supply)
61 return regulator_set_enable(priv->vbus_supply, false);
62 else
63 return 0;
64 }
65 #else
ehci_enable_vbus_supply(struct udevice * dev)66 static int ehci_enable_vbus_supply(struct udevice *dev)
67 {
68 return 0;
69 }
70
ehci_disable_vbus_supply(struct generic_ehci * priv)71 static int ehci_disable_vbus_supply(struct generic_ehci *priv)
72 {
73 return 0;
74 }
75 #endif
76
ehci_usb_probe(struct udevice * dev)77 static int ehci_usb_probe(struct udevice *dev)
78 {
79 struct generic_ehci *priv = dev_get_priv(dev);
80 struct ehci_hccr *hccr;
81 struct ehci_hcor *hcor;
82 int i, err, ret, clock_nb, reset_nb;
83
84 err = 0;
85 priv->clock_count = 0;
86 clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
87 "#clock-cells");
88 if (clock_nb > 0) {
89 priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
90 GFP_KERNEL);
91 if (!priv->clocks)
92 return -ENOMEM;
93
94 for (i = 0; i < clock_nb; i++) {
95 err = clk_get_by_index(dev, i, &priv->clocks[i]);
96
97 if (err < 0)
98 break;
99 err = clk_enable(&priv->clocks[i]);
100 if (err && err != -ENOSYS) {
101 dev_err(dev, "failed to enable clock %d\n", i);
102 clk_free(&priv->clocks[i]);
103 goto clk_err;
104 }
105 priv->clock_count++;
106 }
107 } else {
108 if (clock_nb != -ENOENT) {
109 dev_err(dev, "failed to get clock phandle(%d)\n",
110 clock_nb);
111 return clock_nb;
112 }
113 }
114
115 priv->reset_count = 0;
116 reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
117 "#reset-cells");
118 if (reset_nb > 0) {
119 priv->resets = devm_kcalloc(dev, reset_nb,
120 sizeof(struct reset_ctl),
121 GFP_KERNEL);
122 if (!priv->resets)
123 return -ENOMEM;
124
125 for (i = 0; i < reset_nb; i++) {
126 err = reset_get_by_index(dev, i, &priv->resets[i]);
127 if (err < 0)
128 break;
129
130 if (reset_deassert(&priv->resets[i])) {
131 dev_err(dev, "failed to deassert reset %d\n",
132 i);
133 reset_free(&priv->resets[i]);
134 goto reset_err;
135 }
136 priv->reset_count++;
137 }
138 } else {
139 if (reset_nb != -ENOENT) {
140 dev_err(dev, "failed to get reset phandle(%d)\n",
141 reset_nb);
142 goto clk_err;
143 }
144 }
145
146 err = ehci_enable_vbus_supply(dev);
147 if (err)
148 goto reset_err;
149
150 err = ehci_setup_phy(dev, &priv->phy, 0);
151 if (err)
152 goto regulator_err;
153
154 hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE);
155 hcor = (struct ehci_hcor *)((uintptr_t)hccr +
156 HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
157
158 err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
159 if (err)
160 goto phy_err;
161
162 return 0;
163
164 phy_err:
165 ret = ehci_shutdown_phy(dev, &priv->phy);
166 if (ret)
167 dev_err(dev, "failed to shutdown usb phy\n");
168
169 regulator_err:
170 ret = ehci_disable_vbus_supply(priv);
171 if (ret)
172 dev_err(dev, "failed to disable VBUS supply\n");
173
174 reset_err:
175 ret = reset_release_all(priv->resets, priv->reset_count);
176 if (ret)
177 dev_err(dev, "failed to assert all resets\n");
178 clk_err:
179 ret = clk_release_all(priv->clocks, priv->clock_count);
180 if (ret)
181 dev_err(dev, "failed to disable all clocks\n");
182
183 return err;
184 }
185
ehci_usb_remove(struct udevice * dev)186 static int ehci_usb_remove(struct udevice *dev)
187 {
188 struct generic_ehci *priv = dev_get_priv(dev);
189 int ret;
190
191 ret = ehci_deregister(dev);
192 if (ret)
193 return ret;
194
195 ret = ehci_shutdown_phy(dev, &priv->phy);
196 if (ret)
197 return ret;
198
199 ret = ehci_disable_vbus_supply(priv);
200 if (ret)
201 return ret;
202
203 ret = reset_release_all(priv->resets, priv->reset_count);
204 if (ret)
205 return ret;
206
207 return clk_release_all(priv->clocks, priv->clock_count);
208 }
209
210 static const struct udevice_id ehci_usb_ids[] = {
211 { .compatible = "generic-ehci" },
212 { }
213 };
214
215 U_BOOT_DRIVER(ehci_generic) = {
216 .name = "ehci_generic",
217 .id = UCLASS_USB,
218 .of_match = ehci_usb_ids,
219 .probe = ehci_usb_probe,
220 .remove = ehci_usb_remove,
221 .ops = &ehci_usb_ops,
222 .priv_auto_alloc_size = sizeof(struct generic_ehci),
223 .flags = DM_FLAG_ALLOC_PRIV_DMA,
224 };
225