uboot/drivers/usb/musb/blackfin_usb.c
<<
>>
Prefs
   1/*
   2 * Blackfin MUSB HCD (Host Controller Driver) for u-boot
   3 *
   4 * Copyright (c) 2008-2009 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <common.h>
  10
  11#include <usb.h>
  12
  13#include <asm/blackfin.h>
  14#include <asm/clock.h>
  15#include <asm/mach-common/bits/usb.h>
  16
  17#include "musb_core.h"
  18
  19#ifndef CONFIG_USB_BLACKFIN_CLKIN
  20#define CONFIG_USB_BLACKFIN_CLKIN 24
  21#endif
  22
  23/* MUSB platform configuration */
  24struct musb_config musb_cfg = {
  25        .regs       = (struct musb_regs *)USB_FADDR,
  26        .timeout    = 0x3FFFFFF,
  27        .musb_speed = 0,
  28};
  29
  30/*
  31 * This function read or write data to endpoint fifo
  32 * Blackfin use DMA polling method to avoid buffer alignment issues
  33 *
  34 * ep           - Endpoint number
  35 * length       - Number of bytes to write to FIFO
  36 * fifo_data    - Pointer to data buffer to be read/write
  37 * is_write     - Flag for read or write
  38 */
  39void rw_fifo(u8 ep, u32 length, void *fifo_data, int is_write)
  40{
  41        struct bfin_musb_dma_regs *regs;
  42        u32 val = (u32)fifo_data;
  43
  44        blackfin_dcache_flush_invalidate_range(fifo_data, fifo_data + length);
  45
  46        regs = (void *)USB_DMA_INTERRUPT;
  47        regs += ep;
  48
  49        /* Setup DMA address register */
  50        bfin_write16(&regs->addr_low, val);
  51        SSYNC();
  52
  53        bfin_write16(&regs->addr_high, val >> 16);
  54        SSYNC();
  55
  56        /* Setup DMA count register */
  57        bfin_write16(&regs->count_low, length);
  58        bfin_write16(&regs->count_high, 0);
  59        SSYNC();
  60
  61        /* Enable the DMA */
  62        val = (ep << 4) | DMA_ENA | INT_ENA;
  63        if (is_write)
  64                val |= DIRECTION;
  65        bfin_write16(&regs->control, val);
  66        SSYNC();
  67
  68        /* Wait for compelete */
  69        while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << ep)))
  70                continue;
  71
  72        /* acknowledge dma interrupt */
  73        bfin_write_USB_DMA_INTERRUPT(1 << ep);
  74        SSYNC();
  75
  76        /* Reset DMA */
  77        bfin_write16(&regs->control, 0);
  78        SSYNC();
  79}
  80
  81void write_fifo(u8 ep, u32 length, void *fifo_data)
  82{
  83        rw_fifo(ep, length, fifo_data, 1);
  84}
  85
  86void read_fifo(u8 ep, u32 length, void *fifo_data)
  87{
  88        rw_fifo(ep, length, fifo_data, 0);
  89}
  90
  91
  92/*
  93 * CPU and board-specific MUSB initializations.  Aliased function
  94 * signals caller to move on.
  95 */
  96static void __def_musb_init(void)
  97{
  98}
  99void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
 100
 101static void bfin_anomaly_init(void)
 102{
 103        u32 revid;
 104
 105        if (!ANOMALY_05000346 && !ANOMALY_05000347)
 106                return;
 107
 108        revid = bfin_revid();
 109
 110#ifdef __ADSPBF54x__
 111        if (revid > 0)
 112                return;
 113#endif
 114#ifdef __ADSPBF52x__
 115        if (ANOMALY_BF526 && revid > 0)
 116                return;
 117        if (ANOMALY_BF527 && revid > 1)
 118                return;
 119#endif
 120
 121        if (ANOMALY_05000346) {
 122                bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
 123                SSYNC();
 124        }
 125
 126        if (ANOMALY_05000347) {
 127                bfin_write_USB_APHY_CNTRL(0x0);
 128                SSYNC();
 129        }
 130}
 131
 132int musb_platform_init(void)
 133{
 134        /* board specific initialization */
 135        board_musb_init();
 136
 137        bfin_anomaly_init();
 138
 139        /* Configure PLL oscillator register */
 140        bfin_write_USB_PLLOSC_CTRL(0x3080 |
 141                ((480 / CONFIG_USB_BLACKFIN_CLKIN) << 1));
 142        SSYNC();
 143
 144        bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
 145        SSYNC();
 146
 147        bfin_write_USB_EP_NI0_RXMAXP(64);
 148        SSYNC();
 149
 150        bfin_write_USB_EP_NI0_TXMAXP(64);
 151        SSYNC();
 152
 153        /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
 154        bfin_write_USB_GLOBINTR(0x7);
 155        SSYNC();
 156
 157        bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
 158                                EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
 159                                EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
 160                                EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
 161                                EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
 162        SSYNC();
 163
 164        return 0;
 165}
 166
 167/*
 168 * This function performs Blackfin platform specific deinitialization for usb.
 169*/
 170void musb_platform_deinit(void)
 171{
 172}
 173