blob: 35268ba58ef00b1c18e18ccecd7f0b0c85e3f0b9 [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
Mike Frysinger283ecc12011-03-17 17:35:00 -040018#ifndef CONFIG_USB_BLACKFIN_CLKIN
19#define CONFIG_USB_BLACKFIN_CLKIN 24
20#endif
21
Bryan Wue956f342009-12-16 22:04:02 -050022/* MUSB platform configuration */
23struct 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 */
38void 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
80void write_fifo(u8 ep, u32 length, void *fifo_data)
81{
82 rw_fifo(ep, length, fifo_data, 1);
83}
84
85void 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 */
95static void __def_musb_init(void)
96{
97}
98void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
99
Mike Frysinger47a6ea32011-03-17 17:35:01 -0400100static void bfin_anomaly_init(void)
Bryan Wue956f342009-12-16 22:04:02 -0500101{
Mike Frysinger47a6ea32011-03-17 17:35:01 -0400102 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
Bryan Wue956f342009-12-16 22:04:02 -0500119
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 }
Mike Frysinger47a6ea32011-03-17 17:35:01 -0400129}
130
131int musb_platform_init(void)
132{
133 /* board specific initialization */
134 board_musb_init();
135
136 bfin_anomaly_init();
Bryan Wue956f342009-12-16 22:04:02 -0500137
138 /* Configure PLL oscillator register */
Mike Frysinger283ecc12011-03-17 17:35:00 -0400139 bfin_write_USB_PLLOSC_CTRL(0x3080 |
140 ((480 / CONFIG_USB_BLACKFIN_CLKIN) << 1));
Bryan Wue956f342009-12-16 22:04:02 -0500141 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*/
169void musb_platform_deinit(void)
170{
171}