]>
Commit | Line | Data |
---|---|---|
a1428969 TA |
1 | /* |
2 | * Mentor USB OTG Core functionality common for both Host and Device | |
3 | * functionality. | |
4 | * | |
5 | * Copyright (c) 2008 Texas Instruments | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
a1428969 TA |
8 | * |
9 | * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments | |
10 | */ | |
11 | ||
12 | #include <common.h> | |
13 | ||
14 | #include "musb_core.h" | |
15 | struct musb_regs *musbr; | |
16 | ||
17 | /* | |
18 | * program the mentor core to start (enable interrupts, dma, etc.) | |
19 | */ | |
20 | void musb_start(void) | |
21 | { | |
f298e4b6 | 22 | #if defined(CONFIG_MUSB_HCD) |
a1428969 | 23 | u8 devctl; |
9bb47abf | 24 | u8 busctl; |
f298e4b6 | 25 | #endif |
a1428969 TA |
26 | |
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); | |
35 | #if defined(CONFIG_MUSB_HCD) | |
9bb47abf AKG |
36 | /* 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 | ||
a1428969 TA |
42 | devctl = readb(&musbr->devctl); |
43 | writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl); | |
44 | #endif | |
45 | } | |
46 | ||
df402ba3 BW |
47 | #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); \ | |
53 | writew(fifoaddr >> 3, &musbr->dir##fifoadd); \ | |
54 | } while (0) | |
55 | #endif | |
56 | ||
a1428969 TA |
57 | /* |
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 | */ | |
0228348e | 66 | void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt) |
a1428969 TA |
67 | { |
68 | u16 csr; | |
69 | u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */ | |
70 | u32 fifosize; | |
71 | u8 idx; | |
72 | ||
73 | while (cnt--) { | |
74 | /* prepare fifosize to write to register */ | |
75 | fifosize = epinfo->epsize >> 3; | |
76 | idx = ffs(fifosize) - 1; | |
77 | ||
78 | writeb(epinfo->epnum, &musbr->index); | |
79 | if (epinfo->epdir) { | |
80 | /* Configure fifo size and fifo base address */ | |
df402ba3 | 81 | config_fifo(tx, idx, fifoaddr); |
f298e4b6 TR |
82 | |
83 | csr = readw(&musbr->txcsr); | |
a1428969 TA |
84 | #if defined(CONFIG_MUSB_HCD) |
85 | /* clear the data toggle bit */ | |
a1428969 TA |
86 | writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr); |
87 | #endif | |
88 | /* Flush fifo if required */ | |
89 | if (csr & MUSB_TXCSR_TXPKTRDY) | |
90 | writew(csr | MUSB_TXCSR_FLUSHFIFO, | |
91 | &musbr->txcsr); | |
92 | } else { | |
93 | /* Configure fifo size and fifo base address */ | |
df402ba3 | 94 | config_fifo(rx, idx, fifoaddr); |
f298e4b6 TR |
95 | |
96 | csr = readw(&musbr->rxcsr); | |
a1428969 TA |
97 | #if defined(CONFIG_MUSB_HCD) |
98 | /* clear the data toggle bit */ | |
a1428969 TA |
99 | writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr); |
100 | #endif | |
101 | /* Flush fifo if required */ | |
102 | if (csr & MUSB_RXCSR_RXPKTRDY) | |
103 | writew(csr | MUSB_RXCSR_FLUSHFIFO, | |
104 | &musbr->rxcsr); | |
105 | } | |
106 | fifoaddr += epinfo->epsize; | |
107 | epinfo++; | |
108 | } | |
109 | } | |
110 | ||
111 | /* | |
112 | * This function writes data to endpoint fifo | |
113 | * | |
114 | * ep - endpoint number | |
115 | * length - number of bytes to write to FIFO | |
116 | * fifo_data - Pointer to data buffer that contains the data to write | |
117 | */ | |
df402ba3 | 118 | __attribute__((weak)) |
a1428969 TA |
119 | void write_fifo(u8 ep, u32 length, void *fifo_data) |
120 | { | |
121 | u8 *data = (u8 *)fifo_data; | |
122 | ||
123 | /* select the endpoint index */ | |
124 | writeb(ep, &musbr->index); | |
125 | ||
126 | /* write the data to the fifo */ | |
127 | while (length--) | |
128 | writeb(*data++, &musbr->fifox[ep]); | |
129 | } | |
130 | ||
5689f4b5 AKG |
131 | /* |
132 | * AM35x supports only 32bit read operations so | |
133 | * use seperate read_fifo() function for it. | |
134 | */ | |
135 | #ifndef CONFIG_USB_AM35X | |
a1428969 TA |
136 | /* |
137 | * This function reads data from endpoint fifo | |
138 | * | |
139 | * ep - endpoint number | |
140 | * length - number of bytes to read from FIFO | |
141 | * fifo_data - pointer to data buffer into which data is read | |
142 | */ | |
df402ba3 | 143 | __attribute__((weak)) |
a1428969 TA |
144 | void read_fifo(u8 ep, u32 length, void *fifo_data) |
145 | { | |
146 | u8 *data = (u8 *)fifo_data; | |
147 | ||
148 | /* select the endpoint index */ | |
149 | writeb(ep, &musbr->index); | |
150 | ||
151 | /* read the data to the fifo */ | |
152 | while (length--) | |
153 | *data++ = readb(&musbr->fifox[ep]); | |
154 | } | |
5689f4b5 | 155 | #endif /* CONFIG_USB_AM35X */ |