blob: 65fff887d3ee2e2d50c199a9af337a5594849990 [file] [log] [blame]
Bryan Wue608f222009-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>
Tom Rini130fbeb2014-02-20 10:14:10 -050014#include <asm/clock.h>
Bryan Wue608f222009-12-16 22:04:02 -050015#include <asm/mach-common/bits/usb.h>
16
17#include "musb_core.h"
18
Mike Frysinger38e07452011-03-17 17:35:00 -040019#ifndef CONFIG_USB_BLACKFIN_CLKIN
20#define CONFIG_USB_BLACKFIN_CLKIN 24
21#endif
22
Bryan Wue608f222009-12-16 22:04:02 -050023/* MUSB platform configuration */
24struct 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 */
39void 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
81void write_fifo(u8 ep, u32 length, void *fifo_data)
82{
83 rw_fifo(ep, length, fifo_data, 1);
84}
85
86void 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 */
96static void __def_musb_init(void)
97{
98}
99void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
100
Mike Frysinger081b59e2011-03-17 17:35:01 -0400101static void bfin_anomaly_init(void)
Bryan Wue608f222009-12-16 22:04:02 -0500102{
Mike Frysinger081b59e2011-03-17 17:35:01 -0400103 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
Bryan Wue608f222009-12-16 22:04:02 -0500120
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 }
Mike Frysinger081b59e2011-03-17 17:35:01 -0400130}
131
132int musb_platform_init(void)
133{
134 /* board specific initialization */
135 board_musb_init();
136
137 bfin_anomaly_init();
Bryan Wue608f222009-12-16 22:04:02 -0500138
139 /* Configure PLL oscillator register */
Mike Frysinger38e07452011-03-17 17:35:00 -0400140 bfin_write_USB_PLLOSC_CTRL(0x3080 |
141 ((480 / CONFIG_USB_BLACKFIN_CLKIN) << 1));
Bryan Wue608f222009-12-16 22:04:02 -0500142 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*/
170void musb_platform_deinit(void)
171{
172}