1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
diff --git a/firmware/SOURCES b/firmware/SOURCES
index f5ee787..fbb2474 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -393,7 +393,7 @@ target/arm/usb-drv-arc.c
 #elif CONFIG_USBOTG == USBOTG_AS3525
 target/arm/as3525/usb-drv-as3525.c
 #elif CONFIG_USBOTG == USBOTG_AS3525v2
-target/arm/as3525/usb-drv-as3525v2.c
+target/arm/usb-s3c6400x.c
 #elif CONFIG_USBOTG == USBOTG_ISP1583
 drivers/isp1583.c
 #elif CONFIG_USBOTG == USBOTG_RK27XX
diff --git a/firmware/export/config/sansaclipzip.h b/firmware/export/config/sansaclipzip.h
index e0f39af..1eaa67f 100644
--- a/firmware/export/config/sansaclipzip.h
+++ b/firmware/export/config/sansaclipzip.h
@@ -182,8 +182,7 @@
 
 /* enable these for the experimental usb stack */
 #define HAVE_USBSTACK
-#define USB_HANDLED_BY_OF
-//#define USE_ROCKBOX_USB
+#define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x0781
 #define USB_PRODUCT_ID 0x74e5
 
diff --git a/firmware/export/usb-s3c6400x.h b/firmware/export/usb-s3c6400x.h
index eeac9d0..5e5a84a 100644
--- a/firmware/export/usb-s3c6400x.h
+++ b/firmware/export/usb-s3c6400x.h
@@ -34,6 +34,9 @@
 
 /*** OTG LINK CORE REGISTERS ***/
 /* Core Global Registers */
