summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorTobias Diedrich <ranma+coreboot@tdiedrich.de>2010-05-18 07:00:57 +0000
committerTobias Diedrich <ranma+coreboot@tdiedrich.de>2010-05-18 07:00:57 +0000
commit922f83e64729910dcc83e66cd5aa54c9a4bd4cd2 (patch)
treeeb698f97f936886487bf11baa63c3848223409ea /firmware/target/arm
parentc23a7ccbbc9e8e817503bac5c1401125ef23a136 (diff)
downloadrockbox-922f83e64729910dcc83e66cd5aa54c9a4bd4cd2.tar.gz
rockbox-922f83e64729910dcc83e66cd5aa54c9a4bd4cd2.zip
Not quite working yet, but almost.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26126 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/as3525/system-as3525.c6
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525.c982
2 files changed, 831 insertions, 157 deletions
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index d79caadf1b..ba8aa43715 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -114,6 +114,7 @@ struct vec_int_src vec_int_srcs[] =
114 { INT_SRC_NAND, INT_NAND }, 114 { INT_SRC_NAND, INT_NAND },
115 { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO }, 115 { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO },
116 { INT_SRC_AUDIO, INT_AUDIO }, 116 { INT_SRC_AUDIO, INT_AUDIO },
117 { INT_SRC_USB, INT_USB, },
117#if (defined HAVE_MULTIDRIVE && CONFIG_CPU == AS3525) 118#if (defined HAVE_MULTIDRIVE && CONFIG_CPU == AS3525)
118 { INT_SRC_MCI0, INT_MCI0 }, 119 { INT_SRC_MCI0, INT_MCI0 },
119#endif 120#endif
@@ -324,7 +325,7 @@ void system_init(void)
324 CGU_PLLASUP = 0; /* enable PLLA */ 325 CGU_PLLASUP = 0; /* enable PLLA */
325 while(!(CGU_INTCTRL & (1<<0))); /* wait until PLLA is locked */ 326 while(!(CGU_INTCTRL & (1<<0))); /* wait until PLLA is locked */
326 327
327#if (AS3525_MCLK_SEL == AS3525_CLK_PLLB) 328#if defined(USE_ROCKBOX_USB) || (AS3525_MCLK_SEL == AS3525_CLK_PLLB)
328 CGU_COUNTB = 0xff; 329 CGU_COUNTB = 0xff;
329 CGU_PLLB = AS3525_PLLB_SETTING; 330 CGU_PLLB = AS3525_PLLB_SETTING;
330 CGU_PLLBSUP = 0; /* enable PLLB */ 331 CGU_PLLBSUP = 0; /* enable PLLB */
@@ -392,6 +393,9 @@ void system_reboot(void)
392 393
393void system_exception_wait(void) 394void system_exception_wait(void)
394{ 395{
396 /* make sure backlight is on */
397 _backlight_on();
398 _backlight_pwm(1);
395 /* wait until button release (if a button is pressed) */ 399 /* wait until button release (if a button is pressed) */
396 while(button_read_device()); 400 while(button_read_device());
397 /* then wait until next button press */ 401 /* then wait until next button press */
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.c b/firmware/target/arm/as3525/usb-drv-as3525.c
index 488fbff6b1..d6b9c1dfea 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525.c
@@ -19,6 +19,7 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "system.h"
22#include "usb.h" 23#include "usb.h"
23#include "usb_drv.h" 24#include "usb_drv.h"
24#include "as3525.h" 25#include "as3525.h"
@@ -28,169 +29,489 @@
28#include <stdbool.h> 29#include <stdbool.h>
29#include "panic.h" 30#include "panic.h"
30/*#define LOGF_ENABLE*/ 31/*#define LOGF_ENABLE*/
32#define LOGF_ENABLE
31#include "logf.h" 33#include "logf.h"
34#include "usb_ch9.h"
35#include "usb_core.h"
36#include "string.h"
32 37
38#define USB_NUM_EPS 4
39
40typedef struct {
41 volatile unsigned long offset[4096];
42} __regbase;
43
44/*
45 * This generates better code.
46 * Stripped object size with __regbase construct: 5192
47 * Stripped object size with *((volatile int)(x)): 5228
48 */
49#define USB_REG(x) ((__regbase *)(USB_BASE))->offset[(x)>>2]
33 50
34/* 4 input endpoints */ 51/* 4 input endpoints */
35#define USB_IEP_CTRL(i) *((volatile unsigned long*) (USB_BASE + 0x0000 + (i*0x20))) 52#define USB_IEP_CTRL(i) USB_REG(0x0000 + i*0x20)
36#define USB_IEP_STS(i) *((volatile unsigned long*) (USB_BASE + 0x0004 + (i*0x20))) 53#define USB_IEP_STS(i) USB_REG(0x0004 + i*0x20)
37#define USB_IEP_TXFSIZE(i) *((volatile unsigned long*) (USB_BASE + 0x0008 + (i*0x20))) 54#define USB_IEP_TXFSIZE(i) USB_REG(0x0008 + i*0x20)
38#define USB_IEP_MPS(i) *((volatile unsigned long*) (USB_BASE + 0x000C + (i*0x20))) 55#define USB_IEP_MPS(i) USB_REG(0x000C + i*0x20)
39#define USB_IEP_DESC_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x0014 + (i*0x20))) 56#define USB_IEP_DESC_PTR(i) USB_REG(0x0014 + i*0x20)
40#define USB_IEP_STS_MASK(i) *((volatile unsigned long*) (USB_BASE + 0x0018 + (i*0x20))) 57#define USB_IEP_STS_MASK(i) USB_REG(0x0018 + i*0x20)
41 58
42/* 4 output endpoints */ 59/* 4 output endpoints */
43#define USB_OEP_CTRL(i) *((volatile unsigned long*) (USB_BASE + 0x0200 + (i*0x20))) 60#define USB_OEP_CTRL(i) USB_REG(0x0200 + i*0x20)
44#define USB_OEP_STS(i) *((volatile unsigned long*) (USB_BASE + 0x0204 + (i*0x20))) 61#define USB_OEP_STS(i) USB_REG(0x0204 + i*0x20)
45#define USB_OEP_RXFR(i) *((volatile unsigned long*) (USB_BASE + 0x0208 + (i*0x20))) 62#define USB_OEP_RXFR(i) USB_REG(0x0208 + i*0x20)
46#define USB_OEP_MPS(i) *((volatile unsigned long*) (USB_BASE + 0x020C + (i*0x20))) 63#define USB_OEP_MPS(i) USB_REG(0x020C + i*0x20)
47#define USB_OEP_SUP_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x0210 + (i*0x20))) 64#define USB_OEP_SUP_PTR(i) USB_REG(0x0210 + i*0x20)
48#define USB_OEP_DESC_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x0214 + (i*0x20))) 65#define USB_OEP_DESC_PTR(i) USB_REG(0x0214 + i*0x20)
49#define USB_OEP_STS_MASK(i) *((volatile unsigned long*) (USB_BASE + 0x0218 + (i*0x20))) 66#define USB_OEP_STS_MASK(i) USB_REG(0x0218 + i*0x20)
50 67
51#define USB_DEV_CFG *((volatile unsigned long*) (USB_BASE + 0x0400)) 68/* more general macro */
52#define USB_DEV_CTRL *((volatile unsigned long*) (USB_BASE + 0x0404)) 69/* d: true => IN, false => OUT */
53#define USB_DEV_STS *((volatile unsigned long*) (USB_BASE + 0x0408)) 70#define USB_EP_CTRL(i,d) USB_REG(0x0000 + i*0x20 + (!d)*0x0200)
54#define USB_DEV_INTR *((volatile unsigned long*) (USB_BASE + 0x040C)) 71#define USB_EP_STS(i,d) USB_REG(0x0004 + i*0x20 + (!d)*0x0200)
55#define USB_DEV_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x0410)) 72#define USB_EP_TXFSIZE(i,d) USB_REG(0x0008 + i*0x20 + (!d)*0x0200)
56#define USB_DEV_EP_INTR *((volatile unsigned long*) (USB_BASE + 0x0414)) 73#define USB_EP_MPS(i,d) USB_REG(0x000C + i*0x20 + (!d)*0x0200)
57#define USB_DEV_EP_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x0418)) 74#define USB_EP_DESC_PTR(i,d) USB_REG(0x0014 + i*0x20 + (!d)*0x0200)
58 75#define USB_EP_STS_MASK(i,d) USB_REG(0x0018 + i*0x20 + (!d)*0x0200)
59#define USB_PHY_EP0_INFO *((volatile unsigned long*) (USB_BASE + 0x0504)) 76
60#define USB_PHY_EP1_INFO *((volatile unsigned long*) (USB_BASE + 0x0508)) 77#define USB_DEV_CFG USB_REG(0x0400)
61#define USB_PHY_EP2_INFO *((volatile unsigned long*) (USB_BASE + 0x050C)) 78#define USB_DEV_CTRL USB_REG(0x0404)
62#define USB_PHY_EP3_INFO *((volatile unsigned long*) (USB_BASE + 0x0510)) 79#define USB_DEV_STS USB_REG(0x0408)
63#define USB_PHY_EP4_INFO *((volatile unsigned long*) (USB_BASE + 0x0514)) 80#define USB_DEV_INTR USB_REG(0x040C)
64#define USB_PHY_EP5_INFO *((volatile unsigned long*) (USB_BASE + 0x0518)) 81#define USB_DEV_INTR_MASK USB_REG(0x0410)
82#define USB_DEV_EP_INTR USB_REG(0x0414)
83#define USB_DEV_EP_INTR_MASK USB_REG(0x0418)
84
85/* NOTE: Not written to in OF, most lied in host mode? */
86#define USB_PHY_EP0_INFO USB_REG(0x0504)
87#define USB_PHY_EP1_INFO USB_REG(0x0508)
88#define USB_PHY_EP2_INFO USB_REG(0x050C)
89#define USB_PHY_EP3_INFO USB_REG(0x0510)
90#define USB_PHY_EP4_INFO USB_REG(0x0514)
91#define USB_PHY_EP5_INFO USB_REG(0x0518)
65 92
66/* 4 channels */ 93/* 4 channels */
67#define USB_HOST_CH_SPLT(i) *((volatile unsigned long*) (USB_BASE + 0x1000 + (i*0x20))) 94#define USB_HOST_CH_SPLT(i) USB_REG(0x1000 + i*0x20)
68#define USB_HOST_CH_STS(i) *((volatile unsigned long*) (USB_BASE + 0x1004 + (i*0x20))) 95#define USB_HOST_CH_STS(i) USB_REG(0x1004 + i*0x20)
69#define USB_HOST_CH_TXFSIZE(i) *((volatile unsigned long*) (USB_BASE + 0x1008 + (i*0x20))) 96#define USB_HOST_CH_TXFSIZE(i) USB_REG(0x1008 + i*0x20)
70#define USB_HOST_CH_REQ(i) *((volatile unsigned long*) (USB_BASE + 0x100C + (i*0x20))) 97#define USB_HOST_CH_REQ(i) USB_REG(0x100C + i*0x20)
71#define USB_HOST_CH_PER_INFO(i) *((volatile unsigned long*) (USB_BASE + 0x1010 + (i*0x20))) 98#define USB_HOST_CH_PER_INFO(i) USB_REG(0x1010 + i*0x20)
72#define USB_HOST_CH_DESC_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x1014 + (i*0x20))) 99#define USB_HOST_CH_DESC_PTR(i) USB_REG(0x1014 + i*0x20)
73#define USB_HOST_CH_STS_MASK(i) *((volatile unsigned long*) (USB_BASE + 0x1018 + (i*0x20))) 100#define USB_HOST_CH_STS_MASK(i) USB_REG(0x1018 + i*0x20)
74 101
75#define USB_HOST_CFG *((volatile unsigned long*) (USB_BASE + 0x1400)) 102#define USB_HOST_CFG USB_REG(0x1400)
76#define USB_HOST_CTRL *((volatile unsigned long*) (USB_BASE + 0x1404)) 103#define USB_HOST_CTRL USB_REG(0x1404)
77#define USB_HOST_INTR *((volatile unsigned long*) (USB_BASE + 0x140C)) 104#define USB_HOST_INTR USB_REG(0x140C)
78#define USB_HOST_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x1410)) 105#define USB_HOST_INTR_MASK USB_REG(0x1410)
79#define USB_HOST_CH_INTR *((volatile unsigned long*) (USB_BASE + 0x1414)) 106#define USB_HOST_CH_INTR USB_REG(0x1414)
80#define USB_HOST_CH_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x1418)) 107#define USB_HOST_CH_INTR_MASK USB_REG(0x1418)
81#define USB_HOST_FRAME_INT *((volatile unsigned long*) (USB_BASE + 0x141C)) 108#define USB_HOST_FRAME_INT USB_REG(0x141C)
82#define USB_HOST_FRAME_REM *((volatile unsigned long*) (USB_BASE + 0x1420)) 109#define USB_HOST_FRAME_REM USB_REG(0x1420)
83#define USB_HOST_FRAME_NUM *((volatile unsigned long*) (USB_BASE + 0x1424)) 110#define USB_HOST_FRAME_NUM USB_REG(0x1424)
84 111
85#define USB_HOST_PORT0_CTRL_STS *((volatile unsigned long*) (USB_BASE + 0x1500)) 112#define USB_HOST_PORT0_CTRL_STS USB_REG(0x1500)
86 113
87#define USB_OTG_CSR *((volatile unsigned long*) (USB_BASE + 0x2000)) 114#define USB_OTG_CSR USB_REG(0x2000)
88#define USB_I2C_CSR *((volatile unsigned long*) (USB_BASE + 0x2004)) 115#define USB_I2C_CSR USB_REG(0x2004)
89#define USB_GPIO_CSR *((volatile unsigned long*) (USB_BASE + 0x2008)) 116#define USB_GPIO_CSR USB_REG(0x2008)
90#define USB_SNPSID_CSR *((volatile unsigned long*) (USB_BASE + 0x200C)) 117#define USB_SNPSID_CSR USB_REG(0x200C)
91#define USB_USERID_CSR *((volatile unsigned long*) (USB_BASE + 0x2010)) 118#define USB_USERID_CSR USB_REG(0x2010)
92#define USB_USER_CONF1 *((volatile unsigned long*) (USB_BASE + 0x2014)) 119#define USB_USER_CONF1 USB_REG(0x2014)
93#define USB_USER_CONF2 *((volatile unsigned long*) (USB_BASE + 0x2018)) 120#define USB_USER_CONF2 USB_REG(0x2018)
94#define USB_USER_CONF3 *((volatile unsigned long*) (USB_BASE + 0x201C)) 121#define USB_USER_CONF3 USB_REG(0x201C)
95#define USB_USER_CONF4 *((volatile unsigned long*) (USB_BASE + 0x2020)) 122#define USB_USER_CONF4 USB_REG(0x2020)
96#define USB_USER_CONF5 *((volatile unsigned long*) (USB_BASE + 0x2024)) 123/* USER_CONF5 seems to the same as USBt least on read */
124#define USB_USER_CONF5 USB_REG(0x2024)
125
126/* write bits 31..16 */
127#define USB_GPIO_IDDIG_SEL (1<<30)
128#define USB_GPIO_FS_DATA_EXT (1<<29)
129#define USB_GPIO_FS_SE0_EXT (1<<28)
130#define USB_GPIO_FS_XCVR_OWNER (1<<27)
131#define USB_GPIO_TX_ENABLE_N (1<<26)
132#define USB_GPIO_TX_BIT_STUFF_EN (1<<25)
133#define USB_GPIO_BSESSVLD_EXT (1<<24)
134#define USB_GPIO_ASESSVLD_EXT (1<<23)
135#define USB_GPIO_VBUS_VLD_EXT (1<<22)
136#define USB_GPIO_VBUS_VLD_EXT_SEL (1<<21)
137#define USB_GPIO_XO_ON (1<<20)
138#define USB_GPIO_CLK_SEL11 (3<<18)
139#define USB_GPIO_CLK_SEL10 (2<<18)
140#define USB_GPIO_CLK_SEL01 (1<<18)
141#define USB_GPIO_CLK_SEL00 (0<<18)
142#define USB_GPIO_XO_EXT_CLK_ENBN (1<<17)
143#define USB_GPIO_XO_REFCLK_ENB (1<<16)
144/* readronly bits 15..0 */
145#define USB_GPIO_PHY_VBUSDRV (1<< 1)
146#define USB_GPIO_HS_INTR (1<< 0)
147
148/* Device Control Register and bit fields */
149#define USB_DEV_CTRL_REMOTE_WAKEUP 0x00000001 // set remote wake-up signal
150#define USB_DEV_CTRL_RDE 0x00000004 // receive dma enable
151#define USB_DEV_CTRL_DESC_UPDATE 0x00000010 // descriptor update
152#define USB_DEV_CTRL_THRES_ENABLE 0x00000080 // threshold enable
153#define USB_DEV_CTRL_BURST_CONTROL 0x00000100 // burst control
154#define USB_DEV_CTRL_SOFT_DISCONN 0x00000400 // soft disconnect
155#define USB_DEV_CTRL_APCSR_DONE 0x00002000 // app Prog CSR Done
156#define USB_DEV_CTRL_MASK_BURST_LEN 0x000f0000 // mask for burst length
157#define USB_DEV_CTRL_MASK_THRESHOLD_LEN 0xff000000 // mask for threshold length
158
159/* settings of burst length for maskBurstLen_c field */
160#define USB_DEV_CTRL_BLEN_1DWORD 0x00000000
161#define USB_DEV_CTRL_BLEN_2DWORDS 0x00010000
162#define USB_DEV_CTRL_BLEN_4DWORDS 0x00020000
163#define USB_DEV_CTRL_BLEN_8DWORDS 0x00030000
164#define USB_DEV_CTRL_BLEN_16DWORDS 0x00040000
165#define USB_DEV_CTRL_BLEN_32DWORDS 0x00050000
166#define USB_DEV_CTRL_BLEN_64DWORDS 0x00060000
167#define USB_DEV_CTRL_BLEN_128DWORDS 0x00070000
168#define USB_DEV_CTRL_BLEN_256DWORDS 0x00080000
169#define USB_DEV_CTRL_BLEN_512DWORDS 0x00090000
170
171/* settings of threshold length for maskThresholdLen_c field */
172#define USB_DEV_CTRL_TLEN_1DWORD 0x00000000
173#define USB_DEV_CTRL_TLEN_HALFMAXSIZE 0x01000000
174#define USB_DEV_CTRL_TLEN_4THMAXSIZE 0x02000000
175#define USB_DEV_CTRL_TLEN_8THMAXSIZE 0x03000000
176
177#define USB_DEV_CFG_HS 0x00000000
178#define USB_DEV_CFG_FS 0x00000001 /* 30 or 60MHz */
179#define USB_DEV_CFG_LS 0x00000002
180#define USB_DEV_CFG_FS_48 0x00000003 /* 48MHz */
181#define USB_DEV_CFG_REMOTE_WAKEUP 0x00000004
182#define USB_DEV_CFG_SELF_POWERED 0x00000008
183#define USB_DEV_CFG_SYNC_FRAME 0x00000010
184#define USB_DEV_CFG_PI_16BIT 0x00000000
185#define USB_DEV_CFG_PI_8BIT 0x00000020
186#define USB_DEV_CFG_UNI_DIR 0x00000000
187#define USB_DEV_CFG_BI_DIR 0x00000040
188#define USB_DEV_CFG_STAT_ACK 0x00000000
189#define USB_DEV_CFG_STAT_STALL 0x00000080
190
191/* Device Status Register and bit fields */
192#define USB_DEV_STS_MASK_CFG 0x0000000f
193#define USB_DEV_STS_MASK_IF 0x000000f0
194#define USB_DEV_STS_MASK_ALT_SET 0x00000f00
195#define USB_DEV_STS_SUSPEND_STAT 0x00001000
196#define USB_DEV_STS_MASK_SPD 0x00006000 /* Enumerated Speed */
197#define USB_DEV_STS_SPD_HS 0x00000000
198#define USB_DEV_STS_SPD_FS 0x00002000
199#define USB_DEV_STS_SPD_LS 0x00004000
200#define USB_DEV_STS_RXF_EMPTY 0x00008000
201#define USB_DEV_STS_MASK_FRM_NUM 0xfffc0000 /* SOF frame number */
202
203
204/* Device Intr Register and bit fields */
205#define USB_DEV_INTR_SET_CONFIG 0x00000001 /* set configuration cmd rcvd */
206#define USB_DEV_INTR_SET_INTERFACE 0x00000002 /* set interface command rcvd */
207#define USB_DEV_INTR_EARLY_SUSPEND 0x00000004 /* idle on usb for 3ms */
208#define USB_DEV_INTR_USB_RESET 0x00000008 /* usb bus reset req */
209#define USB_DEV_INTR_USB_SUSPEND 0x00000010 /* usb bus suspend req */
210#define USB_DEV_INTR_SOF 0x00000020 /* SOF seen on bus */
211#define USB_DEV_INTR_ENUM_DONE 0x00000040 /* usb speed enum done */
212#define USB_DEV_INTR_OTG 0x00000080 /* otg status change? */
213#define USB_DEV_INTR_BUSERR 0x00000080 /* AHB DMA error */
214
215/* EP Control Register Fields */
216#define USB_EP_CTRL_STALL 0x00000001
217#define USB_EP_CTRL_FLUSH 0x00000002 /* EP In data fifo Flush */
218#define USB_EP_CTRL_SNOOP_MODE 0x00000004 // snoop mode for out endpoint
219#define USB_EP_CTRL_PD 0x00000008 /* EP Poll Demand */
220#define USB_EP_CTRL_EPTYPE_MASK 0x00000030 // bit 5-4: endpoint types
221#define USB_EP_TYPE_CONTROL 0x00000000 // control endpoint
222#define USB_EP_TYPE_ISO 0x00000010 // isochronous endpoint
223#define USB_EP_TYPE_BULK 0x00000020 // bulk endpoint
224#define USB_EP_TYPE_INTERRUPT 0x00000030 // interrupt endpoint
225#define USB_EP_CTRL_NAK 0x00000040 /* EP NAK Status */
226#define USB_EP_CTRL_SNAK 0x00000080 /* EP Set NAK Bit */
227#define USB_EP_CTRL_CNAK 0x00000100 /* EP Clr NAK Bit */
228#define USB_EP_CTRL_ACT 0x00000400 /* EP Clr NAK Bit */
229
230/* bit fields in EP Status Register */
231#define USB_EP_STAT_OUT_RCVD 0x00000010 /* OUT token received */
232#define USB_EP_STAT_SETUP_RCVD 0x00000020 /* SETUP token received */
233#define USB_EP_STAT_IN 0x00000040 /* IN token received? */
234#define USB_EP_STAT_BNA 0x00000080 /* Buffer Not Available */
235#define USB_EP_STAT_BUFF_ERROR 0x00000100
236#define USB_EP_STAT_HERR 0x00000200 /* Host Error */
237#define USB_EP_STAT_AHB_ERROR 0x00000200
238#define USB_EP_STAT_TDC 0x00000400 /* Transmit DMA Complete */
239
240/*-------------------------*/
241/* DMA Related Definitions */
242/*-------------------------*/
243
244/* dma status */
245#define USB_DMA_DESC_BUFF_STS 0x80000000 /* Buffer Status */
246#define USB_DMA_DESC_BS_HST_RDY 0x80000000 /* Host Ready */
247#define USB_DMA_DESC_BS_DMA_DONE 0x00000000 /* DMA Done */
248#define USB_DMA_DESC_ZERO_LEN 0x40000000 /* zero length packet */
249#define USB_DMA_DESC_EARY_INTR 0x20000000 /* early interrupt */
250#define USB_DMA_DESC_RXTX_STS 0x10000000
251#define USB_DMA_DESC_RTS_SUCC 0x00000000 /* Success */
252#define USB_DMA_DESC_RTS_BUFERR 0x10000000 /* Buffer Error */
253#define USB_DMA_DESC_LAST 0x08000000
254#define USB_DMA_DESC_MASK_FRAM_NUM 0x07ff0000 // bits 26-16: frame number for iso
255#define USB_DMA_DESC_RXTX_BYTES 0x0000FFFF
256
257/* setup descriptor */
258#define SETUP_MASK_CONFIG_STAT 0x0fff0000
259#define SETUP_MASK_CONFIG_NUM 0x0f000000
260#define SETUP_MASK_IF_NUM 0x00f00000
261#define SETUP_MASK_ALT_SETNUM 0x000f0000
262
263#define EP_STATE_ALLOCATED 0x00000001
264#define EP_STATE_BUSY 0x00000002
265#define EP_STATE_ASYNC 0x00000004
266
267struct usb_dev_dma_desc {
268 int status;
269 int resv;
270 void *data_ptr;
271 void *next_desc;
272};
273
274struct usb_dev_setup_buf {
275 int status;
276 int resv;
277 int data1; /* first 4 bytes of data */
278 int data2; /* last 4 bytes of data */
279};
97 280
98struct usb_endpoint 281struct usb_endpoint
99{ 282{
100 void *buf; 283 void *buf;
101 unsigned int len; 284 unsigned int len;
102 union 285 volatile unsigned int state;
103 { 286 int rc;
104 unsigned int sent; 287 struct wakeup complete;
105 unsigned int received; 288 struct usb_dev_dma_desc *uc_desc;
106 };
107 bool wait;
108 bool busy;
109}; 289};
110 290
111static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS*2]; 291static struct usb_endpoint endpoints[USB_NUM_EPS][2];
292
293/*
294 * dma/setup descriptors and buffers should avoid sharing
295 * a cacheline with other data.
296 * dmadescs may share with each other, since we only access them uncached.
297 */
298static struct usb_dev_dma_desc dmadescs[USB_NUM_EPS][2] __attribute__((aligned(32)));
299
300static struct usb_dev_setup_buf setup_desc;
301/* Dummy buffer, to keep rx_buf out of this cacheline */
302static struct usb_dev_setup_buf dummy __attribute__((unused));
303
304static char rx_buf[1024];
305static char tx_buf[1024];
112 306
113void usb_attach(void) 307void usb_attach(void)
114{ 308{
115 usb_enable(true); 309 usb_enable(true);
116} 310}
117 311
118void usb_drv_init(void) 312static inline void usb_delay(int delay)
313{ //TUNEME : delay is in milliseconds
314 delay <<= 14;
315 while(delay--) ;
316}
317
318static void usb_phy_on(void)
319{
320 /* PHY clock */
321 CGU_USB = 1<<5 /* enable */
322 | (CLK_DIV(AS3525_PLLB_FREQ, 48000000) / 2) << 2
323 | 2; /* source = PLLB */
324
325 /* UVDD on */
326 ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) | (1<<4));
327 usb_delay(100);
328
329 /* reset */
330 CCU_SRC = CCU_SRC_USB_AHB_EN|CCU_SRC_USB_PHY_EN;
331 CCU_SRL = CCU_SRL_MAGIC_NUMBER;
332 usb_delay(1);
333 CCU_SRC = CCU_SRC_USB_AHB_EN;
334 usb_delay(1);
335 CCU_SRC = CCU_SRL = 0;
336
337 USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
338 | USB_GPIO_TX_BIT_STUFF_EN
339 | USB_GPIO_XO_ON
340 | USB_GPIO_CLK_SEL10; /* 0x06180000; */
341}
342
343static void usb_phy_suspend(void)
344{
345 USB_GPIO_CSR |= USB_GPIO_ASESSVLD_EXT |
346 USB_GPIO_BSESSVLD_EXT |
347 USB_GPIO_VBUS_VLD_EXT;
348 usb_delay(3);
349 USB_GPIO_CSR |= USB_GPIO_VBUS_VLD_EXT_SEL;
350 usb_delay(10);
351}
352
353static void usb_phy_resume(void)
354{
355 USB_GPIO_CSR &= ~(USB_GPIO_ASESSVLD_EXT |
356 USB_GPIO_BSESSVLD_EXT |
357 USB_GPIO_VBUS_VLD_EXT);
358 usb_delay(3);
359 USB_GPIO_CSR &= ~USB_GPIO_VBUS_VLD_EXT_SEL;
360 usb_delay(10);
361}
362
363static void setup_desc_init(struct usb_dev_setup_buf *desc)
364{
365 struct usb_dev_setup_buf *uc_desc = UNCACHED_ADDR(desc);
366
367 uc_desc->status = USB_DMA_DESC_BS_HST_RDY;
368 uc_desc->resv = 0xffffffff;
369 uc_desc->data1 = 0xffffffff;
370 uc_desc->data2 = 0xffffffff;
371}
372
373static void dma_desc_init(int ep, int dir)
374{
375 struct usb_dev_dma_desc *desc = &dmadescs[ep][dir];
376 struct usb_dev_dma_desc *uc_desc = UNCACHED_ADDR(desc);
377
378 endpoints[ep][dir].uc_desc = uc_desc;
379
380 if (dir == 0) {
381 uc_desc->status = USB_DMA_DESC_BS_DMA_DONE | USB_DMA_DESC_LAST | 0x40;
382 uc_desc->resv = 0xffffffff;
383 uc_desc->data_ptr = tx_buf;
384 uc_desc->next_desc = 0;
385 } else {
386 uc_desc->status = USB_DMA_DESC_BS_HST_RDY | /*USB_DMA_DESC_LAST |*/ 0x40;
387 uc_desc->resv = 0xffffffff;
388 uc_desc->data_ptr = rx_buf;
389 uc_desc->next_desc = 0;
390 }
391}
392
393static void reset_endpoints(int init)
119{ 394{
120 int i; 395 int i;
121 for(i = 0; i < USB_NUM_ENDPOINTS * 2; i++)
122 endpoints[i].busy = false;
123 396
124 ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2); 397 /*
125 ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) & ~(1<<4)); 398 * OUT EP 2 is an alias for OUT EP 0 on this HW!
399 *
400 * Resonates with "3 bidirectional- plus 1 in-endpoints in device mode"
401 * from the datasheet, but why ep2 and not ep3?
402 *
403 * Reserve it here so we will skip over it in request_endpoint().
404 */
405 endpoints[2][1].state |= EP_STATE_ALLOCATED;
406
407 for(i = 0; i < USB_NUM_EPS; i++) {
408 int mps = i == 0 ? 64 : 2048; /* For HS */
409
410 if (init) {
411 endpoints[i][0].state = 0;
412 wakeup_init(&endpoints[i][0].complete);
413
414 if (i != 2) { /* Skip the OUT EP0 alias */
415 endpoints[i][1].state = 0;
416 wakeup_init(&endpoints[i][1].complete);
417 USB_OEP_SUP_PTR(i) = 0;
418 }
419 }
126 420
127 /* PHY part */ 421 dma_desc_init(i, 0);
128 CGU_USB = 1<<5 /* enable */ 422 USB_IEP_CTRL (i) = USB_EP_CTRL_FLUSH|USB_EP_CTRL_SNAK;
129 | (CLK_DIV(AS3525_PLLA_FREQ, 48000000) / 2) << 2 423 USB_IEP_MPS (i) = mps;
130 | 1; /* source = PLLA */ 424 /* We don't care about the 'IN token received' event */
425 USB_IEP_STS_MASK(i) = USB_EP_STAT_IN; /* OF: 0x840 */
426 USB_IEP_TXFSIZE (i) = 0x20;
427 USB_IEP_STS (i) = 0xffffffff; /* clear status */
428 USB_IEP_DESC_PTR(i) = 0;
429
430 if (i != 2) { /* Skip the OUT EP0 alias */
431 dma_desc_init(i, 1);
432 USB_OEP_CTRL (i) = USB_EP_CTRL_FLUSH|USB_EP_CTRL_SNAK;
433 USB_OEP_MPS (i) = 0x08000000|mps;
434 USB_OEP_STS_MASK(i) = 0x0000; /* OF: 0x1800 */
435 USB_OEP_RXFR (i) = 0x00;
436 USB_OEP_STS (i) = 0xffffffff; /* clear status */
437 USB_OEP_DESC_PTR(i) = 0;
438 }
439 }
131 440
132 /* AHB part */ 441 setup_desc_init(&setup_desc);
133 CGU_PERI |= CGU_USB_CLOCK_ENABLE; 442 USB_OEP_SUP_PTR(0) = (int)&setup_desc;
443}
134 444
135 USB_GPIO_CSR = 0x6180000; 445void usb_drv_init(void)
136 USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */ 446{
137 USB_DEV_CTRL |= 0x400; /* soft disconnect */ 447 logf("usb_drv_init() !!!!\n");
138 448
139 /* UVDD */ 449 /* length regulator: normal operation */
140 ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) | (1<<4)); 450 ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2);
141 sleep(10); //msleep(100)
142
143 USB_GPIO_CSR = 0x6180000;
144
145 USB_GPIO_CSR |= 0x1C00000;
146 sleep(1); //msleep(3)
147 USB_GPIO_CSR |= 0x200000;
148 sleep(1); //msleep(10)
149
150 USB_DEV_CTRL |= 0x400; /* soft disconnect */
151
152 USB_GPIO_CSR &= ~0x1C00000;
153 sleep(1); //msleep(3)
154 USB_GPIO_CSR &= ~0x200000;
155 sleep(1); //msleep(10)
156 USB_DEV_CTRL &= ~0x400; /* clear soft disconnect */
157
158#if defined(SANSA_CLIP)
159 GPIOA_DIR |= (1<<6);
160 GPIOA_PIN(6) = (1<<6);
161 GPIOA_DIR &= ~(1<<6); /* restore direction for usb_detect() */
162#elif defined(SANSA_FUZE) || defined(SANSA_E200V2)
163 GPIOA_DIR |= (1<<3);
164 GPIOA_PIN(3) = (1<<3);
165 GPIOA_DIR &= ~(1<<3); /* restore direction for usb_detect() */
166#elif defined(SANSA_C200V2)
167 GPIOA_DIR |= (1<<1);
168 GPIOA_PIN(1) = (1<<1);
169 GPIOA_DIR &= ~(1<<1); /* restore direction for usb_detect() */
170#endif
171 451
172#if 0 /* linux */ 452 /* AHB part */
173 USB_DEV_CFG |= (1<<17) /* csr programming */ 453 CGU_PERI |= CGU_USB_CLOCK_ENABLE;
174 | (1<<3) /* self powered */
175 | (1<<2); /* remote wakeup */
176 454
177 USB_DEV_CFG &= ~3; /* high speed */ 455 /* reset AHB */
178#endif 456 CCU_SRC = CCU_SRC_USB_AHB_EN;
457 CCU_SRL = CCU_SRL_MAGIC_NUMBER;
458 usb_delay(1);
459 CCU_SRC = CCU_SRL = 0;
179 460
180 USB_IEP_CTRL(0) &= (3 << 4); /* control endpoint */ 461 USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
181 USB_IEP_DESC_PTR(0) = 0; 462 | USB_GPIO_TX_BIT_STUFF_EN
463 | USB_GPIO_XO_ON
464 | USB_GPIO_CLK_SEL10; /* 0x06180000; */
182 465
183 USB_OEP_CTRL(0) &= (3 << 4); /* control endpoint */ 466 /* bug workaround according to linux patch */
184 USB_OEP_DESC_PTR(0) = 0; 467 USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */
185 468
186 USB_DEV_INTR_MASK &= ~0xff; /* unmask all flags */ 469 /* enable soft disconnect */
470 USB_DEV_CTRL |= USB_DEV_CTRL_SOFT_DISCONN;
471
472 usb_phy_on();
473 usb_phy_suspend();
474 USB_DEV_CTRL |= USB_DEV_CTRL_SOFT_DISCONN;
475
476 /* We don't care about OTG or SOF events */
477 /* Right now we don't handle suspend or reset, so mask those too */
478 USB_DEV_INTR_MASK = USB_DEV_INTR_OTG |
479 USB_DEV_INTR_SOF |
480 USB_DEV_INTR_USB_SUSPEND |
481 USB_DEV_INTR_EARLY_SUSPEND;
482
483 USB_DEV_CFG = USB_DEV_CFG_STAT_ACK |
484 USB_DEV_CFG_UNI_DIR |
485 USB_DEV_CFG_PI_16BIT |
486 USB_DEV_CFG_HS |
487 USB_DEV_CFG_SELF_POWERED |
488 0x20200;
489
490 USB_DEV_CTRL = USB_DEV_CTRL_BLEN_1DWORD |
491 USB_DEV_CTRL_DESC_UPDATE |
492 USB_DEV_CTRL_THRES_ENABLE |
493 USB_DEV_CTRL_RDE |
494 0x04000000;
187 495
188 USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16)); /* ep 0 */ 496 USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16)); /* ep 0 */
189 497
498 reset_endpoints(1);
499
500 /* clear pending interrupts */
501 USB_DEV_EP_INTR = 0xffffffff;
502 USB_DEV_INTR = 0xffffffff;
503
190 VIC_INT_ENABLE = INTERRUPT_USB; 504 VIC_INT_ENABLE = INTERRUPT_USB;
191 505
192 USB_IEP_CTRL(0) |= (1<<7); /* set NAK */ 506 usb_phy_resume();
193 USB_OEP_CTRL(0) |= (1<<7); /* set NAK */ 507 USB_DEV_CTRL &= ~USB_DEV_CTRL_SOFT_DISCONN;
508
509 USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
510 | USB_GPIO_TX_BIT_STUFF_EN
511 | USB_GPIO_XO_ON
512 | USB_GPIO_HS_INTR
513 | USB_GPIO_CLK_SEL10; /* 0x06180000; */
514
194} 515}
195 516
196void usb_drv_exit(void) 517void usb_drv_exit(void)
@@ -199,72 +520,421 @@ void usb_drv_exit(void)
199 VIC_INT_EN_CLEAR = INTERRUPT_USB; 520 VIC_INT_EN_CLEAR = INTERRUPT_USB;
200 CGU_USB &= ~(1<<5); 521 CGU_USB &= ~(1<<5);
201 CGU_PERI &= ~CGU_USB_CLOCK_ENABLE; 522 CGU_PERI &= ~CGU_USB_CLOCK_ENABLE;
523 /* Disable UVDD generating LDO */
202 ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) & ~(1<<4)); 524 ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) & ~(1<<4));
525 logf("usb_drv_exit() !!!!\n");
203} 526}
204 527
205int usb_drv_port_speed(void) 528int usb_drv_port_speed(void)
206{ 529{
207 return (USB_DEV_CFG & 3) ? 0 : 1; 530 return (USB_DEV_STS & USB_DEV_STS_MASK_SPD) ? 0 : 1;
208} 531}
209 532
210int usb_drv_request_endpoint(int type, int dir) 533int usb_drv_request_endpoint(int type, int dir)
211{ 534{
212 (void) type; 535 int d = dir == USB_DIR_IN ? 0 : 1;
213 int i = dir == USB_DIR_IN ? 0 : 1; 536 int i = 1; /* skip the control EP */
214 537
215 for(; i < USB_NUM_ENDPOINTS * 2; i += 2) 538 for(; i < USB_NUM_EPS; i++) {
216 if(!endpoints[i].busy) 539 if (endpoints[i][d].state & EP_STATE_ALLOCATED)
217 { 540 continue;
218 endpoints[i].busy = true; 541
219 i >>= 1; 542 endpoints[i][d].state |= EP_STATE_ALLOCATED;
220 USB_DEV_EP_INTR_MASK &= ~((1<<i) | (1<<(16+i))); 543
221 return i | dir; 544 if (dir == USB_DIR_IN) {
545 USB_IEP_CTRL(i) = USB_EP_CTRL_FLUSH |
546 USB_EP_CTRL_SNAK |
547 USB_EP_CTRL_ACT |
548 (type << 4);
549 USB_DEV_EP_INTR_MASK &= ~(1<<i);
550 } else {
551 USB_OEP_CTRL(i) = USB_EP_CTRL_FLUSH |
552 USB_EP_CTRL_SNAK |
553 USB_EP_CTRL_ACT |
554 (type << 4);
555 USB_DEV_EP_INTR_MASK &= ~(1<<(16+i));
222 } 556 }
557 logf("usb_drv_request_endpoint(%d, %d): returning %02x\n", type, dir, i | dir);
558 return i | dir;
559 }
223 560
561 logf("usb_drv_request_endpoint(%d, %d): no free endpoint found\n", type, dir);
224 return -1; 562 return -1;
225} 563}
226 564
227void usb_drv_release_endpoint(int ep) 565void usb_drv_release_endpoint(int ep)
228{ 566{
229 int i = (ep & 0x7f) * 2; 567 int i = ep & 0x7f;
230 if(ep & USB_DIR_OUT) 568 int d = ep & USB_DIR_IN ? 0 : 1;
231 i++; 569
232 endpoints[i].busy = false; 570 if (i >= USB_NUM_EPS)
233 USB_DEV_EP_INTR_MASK |= (1<<ep) | (1<<(16+ep)); 571 return;
572 /*
573 * Check for control EP and ignore it.
574 * Unfortunately the usb core calls
575 * usb_drv_release_endpoint() for ep=0..(USB_NUM_ENDPOINTS-1),
576 * but doesn't request a new control EP after that...
577 */
578 if (i == 0 || /* Don't mask control EP */
579 (i == 2 && d == 1)) /* See reset_endpoints(), EP2_OUT == EP0_OUT */
580 return;
581
582 if (!(endpoints[i][d].state & EP_STATE_ALLOCATED))
583 return;
584
585 logf("usb_drv_release_endpoint(%d, %d)\n", i, d);
586 endpoints[i][d].state = 0;
587 USB_DEV_EP_INTR_MASK |= (1<<(16*d+i));
588 USB_EP_CTRL(i, !d) = USB_EP_CTRL_FLUSH | USB_EP_CTRL_SNAK;
234} 589}
235 590
236void usb_drv_cancel_all_transfers(void) 591void usb_drv_cancel_all_transfers(void)
237{ 592{
593 logf("usb_drv_cancel_all_transfers()\n");
594 return;
595
596 int flags = disable_irq_save();
597 reset_endpoints(0);
598 restore_irq(flags);
599}
600
601static void *virt_to_bus(void *addr)
602{
603 unsigned int x = (long)addr;
604
605 x -= (x & 0x40000000) >> 2; /* fix uncached address */
606
607 if (x >= IRAM_ORIG) { /* iram address */
608 x -= IRAM_ORIG;
609 }
610
611 return (void*)x;
238} 612}
239 613
240int usb_drv_recv(int ep, void *ptr, int len) 614int usb_drv_recv(int ep, void *ptr, int len)
241{ 615{
242 (void)ep;(void)ptr;(void)len; 616 struct usb_dev_dma_desc *uc_desc = endpoints[ep][1].uc_desc;
243 if(ep >= 2) 617
244 return -1; 618 ep &= 0x7f;
619 logf("usb_drv_recv(%d,%x,%d)\n", ep, (int)ptr, len);
620
621 if ((int)ptr & 31) {
622 logf("addr %08x not aligned!\n", (int)ptr);
623 }
624
625 endpoints[ep][1].state |= EP_STATE_BUSY;
626 endpoints[ep][1].len = len;
627 endpoints[ep][1].rc = -1;
628
629 /* remove data buffer from cache */
630 invalidate_dcache();
631 /* DMA setup */
632 uc_desc->status = USB_DMA_DESC_BS_HST_RDY |
633 USB_DMA_DESC_LAST |
634 len;
635 if (len == 0) {
636 uc_desc->status |= USB_DMA_DESC_ZERO_LEN;
637 uc_desc->data_ptr = 0;
638 } else {
639 uc_desc->data_ptr = virt_to_bus(ptr);
640 }
641 USB_OEP_DESC_PTR(ep) = (int)&dmadescs[ep][1];
642 USB_OEP_STS(ep) = USB_EP_STAT_OUT_RCVD; /* clear status */
643 USB_OEP_CTRL(ep) |= USB_EP_CTRL_CNAK;
644
645 return 0;
646}
245 647
246 return -1; 648#if defined(LOGF_ENABLE)
649static char hexbuf[1025];
650static char hextab[16] = "0123456789abcdef";
651
652char *make_hex(char *data, int len)
653{
654 int i;
655 if (!((int)data & 0x40000000))
656 data = UNCACHED_ADDR(data); /* don't pollute the cache */
657
658 if (len > 512)
659 len = 512;
660
661 for (i=0; i<len; i++) {
662 hexbuf[2*i ] = hextab[(unsigned char)data[i] >> 4 ];
663 hexbuf[2*i+1] = hextab[(unsigned char)data[i] & 0xf];
664 }
665 hexbuf[2*i] = 0;
666
667 return hexbuf;
668}
669#endif
670
671void ep_send(int ep, void *ptr, int len)
672{
673 struct usb_dev_dma_desc *uc_desc = endpoints[ep][0].uc_desc;
674 int i;
675
676 endpoints[ep][0].state |= EP_STATE_BUSY;
677 endpoints[ep][0].len = len;
678 endpoints[ep][0].rc = -1;
679
680 USB_IEP_CTRL(ep) |= USB_EP_CTRL_CNAK;
681
682 /* TEST: delay a little here */
683 for (i=0; i<1000; i++) asm volatile ("nop\n");
684
685 /* Make sure data is committed to memory */
686 clean_dcache();
687
688 logf("xx%s\n", make_hex(ptr, len));
689
690 uc_desc->status = USB_DMA_DESC_BS_HST_RDY |
691 USB_DMA_DESC_LAST |
692 len;
693 if (len == 0)
694 uc_desc->status |= USB_DMA_DESC_ZERO_LEN;
695
696 uc_desc->data_ptr = virt_to_bus(ptr);
697
698 USB_IEP_CTRL(ep) |= USB_EP_CTRL_FLUSH;
699 USB_IEP_DESC_PTR(ep) = (int)&dmadescs[ep][0];
700 USB_IEP_STS(ep) = 0xffffffff; /* clear status */
701 /* start transfer */
702 USB_IEP_CTRL(ep) |= USB_EP_CTRL_PD;
247} 703}
248 704
249int usb_drv_send(int ep, void *ptr, int len) 705int usb_drv_send(int ep, void *ptr, int len)
250{ 706{
251 (void)ep;(void)ptr;(void)len; 707 logf("usb_drv_send(%d,%x,%d): ", ep, (int)ptr, len);
252 if(ep >= 2)
253 return -1;
254 708
255 return -1; 709 ep &= 0x7f;
710 ep_send(ep, ptr, len);
711 while (endpoints[ep][0].state & EP_STATE_BUSY)
712 wakeup_wait(&endpoints[ep][0].complete, TIMEOUT_BLOCK);
713
714 return endpoints[ep][0].rc;
256} 715}
257 716
258int usb_drv_send_nonblocking(int ep, void *ptr, int len) 717int usb_drv_send_nonblocking(int ep, void *ptr, int len)
259{ 718{
260 /* TODO */ 719 logf("usb_drv_send_nonblocking(%d,%x,%d): ", ep, (int)ptr, len);
261 return usb_drv_send(ep, ptr, len); 720 ep &= 0x7f;
721 endpoints[ep][0].state |= EP_STATE_ASYNC;
722 ep_send(ep, ptr, len);
723 return 0;
724}
725
726static void handle_in_ep(int ep)
727{
728 int ep_sts = USB_IEP_STS(ep) & ~USB_IEP_STS_MASK(ep);
729
730 if (ep > 3)
731 panicf("in_ep > 3?!");
732
733 USB_IEP_STS(ep) = ep_sts; /* ack */
734
735 if (ep_sts & USB_EP_STAT_TDC) {
736 ep_sts &= ~USB_EP_STAT_TDC;
737 /* OF does SNAK and FLUSH at once here */
738 USB_IEP_CTRL(ep) |= USB_EP_CTRL_SNAK | USB_EP_CTRL_FLUSH;
739 endpoints[ep][0].state &= ~EP_STATE_BUSY;
740 endpoints[ep][0].rc = 0;
741 logf("EP%d %stx done len %x stat %08x\n",
742 ep, endpoints[ep][0].state & EP_STATE_ASYNC ? "async " :"",
743 endpoints[ep][0].len,
744 endpoints[ep][0].uc_desc->status);
745 if (endpoints[ep][0].state & EP_STATE_ASYNC) {
746 endpoints[ep][0].state &= ~EP_STATE_ASYNC;
747 usb_core_transfer_complete(ep, USB_DIR_IN, 0, endpoints[ep][0].len);
748 } else {
749 wakeup_signal(&endpoints[ep][0].complete);
750 }
751 }
752
753 if (ep_sts) {
754 logf("ep%d IN, hwstat %lx, epstat %x\n", ep, USB_IEP_STS(ep), endpoints[ep][0].state);
755 panicf("ep%d IN 0x%x", ep, ep_sts);
756 }
757
758 /* HW automatically disables RDE, re-enable it */
759 /* But this an IN ep, I wonder... */
760 USB_DEV_CTRL |= USB_DEV_CTRL_RDE;
761}
762
763static void handle_out_ep(int ep)
764{
765 struct usb_ctrlrequest *req = (void*)UNCACHED_ADDR(&setup_desc.data1);
766 int ep_sts = USB_OEP_STS(ep) & ~USB_OEP_STS_MASK(ep);
767 struct usb_dev_dma_desc *uc_desc = endpoints[ep][1].uc_desc;
768
769 if (ep > 3)
770 panicf("out_ep > 3!?");
771
772 USB_OEP_STS(ep) = ep_sts; /* ACK */
773
774 if (ep_sts & USB_EP_STAT_BNA) { /* Buffer was not set up */
775 logf("ep%d OUT, status %x (BNA)\n", ep, ep_sts);
776 panicf("ep%d OUT 0x%x (BNA)", ep, ep_sts);
777 }
778
779 if (ep_sts & USB_EP_STAT_OUT_RCVD) {
780 int dma_sts = uc_desc->status;
781 int dma_len = dma_sts & 0xffff;
782 int dma_frm = (dma_sts >> 16) & 0x7ff;
783 int dma_mst = dma_sts & 0xf8000000;
784
785 uc_desc->status = USB_DMA_DESC_BS_HST_RDY |
786 USB_DMA_DESC_LAST |
787 0x40;
788 uc_desc->data_ptr = rx_buf;
789 USB_OEP_DESC_PTR(ep) = (int)&dmadescs[ep][1];
790
791 if (!(dma_sts & USB_DMA_DESC_ZERO_LEN)) {
792 logf("EP%d OUT token, st:%08x len:%d frm:%x data=%s\n", ep,
793 dma_mst, dma_len, dma_frm, make_hex(uc_desc->data_ptr, dma_len));
794 /*
795 * If parts of the just dmaed range are in cache, dump them now.
796 */
797 dump_dcache_range(uc_desc->data_ptr, dma_len);
798 } else{
799 logf("EP%d OUT token, st:%08x len:%d frm:%x\n", ep,
800 dma_mst, dma_len, dma_frm);
801 }
802
803 if (endpoints[ep][1].state & EP_STATE_BUSY) {
804 endpoints[ep][1].state &= ~EP_STATE_BUSY;
805 endpoints[ep][1].rc = 0;
806 usb_core_transfer_complete(ep, 0, 0, endpoints[ep][0].len);
807 } else {
808 logf("EP%d OUT, but no one was listening?\n", ep);
809 }
810
811 USB_OEP_CTRL(ep) |= USB_EP_CTRL_SNAK; /* make sure NAK is set */
812
813 ep_sts &= ~USB_EP_STAT_OUT_RCVD;
814 }
815
816 if (ep_sts & USB_EP_STAT_SETUP_RCVD) {
817 static struct usb_ctrlrequest req_copy;
818
819 req_copy = *req;
820 logf("t%ld:got SETUP packet: type=%d req=%d val=%d ind=%d len=%d\n",
821 current_tick,
822 req->bRequestType,
823 req->bRequest,
824 req->wValue,
825 req->wIndex,
826 req->wLength);
827
828 usb_core_control_request(&req_copy);
829 setup_desc_init(&setup_desc);
830
831 ep_sts &= ~USB_EP_STAT_SETUP_RCVD;
832 }
833
834 if (ep_sts) {
835 logf("ep%d OUT, status %x\n", ep, ep_sts);
836 panicf("ep%d OUT 0x%x", ep, ep_sts);
837 }
838
839 /* HW automatically disables RDE, re-enable it */
840 /* THEORY: Because we only set up one DMA buffer... */
841 USB_DEV_CTRL |= USB_DEV_CTRL_RDE;
262} 842}
263 843
264/* interrupt service routine */ 844/* interrupt service routine */
265void INT_USB(void) 845void INT_USB(void)
266{ 846{
267 panicf("USB interrupt !"); 847 int ep = USB_DEV_EP_INTR & ~USB_DEV_EP_INTR_MASK;
848 int intr = USB_DEV_INTR & ~USB_DEV_INTR_MASK;
849
850 /* ACK interrupt sources */
851 USB_DEV_EP_INTR = ep;
852 USB_DEV_INTR = intr;
853
854 /* Handle endpoint interrupts */
855 while (ep) {
856 int onebit = 31-__builtin_clz(ep);
857
858 if (onebit < 16) handle_in_ep(onebit);
859 else handle_out_ep(onebit-16);
860
861 ep &= ~(1 << onebit);
862 }
863
864 /* Handle general device interrupts */
865 if (intr) {
866 if (intr & USB_DEV_INTR_SET_INTERFACE) {/* SET_INTERFACE received */
867 logf("set interface\n");
868 panicf("set interface");
869 intr &= ~USB_DEV_INTR_SET_INTERFACE;
870 }
871 if (intr & USB_DEV_INTR_SET_CONFIG) {/* SET_CONFIGURATION received */
872 /*
873 * This is handled in HW, we have to fake a request here
874 * for usb_core.
875 */
876 static struct usb_ctrlrequest set_config = {
877 bRequestType: USB_TYPE_STANDARD | USB_RECIP_DEVICE,
878 bRequest: USB_REQ_SET_CONFIGURATION,
879 wValue: 0,
880 wIndex: 0,
881 wLength: 0,
882 };
883
884 logf("set config\n");
885
886 set_config.wValue = USB_DEV_STS & USB_DEV_STS_MASK_CFG;
887 usb_core_control_request(&set_config);
888
889 /* Tell the HW we handled the request */
890 USB_DEV_CTRL |= USB_DEV_CTRL_APCSR_DONE;
891 intr &= ~USB_DEV_INTR_SET_CONFIG;
892 }
893 if (intr & USB_DEV_INTR_EARLY_SUSPEND) {/* idle >3ms detected */
894 logf("usb idle\n");
895 intr &= ~USB_DEV_INTR_EARLY_SUSPEND;
896 }
897 if (intr & USB_DEV_INTR_USB_RESET) {/* usb reset from host? */
898 logf("usb reset\n");
899 reset_endpoints(1);
900 usb_core_bus_reset();
901 intr &= ~USB_DEV_INTR_USB_RESET;
902 }
903 if (intr & USB_DEV_INTR_USB_SUSPEND) {/* suspend req from host? */
904 logf("usb suspend\n");
905 intr &= ~USB_DEV_INTR_USB_SUSPEND;
906 }
907 if (intr & USB_DEV_INTR_SOF) {/* sof received */
908 logf("sof\n");
909 intr &= ~USB_DEV_INTR_SOF;
910 }
911 if (intr & USB_DEV_INTR_ENUM_DONE) {/* speed enumeration complete */
912 int spd = USB_DEV_STS & USB_DEV_STS_MASK_SPD; /* Enumerated Speed */
913
914 logf("speed enum complete: ");
915 if (spd == USB_DEV_STS_SPD_HS) logf("hs\n");
916 if (spd == USB_DEV_STS_SPD_FS) logf("fs\n");
917 if (spd == USB_DEV_STS_SPD_LS) logf("ls\n");
918
919 USB_PHY_EP0_INFO = 0x00200000;
920 USB_DEV_CTRL |= USB_DEV_CTRL_APCSR_DONE;
921 USB_IEP_CTRL(0) |= USB_EP_CTRL_ACT;
922 USB_OEP_CTRL(0) |= USB_EP_CTRL_ACT;
923 intr &= ~USB_DEV_INTR_ENUM_DONE;
924 }
925 if (intr & USB_DEV_INTR_BUSERR) {
926 panicf("usb dma bus error");
927 intr &= ~USB_DEV_INTR_BUSERR;
928 }
929 if (intr)
930 panicf("usb devirq 0x%x", intr);
931 }
932
933 if (!(USB_DEV_CTRL & USB_DEV_CTRL_RDE)){
934 logf("re-enabling receive DMA\n");
935 USB_DEV_CTRL |= USB_DEV_CTRL_RDE;
936 }
937
268} 938}
269 939
270/* (not essential? , not implemented in usb-tcc.c) */ 940/* (not essential? , not implemented in usb-tcc.c) */
@@ -273,6 +943,7 @@ void usb_drv_set_test_mode(int mode)
273 (void)mode; 943 (void)mode;
274} 944}
275 945
946/* handled internally by controller */
276void usb_drv_set_address(int address) 947void usb_drv_set_address(int address)
277{ 948{
278 (void)address; 949 (void)address;
@@ -280,12 +951,11 @@ void usb_drv_set_address(int address)
280 951
281void usb_drv_stall(int ep, bool stall, bool in) 952void usb_drv_stall(int ep, bool stall, bool in)
282{ 953{
283 (void)ep;(void)stall;(void)in; 954 if (stall) USB_EP_CTRL(ep, in) |= USB_EP_CTRL_STALL;
955 else USB_EP_CTRL(ep, in) &= ~USB_EP_CTRL_STALL;
284} 956}
285 957
286bool usb_drv_stalled(int ep, bool in) 958bool usb_drv_stalled(int ep, bool in)
287{ 959{
288 (void)ep;(void)in; 960 return USB_EP_CTRL(ep, in) & USB_EP_CTRL_STALL ? true : false;
289 return true;
290} 961}
291