uboot/drivers/usb/musb/musb_core.c
<<
>>
Prefs
   1/*
   2 * Mentor USB OTG Core functionality common for both Host and Device
   3 * functionality.
   4 *
   5 * Copyright (c) 2008 Texas Instruments
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 *
   9 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
  10 */
  11
  12#include <common.h>
  13
  14#include "musb_core.h"
  15struct musb_regs *musbr;
  16
  17/*
  18 * program the mentor core to start (enable interrupts, dma, etc.)
  19 */
  20void musb_start(void)
  21{
  22#if defined(CONFIG_MUSB_HCD)
  23        u8 devctl;
  24        u8 busctl;
  25#endif
  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)
  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
  42        devctl = readb(&musbr->devctl);
  43        writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl);
  44#endif
  45}
  46
  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
  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 */
  66void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
  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 */
  81                        config_fifo(tx, idx, fifoaddr);
  82
  83                        csr = readw(&musbr->txcsr);
  84#if defined(CONFIG_MUSB_HCD)
  85                        /* clear the data toggle bit */
  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 */
  94                        config_fifo(rx, idx, fifoaddr);
  95
  96                        csr = readw(&musbr->rxcsr);
  97#if defined(CONFIG_MUSB_HCD)
  98                        /* clear the data toggle bit */
  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 */
 118__attribute__((weak))
 119void 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
 131/*
 132 * AM35x supports only 32bit read operations so
 133 * use seperate read_fifo() function for it.
 134 */
 135#ifndef CONFIG_USB_AM35X
 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 */
 143__attribute__((weak))
 144void 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}
 155#endif /* CONFIG_USB_AM35X */
 156