xref: /openbmc/u-boot/drivers/usb/musb-new/omap2430.c (revision 0a61ee88)
1 /*
2  * Copyright (C) 2005-2007 by Texas Instruments
3  * Some code has been taken from tusb6010.c
4  * Copyrights for that are attributable to:
5  * Copyright (C) 2006 Nokia Corporation
6  * Tony Lindgren <tony@atomide.com>
7  *
8  * This file is part of the Inventra Controller Driver for Linux.
9  *
10  * SPDX-License-Identifier:	GPL-2.0
11  */
12 #ifndef __UBOOT__
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/init.h>
17 #include <linux/list.h>
18 #include <linux/io.h>
19 #include <linux/platform_device.h>
20 #include <linux/dma-mapping.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/err.h>
23 #include <linux/usb/musb-omap.h>
24 #else
25 #include <common.h>
26 #include <asm/omap_musb.h>
27 #include <twl4030.h>
28 #include "linux-compat.h"
29 #endif
30 
31 #include "musb_core.h"
32 #include "omap2430.h"
33 
34 #ifndef __UBOOT__
35 struct omap2430_glue {
36 	struct device		*dev;
37 	struct platform_device	*musb;
38 	enum omap_musb_vbus_id_status status;
39 	struct work_struct	omap_musb_mailbox_work;
40 };
41 #define glue_to_musb(g)		platform_get_drvdata(g->musb)
42 
43 struct omap2430_glue		*_glue;
44 
45 static struct timer_list musb_idle_timer;
46 
47 static void musb_do_idle(unsigned long _musb)
48 {
49 	struct musb	*musb = (void *)_musb;
50 	unsigned long	flags;
51 	u8	power;
52 	u8	devctl;
53 
54 	spin_lock_irqsave(&musb->lock, flags);
55 
56 	switch (musb->xceiv->state) {
57 	case OTG_STATE_A_WAIT_BCON:
58 
59 		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
60 		if (devctl & MUSB_DEVCTL_BDEVICE) {
61 			musb->xceiv->state = OTG_STATE_B_IDLE;
62 			MUSB_DEV_MODE(musb);
63 		} else {
64 			musb->xceiv->state = OTG_STATE_A_IDLE;
65 			MUSB_HST_MODE(musb);
66 		}
67 		break;
68 	case OTG_STATE_A_SUSPEND:
69 		/* finish RESUME signaling? */
70 		if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
71 			power = musb_readb(musb->mregs, MUSB_POWER);
72 			power &= ~MUSB_POWER_RESUME;
73 			dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
74 			musb_writeb(musb->mregs, MUSB_POWER, power);
75 			musb->is_active = 1;
76 			musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
77 						| MUSB_PORT_STAT_RESUME);
78 			musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
79 			usb_hcd_poll_rh_status(musb_to_hcd(musb));
80 			/* NOTE: it might really be A_WAIT_BCON ... */
81 			musb->xceiv->state = OTG_STATE_A_HOST;
82 		}
83 		break;
84 	case OTG_STATE_A_HOST:
85 		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
86 		if (devctl &  MUSB_DEVCTL_BDEVICE)
87 			musb->xceiv->state = OTG_STATE_B_IDLE;
88 		else
89 			musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
90 	default:
91 		break;
92 	}
93 	spin_unlock_irqrestore(&musb->lock, flags);
94 }
95 
96 
97 static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
98 {
99 	unsigned long		default_timeout = jiffies + msecs_to_jiffies(3);
100 	static unsigned long	last_timer;
101 
102 	if (timeout == 0)
103 		timeout = default_timeout;
104 
105 	/* Never idle if active, or when VBUS timeout is not set as host */
106 	if (musb->is_active || ((musb->a_wait_bcon == 0)
107 			&& (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
108 		dev_dbg(musb->controller, "%s active, deleting timer\n",
109 			otg_state_string(musb->xceiv->state));
110 		del_timer(&musb_idle_timer);
111 		last_timer = jiffies;
112 		return;
113 	}
114 
115 	if (time_after(last_timer, timeout)) {
116 		if (!timer_pending(&musb_idle_timer))
117 			last_timer = timeout;
118 		else {
119 			dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
120 			return;
121 		}
122 	}
123 	last_timer = timeout;
124 
125 	dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
126 		otg_state_string(musb->xceiv->state),
127 		(unsigned long)jiffies_to_msecs(timeout - jiffies));
128 	mod_timer(&musb_idle_timer, timeout);
129 }
130 
131 static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
132 {
133 	struct usb_otg	*otg = musb->xceiv->otg;
134 	u8		devctl;
135 	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
136 	int ret = 1;
137 	/* HDRC controls CPEN, but beware current surges during device
138 	 * connect.  They can trigger transient overcurrent conditions
139 	 * that must be ignored.
140 	 */
141 
142 	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
143 
144 	if (is_on) {
145 		if (musb->xceiv->state == OTG_STATE_A_IDLE) {
146 			/* start the session */
147 			devctl |= MUSB_DEVCTL_SESSION;
148 			musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
149 			/*
150 			 * Wait for the musb to set as A device to enable the
151 			 * VBUS
152 			 */
153 			while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
154 
155 				cpu_relax();
156 
157 				if (time_after(jiffies, timeout)) {
158 					dev_err(musb->controller,
159 					"configured as A device timeout");
160 					ret = -EINVAL;
161 					break;
162 				}
163 			}
164 
165 			if (ret && otg->set_vbus)
166 				otg_set_vbus(otg, 1);
167 		} else {
168 			musb->is_active = 1;
169 			otg->default_a = 1;
170 			musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
171 			devctl |= MUSB_DEVCTL_SESSION;
172 			MUSB_HST_MODE(musb);
173 		}
174 	} else {
175 		musb->is_active = 0;
176 
177 		/* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
178 		 * jumping right to B_IDLE...
179 		 */
180 
181 		otg->default_a = 0;
182 		musb->xceiv->state = OTG_STATE_B_IDLE;
183 		devctl &= ~MUSB_DEVCTL_SESSION;
184 
185 		MUSB_DEV_MODE(musb);
186 	}
187 	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
188 
189 	dev_dbg(musb->controller, "VBUS %s, devctl %02x "
190 		/* otg %3x conf %08x prcm %08x */ "\n",
191 		otg_state_string(musb->xceiv->state),
192 		musb_readb(musb->mregs, MUSB_DEVCTL));
193 }
194 
195 static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
196 {
197 	u8	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
198 
199 	devctl |= MUSB_DEVCTL_SESSION;
200 	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
201 
202 	return 0;
203 }
204 #endif
205 
206 static inline void omap2430_low_level_exit(struct musb *musb)
207 {
208 	u32 l;
209 
210 	/* in any role */
211 	l = musb_readl(musb->mregs, OTG_FORCESTDBY);
212 	l |= ENABLEFORCE;	/* enable MSTANDBY */
213 	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
214 }
215 
216 static inline void omap2430_low_level_init(struct musb *musb)
217 {
218 	u32 l;
219 
220 	l = musb_readl(musb->mregs, OTG_FORCESTDBY);
221 	l &= ~ENABLEFORCE;	/* disable MSTANDBY */
222 	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
223 }
224 
225 #ifndef __UBOOT__
226 void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
227 {
228 	struct omap2430_glue	*glue = _glue;
229 	struct musb		*musb = glue_to_musb(glue);
230 
231 	glue->status = status;
232 	if (!musb) {
233 		dev_err(glue->dev, "musb core is not yet ready\n");
234 		return;
235 	}
236 
237 	schedule_work(&glue->omap_musb_mailbox_work);
238 }
239 EXPORT_SYMBOL_GPL(omap_musb_mailbox);
240 
241 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
242 {
243 	struct musb *musb = glue_to_musb(glue);
244 	struct device *dev = musb->controller;
245 	struct musb_hdrc_platform_data *pdata = dev->platform_data;
246 	struct omap_musb_board_data *data = pdata->board_data;
247 	struct usb_otg *otg = musb->xceiv->otg;
248 
249 	switch (glue->status) {
250 	case OMAP_MUSB_ID_GROUND:
251 		dev_dbg(dev, "ID GND\n");
252 
253 		otg->default_a = true;
254 		musb->xceiv->state = OTG_STATE_A_IDLE;
255 		musb->xceiv->last_event = USB_EVENT_ID;
256 		if (!is_otg_enabled(musb) || musb->gadget_driver) {
257 			pm_runtime_get_sync(dev);
258 			usb_phy_init(musb->xceiv);
259 			omap2430_musb_set_vbus(musb, 1);
260 		}
261 		break;
262 
263 	case OMAP_MUSB_VBUS_VALID:
264 		dev_dbg(dev, "VBUS Connect\n");
265 
266 		otg->default_a = false;
267 		musb->xceiv->state = OTG_STATE_B_IDLE;
268 		musb->xceiv->last_event = USB_EVENT_VBUS;
269 		if (musb->gadget_driver)
270 			pm_runtime_get_sync(dev);
271 		usb_phy_init(musb->xceiv);
272 		break;
273 
274 	case OMAP_MUSB_ID_FLOAT:
275 	case OMAP_MUSB_VBUS_OFF:
276 		dev_dbg(dev, "VBUS Disconnect\n");
277 
278 		musb->xceiv->last_event = USB_EVENT_NONE;
279 		if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
280 			if (musb->gadget_driver) {
281 				pm_runtime_mark_last_busy(dev);
282 				pm_runtime_put_autosuspend(dev);
283 			}
284 
285 		if (data->interface_type == MUSB_INTERFACE_UTMI) {
286 			if (musb->xceiv->otg->set_vbus)
287 				otg_set_vbus(musb->xceiv->otg, 0);
288 		}
289 		usb_phy_shutdown(musb->xceiv);
290 		break;
291 	default:
292 		dev_dbg(dev, "ID float\n");
293 	}
294 }
295 
296 
297 static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
298 {
299 	struct omap2430_glue *glue = container_of(mailbox_work,
300 				struct omap2430_glue, omap_musb_mailbox_work);
301 	omap_musb_set_mailbox(glue);
302 }
303 #endif
304 
305 static int omap2430_musb_init(struct musb *musb)
306 {
307 	u32 l;
308 	int status = 0;
309 	unsigned long int start;
310 #ifndef __UBOOT__
311 	struct device *dev = musb->controller;
312 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
313 	struct musb_hdrc_platform_data *plat = dev->platform_data;
314 	struct omap_musb_board_data *data = plat->board_data;
315 #else
316 	struct omap_musb_board_data *data =
317 		(struct omap_musb_board_data *)musb->controller;
318 #endif
319 
320 	/* Reset the controller */
321 	musb_writel(musb->mregs, OTG_SYSCONFIG, SOFTRST);
322 
323 	start = get_timer(0);
324 
325 	while (1) {
326 		l = musb_readl(musb->mregs, OTG_SYSCONFIG);
327 		if ((l & SOFTRST) == 0)
328 			break;
329 
330 		if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
331 			dev_err(musb->controller, "MUSB reset is taking too long\n");
332 			return -ENODEV;
333 		}
334 	}
335 
336 #ifndef __UBOOT__
337 	/* We require some kind of external transceiver, hooked
338 	 * up through ULPI.  TWL4030-family PMICs include one,
339 	 * which needs a driver, drivers aren't always needed.
340 	 */
341 	musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
342 	if (IS_ERR_OR_NULL(musb->xceiv)) {
343 		pr_err("HS USB OTG: no transceiver configured\n");
344 		return -ENODEV;
345 	}
346 
347 	status = pm_runtime_get_sync(dev);
348 	if (status < 0) {
349 		dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
350 		goto err1;
351 	}
352 #endif
353 
354 	l = musb_readl(musb->mregs, OTG_INTERFSEL);
355 
356 	if (data->interface_type == MUSB_INTERFACE_UTMI) {
357 		/* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
358 		l &= ~ULPI_12PIN;       /* Disable ULPI */
359 		l |= UTMI_8BIT;         /* Enable UTMI  */
360 	} else {
361 		l |= ULPI_12PIN;
362 	}
363 
364 	musb_writel(musb->mregs, OTG_INTERFSEL, l);
365 
366 	pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
367 			"sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
368 			musb_readl(musb->mregs, OTG_REVISION),
369 			musb_readl(musb->mregs, OTG_SYSCONFIG),
370 			musb_readl(musb->mregs, OTG_SYSSTATUS),
371 			musb_readl(musb->mregs, OTG_INTERFSEL),
372 			musb_readl(musb->mregs, OTG_SIMENABLE));
373 
374 #ifndef __UBOOT__
375 	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
376 
377 	if (glue->status != OMAP_MUSB_UNKNOWN)
378 		omap_musb_set_mailbox(glue);
379 
380 	pm_runtime_put_noidle(musb->controller);
381 #endif
382 	return 0;
383 
384 err1:
385 	return status;
386 }
387 
388 #ifndef __UBOOT__
389 static void omap2430_musb_enable(struct musb *musb)
390 #else
391 static int omap2430_musb_enable(struct musb *musb)
392 #endif
393 {
394 #ifndef __UBOOT__
395 	u8		devctl;
396 	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
397 	struct device *dev = musb->controller;
398 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
399 	struct musb_hdrc_platform_data *pdata = dev->platform_data;
400 	struct omap_musb_board_data *data = pdata->board_data;
401 
402 	switch (glue->status) {
403 
404 	case OMAP_MUSB_ID_GROUND:
405 		usb_phy_init(musb->xceiv);
406 		if (data->interface_type != MUSB_INTERFACE_UTMI)
407 			break;
408 		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
409 		/* start the session */
410 		devctl |= MUSB_DEVCTL_SESSION;
411 		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
412 		while (musb_readb(musb->mregs, MUSB_DEVCTL) &
413 				MUSB_DEVCTL_BDEVICE) {
414 			cpu_relax();
415 
416 			if (time_after(jiffies, timeout)) {
417 				dev_err(dev, "configured as A device timeout");
418 				break;
419 			}
420 		}
421 		break;
422 
423 	case OMAP_MUSB_VBUS_VALID:
424 		usb_phy_init(musb->xceiv);
425 		break;
426 
427 	default:
428 		break;
429 	}
430 #else
431 #ifdef CONFIG_TWL4030_USB
432 	if (twl4030_usb_ulpi_init()) {
433 		serial_printf("ERROR: %s Could not initialize PHY\n",
434 				__PRETTY_FUNCTION__);
435 	}
436 #endif
437 	return 0;
438 #endif
439 }
440 
441 static void omap2430_musb_disable(struct musb *musb)
442 {
443 #ifndef __UBOOT__
444 	struct device *dev = musb->controller;
445 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
446 
447 	if (glue->status != OMAP_MUSB_UNKNOWN)
448 		usb_phy_shutdown(musb->xceiv);
449 #endif
450 }
451 
452 static int omap2430_musb_exit(struct musb *musb)
453 {
454 	del_timer_sync(&musb_idle_timer);
455 
456 	omap2430_low_level_exit(musb);
457 
458 	return 0;
459 }
460 
461 #ifndef __UBOOT__
462 static const struct musb_platform_ops omap2430_ops = {
463 #else
464 const struct musb_platform_ops omap2430_ops = {
465 #endif
466 	.init		= omap2430_musb_init,
467 	.exit		= omap2430_musb_exit,
468 
469 #ifndef __UBOOT__
470 	.set_mode	= omap2430_musb_set_mode,
471 	.try_idle	= omap2430_musb_try_idle,
472 
473 	.set_vbus	= omap2430_musb_set_vbus,
474 #endif
475 
476 	.enable		= omap2430_musb_enable,
477 	.disable	= omap2430_musb_disable,
478 };
479 
480 #ifndef __UBOOT__
481 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
482 
483 static int __devinit omap2430_probe(struct platform_device *pdev)
484 {
485 	struct musb_hdrc_platform_data	*pdata = pdev->dev.platform_data;
486 	struct platform_device		*musb;
487 	struct omap2430_glue		*glue;
488 	int				ret = -ENOMEM;
489 
490 	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
491 	if (!glue) {
492 		dev_err(&pdev->dev, "failed to allocate glue context\n");
493 		goto err0;
494 	}
495 
496 	musb = platform_device_alloc("musb-hdrc", -1);
497 	if (!musb) {
498 		dev_err(&pdev->dev, "failed to allocate musb device\n");
499 		goto err0;
500 	}
501 
502 	musb->dev.parent		= &pdev->dev;
503 	musb->dev.dma_mask		= &omap2430_dmamask;
504 	musb->dev.coherent_dma_mask	= omap2430_dmamask;
505 
506 	glue->dev			= &pdev->dev;
507 	glue->musb			= musb;
508 	glue->status			= OMAP_MUSB_UNKNOWN;
509 
510 	pdata->platform_ops		= &omap2430_ops;
511 
512 	platform_set_drvdata(pdev, glue);
513 
514 	/*
515 	 * REVISIT if we ever have two instances of the wrapper, we will be
516 	 * in big trouble
517 	 */
518 	_glue	= glue;
519 
520 	INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
521 
522 	ret = platform_device_add_resources(musb, pdev->resource,
523 			pdev->num_resources);
524 	if (ret) {
525 		dev_err(&pdev->dev, "failed to add resources\n");
526 		goto err1;
527 	}
528 
529 	ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
530 	if (ret) {
531 		dev_err(&pdev->dev, "failed to add platform_data\n");
532 		goto err1;
533 	}
534 
535 	pm_runtime_enable(&pdev->dev);
536 
537 	ret = platform_device_add(musb);
538 	if (ret) {
539 		dev_err(&pdev->dev, "failed to register musb device\n");
540 		goto err1;
541 	}
542 
543 	return 0;
544 
545 err1:
546 	platform_device_put(musb);
547 
548 err0:
549 	return ret;
550 }
551 
552 static int __devexit omap2430_remove(struct platform_device *pdev)
553 {
554 	struct omap2430_glue		*glue = platform_get_drvdata(pdev);
555 
556 	cancel_work_sync(&glue->omap_musb_mailbox_work);
557 	platform_device_del(glue->musb);
558 	platform_device_put(glue->musb);
559 
560 	return 0;
561 }
562 
563 #ifdef CONFIG_PM
564 
565 static int omap2430_runtime_suspend(struct device *dev)
566 {
567 	struct omap2430_glue		*glue = dev_get_drvdata(dev);
568 	struct musb			*musb = glue_to_musb(glue);
569 
570 	if (musb) {
571 		musb->context.otg_interfsel = musb_readl(musb->mregs,
572 				OTG_INTERFSEL);
573 
574 		omap2430_low_level_exit(musb);
575 		usb_phy_set_suspend(musb->xceiv, 1);
576 	}
577 
578 	return 0;
579 }
580 
581 static int omap2430_runtime_resume(struct device *dev)
582 {
583 	struct omap2430_glue		*glue = dev_get_drvdata(dev);
584 	struct musb			*musb = glue_to_musb(glue);
585 
586 	if (musb) {
587 		omap2430_low_level_init(musb);
588 		musb_writel(musb->mregs, OTG_INTERFSEL,
589 				musb->context.otg_interfsel);
590 
591 		usb_phy_set_suspend(musb->xceiv, 0);
592 	}
593 
594 	return 0;
595 }
596 
597 static struct dev_pm_ops omap2430_pm_ops = {
598 	.runtime_suspend = omap2430_runtime_suspend,
599 	.runtime_resume = omap2430_runtime_resume,
600 };
601 
602 #define DEV_PM_OPS	(&omap2430_pm_ops)
603 #else
604 #define DEV_PM_OPS	NULL
605 #endif
606 
607 static struct platform_driver omap2430_driver = {
608 	.probe		= omap2430_probe,
609 	.remove		= __devexit_p(omap2430_remove),
610 	.driver		= {
611 		.name	= "musb-omap2430",
612 		.pm	= DEV_PM_OPS,
613 	},
614 };
615 
616 MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
617 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
618 MODULE_LICENSE("GPL v2");
619 
620 static int __init omap2430_init(void)
621 {
622 	return platform_driver_register(&omap2430_driver);
623 }
624 subsys_initcall(omap2430_init);
625 
626 static void __exit omap2430_exit(void)
627 {
628 	platform_driver_unregister(&omap2430_driver);
629 }
630 module_exit(omap2430_exit);
631 #endif
632