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