USB: support DWC_OTG Driver Version3.10 and used by default
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_rk30.c
1 #include <linux/kernel.h>
2 #include <linux/platform_device.h>
3 #include <linux/delay.h>
4 #include <linux/dma-mapping.h>
5 #include <linux/clk.h>
6 #include <linux/module.h>
7 #include <linux/slab.h>
8 #include <linux/of.h>
9 #include <linux/err.h>
10 #include <linux/io.h>
11 #include <linux/of_gpio.h>
12 #include <linux/gpio.h>
13 #include "usbdev_rk.h"
14 #include "dwc_otg_regs.h"
15
16 static struct dwc_otg_control_usb *control_usb;
17
18 int dwc_otg_check_dpdm(void)
19 {
20         int bus_status = 0;
21         return bus_status;
22 }
23
24 EXPORT_SYMBOL(dwc_otg_check_dpdm);
25
26 #ifdef CONFIG_USB20_OTG
27
28 void usb20otg_hw_init(void)
29 {
30 #ifndef CONFIG_USB20_HOST
31         unsigned int * otg_phy_con1 = (control_usb->grf_uoc1_base + 0x8);
32         unsigned int * otg_phy_con2 = (control_usb->grf_uoc1_base + 0xc);
33         *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16);     //enable soft control
34         *otg_phy_con2 = 0x2A|(0x3F<<16);               // enter suspend
35 #endif
36         /* usb phy config init
37          * usb phy enter usb mode */
38         unsigned int * otg_phy_con3 = (control_usb->grf_uoc0_base);
39         *otg_phy_con3 = (0x0300 << 16);
40
41         /* other haredware init,include:
42          * DRV_VBUS GPIO init */
43         gpio_direction_output(control_usb->otg_gpios->gpio, 0);
44 }
45
46 void usb20otg_phy_suspend(void* pdata, int suspend)
47 {
48         struct dwc_otg_platform_data *usbpdata=pdata;
49         unsigned int * otg_phy_con1 = (control_usb->grf_uoc0_base + 0x8);
50         unsigned int * otg_phy_con2 = (control_usb->grf_uoc0_base + 0xc);
51
52         if(suspend){
53                 *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16);      //enable soft control
54                 *otg_phy_con2 = 0x2A|(0x3F<<16);                // enter suspend
55                 usbpdata->phy_status = 1;
56         }else{
57                 *otg_phy_con1 = ((0x01<<2)<<16);                // exit suspend.
58                 usbpdata->phy_status = 0;
59         }
60 }
61
62 void usb20otg_soft_reset(void)
63 {
64 }
65
66 void usb20otg_clock_init(void* pdata)
67 {
68         struct dwc_otg_platform_data *usbpdata=pdata;
69         struct clk* ahbclk,*phyclk;
70
71         ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg0");
72         if (IS_ERR(ahbclk)) {
73                 dev_err(usbpdata->dev, "Failed to get hclk_otg0\n");
74                 return;
75         }
76
77         phyclk = devm_clk_get(usbpdata->dev, "otgphy0");
78         if (IS_ERR(phyclk)) {
79                 dev_err(usbpdata->dev, "Failed to get otgphy0\n");
80                 return;
81         }
82
83         usbpdata->phyclk = phyclk;
84         usbpdata->ahbclk = ahbclk;
85 }
86
87 void usb20otg_clock_enable(void* pdata, int enable)
88 {
89         struct dwc_otg_platform_data *usbpdata=pdata;
90
91         if(enable){
92                 clk_prepare_enable(usbpdata->ahbclk);
93                 clk_prepare_enable(usbpdata->phyclk);
94         }else{
95                 clk_disable_unprepare(usbpdata->ahbclk);
96                 clk_disable_unprepare(usbpdata->phyclk);
97         }
98 }
99
100 int usb20otg_get_status(int id)
101 {
102         int ret = -1;
103         unsigned int usbgrf_status = *(unsigned int*)(control_usb->grf_soc_status0);
104
105         switch(id){
106                 case USB_STATUS_BVABLID:
107                         // bvalid in grf
108                         ret = (usbgrf_status &(1<<10));
109                         break;
110                 case USB_STATUS_DPDM:
111                         // dpdm in grf
112                         ret = (usbgrf_status &(3<<11));
113                         break;
114                 case USB_STATUS_ID:
115                         // id in grf
116                         ret = (usbgrf_status &(1<<13));
117                         break;
118                 default:
119                         break;
120         }
121
122         return ret;
123 }
124
125 #ifdef CONFIG_RK_USB_UART
126 void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)
127 {
128         unsigned int * otg_phy_con1 = (unsigned int*)(control_usb->grf_uoc0_base);
129
130         if(1 == enter_usb_uart_mode){
131                 /* enter uart mode
132                  * note: can't disable otg here! If otg disable, the ID change
133                  * interrupt can't be triggered when otg cable connect without
134                  * device.At the same time, uart can't be used normally
135                  */
136                 *otg_phy_con1 = (0x0300 | (0x0300 << 16));      //bypass dm
137         }else if(0 == enter_usb_uart_mode){
138                 /* enter usb mode */
139                 *otg_phy_con1 = (0x0300 << 16);                 //bypass dm disable
140         }
141 }
142 #endif
143
144 void usb20otg_power_enable(int enable)
145 {
146         if(0 == enable){//disable otg_drv power
147                 gpio_set_value(control_usb->otg_gpios->gpio, 0);
148         }else if(1 == enable){//enable otg_drv power
149                 gpio_set_value(control_usb->otg_gpios->gpio, 1);
150         }
151 }
152
153 struct dwc_otg_platform_data usb20otg_pdata = {
154         .phyclk = NULL,
155         .ahbclk = NULL,
156         .busclk = NULL,
157         .phy_status = 0,
158         .hw_init=usb20otg_hw_init,
159         .phy_suspend=usb20otg_phy_suspend,
160         .soft_reset=usb20otg_soft_reset,
161         .clock_init=usb20otg_clock_init,
162         .clock_enable=usb20otg_clock_enable,
163         .get_status=usb20otg_get_status,
164         .power_enable=usb20otg_power_enable,
165 #ifdef CONFIG_RK_USB_UART
166         .dwc_otg_uart_mode=dwc_otg_uart_mode,
167 #endif
168 };
169
170 #endif
171
172 #ifdef CONFIG_USB20_HOST
173 void usb20host_hw_init(void)
174 {
175         /* usb phy config init */
176
177         /* other haredware init,include:
178          * DRV_VBUS GPIO init */
179         gpio_direction_output(control_usb->host_gpios->gpio, 1);
180
181 }
182
183 void usb20host_phy_suspend(void* pdata, int suspend)
184 {
185         struct dwc_otg_platform_data *usbpdata=pdata;
186         unsigned int * otg_phy_con1 = (unsigned int*)(control_usb->grf_uoc1_base + 0x8);
187         unsigned int * otg_phy_con2 = (unsigned int*)(control_usb->grf_uoc1_base + 0xc);
188
189         if(suspend){
190                 *otg_phy_con1 =  (0x01<<2)|((0x01<<2)<<16);     // enable soft control
191                 *otg_phy_con2 =  0x2A|(0x3F<<16);               // enter suspend
192                 usbpdata->phy_status = 1;
193         }else{
194                 *otg_phy_con1 = ((0x01<<2)<<16);                // exit suspend.
195                 usbpdata->phy_status = 0;
196         }
197 }
198
199 void usb20host_soft_reset(void)
200 {
201 }
202
203 void usb20host_clock_init(void* pdata)
204 {
205         struct dwc_otg_platform_data *usbpdata=pdata;
206         struct clk* ahbclk,*phyclk;
207
208         ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg1");
209         if (IS_ERR(ahbclk)) {
210                 dev_err(usbpdata->dev, "Failed to get hclk_otg1\n");
211                 return;
212         }
213
214         phyclk = devm_clk_get(usbpdata->dev, "otgphy1");
215         if (IS_ERR(phyclk)) {
216                 dev_err(usbpdata->dev, "Failed to get otgphy1\n");
217                 return;
218         }
219
220         usbpdata->phyclk = phyclk;
221         usbpdata->ahbclk = ahbclk;
222 }
223
224 void usb20host_clock_enable(void* pdata, int enable)
225 {
226         struct dwc_otg_platform_data *usbpdata=pdata;
227
228         if(enable){
229                 clk_prepare_enable(usbpdata->ahbclk);
230                 clk_prepare_enable(usbpdata->phyclk);
231         }else{
232                 clk_disable_unprepare(usbpdata->ahbclk);
233                 clk_disable_unprepare(usbpdata->phyclk);
234         }
235 }
236
237 int usb20host_get_status(int id)
238 {
239         int ret = -1;
240         unsigned int usbgrf_status = *(unsigned int*)(control_usb->grf_soc_status0);
241
242         switch(id){
243                 case USB_STATUS_BVABLID:
244                         // bvalid in grf
245                         ret = (usbgrf_status &(1<<17));
246                         break;
247                 case USB_STATUS_DPDM:
248                         // dpdm in grf
249                         ret = (usbgrf_status &(3<<18));
250                         break;
251                 case USB_STATUS_ID:
252                         // id in grf
253                         ret = (usbgrf_status &(1<<20));
254                         break;
255                 default:
256                         break;
257         }
258
259         return ret;
260 }
261
262 void usb20host_power_enable(int enable)
263 {
264         if(0 == enable){//disable host_drv power
265                 //do not disable power in default
266         }else if(1 == enable){//enable host_drv power
267                 gpio_set_value(control_usb->host_gpios->gpio, 1);
268         }
269 }
270
271 struct dwc_otg_platform_data usb20host_pdata = {
272         .phyclk = NULL,
273         .ahbclk = NULL,
274         .busclk = NULL,
275         .phy_status = 0,
276         .hw_init=usb20host_hw_init,
277         .phy_suspend=usb20host_phy_suspend,
278         .soft_reset=usb20host_soft_reset,
279         .clock_init=usb20host_clock_init,
280         .clock_enable=usb20host_clock_enable,
281         .get_status=usb20host_get_status,
282         .power_enable=usb20host_power_enable,
283 };
284 #endif
285
286 #ifdef CONFIG_USB_EHCI_RK
287 void rk_hsic_hw_init(void)
288 {
289         unsigned int * phy_con0 = (control_usb->grf_uoc0_base);
290         unsigned int * phy_con1 = (control_usb->grf_uoc1_base);
291         unsigned int * phy_con2 = (control_usb->grf_uoc2_base);
292         unsigned int * phy_con3 = (control_usb->grf_uoc3_base);
293
294         // usb phy config init
295         // hsic phy config init, set hsicphy_txsrtune
296         *phy_con2 = ((0xf<<6)<<16)|(0xf<<6);
297
298         /* other haredware init
299          * set common_on, in suspend mode, otg/host PLL blocks remain powered
300          * for RK3168 set *phy_con0 = (1<<16)|0;
301          * for Rk3188 set *phy_con1 = (1<<16)|0;
302          */
303         *phy_con1 = (1<<16)|0;
304
305         /* change INCR to INCR16 or INCR8(beats less than 16)
306          * or INCR4(beats less than 8) or SINGLE(beats less than 4)
307          */
308         *phy_con3 = 0x00ff00bc;
309 }
310
311 void rk_hsic_clock_init(void* pdata)
312 {
313         /* By default, hsicphy_480m's parent is otg phy 480MHz clk
314          * rk3188 must use host phy 480MHz clk, because if otg bypass
315          * to uart mode, otg phy 480MHz clk will be closed automatically
316          */
317         struct rkehci_platform_data *usbpdata=pdata;
318         struct clk *ahbclk, *phyclk480m_hsic, *phyclk12m_hsic, *phyclk_otgphy1;
319
320         phyclk480m_hsic = devm_clk_get(usbpdata->dev, "hsicphy480m");
321         if (IS_ERR(phyclk480m_hsic)) {
322                 dev_err(usbpdata->dev, "Failed to get hsicphy480m\n");
323                 return;
324         }
325
326         phyclk12m_hsic = devm_clk_get(usbpdata->dev, "hsicphy12m");
327         if (IS_ERR(phyclk12m_hsic)) {
328                 dev_err(usbpdata->dev, "Failed to get hsicphy12m\n");
329                 return;
330         }
331
332         phyclk_otgphy1 = devm_clk_get(usbpdata->dev, "hsic_otgphy1");
333         if (IS_ERR(phyclk_otgphy1)) {
334                 dev_err(usbpdata->dev, "Failed to get hsic_otgphy1\n");
335                 return;
336         }
337
338         ahbclk = devm_clk_get(usbpdata->dev, "hclk_hsic");
339         if (IS_ERR(ahbclk)) {
340                 dev_err(usbpdata->dev, "Failed to get hclk_hsic\n");
341                 return;
342         }
343
344         clk_set_parent(phyclk480m_hsic, phyclk_otgphy1);
345         
346         usbpdata->hclk_hsic = ahbclk;
347         usbpdata->hsic_phy_480m = phyclk480m_hsic;
348         usbpdata->hsic_phy_12m = phyclk12m_hsic;
349 }
350
351 void rk_hsic_clock_enable(void* pdata, int enable)
352 {
353         struct rkehci_platform_data *usbpdata=pdata;
354
355         if(enable == usbpdata->clk_status)
356                 return;
357         if(enable){
358                 clk_prepare_enable(usbpdata->hclk_hsic);
359                 clk_prepare_enable(usbpdata->hsic_phy_480m);
360                 clk_prepare_enable(usbpdata->hsic_phy_12m);
361                 usbpdata->clk_status = 1;
362         }else{
363                 clk_disable_unprepare(usbpdata->hclk_hsic);
364                 clk_disable_unprepare(usbpdata->hsic_phy_480m);
365                 clk_disable_unprepare(usbpdata->hsic_phy_12m);
366                 usbpdata->clk_status = 0;
367         }
368 }
369
370 void rk_hsic_soft_reset(void)
371 {
372
373 }
374
375 struct rkehci_platform_data rkhsic_pdata = {
376         .hclk_hsic = NULL,
377         .hsic_phy_12m = NULL,
378         .hsic_phy_480m = NULL,
379         .clk_status = -1,
380         .hw_init = rk_hsic_hw_init,
381         .clock_init = rk_hsic_clock_init,
382         .clock_enable = rk_hsic_clock_enable,
383         .soft_reset = rk_hsic_soft_reset,
384 };
385 #endif
386
387 static int dwc_otg_control_usb_probe(struct platform_device *pdev)
388 {
389         struct resource *res;
390         int gpio, err;
391         struct device_node *np = pdev->dev.of_node;
392         struct clk* hclk_usb_peri;
393         int ret = 0;
394
395         control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),GFP_KERNEL);
396         if (!control_usb) {
397                 dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
398                 ret =  -ENOMEM;
399                 goto err1;
400         }
401
402         hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
403         if (IS_ERR(hclk_usb_peri)) {
404                 dev_err(&pdev->dev, "Failed to get hclk_usb_peri\n");
405                 ret = -EINVAL;
406                 goto err1;
407         }
408         control_usb->hclk_usb_peri = hclk_usb_peri;
409         clk_prepare_enable(hclk_usb_peri);
410
411         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
412                                                 "GRF_SOC_STATUS0");
413         control_usb->grf_soc_status0 = devm_ioremap_resource(&pdev->dev, res);
414         if (IS_ERR(control_usb->grf_soc_status0)){
415                 ret = PTR_ERR(control_usb->grf_soc_status0);
416                 goto err2;
417         }
418
419         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
420                                                 "GRF_UOC0_BASE");
421         control_usb->grf_uoc0_base = devm_ioremap_resource(&pdev->dev, res);
422         if (IS_ERR(control_usb->grf_uoc0_base)){
423                 ret = PTR_ERR(control_usb->grf_uoc0_base);
424                 goto err2;
425         }
426
427         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
428                                                 "GRF_UOC1_BASE");
429         control_usb->grf_uoc1_base = devm_ioremap_resource(&pdev->dev, res);
430         if (IS_ERR(control_usb->grf_uoc1_base)){
431                 ret = PTR_ERR(control_usb->grf_uoc1_base);
432                 goto err2;
433         }
434
435         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
436                                                 "GRF_UOC2_BASE");
437         control_usb->grf_uoc2_base = devm_ioremap_resource(&pdev->dev, res);
438         if (IS_ERR(control_usb->grf_uoc2_base)){
439                 ret = PTR_ERR(control_usb->grf_uoc2_base);
440                 goto err2;
441         }
442
443         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
444                                                 "GRF_UOC3_BASE");
445         control_usb->grf_uoc3_base = devm_ioremap_resource(&pdev->dev, res);
446         if (IS_ERR(control_usb->grf_uoc3_base)){
447                 ret = PTR_ERR(control_usb->grf_uoc3_base);
448                 goto err2;
449         }
450
451         control_usb->host_gpios = devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
452
453         gpio =  of_get_named_gpio(np, "gpios", 0);
454         if(!gpio_is_valid(gpio)){
455                 dev_err(&pdev->dev, "invalid host gpio%d\n", gpio);
456                 ret = -EINVAL;
457                 goto err2;
458         }
459         control_usb->host_gpios->gpio = gpio;
460         err = devm_gpio_request(&pdev->dev, gpio, "host_drv_gpio");
461         if (err) {
462                 dev_err(&pdev->dev,
463                         "failed to request GPIO%d for host_drv\n",
464                         gpio);
465                 ret = err;
466                 goto err2;
467         }
468
469         control_usb->otg_gpios = devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
470
471         gpio =  of_get_named_gpio(np, "gpios", 1);
472         if(!gpio_is_valid(gpio)){
473                 dev_err(&pdev->dev, "invalid otg gpio%d\n", gpio);
474                 ret = -EINVAL;
475                 goto err2;
476         }
477         control_usb->otg_gpios->gpio = gpio;
478         err = devm_gpio_request(&pdev->dev, gpio, "otg_drv_gpio");
479         if (err) {
480                 dev_err(&pdev->dev,
481                         "failed to request GPIO%d for otg_drv\n",
482                         gpio);
483                 ret = err;
484                 goto err2;
485         }
486
487         return 0;
488
489 err2:
490         clk_disable_unprepare(hclk_usb_peri);
491 err1:
492         return ret;
493 }
494
495 static int dwc_otg_control_usb_remove(struct platform_device *pdev)
496 {
497         clk_disable_unprepare(control_usb->hclk_usb_peri);
498         return 0;
499 }
500
501 #ifdef CONFIG_OF
502 static const struct of_device_id dwc_otg_control_usb_id_table[] = {
503         { .compatible = "rockchip,dwc-control-usb" },
504         {}
505 };
506 MODULE_DEVICE_TABLE(of, dwc_otg_control_usb_id_table);
507 #endif
508
509 static struct platform_driver dwc_otg_control_usb_driver = {
510         .probe          = dwc_otg_control_usb_probe,
511         .remove         = dwc_otg_control_usb_remove,
512         .driver         = {
513                 .name   = "dwc-control-usb",
514                 .owner  = THIS_MODULE,
515                 .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
516         },
517 };
518
519 static int __init dwc_otg_control_usb_init(void)
520 {
521         return platform_driver_register(&dwc_otg_control_usb_driver);
522 }
523 subsys_initcall(dwc_otg_control_usb_init);
524
525 static void __exit dwc_otg_control_usb_exit(void)
526 {
527         platform_driver_unregister(&dwc_otg_control_usb_driver);
528 }
529
530 module_exit(dwc_otg_control_usb_exit);
531 MODULE_ALIAS("platform: dwc_control_usb");
532 MODULE_AUTHOR("RockChip Inc.");
533 MODULE_DESCRIPTION("RockChip Control Module USB Driver");
534 MODULE_LICENSE("GPL v2");