3 #include "usbdev_grf_regs.h"
4 #include "dwc_otg_regs.h"
6 static struct dwc_otg_control_usb *control_usb;
8 #ifdef CONFIG_USB20_OTG
10 static void usb20otg_hw_init(void)
12 #ifndef CONFIG_USB20_HOST
13 /* enable soft control */
14 control_usb->grf_uoc1_base->CON2 = (0x01 << 2) | ((0x01 << 2) << 16);
16 control_usb->grf_uoc1_base->CON3 = 0x2A | (0x3F << 16);
18 /* usb phy config init
19 * usb phy enter usb mode */
20 control_usb->grf_uoc0_base->CON0 = (0x0300 << 16);
22 /* other haredware init,include:
23 * DRV_VBUS GPIO init */
24 if (gpio_get_value(control_usb->otg_gpios->gpio))
25 gpio_set_value(control_usb->otg_gpios->gpio, 0);
28 static void usb20otg_phy_suspend(void *pdata, int suspend)
30 struct dwc_otg_platform_data *usbpdata = pdata;
33 /* enable soft control */
34 control_usb->grf_uoc0_base->CON2 =
35 (0x01 << 2) | ((0x01 << 2) << 16);
37 control_usb->grf_uoc0_base->CON3 = 0x2A | (0x3F << 16);
38 usbpdata->phy_status = 1;
41 control_usb->grf_uoc0_base->CON2 = ((0x01 << 2) << 16);
42 usbpdata->phy_status = 0;
46 static void usb20otg_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
50 static void usb20otg_clock_init(void *pdata)
52 struct dwc_otg_platform_data *usbpdata = pdata;
53 struct clk *ahbclk, *phyclk;
55 ahbclk = devm_clk_get(usbpdata->dev, "hclk_usb0");
57 dev_err(usbpdata->dev, "Failed to get hclk_usb0\n");
61 phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy0");
63 dev_err(usbpdata->dev, "Failed to get clk_usbphy0\n");
67 usbpdata->phyclk = phyclk;
68 usbpdata->ahbclk = ahbclk;
71 static void usb20otg_clock_enable(void *pdata, int enable)
73 struct dwc_otg_platform_data *usbpdata = pdata;
76 clk_prepare_enable(usbpdata->ahbclk);
77 clk_prepare_enable(usbpdata->phyclk);
79 clk_disable_unprepare(usbpdata->ahbclk);
80 clk_disable_unprepare(usbpdata->phyclk);
84 static int usb20otg_get_status(int id)
89 case USB_STATUS_BVABLID:
91 ret = control_usb->grf_soc_status0_rk3188->otg_bvalid;
95 ret = control_usb->grf_soc_status0_rk3188->otg_linestate;
99 ret = control_usb->grf_soc_status0_rk3188->otg_iddig;
102 ret = control_usb->chip_id;
104 case USB_REMOTE_WAKEUP:
105 ret = control_usb->remote_wakeup;
108 ret = control_usb->usb_irq_wakeup;
117 #ifdef CONFIG_RK_USB_UART
118 static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
120 if (1 == enter_usb_uart_mode) {
122 * note: can't disable otg here! If otg disable, the ID change
123 * interrupt can't be triggered when otg cable connect without
124 * device.At the same time, uart can't be used normally
126 /* bypass dm, enter uart mode */
127 control_usb->grf_uoc0_base->CON0 = (0x0300 | (0x0300 << 16));
128 } else if (0 == enter_usb_uart_mode) {
130 control_usb->grf_uoc0_base->CON0 = (0x0300 << 16);
135 static void usb20otg_power_enable(int enable)
138 /* disable otg_drv power */
139 gpio_set_value(control_usb->otg_gpios->gpio, 0);
140 } else if (1 == enable) {
141 /* enable otg_drv power */
142 gpio_set_value(control_usb->otg_gpios->gpio, 1);
146 struct dwc_otg_platform_data usb20otg_pdata_rk3188 = {
151 .hw_init = usb20otg_hw_init,
152 .phy_suspend = usb20otg_phy_suspend,
153 .soft_reset = usb20otg_soft_reset,
154 .clock_init = usb20otg_clock_init,
155 .clock_enable = usb20otg_clock_enable,
156 .get_status = usb20otg_get_status,
157 .power_enable = usb20otg_power_enable,
158 #ifdef CONFIG_RK_USB_UART
159 .dwc_otg_uart_mode = dwc_otg_uart_mode,
161 .bc_detect_cb = rk_battery_charger_detect_cb,
166 #ifdef CONFIG_USB20_HOST
167 static void usb20host_hw_init(void)
169 /* usb phy config init */
171 /* other haredware init,include:
172 * DRV_VBUS GPIO init */
173 if (!gpio_get_value(control_usb->host_gpios->gpio))
174 gpio_set_value(control_usb->host_gpios->gpio, 1);
177 static void usb20host_phy_suspend(void *pdata, int suspend)
179 struct dwc_otg_platform_data *usbpdata = pdata;
182 /* enable soft control */
183 control_usb->grf_uoc1_base->CON2 =
184 (0x01 << 2) | ((0x01 << 2) << 16);
186 control_usb->grf_uoc1_base->CON3 = 0x2A | (0x3F << 16);
187 usbpdata->phy_status = 1;
190 control_usb->grf_uoc1_base->CON2 = ((0x01 << 2) << 16);
191 usbpdata->phy_status = 0;
195 static void usb20host_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
199 static void usb20host_clock_init(void *pdata)
201 struct dwc_otg_platform_data *usbpdata = pdata;
202 struct clk *ahbclk, *phyclk;
204 ahbclk = devm_clk_get(usbpdata->dev, "hclk_usb1");
205 if (IS_ERR(ahbclk)) {
206 dev_err(usbpdata->dev, "Failed to get hclk_usb1\n");
210 phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy1");
211 if (IS_ERR(phyclk)) {
212 dev_err(usbpdata->dev, "Failed to get clk_usbphy1\n");
216 usbpdata->phyclk = phyclk;
217 usbpdata->ahbclk = ahbclk;
220 static void usb20host_clock_enable(void *pdata, int enable)
222 struct dwc_otg_platform_data *usbpdata = pdata;
225 clk_prepare_enable(usbpdata->ahbclk);
226 clk_prepare_enable(usbpdata->phyclk);
228 clk_disable_unprepare(usbpdata->ahbclk);
229 clk_disable_unprepare(usbpdata->phyclk);
233 static int usb20host_get_status(int id)
238 case USB_STATUS_BVABLID:
240 ret = control_usb->grf_soc_status0_rk3188->uhost_bvalid;
242 case USB_STATUS_DPDM:
244 ret = control_usb->grf_soc_status0_rk3188->uhost_linestate;
248 ret = control_usb->grf_soc_status0_rk3188->uhost_iddig;
251 ret = control_usb->chip_id;
253 case USB_REMOTE_WAKEUP:
254 ret = control_usb->remote_wakeup;
257 ret = control_usb->usb_irq_wakeup;
266 static void usb20host_power_enable(int enable)
269 /* disable host_drv power */
270 /* do not disable power in default */
271 } else if (1 == enable) {
272 /* enable host_drv power */
273 gpio_set_value(control_usb->host_gpios->gpio, 1);
277 struct dwc_otg_platform_data usb20host_pdata_rk3188 = {
282 .hw_init = usb20host_hw_init,
283 .phy_suspend = usb20host_phy_suspend,
284 .soft_reset = usb20host_soft_reset,
285 .clock_init = usb20host_clock_init,
286 .clock_enable = usb20host_clock_enable,
287 .get_status = usb20host_get_status,
288 .power_enable = usb20host_power_enable,
292 #ifdef CONFIG_USB_EHCI1_RK
293 static void rk_ehci1_hw_init(void)
295 /* usb phy config init
296 * ehci1 phy config init, set ehci1phy_txsrtune */
297 control_usb->grf_uoc2_base->CON0 = ((0xf << 6) << 16) | (0xf << 6);
299 /* other haredware init
300 * set common_on, in suspend mode, otg/host PLL blocks remain powered
301 * for RK3168 set control_usb->grf_uoc0_base->CON0 = (1<<16)|0;
302 * for Rk3188 set control_usb->grf_uoc1_base->CON0 = (1<<16)|0;
304 control_usb->grf_uoc1_base->CON0 = (1 << 16) | 0;
306 /* change INCR to INCR16 or INCR8(beats less than 16)
307 * or INCR4(beats less than 8) or SINGLE(beats less than 4)
309 control_usb->grf_uoc3_base->CON0 = 0x00ff00bc;
312 static void rk_ehci1_clock_init(void *pdata)
314 /* By default, ehci1phy_480m's parent is otg phy 480MHz clk
315 * rk3188 must use host phy 480MHz clk, because if otg bypass
316 * to uart mode, otg phy 480MHz clk will be closed automatically
318 struct rkehci_platform_data *usbpdata = pdata;
319 struct clk *ahbclk, *phyclk480m_ehci1, *phyclk12m_ehci1, *phyclk_usbphy1;
321 phyclk480m_ehci1 = devm_clk_get(usbpdata->dev, "ehci1phy_480m");
322 if (IS_ERR(phyclk480m_ehci1)) {
323 dev_err(usbpdata->dev, "Failed to get ehci1phy_480m\n");
327 phyclk12m_ehci1 = devm_clk_get(usbpdata->dev, "ehci1phy_12m");
328 if (IS_ERR(phyclk12m_ehci1)) {
329 dev_err(usbpdata->dev, "Failed to get ehci1phy_12m\n");
333 phyclk_usbphy1 = devm_clk_get(usbpdata->dev, "ehci1_usbphy1");
334 if (IS_ERR(phyclk_usbphy1)) {
335 dev_err(usbpdata->dev, "Failed to get ehci1_usbphy1\n");
339 ahbclk = devm_clk_get(usbpdata->dev, "hclk_ehci1");
340 if (IS_ERR(ahbclk)) {
341 dev_err(usbpdata->dev, "Failed to get hclk_ehci1\n");
345 clk_set_parent(phyclk480m_ehci1, phyclk_usbphy1);
347 usbpdata->hclk_ehci = ahbclk;
348 usbpdata->ehci_phy_480m = phyclk480m_ehci1;
349 usbpdata->ehci_phy_12m = phyclk12m_ehci1;
352 static void rk_ehci1_clock_enable(void *pdata, int enable)
354 struct rkehci_platform_data *usbpdata = pdata;
356 if (enable == usbpdata->clk_status)
359 clk_prepare_enable(usbpdata->hclk_ehci);
360 clk_prepare_enable(usbpdata->ehci_phy_480m);
361 clk_prepare_enable(usbpdata->ehci_phy_12m);
362 usbpdata->clk_status = 1;
364 clk_disable_unprepare(usbpdata->hclk_ehci);
365 clk_disable_unprepare(usbpdata->ehci_phy_480m);
366 clk_disable_unprepare(usbpdata->ehci_phy_12m);
367 usbpdata->clk_status = 0;
371 static void rk_ehci1_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
376 struct rkehci_platform_data rkehci_pdata_rk3188 = {
378 .ehci_phy_12m = NULL,
379 .ehci_phy_480m = NULL,
381 .hw_init = rk_ehci1_hw_init,
382 .clock_init = rk_ehci1_clock_init,
383 .clock_enable = rk_ehci1_clock_enable,
384 .soft_reset = rk_ehci1_soft_reset,
388 #define WAKE_LOCK_TIMEOUT (HZ * 10)
390 static inline void do_wakeup(struct work_struct *work)
392 rk_send_wakeup_key(); /* wake up the system */
395 /********** handler for bvalid irq **********/
396 static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
399 control_usb->grf_uoc0_base->CON3 = (1 << 31) | (1 << 15);
401 #ifdef CONFIG_RK_USB_UART
402 /* usb otg dp/dm switch to usb phy */
403 dwc_otg_uart_mode(NULL, PHY_USB_MODE);
406 if (control_usb->usb_irq_wakeup) {
407 wake_lock_timeout(&control_usb->usb_wakelock,
409 schedule_delayed_work(&control_usb->usb_det_wakeup_work,
416 /************* register bvalid irq **************/
417 static int otg_irq_detect_init(struct platform_device *pdev)
422 if (control_usb->usb_irq_wakeup) {
423 wake_lock_init(&control_usb->usb_wakelock, WAKE_LOCK_SUSPEND,
425 INIT_DELAYED_WORK(&control_usb->usb_det_wakeup_work, do_wakeup);
428 irq = platform_get_irq_byname(pdev, "otg_bvalid");
431 request_irq(irq, bvalid_irq_handler, 0, "otg_bvalid", NULL);
433 dev_err(&pdev->dev, "request_irq %d failed!\n", irq);
437 /* clear & enable bvalid irq */
438 control_usb->grf_uoc0_base->CON3 = (3 << 30) | (3 << 14);
440 if (control_usb->usb_irq_wakeup)
441 enable_irq_wake(irq);
447 static int usb_grf_ioremap(struct platform_device *pdev)
450 struct resource *res;
451 void *grf_soc_status0;
457 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
459 grf_soc_status0 = devm_ioremap_resource(&pdev->dev, res);
460 if (IS_ERR(grf_soc_status0)) {
461 ret = PTR_ERR(grf_soc_status0);
464 control_usb->grf_soc_status0_rk3188 =
465 (pGRF_SOC_STATUS_RK3188) grf_soc_status0;
467 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
469 grf_uoc0_base = devm_ioremap_resource(&pdev->dev, res);
470 if (IS_ERR(grf_uoc0_base)) {
471 ret = PTR_ERR(grf_uoc0_base);
474 control_usb->grf_uoc0_base = (pGRF_UOC0_REG) grf_uoc0_base;
476 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
478 grf_uoc1_base = devm_ioremap_resource(&pdev->dev, res);
479 if (IS_ERR(grf_uoc1_base)) {
480 ret = PTR_ERR(grf_uoc1_base);
483 control_usb->grf_uoc1_base = (pGRF_UOC1_REG) grf_uoc1_base;
485 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
487 grf_uoc2_base = devm_ioremap_resource(&pdev->dev, res);
488 if (IS_ERR(grf_uoc2_base)) {
489 ret = PTR_ERR(grf_uoc2_base);
492 control_usb->grf_uoc2_base = (pGRF_UOC2_REG) grf_uoc2_base;
494 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
496 grf_uoc3_base = devm_ioremap_resource(&pdev->dev, res);
497 if (IS_ERR(grf_uoc3_base)) {
498 ret = PTR_ERR(grf_uoc3_base);
501 control_usb->grf_uoc3_base = (pGRF_UOC3_REG) grf_uoc3_base;
508 static const struct of_device_id dwc_otg_control_usb_id_table[] = {
510 .compatible = "rockchip,rk3188-dwc-control-usb",
515 MODULE_DEVICE_TABLE(of, dwc_otg_control_usb_id_table);
518 static int dwc_otg_control_usb_probe(struct platform_device *pdev)
521 struct device_node *np = pdev->dev.of_node;
522 struct clk *hclk_usb_peri;
526 devm_kzalloc(&pdev->dev, sizeof(*control_usb), GFP_KERNEL);
529 dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
534 control_usb->chip_id = RK3188_USB_CTLR;
535 control_usb->remote_wakeup = of_property_read_bool(np,
536 "rockchip,remote_wakeup");
537 control_usb->usb_irq_wakeup = of_property_read_bool(np,
538 "rockchip,usb_irq_wakeup");
540 hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
541 if (IS_ERR(hclk_usb_peri)) {
542 dev_err(&pdev->dev, "Failed to get hclk_usb_peri\n");
547 control_usb->hclk_usb_peri = hclk_usb_peri;
548 clk_prepare_enable(hclk_usb_peri);
550 ret = usb_grf_ioremap(pdev);
552 dev_err(&pdev->dev, "Failed to ioremap usb grf\n");
557 control_usb->host_gpios =
558 devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
559 if (!control_usb->host_gpios) {
560 dev_err(&pdev->dev, "unable to alloc memory for host_gpios\n");
565 gpio = of_get_named_gpio(np, "gpios", 0);
566 if (!gpio_is_valid(gpio)) {
567 dev_err(&pdev->dev, "invalid host gpio%d\n", gpio);
572 control_usb->host_gpios->gpio = gpio;
574 err = devm_gpio_request(&pdev->dev, gpio, "host_drv_gpio");
577 "failed to request GPIO%d for host_drv\n", gpio);
581 gpio_direction_output(control_usb->host_gpios->gpio, 1);
584 control_usb->otg_gpios =
585 devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
586 if (!control_usb->otg_gpios) {
587 dev_err(&pdev->dev, "unable to alloc memory for otg_gpios\n");
592 gpio = of_get_named_gpio(np, "gpios", 1);
593 if (!gpio_is_valid(gpio)) {
594 dev_err(&pdev->dev, "invalid otg gpio%d\n", gpio);
598 control_usb->otg_gpios->gpio = gpio;
599 err = devm_gpio_request(&pdev->dev, gpio, "otg_drv_gpio");
602 "failed to request GPIO%d for otg_drv\n", gpio);
606 gpio_direction_output(control_usb->otg_gpios->gpio, 0);
608 ret = otg_irq_detect_init(pdev);
615 clk_disable_unprepare(hclk_usb_peri);
620 static int dwc_otg_control_usb_remove(struct platform_device *pdev)
622 clk_disable_unprepare(control_usb->hclk_usb_peri);
626 static struct platform_driver dwc_otg_control_usb_driver = {
627 .probe = dwc_otg_control_usb_probe,
628 .remove = dwc_otg_control_usb_remove,
630 .name = "rk3188-dwc-control-usb",
631 .owner = THIS_MODULE,
632 .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
636 static int __init dwc_otg_control_usb_init(void)
638 return platform_driver_register(&dwc_otg_control_usb_driver);
641 subsys_initcall(dwc_otg_control_usb_init);
643 static void __exit dwc_otg_control_usb_exit(void)
645 platform_driver_unregister(&dwc_otg_control_usb_driver);
648 module_exit(dwc_otg_control_usb_exit);
649 MODULE_ALIAS("platform: dwc_control_usb");
650 MODULE_AUTHOR("RockChip Inc.");
651 MODULE_DESCRIPTION("RockChip Control Module USB Driver");
652 MODULE_LICENSE("GPL v2");