1 // SPDX-License-Identifier: GPL-2.0+
3 * Mentor USB OTG Core functionality common for both Host and Device
6 * Copyright (c) 2008 Texas Instruments
8 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
13 #include "musb_core.h"
14 struct musb_regs *musbr;
17 * program the mentor core to start (enable interrupts, dma, etc.)
21 #if defined(CONFIG_USB_MUSB_HCD)
26 /* disable all interrupts */
27 writew(0, &musbr->intrtxe);
28 writew(0, &musbr->intrrxe);
29 writeb(0, &musbr->intrusbe);
30 writeb(0, &musbr->testmode);
32 /* put into basic highspeed mode and start session */
33 writeb(MUSB_POWER_HSENAB, &musbr->power);
34 #if defined(CONFIG_USB_MUSB_HCD)
35 /* Program PHY to use EXT VBUS if required */
36 if (musb_cfg.extvbus == 1) {
37 busctl = musb_read_ulpi_buscontrol(musbr);
38 musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS);
41 devctl = readb(&musbr->devctl);
42 writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl);
46 #ifdef MUSB_NO_DYNAMIC_FIFO
47 # define config_fifo(dir, idx, addr)
49 # define config_fifo(dir, idx, addr) \
51 writeb(idx, &musbr->dir##fifosz); \
52 writew(fifoaddr >> 3, &musbr->dir##fifoadd); \
57 * This function configures the endpoint configuration. The musb hcd or musb
58 * device implementation can use this function to configure the endpoints
59 * and set the FIFO sizes. Note: The summation of FIFO sizes of all endpoints
60 * should not be more than the available FIFO size.
62 * epinfo - Pointer to EP configuration table
63 * cnt - Number of entries in the EP conf table.
65 void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
68 u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */
73 /* prepare fifosize to write to register */
74 fifosize = epinfo->epsize >> 3;
75 idx = ffs(fifosize) - 1;
77 writeb(epinfo->epnum, &musbr->index);
79 /* Configure fifo size and fifo base address */
80 config_fifo(tx, idx, fifoaddr);
82 csr = readw(&musbr->txcsr);
83 #if defined(CONFIG_USB_MUSB_HCD)
84 /* clear the data toggle bit */
85 writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
87 /* Flush fifo if required */
88 if (csr & MUSB_TXCSR_TXPKTRDY)
89 writew(csr | MUSB_TXCSR_FLUSHFIFO,
92 /* Configure fifo size and fifo base address */
93 config_fifo(rx, idx, fifoaddr);
95 csr = readw(&musbr->rxcsr);
96 #if defined(CONFIG_USB_MUSB_HCD)
97 /* clear the data toggle bit */
98 writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
100 /* Flush fifo if required */
101 if (csr & MUSB_RXCSR_RXPKTRDY)
102 writew(csr | MUSB_RXCSR_FLUSHFIFO,
105 fifoaddr += epinfo->epsize;
111 * This function writes data to endpoint fifo
113 * ep - endpoint number
114 * length - number of bytes to write to FIFO
115 * fifo_data - Pointer to data buffer that contains the data to write
117 __attribute__((weak))
118 void write_fifo(u8 ep, u32 length, void *fifo_data)
120 u8 *data = (u8 *)fifo_data;
122 /* select the endpoint index */
123 writeb(ep, &musbr->index);
125 /* write the data to the fifo */
127 writeb(*data++, &musbr->fifox[ep]);
131 * AM35x supports only 32bit read operations so
132 * use seperate read_fifo() function for it.
134 #ifndef CONFIG_USB_AM35X
136 * This function reads data from endpoint fifo
138 * ep - endpoint number
139 * length - number of bytes to read from FIFO
140 * fifo_data - pointer to data buffer into which data is read
142 __attribute__((weak))
143 void read_fifo(u8 ep, u32 length, void *fifo_data)
145 u8 *data = (u8 *)fifo_data;
147 /* select the endpoint index */
148 writeb(ep, &musbr->index);
150 /* read the data to the fifo */
152 *data++ = readb(&musbr->fifox[ep]);
154 #endif /* CONFIG_USB_AM35X */