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 /* 54 * This function configures the endpoint configuration. The musb hcd or musb 55 * device implementation can use this function to configure the endpoints 56 * and set the FIFO sizes. Note: The summation of FIFO sizes of all endpoints 57 * should not be more than the available FIFO size. 58 * 59 * epinfo - Pointer to EP configuration table 60 * cnt - Number of entries in the EP conf table. 61 */ 62 void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt) 63 { 64 u16 csr; 65 u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */ 66 u32 fifosize; 67 u8 idx; 68 69 while (cnt--) { 70 /* prepare fifosize to write to register */ 71 fifosize = epinfo->epsize >> 3; 72 idx = ffs(fifosize) - 1; 73 74 writeb(epinfo->epnum, &musbr->index); 75 if (epinfo->epdir) { 76 /* Configure fifo size and fifo base address */ 77 writeb(idx, &musbr->txfifosz); 78 writew(fifoaddr >> 3, &musbr->txfifoadd); 79 80 csr = readw(&musbr->txcsr); 81 #if defined(CONFIG_MUSB_HCD) 82 /* clear the data toggle bit */ 83 writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr); 84 #endif 85 /* Flush fifo if required */ 86 if (csr & MUSB_TXCSR_TXPKTRDY) 87 writew(csr | MUSB_TXCSR_FLUSHFIFO, 88 &musbr->txcsr); 89 } else { 90 /* Configure fifo size and fifo base address */ 91 writeb(idx, &musbr->rxfifosz); 92 writew(fifoaddr >> 3, &musbr->rxfifoadd); 93 94 csr = readw(&musbr->rxcsr); 95 #if defined(CONFIG_MUSB_HCD) 96 /* clear the data toggle bit */ 97 writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr); 98 #endif 99 /* Flush fifo if required */ 100 if (csr & MUSB_RXCSR_RXPKTRDY) 101 writew(csr | MUSB_RXCSR_FLUSHFIFO, 102 &musbr->rxcsr); 103 } 104 fifoaddr += epinfo->epsize; 105 epinfo++; 106 } 107 } 108 109 /* 110 * This function writes data to endpoint fifo 111 * 112 * ep - endpoint number 113 * length - number of bytes to write to FIFO 114 * fifo_data - Pointer to data buffer that contains the data to write 115 */ 116 void write_fifo(u8 ep, u32 length, void *fifo_data) 117 { 118 u8 *data = (u8 *)fifo_data; 119 120 /* select the endpoint index */ 121 writeb(ep, &musbr->index); 122 123 /* write the data to the fifo */ 124 while (length--) 125 writeb(*data++, &musbr->fifox[ep]); 126 } 127 128 /* 129 * This function reads data from endpoint fifo 130 * 131 * ep - endpoint number 132 * length - number of bytes to read from FIFO 133 * fifo_data - pointer to data buffer into which data is read 134 */ 135 void read_fifo(u8 ep, u32 length, void *fifo_data) 136 { 137 u8 *data = (u8 *)fifo_data; 138 139 /* select the endpoint index */ 140 writeb(ep, &musbr->index); 141 142 /* read the data to the fifo */ 143 while (length--) 144 *data++ = readb(&musbr->fifox[ep]); 145 } 146