xref: /linux/drivers/mfd/omap-usb-host.c (revision 80739fd00c7ea1315d362ce889bef499452913ef)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI
4  *
5  * Copyright (C) 2011-2013 Texas Instruments Incorporated - https://www.ti.com
6  * Author: Keshava Munegowda <keshava_mgowda@ti.com>
7  * Author: Roger Quadros <rogerq@ti.com>
8  */
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/types.h>
12 #include <linux/slab.h>
13 #include <linux/delay.h>
14 #include <linux/clk.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/platform_device.h>
17 #include <linux/platform_data/usb-omap.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/of.h>
20 #include <linux/of_platform.h>
21 #include <linux/err.h>
22 
23 #include "omap-usb.h"
24 
25 #define USBHS_DRIVER_NAME	"usbhs_omap"
26 #define OMAP_EHCI_DEVICE	"ehci-omap"
27 #define OMAP_OHCI_DEVICE	"ohci-omap3"
28 
29 /* OMAP USBHOST Register addresses  */
30 
31 /* UHH Register Set */
32 #define	OMAP_UHH_REVISION				(0x00)
33 #define	OMAP_UHH_SYSCONFIG				(0x10)
34 #define	OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12)
35 #define	OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8)
36 #define	OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3)
37 #define	OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2)
38 #define	OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1)
39 #define	OMAP_UHH_SYSCONFIG_AUTOIDLE			(1 << 0)
40 
41 #define	OMAP_UHH_SYSSTATUS				(0x14)
42 #define	OMAP_UHH_HOSTCONFIG				(0x40)
43 #define	OMAP_UHH_HOSTCONFIG_ULPI_BYPASS			(1 << 0)
44 #define	OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS		(1 << 0)
45 #define	OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS		(1 << 11)
46 #define	OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS		(1 << 12)
47 #define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2)
48 #define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN		(1 << 3)
49 #define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN		(1 << 4)
50 #define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN		(1 << 5)
51 #define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS		(1 << 8)
52 #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS		(1 << 9)
53 #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS		(1 << 10)
54 #define OMAP4_UHH_HOSTCONFIG_APP_START_CLK		(1 << 31)
55 
56 /* OMAP4-specific defines */
57 #define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR		(3 << 2)
58 #define OMAP4_UHH_SYSCONFIG_NOIDLE			(1 << 2)
59 #define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR		(3 << 4)
60 #define OMAP4_UHH_SYSCONFIG_NOSTDBY			(1 << 4)
61 #define OMAP4_UHH_SYSCONFIG_SOFTRESET			(1 << 0)
62 
63 #define OMAP4_P1_MODE_CLEAR				(3 << 16)
64 #define OMAP4_P1_MODE_TLL				(1 << 16)
65 #define OMAP4_P1_MODE_HSIC				(3 << 16)
66 #define OMAP4_P2_MODE_CLEAR				(3 << 18)
67 #define OMAP4_P2_MODE_TLL				(1 << 18)
68 #define OMAP4_P2_MODE_HSIC				(3 << 18)
69 
70 #define	OMAP_UHH_DEBUG_CSR				(0x44)
71 
72 /* Values of UHH_REVISION - Note: these are not given in the TRM */
73 #define OMAP_USBHS_REV1		0x00000010	/* OMAP3 */
74 #define OMAP_USBHS_REV2		0x50700100	/* OMAP4 */
75 
76 #define is_omap_usbhs_rev1(x)	(x->usbhs_rev == OMAP_USBHS_REV1)
77 #define is_omap_usbhs_rev2(x)	(x->usbhs_rev == OMAP_USBHS_REV2)
78 
79 #define is_ehci_phy_mode(x)	(x == OMAP_EHCI_PORT_MODE_PHY)
80 #define is_ehci_tll_mode(x)	(x == OMAP_EHCI_PORT_MODE_TLL)
81 #define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
82 
83 
84 struct usbhs_hcd_omap {
85 	int				nports;
86 	struct clk			**utmi_clk;
87 	struct clk			**hsic60m_clk;
88 	struct clk			**hsic480m_clk;
89 
90 	struct clk			*xclk60mhsp1_ck;
91 	struct clk			*xclk60mhsp2_ck;
92 	struct clk			*utmi_p1_gfclk;
93 	struct clk			*utmi_p2_gfclk;
94 	struct clk			*init_60m_fclk;
95 	struct clk			*ehci_logic_fck;
96 
97 	void __iomem			*uhh_base;
98 
99 	struct usbhs_omap_platform_data	*pdata;
100 
101 	u32				usbhs_rev;
102 };
103 /*-------------------------------------------------------------------------*/
104 
105 static const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
106 static u64 usbhs_dmamask = DMA_BIT_MASK(32);
107 
108 /*-------------------------------------------------------------------------*/
109 
usbhs_write(void __iomem * base,u32 reg,u32 val)110 static inline void usbhs_write(void __iomem *base, u32 reg, u32 val)
111 {
112 	writel_relaxed(val, base + reg);
113 }
114 
usbhs_read(void __iomem * base,u32 reg)115 static inline u32 usbhs_read(void __iomem *base, u32 reg)
116 {
117 	return readl_relaxed(base + reg);
118 }
119 
120 /*-------------------------------------------------------------------------*/
121 
122 /*
123  * Map 'enum usbhs_omap_port_mode' found in <linux/platform_data/usb-omap.h>
124  * to the device tree binding portN-mode found in
125  * 'Documentation/devicetree/bindings/mfd/omap-usb-host.txt'
126  */
127 static const char * const port_modes[] = {
128 	[OMAP_USBHS_PORT_MODE_UNUSED]	= "",
129 	[OMAP_EHCI_PORT_MODE_PHY]	= "ehci-phy",
130 	[OMAP_EHCI_PORT_MODE_TLL]	= "ehci-tll",
131 	[OMAP_EHCI_PORT_MODE_HSIC]	= "ehci-hsic",
132 	[OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0]	= "ohci-phy-6pin-datse0",
133 	[OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM]	= "ohci-phy-6pin-dpdm",
134 	[OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0]	= "ohci-phy-3pin-datse0",
135 	[OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM]	= "ohci-phy-4pin-dpdm",
136 	[OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0]	= "ohci-tll-6pin-datse0",
137 	[OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM]	= "ohci-tll-6pin-dpdm",
138 	[OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0]	= "ohci-tll-3pin-datse0",
139 	[OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM]	= "ohci-tll-4pin-dpdm",
140 	[OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0]	= "ohci-tll-2pin-datse0",
141 	[OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM]	= "ohci-tll-2pin-dpdm",
142 };
143 
omap_usbhs_alloc_child(const char * name,struct resource * res,int num_resources,void * pdata,size_t pdata_size,struct device * dev)144 static struct platform_device *omap_usbhs_alloc_child(const char *name,
145 			struct resource	*res, int num_resources, void *pdata,
146 			size_t pdata_size, struct device *dev)
147 {
148 	struct platform_device	*child;
149 	int			ret;
150 
151 	child = platform_device_alloc(name, 0);
152 
153 	if (!child) {
154 		dev_err(dev, "platform_device_alloc %s failed\n", name);
155 		goto err_end;
156 	}
157 
158 	ret = platform_device_add_resources(child, res, num_resources);
159 	if (ret) {
160 		dev_err(dev, "platform_device_add_resources failed\n");
161 		goto err_alloc;
162 	}
163 
164 	ret = platform_device_add_data(child, pdata, pdata_size);
165 	if (ret) {
166 		dev_err(dev, "platform_device_add_data failed\n");
167 		goto err_alloc;
168 	}
169 
170 	child->dev.dma_mask		= &usbhs_dmamask;
171 	dma_set_coherent_mask(&child->dev, DMA_BIT_MASK(32));
172 	child->dev.parent		= dev;
173 
174 	ret = platform_device_add(child);
175 	if (ret) {
176 		dev_err(dev, "platform_device_add failed\n");
177 		goto err_alloc;
178 	}
179 
180 	return child;
181 
182 err_alloc:
183 	platform_device_put(child);
184 
185 err_end:
186 	return NULL;
187 }
188 
omap_usbhs_alloc_children(struct platform_device * pdev)189 static int omap_usbhs_alloc_children(struct platform_device *pdev)
190 {
191 	struct device				*dev = &pdev->dev;
192 	struct usbhs_omap_platform_data		*pdata = dev_get_platdata(dev);
193 	struct platform_device			*ehci;
194 	struct platform_device			*ohci;
195 	struct resource				*res;
196 	struct resource				resources[2];
197 	int					ret;
198 
199 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
200 	if (!res) {
201 		dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n");
202 		ret = -ENODEV;
203 		goto err_end;
204 	}
205 	resources[0] = *res;
206 
207 	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq");
208 	if (!res) {
209 		dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n");
210 		ret = -ENODEV;
211 		goto err_end;
212 	}
213 	resources[1] = *res;
214 
215 	ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, pdata,
216 		sizeof(*pdata), dev);
217 
218 	if (!ehci) {
219 		dev_err(dev, "omap_usbhs_alloc_child failed\n");
220 		ret = -ENOMEM;
221 		goto err_end;
222 	}
223 
224 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci");
225 	if (!res) {
226 		dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n");
227 		ret = -ENODEV;
228 		goto err_ehci;
229 	}
230 	resources[0] = *res;
231 
232 	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq");
233 	if (!res) {
234 		dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n");
235 		ret = -ENODEV;
236 		goto err_ehci;
237 	}
238 	resources[1] = *res;
239 
240 	ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, pdata,
241 		sizeof(*pdata), dev);
242 	if (!ohci) {
243 		dev_err(dev, "omap_usbhs_alloc_child failed\n");
244 		ret = -ENOMEM;
245 		goto err_ehci;
246 	}
247 
248 	return 0;
249 
250 err_ehci:
251 	platform_device_unregister(ehci);
252 
253 err_end:
254 	return ret;
255 }
256 
is_ohci_port(enum usbhs_omap_port_mode pmode)257 static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
258 {
259 	switch (pmode) {
260 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
261 	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
262 	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
263 	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
264 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
265 	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
266 	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
267 	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
268 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
269 	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
270 		return true;
271 
272 	default:
273 		return false;
274 	}
275 }
276 
usbhs_runtime_resume(struct device * dev)277 static int usbhs_runtime_resume(struct device *dev)
278 {
279 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
280 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
281 	int i, r;
282 
283 	dev_dbg(dev, "usbhs_runtime_resume\n");
284 
285 	omap_tll_enable(pdata);
286 
287 	if (!IS_ERR(omap->ehci_logic_fck))
288 		clk_prepare_enable(omap->ehci_logic_fck);
289 
290 	for (i = 0; i < omap->nports; i++) {
291 		switch (pdata->port_mode[i]) {
292 		case OMAP_EHCI_PORT_MODE_HSIC:
293 			if (!IS_ERR(omap->hsic60m_clk[i])) {
294 				r = clk_prepare_enable(omap->hsic60m_clk[i]);
295 				if (r) {
296 					dev_err(dev,
297 					 "Can't enable port %d hsic60m clk:%d\n",
298 					 i, r);
299 				}
300 			}
301 
302 			if (!IS_ERR(omap->hsic480m_clk[i])) {
303 				r = clk_prepare_enable(omap->hsic480m_clk[i]);
304 				if (r) {
305 					dev_err(dev,
306 					 "Can't enable port %d hsic480m clk:%d\n",
307 					 i, r);
308 				}
309 			}
310 			fallthrough;	/* as HSIC mode needs utmi_clk */
311 
312 		case OMAP_EHCI_PORT_MODE_TLL:
313 			if (!IS_ERR(omap->utmi_clk[i])) {
314 				r = clk_prepare_enable(omap->utmi_clk[i]);
315 				if (r) {
316 					dev_err(dev,
317 					 "Can't enable port %d clk : %d\n",
318 					 i, r);
319 				}
320 			}
321 			break;
322 		default:
323 			break;
324 		}
325 	}
326 
327 	return 0;
328 }
329 
usbhs_runtime_suspend(struct device * dev)330 static int usbhs_runtime_suspend(struct device *dev)
331 {
332 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
333 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
334 	int i;
335 
336 	dev_dbg(dev, "usbhs_runtime_suspend\n");
337 
338 	for (i = 0; i < omap->nports; i++) {
339 		switch (pdata->port_mode[i]) {
340 		case OMAP_EHCI_PORT_MODE_HSIC:
341 			if (!IS_ERR(omap->hsic60m_clk[i]))
342 				clk_disable_unprepare(omap->hsic60m_clk[i]);
343 
344 			if (!IS_ERR(omap->hsic480m_clk[i]))
345 				clk_disable_unprepare(omap->hsic480m_clk[i]);
346 			fallthrough;	/* as utmi_clks were used in HSIC mode */
347 
348 		case OMAP_EHCI_PORT_MODE_TLL:
349 			if (!IS_ERR(omap->utmi_clk[i]))
350 				clk_disable_unprepare(omap->utmi_clk[i]);
351 			break;
352 		default:
353 			break;
354 		}
355 	}
356 
357 	if (!IS_ERR(omap->ehci_logic_fck))
358 		clk_disable_unprepare(omap->ehci_logic_fck);
359 
360 	omap_tll_disable(pdata);
361 
362 	return 0;
363 }
364 
omap_usbhs_rev1_hostconfig(struct usbhs_hcd_omap * omap,unsigned reg)365 static unsigned omap_usbhs_rev1_hostconfig(struct usbhs_hcd_omap *omap,
366 						unsigned reg)
367 {
368 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
369 	int i;
370 
371 	for (i = 0; i < omap->nports; i++) {
372 		switch (pdata->port_mode[i]) {
373 		case OMAP_USBHS_PORT_MODE_UNUSED:
374 			reg &= ~(OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS << i);
375 			break;
376 		case OMAP_EHCI_PORT_MODE_PHY:
377 			if (pdata->single_ulpi_bypass)
378 				break;
379 
380 			if (i == 0)
381 				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
382 			else
383 				reg &= ~(OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
384 								<< (i-1));
385 			break;
386 		default:
387 			if (pdata->single_ulpi_bypass)
388 				break;
389 
390 			if (i == 0)
391 				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
392 			else
393 				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
394 								<< (i-1);
395 			break;
396 		}
397 	}
398 
399 	if (pdata->single_ulpi_bypass) {
400 		/* bypass ULPI only if none of the ports use PHY mode */
401 		reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
402 
403 		for (i = 0; i < omap->nports; i++) {
404 			if (is_ehci_phy_mode(pdata->port_mode[i])) {
405 				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
406 				break;
407 			}
408 		}
409 	}
410 
411 	return reg;
412 }
413 
omap_usbhs_rev2_hostconfig(struct usbhs_hcd_omap * omap,unsigned reg)414 static unsigned omap_usbhs_rev2_hostconfig(struct usbhs_hcd_omap *omap,
415 						unsigned reg)
416 {
417 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
418 	int i;
419 
420 	for (i = 0; i < omap->nports; i++) {
421 		/* Clear port mode fields for PHY mode */
422 		reg &= ~(OMAP4_P1_MODE_CLEAR << 2 * i);
423 
424 		if (is_ehci_tll_mode(pdata->port_mode[i]) ||
425 				(is_ohci_port(pdata->port_mode[i])))
426 			reg |= OMAP4_P1_MODE_TLL << 2 * i;
427 		else if (is_ehci_hsic_mode(pdata->port_mode[i]))
428 			reg |= OMAP4_P1_MODE_HSIC << 2 * i;
429 	}
430 
431 	return reg;
432 }
433 
omap_usbhs_init(struct device * dev)434 static void omap_usbhs_init(struct device *dev)
435 {
436 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
437 	unsigned			reg;
438 
439 	dev_dbg(dev, "starting TI HSUSB Controller\n");
440 
441 	pm_runtime_get_sync(dev);
442 
443 	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
444 	/* setup ULPI bypass and burst configurations */
445 	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
446 			| OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN
447 			| OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN);
448 	reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK;
449 	reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
450 
451 	switch (omap->usbhs_rev) {
452 	case OMAP_USBHS_REV1:
453 		reg = omap_usbhs_rev1_hostconfig(omap, reg);
454 		break;
455 
456 	case OMAP_USBHS_REV2:
457 		reg = omap_usbhs_rev2_hostconfig(omap, reg);
458 		break;
459 
460 	default:	/* newer revisions */
461 		reg = omap_usbhs_rev2_hostconfig(omap, reg);
462 		break;
463 	}
464 
465 	usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
466 	dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
467 
468 	pm_runtime_put_sync(dev);
469 }
470 
usbhs_omap_get_dt_pdata(struct device * dev,struct usbhs_omap_platform_data * pdata)471 static int usbhs_omap_get_dt_pdata(struct device *dev,
472 					struct usbhs_omap_platform_data *pdata)
473 {
474 	int ret, i;
475 	struct device_node *node = dev->of_node;
476 
477 	ret = of_property_read_u32(node, "num-ports", &pdata->nports);
478 	if (ret)
479 		pdata->nports = 0;
480 
481 	if (pdata->nports > OMAP3_HS_USB_PORTS) {
482 		dev_warn(dev, "Too many num_ports <%d> in device tree. Max %d\n",
483 				pdata->nports, OMAP3_HS_USB_PORTS);
484 		return -ENODEV;
485 	}
486 
487 	/* get port modes */
488 	for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
489 		char prop[11];
490 		const char *mode;
491 
492 		pdata->port_mode[i] = OMAP_USBHS_PORT_MODE_UNUSED;
493 
494 		snprintf(prop, sizeof(prop), "port%d-mode", i + 1);
495 		ret = of_property_read_string(node, prop, &mode);
496 		if (ret < 0)
497 			continue;
498 
499 		/* get 'enum usbhs_omap_port_mode' from port mode string */
500 		ret = match_string(port_modes, ARRAY_SIZE(port_modes), mode);
501 		if (ret < 0) {
502 			dev_warn(dev, "Invalid port%d-mode \"%s\" in device tree\n",
503 					i, mode);
504 			return -ENODEV;
505 		}
506 
507 		dev_dbg(dev, "port%d-mode: %s -> %d\n", i, mode, ret);
508 		pdata->port_mode[i] = ret;
509 	}
510 
511 	/* get flags */
512 	pdata->single_ulpi_bypass = of_property_read_bool(node,
513 						"single-ulpi-bypass");
514 
515 	return 0;
516 }
517 
518 static const struct of_device_id usbhs_child_match_table[] = {
519 	{ .compatible = "ti,ehci-omap", },
520 	{ .compatible = "ti,ohci-omap3", },
521 	{ }
522 };
523 
524 /**
525  * usbhs_omap_probe - initialize TI-based HCDs
526  *
527  * Allocates basic resources for this USB host controller.
528  *
529  * @pdev: Pointer to this device's platform device structure
530  */
usbhs_omap_probe(struct platform_device * pdev)531 static int usbhs_omap_probe(struct platform_device *pdev)
532 {
533 	struct device			*dev =  &pdev->dev;
534 	struct usbhs_omap_platform_data	*pdata = dev_get_platdata(dev);
535 	struct usbhs_hcd_omap		*omap;
536 	int				ret = 0;
537 	int				i;
538 	bool				need_logic_fck;
539 
540 	if (dev->of_node) {
541 		/* For DT boot we populate platform data from OF node */
542 		pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
543 		if (!pdata)
544 			return -ENOMEM;
545 
546 		ret = usbhs_omap_get_dt_pdata(dev, pdata);
547 		if (ret)
548 			return ret;
549 
550 		dev->platform_data = pdata;
551 	}
552 
553 	if (!pdata) {
554 		dev_err(dev, "Missing platform data\n");
555 		return -ENODEV;
556 	}
557 
558 	if (pdata->nports > OMAP3_HS_USB_PORTS) {
559 		dev_info(dev, "Too many num_ports <%d> in platform_data. Max %d\n",
560 				pdata->nports, OMAP3_HS_USB_PORTS);
561 		return -ENODEV;
562 	}
563 
564 	omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
565 	if (!omap) {
566 		dev_err(dev, "Memory allocation failed\n");
567 		return -ENOMEM;
568 	}
569 
570 	omap->uhh_base = devm_platform_ioremap_resource(pdev, 0);
571 	if (IS_ERR(omap->uhh_base))
572 		return PTR_ERR(omap->uhh_base);
573 
574 	omap->pdata = pdata;
575 
576 	/* Initialize the TLL subsystem */
577 	omap_tll_init(pdata);
578 
579 	pm_runtime_enable(dev);
580 
581 	platform_set_drvdata(pdev, omap);
582 	pm_runtime_get_sync(dev);
583 
584 	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
585 
586 	/* we need to call runtime suspend before we update omap->nports
587 	 * to prevent unbalanced clk_disable()
588 	 */
589 	pm_runtime_put_sync(dev);
590 
591 	/*
592 	 * If platform data contains nports then use that
593 	 * else make out number of ports from USBHS revision
594 	 */
595 	if (pdata->nports) {
596 		omap->nports = pdata->nports;
597 	} else {
598 		switch (omap->usbhs_rev) {
599 		case OMAP_USBHS_REV1:
600 			omap->nports = 3;
601 			break;
602 		case OMAP_USBHS_REV2:
603 			omap->nports = 2;
604 			break;
605 		default:
606 			omap->nports = OMAP3_HS_USB_PORTS;
607 			dev_dbg(dev,
608 			 "USB HOST Rev:0x%x not recognized, assuming %d ports\n",
609 			 omap->usbhs_rev, omap->nports);
610 			break;
611 		}
612 		pdata->nports = omap->nports;
613 	}
614 
615 	i = sizeof(struct clk *) * omap->nports;
616 	omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
617 	omap->hsic480m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
618 	omap->hsic60m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
619 
620 	if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk) {
621 		dev_err(dev, "Memory allocation failed\n");
622 		ret = -ENOMEM;
623 		goto err_mem;
624 	}
625 
626 	/* Set all clocks as invalid to begin with */
627 	omap->ehci_logic_fck = ERR_PTR(-ENODEV);
628 	omap->init_60m_fclk = ERR_PTR(-ENODEV);
629 	omap->utmi_p1_gfclk = ERR_PTR(-ENODEV);
630 	omap->utmi_p2_gfclk = ERR_PTR(-ENODEV);
631 	omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV);
632 	omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV);
633 
634 	for (i = 0; i < omap->nports; i++) {
635 		omap->utmi_clk[i] = ERR_PTR(-ENODEV);
636 		omap->hsic480m_clk[i] = ERR_PTR(-ENODEV);
637 		omap->hsic60m_clk[i] = ERR_PTR(-ENODEV);
638 	}
639 
640 	/* for OMAP3 i.e. USBHS REV1 */
641 	if (omap->usbhs_rev == OMAP_USBHS_REV1) {
642 		need_logic_fck = false;
643 		for (i = 0; i < omap->nports; i++) {
644 			if (is_ehci_phy_mode(pdata->port_mode[i]) ||
645 			    is_ehci_tll_mode(pdata->port_mode[i]) ||
646 			    is_ehci_hsic_mode(pdata->port_mode[i]))
647 
648 				need_logic_fck |= true;
649 		}
650 
651 		if (need_logic_fck) {
652 			omap->ehci_logic_fck = devm_clk_get(dev,
653 							    "usbhost_120m_fck");
654 			if (IS_ERR(omap->ehci_logic_fck)) {
655 				ret = PTR_ERR(omap->ehci_logic_fck);
656 				dev_err(dev, "usbhost_120m_fck failed:%d\n",
657 					ret);
658 				goto err_mem;
659 			}
660 		}
661 		goto initialize;
662 	}
663 
664 	/* for OMAP4+ i.e. USBHS REV2+ */
665 	omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk");
666 	if (IS_ERR(omap->utmi_p1_gfclk)) {
667 		ret = PTR_ERR(omap->utmi_p1_gfclk);
668 		dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
669 		goto err_mem;
670 	}
671 
672 	omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk");
673 	if (IS_ERR(omap->utmi_p2_gfclk)) {
674 		ret = PTR_ERR(omap->utmi_p2_gfclk);
675 		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
676 		goto err_mem;
677 	}
678 
679 	omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
680 	if (IS_ERR(omap->xclk60mhsp1_ck)) {
681 		ret = PTR_ERR(omap->xclk60mhsp1_ck);
682 		dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret);
683 		goto err_mem;
684 	}
685 
686 	omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
687 	if (IS_ERR(omap->xclk60mhsp2_ck)) {
688 		ret = PTR_ERR(omap->xclk60mhsp2_ck);
689 		dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret);
690 		goto err_mem;
691 	}
692 
693 	omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
694 	if (IS_ERR(omap->init_60m_fclk)) {
695 		ret = PTR_ERR(omap->init_60m_fclk);
696 		dev_err(dev, "refclk_60m_int failed error:%d\n", ret);
697 		goto err_mem;
698 	}
699 
700 	for (i = 0; i < omap->nports; i++) {
701 		char clkname[40];
702 
703 		/* clock names are indexed from 1*/
704 		snprintf(clkname, sizeof(clkname),
705 				"usb_host_hs_utmi_p%d_clk", i + 1);
706 
707 		/* If a clock is not found we won't bail out as not all
708 		 * platforms have all clocks and we can function without
709 		 * them
710 		 */
711 		omap->utmi_clk[i] = devm_clk_get(dev, clkname);
712 		if (IS_ERR(omap->utmi_clk[i])) {
713 			ret = PTR_ERR(omap->utmi_clk[i]);
714 			dev_err(dev, "Failed to get clock : %s : %d\n",
715 				clkname, ret);
716 			goto err_mem;
717 		}
718 
719 		snprintf(clkname, sizeof(clkname),
720 				"usb_host_hs_hsic480m_p%d_clk", i + 1);
721 		omap->hsic480m_clk[i] = devm_clk_get(dev, clkname);
722 		if (IS_ERR(omap->hsic480m_clk[i])) {
723 			ret = PTR_ERR(omap->hsic480m_clk[i]);
724 			dev_err(dev, "Failed to get clock : %s : %d\n",
725 				clkname, ret);
726 			goto err_mem;
727 		}
728 
729 		snprintf(clkname, sizeof(clkname),
730 				"usb_host_hs_hsic60m_p%d_clk", i + 1);
731 		omap->hsic60m_clk[i] = devm_clk_get(dev, clkname);
732 		if (IS_ERR(omap->hsic60m_clk[i])) {
733 			ret = PTR_ERR(omap->hsic60m_clk[i]);
734 			dev_err(dev, "Failed to get clock : %s : %d\n",
735 				clkname, ret);
736 			goto err_mem;
737 		}
738 	}
739 
740 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
741 		ret = clk_set_parent(omap->utmi_p1_gfclk,
742 					omap->xclk60mhsp1_ck);
743 		if (ret != 0) {
744 			dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n",
745 				ret);
746 			goto err_mem;
747 		}
748 	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
749 		ret = clk_set_parent(omap->utmi_p1_gfclk,
750 					omap->init_60m_fclk);
751 		if (ret != 0) {
752 			dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n",
753 				ret);
754 			goto err_mem;
755 		}
756 	}
757 
758 	if (is_ehci_phy_mode(pdata->port_mode[1])) {
759 		ret = clk_set_parent(omap->utmi_p2_gfclk,
760 					omap->xclk60mhsp2_ck);
761 		if (ret != 0) {
762 			dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n",
763 				ret);
764 			goto err_mem;
765 		}
766 	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
767 		ret = clk_set_parent(omap->utmi_p2_gfclk,
768 						omap->init_60m_fclk);
769 		if (ret != 0) {
770 			dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n",
771 				ret);
772 			goto err_mem;
773 		}
774 	}
775 
776 initialize:
777 	omap_usbhs_init(dev);
778 
779 	if (dev->of_node) {
780 		ret = of_platform_populate(dev->of_node,
781 				usbhs_child_match_table, NULL, dev);
782 
783 		if (ret) {
784 			dev_err(dev, "Failed to create DT children: %d\n", ret);
785 			goto err_mem;
786 		}
787 
788 	} else {
789 		ret = omap_usbhs_alloc_children(pdev);
790 		if (ret) {
791 			dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
792 						ret);
793 			goto err_mem;
794 		}
795 	}
796 
797 	return 0;
798 
799 err_mem:
800 	pm_runtime_disable(dev);
801 
802 	return ret;
803 }
804 
usbhs_omap_remove_child(struct device * dev,void * data)805 static int usbhs_omap_remove_child(struct device *dev, void *data)
806 {
807 	dev_info(dev, "unregistering\n");
808 	platform_device_unregister(to_platform_device(dev));
809 	return 0;
810 }
811 
812 /**
813  * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
814  * @pdev: USB Host Controller being removed
815  *
816  * Reverses the effect of usbhs_omap_probe().
817  */
usbhs_omap_remove(struct platform_device * pdev)818 static void usbhs_omap_remove(struct platform_device *pdev)
819 {
820 	pm_runtime_disable(&pdev->dev);
821 
822 	/* remove children */
823 	device_for_each_child(&pdev->dev, NULL, usbhs_omap_remove_child);
824 }
825 
826 static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
827 	.runtime_suspend	= usbhs_runtime_suspend,
828 	.runtime_resume		= usbhs_runtime_resume,
829 };
830 
831 static const struct of_device_id usbhs_omap_dt_ids[] = {
832 	{ .compatible = "ti,usbhs-host" },
833 	{ }
834 };
835 
836 MODULE_DEVICE_TABLE(of, usbhs_omap_dt_ids);
837 
838 
839 static struct platform_driver usbhs_omap_driver = {
840 	.driver = {
841 		.name		= usbhs_driver_name,
842 		.pm		= &usbhsomap_dev_pm_ops,
843 		.of_match_table = usbhs_omap_dt_ids,
844 	},
845 	.probe		= usbhs_omap_probe,
846 	.remove		= usbhs_omap_remove,
847 };
848 
849 MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
850 MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
851 MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
852 MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");
853 
omap_usbhs_drvinit(void)854 static int omap_usbhs_drvinit(void)
855 {
856 	return platform_driver_register(&usbhs_omap_driver);
857 }
858 
859 /*
860  * init before ehci and ohci drivers;
861  * The usbhs core driver should be initialized much before
862  * the omap ehci and ohci probe functions are called.
863  * This usbhs core driver should be initialized after
864  * usb tll driver
865  */
866 fs_initcall_sync(omap_usbhs_drvinit);
867 
omap_usbhs_drvexit(void)868 static void omap_usbhs_drvexit(void)
869 {
870 	platform_driver_unregister(&usbhs_omap_driver);
871 }
872 module_exit(omap_usbhs_drvexit);
873