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 .flags
= CI_HDRC_HAS_SHORT_PKT_LIMIT
,
346 .notify_event
= ci_hdrc_imx_notify_event
,
349 const struct ci_hdrc_imx_platform_flag
*imx_platform_flag
;
350 struct device_node
*np
= pdev
->dev
.of_node
;
351 struct device
*dev
= &pdev
->dev
;
353 imx_platform_flag
= of_device_get_match_data(&pdev
->dev
);
355 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
), GFP_KERNEL
);
359 data
->plat_data
= imx_platform_flag
;
360 pdata
.flags
|= imx_platform_flag
->flags
;
361 platform_set_drvdata(pdev
, data
);
362 data
->usbmisc_data
= usbmisc_get_init_data(dev
);
363 if (IS_ERR(data
->usbmisc_data
))
364 return PTR_ERR(data
->usbmisc_data
);
366 if ((of_usb_get_phy_mode(dev
->of_node
) == USBPHY_INTERFACE_MODE_HSIC
)
367 && data
->usbmisc_data
) {
368 pdata
.flags
|= CI_HDRC_IMX_IS_HSIC
;
369 data
->usbmisc_data
->hsic
= 1;
370 data
->pinctrl
= devm_pinctrl_get(dev
);
371 if (PTR_ERR(data
->pinctrl
) == -ENODEV
)
372 data
->pinctrl
= NULL
;
373 else if (IS_ERR(data
->pinctrl
)) {
374 ret
= dev_err_probe(dev
, PTR_ERR(data
->pinctrl
),
375 "pinctrl get failed\n");
379 data
->hsic_pad_regulator
=
380 devm_regulator_get_optional(dev
, "hsic");
381 if (PTR_ERR(data
->hsic_pad_regulator
) == -ENODEV
) {
382 /* no pad regulator is needed */
383 data
->hsic_pad_regulator
= NULL
;
384 } else if (IS_ERR(data
->hsic_pad_regulator
)) {
385 ret
= dev_err_probe(dev
, PTR_ERR(data
->hsic_pad_regulator
),
386 "Get HSIC pad regulator error\n");
390 if (data
->hsic_pad_regulator
) {
391 ret
= regulator_enable(data
->hsic_pad_regulator
);
394 "Failed to enable HSIC pad regulator\n");
400 /* HSIC pinctrl handling */
402 struct pinctrl_state
*pinctrl_hsic_idle
;
404 pinctrl_hsic_idle
= pinctrl_lookup_state(data
->pinctrl
, "idle");
405 if (IS_ERR(pinctrl_hsic_idle
)) {
407 "pinctrl_hsic_idle lookup failed, err=%ld\n",
408 PTR_ERR(pinctrl_hsic_idle
));
409 ret
= PTR_ERR(pinctrl_hsic_idle
);
413 ret
= pinctrl_select_state(data
->pinctrl
, pinctrl_hsic_idle
);
415 dev_err(dev
, "hsic_idle select failed, err=%d\n", ret
);
419 data
->pinctrl_hsic_active
= pinctrl_lookup_state(data
->pinctrl
,
421 if (IS_ERR(data
->pinctrl_hsic_active
)) {
423 "pinctrl_hsic_active lookup failed, err=%ld\n",
424 PTR_ERR(data
->pinctrl_hsic_active
));
425 ret
= PTR_ERR(data
->pinctrl_hsic_active
);
430 if (pdata
.flags
& CI_HDRC_PMQOS
)
431 cpu_latency_qos_add_request(&data
->pm_qos_req
, 0);
433 ret
= imx_get_clks(dev
);
435 goto disable_hsic_regulator
;
437 ret
= imx_prepare_enable_clks(dev
);
439 goto disable_hsic_regulator
;
441 ret
= clk_prepare_enable(data
->clk_wakeup
);
445 data
->phy
= devm_usb_get_phy_by_phandle(dev
, "fsl,usbphy", 0);
446 if (IS_ERR(data
->phy
)) {
447 ret
= PTR_ERR(data
->phy
);
448 if (ret
!= -ENODEV
) {
449 dev_err_probe(dev
, ret
, "Failed to parse fsl,usbphy\n");
452 data
->phy
= devm_usb_get_phy_by_phandle(dev
, "phys", 0);
453 if (IS_ERR(data
->phy
)) {
454 ret
= PTR_ERR(data
->phy
);
455 if (ret
== -ENODEV
) {
458 dev_err_probe(dev
, ret
, "Failed to parse phys\n");
464 pdata
.usb_phy
= data
->phy
;
465 if (data
->usbmisc_data
)
466 data
->usbmisc_data
->usb_phy
= data
->phy
;
468 if ((of_device_is_compatible(np
, "fsl,imx53-usb") ||
469 of_device_is_compatible(np
, "fsl,imx51-usb")) && pdata
.usb_phy
&&
470 of_usb_get_phy_mode(np
) == USBPHY_INTERFACE_MODE_ULPI
) {
471 pdata
.flags
|= CI_HDRC_OVERRIDE_PHY_CONTROL
;
472 data
->override_phy_control
= true;
473 usb_phy_init(pdata
.usb_phy
);
476 if (pdata
.flags
& CI_HDRC_SUPPORTS_RUNTIME_PM
)
477 data
->supports_runtime_pm
= true;
479 ret
= imx_usbmisc_init(data
->usbmisc_data
);
481 dev_err(dev
, "usbmisc init failed, ret=%d\n", ret
);
485 data
->ci_pdev
= ci_hdrc_add_device(dev
,
486 pdev
->resource
, pdev
->num_resources
,
488 if (IS_ERR(data
->ci_pdev
)) {
489 ret
= PTR_ERR(data
->ci_pdev
);
490 dev_err_probe(dev
, ret
, "ci_hdrc_add_device failed\n");
494 if (data
->usbmisc_data
) {
495 if (!IS_ERR(pdata
.id_extcon
.edev
) ||
496 of_property_read_bool(np
, "usb-role-switch"))
497 data
->usbmisc_data
->ext_id
= 1;
499 if (!IS_ERR(pdata
.vbus_extcon
.edev
) ||
500 of_property_read_bool(np
, "usb-role-switch"))
501 data
->usbmisc_data
->ext_vbus
= 1;
503 /* usbmisc needs to know dr mode to choose wakeup setting */
504 data
->usbmisc_data
->available_role
=
505 ci_hdrc_query_available_role(data
->ci_pdev
);
508 ret
= imx_usbmisc_init_post(data
->usbmisc_data
);
510 dev_err(dev
, "usbmisc post failed, ret=%d\n", ret
);
514 if (data
->supports_runtime_pm
) {
515 pm_runtime_set_active(dev
);
516 pm_runtime_enable(dev
);
519 device_set_wakeup_capable(dev
, true);
524 ci_hdrc_remove_device(data
->ci_pdev
);
526 clk_disable_unprepare(data
->clk_wakeup
);
528 imx_disable_unprepare_clks(dev
);
529 disable_hsic_regulator
:
530 if (data
->hsic_pad_regulator
)
531 /* don't overwrite original ret (cf. EPROBE_DEFER) */
532 regulator_disable(data
->hsic_pad_regulator
);
533 if (pdata
.flags
& CI_HDRC_PMQOS
)
534 cpu_latency_qos_remove_request(&data
->pm_qos_req
);
535 data
->ci_pdev
= NULL
;
537 put_device(data
->usbmisc_data
->dev
);
541 static void ci_hdrc_imx_remove(struct platform_device
*pdev
)
543 struct ci_hdrc_imx_data
*data
= platform_get_drvdata(pdev
);
545 if (data
->supports_runtime_pm
) {
546 pm_runtime_get_sync(&pdev
->dev
);
547 pm_runtime_disable(&pdev
->dev
);
548 pm_runtime_put_noidle(&pdev
->dev
);
551 ci_hdrc_remove_device(data
->ci_pdev
);
552 if (data
->override_phy_control
)
553 usb_phy_shutdown(data
->phy
);
555 imx_disable_unprepare_clks(&pdev
->dev
);
556 clk_disable_unprepare(data
->clk_wakeup
);
557 if (data
->plat_data
->flags
& CI_HDRC_PMQOS
)
558 cpu_latency_qos_remove_request(&data
->pm_qos_req
);
559 if (data
->hsic_pad_regulator
)
560 regulator_disable(data
->hsic_pad_regulator
);
562 put_device(data
->usbmisc_data
->dev
);
565 static void ci_hdrc_imx_shutdown(struct platform_device
*pdev
)
567 ci_hdrc_imx_remove(pdev
);
570 static int imx_controller_suspend(struct device
*dev
,
573 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
576 dev_dbg(dev
, "at %s\n", __func__
);
578 ret
= imx_usbmisc_suspend(data
->usbmisc_data
,
579 PMSG_IS_AUTO(msg
) || device_may_wakeup(dev
));
582 "usbmisc suspend failed, ret=%d\n", ret
);
586 imx_disable_unprepare_clks(dev
);
587 if (data
->plat_data
->flags
& CI_HDRC_PMQOS
)
588 cpu_latency_qos_remove_request(&data
->pm_qos_req
);
595 static int imx_controller_resume(struct device
*dev
,
598 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
601 dev_dbg(dev
, "at %s\n", __func__
);
608 if (data
->plat_data
->flags
& CI_HDRC_PMQOS
)
609 cpu_latency_qos_add_request(&data
->pm_qos_req
, 0);
611 ret
= imx_prepare_enable_clks(dev
);
615 data
->in_lpm
= false;
617 ret
= imx_usbmisc_resume(data
->usbmisc_data
,
618 PMSG_IS_AUTO(msg
) || device_may_wakeup(dev
));
620 dev_err(dev
, "usbmisc resume failed, ret=%d\n", ret
);
627 imx_disable_unprepare_clks(dev
);
631 static int ci_hdrc_imx_suspend(struct device
*dev
)
635 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
638 /* The core's suspend doesn't run */
641 ret
= imx_controller_suspend(dev
, PMSG_SUSPEND
);
645 pinctrl_pm_select_sleep_state(dev
);
649 static int ci_hdrc_imx_resume(struct device
*dev
)
651 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
654 pinctrl_pm_select_default_state(dev
);
655 ret
= imx_controller_resume(dev
, PMSG_RESUME
);
656 if (!ret
&& data
->supports_runtime_pm
) {
657 pm_runtime_disable(dev
);
658 pm_runtime_set_active(dev
);
659 pm_runtime_enable(dev
);
665 static int ci_hdrc_imx_runtime_suspend(struct device
*dev
)
667 struct ci_hdrc_imx_data
*data
= dev_get_drvdata(dev
);
674 return imx_controller_suspend(dev
, PMSG_AUTO_SUSPEND
);
677 static int ci_hdrc_imx_runtime_resume(struct device
*dev
)
679 return imx_controller_resume(dev
, PMSG_AUTO_RESUME
);
682 static const struct dev_pm_ops ci_hdrc_imx_pm_ops
= {
683 SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend
, ci_hdrc_imx_resume
)
684 RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend
, ci_hdrc_imx_runtime_resume
, NULL
)
686 static struct platform_driver ci_hdrc_imx_driver
= {
687 .probe
= ci_hdrc_imx_probe
,
688 .remove
= ci_hdrc_imx_remove
,
689 .shutdown
= ci_hdrc_imx_shutdown
,
692 .of_match_table
= ci_hdrc_imx_dt_ids
,
693 .pm
= pm_ptr(&ci_hdrc_imx_pm_ops
),
697 module_platform_driver(ci_hdrc_imx_driver
);
699 MODULE_ALIAS("platform:imx-usb");
700 MODULE_LICENSE("GPL");
701 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
702 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
703 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");