1f6e51ed983ab71928ca5d5460adc1809d268461
[oweals/u-boot.git] / drivers / usb / musb-new / da8xx.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Texas Instruments da8xx "glue layer"
4  *
5  * Copyright (c) 2019, by Texas Instruments
6  *
7  * Based on the DA8xx "glue layer" code.
8  * Copyright (c) 2008-2019, MontaVista Software, Inc. <source@mvista.com>
9  *
10  * DT support
11  * Copyright (c) 2016 Petr Kulhavy <petr@barix.com>
12  * This file is part of the Inventra Controller Driver for Linux.
13  *
14  */
15
16 #include <common.h>
17 #include <dm.h>
18 #include <log.h>
19 #include <dm/device-internal.h>
20 #include <dm/device_compat.h>
21 #include <dm/lists.h>
22 #include <asm/arch/hardware.h>
23 #include <asm/arch/da8xx-usb.h>
24 #include <linux/usb/otg.h>
25 #include <asm/omap_musb.h>
26 #include <generic-phy.h>
27 #include "linux-compat.h"
28 #include "musb_core.h"
29 #include "musb_uboot.h"
30
31 /* USB 2.0 OTG module registers */
32 #define DA8XX_USB_REVISION_REG  0x00
33 #define DA8XX_USB_CTRL_REG      0x04
34 #define DA8XX_USB_STAT_REG      0x08
35 #define DA8XX_USB_EMULATION_REG 0x0c
36 #define DA8XX_USB_SRP_FIX_TIME_REG 0x18
37 #define DA8XX_USB_INTR_SRC_REG  0x20
38 #define DA8XX_USB_INTR_SRC_SET_REG 0x24
39 #define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28
40 #define DA8XX_USB_INTR_MASK_REG 0x2c
41 #define DA8XX_USB_INTR_MASK_SET_REG 0x30
42 #define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34
43 #define DA8XX_USB_INTR_SRC_MASKED_REG 0x38
44 #define DA8XX_USB_END_OF_INTR_REG 0x3c
45 #define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2))
46
47 /* Control register bits */
48 #define DA8XX_SOFT_RESET_MASK   1
49
50 #define DA8XX_USB_TX_EP_MASK    0x1f            /* EP0 + 4 Tx EPs */
51 #define DA8XX_USB_RX_EP_MASK    0x1e            /* 4 Rx EPs */
52
53 /* USB interrupt register bits */
54 #define DA8XX_INTR_USB_SHIFT    16
55 #define DA8XX_INTR_USB_MASK     (0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */
56                                         /* interrupts and DRVVBUS interrupt */
57 #define DA8XX_INTR_DRVVBUS      0x100
58 #define DA8XX_INTR_RX_SHIFT     8
59 #define DA8XX_INTR_RX_MASK      (DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT)
60 #define DA8XX_INTR_TX_SHIFT     0
61 #define DA8XX_INTR_TX_MASK      (DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT)
62
63 #define DA8XX_MENTOR_CORE_OFFSET 0x400
64
65 static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
66 {
67         struct musb             *musb = hci;
68         void __iomem            *reg_base = musb->ctrl_base;
69         unsigned long           flags;
70         irqreturn_t             ret = IRQ_NONE;
71         u32                     status;
72
73         spin_lock_irqsave(&musb->lock, flags);
74
75         /*
76          * NOTE: DA8XX shadows the Mentor IRQs.  Don't manage them through
77          * the Mentor registers (except for setup), use the TI ones and EOI.
78          */
79
80         /* Acknowledge and handle non-CPPI interrupts */
81         status = musb_readl(reg_base, DA8XX_USB_INTR_SRC_MASKED_REG);
82         if (!status)
83                 goto eoi;
84
85         musb_writel(reg_base, DA8XX_USB_INTR_SRC_CLEAR_REG, status);
86         dev_dbg(musb->controller, "USB IRQ %08x\n", status);
87
88         musb->int_rx = (status & DA8XX_INTR_RX_MASK) >> DA8XX_INTR_RX_SHIFT;
89         musb->int_tx = (status & DA8XX_INTR_TX_MASK) >> DA8XX_INTR_TX_SHIFT;
90         musb->int_usb = (status & DA8XX_INTR_USB_MASK) >> DA8XX_INTR_USB_SHIFT;
91
92         /*
93          * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
94          * DA8xx's missing ID change IRQ.  We need an ID change IRQ to
95          * switch appropriately between halves of the OTG state machine.
96          * Managing DEVCTL.Session per Mentor docs requires that we know its
97          * value but DEVCTL.BDevice is invalid without DEVCTL.Session set.
98          * Also, DRVVBUS pulses for SRP (but not at 5 V)...
99          */
100         if (status & (DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT)) {
101                 int drvvbus = musb_readl(reg_base, DA8XX_USB_STAT_REG);
102                 void __iomem *mregs = musb->mregs;
103                 u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
104                 int err;
105
106                 err = musb->int_usb & MUSB_INTR_VBUSERROR;
107                 if (err) {
108                         /*
109                          * The Mentor core doesn't debounce VBUS as needed
110                          * to cope with device connect current spikes. This
111                          * means it's not uncommon for bus-powered devices
112                          * to get VBUS errors during enumeration.
113                          *
114                          * This is a workaround, but newer RTL from Mentor
115                          * seems to allow a better one: "re"-starting sessions
116                          * without waiting for VBUS to stop registering in
117                          * devctl.
118                          */
119                         musb->int_usb &= ~MUSB_INTR_VBUSERROR;
120                         WARNING("VBUS error workaround (delay coming)\n");
121                 } else if (drvvbus) {
122                         MUSB_HST_MODE(musb);
123                         musb->port1_status |= USB_PORT_STAT_POWER;
124                 } else if (!(musb->int_usb & MUSB_INTR_BABBLE)) {
125                         /*
126                          * When babble condition happens, drvvbus interrupt
127                          * is also generated. Ignore this drvvbus interrupt
128                          * and let babble interrupt handler recovers the
129                          * controller; otherwise, the host-mode flag is lost
130                          * due to the MUSB_DEV_MODE() call below and babble
131                          * recovery logic will not be called.
132                          */
133                         musb->is_active = 0;
134                         MUSB_DEV_MODE(musb);
135                         musb->port1_status &= ~USB_PORT_STAT_POWER;
136                 }
137                 ret = IRQ_HANDLED;
138         }
139
140         if (musb->int_tx || musb->int_rx || musb->int_usb)
141                 ret |= musb_interrupt(musb);
142 eoi:
143         /* EOI needs to be written for the IRQ to be re-asserted. */
144         if (ret == IRQ_HANDLED || status)
145                 musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
146
147         spin_unlock_irqrestore(&musb->lock, flags);
148
149         return ret;
150 }
151
152 static int da8xx_musb_init(struct musb *musb)
153 {
154         u32  revision;
155         void __iomem *reg_base = musb->ctrl_base;
156
157         int ret;
158
159         /* reset the controller */
160         writel(0x1, &da8xx_usb_regs->control);
161         udelay(50);
162
163         /* Returns zero if e.g. not clocked */
164         revision = readl(&da8xx_usb_regs->revision);
165         if (revision == 0)
166                 return -ENODEV;
167
168         /* Disable all interrupts */
169         writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK |
170                 DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_set);
171
172         musb->mregs += DA8XX_MENTOR_CORE_OFFSET;
173
174         /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */
175         debug("DA8xx OTG revision %08x, control %02x\n", revision,
176               musb_readb(reg_base, DA8XX_USB_CTRL_REG));
177
178         musb->isr = da8xx_musb_interrupt;
179         return 0;
180 }
181
182 static int da8xx_musb_exit(struct musb *musb)
183 {
184         /* flush any interrupts */
185         writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK |
186                 DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_clr);
187         writel(0, &da8xx_usb_regs->eoi);
188
189         return 0;
190 }
191
192 /**
193  * da8xx_musb_enable - enable interrupts
194  */
195 static int da8xx_musb_enable(struct musb *musb)
196 {
197         void __iomem *reg_base = musb->ctrl_base;
198         u32 mask;
199
200         /* Workaround: setup IRQs through both register sets. */
201         mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) |
202                ((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) |
203                DA8XX_INTR_USB_MASK;
204         musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask);
205
206         /* Force the DRVVBUS IRQ so we can start polling for ID change. */
207         musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG,
208                     DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT);
209
210         return 0;
211 }
212
213 /**
214  * da8xx_musb_disable - disable HDRC and flush interrupts
215  */
216 static void da8xx_musb_disable(struct musb *musb)
217 {
218         void __iomem *reg_base = musb->ctrl_base;
219
220         musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG,
221                     DA8XX_INTR_USB_MASK |
222                     DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK);
223         musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
224 }
225
226 void da8xx_musb_reset(struct udevice *dev)
227 {
228         void *reg_base = dev_read_addr_ptr(dev);
229
230         /* Reset the controller */
231         musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK);
232 }
233
234 void da8xx_musb_clear_irq(struct udevice *dev)
235 {
236         /* flush any interrupts */
237         writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK |
238                 DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_clr);
239         writel(0, &da8xx_usb_regs->eoi);
240 }
241
242 const struct musb_platform_ops da8xx_ops = {
243         .init           = da8xx_musb_init,
244         .exit           = da8xx_musb_exit,
245         .enable         = da8xx_musb_enable,
246         .disable        = da8xx_musb_disable,
247 };
248
249 struct da8xx_musb_platdata {
250         void *base;
251         void *ctrl_mod_base;
252         struct musb_hdrc_platform_data plat;
253         struct musb_hdrc_config musb_config;
254         struct omap_musb_board_data otg_board_data;
255         struct phy phy;
256 };
257
258 static int da8xx_musb_ofdata_to_platdata(struct udevice *dev)
259 {
260         struct da8xx_musb_platdata *platdata = dev_get_platdata(dev);
261         const void *fdt = gd->fdt_blob;
262         int node = dev_of_offset(dev);
263
264         platdata->base = (void *)dev_read_addr_ptr(dev);
265         platdata->musb_config.multipoint = 1;
266         platdata->musb_config.dyn_fifo = 1;
267         platdata->musb_config.num_eps = 5;
268         platdata->musb_config.ram_bits = 10;
269         platdata->plat.power = fdtdec_get_int(fdt, node, "power", 50);
270         platdata->otg_board_data.interface_type = MUSB_INTERFACE_UTMI;
271         platdata->plat.mode = MUSB_HOST;
272         platdata->otg_board_data.dev = dev;
273         platdata->plat.config = &platdata->musb_config;
274         platdata->plat.platform_ops = &da8xx_ops;
275         platdata->plat.board_data = &platdata->otg_board_data;
276         platdata->otg_board_data.clear_irq = da8xx_musb_clear_irq;
277         platdata->otg_board_data.reset = da8xx_musb_reset;
278         return 0;
279 }
280
281 static int da8xx_musb_probe(struct udevice *dev)
282 {
283         struct musb_host_data *host = dev_get_priv(dev);
284         struct da8xx_musb_platdata *platdata = dev_get_platdata(dev);
285         struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
286         struct omap_musb_board_data *otg_board_data;
287         int ret;
288         void *base = dev_read_addr_ptr(dev);
289
290         /* Get the phy info from the device tree */
291         ret = generic_phy_get_by_name(dev, "usb-phy", &platdata->phy);
292         if (ret)
293                 return ret;
294
295         /* Initialize the phy */
296         ret = generic_phy_init(&platdata->phy);
297         if (ret)
298                 return ret;
299
300         /* enable psc for usb2.0 */
301         lpsc_on(33);
302
303         /* Enable phy */
304         generic_phy_power_on(&platdata->phy);
305
306         priv->desc_before_addr = true;
307         otg_board_data = &platdata->otg_board_data;
308
309         host->host = musb_init_controller(&platdata->plat,
310                                           (struct device *)otg_board_data,
311                                           platdata->base);
312         if (!host->host) {
313                 ret = -ENODEV;
314                 goto shutdown; /* Shutdown what we started */
315         }
316
317         ret = musb_lowlevel_init(host);
318
319         if (ret == 0)
320                 return 0;
321 shutdown:
322         /* Turn off the phy if we fail */
323         generic_phy_power_off(&platdata->phy);
324         lpsc_disable(33);
325         return ret;
326 }
327
328 static int da8xx_musb_remove(struct udevice *dev)
329 {
330         struct musb_host_data *host = dev_get_priv(dev);
331
332         musb_stop(host->host);
333
334         return 0;
335 }
336
337 static const struct udevice_id da8xx_musb_ids[] = {
338         { .compatible = "ti,da830-musb" },
339         { }
340 };
341
342 U_BOOT_DRIVER(da8xx_musb) = {
343         .name   = "da8xx-musb",
344         .id             = UCLASS_USB,
345         .of_match = da8xx_musb_ids,
346         .ofdata_to_platdata = da8xx_musb_ofdata_to_platdata,
347         .probe = da8xx_musb_probe,
348         .remove = da8xx_musb_remove,
349         .ops = &musb_usb_ops,
350         .platdata_auto_alloc_size = sizeof(struct da8xx_musb_platdata),
351         .priv_auto_alloc_size = sizeof(struct musb_host_data),
352 };