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