forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/usb/host/ehci-mv.c
....@@ -11,62 +11,64 @@
1111 #include <linux/clk.h>
1212 #include <linux/err.h>
1313 #include <linux/usb/otg.h>
14
+#include <linux/usb/of.h>
1415 #include <linux/platform_data/mv_usb.h>
16
+#include <linux/io.h>
17
+
18
+#include <linux/usb/hcd.h>
19
+
20
+#include "ehci.h"
21
+
22
+/* registers */
23
+#define U2x_CAPREGS_OFFSET 0x100
1524
1625 #define CAPLENGTH_MASK (0xff)
1726
18
-struct ehci_hcd_mv {
19
- struct usb_hcd *hcd;
27
+#define hcd_to_ehci_hcd_mv(h) ((struct ehci_hcd_mv *)hcd_to_ehci(h)->priv)
2028
29
+struct ehci_hcd_mv {
2130 /* Which mode does this ehci running OTG/Host ? */
2231 int mode;
2332
24
- void __iomem *phy_regs;
33
+ void __iomem *base;
2534 void __iomem *cap_regs;
2635 void __iomem *op_regs;
2736
2837 struct usb_phy *otg;
29
-
30
- struct mv_usb_platform_data *pdata;
31
-
3238 struct clk *clk;
39
+
40
+ struct phy *phy;
41
+
42
+ int (*set_vbus)(unsigned int vbus);
3343 };
34
-
35
-static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv)
36
-{
37
- clk_prepare_enable(ehci_mv->clk);
38
-}
39
-
40
-static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv)
41
-{
42
- clk_disable_unprepare(ehci_mv->clk);
43
-}
4444
4545 static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv)
4646 {
4747 int retval;
4848
49
- ehci_clock_enable(ehci_mv);
50
- if (ehci_mv->pdata->phy_init) {
51
- retval = ehci_mv->pdata->phy_init(ehci_mv->phy_regs);
52
- if (retval)
53
- return retval;
54
- }
49
+ retval = clk_prepare_enable(ehci_mv->clk);
50
+ if (retval)
51
+ return retval;
5552
56
- return 0;
53
+ retval = phy_init(ehci_mv->phy);
54
+ if (retval)
55
+ clk_disable_unprepare(ehci_mv->clk);
56
+
57
+ return retval;
5758 }
5859
5960 static void mv_ehci_disable(struct ehci_hcd_mv *ehci_mv)
6061 {
61
- if (ehci_mv->pdata->phy_deinit)
62
- ehci_mv->pdata->phy_deinit(ehci_mv->phy_regs);
63
- ehci_clock_disable(ehci_mv);
62
+ phy_exit(ehci_mv->phy);
63
+ clk_disable_unprepare(ehci_mv->clk);
6464 }
6565
6666 static int mv_ehci_reset(struct usb_hcd *hcd)
6767 {
6868 struct device *dev = hcd->self.controller;
69
- struct ehci_hcd_mv *ehci_mv = dev_get_drvdata(dev);
69
+ struct ehci_hcd_mv *ehci_mv = hcd_to_ehci_hcd_mv(hcd);
70
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
71
+ u32 status;
7072 int retval;
7173
7274 if (ehci_mv == NULL) {
....@@ -80,49 +82,22 @@
8082 if (retval)
8183 dev_err(dev, "ehci_setup failed %d\n", retval);
8284
85
+ if (of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC) {
86
+ status = ehci_readl(ehci, &ehci->regs->port_status[0]);
87
+ status |= PORT_TEST_FORCE;
88
+ ehci_writel(ehci, status, &ehci->regs->port_status[0]);
89
+ status &= ~PORT_TEST_FORCE;
90
+ ehci_writel(ehci, status, &ehci->regs->port_status[0]);
91
+ }
92
+
8393 return retval;
8494 }
8595
86
-static const struct hc_driver mv_ehci_hc_driver = {
87
- .description = hcd_name,
88
- .product_desc = "Marvell EHCI",
89
- .hcd_priv_size = sizeof(struct ehci_hcd),
96
+static struct hc_driver __read_mostly ehci_platform_hc_driver;
9097
91
- /*
92
- * generic hardware linkage
93
- */
94
- .irq = ehci_irq,
95
- .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
96
-
97
- /*
98
- * basic lifecycle operations
99
- */
100
- .reset = mv_ehci_reset,
101
- .start = ehci_run,
102
- .stop = ehci_stop,
103
- .shutdown = ehci_shutdown,
104
-
105
- /*
106
- * managing i/o requests and associated device resources
107
- */
108
- .urb_enqueue = ehci_urb_enqueue,
109
- .urb_dequeue = ehci_urb_dequeue,
110
- .endpoint_disable = ehci_endpoint_disable,
111
- .endpoint_reset = ehci_endpoint_reset,
112
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
113
-
114
- /*
115
- * scheduling support
116
- */
117
- .get_frame_number = ehci_get_frame,
118
-
119
- /*
120
- * root hub support
121
- */
122
- .hub_status_data = ehci_hub_status_data,
123
- .hub_control = ehci_hub_control,
124
- .bus_suspend = ehci_bus_suspend,
125
- .bus_resume = ehci_bus_resume,
98
+static const struct ehci_driver_overrides platform_overrides __initconst = {
99
+ .reset = mv_ehci_reset,
100
+ .extra_priv_size = sizeof(struct ehci_hcd_mv),
126101 };
127102
128103 static int mv_ehci_probe(struct platform_device *pdev)
....@@ -132,30 +107,33 @@
132107 struct ehci_hcd *ehci;
133108 struct ehci_hcd_mv *ehci_mv;
134109 struct resource *r;
135
- int retval = -ENODEV;
110
+ int retval;
136111 u32 offset;
137
-
138
- if (!pdata) {
139
- dev_err(&pdev->dev, "missing platform_data\n");
140
- return -ENODEV;
141
- }
112
+ u32 status;
142113
143114 if (usb_disabled())
144115 return -ENODEV;
145116
146
- hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci");
117
+ hcd = usb_create_hcd(&ehci_platform_hc_driver, &pdev->dev, dev_name(&pdev->dev));
147118 if (!hcd)
148119 return -ENOMEM;
149120
150
- ehci_mv = devm_kzalloc(&pdev->dev, sizeof(*ehci_mv), GFP_KERNEL);
151
- if (ehci_mv == NULL) {
152
- retval = -ENOMEM;
153
- goto err_put_hcd;
121
+ platform_set_drvdata(pdev, hcd);
122
+ ehci_mv = hcd_to_ehci_hcd_mv(hcd);
123
+
124
+ ehci_mv->mode = MV_USB_MODE_HOST;
125
+ if (pdata) {
126
+ ehci_mv->mode = pdata->mode;
127
+ ehci_mv->set_vbus = pdata->set_vbus;
154128 }
155129
156
- platform_set_drvdata(pdev, ehci_mv);
157
- ehci_mv->pdata = pdata;
158
- ehci_mv->hcd = hcd;
130
+ ehci_mv->phy = devm_phy_optional_get(&pdev->dev, "usb");
131
+ if (IS_ERR(ehci_mv->phy)) {
132
+ retval = PTR_ERR(ehci_mv->phy);
133
+ if (retval != -EPROBE_DEFER)
134
+ dev_err(&pdev->dev, "Failed to get phy.\n");
135
+ goto err_put_hcd;
136
+ }
159137
160138 ehci_mv->clk = devm_clk_get(&pdev->dev, NULL);
161139 if (IS_ERR(ehci_mv->clk)) {
....@@ -164,17 +142,10 @@
164142 goto err_put_hcd;
165143 }
166144
167
- r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs");
168
- ehci_mv->phy_regs = devm_ioremap_resource(&pdev->dev, r);
169
- if (IS_ERR(ehci_mv->phy_regs)) {
170
- retval = PTR_ERR(ehci_mv->phy_regs);
171
- goto err_put_hcd;
172
- }
173
-
174
- r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs");
175
- ehci_mv->cap_regs = devm_ioremap_resource(&pdev->dev, r);
176
- if (IS_ERR(ehci_mv->cap_regs)) {
177
- retval = PTR_ERR(ehci_mv->cap_regs);
145
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
146
+ ehci_mv->base = devm_ioremap_resource(&pdev->dev, r);
147
+ if (IS_ERR(ehci_mv->base)) {
148
+ retval = PTR_ERR(ehci_mv->base);
178149 goto err_put_hcd;
179150 }
180151
....@@ -184,6 +155,8 @@
184155 goto err_put_hcd;
185156 }
186157
158
+ ehci_mv->cap_regs =
159
+ (void __iomem *) ((unsigned long) ehci_mv->base + U2x_CAPREGS_OFFSET);
187160 offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK;
188161 ehci_mv->op_regs =
189162 (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset);
....@@ -198,9 +171,8 @@
198171 hcd->irq = retval;
199172
200173 ehci = hcd_to_ehci(hcd);
201
- ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs;
174
+ ehci->caps = (struct ehci_caps __iomem *) ehci_mv->cap_regs;
202175
203
- ehci_mv->mode = pdata->mode;
204176 if (ehci_mv->mode == MV_USB_MODE_OTG) {
205177 ehci_mv->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
206178 if (IS_ERR(ehci_mv->otg)) {
....@@ -225,8 +197,8 @@
225197 /* otg will enable clock before use as host */
226198 mv_ehci_disable(ehci_mv);
227199 } else {
228
- if (pdata->set_vbus)
229
- pdata->set_vbus(1);
200
+ if (ehci_mv->set_vbus)
201
+ ehci_mv->set_vbus(1);
230202
231203 retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
232204 if (retval) {
....@@ -237,8 +209,13 @@
237209 device_wakeup_enable(hcd->self.controller);
238210 }
239211
240
- if (pdata->private_init)
241
- pdata->private_init(ehci_mv->op_regs, ehci_mv->phy_regs);
212
+ if (of_usb_get_phy_mode(pdev->dev.of_node) == USBPHY_INTERFACE_MODE_HSIC) {
213
+ status = ehci_readl(ehci, &ehci->regs->port_status[0]);
214
+ /* These "reserved" bits actually enable HSIC mode. */
215
+ status |= BIT(25);
216
+ status &= ~GENMASK(31, 30);
217
+ ehci_writel(ehci, status, &ehci->regs->port_status[0]);
218
+ }
242219
243220 dev_info(&pdev->dev,
244221 "successful find EHCI device with regs 0x%p irq %d"
....@@ -248,8 +225,8 @@
248225 return 0;
249226
250227 err_set_vbus:
251
- if (pdata->set_vbus)
252
- pdata->set_vbus(0);
228
+ if (ehci_mv->set_vbus)
229
+ ehci_mv->set_vbus(0);
253230 err_disable_clk:
254231 mv_ehci_disable(ehci_mv);
255232 err_put_hcd:
....@@ -260,8 +237,8 @@
260237
261238 static int mv_ehci_remove(struct platform_device *pdev)
262239 {
263
- struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev);
264
- struct usb_hcd *hcd = ehci_mv->hcd;
240
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
241
+ struct ehci_hcd_mv *ehci_mv = hcd_to_ehci_hcd_mv(hcd);
265242
266243 if (hcd->rh_registered)
267244 usb_remove_hcd(hcd);
....@@ -270,8 +247,8 @@
270247 otg_set_host(ehci_mv->otg->otg, NULL);
271248
272249 if (ehci_mv->mode == MV_USB_MODE_HOST) {
273
- if (ehci_mv->pdata->set_vbus)
274
- ehci_mv->pdata->set_vbus(0);
250
+ if (ehci_mv->set_vbus)
251
+ ehci_mv->set_vbus(0);
275252
276253 mv_ehci_disable(ehci_mv);
277254 }
....@@ -284,17 +261,14 @@
284261 MODULE_ALIAS("mv-ehci");
285262
286263 static const struct platform_device_id ehci_id_table[] = {
287
- {"pxa-u2oehci", PXA_U2OEHCI},
288
- {"pxa-sph", PXA_SPH},
289
- {"mmp3-hsic", MMP3_HSIC},
290
- {"mmp3-fsic", MMP3_FSIC},
264
+ {"pxa-u2oehci", 0},
265
+ {"pxa-sph", 0},
291266 {},
292267 };
293268
294269 static void mv_ehci_shutdown(struct platform_device *pdev)
295270 {
296
- struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev);
297
- struct usb_hcd *hcd = ehci_mv->hcd;
271
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
298272
299273 if (!hcd->rh_registered)
300274 return;
....@@ -303,13 +277,42 @@
303277 hcd->driver->shutdown(hcd);
304278 }
305279
280
+static const struct of_device_id ehci_mv_dt_ids[] = {
281
+ { .compatible = "marvell,pxau2o-ehci", },
282
+ {},
283
+};
284
+
306285 static struct platform_driver ehci_mv_driver = {
307286 .probe = mv_ehci_probe,
308287 .remove = mv_ehci_remove,
309288 .shutdown = mv_ehci_shutdown,
310289 .driver = {
311
- .name = "mv-ehci",
312
- .bus = &platform_bus_type,
313
- },
290
+ .name = "mv-ehci",
291
+ .bus = &platform_bus_type,
292
+ .of_match_table = ehci_mv_dt_ids,
293
+ },
314294 .id_table = ehci_id_table,
315295 };
296
+
297
+static int __init ehci_platform_init(void)
298
+{
299
+ if (usb_disabled())
300
+ return -ENODEV;
301
+
302
+ ehci_init_driver(&ehci_platform_hc_driver, &platform_overrides);
303
+ return platform_driver_register(&ehci_mv_driver);
304
+}
305
+module_init(ehci_platform_init);
306
+
307
+static void __exit ehci_platform_cleanup(void)
308
+{
309
+ platform_driver_unregister(&ehci_mv_driver);
310
+}
311
+module_exit(ehci_platform_cleanup);
312
+
313
+MODULE_DESCRIPTION("Marvell EHCI driver");
314
+MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>");
315
+MODULE_AUTHOR("Neil Zhang <zhangwm@marvell.com>");
316
+MODULE_ALIAS("mv-ehci");
317
+MODULE_LICENSE("GPL");
318
+MODULE_DEVICE_TABLE(of, ehci_mv_dt_ids);