blob: 38aceb2e93d32a2a0d49dee2076d0eb55fae2b1f [file] [log] [blame]
Bryan Wue956f342009-12-16 22:04:02 -05001/*
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/mach-common/bits/usb.h>
15
16#include "musb_core.h"
17
18/* MUSB platform configuration */
19struct musb_config musb_cfg = {
20 .regs = (struct musb_regs *)USB_FADDR,
21 .timeout = 0x3FFFFFF,
22 .musb_speed = 0,
23};
24
25/*
26 * This function read or write data to endpoint fifo
27 * Blackfin use DMA polling method to avoid buffer alignment issues
28 *
29 * ep - Endpoint number
30 * length - Number of bytes to write to FIFO
31 * fifo_data - Pointer to data buffer to be read/write
32 * is_write - Flag for read or write
33 */
34void rw_fifo(u8 ep, u32 length, void *fifo_data, int is_write)
35{
36 struct bfin_musb_dma_regs *regs;
37 u32 val = (u32)fifo_data;
38
39 blackfin_dcache_flush_invalidate_range(fifo_data, fifo_data + length);
40
41 regs = (void *)USB_DMA_INTERRUPT;
42 regs += ep;
43
44 /* Setup DMA address register */
45 bfin_write16(&regs->addr_low, val);
46 SSYNC();
47
48 bfin_write16(&regs->addr_high, val >> 16);
49 SSYNC();
50
51 /* Setup DMA count register */
52 bfin_write16(&regs->count_low, length);
53 bfin_write16(&regs->count_high, 0);
54 SSYNC();
55
56 /* Enable the DMA */
57 val = (ep << 4) | DMA_ENA | INT_ENA;
58 if (is_write)
59 val |= DIRECTION;
60 bfin_write16(&regs->control, val);
61 SSYNC();
62
63 /* Wait for compelete */
64 while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << ep)))
65 continue;
66
67 /* acknowledge dma interrupt */
68 bfin_write_USB_DMA_INTERRUPT(1 << ep);
69 SSYNC();
70
71 /* Reset DMA */
72 bfin_write16(&regs->control, 0);
73 SSYNC();
74}
75
76void write_fifo(u8 ep, u32 length, void *fifo_data)
77{
78 rw_fifo(ep, length, fifo_data, 1);
79}
80
81void read_fifo(u8 ep, u32 length, void *fifo_data)
82{
83 rw_fifo(ep, length, fifo_data, 0);
84}
85
86
87/*
88 * CPU and board-specific MUSB initializations. Aliased function
89 * signals caller to move on.
90 */
91static void __def_musb_init(void)
92{
93}
94void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
95
96int musb_platform_init(void)
97{
98 /* board specific initialization */
99 board_musb_init();
100
101 if (ANOMALY_05000346) {
102 bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
103 SSYNC();
104 }
105
106 if (ANOMALY_05000347) {
107 bfin_write_USB_APHY_CNTRL(0x0);
108 SSYNC();
109 }
110
111 /* Configure PLL oscillator register */
112 bfin_write_USB_PLLOSC_CTRL(0x30a8);
113 SSYNC();
114
115 bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
116 SSYNC();
117
118 bfin_write_USB_EP_NI0_RXMAXP(64);
119 SSYNC();
120
121 bfin_write_USB_EP_NI0_TXMAXP(64);
122 SSYNC();
123
124 /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
125 bfin_write_USB_GLOBINTR(0x7);
126 SSYNC();
127
128 bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
129 EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
130 EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
131 EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
132 EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
133 SSYNC();
134
135 return 0;
136}
137
138/*
139 * This function performs Blackfin platform specific deinitialization for usb.
140*/
141void musb_platform_deinit(void)
142{
143}