blob: 9651f074a49d4c277cbdecab9496c3a6d33f160a [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Thomas Abrahama1428962009-01-04 09:41:03 +05302/*
3 * Mentor USB OTG Core functionality common for both Host and Device
4 * functionality.
5 *
6 * Copyright (c) 2008 Texas Instruments
7 *
Thomas Abrahama1428962009-01-04 09:41:03 +05308 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
9 */
10
11#include <common.h>
Simon Glasscd93d622020-05-10 11:40:13 -060012#include <linux/bitops.h>
Thomas Abrahama1428962009-01-04 09:41:03 +053013
14#include "musb_core.h"
15struct musb_regs *musbr;
16
17/*
18 * program the mentor core to start (enable interrupts, dma, etc.)
19 */
20void musb_start(void)
21{
Paul Kocialkowski95de1e22015-08-04 17:04:06 +020022#if defined(CONFIG_USB_MUSB_HCD)
Thomas Abrahama1428962009-01-04 09:41:03 +053023 u8 devctl;
Ajay Kumar Gupta9bb47ab2010-06-10 11:20:48 +053024 u8 busctl;
Tom Rixf298e4b2009-10-31 12:37:41 -050025#endif
Thomas Abrahama1428962009-01-04 09:41:03 +053026
27 /* disable all interrupts */
28 writew(0, &musbr->intrtxe);
29 writew(0, &musbr->intrrxe);
30 writeb(0, &musbr->intrusbe);
31 writeb(0, &musbr->testmode);
32
33 /* put into basic highspeed mode and start session */
34 writeb(MUSB_POWER_HSENAB, &musbr->power);
Paul Kocialkowski95de1e22015-08-04 17:04:06 +020035#if defined(CONFIG_USB_MUSB_HCD)
Ajay Kumar Gupta9bb47ab2010-06-10 11:20:48 +053036 /* Program PHY to use EXT VBUS if required */
37 if (musb_cfg.extvbus == 1) {
38 busctl = musb_read_ulpi_buscontrol(musbr);
39 musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS);
40 }
41
Thomas Abrahama1428962009-01-04 09:41:03 +053042 devctl = readb(&musbr->devctl);
43 writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl);
44#endif
45}
46
Bryan Wudf402ba2009-12-16 22:03:59 -050047#ifdef MUSB_NO_DYNAMIC_FIFO
48# define config_fifo(dir, idx, addr)
49#else
50# define config_fifo(dir, idx, addr) \
51 do { \
52 writeb(idx, &musbr->dir##fifosz); \
Pali Rohár10bc1322021-02-07 14:50:05 +010053 writew(addr, &musbr->dir##fifoadd); \
Bryan Wudf402ba2009-12-16 22:03:59 -050054 } while (0)
55#endif
56
Thomas Abrahama1428962009-01-04 09:41:03 +053057/*
58 * This function configures the endpoint configuration. The musb hcd or musb
59 * device implementation can use this function to configure the endpoints
60 * and set the FIFO sizes. Note: The summation of FIFO sizes of all endpoints
61 * should not be more than the available FIFO size.
62 *
63 * epinfo - Pointer to EP configuration table
64 * cnt - Number of entries in the EP conf table.
65 */
Mike Frysinger02283482010-10-20 07:15:35 -040066void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
Thomas Abrahama1428962009-01-04 09:41:03 +053067{
68 u16 csr;
Pali Rohár10bc1322021-02-07 14:50:05 +010069 u16 fifoaddr = 64 >> 3; /* First 64 bytes of FIFO reserved for EP0 */
Thomas Abrahama1428962009-01-04 09:41:03 +053070 u32 fifosize;
71 u8 idx;
72
73 while (cnt--) {
74 /* prepare fifosize to write to register */
75 fifosize = epinfo->epsize >> 3;
Pali Rohár10bc1322021-02-07 14:50:05 +010076 idx = fifosize ? ((ffs(fifosize) - 1) & 0xF) : 0;
Thomas Abrahama1428962009-01-04 09:41:03 +053077
78 writeb(epinfo->epnum, &musbr->index);
79 if (epinfo->epdir) {
80 /* Configure fifo size and fifo base address */
Bryan Wudf402ba2009-12-16 22:03:59 -050081 config_fifo(tx, idx, fifoaddr);
Tom Rixf298e4b2009-10-31 12:37:41 -050082
83 csr = readw(&musbr->txcsr);
Thomas Abrahama1428962009-01-04 09:41:03 +053084 /* clear the data toggle bit */
Thomas Abrahama1428962009-01-04 09:41:03 +053085 writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
Thomas Abrahama1428962009-01-04 09:41:03 +053086 /* Flush fifo if required */
87 if (csr & MUSB_TXCSR_TXPKTRDY)
88 writew(csr | MUSB_TXCSR_FLUSHFIFO,
89 &musbr->txcsr);
90 } else {
91 /* Configure fifo size and fifo base address */
Bryan Wudf402ba2009-12-16 22:03:59 -050092 config_fifo(rx, idx, fifoaddr);
Tom Rixf298e4b2009-10-31 12:37:41 -050093
94 csr = readw(&musbr->rxcsr);
Thomas Abrahama1428962009-01-04 09:41:03 +053095 /* clear the data toggle bit */
Thomas Abrahama1428962009-01-04 09:41:03 +053096 writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
Thomas Abrahama1428962009-01-04 09:41:03 +053097 /* Flush fifo if required */
98 if (csr & MUSB_RXCSR_RXPKTRDY)
99 writew(csr | MUSB_RXCSR_FLUSHFIFO,
100 &musbr->rxcsr);
101 }
Pali Rohár10bc1322021-02-07 14:50:05 +0100102 fifoaddr += 1 << idx;
Thomas Abrahama1428962009-01-04 09:41:03 +0530103 epinfo++;
104 }
105}
106
107/*
108 * This function writes data to endpoint fifo
109 *
110 * ep - endpoint number
111 * length - number of bytes to write to FIFO
112 * fifo_data - Pointer to data buffer that contains the data to write
113 */
Bryan Wudf402ba2009-12-16 22:03:59 -0500114__attribute__((weak))
Thomas Abrahama1428962009-01-04 09:41:03 +0530115void write_fifo(u8 ep, u32 length, void *fifo_data)
116{
117 u8 *data = (u8 *)fifo_data;
118
119 /* select the endpoint index */
120 writeb(ep, &musbr->index);
121
122 /* write the data to the fifo */
123 while (length--)
124 writeb(*data++, &musbr->fifox[ep]);
125}
126
127/*
Ajay Kumar Gupta5689f4b2010-07-09 11:43:49 +0530128 * AM35x supports only 32bit read operations so
129 * use seperate read_fifo() function for it.
130 */
131#ifndef CONFIG_USB_AM35X
132/*
Thomas Abrahama1428962009-01-04 09:41:03 +0530133 * This function reads data from endpoint fifo
134 *
135 * ep - endpoint number
136 * length - number of bytes to read from FIFO
137 * fifo_data - pointer to data buffer into which data is read
138 */
Bryan Wudf402ba2009-12-16 22:03:59 -0500139__attribute__((weak))
Thomas Abrahama1428962009-01-04 09:41:03 +0530140void read_fifo(u8 ep, u32 length, void *fifo_data)
141{
142 u8 *data = (u8 *)fifo_data;
143
144 /* select the endpoint index */
145 writeb(ep, &musbr->index);
146
147 /* read the data to the fifo */
148 while (length--)
149 *data++ = readb(&musbr->fifox[ep]);
150}
Ajay Kumar Gupta5689f4b2010-07-09 11:43:49 +0530151#endif /* CONFIG_USB_AM35X */