xref: /linux/drivers/usb/chipidea/ci_hdrc_imx.c (revision 4e0ae876f77bc01a7e77724dea57b4b82bd53244)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2012 Freescale Semiconductor, Inc.
4  * Copyright (C) 2012 Marek Vasut <marex@denx.de>
5  * on behalf of DENX Software Engineering GmbH
6  */
7 
8 #include <linux/module.h>
9 #include <linux/of_platform.h>
10 #include <linux/platform_device.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/usb/chipidea.h>
13 #include <linux/usb/of.h>
14 #include <linux/clk.h>
15 #include <linux/pinctrl/consumer.h>
16 
17 #include "ci.h"
18 #include "ci_hdrc_imx.h"
19 
20 struct ci_hdrc_imx_platform_flag {
21 	unsigned int flags;
22 };
23 
24 static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
25 	.flags = CI_HDRC_TURN_VBUS_EARLY_ON |
26 		CI_HDRC_DISABLE_STREAMING,
27 };
28 
29 static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
30 	.flags = CI_HDRC_DISABLE_STREAMING,
31 };
32 
33 static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
34 	.flags = CI_HDRC_IMX28_WRITE_FIX |
35 		CI_HDRC_TURN_VBUS_EARLY_ON |
36 		CI_HDRC_DISABLE_STREAMING,
37 };
38 
39 static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
40 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
41 		CI_HDRC_TURN_VBUS_EARLY_ON |
42 		CI_HDRC_DISABLE_STREAMING,
43 };
44 
45 static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
46 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
47 		CI_HDRC_TURN_VBUS_EARLY_ON |
48 		CI_HDRC_DISABLE_HOST_STREAMING,
49 };
50 
51 static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
52 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
53 		CI_HDRC_TURN_VBUS_EARLY_ON |
54 		CI_HDRC_DISABLE_HOST_STREAMING,
55 };
56 
57 static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
58 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
59 		CI_HDRC_TURN_VBUS_EARLY_ON,
60 };
61 
62 static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
63 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
64 };
65 
66 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
67 	{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
68 	{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
69 	{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
70 	{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
71 	{ .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
72 	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
73 	{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
74 	{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
75 	{ /* sentinel */ }
76 };
77 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
78 
79 struct ci_hdrc_imx_data {
80 	struct usb_phy *phy;
81 	struct platform_device *ci_pdev;
82 	struct clk *clk;
83 	struct imx_usbmisc_data *usbmisc_data;
84 	bool supports_runtime_pm;
85 	bool override_phy_control;
86 	bool in_lpm;
87 	struct pinctrl *pinctrl;
88 	struct pinctrl_state *pinctrl_hsic_active;
89 	struct regulator *hsic_pad_regulator;
90 	/* SoC before i.mx6 (except imx23/imx28) needs three clks */
91 	bool need_three_clks;
92 	struct clk *clk_ipg;
93 	struct clk *clk_ahb;
94 	struct clk *clk_per;
95 	/* --------------------------------- */
96 };
97 
98 /* Common functions shared by usbmisc drivers */
99 
100 static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
101 {
102 	struct platform_device *misc_pdev;
103 	struct device_node *np = dev->of_node;
104 	struct of_phandle_args args;
105 	struct imx_usbmisc_data *data;
106 	int ret;
107 
108 	/*
109 	 * In case the fsl,usbmisc property is not present this device doesn't
110 	 * need usbmisc. Return NULL (which is no error here)
111 	 */
112 	if (!of_get_property(np, "fsl,usbmisc", NULL))
113 		return NULL;
114 
115 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
116 	if (!data)
117 		return ERR_PTR(-ENOMEM);
118 
119 	ret = of_parse_phandle_with_args(np, "fsl,usbmisc", "#index-cells",
120 					0, &args);
121 	if (ret) {
122 		dev_err(dev, "Failed to parse property fsl,usbmisc, errno %d\n",
123 			ret);
124 		return ERR_PTR(ret);
125 	}
126 
127 	data->index = args.args[0];
128 
129 	misc_pdev = of_find_device_by_node(args.np);
130 	of_node_put(args.np);
131 
132 	if (!misc_pdev || !platform_get_drvdata(misc_pdev))
133 		return ERR_PTR(-EPROBE_DEFER);
134 
135 	data->dev = &misc_pdev->dev;
136 
137 	/*
138 	 * Check the various over current related properties. If over current
139 	 * detection is disabled we're not interested in the polarity.
140 	 */
141 	if (of_find_property(np, "disable-over-current", NULL)) {
142 		data->disable_oc = 1;
143 	} else if (of_find_property(np, "over-current-active-high", NULL)) {
144 		data->oc_pol_active_low = 0;
145 		data->oc_pol_configured = 1;
146 	} else if (of_find_property(np, "over-current-active-low", NULL)) {
147 		data->oc_pol_active_low = 1;
148 		data->oc_pol_configured = 1;
149 	} else {
150 		dev_warn(dev, "No over current polarity defined\n");
151 	}
152 
153 	data->pwr_pol = of_property_read_bool(np, "power-active-high");
154 	data->evdo = of_property_read_bool(np, "external-vbus-divider");
155 
156 	if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
157 		data->ulpi = 1;
158 
159 	return data;
160 }
161 
162 /* End of common functions shared by usbmisc drivers*/
163 static int imx_get_clks(struct device *dev)
164 {
165 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
166 	int ret = 0;
167 
168 	data->clk_ipg = devm_clk_get(dev, "ipg");
169 	if (IS_ERR(data->clk_ipg)) {
170 		/* If the platform only needs one clocks */
171 		data->clk = devm_clk_get(dev, NULL);
172 		if (IS_ERR(data->clk)) {
173 			ret = PTR_ERR(data->clk);
174 			dev_err(dev,
175 				"Failed to get clks, err=%ld,%ld\n",
176 				PTR_ERR(data->clk), PTR_ERR(data->clk_ipg));
177 			return ret;
178 		}
179 		return ret;
180 	}
181 
182 	data->clk_ahb = devm_clk_get(dev, "ahb");
183 	if (IS_ERR(data->clk_ahb)) {
184 		ret = PTR_ERR(data->clk_ahb);
185 		dev_err(dev,
186 			"Failed to get ahb clock, err=%d\n", ret);
187 		return ret;
188 	}
189 
190 	data->clk_per = devm_clk_get(dev, "per");
191 	if (IS_ERR(data->clk_per)) {
192 		ret = PTR_ERR(data->clk_per);
193 		dev_err(dev,
194 			"Failed to get per clock, err=%d\n", ret);
195 		return ret;
196 	}
197 
198 	data->need_three_clks = true;
199 	return ret;
200 }
201 
202 static int imx_prepare_enable_clks(struct device *dev)
203 {
204 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
205 	int ret = 0;
206 
207 	if (data->need_three_clks) {
208 		ret = clk_prepare_enable(data->clk_ipg);
209 		if (ret) {
210 			dev_err(dev,
211 				"Failed to prepare/enable ipg clk, err=%d\n",
212 				ret);
213 			return ret;
214 		}
215 
216 		ret = clk_prepare_enable(data->clk_ahb);
217 		if (ret) {
218 			dev_err(dev,
219 				"Failed to prepare/enable ahb clk, err=%d\n",
220 				ret);
221 			clk_disable_unprepare(data->clk_ipg);
222 			return ret;
223 		}
224 
225 		ret = clk_prepare_enable(data->clk_per);
226 		if (ret) {
227 			dev_err(dev,
228 				"Failed to prepare/enable per clk, err=%d\n",
229 				ret);
230 			clk_disable_unprepare(data->clk_ahb);
231 			clk_disable_unprepare(data->clk_ipg);
232 			return ret;
233 		}
234 	} else {
235 		ret = clk_prepare_enable(data->clk);
236 		if (ret) {
237 			dev_err(dev,
238 				"Failed to prepare/enable clk, err=%d\n",
239 				ret);
240 			return ret;
241 		}
242 	}
243 
244 	return ret;
245 }
246 
247 static void imx_disable_unprepare_clks(struct device *dev)
248 {
249 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
250 
251 	if (data->need_three_clks) {
252 		clk_disable_unprepare(data->clk_per);
253 		clk_disable_unprepare(data->clk_ahb);
254 		clk_disable_unprepare(data->clk_ipg);
255 	} else {
256 		clk_disable_unprepare(data->clk);
257 	}
258 }
259 
260 static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
261 {
262 	struct device *dev = ci->dev->parent;
263 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
264 	int ret = 0;
265 
266 	switch (event) {
267 	case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
268 		ret = pinctrl_select_state(data->pinctrl,
269 				data->pinctrl_hsic_active);
270 		if (ret)
271 			dev_err(dev, "hsic_active select failed, err=%d\n",
272 				ret);
273 		break;
274 	case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
275 		ret = imx_usbmisc_hsic_set_connect(data->usbmisc_data);
276 		if (ret)
277 			dev_err(dev,
278 				"hsic_set_connect failed, err=%d\n", ret);
279 		break;
280 	default:
281 		break;
282 	}
283 
284 	return ret;
285 }
286 
287 static int ci_hdrc_imx_probe(struct platform_device *pdev)
288 {
289 	struct ci_hdrc_imx_data *data;
290 	struct ci_hdrc_platform_data pdata = {
291 		.name		= dev_name(&pdev->dev),
292 		.capoffset	= DEF_CAPOFFSET,
293 		.notify_event	= ci_hdrc_imx_notify_event,
294 	};
295 	int ret;
296 	const struct of_device_id *of_id;
297 	const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
298 	struct device_node *np = pdev->dev.of_node;
299 	struct device *dev = &pdev->dev;
300 	struct pinctrl_state *pinctrl_hsic_idle;
301 
302 	of_id = of_match_device(ci_hdrc_imx_dt_ids, dev);
303 	if (!of_id)
304 		return -ENODEV;
305 
306 	imx_platform_flag = of_id->data;
307 
308 	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
309 	if (!data)
310 		return -ENOMEM;
311 
312 	platform_set_drvdata(pdev, data);
313 	data->usbmisc_data = usbmisc_get_init_data(dev);
314 	if (IS_ERR(data->usbmisc_data))
315 		return PTR_ERR(data->usbmisc_data);
316 
317 	if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC)
318 		&& data->usbmisc_data) {
319 		pdata.flags |= CI_HDRC_IMX_IS_HSIC;
320 		data->usbmisc_data->hsic = 1;
321 		data->pinctrl = devm_pinctrl_get(dev);
322 		if (IS_ERR(data->pinctrl)) {
323 			dev_err(dev, "pinctrl get failed, err=%ld\n",
324 					PTR_ERR(data->pinctrl));
325 			return PTR_ERR(data->pinctrl);
326 		}
327 
328 		pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
329 		if (IS_ERR(pinctrl_hsic_idle)) {
330 			dev_err(dev,
331 				"pinctrl_hsic_idle lookup failed, err=%ld\n",
332 					PTR_ERR(pinctrl_hsic_idle));
333 			return PTR_ERR(pinctrl_hsic_idle);
334 		}
335 
336 		ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
337 		if (ret) {
338 			dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
339 			return ret;
340 		}
341 
342 		data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
343 								"active");
344 		if (IS_ERR(data->pinctrl_hsic_active)) {
345 			dev_err(dev,
346 				"pinctrl_hsic_active lookup failed, err=%ld\n",
347 					PTR_ERR(data->pinctrl_hsic_active));
348 			return PTR_ERR(data->pinctrl_hsic_active);
349 		}
350 
351 		data->hsic_pad_regulator = devm_regulator_get(dev, "hsic");
352 		if (PTR_ERR(data->hsic_pad_regulator) == -EPROBE_DEFER) {
353 			return -EPROBE_DEFER;
354 		} else if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
355 			/* no pad regualator is needed */
356 			data->hsic_pad_regulator = NULL;
357 		} else if (IS_ERR(data->hsic_pad_regulator)) {
358 			dev_err(dev, "Get HSIC pad regulator error: %ld\n",
359 					PTR_ERR(data->hsic_pad_regulator));
360 			return PTR_ERR(data->hsic_pad_regulator);
361 		}
362 
363 		if (data->hsic_pad_regulator) {
364 			ret = regulator_enable(data->hsic_pad_regulator);
365 			if (ret) {
366 				dev_err(dev,
367 					"Failed to enable HSIC pad regulator\n");
368 				return ret;
369 			}
370 		}
371 	}
372 	ret = imx_get_clks(dev);
373 	if (ret)
374 		goto disable_hsic_regulator;
375 
376 	ret = imx_prepare_enable_clks(dev);
377 	if (ret)
378 		goto disable_hsic_regulator;
379 
380 	data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
381 	if (IS_ERR(data->phy)) {
382 		ret = PTR_ERR(data->phy);
383 		/* Return -EINVAL if no usbphy is available */
384 		if (ret == -ENODEV)
385 			ret = -EINVAL;
386 		goto err_clk;
387 	}
388 
389 	pdata.usb_phy = data->phy;
390 
391 	if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
392 	     of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
393 	    of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
394 		pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
395 		data->override_phy_control = true;
396 		usb_phy_init(pdata.usb_phy);
397 	}
398 
399 	pdata.flags |= imx_platform_flag->flags;
400 	if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
401 		data->supports_runtime_pm = true;
402 
403 	ret = imx_usbmisc_init(data->usbmisc_data);
404 	if (ret) {
405 		dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
406 		goto err_clk;
407 	}
408 
409 	data->ci_pdev = ci_hdrc_add_device(dev,
410 				pdev->resource, pdev->num_resources,
411 				&pdata);
412 	if (IS_ERR(data->ci_pdev)) {
413 		ret = PTR_ERR(data->ci_pdev);
414 		if (ret != -EPROBE_DEFER)
415 			dev_err(dev, "ci_hdrc_add_device failed, err=%d\n",
416 					ret);
417 		goto err_clk;
418 	}
419 
420 	ret = imx_usbmisc_init_post(data->usbmisc_data);
421 	if (ret) {
422 		dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
423 		goto disable_device;
424 	}
425 
426 	if (data->supports_runtime_pm) {
427 		pm_runtime_set_active(dev);
428 		pm_runtime_enable(dev);
429 	}
430 
431 	device_set_wakeup_capable(dev, true);
432 
433 	return 0;
434 
435 disable_device:
436 	ci_hdrc_remove_device(data->ci_pdev);
437 err_clk:
438 	imx_disable_unprepare_clks(dev);
439 disable_hsic_regulator:
440 	if (data->hsic_pad_regulator)
441 		ret = regulator_disable(data->hsic_pad_regulator);
442 	return ret;
443 }
444 
445 static int ci_hdrc_imx_remove(struct platform_device *pdev)
446 {
447 	struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev);
448 
449 	if (data->supports_runtime_pm) {
450 		pm_runtime_get_sync(&pdev->dev);
451 		pm_runtime_disable(&pdev->dev);
452 		pm_runtime_put_noidle(&pdev->dev);
453 	}
454 	ci_hdrc_remove_device(data->ci_pdev);
455 	if (data->override_phy_control)
456 		usb_phy_shutdown(data->phy);
457 	imx_disable_unprepare_clks(&pdev->dev);
458 	if (data->hsic_pad_regulator)
459 		regulator_disable(data->hsic_pad_regulator);
460 
461 	return 0;
462 }
463 
464 static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
465 {
466 	ci_hdrc_imx_remove(pdev);
467 }
468 
469 static int __maybe_unused imx_controller_suspend(struct device *dev)
470 {
471 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
472 	int ret = 0;
473 
474 	dev_dbg(dev, "at %s\n", __func__);
475 
476 	ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false);
477 	if (ret) {
478 		dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
479 		return ret;
480 	}
481 
482 	imx_disable_unprepare_clks(dev);
483 	data->in_lpm = true;
484 
485 	return 0;
486 }
487 
488 static int __maybe_unused imx_controller_resume(struct device *dev)
489 {
490 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
491 	int ret = 0;
492 
493 	dev_dbg(dev, "at %s\n", __func__);
494 
495 	if (!data->in_lpm) {
496 		WARN_ON(1);
497 		return 0;
498 	}
499 
500 	ret = imx_prepare_enable_clks(dev);
501 	if (ret)
502 		return ret;
503 
504 	data->in_lpm = false;
505 
506 	ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
507 	if (ret) {
508 		dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
509 		goto clk_disable;
510 	}
511 
512 	ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true);
513 	if (ret) {
514 		dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
515 		goto hsic_set_clk_fail;
516 	}
517 
518 	return 0;
519 
520 hsic_set_clk_fail:
521 	imx_usbmisc_set_wakeup(data->usbmisc_data, true);
522 clk_disable:
523 	imx_disable_unprepare_clks(dev);
524 	return ret;
525 }
526 
527 static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev)
528 {
529 	int ret;
530 
531 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
532 
533 	if (data->in_lpm)
534 		/* The core's suspend doesn't run */
535 		return 0;
536 
537 	if (device_may_wakeup(dev)) {
538 		ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
539 		if (ret) {
540 			dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n",
541 					ret);
542 			return ret;
543 		}
544 	}
545 
546 	return imx_controller_suspend(dev);
547 }
548 
549 static int __maybe_unused ci_hdrc_imx_resume(struct device *dev)
550 {
551 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
552 	int ret;
553 
554 	ret = imx_controller_resume(dev);
555 	if (!ret && data->supports_runtime_pm) {
556 		pm_runtime_disable(dev);
557 		pm_runtime_set_active(dev);
558 		pm_runtime_enable(dev);
559 	}
560 
561 	return ret;
562 }
563 
564 static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev)
565 {
566 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
567 	int ret;
568 
569 	if (data->in_lpm) {
570 		WARN_ON(1);
571 		return 0;
572 	}
573 
574 	ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
575 	if (ret) {
576 		dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
577 		return ret;
578 	}
579 
580 	return imx_controller_suspend(dev);
581 }
582 
583 static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev)
584 {
585 	return imx_controller_resume(dev);
586 }
587 
588 static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
589 	SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
590 	SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
591 			ci_hdrc_imx_runtime_resume, NULL)
592 };
593 static struct platform_driver ci_hdrc_imx_driver = {
594 	.probe = ci_hdrc_imx_probe,
595 	.remove = ci_hdrc_imx_remove,
596 	.shutdown = ci_hdrc_imx_shutdown,
597 	.driver = {
598 		.name = "imx_usb",
599 		.of_match_table = ci_hdrc_imx_dt_ids,
600 		.pm = &ci_hdrc_imx_pm_ops,
601 	 },
602 };
603 
604 module_platform_driver(ci_hdrc_imx_driver);
605 
606 MODULE_ALIAS("platform:imx-usb");
607 MODULE_LICENSE("GPL");
608 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
609 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
610 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
611