1 /* 2 * Mentor USB OTG Core functionality common for both Host and Device 3 * functionality. 4 * 5 * Copyright (c) 2008 Texas Instruments 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 * 22 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments 23 */ 24 25 #include <common.h> 26 27 #include "musb_core.h" 28 struct musb_regs *musbr; 29 30 /* 31 * program the mentor core to start (enable interrupts, dma, etc.) 32 */ 33 void musb_start(void) 34 { 35 #if defined(CONFIG_MUSB_HCD) 36 u8 devctl; 37 #endif 38 39 /* disable all interrupts */ 40 writew(0, &musbr->intrtxe); 41 writew(0, &musbr->intrrxe); 42 writeb(0, &musbr->intrusbe); 43 writeb(0, &musbr->testmode); 44 45 /* put into basic highspeed mode and start session */ 46 writeb(MUSB_POWER_HSENAB, &musbr->power); 47 #if defined(CONFIG_MUSB_HCD) 48 devctl = readb(&musbr->devctl); 49 writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl); 50 #endif 51 } 52 53 #ifdef MUSB_NO_DYNAMIC_FIFO 54 # define config_fifo(dir, idx, addr) 55 #else 56 # define config_fifo(dir, idx, addr) \ 57 do { \ 58 writeb(idx, &musbr->dir##fifosz); \ 59 writew(fifoaddr >> 3, &musbr->dir##fifoadd); \ 60 } while (0) 61 #endif 62 63 /* 64 * This function configures the endpoint configuration. The musb hcd or musb 65 * device implementation can use this function to configure the endpoints 66 * and set the FIFO sizes. Note: The summation of FIFO sizes of all endpoints 67 * should not be more than the available FIFO size. 68 * 69 * epinfo - Pointer to EP configuration table 70 * cnt - Number of entries in the EP conf table. 71 */ 72 void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt) 73 { 74 u16 csr; 75 u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */ 76 u32 fifosize; 77 u8 idx; 78 79 while (cnt--) { 80 /* prepare fifosize to write to register */ 81 fifosize = epinfo->epsize >> 3; 82 idx = ffs(fifosize) - 1; 83 84 writeb(epinfo->epnum, &musbr->index); 85 if (epinfo->epdir) { 86 /* Configure fifo size and fifo base address */ 87 config_fifo(tx, idx, fifoaddr); 88 89 csr = readw(&musbr->txcsr); 90 #if defined(CONFIG_MUSB_HCD) 91 /* clear the data toggle bit */ 92 writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr); 93 #endif 94 /* Flush fifo if required */ 95 if (csr & MUSB_TXCSR_TXPKTRDY) 96 writew(csr | MUSB_TXCSR_FLUSHFIFO, 97 &musbr->txcsr); 98 } else { 99 /* Configure fifo size and fifo base address */ 100 config_fifo(rx, idx, fifoaddr); 101 102 csr = readw(&musbr->rxcsr); 103 #if defined(CONFIG_MUSB_HCD) 104 /* clear the data toggle bit */ 105 writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr); 106 #endif 107 /* Flush fifo if required */ 108 if (csr & MUSB_RXCSR_RXPKTRDY) 109 writew(csr | MUSB_RXCSR_FLUSHFIFO, 110 &musbr->rxcsr); 111 } 112 fifoaddr += epinfo->epsize; 113 epinfo++; 114 } 115 } 116 117 /* 118 * This function writes data to endpoint fifo 119 * 120 * ep - endpoint number 121 * length - number of bytes to write to FIFO 122 * fifo_data - Pointer to data buffer that contains the data to write 123 */ 124 __attribute__((weak)) 125 void write_fifo(u8 ep, u32 length, void *fifo_data) 126 { 127 u8 *data = (u8 *)fifo_data; 128 129 /* select the endpoint index */ 130 writeb(ep, &musbr->index); 131 132 /* write the data to the fifo */ 133 while (length--) 134 writeb(*data++, &musbr->fifox[ep]); 135 } 136 137 /* 138 * This function reads data from endpoint fifo 139 * 140 * ep - endpoint number 141 * length - number of bytes to read from FIFO 142 * fifo_data - pointer to data buffer into which data is read 143 */ 144 __attribute__((weak)) 145 void read_fifo(u8 ep, u32 length, void *fifo_data) 146 { 147 u8 *data = (u8 *)fifo_data; 148 149 /* select the endpoint index */ 150 writeb(ep, &musbr->index); 151 152 /* read the data to the fifo */ 153 while (length--) 154 *data++ = readb(&musbr->fifox[ep]); 155 } 156