xref: /openbmc/linux/drivers/usb/dwc3/dwc3-qcom.c (revision 66a28915)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, The Linux Foundation. All rights reserved.
3  *
4  * Inspired by dwc3-of-simple.c
5  */
6 
7 #include <linux/acpi.h>
8 #include <linux/io.h>
9 #include <linux/of.h>
10 #include <linux/clk.h>
11 #include <linux/irq.h>
12 #include <linux/of_clk.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/extcon.h>
16 #include <linux/interconnect.h>
17 #include <linux/of_platform.h>
18 #include <linux/platform_device.h>
19 #include <linux/phy/phy.h>
20 #include <linux/usb/of.h>
21 #include <linux/reset.h>
22 #include <linux/iopoll.h>
23 
24 #include "core.h"
25 
26 /* USB QSCRATCH Hardware registers */
27 #define QSCRATCH_HS_PHY_CTRL			0x10
28 #define UTMI_OTG_VBUS_VALID			BIT(20)
29 #define SW_SESSVLD_SEL				BIT(28)
30 
31 #define QSCRATCH_SS_PHY_CTRL			0x30
32 #define LANE0_PWR_PRESENT			BIT(24)
33 
34 #define QSCRATCH_GENERAL_CFG			0x08
35 #define PIPE_UTMI_CLK_SEL			BIT(0)
36 #define PIPE3_PHYSTATUS_SW			BIT(3)
37 #define PIPE_UTMI_CLK_DIS			BIT(8)
38 
39 #define PWR_EVNT_IRQ_STAT_REG			0x58
40 #define PWR_EVNT_LPM_IN_L2_MASK			BIT(4)
41 #define PWR_EVNT_LPM_OUT_L2_MASK		BIT(5)
42 
43 #define SDM845_QSCRATCH_BASE_OFFSET		0xf8800
44 #define SDM845_QSCRATCH_SIZE			0x400
45 #define SDM845_DWC3_CORE_SIZE			0xcd00
46 
47 /* Interconnect path bandwidths in MBps */
48 #define USB_MEMORY_AVG_HS_BW MBps_to_icc(240)
49 #define USB_MEMORY_PEAK_HS_BW MBps_to_icc(700)
50 #define USB_MEMORY_AVG_SS_BW  MBps_to_icc(1000)
51 #define USB_MEMORY_PEAK_SS_BW MBps_to_icc(2500)
52 #define APPS_USB_AVG_BW 0
53 #define APPS_USB_PEAK_BW MBps_to_icc(40)
54 
55 struct dwc3_acpi_pdata {
56 	u32			qscratch_base_offset;
57 	u32			qscratch_base_size;
58 	u32			dwc3_core_base_size;
59 	int			hs_phy_irq_index;
60 	int			dp_hs_phy_irq_index;
61 	int			dm_hs_phy_irq_index;
62 	int			ss_phy_irq_index;
63 };
64 
65 struct dwc3_qcom {
66 	struct device		*dev;
67 	void __iomem		*qscratch_base;
68 	struct platform_device	*dwc3;
69 	struct clk		**clks;
70 	int			num_clocks;
71 	struct reset_control	*resets;
72 
73 	int			hs_phy_irq;
74 	int			dp_hs_phy_irq;
75 	int			dm_hs_phy_irq;
76 	int			ss_phy_irq;
77 
78 	struct extcon_dev	*edev;
79 	struct extcon_dev	*host_edev;
80 	struct notifier_block	vbus_nb;
81 	struct notifier_block	host_nb;
82 
83 	const struct dwc3_acpi_pdata *acpi_pdata;
84 
85 	enum usb_dr_mode	mode;
86 	bool			is_suspended;
87 	bool			pm_suspended;
88 	struct icc_path		*icc_path_ddr;
89 	struct icc_path		*icc_path_apps;
90 };
91 
92 static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val)
93 {
94 	u32 reg;
95 
96 	reg = readl(base + offset);
97 	reg |= val;
98 	writel(reg, base + offset);
99 
100 	/* ensure that above write is through */
101 	readl(base + offset);
102 }
103 
104 static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val)
105 {
106 	u32 reg;
107 
108 	reg = readl(base + offset);
109 	reg &= ~val;
110 	writel(reg, base + offset);
111 
112 	/* ensure that above write is through */
113 	readl(base + offset);
114 }
115 
116 static void dwc3_qcom_vbus_overrride_enable(struct dwc3_qcom *qcom, bool enable)
117 {
118 	if (enable) {
119 		dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
120 				  LANE0_PWR_PRESENT);
121 		dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
122 				  UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
123 	} else {
124 		dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
125 				  LANE0_PWR_PRESENT);
126 		dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
127 				  UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
128 	}
129 }
130 
131 static int dwc3_qcom_vbus_notifier(struct notifier_block *nb,
132 				   unsigned long event, void *ptr)
133 {
134 	struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb);
135 
136 	/* enable vbus override for device mode */
137 	dwc3_qcom_vbus_overrride_enable(qcom, event);
138 	qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
139 
140 	return NOTIFY_DONE;
141 }
142 
143 static int dwc3_qcom_host_notifier(struct notifier_block *nb,
144 				   unsigned long event, void *ptr)
145 {
146 	struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb);
147 
148 	/* disable vbus override in host mode */
149 	dwc3_qcom_vbus_overrride_enable(qcom, !event);
150 	qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
151 
152 	return NOTIFY_DONE;
153 }
154 
155 static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
156 {
157 	struct device		*dev = qcom->dev;
158 	struct extcon_dev	*host_edev;
159 	int			ret;
160 
161 	if (!of_property_read_bool(dev->of_node, "extcon"))
162 		return 0;
163 
164 	qcom->edev = extcon_get_edev_by_phandle(dev, 0);
165 	if (IS_ERR(qcom->edev))
166 		return PTR_ERR(qcom->edev);
167 
168 	qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier;
169 
170 	qcom->host_edev = extcon_get_edev_by_phandle(dev, 1);
171 	if (IS_ERR(qcom->host_edev))
172 		qcom->host_edev = NULL;
173 
174 	ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB,
175 					    &qcom->vbus_nb);
176 	if (ret < 0) {
177 		dev_err(dev, "VBUS notifier register failed\n");
178 		return ret;
179 	}
180 
181 	if (qcom->host_edev)
182 		host_edev = qcom->host_edev;
183 	else
184 		host_edev = qcom->edev;
185 
186 	qcom->host_nb.notifier_call = dwc3_qcom_host_notifier;
187 	ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST,
188 					    &qcom->host_nb);
189 	if (ret < 0) {
190 		dev_err(dev, "Host notifier register failed\n");
191 		return ret;
192 	}
193 
194 	/* Update initial VBUS override based on extcon state */
195 	if (extcon_get_state(qcom->edev, EXTCON_USB) ||
196 	    !extcon_get_state(host_edev, EXTCON_USB_HOST))
197 		dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev);
198 	else
199 		dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev);
200 
201 	return 0;
202 }
203 
204 static int dwc3_qcom_interconnect_enable(struct dwc3_qcom *qcom)
205 {
206 	int ret;
207 
208 	ret = icc_enable(qcom->icc_path_ddr);
209 	if (ret)
210 		return ret;
211 
212 	ret = icc_enable(qcom->icc_path_apps);
213 	if (ret)
214 		icc_disable(qcom->icc_path_ddr);
215 
216 	return ret;
217 }
218 
219 static int dwc3_qcom_interconnect_disable(struct dwc3_qcom *qcom)
220 {
221 	int ret;
222 
223 	ret = icc_disable(qcom->icc_path_ddr);
224 	if (ret)
225 		return ret;
226 
227 	ret = icc_disable(qcom->icc_path_apps);
228 	if (ret)
229 		icc_enable(qcom->icc_path_ddr);
230 
231 	return ret;
232 }
233 
234 /**
235  * dwc3_qcom_interconnect_init() - Get interconnect path handles
236  * and set bandwidhth.
237  * @qcom:			Pointer to the concerned usb core.
238  *
239  */
240 static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
241 {
242 	struct device *dev = qcom->dev;
243 	int ret;
244 
245 	qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr");
246 	if (IS_ERR(qcom->icc_path_ddr)) {
247 		dev_err(dev, "failed to get usb-ddr path: %ld\n",
248 			PTR_ERR(qcom->icc_path_ddr));
249 		return PTR_ERR(qcom->icc_path_ddr);
250 	}
251 
252 	qcom->icc_path_apps = of_icc_get(dev, "apps-usb");
253 	if (IS_ERR(qcom->icc_path_apps)) {
254 		dev_err(dev, "failed to get apps-usb path: %ld\n",
255 				PTR_ERR(qcom->icc_path_apps));
256 		return PTR_ERR(qcom->icc_path_apps);
257 	}
258 
259 	if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
260 			usb_get_maximum_speed(&qcom->dwc3->dev) == USB_SPEED_UNKNOWN)
261 		ret = icc_set_bw(qcom->icc_path_ddr,
262 			USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW);
263 	else
264 		ret = icc_set_bw(qcom->icc_path_ddr,
265 			USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW);
266 
267 	if (ret) {
268 		dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
269 		return ret;
270 	}
271 
272 	ret = icc_set_bw(qcom->icc_path_apps,
273 		APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
274 	if (ret) {
275 		dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
276 		return ret;
277 	}
278 
279 	return 0;
280 }
281 
282 /**
283  * dwc3_qcom_interconnect_exit() - Release interconnect path handles
284  * @qcom:			Pointer to the concerned usb core.
285  *
286  * This function is used to release interconnect path handle.
287  */
288 static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom)
289 {
290 	icc_put(qcom->icc_path_ddr);
291 	icc_put(qcom->icc_path_apps);
292 }
293 
294 static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
295 {
296 	if (qcom->hs_phy_irq) {
297 		disable_irq_wake(qcom->hs_phy_irq);
298 		disable_irq_nosync(qcom->hs_phy_irq);
299 	}
300 
301 	if (qcom->dp_hs_phy_irq) {
302 		disable_irq_wake(qcom->dp_hs_phy_irq);
303 		disable_irq_nosync(qcom->dp_hs_phy_irq);
304 	}
305 
306 	if (qcom->dm_hs_phy_irq) {
307 		disable_irq_wake(qcom->dm_hs_phy_irq);
308 		disable_irq_nosync(qcom->dm_hs_phy_irq);
309 	}
310 
311 	if (qcom->ss_phy_irq) {
312 		disable_irq_wake(qcom->ss_phy_irq);
313 		disable_irq_nosync(qcom->ss_phy_irq);
314 	}
315 }
316 
317 static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
318 {
319 	if (qcom->hs_phy_irq) {
320 		enable_irq(qcom->hs_phy_irq);
321 		enable_irq_wake(qcom->hs_phy_irq);
322 	}
323 
324 	if (qcom->dp_hs_phy_irq) {
325 		enable_irq(qcom->dp_hs_phy_irq);
326 		enable_irq_wake(qcom->dp_hs_phy_irq);
327 	}
328 
329 	if (qcom->dm_hs_phy_irq) {
330 		enable_irq(qcom->dm_hs_phy_irq);
331 		enable_irq_wake(qcom->dm_hs_phy_irq);
332 	}
333 
334 	if (qcom->ss_phy_irq) {
335 		enable_irq(qcom->ss_phy_irq);
336 		enable_irq_wake(qcom->ss_phy_irq);
337 	}
338 }
339 
340 static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
341 {
342 	u32 val;
343 	int i, ret;
344 
345 	if (qcom->is_suspended)
346 		return 0;
347 
348 	val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG);
349 	if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
350 		dev_err(qcom->dev, "HS-PHY not in L2\n");
351 
352 	for (i = qcom->num_clocks - 1; i >= 0; i--)
353 		clk_disable_unprepare(qcom->clks[i]);
354 
355 	ret = dwc3_qcom_interconnect_disable(qcom);
356 	if (ret)
357 		dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);
358 
359 	qcom->is_suspended = true;
360 	dwc3_qcom_enable_interrupts(qcom);
361 
362 	return 0;
363 }
364 
365 static int dwc3_qcom_resume(struct dwc3_qcom *qcom)
366 {
367 	int ret;
368 	int i;
369 
370 	if (!qcom->is_suspended)
371 		return 0;
372 
373 	dwc3_qcom_disable_interrupts(qcom);
374 
375 	for (i = 0; i < qcom->num_clocks; i++) {
376 		ret = clk_prepare_enable(qcom->clks[i]);
377 		if (ret < 0) {
378 			while (--i >= 0)
379 				clk_disable_unprepare(qcom->clks[i]);
380 			return ret;
381 		}
382 	}
383 
384 	ret = dwc3_qcom_interconnect_enable(qcom);
385 	if (ret)
386 		dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret);
387 
388 	/* Clear existing events from PHY related to L2 in/out */
389 	dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG,
390 			  PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK);
391 
392 	qcom->is_suspended = false;
393 
394 	return 0;
395 }
396 
397 static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data)
398 {
399 	struct dwc3_qcom *qcom = data;
400 	struct dwc3	*dwc = platform_get_drvdata(qcom->dwc3);
401 
402 	/* If pm_suspended then let pm_resume take care of resuming h/w */
403 	if (qcom->pm_suspended)
404 		return IRQ_HANDLED;
405 
406 	if (dwc->xhci)
407 		pm_runtime_resume(&dwc->xhci->dev);
408 
409 	return IRQ_HANDLED;
410 }
411 
412 static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom)
413 {
414 	/* Configure dwc3 to use UTMI clock as PIPE clock not present */
415 	dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
416 			  PIPE_UTMI_CLK_DIS);
417 
418 	usleep_range(100, 1000);
419 
420 	dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
421 			  PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
422 
423 	usleep_range(100, 1000);
424 
425 	dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
426 			  PIPE_UTMI_CLK_DIS);
427 }
428 
429 static int dwc3_qcom_get_irq(struct platform_device *pdev,
430 			     const char *name, int num)
431 {
432 	struct device_node *np = pdev->dev.of_node;
433 	int ret;
434 
435 	if (np)
436 		ret = platform_get_irq_byname(pdev, name);
437 	else
438 		ret = platform_get_irq(pdev, num);
439 
440 	return ret;
441 }
442 
443 static int dwc3_qcom_setup_irq(struct platform_device *pdev)
444 {
445 	struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
446 	const struct dwc3_acpi_pdata *pdata = qcom->acpi_pdata;
447 	int irq;
448 	int ret;
449 
450 	irq = dwc3_qcom_get_irq(pdev, "hs_phy_irq",
451 				pdata ? pdata->hs_phy_irq_index : -1);
452 	if (irq > 0) {
453 		/* Keep wakeup interrupts disabled until suspend */
454 		irq_set_status_flags(irq, IRQ_NOAUTOEN);
455 		ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
456 					qcom_dwc3_resume_irq,
457 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
458 					"qcom_dwc3 HS", qcom);
459 		if (ret) {
460 			dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret);
461 			return ret;
462 		}
463 		qcom->hs_phy_irq = irq;
464 	}
465 
466 	irq = dwc3_qcom_get_irq(pdev, "dp_hs_phy_irq",
467 				pdata ? pdata->dp_hs_phy_irq_index : -1);
468 	if (irq > 0) {
469 		irq_set_status_flags(irq, IRQ_NOAUTOEN);
470 		ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
471 					qcom_dwc3_resume_irq,
472 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
473 					"qcom_dwc3 DP_HS", qcom);
474 		if (ret) {
475 			dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret);
476 			return ret;
477 		}
478 		qcom->dp_hs_phy_irq = irq;
479 	}
480 
481 	irq = dwc3_qcom_get_irq(pdev, "dm_hs_phy_irq",
482 				pdata ? pdata->dm_hs_phy_irq_index : -1);
483 	if (irq > 0) {
484 		irq_set_status_flags(irq, IRQ_NOAUTOEN);
485 		ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
486 					qcom_dwc3_resume_irq,
487 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
488 					"qcom_dwc3 DM_HS", qcom);
489 		if (ret) {
490 			dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret);
491 			return ret;
492 		}
493 		qcom->dm_hs_phy_irq = irq;
494 	}
495 
496 	irq = dwc3_qcom_get_irq(pdev, "ss_phy_irq",
497 				pdata ? pdata->ss_phy_irq_index : -1);
498 	if (irq > 0) {
499 		irq_set_status_flags(irq, IRQ_NOAUTOEN);
500 		ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
501 					qcom_dwc3_resume_irq,
502 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
503 					"qcom_dwc3 SS", qcom);
504 		if (ret) {
505 			dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret);
506 			return ret;
507 		}
508 		qcom->ss_phy_irq = irq;
509 	}
510 
511 	return 0;
512 }
513 
514 static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count)
515 {
516 	struct device		*dev = qcom->dev;
517 	struct device_node	*np = dev->of_node;
518 	int			i;
519 
520 	if (!np || !count)
521 		return 0;
522 
523 	if (count < 0)
524 		return count;
525 
526 	qcom->num_clocks = count;
527 
528 	qcom->clks = devm_kcalloc(dev, qcom->num_clocks,
529 				  sizeof(struct clk *), GFP_KERNEL);
530 	if (!qcom->clks)
531 		return -ENOMEM;
532 
533 	for (i = 0; i < qcom->num_clocks; i++) {
534 		struct clk	*clk;
535 		int		ret;
536 
537 		clk = of_clk_get(np, i);
538 		if (IS_ERR(clk)) {
539 			while (--i >= 0)
540 				clk_put(qcom->clks[i]);
541 			return PTR_ERR(clk);
542 		}
543 
544 		ret = clk_prepare_enable(clk);
545 		if (ret < 0) {
546 			while (--i >= 0) {
547 				clk_disable_unprepare(qcom->clks[i]);
548 				clk_put(qcom->clks[i]);
549 			}
550 			clk_put(clk);
551 
552 			return ret;
553 		}
554 
555 		qcom->clks[i] = clk;
556 	}
557 
558 	return 0;
559 }
560 
561 static const struct property_entry dwc3_qcom_acpi_properties[] = {
562 	PROPERTY_ENTRY_STRING("dr_mode", "host"),
563 	{}
564 };
565 
566 static int dwc3_qcom_acpi_register_core(struct platform_device *pdev)
567 {
568 	struct dwc3_qcom	*qcom = platform_get_drvdata(pdev);
569 	struct device		*dev = &pdev->dev;
570 	struct resource		*res, *child_res = NULL;
571 	int			irq;
572 	int			ret;
573 
574 	qcom->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
575 	if (!qcom->dwc3)
576 		return -ENOMEM;
577 
578 	qcom->dwc3->dev.parent = dev;
579 	qcom->dwc3->dev.type = dev->type;
580 	qcom->dwc3->dev.dma_mask = dev->dma_mask;
581 	qcom->dwc3->dev.dma_parms = dev->dma_parms;
582 	qcom->dwc3->dev.coherent_dma_mask = dev->coherent_dma_mask;
583 
584 	child_res = kcalloc(2, sizeof(*child_res), GFP_KERNEL);
585 	if (!child_res)
586 		return -ENOMEM;
587 
588 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
589 	if (!res) {
590 		dev_err(&pdev->dev, "failed to get memory resource\n");
591 		ret = -ENODEV;
592 		goto out;
593 	}
594 
595 	child_res[0].flags = res->flags;
596 	child_res[0].start = res->start;
597 	child_res[0].end = child_res[0].start +
598 		qcom->acpi_pdata->dwc3_core_base_size;
599 
600 	irq = platform_get_irq(pdev, 0);
601 	child_res[1].flags = IORESOURCE_IRQ;
602 	child_res[1].start = child_res[1].end = irq;
603 
604 	ret = platform_device_add_resources(qcom->dwc3, child_res, 2);
605 	if (ret) {
606 		dev_err(&pdev->dev, "failed to add resources\n");
607 		goto out;
608 	}
609 
610 	ret = platform_device_add_properties(qcom->dwc3,
611 					     dwc3_qcom_acpi_properties);
612 	if (ret < 0) {
613 		dev_err(&pdev->dev, "failed to add properties\n");
614 		goto out;
615 	}
616 
617 	ret = platform_device_add(qcom->dwc3);
618 	if (ret)
619 		dev_err(&pdev->dev, "failed to add device\n");
620 
621 out:
622 	kfree(child_res);
623 	return ret;
624 }
625 
626 static int dwc3_qcom_of_register_core(struct platform_device *pdev)
627 {
628 	struct dwc3_qcom	*qcom = platform_get_drvdata(pdev);
629 	struct device_node	*np = pdev->dev.of_node, *dwc3_np;
630 	struct device		*dev = &pdev->dev;
631 	int			ret;
632 
633 	dwc3_np = of_get_child_by_name(np, "dwc3");
634 	if (!dwc3_np) {
635 		dev_err(dev, "failed to find dwc3 core child\n");
636 		return -ENODEV;
637 	}
638 
639 	ret = of_platform_populate(np, NULL, NULL, dev);
640 	if (ret) {
641 		dev_err(dev, "failed to register dwc3 core - %d\n", ret);
642 		return ret;
643 	}
644 
645 	qcom->dwc3 = of_find_device_by_node(dwc3_np);
646 	if (!qcom->dwc3) {
647 		dev_err(dev, "failed to get dwc3 platform device\n");
648 		return -ENODEV;
649 	}
650 
651 	return 0;
652 }
653 
654 static int dwc3_qcom_probe(struct platform_device *pdev)
655 {
656 	struct device_node	*np = pdev->dev.of_node;
657 	struct device		*dev = &pdev->dev;
658 	struct dwc3_qcom	*qcom;
659 	struct resource		*res, *parent_res = NULL;
660 	int			ret, i;
661 	bool			ignore_pipe_clk;
662 
663 	qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
664 	if (!qcom)
665 		return -ENOMEM;
666 
667 	platform_set_drvdata(pdev, qcom);
668 	qcom->dev = &pdev->dev;
669 
670 	if (has_acpi_companion(dev)) {
671 		qcom->acpi_pdata = acpi_device_get_match_data(dev);
672 		if (!qcom->acpi_pdata) {
673 			dev_err(&pdev->dev, "no supporting ACPI device data\n");
674 			return -EINVAL;
675 		}
676 	}
677 
678 	qcom->resets = devm_reset_control_array_get_optional_exclusive(dev);
679 	if (IS_ERR(qcom->resets)) {
680 		ret = PTR_ERR(qcom->resets);
681 		dev_err(&pdev->dev, "failed to get resets, err=%d\n", ret);
682 		return ret;
683 	}
684 
685 	ret = reset_control_assert(qcom->resets);
686 	if (ret) {
687 		dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret);
688 		return ret;
689 	}
690 
691 	usleep_range(10, 1000);
692 
693 	ret = reset_control_deassert(qcom->resets);
694 	if (ret) {
695 		dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret);
696 		goto reset_assert;
697 	}
698 
699 	ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np));
700 	if (ret) {
701 		dev_err(dev, "failed to get clocks\n");
702 		goto reset_assert;
703 	}
704 
705 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
706 
707 	if (np) {
708 		parent_res = res;
709 	} else {
710 		parent_res = kmemdup(res, sizeof(struct resource), GFP_KERNEL);
711 		if (!parent_res)
712 			return -ENOMEM;
713 
714 		parent_res->start = res->start +
715 			qcom->acpi_pdata->qscratch_base_offset;
716 		parent_res->end = parent_res->start +
717 			qcom->acpi_pdata->qscratch_base_size;
718 	}
719 
720 	qcom->qscratch_base = devm_ioremap_resource(dev, parent_res);
721 	if (IS_ERR(qcom->qscratch_base)) {
722 		dev_err(dev, "failed to map qscratch, err=%d\n", ret);
723 		ret = PTR_ERR(qcom->qscratch_base);
724 		goto clk_disable;
725 	}
726 
727 	ret = dwc3_qcom_setup_irq(pdev);
728 	if (ret) {
729 		dev_err(dev, "failed to setup IRQs, err=%d\n", ret);
730 		goto clk_disable;
731 	}
732 
733 	/*
734 	 * Disable pipe_clk requirement if specified. Used when dwc3
735 	 * operates without SSPHY and only HS/FS/LS modes are supported.
736 	 */
737 	ignore_pipe_clk = device_property_read_bool(dev,
738 				"qcom,select-utmi-as-pipe-clk");
739 	if (ignore_pipe_clk)
740 		dwc3_qcom_select_utmi_clk(qcom);
741 
742 	if (np)
743 		ret = dwc3_qcom_of_register_core(pdev);
744 	else
745 		ret = dwc3_qcom_acpi_register_core(pdev);
746 
747 	if (ret) {
748 		dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret);
749 		goto depopulate;
750 	}
751 
752 	ret = dwc3_qcom_interconnect_init(qcom);
753 	if (ret)
754 		goto depopulate;
755 
756 	qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
757 
758 	/* enable vbus override for device mode */
759 	if (qcom->mode == USB_DR_MODE_PERIPHERAL)
760 		dwc3_qcom_vbus_overrride_enable(qcom, true);
761 
762 	/* register extcon to override sw_vbus on Vbus change later */
763 	ret = dwc3_qcom_register_extcon(qcom);
764 	if (ret)
765 		goto interconnect_exit;
766 
767 	device_init_wakeup(&pdev->dev, 1);
768 	qcom->is_suspended = false;
769 	pm_runtime_set_active(dev);
770 	pm_runtime_enable(dev);
771 	pm_runtime_forbid(dev);
772 
773 	return 0;
774 
775 interconnect_exit:
776 	dwc3_qcom_interconnect_exit(qcom);
777 depopulate:
778 	if (np)
779 		of_platform_depopulate(&pdev->dev);
780 	else
781 		platform_device_put(pdev);
782 clk_disable:
783 	for (i = qcom->num_clocks - 1; i >= 0; i--) {
784 		clk_disable_unprepare(qcom->clks[i]);
785 		clk_put(qcom->clks[i]);
786 	}
787 reset_assert:
788 	reset_control_assert(qcom->resets);
789 
790 	return ret;
791 }
792 
793 static int dwc3_qcom_remove(struct platform_device *pdev)
794 {
795 	struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
796 	struct device *dev = &pdev->dev;
797 	int i;
798 
799 	of_platform_depopulate(dev);
800 
801 	for (i = qcom->num_clocks - 1; i >= 0; i--) {
802 		clk_disable_unprepare(qcom->clks[i]);
803 		clk_put(qcom->clks[i]);
804 	}
805 	qcom->num_clocks = 0;
806 
807 	dwc3_qcom_interconnect_exit(qcom);
808 	reset_control_assert(qcom->resets);
809 
810 	pm_runtime_allow(dev);
811 	pm_runtime_disable(dev);
812 
813 	return 0;
814 }
815 
816 static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
817 {
818 	struct dwc3_qcom *qcom = dev_get_drvdata(dev);
819 	int ret = 0;
820 
821 	ret = dwc3_qcom_suspend(qcom);
822 	if (!ret)
823 		qcom->pm_suspended = true;
824 
825 	return ret;
826 }
827 
828 static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev)
829 {
830 	struct dwc3_qcom *qcom = dev_get_drvdata(dev);
831 	int ret;
832 
833 	ret = dwc3_qcom_resume(qcom);
834 	if (!ret)
835 		qcom->pm_suspended = false;
836 
837 	return ret;
838 }
839 
840 static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
841 {
842 	struct dwc3_qcom *qcom = dev_get_drvdata(dev);
843 
844 	return dwc3_qcom_suspend(qcom);
845 }
846 
847 static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev)
848 {
849 	struct dwc3_qcom *qcom = dev_get_drvdata(dev);
850 
851 	return dwc3_qcom_resume(qcom);
852 }
853 
854 static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
855 	SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
856 	SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume,
857 			   NULL)
858 };
859 
860 static const struct of_device_id dwc3_qcom_of_match[] = {
861 	{ .compatible = "qcom,dwc3" },
862 	{ .compatible = "qcom,msm8996-dwc3" },
863 	{ .compatible = "qcom,msm8998-dwc3" },
864 	{ .compatible = "qcom,sdm845-dwc3" },
865 	{ }
866 };
867 MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match);
868 
869 #ifdef CONFIG_ACPI
870 static const struct dwc3_acpi_pdata sdm845_acpi_pdata = {
871 	.qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET,
872 	.qscratch_base_size = SDM845_QSCRATCH_SIZE,
873 	.dwc3_core_base_size = SDM845_DWC3_CORE_SIZE,
874 	.hs_phy_irq_index = 1,
875 	.dp_hs_phy_irq_index = 4,
876 	.dm_hs_phy_irq_index = 3,
877 	.ss_phy_irq_index = 2
878 };
879 
880 static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
881 	{ "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
882 	{ },
883 };
884 MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);
885 #endif
886 
887 static struct platform_driver dwc3_qcom_driver = {
888 	.probe		= dwc3_qcom_probe,
889 	.remove		= dwc3_qcom_remove,
890 	.driver		= {
891 		.name	= "dwc3-qcom",
892 		.pm	= &dwc3_qcom_dev_pm_ops,
893 		.of_match_table	= dwc3_qcom_of_match,
894 		.acpi_match_table = ACPI_PTR(dwc3_qcom_acpi_match),
895 	},
896 };
897 
898 module_platform_driver(dwc3_qcom_driver);
899 
900 MODULE_LICENSE("GPL v2");
901 MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver");
902