uboot/drivers/usb/musb/musb_core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Mentor USB OTG Core functionality common for both Host and Device
   4 * functionality.
   5 *
   6 * Copyright (c) 2008 Texas Instruments
   7 *
   8 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
   9 */
  10
  11#include <common.h>
  12#include <linux/bitops.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_USB_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_USB_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(addr, &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 >> 3; /* 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 = fifosize ? ((ffs(fifosize) - 1) & 0xF) : 0;
  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                        /* clear the data toggle bit */
  85                        writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
  86                        /* Flush fifo if required */
  87                        if (csr & MUSB_TXCSR_TXPKTRDY)
  88                                writew(csr | MUSB_TXCSR_FLUSHFIFO,
  89                                        &musbr->txcsr);
  90                } else {
  91                        /* Configure fifo size and fifo base address */
  92                        config_fifo(rx, idx, fifoaddr);
  93
  94                        csr = readw(&musbr->rxcsr);
  95                        /* clear the data toggle bit */
  96                        writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
  97                        /* Flush fifo if required */
  98                        if (csr & MUSB_RXCSR_RXPKTRDY)
  99                                writew(csr | MUSB_RXCSR_FLUSHFIFO,
 100                                        &musbr->rxcsr);
 101                }
 102                fifoaddr += 1 << idx;
 103                epinfo++;
 104        }
 105}
 106
 107/*
 108 * This function writes data to endpoint fifo
 109 *
 110 * ep           - endpoint number
 111 * length       - number of bytes to write to FIFO
 112 * fifo_data    - Pointer to data buffer that contains the data to write
 113 */
 114__attribute__((weak))
 115void write_fifo(u8 ep, u32 length, void *fifo_data)
 116{
 117        u8  *data = (u8 *)fifo_data;
 118
 119        /* select the endpoint index */
 120        writeb(ep, &musbr->index);
 121
 122        /* write the data to the fifo */
 123        while (length--)
 124                writeb(*data++, &musbr->fifox[ep]);
 125}
 126
 127/*
 128 * AM35x supports only 32bit read operations so
 129 * use seperate read_fifo() function for it.
 130 */
 131#ifndef CONFIG_USB_AM35X
 132/*
 133 * This function reads data from endpoint fifo
 134 *
 135 * ep           - endpoint number
 136 * length       - number of bytes to read from FIFO
 137 * fifo_data    - pointer to data buffer into which data is read
 138 */
 139__attribute__((weak))
 140void read_fifo(u8 ep, u32 length, void *fifo_data)
 141{
 142        u8  *data = (u8 *)fifo_data;
 143
 144        /* select the endpoint index */
 145        writeb(ep, &musbr->index);
 146
 147        /* read the data to the fifo */
 148        while (length--)
 149                *data++ = readb(&musbr->fifox[ep]);
 150}
 151#endif /* CONFIG_USB_AM35X */
 152