+#ifndef OTGBASE
+#define OTGBASE USB_BASE
+#endif
 #define GOTGCTL     (*((uint32_t volatile*)(OTGBASE + 0x000)))
 #define GOTGINT     (*((uint32_t volatile*)(OTGBASE + 0x004)))
 #define GAHBCFG     (*((uint32_t volatile*)(OTGBASE + 0x008)))
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c
index 4476549..b076a07 100644
--- a/firmware/target/arm/usb-s3c6400x.c
+++ b/firmware/target/arm/usb-s3c6400x.c
@@ -60,7 +60,7 @@ static struct
 {
     struct usb_ctrlrequest header; /* 8 bytes */
     unsigned char payload[64 - sizeof(struct usb_ctrlrequest)];
-} ctrlreq USB_DEVBSS_ATTR;
+} ctrlreq_ USB_DEVBSS_ATTR, *ctrlreq =  AS3525_UNCACHED_ADDR(&ctrlreq_);
 
 int usb_drv_port_speed(void)
 {
@@ -82,7 +82,7 @@ static void reset_endpoints(int reinit)
     DOEPCTL0 = 0x8000;  /* EP0 OUT ACTIVE */
     DOEPTSIZ0 = 0x20080040;  /* EP0 OUT Transfer Size:
                                 64 Bytes, 1 Packet, 1 Setup Packet */
-    DOEPDMA0 = &ctrlreq;
+    DOEPDMA0 = AS3525_PHYSICAL_ADDR(&ctrlreq_);
     DOEPCTL0 |= 0x84000000;  /* EP0 OUT ENABLE CLEARNAK */
     if (reinit)
     {
@@ -142,10 +142,21 @@ void usb_drv_release_endpoint(int ep)
     endpoints[ep].active = false;
 }
 
-static void usb_reset(void)
+static inline void usb_delay(void)
 {
-    DCTL = 0x802;  /* Soft Disconnect */
+    register int i = 0;
+    asm volatile(
+        "1: nop             \n"
+        "   add %0, %0, #1  \n"
+        "   cmp %0, #0x300  \n"
+        "   bne 1b          \n"
+        : "+r"(i)
+    );
+}
 
+static void usb_reset(void)
+{
+#if 0
     OPHYPWR = 0;  /* PHY: Power up */
     udelay(10);
     OPHYUNK1 = 1;
@@ -154,8 +165,62 @@ static void usb_reset(void)
     udelay(10);
     ORSTCON = 0;  /* PHY: Deassert Software Reset */
     OPHYUNK3 = 0x600;
-    OPHYCLK = SYNOPSYSOTG_CLOCK;
+    OPHYCLK = 0;
     udelay(400);
+#else
+    /* 1) enable usb core clock */
+    bitset32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
+    usb_delay();
+    /* 2) enable usb phy clock */
+    CCU_USB = (CCU_USB & ~(3<<24)) | (1 << 24); /* ?? */
+    /* PHY clock */
+    CGU_USB = 1<<5  /* enable */
+        | 0 << 2
+        | 0; /* source = ? (24MHz crystal?) */
+    usb_delay();
+    /* 3) clear "stop pclk" */
+    PCGCCTL &= ~0x1;
+    usb_delay();
+    /* 4) clear "power clamp" */
+    PCGCCTL &= ~0x4;
+    usb_delay();
+    /* 5) clear "reset power down module" */
+    PCGCCTL &= ~0x8;
+    usb_delay();
+    /* 6) set "power on program done" */
+#define DCTL_pwronprgdone   (1 << 11) /** Power on Program Done ? */
+    DCTL |= DCTL_pwronprgdone;
+    usb_delay();
+    /* 7) core soft reset */
+#define GRSTCTL_csftrst         (1 << 0) /** Core soft reset */
+#define GRSTCTL_hsftrst         (1 << 1) /** Hclk soft reset */
+
+    GRSTCTL |= GRSTCTL_csftrst;
+    usb_delay();
+    /* 8) hclk soft reset */
+    GRSTCTL |= GRSTCTL_hsftrst;
+    usb_delay();
+    /* 9) flush and reset everything */
+    GRSTCTL |= 0x3f;
+    usb_delay();
+    /* 10) force device mode*/
+#define GUSBCFG_force_host_mode         (1 << 29)
+#define GUSBCFG_force_device_mode       (1 << 30)
+
+    GUSBCFG &= ~GUSBCFG_force_host_mode;
+    GUSBCFG |= GUSBCFG_force_device_mode;
+    usb_delay();
+    /* 11) Do something that is probably CCU related but undocumented*/
+    CCU_USB |= 0x1000;
+    CCU_USB &= ~0x300000;
+    usb_delay();
+    /* 12) reset usb core parameters (dev addr, speed, ...) */
+    DCFG = 0;
+    usb_delay();
+#endif
+
+
+    DCTL = 0x802;  /* Soft Disconnect */
 
     GRSTCTL = 1;  /* OTG: Assert Software Reset */
     while (GRSTCTL & 1);  /* Wait for OTG to ack reset */
@@ -163,7 +228,20 @@ static void usb_reset(void)
 
     GRXFSIZ = 0x00000200;  /* RX FIFO: 512 bytes */
     GNPTXFSIZ = 0x02000200;  /* Non-periodic TX FIFO: 512 bytes */
-    GAHBCFG = SYNOPSYSOTG_AHBCFG;
+
+#define GAHBCFG_glblintrmsk             (1 << 0) /** Global interrupt mask */
+#define GAHBCFG_hburstlen_bitp          1
+#define GAHBCFG_hburstlen_bits          0xf
+#define GAHBCFG_INT_DMA_BURST_SINGLE    0
+#define GAHBCFG_INT_DMA_BURST_INCR      1 /** note: the linux patch has several other value, this is one picked for internal dma */
+#define GAHBCFG_INT_DMA_BURST_INCR4     3
+#define GAHBCFG_INT_DMA_BURST_INCR8     5
+#define GAHBCFG_INT_DMA_BURST_INCR16    7
+#define GAHBCFG_dma_enable              (1 << 5) /** Enable DMA */
+
+    GAHBCFG = (GAHBCFG_INT_DMA_BURST_INCR << GAHBCFG_hburstlen_bitp)
+        | GAHBCFG_dma_enable;
+
     GUSBCFG = 0x1408;  /* OTG: 16bit PHY and some reserved bits */
 
     DCFG = 4;  /* Address 0 */
@@ -177,7 +255,7 @@ static void usb_reset(void)
 }
 
 /* IRQ handler */
-void INT_USB_FUNC(void)
+void INT_USB(void)
 {
     int i;
     uint32_t ints = GINTSTS;
@@ -255,14 +333,14 @@ void INT_USB_FUNC(void)
                     invalidate_dcache();
                     if (i == 0)
                     {
-                        if (ctrlreq.header.bRequest == 5)
+                        if (ctrlreq->header.bRequest == 5)
                         {
                             /* Already set the new address here,
                                before passing the packet to the core.
                                See below (usb_drv_set_address) for details. */
-                            DCFG = (DCFG & ~0x7F0) | (ctrlreq.header.wValue << 4);
+                            DCFG = (DCFG & ~0x7F0) | (ctrlreq->header.wValue << 4);
                         }
-                        usb_core_control_request(&ctrlreq.header);
+                        usb_core_control_request(&ctrlreq->header);
                     }
                     else panicf("USB: SETUP done on OUT EP%d!?", i);
                 }
@@ -270,7 +348,7 @@ void INT_USB_FUNC(void)
                 if (!i)
                 {
                     DOEPTSIZ0 = 0x20080040;
-                    DOEPDMA0 = &ctrlreq;
+                    DOEPDMA0 = AS3525_PHYSICAL_ADDR(&ctrlreq_);
                     DOEPCTL0 |= 0x84000000;
                 }
                 DOEPINT(i) = epints;
@@ -320,12 +398,12 @@ static void ep_recv(int ep, void *ptr, int length)
     if (!length)
     {
         DOEPTSIZ(ep) = 1 << 19;  /* one empty packet */
-        DOEPDMA(ep) = NULL;
+        DOEPDMA(ep) = (void*)0x10000000;
     }
     else
     {
         DOEPTSIZ(ep) = length | (packets << 19);
-        DOEPDMA(ep) = ptr;
+        DOEPDMA(ep) = AS3525_PHYSICAL_ADDR(ptr);
     }
     clean_dcache();
     DOEPCTL(ep) |= 0x84000000;  /* EPx OUT ENABLE CLEARNAK */
@@ -387,6 +465,7 @@ void usb_drv_stall(int endpoint, bool stall, bool in)
 
 void usb_drv_init(void)
 {
+    cpu_boost(1);
     /* Enable USB clock */
 #if CONFIG_CPU==S5L8701
     PWRCON &= ~0x4000;
@@ -397,7 +476,7 @@ void usb_drv_init(void)
     PWRCON(1) &= ~0x8;
     VIC0INTENABLE |= 1 << 19;
 #endif
-    PCGCCTL = 0;
+    //PCGCCTL = 0;
 
     /* reset the beast */
     usb_reset();
@@ -407,11 +486,18 @@ void usb_drv_exit(void)
 {
     DCTL = 0x802;  /* Soft Disconnect */
 
+#if 0
     OPHYPWR = 0xF;  /* PHY: Power down */
     udelay(10);
     ORSTCON = 7;  /* Put the PHY into reset (needed to get current down) */
     udelay(10);
     PCGCCTL = 1;  /* Shut down PHY clock */
+#else
+    /* Disable clock */
+    CGU_USB = 0;
+    bitclr32(&CGU_PERI, CGU_USB_CLOCK_ENABLE);
+    cpu_boost(1);
+#endif
     
 #if CONFIG_CPU==S5L8701
     PWRCON |= 0x4000;
@@ -444,25 +530,13 @@ void usb_init_device(void)
     usb_drv_exit();
 }
 
-void usb_enable(bool on)
-{
-    if (on) usb_core_init();
-    else usb_core_exit();
-}
-
 void usb_attach(void)
 {
     usb_enable(true);
 }
 
-int usb_detect(void)
-{
-    if (charger_inserted())
-        return USB_INSERTED;
-    return USB_EXTRACTED;
-}
-
 #else
+#error LOL
 void usb_init_device(void)
 {
     DCTL = 0x802;  /* Soft Disconnect */
diff --git a/rbutil/mkamsboot/dualboot/dualboot.S b/rbutil/mkamsboot/dualboot/dualboot.S
index fae13df..773c5cc 100644
--- a/rbutil/mkamsboot/dualboot/dualboot.S
+++ b/rbutil/mkamsboot/dualboot/dualboot.S
@@ -273,7 +273,7 @@ uclcopy:
         #error No target-specific key check defined!
 #endif
 
-#if defined(SANSA_CLIPPLUS) || defined(SANSA_FUZEV2)
+#if defined(SANSA_CLIPPLUS)
         /* Check for USB after buttons because I trust more the GPIO code than
          * the i2c code.
          * Also it seems we need to wait a bit before detecting USB connection