summaryrefslogtreecommitdiffstats
path: root/u-boot/drivers/usb/musb/musb_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'u-boot/drivers/usb/musb/musb_core.c')
-rw-r--r--u-boot/drivers/usb/musb/musb_core.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/u-boot/drivers/usb/musb/musb_core.c b/u-boot/drivers/usb/musb/musb_core.c
new file mode 100644
index 0000000..545ebf4
--- /dev/null
+++ b/u-boot/drivers/usb/musb/musb_core.c
@@ -0,0 +1,168 @@
+/*
+ * Mentor USB OTG Core functionality common for both Host and Device
+ * functionality.
+ *
+ * Copyright (c) 2008 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
+ */
+
+#include <common.h>
+
+#include "musb_core.h"
+struct musb_regs *musbr;
+
+/*
+ * program the mentor core to start (enable interrupts, dma, etc.)
+ */
+void musb_start(void)
+{
+#if defined(CONFIG_MUSB_HCD)
+ u8 devctl;
+ u8 busctl;
+#endif
+
+ /* disable all interrupts */
+ writew(0, &musbr->intrtxe);
+ writew(0, &musbr->intrrxe);
+ writeb(0, &musbr->intrusbe);
+ writeb(0, &musbr->testmode);
+
+ /* put into basic highspeed mode and start session */
+ writeb(MUSB_POWER_HSENAB, &musbr->power);
+#if defined(CONFIG_MUSB_HCD)
+ /* Program PHY to use EXT VBUS if required */
+ if (musb_cfg.extvbus == 1) {
+ busctl = musb_read_ulpi_buscontrol(musbr);
+ musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS);
+ }
+
+ devctl = readb(&musbr->devctl);
+ writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl);
+#endif
+}
+
+#ifdef MUSB_NO_DYNAMIC_FIFO
+# define config_fifo(dir, idx, addr)
+#else
+# define config_fifo(dir, idx, addr) \
+ do { \
+ writeb(idx, &musbr->dir##fifosz); \
+ writew(fifoaddr >> 3, &musbr->dir##fifoadd); \
+ } while (0)
+#endif
+
+/*
+ * This function configures the endpoint configuration. The musb hcd or musb
+ * device implementation can use this function to configure the endpoints
+ * and set the FIFO sizes. Note: The summation of FIFO sizes of all endpoints
+ * should not be more than the available FIFO size.
+ *
+ * epinfo - Pointer to EP configuration table
+ * cnt - Number of entries in the EP conf table.
+ */
+void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
+{
+ u16 csr;
+ u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */
+ u32 fifosize;
+ u8 idx;
+
+ while (cnt--) {
+ /* prepare fifosize to write to register */
+ fifosize = epinfo->epsize >> 3;
+ idx = ffs(fifosize) - 1;
+
+ writeb(epinfo->epnum, &musbr->index);
+ if (epinfo->epdir) {
+ /* Configure fifo size and fifo base address */
+ config_fifo(tx, idx, fifoaddr);
+
+ csr = readw(&musbr->txcsr);
+#if defined(CONFIG_MUSB_HCD)
+ /* clear the data toggle bit */
+ writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
+#endif
+ /* Flush fifo if required */
+ if (csr & MUSB_TXCSR_TXPKTRDY)
+ writew(csr | MUSB_TXCSR_FLUSHFIFO,
+ &musbr->txcsr);
+ } else {
+ /* Configure fifo size and fifo base address */
+ config_fifo(rx, idx, fifoaddr);
+
+ csr = readw(&musbr->rxcsr);
+#if defined(CONFIG_MUSB_HCD)
+ /* clear the data toggle bit */
+ writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
+#endif
+ /* Flush fifo if required */
+ if (csr & MUSB_RXCSR_RXPKTRDY)
+ writew(csr | MUSB_RXCSR_FLUSHFIFO,
+ &musbr->rxcsr);
+ }
+ fifoaddr += epinfo->epsize;
+ epinfo++;
+ }
+}
+
+/*
+ * This function writes data to endpoint fifo
+ *
+ * ep - endpoint number
+ * length - number of bytes to write to FIFO
+ * fifo_data - Pointer to data buffer that contains the data to write
+ */
+__attribute__((weak))
+void write_fifo(u8 ep, u32 length, void *fifo_data)
+{
+ u8 *data = (u8 *)fifo_data;
+
+ /* select the endpoint index */
+ writeb(ep, &musbr->index);
+
+ /* write the data to the fifo */
+ while (length--)
+ writeb(*data++, &musbr->fifox[ep]);
+}
+
+/*
+ * AM35x supports only 32bit read operations so
+ * use seperate read_fifo() function for it.
+ */
+#ifndef CONFIG_USB_AM35X
+/*
+ * This function reads data from endpoint fifo
+ *
+ * ep - endpoint number
+ * length - number of bytes to read from FIFO
+ * fifo_data - pointer to data buffer into which data is read
+ */
+__attribute__((weak))
+void read_fifo(u8 ep, u32 length, void *fifo_data)
+{
+ u8 *data = (u8 *)fifo_data;
+
+ /* select the endpoint index */
+ writeb(ep, &musbr->index);
+
+ /* read the data to the fifo */
+ while (length--)
+ *data++ = readb(&musbr->fifox[ep]);
+}
+#endif /* CONFIG_USB_AM35X */