forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
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,11 @@
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
+
6873 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
6974 { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
7075 { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
....@@ -74,6 +79,7 @@
7479 { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
7580 { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
7681 { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
82
+ { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
7783 { /* sentinel */ }
7884 };
7985 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
....@@ -86,12 +92,17 @@
8692 bool supports_runtime_pm;
8793 bool override_phy_control;
8894 bool in_lpm;
95
+ struct pinctrl *pinctrl;
96
+ struct pinctrl_state *pinctrl_hsic_active;
97
+ struct regulator *hsic_pad_regulator;
8998 /* SoC before i.mx6 (except imx23/imx28) needs three clks */
9099 bool need_three_clks;
91100 struct clk *clk_ipg;
92101 struct clk *clk_ahb;
93102 struct clk *clk_per;
94103 /* --------------------------------- */
104
+ struct pm_qos_request pm_qos_req;
105
+ const struct ci_hdrc_imx_platform_flag *plat_data;
95106 };
96107
97108 /* Common functions shared by usbmisc drivers */
....@@ -137,17 +148,32 @@
137148 }
138149 data->dev = &misc_pdev->dev;
139150
140
- if (of_find_property(np, "disable-over-current", NULL))
151
+ /*
152
+ * Check the various over current related properties. If over current
153
+ * detection is disabled we're not interested in the polarity.
154
+ */
155
+ if (of_find_property(np, "disable-over-current", NULL)) {
141156 data->disable_oc = 1;
157
+ } else if (of_find_property(np, "over-current-active-high", NULL)) {
158
+ data->oc_pol_active_low = 0;
159
+ data->oc_pol_configured = 1;
160
+ } else if (of_find_property(np, "over-current-active-low", NULL)) {
161
+ data->oc_pol_active_low = 1;
162
+ data->oc_pol_configured = 1;
163
+ } else {
164
+ dev_warn(dev, "No over current polarity defined\n");
165
+ }
142166
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;
167
+ data->pwr_pol = of_property_read_bool(np, "power-active-high");
168
+ data->evdo = of_property_read_bool(np, "external-vbus-divider");
148169
149170 if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
150171 data->ulpi = 1;
172
+
173
+ of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control",
174
+ &data->emp_curr_control);
175
+ of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust",
176
+ &data->dc_vol_level_adjust);
151177
152178 return data;
153179 }
....@@ -250,19 +276,60 @@
250276 }
251277 }
252278
279
+static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
280
+{
281
+ struct device *dev = ci->dev->parent;
282
+ struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
283
+ int ret = 0;
284
+ struct imx_usbmisc_data *mdata = data->usbmisc_data;
285
+
286
+ switch (event) {
287
+ case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
288
+ if (data->pinctrl) {
289
+ ret = pinctrl_select_state(data->pinctrl,
290
+ data->pinctrl_hsic_active);
291
+ if (ret)
292
+ dev_err(dev,
293
+ "hsic_active select failed, err=%d\n",
294
+ ret);
295
+ }
296
+ break;
297
+ case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
298
+ ret = imx_usbmisc_hsic_set_connect(mdata);
299
+ if (ret)
300
+ dev_err(dev,
301
+ "hsic_set_connect failed, err=%d\n", ret);
302
+ break;
303
+ case CI_HDRC_CONTROLLER_VBUS_EVENT:
304
+ if (ci->vbus_active)
305
+ ret = imx_usbmisc_charger_detection(mdata, true);
306
+ else
307
+ ret = imx_usbmisc_charger_detection(mdata, false);
308
+ if (ci->usb_phy)
309
+ schedule_work(&ci->usb_phy->chg_work);
310
+ break;
311
+ default:
312
+ break;
313
+ }
314
+
315
+ return ret;
316
+}
317
+
253318 static int ci_hdrc_imx_probe(struct platform_device *pdev)
254319 {
255320 struct ci_hdrc_imx_data *data;
256321 struct ci_hdrc_platform_data pdata = {
257322 .name = dev_name(&pdev->dev),
258323 .capoffset = DEF_CAPOFFSET,
324
+ .notify_event = ci_hdrc_imx_notify_event,
259325 };
260326 int ret;
261327 const struct of_device_id *of_id;
262328 const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
263329 struct device_node *np = pdev->dev.of_node;
330
+ struct device *dev = &pdev->dev;
264331
265
- of_id = of_match_device(ci_hdrc_imx_dt_ids, &pdev->dev);
332
+ of_id = of_match_device(ci_hdrc_imx_dt_ids, dev);
266333 if (!of_id)
267334 return -ENODEV;
268335
....@@ -272,29 +339,107 @@
272339 if (!data)
273340 return -ENOMEM;
274341
342
+ data->plat_data = imx_platform_flag;
343
+ pdata.flags |= imx_platform_flag->flags;
275344 platform_set_drvdata(pdev, data);
276
- data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
345
+ data->usbmisc_data = usbmisc_get_init_data(dev);
277346 if (IS_ERR(data->usbmisc_data))
278347 return PTR_ERR(data->usbmisc_data);
279348
280
- ret = imx_get_clks(&pdev->dev);
281
- if (ret)
282
- return ret;
349
+ if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC)
350
+ && data->usbmisc_data) {
351
+ pdata.flags |= CI_HDRC_IMX_IS_HSIC;
352
+ data->usbmisc_data->hsic = 1;
353
+ data->pinctrl = devm_pinctrl_get(dev);
354
+ if (PTR_ERR(data->pinctrl) == -ENODEV)
355
+ data->pinctrl = NULL;
356
+ else if (IS_ERR(data->pinctrl)) {
357
+ if (PTR_ERR(data->pinctrl) != -EPROBE_DEFER)
358
+ dev_err(dev, "pinctrl get failed, err=%ld\n",
359
+ PTR_ERR(data->pinctrl));
360
+ return PTR_ERR(data->pinctrl);
361
+ }
283362
284
- ret = imx_prepare_enable_clks(&pdev->dev);
285
- if (ret)
286
- return ret;
363
+ data->hsic_pad_regulator =
364
+ devm_regulator_get_optional(dev, "hsic");
365
+ if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
366
+ /* no pad regualator is needed */
367
+ data->hsic_pad_regulator = NULL;
368
+ } else if (IS_ERR(data->hsic_pad_regulator)) {
369
+ if (PTR_ERR(data->hsic_pad_regulator) != -EPROBE_DEFER)
370
+ dev_err(dev,
371
+ "Get HSIC pad regulator error: %ld\n",
372
+ PTR_ERR(data->hsic_pad_regulator));
373
+ return PTR_ERR(data->hsic_pad_regulator);
374
+ }
287375
288
- data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
376
+ if (data->hsic_pad_regulator) {
377
+ ret = regulator_enable(data->hsic_pad_regulator);
378
+ if (ret) {
379
+ dev_err(dev,
380
+ "Failed to enable HSIC pad regulator\n");
381
+ return ret;
382
+ }
383
+ }
384
+ }
385
+
386
+ /* HSIC pinctrl handling */
387
+ if (data->pinctrl) {
388
+ struct pinctrl_state *pinctrl_hsic_idle;
389
+
390
+ pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
391
+ if (IS_ERR(pinctrl_hsic_idle)) {
392
+ dev_err(dev,
393
+ "pinctrl_hsic_idle lookup failed, err=%ld\n",
394
+ PTR_ERR(pinctrl_hsic_idle));
395
+ return PTR_ERR(pinctrl_hsic_idle);
396
+ }
397
+
398
+ ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
399
+ if (ret) {
400
+ dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
401
+ return ret;
402
+ }
403
+
404
+ data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
405
+ "active");
406
+ if (IS_ERR(data->pinctrl_hsic_active)) {
407
+ dev_err(dev,
408
+ "pinctrl_hsic_active lookup failed, err=%ld\n",
409
+ PTR_ERR(data->pinctrl_hsic_active));
410
+ return PTR_ERR(data->pinctrl_hsic_active);
411
+ }
412
+ }
413
+
414
+ if (pdata.flags & CI_HDRC_PMQOS)
415
+ cpu_latency_qos_add_request(&data->pm_qos_req, 0);
416
+
417
+ ret = imx_get_clks(dev);
418
+ if (ret)
419
+ goto disable_hsic_regulator;
420
+
421
+ ret = imx_prepare_enable_clks(dev);
422
+ if (ret)
423
+ goto disable_hsic_regulator;
424
+
425
+ data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
289426 if (IS_ERR(data->phy)) {
290427 ret = PTR_ERR(data->phy);
291
- /* Return -EINVAL if no usbphy is available */
292
- if (ret == -ENODEV)
293
- ret = -EINVAL;
294
- goto err_clk;
428
+ if (ret != -ENODEV)
429
+ goto err_clk;
430
+ data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
431
+ if (IS_ERR(data->phy)) {
432
+ ret = PTR_ERR(data->phy);
433
+ if (ret == -ENODEV)
434
+ data->phy = NULL;
435
+ else
436
+ goto err_clk;
437
+ }
295438 }
296439
297440 pdata.usb_phy = data->phy;
441
+ if (data->usbmisc_data)
442
+ data->usbmisc_data->usb_phy = data->phy;
298443
299444 if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
300445 of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
....@@ -304,46 +449,66 @@
304449 usb_phy_init(pdata.usb_phy);
305450 }
306451
307
- pdata.flags |= imx_platform_flag->flags;
308452 if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
309453 data->supports_runtime_pm = true;
310454
311455 ret = imx_usbmisc_init(data->usbmisc_data);
312456 if (ret) {
313
- dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n", ret);
457
+ dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
314458 goto err_clk;
315459 }
316460
317
- data->ci_pdev = ci_hdrc_add_device(&pdev->dev,
461
+ data->ci_pdev = ci_hdrc_add_device(dev,
318462 pdev->resource, pdev->num_resources,
319463 &pdata);
320464 if (IS_ERR(data->ci_pdev)) {
321465 ret = PTR_ERR(data->ci_pdev);
322466 if (ret != -EPROBE_DEFER)
323
- dev_err(&pdev->dev,
324
- "ci_hdrc_add_device failed, err=%d\n", ret);
467
+ dev_err(dev, "ci_hdrc_add_device failed, err=%d\n",
468
+ ret);
325469 goto err_clk;
470
+ }
471
+
472
+ if (data->usbmisc_data) {
473
+ if (!IS_ERR(pdata.id_extcon.edev) ||
474
+ of_property_read_bool(np, "usb-role-switch"))
475
+ data->usbmisc_data->ext_id = 1;
476
+
477
+ if (!IS_ERR(pdata.vbus_extcon.edev) ||
478
+ of_property_read_bool(np, "usb-role-switch"))
479
+ data->usbmisc_data->ext_vbus = 1;
480
+
481
+ /* usbmisc needs to know dr mode to choose wakeup setting */
482
+ data->usbmisc_data->available_role =
483
+ ci_hdrc_query_available_role(data->ci_pdev);
326484 }
327485
328486 ret = imx_usbmisc_init_post(data->usbmisc_data);
329487 if (ret) {
330
- dev_err(&pdev->dev, "usbmisc post failed, ret=%d\n", ret);
488
+ dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
331489 goto disable_device;
332490 }
333491
334492 if (data->supports_runtime_pm) {
335
- pm_runtime_set_active(&pdev->dev);
336
- pm_runtime_enable(&pdev->dev);
493
+ pm_runtime_set_active(dev);
494
+ pm_runtime_enable(dev);
337495 }
338496
339
- device_set_wakeup_capable(&pdev->dev, true);
497
+ device_set_wakeup_capable(dev, true);
340498
341499 return 0;
342500
343501 disable_device:
344502 ci_hdrc_remove_device(data->ci_pdev);
345503 err_clk:
346
- imx_disable_unprepare_clks(&pdev->dev);
504
+ imx_disable_unprepare_clks(dev);
505
+disable_hsic_regulator:
506
+ if (data->hsic_pad_regulator)
507
+ /* don't overwrite original ret (cf. EPROBE_DEFER) */
508
+ regulator_disable(data->hsic_pad_regulator);
509
+ if (pdata.flags & CI_HDRC_PMQOS)
510
+ cpu_latency_qos_remove_request(&data->pm_qos_req);
511
+ data->ci_pdev = NULL;
347512 return ret;
348513 }
349514
....@@ -356,10 +521,17 @@
356521 pm_runtime_disable(&pdev->dev);
357522 pm_runtime_put_noidle(&pdev->dev);
358523 }
359
- ci_hdrc_remove_device(data->ci_pdev);
524
+ if (data->ci_pdev)
525
+ ci_hdrc_remove_device(data->ci_pdev);
360526 if (data->override_phy_control)
361527 usb_phy_shutdown(data->phy);
362
- imx_disable_unprepare_clks(&pdev->dev);
528
+ if (data->ci_pdev) {
529
+ imx_disable_unprepare_clks(&pdev->dev);
530
+ if (data->plat_data->flags & CI_HDRC_PMQOS)
531
+ cpu_latency_qos_remove_request(&data->pm_qos_req);
532
+ if (data->hsic_pad_regulator)
533
+ regulator_disable(data->hsic_pad_regulator);
534
+ }
363535
364536 return 0;
365537 }
....@@ -369,20 +541,29 @@
369541 ci_hdrc_imx_remove(pdev);
370542 }
371543
372
-#ifdef CONFIG_PM
373
-static int imx_controller_suspend(struct device *dev)
544
+static int __maybe_unused imx_controller_suspend(struct device *dev)
374545 {
375546 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
547
+ int ret = 0;
376548
377549 dev_dbg(dev, "at %s\n", __func__);
378550
551
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false);
552
+ if (ret) {
553
+ dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
554
+ return ret;
555
+ }
556
+
379557 imx_disable_unprepare_clks(dev);
558
+ if (data->plat_data->flags & CI_HDRC_PMQOS)
559
+ cpu_latency_qos_remove_request(&data->pm_qos_req);
560
+
380561 data->in_lpm = true;
381562
382563 return 0;
383564 }
384565
385
-static int imx_controller_resume(struct device *dev)
566
+static int __maybe_unused imx_controller_resume(struct device *dev)
386567 {
387568 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
388569 int ret = 0;
....@@ -393,6 +574,9 @@
393574 WARN_ON(1);
394575 return 0;
395576 }
577
+
578
+ if (data->plat_data->flags & CI_HDRC_PMQOS)
579
+ cpu_latency_qos_add_request(&data->pm_qos_req, 0);
396580
397581 ret = imx_prepare_enable_clks(dev);
398582 if (ret)
....@@ -406,15 +590,22 @@
406590 goto clk_disable;
407591 }
408592
593
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true);
594
+ if (ret) {
595
+ dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
596
+ goto hsic_set_clk_fail;
597
+ }
598
+
409599 return 0;
410600
601
+hsic_set_clk_fail:
602
+ imx_usbmisc_set_wakeup(data->usbmisc_data, true);
411603 clk_disable:
412604 imx_disable_unprepare_clks(dev);
413605 return ret;
414606 }
415607
416
-#ifdef CONFIG_PM_SLEEP
417
-static int ci_hdrc_imx_suspend(struct device *dev)
608
+static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev)
418609 {
419610 int ret;
420611
....@@ -433,14 +624,20 @@
433624 }
434625 }
435626
436
- return imx_controller_suspend(dev);
627
+ ret = imx_controller_suspend(dev);
628
+ if (ret)
629
+ return ret;
630
+
631
+ pinctrl_pm_select_sleep_state(dev);
632
+ return ret;
437633 }
438634
439
-static int ci_hdrc_imx_resume(struct device *dev)
635
+static int __maybe_unused ci_hdrc_imx_resume(struct device *dev)
440636 {
441637 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
442638 int ret;
443639
640
+ pinctrl_pm_select_default_state(dev);
444641 ret = imx_controller_resume(dev);
445642 if (!ret && data->supports_runtime_pm) {
446643 pm_runtime_disable(dev);
....@@ -450,9 +647,8 @@
450647
451648 return ret;
452649 }
453
-#endif /* CONFIG_PM_SLEEP */
454650
455
-static int ci_hdrc_imx_runtime_suspend(struct device *dev)
651
+static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev)
456652 {
457653 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
458654 int ret;
....@@ -471,12 +667,10 @@
471667 return imx_controller_suspend(dev);
472668 }
473669
474
-static int ci_hdrc_imx_runtime_resume(struct device *dev)
670
+static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev)
475671 {
476672 return imx_controller_resume(dev);
477673 }
478
-
479
-#endif /* CONFIG_PM */
480674
481675 static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
482676 SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
....@@ -497,7 +691,7 @@
497691 module_platform_driver(ci_hdrc_imx_driver);
498692
499693 MODULE_ALIAS("platform:imx-usb");
500
-MODULE_LICENSE("GPL v2");
694
+MODULE_LICENSE("GPL");
501695 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
502696 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
503697 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");