forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/usb/chipidea/ci_hdrc_imx.c
....@@ -7,13 +7,13 @@
77
88 #include <linux/module.h>
99 #include <linux/of_platform.h>
10
-#include <linux/of_gpio.h>
1110 #include <linux/platform_device.h>
1211 #include <linux/pm_runtime.h>
13
-#include <linux/dma-mapping.h>
1412 #include <linux/usb/chipidea.h>
1513 #include <linux/usb/of.h>
1614 #include <linux/clk.h>
15
+#include <linux/pinctrl/consumer.h>
16
+#include <linux/pm_qos.h>
1717
1818 #include "ci.h"
1919 #include "ci_hdrc_imx.h"
....@@ -65,6 +65,15 @@
6565 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
6666 };
6767
68
+static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
69
+ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
70
+ CI_HDRC_PMQOS,
71
+};
72
+
73
+static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = {
74
+ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
75
+};
76
+
6877 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
6978 { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
7079 { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
....@@ -74,6 +83,8 @@
7483 { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
7584 { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
7685 { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
86
+ { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
87
+ { .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data},
7788 { /* sentinel */ }
7889 };
7990 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
....@@ -86,12 +97,17 @@
8697 bool supports_runtime_pm;
8798 bool override_phy_control;
8899 bool in_lpm;
100
+ struct pinctrl *pinctrl;
101
+ struct pinctrl_state *pinctrl_hsic_active;
102
+ struct regulator *hsic_pad_regulator;
89103 /* SoC before i.mx6 (except imx23/imx28) needs three clks */
90104 bool need_three_clks;
91105 struct clk *clk_ipg;
92106 struct clk *clk_ahb;
93107 struct clk *clk_per;
94108 /* --------------------------------- */
109
+ struct pm_qos_request pm_qos_req;
110
+ const struct ci_hdrc_imx_platform_flag *plat_data;
95111 };
96112
97113 /* Common functions shared by usbmisc drivers */
....@@ -137,17 +153,34 @@
137153 }
138154 data->dev = &misc_pdev->dev;
139155
140
- if (of_find_property(np, "disable-over-current", NULL))
156
+ /*
157
+ * Check the various over current related properties. If over current
158
+ * detection is disabled we're not interested in the polarity.
159
+ */
160
+ if (of_find_property(np, "disable-over-current", NULL)) {
141161 data->disable_oc = 1;
162
+ } else if (of_find_property(np, "over-current-active-high", NULL)) {
163
+ data->oc_pol_active_low = 0;
164
+ data->oc_pol_configured = 1;
165
+ } else if (of_find_property(np, "over-current-active-low", NULL)) {
166
+ data->oc_pol_active_low = 1;
167
+ data->oc_pol_configured = 1;
168
+ } else {
169
+ dev_warn(dev, "No over current polarity defined\n");
170
+ }
142171
143
- if (of_find_property(np, "over-current-active-high", NULL))
144
- data->oc_polarity = 1;
145
-
146
- if (of_find_property(np, "external-vbus-divider", NULL))
147
- data->evdo = 1;
172
+ data->pwr_pol = of_property_read_bool(np, "power-active-high");
173
+ data->evdo = of_property_read_bool(np, "external-vbus-divider");
148174
149175 if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
150176 data->ulpi = 1;
177
+
178
+ if (of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control",
179
+ &data->emp_curr_control))
180
+ data->emp_curr_control = -1;
181
+ if (of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust",
182
+ &data->dc_vol_level_adjust))
183
+ data->dc_vol_level_adjust = -1;
151184
152185 return data;
153186 }
....@@ -250,19 +283,60 @@
250283 }
251284 }
252285
286
+static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
287
+{
288
+ struct device *dev = ci->dev->parent;
289
+ struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
290
+ int ret = 0;
291
+ struct imx_usbmisc_data *mdata = data->usbmisc_data;
292
+
293
+ switch (event) {
294
+ case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
295
+ if (data->pinctrl) {
296
+ ret = pinctrl_select_state(data->pinctrl,
297
+ data->pinctrl_hsic_active);
298
+ if (ret)
299
+ dev_err(dev,
300
+ "hsic_active select failed, err=%d\n",
301
+ ret);
302
+ }
303
+ break;
304
+ case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
305
+ ret = imx_usbmisc_hsic_set_connect(mdata);
306
+ if (ret)
307
+ dev_err(dev,
308
+ "hsic_set_connect failed, err=%d\n", ret);
309
+ break;
310
+ case CI_HDRC_CONTROLLER_VBUS_EVENT:
311
+ if (ci->vbus_active)
312
+ ret = imx_usbmisc_charger_detection(mdata, true);
313
+ else
314
+ ret = imx_usbmisc_charger_detection(mdata, false);
315
+ if (ci->usb_phy)
316
+ schedule_work(&ci->usb_phy->chg_work);
317
+ break;
318
+ default:
319
+ break;
320
+ }
321
+
322
+ return ret;
323
+}
324
+
253325 static int ci_hdrc_imx_probe(struct platform_device *pdev)
254326 {
255327 struct ci_hdrc_imx_data *data;
256328 struct ci_hdrc_platform_data pdata = {
257329 .name = dev_name(&pdev->dev),
258330 .capoffset = DEF_CAPOFFSET,
331
+ .notify_event = ci_hdrc_imx_notify_event,
259332 };
260333 int ret;
261334 const struct of_device_id *of_id;
262335 const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
263336 struct device_node *np = pdev->dev.of_node;
337
+ struct device *dev = &pdev->dev;
264338
265
- of_id = of_match_device(ci_hdrc_imx_dt_ids, &pdev->dev);
339
+ of_id = of_match_device(ci_hdrc_imx_dt_ids, dev);
266340 if (!of_id)
267341 return -ENODEV;
268342
....@@ -272,29 +346,107 @@
272346 if (!data)
273347 return -ENOMEM;
274348
349
+ data->plat_data = imx_platform_flag;
350
+ pdata.flags |= imx_platform_flag->flags;
275351 platform_set_drvdata(pdev, data);
276
- data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
352
+ data->usbmisc_data = usbmisc_get_init_data(dev);
277353 if (IS_ERR(data->usbmisc_data))
278354 return PTR_ERR(data->usbmisc_data);
279355
280
- ret = imx_get_clks(&pdev->dev);
281
- if (ret)
282
- return ret;
356
+ if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC)
357
+ && data->usbmisc_data) {
358
+ pdata.flags |= CI_HDRC_IMX_IS_HSIC;
359
+ data->usbmisc_data->hsic = 1;
360
+ data->pinctrl = devm_pinctrl_get(dev);
361
+ if (PTR_ERR(data->pinctrl) == -ENODEV)
362
+ data->pinctrl = NULL;
363
+ else if (IS_ERR(data->pinctrl)) {
364
+ if (PTR_ERR(data->pinctrl) != -EPROBE_DEFER)
365
+ dev_err(dev, "pinctrl get failed, err=%ld\n",
366
+ PTR_ERR(data->pinctrl));
367
+ return PTR_ERR(data->pinctrl);
368
+ }
283369
284
- ret = imx_prepare_enable_clks(&pdev->dev);
285
- if (ret)
286
- return ret;
370
+ data->hsic_pad_regulator =
371
+ devm_regulator_get_optional(dev, "hsic");
372
+ if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
373
+ /* no pad regualator is needed */
374
+ data->hsic_pad_regulator = NULL;
375
+ } else if (IS_ERR(data->hsic_pad_regulator)) {
376
+ if (PTR_ERR(data->hsic_pad_regulator) != -EPROBE_DEFER)
377
+ dev_err(dev,
378
+ "Get HSIC pad regulator error: %ld\n",
379
+ PTR_ERR(data->hsic_pad_regulator));
380
+ return PTR_ERR(data->hsic_pad_regulator);
381
+ }
287382
288
- data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
383
+ if (data->hsic_pad_regulator) {
384
+ ret = regulator_enable(data->hsic_pad_regulator);
385
+ if (ret) {
386
+ dev_err(dev,
387
+ "Failed to enable HSIC pad regulator\n");
388
+ return ret;
389
+ }
390
+ }
391
+ }
392
+
393
+ /* HSIC pinctrl handling */
394
+ if (data->pinctrl) {
395
+ struct pinctrl_state *pinctrl_hsic_idle;
396
+
397
+ pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
398
+ if (IS_ERR(pinctrl_hsic_idle)) {
399
+ dev_err(dev,
400
+ "pinctrl_hsic_idle lookup failed, err=%ld\n",
401
+ PTR_ERR(pinctrl_hsic_idle));
402
+ return PTR_ERR(pinctrl_hsic_idle);
403
+ }
404
+
405
+ ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
406
+ if (ret) {
407
+ dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
408
+ return ret;
409
+ }
410
+
411
+ data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
412
+ "active");
413
+ if (IS_ERR(data->pinctrl_hsic_active)) {
414
+ dev_err(dev,
415
+ "pinctrl_hsic_active lookup failed, err=%ld\n",
416
+ PTR_ERR(data->pinctrl_hsic_active));
417
+ return PTR_ERR(data->pinctrl_hsic_active);
418
+ }
419
+ }
420
+
421
+ if (pdata.flags & CI_HDRC_PMQOS)
422
+ cpu_latency_qos_add_request(&data->pm_qos_req, 0);
423
+
424
+ ret = imx_get_clks(dev);
425
+ if (ret)
426
+ goto disable_hsic_regulator;
427
+
428
+ ret = imx_prepare_enable_clks(dev);
429
+ if (ret)
430
+ goto disable_hsic_regulator;
431
+
432
+ data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
289433 if (IS_ERR(data->phy)) {
290434 ret = PTR_ERR(data->phy);
291
- /* Return -EINVAL if no usbphy is available */
292
- if (ret == -ENODEV)
293
- ret = -EINVAL;
294
- goto err_clk;
435
+ if (ret != -ENODEV)
436
+ goto err_clk;
437
+ data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
438
+ if (IS_ERR(data->phy)) {
439
+ ret = PTR_ERR(data->phy);
440
+ if (ret == -ENODEV)
441
+ data->phy = NULL;
442
+ else
443
+ goto err_clk;
444
+ }
295445 }
296446
297447 pdata.usb_phy = data->phy;
448
+ if (data->usbmisc_data)
449
+ data->usbmisc_data->usb_phy = data->phy;
298450
299451 if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
300452 of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
....@@ -304,46 +456,66 @@
304456 usb_phy_init(pdata.usb_phy);
305457 }
306458
307
- pdata.flags |= imx_platform_flag->flags;
308459 if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
309460 data->supports_runtime_pm = true;
310461
311462 ret = imx_usbmisc_init(data->usbmisc_data);
312463 if (ret) {
313
- dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n", ret);
464
+ dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
314465 goto err_clk;
315466 }
316467
317
- data->ci_pdev = ci_hdrc_add_device(&pdev->dev,
468
+ data->ci_pdev = ci_hdrc_add_device(dev,
318469 pdev->resource, pdev->num_resources,
319470 &pdata);
320471 if (IS_ERR(data->ci_pdev)) {
321472 ret = PTR_ERR(data->ci_pdev);
322473 if (ret != -EPROBE_DEFER)
323
- dev_err(&pdev->dev,
324
- "ci_hdrc_add_device failed, err=%d\n", ret);
474
+ dev_err(dev, "ci_hdrc_add_device failed, err=%d\n",
475
+ ret);
325476 goto err_clk;
477
+ }
478
+
479
+ if (data->usbmisc_data) {
480
+ if (!IS_ERR(pdata.id_extcon.edev) ||
481
+ of_property_read_bool(np, "usb-role-switch"))
482
+ data->usbmisc_data->ext_id = 1;
483
+
484
+ if (!IS_ERR(pdata.vbus_extcon.edev) ||
485
+ of_property_read_bool(np, "usb-role-switch"))
486
+ data->usbmisc_data->ext_vbus = 1;
487
+
488
+ /* usbmisc needs to know dr mode to choose wakeup setting */
489
+ data->usbmisc_data->available_role =
490
+ ci_hdrc_query_available_role(data->ci_pdev);
326491 }
327492
328493 ret = imx_usbmisc_init_post(data->usbmisc_data);
329494 if (ret) {
330
- dev_err(&pdev->dev, "usbmisc post failed, ret=%d\n", ret);
495
+ dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
331496 goto disable_device;
332497 }
333498
334499 if (data->supports_runtime_pm) {
335
- pm_runtime_set_active(&pdev->dev);
336
- pm_runtime_enable(&pdev->dev);
500
+ pm_runtime_set_active(dev);
501
+ pm_runtime_enable(dev);
337502 }
338503
339
- device_set_wakeup_capable(&pdev->dev, true);
504
+ device_set_wakeup_capable(dev, true);
340505
341506 return 0;
342507
343508 disable_device:
344509 ci_hdrc_remove_device(data->ci_pdev);
345510 err_clk:
346
- imx_disable_unprepare_clks(&pdev->dev);
511
+ imx_disable_unprepare_clks(dev);
512
+disable_hsic_regulator:
513
+ if (data->hsic_pad_regulator)
514
+ /* don't overwrite original ret (cf. EPROBE_DEFER) */
515
+ regulator_disable(data->hsic_pad_regulator);
516
+ if (pdata.flags & CI_HDRC_PMQOS)
517
+ cpu_latency_qos_remove_request(&data->pm_qos_req);
518
+ data->ci_pdev = NULL;
347519 return ret;
348520 }
349521
....@@ -356,10 +528,17 @@
356528 pm_runtime_disable(&pdev->dev);
357529 pm_runtime_put_noidle(&pdev->dev);
358530 }
359
- ci_hdrc_remove_device(data->ci_pdev);
531
+ if (data->ci_pdev)
532
+ ci_hdrc_remove_device(data->ci_pdev);
360533 if (data->override_phy_control)
361534 usb_phy_shutdown(data->phy);
362
- imx_disable_unprepare_clks(&pdev->dev);
535
+ if (data->ci_pdev) {
536
+ imx_disable_unprepare_clks(&pdev->dev);
537
+ if (data->plat_data->flags & CI_HDRC_PMQOS)
538
+ cpu_latency_qos_remove_request(&data->pm_qos_req);
539
+ if (data->hsic_pad_regulator)
540
+ regulator_disable(data->hsic_pad_regulator);
541
+ }
363542
364543 return 0;
365544 }
....@@ -369,20 +548,29 @@
369548 ci_hdrc_imx_remove(pdev);
370549 }
371550
372
-#ifdef CONFIG_PM
373
-static int imx_controller_suspend(struct device *dev)
551
+static int __maybe_unused imx_controller_suspend(struct device *dev)
374552 {
375553 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
554
+ int ret = 0;
376555
377556 dev_dbg(dev, "at %s\n", __func__);
378557
558
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false);
559
+ if (ret) {
560
+ dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
561
+ return ret;
562
+ }
563
+
379564 imx_disable_unprepare_clks(dev);
565
+ if (data->plat_data->flags & CI_HDRC_PMQOS)
566
+ cpu_latency_qos_remove_request(&data->pm_qos_req);
567
+
380568 data->in_lpm = true;
381569
382570 return 0;
383571 }
384572
385
-static int imx_controller_resume(struct device *dev)
573
+static int __maybe_unused imx_controller_resume(struct device *dev)
386574 {
387575 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
388576 int ret = 0;
....@@ -393,6 +581,9 @@
393581 WARN_ON(1);
394582 return 0;
395583 }
584
+
585
+ if (data->plat_data->flags & CI_HDRC_PMQOS)
586
+ cpu_latency_qos_add_request(&data->pm_qos_req, 0);
396587
397588 ret = imx_prepare_enable_clks(dev);
398589 if (ret)
....@@ -406,15 +597,22 @@
406597 goto clk_disable;
407598 }
408599
600
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true);
601
+ if (ret) {
602
+ dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
603
+ goto hsic_set_clk_fail;
604
+ }
605
+
409606 return 0;
410607
608
+hsic_set_clk_fail:
609
+ imx_usbmisc_set_wakeup(data->usbmisc_data, true);
411610 clk_disable:
412611 imx_disable_unprepare_clks(dev);
413612 return ret;
414613 }
415614
416
-#ifdef CONFIG_PM_SLEEP
417
-static int ci_hdrc_imx_suspend(struct device *dev)
615
+static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev)
418616 {
419617 int ret;
420618
....@@ -433,14 +631,20 @@
433631 }
434632 }
435633
436
- return imx_controller_suspend(dev);
634
+ ret = imx_controller_suspend(dev);
635
+ if (ret)
636
+ return ret;
637
+
638
+ pinctrl_pm_select_sleep_state(dev);
639
+ return ret;
437640 }
438641
439
-static int ci_hdrc_imx_resume(struct device *dev)
642
+static int __maybe_unused ci_hdrc_imx_resume(struct device *dev)
440643 {
441644 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
442645 int ret;
443646
647
+ pinctrl_pm_select_default_state(dev);
444648 ret = imx_controller_resume(dev);
445649 if (!ret && data->supports_runtime_pm) {
446650 pm_runtime_disable(dev);
....@@ -450,9 +654,8 @@
450654
451655 return ret;
452656 }
453
-#endif /* CONFIG_PM_SLEEP */
454657
455
-static int ci_hdrc_imx_runtime_suspend(struct device *dev)
658
+static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev)
456659 {
457660 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
458661 int ret;
....@@ -471,12 +674,10 @@
471674 return imx_controller_suspend(dev);
472675 }
473676
474
-static int ci_hdrc_imx_runtime_resume(struct device *dev)
677
+static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev)
475678 {
476679 return imx_controller_resume(dev);
477680 }
478
-
479
-#endif /* CONFIG_PM */
480681
481682 static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
482683 SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
....@@ -497,7 +698,7 @@
497698 module_platform_driver(ci_hdrc_imx_driver);
498699
499700 MODULE_ALIAS("platform:imx-usb");
500
-MODULE_LICENSE("GPL v2");
701
+MODULE_LICENSE("GPL");
501702 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
502703 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
503704 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");