]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/usb/musb/blackfin_usb.c
Merge branch 'master' of git://git.denx.de/u-boot-spi
[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/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 */
24 struct 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  */
39 void 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
81 void write_fifo(u8 ep, u32 length, void *fifo_data)
82 {
83         rw_fifo(ep, length, fifo_data, 1);
84 }
85
86 void 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  */
96 static void __def_musb_init(void)
97 {
98 }
99 void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
100
101 static 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
132 int 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 */
170 void musb_platform_deinit(void)
171 {
172 }