1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2012 Freescale Semiconductor, Inc.
4 * Copyright (C) 2012 Marek Vasut <marex@denx.de>
5 * on behalf of DENX Software Engineering GmbH
8 #include <linux/module.h>
10 #include <linux/of_platform.h>
11 #include <linux/platform_device.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/usb/chipidea.h>
14 #include <linux/usb/of.h>
15 #include <linux/clk.h>
16 #include <linux/pinctrl/consumer.h>
17 #include <linux/pm_qos.h>
20 #include "ci_hdrc_imx.h"
22 struct ci_hdrc_imx_platform_flag
{
26 static const struct ci_hdrc_imx_platform_flag imx23_usb_data
= {
27 .flags
= CI_HDRC_TURN_VBUS_EARLY_ON
|
28 CI_HDRC_DISABLE_STREAMING
,
31 static const struct ci_hdrc_imx_platform_flag imx27_usb_data
= {
32 .flags
= CI_HDRC_DISABLE_STREAMING
,
35 static const struct ci_hdrc_imx_platform_flag imx28_usb_data
= {
36 .flags
= CI_HDRC_IMX28_WRITE_FIX
|
37 CI_HDRC_TURN_VBUS_EARLY_ON
|
38 CI_HDRC_DISABLE_STREAMING
,
41 static const struct ci_hdrc_imx_platform_flag imx6q_usb_data
= {
42 .flags
= CI_HDRC_SUPPORTS_RUNTIME_PM
|
43 CI_HDRC_TURN_VBUS_EARLY_ON
|
44 CI_HDRC_DISABLE_STREAMING
,
47 static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data
= {
48 .flags
= CI_HDRC_SUPPORTS_RUNTIME_PM
|
49 CI_HDRC_TURN_VBUS_EARLY_ON
|
50 CI_HDRC_DISABLE_HOST_STREAMING
,
53 static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data
= {
54 .flags
= CI_HDRC_SUPPORTS_RUNTIME_PM
|
55 CI_HDRC_TURN_VBUS_EARLY_ON
|
56 CI_HDRC_DISABLE_HOST_STREAMING
,
59 static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data
= {
60 .flags
= CI_HDRC_SUPPORTS_RUNTIME_PM
|
61 CI_HDRC_TURN_VBUS_EARLY_ON
|
62 CI_HDRC_DISABLE_DEVICE_STREAMING
,
65 static const struct ci_hdrc_imx_platform_flag imx7d_usb_data
= {
66 .flags
= CI_HDRC_SUPPORTS_RUNTIME_PM
,
69 static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data
= {
70 .flags
= CI_HDRC_SUPPORTS_RUNTIME_PM
|
71 CI_HDRC_HAS_PORTSC_PEC_MISSED
|
75 static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data
= {
76 .flags
= CI_HDRC_SUPPORTS_RUNTIME_PM
|
77 CI_HDRC_HAS_PORTSC_PEC_MISSED
,
80 static const struct of_device_id ci_hdrc_imx_dt_ids
[] = {
81 { .compatible
= "fsl,imx23-usb", .data
= &imx23_usb_data
},
82 { .compatible
= "fsl,imx28-usb", .data
= &imx28_usb_data
},
83 { .compatible
= "fsl,imx27-usb", .data
= &imx27_usb_data
},
84 { .compatible
= "fsl,imx6q-usb", .data
= &imx6q_usb_data
},
85 { .compatible
= "fsl,imx6sl-usb", .data
= &imx6sl_usb_data
},
86 { .compatible
= "fsl,imx6sx-usb", .data
= &imx6sx_usb_data
},
87 { .compatible
= "fsl,imx6ul-usb", .data
= &imx6ul_usb_data
},
88 { .compatible
= "fsl,imx7d-usb", .data
= &imx7d_usb_data
},
89 { .compatible
= "fsl,imx7ulp-usb", .data
= &imx7ulp_usb_data
},
90 { .compatible
= "fsl,imx8ulp-usb", .data
= &imx8ulp_usb_data
},
93 MODULE_DEVICE_TABLE(of
, ci_hdrc_imx_dt_ids
);
95 struct ci_hdrc_imx_data
{
97 struct platform_device
*ci_pdev
;
99 struct clk
*clk_wakeup
;
100 struct imx_usbmisc_data
*usbmisc_data
;
101 bool supports_runtime_pm
;
102 bool override_phy_control
;
104 struct pinctrl
*pinctrl
;
105 struct pinctrl_state
*pinctrl_hsic_active
;
106 struct regulator
*hsic_pad_regulator
;
107 /* SoC before i.mx6 (except imx23/imx28) needs three clks */
108 bool need_three_clks
;
112 /* --------------------------------- */
113 struct pm_qos_request pm_qos_req
;
114 const struct ci_hdrc_imx_platform_flag
*plat_data
;
117 /* Common functions shared by usbmisc drivers */
119 static struct imx_usbmisc_data
*usbmisc_get_init_data(struct device
*dev
)
121 struct platform_device
*misc_pdev
;
122 struct device_node
*np
= dev
->of_node
;
123 struct of_phandle_args args
;
124 struct imx_usbmisc_data
*data
;
128 * In case the fsl,usbmisc property is not present this device doesn't
129 * need usbmisc. Return NULL (which is no error here)
131 if (!of_property_present(np
, "fsl,usbmisc"))
134 data
= devm_kzalloc(dev
, sizeof(*data
), GFP_KERNEL
);
136 return ERR_PTR(-ENOMEM
);
138 ret
= of_parse_phandle_with_args(np
, "fsl,usbmisc", "#index-cells",
141 dev_err(dev
, "Failed to parse property fsl,usbmisc, errno %d\n",
146 data
->index
= args
.args
[0];
148 misc_pdev
= of_find_device_by_node(args
.np
);
149 of_node_put(args
.np
);
152 return ERR_PTR(-EPROBE_DEFER
);
154 if (!platform_get_drvdata(misc_pdev
)) {
155 put_device(&misc_pdev
->dev
);
156 return ERR_PTR(-EPROBE_DEFER
);
158 data
->dev
= &misc_pdev
->dev
;
161 * Check the various over current related properties. If over current
162 * detection is disabled we're not interested in the polarity.
164 if (of_property_read_bool(np
, "disable-over-current")) {
165 data
->disable_oc
= 1;
166 } else if (of_property_read_bool(np
, "over-current-active-high")) {
167 data
->oc_pol_active_low
= 0;
168 data
->oc_pol_configured
= 1;
169 } else if (of_property_read_bool(np
, "over-current-active-low")) {
170 data
->oc_pol_active_low
= 1;
171 data
->oc_pol_configured
= 1;
173 dev_warn(dev
, "No over current polarity defined\n");
176 data
->pwr_pol
= of_property_read_bool(np
, "power-active-high");
177 data
->evdo
= of_property_read_bool(np
, "external-vbus-divider");
179 if (of_usb_get_phy_mode(np
) == USBPHY_INTERFACE_MODE_ULPI
)
182 if (of_property_read_u32(np
, "samsung,picophy-pre-emp-curr-control",
183 &data
->emp_curr_control
))
184 data
->emp_curr_control
= -1;
185 if (of_property_read_u32(np
, "samsung,picophy-dc-vol-level-adjust",
186 &data
->dc_vol_level_adjust
))
187 data
->dc_vol_level_adjust
= -1;
188 if (of_property_read_u32(np
, "fsl,picophy-rise-fall-time-adjust",
189 &data
->rise_fall_time_adjust
))
190 data
->rise_fall_time_adjust
= -1;
195 /* End of common functions shared by usbmisc drivers*/
196 static int imx_get_clks(struct device
*dev
)
198 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
201 data
->clk_ipg
= devm_clk_get(dev
, "ipg");
202 if (IS_ERR(data
->clk_ipg
)) {
203 /* If the platform only needs one primary clock */
204 data
->clk
= devm_clk_get(dev
, NULL
);
205 if (IS_ERR(data
->clk
)) {
206 ret
= PTR_ERR(data
->clk
);
208 "Failed to get clks, err=%ld,%ld\n",
209 PTR_ERR(data
->clk
), PTR_ERR(data
->clk_ipg
));
212 /* Get wakeup clock. Not all of the platforms need to
213 * handle this clock. So make it optional.
215 data
->clk_wakeup
= devm_clk_get_optional(dev
, "usb_wakeup");
216 if (IS_ERR(data
->clk_wakeup
))
217 ret
= dev_err_probe(dev
, PTR_ERR(data
->clk_wakeup
),
218 "Failed to get wakeup clk\n");
222 data
->clk_ahb
= devm_clk_get(dev
, "ahb");
223 if (IS_ERR(data
->clk_ahb
)) {
224 ret
= PTR_ERR(data
->clk_ahb
);
226 "Failed to get ahb clock, err=%d\n", ret
);
230 data
->clk_per
= devm_clk_get(dev
, "per");
231 if (IS_ERR(data
->clk_per
)) {
232 ret
= PTR_ERR(data
->clk_per
);
234 "Failed to get per clock, err=%d\n", ret
);
238 data
->need_three_clks
= true;
242 static int imx_prepare_enable_clks(struct device
*dev
)
244 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
247 if (data
->need_three_clks
) {
248 ret
= clk_prepare_enable(data
->clk_ipg
);
251 "Failed to prepare/enable ipg clk, err=%d\n",
256 ret
= clk_prepare_enable(data
->clk_ahb
);
259 "Failed to prepare/enable ahb clk, err=%d\n",
261 clk_disable_unprepare(data
->clk_ipg
);
265 ret
= clk_prepare_enable(data
->clk_per
);
268 "Failed to prepare/enable per clk, err=%d\n",
270 clk_disable_unprepare(data
->clk_ahb
);
271 clk_disable_unprepare(data
->clk_ipg
);
275 ret
= clk_prepare_enable(data
->clk
);
278 "Failed to prepare/enable clk, err=%d\n",
287 static void imx_disable_unprepare_clks(struct device
*dev
)
289 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
291 if (data
->need_three_clks
) {
292 clk_disable_unprepare(data
->clk_per
);
293 clk_disable_unprepare(data
->clk_ahb
);
294 clk_disable_unprepare(data
->clk_ipg
);
296 clk_disable_unprepare(data
->clk
);
300 static int ci_hdrc_imx_notify_event(struct ci_hdrc
*ci
, unsigned int event
)
302 struct device
*dev
= ci
->dev
->parent
;
303 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
305 struct imx_usbmisc_data
*mdata
= data
->usbmisc_data
;
308 case CI_HDRC_IMX_HSIC_ACTIVE_EVENT
:
310 ret
= pinctrl_select_state(data
->pinctrl
,
311 data
->pinctrl_hsic_active
);
314 "hsic_active select failed, err=%d\n",
318 case CI_HDRC_IMX_HSIC_SUSPEND_EVENT
:
319 ret
= imx_usbmisc_hsic_set_connect(mdata
);
322 "hsic_set_connect failed, err=%d\n", ret
);
324 case CI_HDRC_CONTROLLER_VBUS_EVENT
:
326 ret
= imx_usbmisc_charger_detection(mdata
, true);
328 ret
= imx_usbmisc_charger_detection(mdata
, false);
330 schedule_work(&ci
->usb_phy
->chg_work
);
339 static int ci_hdrc_imx_probe(struct platform_device
*pdev
)
341 struct ci_hdrc_imx_data
*data
;
342 struct ci_hdrc_platform_data pdata
= {
343 .name
= dev_name(&pdev
->dev
),
344 .capoffset
= DEF_CAPOFFSET
,
345 .notify_event
= ci_hdrc_imx_notify_event
,
348 const struct ci_hdrc_imx_platform_flag
*imx_platform_flag
;
349 struct device_node
*np
= pdev
->dev
.of_node
;
350 struct device
*dev
= &pdev
->dev
;
352 imx_platform_flag
= of_device_get_match_data(&pdev
->dev
);
354 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
), GFP_KERNEL
);
358 data
->plat_data
= imx_platform_flag
;
359 pdata
.flags
|= imx_platform_flag
->flags
;
360 platform_set_drvdata(pdev
, data
);
361 data
->usbmisc_data
= usbmisc_get_init_data(dev
);
362 if (IS_ERR(data
->usbmisc_data
))
363 return PTR_ERR(data
->usbmisc_data
);
365 if ((of_usb_get_phy_mode(dev
->of_node
) == USBPHY_INTERFACE_MODE_HSIC
)
366 && data
->usbmisc_data
) {
367 pdata
.flags
|= CI_HDRC_IMX_IS_HSIC
;
368 data
->usbmisc_data
->hsic
= 1;
369 data
->pinctrl
= devm_pinctrl_get(dev
);
370 if (PTR_ERR(data
->pinctrl
) == -ENODEV
)
371 data
->pinctrl
= NULL
;
372 else if (IS_ERR(data
->pinctrl
))
373 return dev_err_probe(dev
, PTR_ERR(data
->pinctrl
),
374 "pinctrl get failed\n");
376 data
->hsic_pad_regulator
=
377 devm_regulator_get_optional(dev
, "hsic");
378 if (PTR_ERR(data
->hsic_pad_regulator
) == -ENODEV
) {
379 /* no pad regulator is needed */
380 data
->hsic_pad_regulator
= NULL
;
381 } else if (IS_ERR(data
->hsic_pad_regulator
))
382 return dev_err_probe(dev
, PTR_ERR(data
->hsic_pad_regulator
),
383 "Get HSIC pad regulator error\n");
385 if (data
->hsic_pad_regulator
) {
386 ret
= regulator_enable(data
->hsic_pad_regulator
);
389 "Failed to enable HSIC pad regulator\n");
395 /* HSIC pinctrl handling */
397 struct pinctrl_state
*pinctrl_hsic_idle
;
399 pinctrl_hsic_idle
= pinctrl_lookup_state(data
->pinctrl
, "idle");
400 if (IS_ERR(pinctrl_hsic_idle
)) {
402 "pinctrl_hsic_idle lookup failed, err=%ld\n",
403 PTR_ERR(pinctrl_hsic_idle
));
404 return PTR_ERR(pinctrl_hsic_idle
);
407 ret
= pinctrl_select_state(data
->pinctrl
, pinctrl_hsic_idle
);
409 dev_err(dev
, "hsic_idle select failed, err=%d\n", ret
);
413 data
->pinctrl_hsic_active
= pinctrl_lookup_state(data
->pinctrl
,
415 if (IS_ERR(data
->pinctrl_hsic_active
)) {
417 "pinctrl_hsic_active lookup failed, err=%ld\n",
418 PTR_ERR(data
->pinctrl_hsic_active
));
419 return PTR_ERR(data
->pinctrl_hsic_active
);
423 if (pdata
.flags
& CI_HDRC_PMQOS
)
424 cpu_latency_qos_add_request(&data
->pm_qos_req
, 0);
426 ret
= imx_get_clks(dev
);
428 goto disable_hsic_regulator
;
430 ret
= imx_prepare_enable_clks(dev
);
432 goto disable_hsic_regulator
;
434 ret
= clk_prepare_enable(data
->clk_wakeup
);
438 data
->phy
= devm_usb_get_phy_by_phandle(dev
, "fsl,usbphy", 0);
439 if (IS_ERR(data
->phy
)) {
440 ret
= PTR_ERR(data
->phy
);
441 if (ret
!= -ENODEV
) {
442 dev_err_probe(dev
, ret
, "Failed to parse fsl,usbphy\n");
445 data
->phy
= devm_usb_get_phy_by_phandle(dev
, "phys", 0);
446 if (IS_ERR(data
->phy
)) {
447 ret
= PTR_ERR(data
->phy
);
448 if (ret
== -ENODEV
) {
451 dev_err_probe(dev
, ret
, "Failed to parse phys\n");
457 pdata
.usb_phy
= data
->phy
;
458 if (data
->usbmisc_data
)
459 data
->usbmisc_data
->usb_phy
= data
->phy
;
461 if ((of_device_is_compatible(np
, "fsl,imx53-usb") ||
462 of_device_is_compatible(np
, "fsl,imx51-usb")) && pdata
.usb_phy
&&
463 of_usb_get_phy_mode(np
) == USBPHY_INTERFACE_MODE_ULPI
) {
464 pdata
.flags
|= CI_HDRC_OVERRIDE_PHY_CONTROL
;
465 data
->override_phy_control
= true;
466 usb_phy_init(pdata
.usb_phy
);
469 if (pdata
.flags
& CI_HDRC_SUPPORTS_RUNTIME_PM
)
470 data
->supports_runtime_pm
= true;
472 ret
= imx_usbmisc_init(data
->usbmisc_data
);
474 dev_err(dev
, "usbmisc init failed, ret=%d\n", ret
);
478 data
->ci_pdev
= ci_hdrc_add_device(dev
,
479 pdev
->resource
, pdev
->num_resources
,
481 if (IS_ERR(data
->ci_pdev
)) {
482 ret
= PTR_ERR(data
->ci_pdev
);
483 dev_err_probe(dev
, ret
, "ci_hdrc_add_device failed\n");
487 if (data
->usbmisc_data
) {
488 if (!IS_ERR(pdata
.id_extcon
.edev
) ||
489 of_property_read_bool(np
, "usb-role-switch"))
490 data
->usbmisc_data
->ext_id
= 1;
492 if (!IS_ERR(pdata
.vbus_extcon
.edev
) ||
493 of_property_read_bool(np
, "usb-role-switch"))
494 data
->usbmisc_data
->ext_vbus
= 1;
496 /* usbmisc needs to know dr mode to choose wakeup setting */
497 data
->usbmisc_data
->available_role
=
498 ci_hdrc_query_available_role(data
->ci_pdev
);
501 ret
= imx_usbmisc_init_post(data
->usbmisc_data
);
503 dev_err(dev
, "usbmisc post failed, ret=%d\n", ret
);
507 if (data
->supports_runtime_pm
) {
508 pm_runtime_set_active(dev
);
509 pm_runtime_enable(dev
);
512 device_set_wakeup_capable(dev
, true);
517 ci_hdrc_remove_device(data
->ci_pdev
);
519 clk_disable_unprepare(data
->clk_wakeup
);
521 imx_disable_unprepare_clks(dev
);
522 disable_hsic_regulator
:
523 if (data
->hsic_pad_regulator
)
524 /* don't overwrite original ret (cf. EPROBE_DEFER) */
525 regulator_disable(data
->hsic_pad_regulator
);
526 if (pdata
.flags
& CI_HDRC_PMQOS
)
527 cpu_latency_qos_remove_request(&data
->pm_qos_req
);
528 data
->ci_pdev
= NULL
;
532 static void ci_hdrc_imx_remove(struct platform_device
*pdev
)
534 struct ci_hdrc_imx_data
*data
= platform_get_drvdata(pdev
);
536 if (data
->supports_runtime_pm
) {
537 pm_runtime_get_sync(&pdev
->dev
);
538 pm_runtime_disable(&pdev
->dev
);
539 pm_runtime_put_noidle(&pdev
->dev
);
542 ci_hdrc_remove_device(data
->ci_pdev
);
543 if (data
->override_phy_control
)
544 usb_phy_shutdown(data
->phy
);
546 imx_disable_unprepare_clks(&pdev
->dev
);
547 clk_disable_unprepare(data
->clk_wakeup
);
548 if (data
->plat_data
->flags
& CI_HDRC_PMQOS
)
549 cpu_latency_qos_remove_request(&data
->pm_qos_req
);
550 if (data
->hsic_pad_regulator
)
551 regulator_disable(data
->hsic_pad_regulator
);
555 static void ci_hdrc_imx_shutdown(struct platform_device
*pdev
)
557 ci_hdrc_imx_remove(pdev
);
560 static int imx_controller_suspend(struct device
*dev
,
563 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
566 dev_dbg(dev
, "at %s\n", __func__
);
568 ret
= imx_usbmisc_suspend(data
->usbmisc_data
,
569 PMSG_IS_AUTO(msg
) || device_may_wakeup(dev
));
572 "usbmisc suspend failed, ret=%d\n", ret
);
576 imx_disable_unprepare_clks(dev
);
577 if (data
->plat_data
->flags
& CI_HDRC_PMQOS
)
578 cpu_latency_qos_remove_request(&data
->pm_qos_req
);
585 static int imx_controller_resume(struct device
*dev
,
588 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
591 dev_dbg(dev
, "at %s\n", __func__
);
598 if (data
->plat_data
->flags
& CI_HDRC_PMQOS
)
599 cpu_latency_qos_add_request(&data
->pm_qos_req
, 0);
601 ret
= imx_prepare_enable_clks(dev
);
605 data
->in_lpm
= false;
607 ret
= imx_usbmisc_resume(data
->usbmisc_data
,
608 PMSG_IS_AUTO(msg
) || device_may_wakeup(dev
));
610 dev_err(dev
, "usbmisc resume failed, ret=%d\n", ret
);
617 imx_disable_unprepare_clks(dev
);
621 static int ci_hdrc_imx_suspend(struct device
*dev
)
625 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
628 /* The core's suspend doesn't run */
631 ret
= imx_controller_suspend(dev
, PMSG_SUSPEND
);
635 pinctrl_pm_select_sleep_state(dev
);
639 static int ci_hdrc_imx_resume(struct device
*dev
)
641 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
644 pinctrl_pm_select_default_state(dev
);
645 ret
= imx_controller_resume(dev
, PMSG_RESUME
);
646 if (!ret
&& data
->supports_runtime_pm
) {
647 pm_runtime_disable(dev
);
648 pm_runtime_set_active(dev
);
649 pm_runtime_enable(dev
);
655 static int ci_hdrc_imx_runtime_suspend(struct device
*dev
)
657 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
664 return imx_controller_suspend(dev
, PMSG_AUTO_SUSPEND
);
667 static int ci_hdrc_imx_runtime_resume(struct device
*dev
)
669 return imx_controller_resume(dev
, PMSG_AUTO_RESUME
);
672 static const struct dev_pm_ops ci_hdrc_imx_pm_ops
= {
673 SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend
, ci_hdrc_imx_resume
)
674 RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend
, ci_hdrc_imx_runtime_resume
, NULL
)
676 static struct platform_driver ci_hdrc_imx_driver
= {
677 .probe
= ci_hdrc_imx_probe
,
678 .remove_new
= ci_hdrc_imx_remove
,
679 .shutdown
= ci_hdrc_imx_shutdown
,
682 .of_match_table
= ci_hdrc_imx_dt_ids
,
683 .pm
= pm_ptr(&ci_hdrc_imx_pm_ops
),
687 module_platform_driver(ci_hdrc_imx_driver
);
689 MODULE_ALIAS("platform:imx-usb");
690 MODULE_LICENSE("GPL");
691 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
692 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
693 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");