1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Texas Instruments AM35x "glue layer"
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (c) 2010, by Texas Instruments
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Based on the DA8xx "glue layer" code.
7*4882a593Smuzhiyun * Copyright (c) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * This file is part of the Inventra Controller Driver for Linux.
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #ifndef __UBOOT__
16*4882a593Smuzhiyun #include <linux/init.h>
17*4882a593Smuzhiyun #include <linux/module.h>
18*4882a593Smuzhiyun #include <linux/clk.h>
19*4882a593Smuzhiyun #include <linux/err.h>
20*4882a593Smuzhiyun #include <linux/io.h>
21*4882a593Smuzhiyun #include <linux/platform_device.h>
22*4882a593Smuzhiyun #include <linux/dma-mapping.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #include <plat/usb.h>
25*4882a593Smuzhiyun #else
26*4882a593Smuzhiyun #include <common.h>
27*4882a593Smuzhiyun #include <asm/omap_musb.h>
28*4882a593Smuzhiyun #include "linux-compat.h"
29*4882a593Smuzhiyun #endif
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "musb_core.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun /*
34*4882a593Smuzhiyun * AM35x specific definitions
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun /* USB 2.0 OTG module registers */
37*4882a593Smuzhiyun #define USB_REVISION_REG 0x00
38*4882a593Smuzhiyun #define USB_CTRL_REG 0x04
39*4882a593Smuzhiyun #define USB_STAT_REG 0x08
40*4882a593Smuzhiyun #define USB_EMULATION_REG 0x0c
41*4882a593Smuzhiyun /* 0x10 Reserved */
42*4882a593Smuzhiyun #define USB_AUTOREQ_REG 0x14
43*4882a593Smuzhiyun #define USB_SRP_FIX_TIME_REG 0x18
44*4882a593Smuzhiyun #define USB_TEARDOWN_REG 0x1c
45*4882a593Smuzhiyun #define EP_INTR_SRC_REG 0x20
46*4882a593Smuzhiyun #define EP_INTR_SRC_SET_REG 0x24
47*4882a593Smuzhiyun #define EP_INTR_SRC_CLEAR_REG 0x28
48*4882a593Smuzhiyun #define EP_INTR_MASK_REG 0x2c
49*4882a593Smuzhiyun #define EP_INTR_MASK_SET_REG 0x30
50*4882a593Smuzhiyun #define EP_INTR_MASK_CLEAR_REG 0x34
51*4882a593Smuzhiyun #define EP_INTR_SRC_MASKED_REG 0x38
52*4882a593Smuzhiyun #define CORE_INTR_SRC_REG 0x40
53*4882a593Smuzhiyun #define CORE_INTR_SRC_SET_REG 0x44
54*4882a593Smuzhiyun #define CORE_INTR_SRC_CLEAR_REG 0x48
55*4882a593Smuzhiyun #define CORE_INTR_MASK_REG 0x4c
56*4882a593Smuzhiyun #define CORE_INTR_MASK_SET_REG 0x50
57*4882a593Smuzhiyun #define CORE_INTR_MASK_CLEAR_REG 0x54
58*4882a593Smuzhiyun #define CORE_INTR_SRC_MASKED_REG 0x58
59*4882a593Smuzhiyun /* 0x5c Reserved */
60*4882a593Smuzhiyun #define USB_END_OF_INTR_REG 0x60
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* Control register bits */
63*4882a593Smuzhiyun #define AM35X_SOFT_RESET_MASK 1
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /* USB interrupt register bits */
66*4882a593Smuzhiyun #define AM35X_INTR_USB_SHIFT 16
67*4882a593Smuzhiyun #define AM35X_INTR_USB_MASK (0x1ff << AM35X_INTR_USB_SHIFT)
68*4882a593Smuzhiyun #define AM35X_INTR_DRVVBUS 0x100
69*4882a593Smuzhiyun #define AM35X_INTR_RX_SHIFT 16
70*4882a593Smuzhiyun #define AM35X_INTR_TX_SHIFT 0
71*4882a593Smuzhiyun #define AM35X_TX_EP_MASK 0xffff /* EP0 + 15 Tx EPs */
72*4882a593Smuzhiyun #define AM35X_RX_EP_MASK 0xfffe /* 15 Rx EPs */
73*4882a593Smuzhiyun #define AM35X_TX_INTR_MASK (AM35X_TX_EP_MASK << AM35X_INTR_TX_SHIFT)
74*4882a593Smuzhiyun #define AM35X_RX_INTR_MASK (AM35X_RX_EP_MASK << AM35X_INTR_RX_SHIFT)
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun #define USB_MENTOR_CORE_OFFSET 0x400
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun struct am35x_glue {
79*4882a593Smuzhiyun struct device *dev;
80*4882a593Smuzhiyun struct platform_device *musb;
81*4882a593Smuzhiyun struct clk *phy_clk;
82*4882a593Smuzhiyun struct clk *clk;
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun #define glue_to_musb(g) platform_get_drvdata(g->musb)
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /*
87*4882a593Smuzhiyun * am35x_musb_enable - enable interrupts
88*4882a593Smuzhiyun */
89*4882a593Smuzhiyun #ifndef __UBOOT__
am35x_musb_enable(struct musb * musb)90*4882a593Smuzhiyun static void am35x_musb_enable(struct musb *musb)
91*4882a593Smuzhiyun #else
92*4882a593Smuzhiyun static int am35x_musb_enable(struct musb *musb)
93*4882a593Smuzhiyun #endif
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun void __iomem *reg_base = musb->ctrl_base;
96*4882a593Smuzhiyun u32 epmask;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* Workaround: setup IRQs through both register sets. */
99*4882a593Smuzhiyun epmask = ((musb->epmask & AM35X_TX_EP_MASK) << AM35X_INTR_TX_SHIFT) |
100*4882a593Smuzhiyun ((musb->epmask & AM35X_RX_EP_MASK) << AM35X_INTR_RX_SHIFT);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun musb_writel(reg_base, EP_INTR_MASK_SET_REG, epmask);
103*4882a593Smuzhiyun musb_writel(reg_base, CORE_INTR_MASK_SET_REG, AM35X_INTR_USB_MASK);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /* Force the DRVVBUS IRQ so we can start polling for ID change. */
106*4882a593Smuzhiyun if (is_otg_enabled(musb))
107*4882a593Smuzhiyun musb_writel(reg_base, CORE_INTR_SRC_SET_REG,
108*4882a593Smuzhiyun AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT);
109*4882a593Smuzhiyun #ifdef __UBOOT__
110*4882a593Smuzhiyun return 0;
111*4882a593Smuzhiyun #endif
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun /*
115*4882a593Smuzhiyun * am35x_musb_disable - disable HDRC and flush interrupts
116*4882a593Smuzhiyun */
am35x_musb_disable(struct musb * musb)117*4882a593Smuzhiyun static void am35x_musb_disable(struct musb *musb)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun void __iomem *reg_base = musb->ctrl_base;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK);
122*4882a593Smuzhiyun musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG,
123*4882a593Smuzhiyun AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK);
124*4882a593Smuzhiyun musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
125*4882a593Smuzhiyun musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun #ifndef __UBOOT__
129*4882a593Smuzhiyun #define portstate(stmt) stmt
130*4882a593Smuzhiyun
am35x_musb_set_vbus(struct musb * musb,int is_on)131*4882a593Smuzhiyun static void am35x_musb_set_vbus(struct musb *musb, int is_on)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun WARN_ON(is_on && is_peripheral_active(musb));
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun #define POLL_SECONDS 2
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun static struct timer_list otg_workaround;
139*4882a593Smuzhiyun
otg_timer(unsigned long _musb)140*4882a593Smuzhiyun static void otg_timer(unsigned long _musb)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun struct musb *musb = (void *)_musb;
143*4882a593Smuzhiyun void __iomem *mregs = musb->mregs;
144*4882a593Smuzhiyun u8 devctl;
145*4882a593Smuzhiyun unsigned long flags;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun /*
148*4882a593Smuzhiyun * We poll because AM35x's won't expose several OTG-critical
149*4882a593Smuzhiyun * status change events (from the transceiver) otherwise.
150*4882a593Smuzhiyun */
151*4882a593Smuzhiyun devctl = musb_readb(mregs, MUSB_DEVCTL);
152*4882a593Smuzhiyun dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
153*4882a593Smuzhiyun otg_state_string(musb->xceiv->state));
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun spin_lock_irqsave(&musb->lock, flags);
156*4882a593Smuzhiyun switch (musb->xceiv->state) {
157*4882a593Smuzhiyun case OTG_STATE_A_WAIT_BCON:
158*4882a593Smuzhiyun devctl &= ~MUSB_DEVCTL_SESSION;
159*4882a593Smuzhiyun musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
162*4882a593Smuzhiyun if (devctl & MUSB_DEVCTL_BDEVICE) {
163*4882a593Smuzhiyun musb->xceiv->state = OTG_STATE_B_IDLE;
164*4882a593Smuzhiyun MUSB_DEV_MODE(musb);
165*4882a593Smuzhiyun } else {
166*4882a593Smuzhiyun musb->xceiv->state = OTG_STATE_A_IDLE;
167*4882a593Smuzhiyun MUSB_HST_MODE(musb);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun break;
170*4882a593Smuzhiyun case OTG_STATE_A_WAIT_VFALL:
171*4882a593Smuzhiyun musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
172*4882a593Smuzhiyun musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG,
173*4882a593Smuzhiyun MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT);
174*4882a593Smuzhiyun break;
175*4882a593Smuzhiyun case OTG_STATE_B_IDLE:
176*4882a593Smuzhiyun if (!is_peripheral_enabled(musb))
177*4882a593Smuzhiyun break;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun devctl = musb_readb(mregs, MUSB_DEVCTL);
180*4882a593Smuzhiyun if (devctl & MUSB_DEVCTL_BDEVICE)
181*4882a593Smuzhiyun mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
182*4882a593Smuzhiyun else
183*4882a593Smuzhiyun musb->xceiv->state = OTG_STATE_A_IDLE;
184*4882a593Smuzhiyun break;
185*4882a593Smuzhiyun default:
186*4882a593Smuzhiyun break;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun spin_unlock_irqrestore(&musb->lock, flags);
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
am35x_musb_try_idle(struct musb * musb,unsigned long timeout)191*4882a593Smuzhiyun static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun static unsigned long last_timer;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun if (!is_otg_enabled(musb))
196*4882a593Smuzhiyun return;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun if (timeout == 0)
199*4882a593Smuzhiyun timeout = jiffies + msecs_to_jiffies(3);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /* Never idle if active, or when VBUS timeout is not set as host */
202*4882a593Smuzhiyun if (musb->is_active || (musb->a_wait_bcon == 0 &&
203*4882a593Smuzhiyun musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
204*4882a593Smuzhiyun dev_dbg(musb->controller, "%s active, deleting timer\n",
205*4882a593Smuzhiyun otg_state_string(musb->xceiv->state));
206*4882a593Smuzhiyun del_timer(&otg_workaround);
207*4882a593Smuzhiyun last_timer = jiffies;
208*4882a593Smuzhiyun return;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) {
212*4882a593Smuzhiyun dev_dbg(musb->controller, "Longer idle timer already pending, ignoring...\n");
213*4882a593Smuzhiyun return;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun last_timer = timeout;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
218*4882a593Smuzhiyun otg_state_string(musb->xceiv->state),
219*4882a593Smuzhiyun jiffies_to_msecs(timeout - jiffies));
220*4882a593Smuzhiyun mod_timer(&otg_workaround, timeout);
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun #endif
223*4882a593Smuzhiyun
am35x_musb_interrupt(int irq,void * hci)224*4882a593Smuzhiyun static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun struct musb *musb = hci;
227*4882a593Smuzhiyun void __iomem *reg_base = musb->ctrl_base;
228*4882a593Smuzhiyun #ifndef __UBOOT__
229*4882a593Smuzhiyun struct device *dev = musb->controller;
230*4882a593Smuzhiyun struct musb_hdrc_platform_data *plat = dev->platform_data;
231*4882a593Smuzhiyun struct omap_musb_board_data *data = plat->board_data;
232*4882a593Smuzhiyun struct usb_otg *otg = musb->xceiv->otg;
233*4882a593Smuzhiyun #else
234*4882a593Smuzhiyun struct omap_musb_board_data *data =
235*4882a593Smuzhiyun (struct omap_musb_board_data *)musb->controller;
236*4882a593Smuzhiyun #endif
237*4882a593Smuzhiyun unsigned long flags;
238*4882a593Smuzhiyun irqreturn_t ret = IRQ_NONE;
239*4882a593Smuzhiyun u32 epintr, usbintr;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun #ifdef __UBOOT__
242*4882a593Smuzhiyun /*
243*4882a593Smuzhiyun * It seems that on AM35X interrupt registers can be updated
244*4882a593Smuzhiyun * before core registers. This confuses the code.
245*4882a593Smuzhiyun * As a workaround add a small delay here.
246*4882a593Smuzhiyun */
247*4882a593Smuzhiyun udelay(10);
248*4882a593Smuzhiyun #endif
249*4882a593Smuzhiyun spin_lock_irqsave(&musb->lock, flags);
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun /* Get endpoint interrupts */
252*4882a593Smuzhiyun epintr = musb_readl(reg_base, EP_INTR_SRC_MASKED_REG);
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if (epintr) {
255*4882a593Smuzhiyun musb_writel(reg_base, EP_INTR_SRC_CLEAR_REG, epintr);
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun musb->int_rx =
258*4882a593Smuzhiyun (epintr & AM35X_RX_INTR_MASK) >> AM35X_INTR_RX_SHIFT;
259*4882a593Smuzhiyun musb->int_tx =
260*4882a593Smuzhiyun (epintr & AM35X_TX_INTR_MASK) >> AM35X_INTR_TX_SHIFT;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun /* Get usb core interrupts */
264*4882a593Smuzhiyun usbintr = musb_readl(reg_base, CORE_INTR_SRC_MASKED_REG);
265*4882a593Smuzhiyun if (!usbintr && !epintr)
266*4882a593Smuzhiyun goto eoi;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun if (usbintr) {
269*4882a593Smuzhiyun musb_writel(reg_base, CORE_INTR_SRC_CLEAR_REG, usbintr);
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun musb->int_usb =
272*4882a593Smuzhiyun (usbintr & AM35X_INTR_USB_MASK) >> AM35X_INTR_USB_SHIFT;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun #ifndef __UBOOT__
275*4882a593Smuzhiyun /*
276*4882a593Smuzhiyun * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
277*4882a593Smuzhiyun * AM35x's missing ID change IRQ. We need an ID change IRQ to
278*4882a593Smuzhiyun * switch appropriately between halves of the OTG state machine.
279*4882a593Smuzhiyun * Managing DEVCTL.SESSION per Mentor docs requires that we know its
280*4882a593Smuzhiyun * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
281*4882a593Smuzhiyun * Also, DRVVBUS pulses for SRP (but not at 5V) ...
282*4882a593Smuzhiyun */
283*4882a593Smuzhiyun if (usbintr & (AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT)) {
284*4882a593Smuzhiyun int drvvbus = musb_readl(reg_base, USB_STAT_REG);
285*4882a593Smuzhiyun void __iomem *mregs = musb->mregs;
286*4882a593Smuzhiyun u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
287*4882a593Smuzhiyun int err;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun err = is_host_enabled(musb) && (musb->int_usb &
290*4882a593Smuzhiyun MUSB_INTR_VBUSERROR);
291*4882a593Smuzhiyun if (err) {
292*4882a593Smuzhiyun /*
293*4882a593Smuzhiyun * The Mentor core doesn't debounce VBUS as needed
294*4882a593Smuzhiyun * to cope with device connect current spikes. This
295*4882a593Smuzhiyun * means it's not uncommon for bus-powered devices
296*4882a593Smuzhiyun * to get VBUS errors during enumeration.
297*4882a593Smuzhiyun *
298*4882a593Smuzhiyun * This is a workaround, but newer RTL from Mentor
299*4882a593Smuzhiyun * seems to allow a better one: "re"-starting sessions
300*4882a593Smuzhiyun * without waiting for VBUS to stop registering in
301*4882a593Smuzhiyun * devctl.
302*4882a593Smuzhiyun */
303*4882a593Smuzhiyun musb->int_usb &= ~MUSB_INTR_VBUSERROR;
304*4882a593Smuzhiyun musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
305*4882a593Smuzhiyun mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
306*4882a593Smuzhiyun WARNING("VBUS error workaround (delay coming)\n");
307*4882a593Smuzhiyun } else if (is_host_enabled(musb) && drvvbus) {
308*4882a593Smuzhiyun MUSB_HST_MODE(musb);
309*4882a593Smuzhiyun otg->default_a = 1;
310*4882a593Smuzhiyun musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
311*4882a593Smuzhiyun portstate(musb->port1_status |= USB_PORT_STAT_POWER);
312*4882a593Smuzhiyun del_timer(&otg_workaround);
313*4882a593Smuzhiyun } else {
314*4882a593Smuzhiyun musb->is_active = 0;
315*4882a593Smuzhiyun MUSB_DEV_MODE(musb);
316*4882a593Smuzhiyun otg->default_a = 0;
317*4882a593Smuzhiyun musb->xceiv->state = OTG_STATE_B_IDLE;
318*4882a593Smuzhiyun portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun /* NOTE: this must complete power-on within 100 ms. */
322*4882a593Smuzhiyun dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
323*4882a593Smuzhiyun drvvbus ? "on" : "off",
324*4882a593Smuzhiyun otg_state_string(musb->xceiv->state),
325*4882a593Smuzhiyun err ? " ERROR" : "",
326*4882a593Smuzhiyun devctl);
327*4882a593Smuzhiyun ret = IRQ_HANDLED;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun #endif
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun if (musb->int_tx || musb->int_rx || musb->int_usb)
332*4882a593Smuzhiyun ret |= musb_interrupt(musb);
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun eoi:
335*4882a593Smuzhiyun /* EOI needs to be written for the IRQ to be re-asserted. */
336*4882a593Smuzhiyun if (ret == IRQ_HANDLED || epintr || usbintr) {
337*4882a593Smuzhiyun /* clear level interrupt */
338*4882a593Smuzhiyun if (data->clear_irq)
339*4882a593Smuzhiyun data->clear_irq(data->dev);
340*4882a593Smuzhiyun /* write EOI */
341*4882a593Smuzhiyun musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun #ifndef __UBOOT__
345*4882a593Smuzhiyun /* Poll for ID change */
346*4882a593Smuzhiyun if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
347*4882a593Smuzhiyun mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
348*4882a593Smuzhiyun #endif
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun spin_unlock_irqrestore(&musb->lock, flags);
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun return ret;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun #ifndef __UBOOT__
am35x_musb_set_mode(struct musb * musb,u8 musb_mode)356*4882a593Smuzhiyun static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun struct device *dev = musb->controller;
359*4882a593Smuzhiyun struct musb_hdrc_platform_data *plat = dev->platform_data;
360*4882a593Smuzhiyun struct omap_musb_board_data *data = plat->board_data;
361*4882a593Smuzhiyun int retval = 0;
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun if (data->set_mode)
364*4882a593Smuzhiyun data->set_mode(musb_mode);
365*4882a593Smuzhiyun else
366*4882a593Smuzhiyun retval = -EIO;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun return retval;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun #endif
371*4882a593Smuzhiyun
am35x_musb_init(struct musb * musb)372*4882a593Smuzhiyun static int am35x_musb_init(struct musb *musb)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun #ifndef __UBOOT__
375*4882a593Smuzhiyun struct device *dev = musb->controller;
376*4882a593Smuzhiyun struct musb_hdrc_platform_data *plat = dev->platform_data;
377*4882a593Smuzhiyun struct omap_musb_board_data *data = plat->board_data;
378*4882a593Smuzhiyun #else
379*4882a593Smuzhiyun struct omap_musb_board_data *data =
380*4882a593Smuzhiyun (struct omap_musb_board_data *)musb->controller;
381*4882a593Smuzhiyun #endif
382*4882a593Smuzhiyun void __iomem *reg_base = musb->ctrl_base;
383*4882a593Smuzhiyun u32 rev;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun musb->mregs += USB_MENTOR_CORE_OFFSET;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /* Returns zero if e.g. not clocked */
388*4882a593Smuzhiyun rev = musb_readl(reg_base, USB_REVISION_REG);
389*4882a593Smuzhiyun if (!rev)
390*4882a593Smuzhiyun return -ENODEV;
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun #ifndef __UBOOT__
393*4882a593Smuzhiyun usb_nop_xceiv_register();
394*4882a593Smuzhiyun musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
395*4882a593Smuzhiyun if (IS_ERR_OR_NULL(musb->xceiv))
396*4882a593Smuzhiyun return -ENODEV;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun if (is_host_enabled(musb))
399*4882a593Smuzhiyun setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
400*4882a593Smuzhiyun #endif
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun /* Reset the musb */
403*4882a593Smuzhiyun if (data->reset)
404*4882a593Smuzhiyun data->reset(data->dev);
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /* Reset the controller */
407*4882a593Smuzhiyun musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK);
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun /* Start the on-chip PHY and its PLL. */
410*4882a593Smuzhiyun if (data->set_phy_power)
411*4882a593Smuzhiyun data->set_phy_power(data->dev, 1);
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun msleep(5);
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun musb->isr = am35x_musb_interrupt;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun /* clear level interrupt */
418*4882a593Smuzhiyun if (data->clear_irq)
419*4882a593Smuzhiyun data->clear_irq(data->dev);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun return 0;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
am35x_musb_exit(struct musb * musb)424*4882a593Smuzhiyun static int am35x_musb_exit(struct musb *musb)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun #ifndef __UBOOT__
427*4882a593Smuzhiyun struct device *dev = musb->controller;
428*4882a593Smuzhiyun struct musb_hdrc_platform_data *plat = dev->platform_data;
429*4882a593Smuzhiyun struct omap_musb_board_data *data = plat->board_data;
430*4882a593Smuzhiyun #else
431*4882a593Smuzhiyun struct omap_musb_board_data *data =
432*4882a593Smuzhiyun (struct omap_musb_board_data *)musb->controller;
433*4882a593Smuzhiyun #endif
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun #ifndef __UBOOT__
436*4882a593Smuzhiyun if (is_host_enabled(musb))
437*4882a593Smuzhiyun del_timer_sync(&otg_workaround);
438*4882a593Smuzhiyun #endif
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun /* Shutdown the on-chip PHY and its PLL. */
441*4882a593Smuzhiyun if (data->set_phy_power)
442*4882a593Smuzhiyun data->set_phy_power(data->dev, 0);
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun #ifndef __UBOOT__
445*4882a593Smuzhiyun usb_put_phy(musb->xceiv);
446*4882a593Smuzhiyun usb_nop_xceiv_unregister();
447*4882a593Smuzhiyun #endif
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun return 0;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun /* AM35x supports only 32bit read operation */
musb_read_fifo(struct musb_hw_ep * hw_ep,u16 len,u8 * dst)453*4882a593Smuzhiyun void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun void __iomem *fifo = hw_ep->fifo;
456*4882a593Smuzhiyun u32 val;
457*4882a593Smuzhiyun int i;
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun /* Read for 32bit-aligned destination address */
460*4882a593Smuzhiyun if (likely((0x03 & (unsigned long) dst) == 0) && len >= 4) {
461*4882a593Smuzhiyun readsl(fifo, dst, len >> 2);
462*4882a593Smuzhiyun dst += len & ~0x03;
463*4882a593Smuzhiyun len &= 0x03;
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun /*
466*4882a593Smuzhiyun * Now read the remaining 1 to 3 byte or complete length if
467*4882a593Smuzhiyun * unaligned address.
468*4882a593Smuzhiyun */
469*4882a593Smuzhiyun if (len > 4) {
470*4882a593Smuzhiyun for (i = 0; i < (len >> 2); i++) {
471*4882a593Smuzhiyun *(u32 *) dst = musb_readl(fifo, 0);
472*4882a593Smuzhiyun dst += 4;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun len &= 0x03;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun if (len > 0) {
477*4882a593Smuzhiyun val = musb_readl(fifo, 0);
478*4882a593Smuzhiyun memcpy(dst, &val, len);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun #ifndef __UBOOT__
483*4882a593Smuzhiyun static const struct musb_platform_ops am35x_ops = {
484*4882a593Smuzhiyun #else
485*4882a593Smuzhiyun const struct musb_platform_ops am35x_ops = {
486*4882a593Smuzhiyun #endif
487*4882a593Smuzhiyun .init = am35x_musb_init,
488*4882a593Smuzhiyun .exit = am35x_musb_exit,
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun .enable = am35x_musb_enable,
491*4882a593Smuzhiyun .disable = am35x_musb_disable,
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun #ifndef __UBOOT__
494*4882a593Smuzhiyun .set_mode = am35x_musb_set_mode,
495*4882a593Smuzhiyun .try_idle = am35x_musb_try_idle,
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun .set_vbus = am35x_musb_set_vbus,
498*4882a593Smuzhiyun #endif
499*4882a593Smuzhiyun };
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun #ifndef __UBOOT__
502*4882a593Smuzhiyun static u64 am35x_dmamask = DMA_BIT_MASK(32);
503*4882a593Smuzhiyun
am35x_probe(struct platform_device * pdev)504*4882a593Smuzhiyun static int __devinit am35x_probe(struct platform_device *pdev)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
507*4882a593Smuzhiyun struct platform_device *musb;
508*4882a593Smuzhiyun struct am35x_glue *glue;
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun struct clk *phy_clk;
511*4882a593Smuzhiyun struct clk *clk;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun int ret = -ENOMEM;
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun glue = kzalloc(sizeof(*glue), GFP_KERNEL);
516*4882a593Smuzhiyun if (!glue) {
517*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to allocate glue context\n");
518*4882a593Smuzhiyun goto err0;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun musb = platform_device_alloc("musb-hdrc", -1);
522*4882a593Smuzhiyun if (!musb) {
523*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to allocate musb device\n");
524*4882a593Smuzhiyun goto err1;
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun phy_clk = clk_get(&pdev->dev, "fck");
528*4882a593Smuzhiyun if (IS_ERR(phy_clk)) {
529*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get PHY clock\n");
530*4882a593Smuzhiyun ret = PTR_ERR(phy_clk);
531*4882a593Smuzhiyun goto err2;
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun clk = clk_get(&pdev->dev, "ick");
535*4882a593Smuzhiyun if (IS_ERR(clk)) {
536*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get clock\n");
537*4882a593Smuzhiyun ret = PTR_ERR(clk);
538*4882a593Smuzhiyun goto err3;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun ret = clk_enable(phy_clk);
542*4882a593Smuzhiyun if (ret) {
543*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to enable PHY clock\n");
544*4882a593Smuzhiyun goto err4;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun ret = clk_enable(clk);
548*4882a593Smuzhiyun if (ret) {
549*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to enable clock\n");
550*4882a593Smuzhiyun goto err5;
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun musb->dev.parent = &pdev->dev;
554*4882a593Smuzhiyun musb->dev.dma_mask = &am35x_dmamask;
555*4882a593Smuzhiyun musb->dev.coherent_dma_mask = am35x_dmamask;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun glue->dev = &pdev->dev;
558*4882a593Smuzhiyun glue->musb = musb;
559*4882a593Smuzhiyun glue->phy_clk = phy_clk;
560*4882a593Smuzhiyun glue->clk = clk;
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun pdata->platform_ops = &am35x_ops;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun platform_set_drvdata(pdev, glue);
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun ret = platform_device_add_resources(musb, pdev->resource,
567*4882a593Smuzhiyun pdev->num_resources);
568*4882a593Smuzhiyun if (ret) {
569*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to add resources\n");
570*4882a593Smuzhiyun goto err6;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
574*4882a593Smuzhiyun if (ret) {
575*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to add platform_data\n");
576*4882a593Smuzhiyun goto err6;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun ret = platform_device_add(musb);
580*4882a593Smuzhiyun if (ret) {
581*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to register musb device\n");
582*4882a593Smuzhiyun goto err6;
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun return 0;
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun err6:
588*4882a593Smuzhiyun clk_disable(clk);
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun err5:
591*4882a593Smuzhiyun clk_disable(phy_clk);
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun err4:
594*4882a593Smuzhiyun clk_put(clk);
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun err3:
597*4882a593Smuzhiyun clk_put(phy_clk);
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun err2:
600*4882a593Smuzhiyun platform_device_put(musb);
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun err1:
603*4882a593Smuzhiyun kfree(glue);
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun err0:
606*4882a593Smuzhiyun return ret;
607*4882a593Smuzhiyun }
608*4882a593Smuzhiyun
am35x_remove(struct platform_device * pdev)609*4882a593Smuzhiyun static int __devexit am35x_remove(struct platform_device *pdev)
610*4882a593Smuzhiyun {
611*4882a593Smuzhiyun struct am35x_glue *glue = platform_get_drvdata(pdev);
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun platform_device_del(glue->musb);
614*4882a593Smuzhiyun platform_device_put(glue->musb);
615*4882a593Smuzhiyun clk_disable(glue->clk);
616*4882a593Smuzhiyun clk_disable(glue->phy_clk);
617*4882a593Smuzhiyun clk_put(glue->clk);
618*4882a593Smuzhiyun clk_put(glue->phy_clk);
619*4882a593Smuzhiyun kfree(glue);
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun return 0;
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun #ifdef CONFIG_PM
am35x_suspend(struct device * dev)625*4882a593Smuzhiyun static int am35x_suspend(struct device *dev)
626*4882a593Smuzhiyun {
627*4882a593Smuzhiyun struct am35x_glue *glue = dev_get_drvdata(dev);
628*4882a593Smuzhiyun struct musb_hdrc_platform_data *plat = dev->platform_data;
629*4882a593Smuzhiyun struct omap_musb_board_data *data = plat->board_data;
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun /* Shutdown the on-chip PHY and its PLL. */
632*4882a593Smuzhiyun if (data->set_phy_power)
633*4882a593Smuzhiyun data->set_phy_power(data->dev, 0);
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun clk_disable(glue->phy_clk);
636*4882a593Smuzhiyun clk_disable(glue->clk);
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun return 0;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun
am35x_resume(struct device * dev)641*4882a593Smuzhiyun static int am35x_resume(struct device *dev)
642*4882a593Smuzhiyun {
643*4882a593Smuzhiyun struct am35x_glue *glue = dev_get_drvdata(dev);
644*4882a593Smuzhiyun struct musb_hdrc_platform_data *plat = dev->platform_data;
645*4882a593Smuzhiyun struct omap_musb_board_data *data = plat->board_data;
646*4882a593Smuzhiyun int ret;
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun /* Start the on-chip PHY and its PLL. */
649*4882a593Smuzhiyun if (data->set_phy_power)
650*4882a593Smuzhiyun data->set_phy_power(data->dev, 1);
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun ret = clk_enable(glue->phy_clk);
653*4882a593Smuzhiyun if (ret) {
654*4882a593Smuzhiyun dev_err(dev, "failed to enable PHY clock\n");
655*4882a593Smuzhiyun return ret;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun
658*4882a593Smuzhiyun ret = clk_enable(glue->clk);
659*4882a593Smuzhiyun if (ret) {
660*4882a593Smuzhiyun dev_err(dev, "failed to enable clock\n");
661*4882a593Smuzhiyun return ret;
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun return 0;
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun static struct dev_pm_ops am35x_pm_ops = {
668*4882a593Smuzhiyun .suspend = am35x_suspend,
669*4882a593Smuzhiyun .resume = am35x_resume,
670*4882a593Smuzhiyun };
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun #define DEV_PM_OPS &am35x_pm_ops
673*4882a593Smuzhiyun #else
674*4882a593Smuzhiyun #define DEV_PM_OPS NULL
675*4882a593Smuzhiyun #endif
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun static struct platform_driver am35x_driver = {
678*4882a593Smuzhiyun .probe = am35x_probe,
679*4882a593Smuzhiyun .remove = __devexit_p(am35x_remove),
680*4882a593Smuzhiyun .driver = {
681*4882a593Smuzhiyun .name = "musb-am35x",
682*4882a593Smuzhiyun .pm = DEV_PM_OPS,
683*4882a593Smuzhiyun },
684*4882a593Smuzhiyun };
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun MODULE_DESCRIPTION("AM35x MUSB Glue Layer");
687*4882a593Smuzhiyun MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
688*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
689*4882a593Smuzhiyun
am35x_init(void)690*4882a593Smuzhiyun static int __init am35x_init(void)
691*4882a593Smuzhiyun {
692*4882a593Smuzhiyun return platform_driver_register(&am35x_driver);
693*4882a593Smuzhiyun }
694*4882a593Smuzhiyun module_init(am35x_init);
695*4882a593Smuzhiyun
am35x_exit(void)696*4882a593Smuzhiyun static void __exit am35x_exit(void)
697*4882a593Smuzhiyun {
698*4882a593Smuzhiyun platform_driver_unregister(&am35x_driver);
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun module_exit(am35x_exit);
701*4882a593Smuzhiyun #endif
702