Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / drivers / usb / musb / blackfin_usb.c
diff --git a/qemu/roms/u-boot/drivers/usb/musb/blackfin_usb.c b/qemu/roms/u-boot/drivers/usb/musb/blackfin_usb.c
new file mode 100644 (file)
index 0000000..65fff88
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Blackfin MUSB HCD (Host Controller Driver) for u-boot
+ *
+ * Copyright (c) 2008-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+
+#include <usb.h>
+
+#include <asm/blackfin.h>
+#include <asm/clock.h>
+#include <asm/mach-common/bits/usb.h>
+
+#include "musb_core.h"
+
+#ifndef CONFIG_USB_BLACKFIN_CLKIN
+#define CONFIG_USB_BLACKFIN_CLKIN 24
+#endif
+
+/* MUSB platform configuration */
+struct musb_config musb_cfg = {
+       .regs       = (struct musb_regs *)USB_FADDR,
+       .timeout    = 0x3FFFFFF,
+       .musb_speed = 0,
+};
+
+/*
+ * This function read or write data to endpoint fifo
+ * Blackfin use DMA polling method to avoid buffer alignment issues
+ *
+ * ep          - Endpoint number
+ * length      - Number of bytes to write to FIFO
+ * fifo_data   - Pointer to data buffer to be read/write
+ * is_write    - Flag for read or write
+ */
+void rw_fifo(u8 ep, u32 length, void *fifo_data, int is_write)
+{
+       struct bfin_musb_dma_regs *regs;
+       u32 val = (u32)fifo_data;
+
+       blackfin_dcache_flush_invalidate_range(fifo_data, fifo_data + length);
+
+       regs = (void *)USB_DMA_INTERRUPT;
+       regs += ep;
+
+       /* Setup DMA address register */
+       bfin_write16(&regs->addr_low, val);
+       SSYNC();
+
+       bfin_write16(&regs->addr_high, val >> 16);
+       SSYNC();
+
+       /* Setup DMA count register */
+       bfin_write16(&regs->count_low, length);
+       bfin_write16(&regs->count_high, 0);
+       SSYNC();
+
+       /* Enable the DMA */
+       val = (ep << 4) | DMA_ENA | INT_ENA;
+       if (is_write)
+               val |= DIRECTION;
+       bfin_write16(&regs->control, val);
+       SSYNC();
+
+       /* Wait for compelete */
+       while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << ep)))
+               continue;
+
+       /* acknowledge dma interrupt */
+       bfin_write_USB_DMA_INTERRUPT(1 << ep);
+       SSYNC();
+
+       /* Reset DMA */
+       bfin_write16(&regs->control, 0);
+       SSYNC();
+}
+
+void write_fifo(u8 ep, u32 length, void *fifo_data)
+{
+       rw_fifo(ep, length, fifo_data, 1);
+}
+
+void read_fifo(u8 ep, u32 length, void *fifo_data)
+{
+       rw_fifo(ep, length, fifo_data, 0);
+}
+
+
+/*
+ * CPU and board-specific MUSB initializations.  Aliased function
+ * signals caller to move on.
+ */
+static void __def_musb_init(void)
+{
+}
+void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
+
+static void bfin_anomaly_init(void)
+{
+       u32 revid;
+
+       if (!ANOMALY_05000346 && !ANOMALY_05000347)
+               return;
+
+       revid = bfin_revid();
+
+#ifdef __ADSPBF54x__
+       if (revid > 0)
+               return;
+#endif
+#ifdef __ADSPBF52x__
+       if (ANOMALY_BF526 && revid > 0)
+               return;
+       if (ANOMALY_BF527 && revid > 1)
+               return;
+#endif
+
+       if (ANOMALY_05000346) {
+               bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
+               SSYNC();
+       }
+
+       if (ANOMALY_05000347) {
+               bfin_write_USB_APHY_CNTRL(0x0);
+               SSYNC();
+       }
+}
+
+int musb_platform_init(void)
+{
+       /* board specific initialization */
+       board_musb_init();
+
+       bfin_anomaly_init();
+
+       /* Configure PLL oscillator register */
+       bfin_write_USB_PLLOSC_CTRL(0x3080 |
+               ((480 / CONFIG_USB_BLACKFIN_CLKIN) << 1));
+       SSYNC();
+
+       bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
+       SSYNC();
+
+       bfin_write_USB_EP_NI0_RXMAXP(64);
+       SSYNC();
+
+       bfin_write_USB_EP_NI0_TXMAXP(64);
+       SSYNC();
+
+       /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
+       bfin_write_USB_GLOBINTR(0x7);
+       SSYNC();
+
+       bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
+                               EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
+                               EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
+                               EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
+                               EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
+       SSYNC();
+
+       return 0;
+}
+
+/*
+ * This function performs Blackfin platform specific deinitialization for usb.
+*/
+void musb_platform_deinit(void)
+{
+}