summaryrefslogtreecommitdiff
path: root/utils/imxtools/hwemul/dev/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/imxtools/hwemul/dev/main.c')
-rw-r--r--utils/imxtools/hwemul/dev/main.c1512
1 files changed, 1512 insertions, 0 deletions
diff --git a/utils/imxtools/hwemul/dev/main.c b/utils/imxtools/hwemul/dev/main.c
new file mode 100644
index 0000000000..3a4d8620c0
--- /dev/null
+++ b/utils/imxtools/hwemul/dev/main.c
@@ -0,0 +1,1512 @@
1#include "stddef.h"
2#include "protocol.h"
3#include "logf.h"
4#include "usb_ch9.h"
5
6extern unsigned char oc_codestart[];
7extern unsigned char oc_codeend[];
8extern unsigned char oc_stackstart[];
9extern unsigned char oc_stackend[];
10extern unsigned char oc_bufferstart[];
11extern unsigned char oc_bufferend[];
12
13#define oc_codesize ((size_t)(oc_codeend - oc_codestart))
14#define oc_stacksize ((size_t)(oc_stackend - oc_stackstart))
15#define oc_buffersize ((size_t)(oc_bufferend - oc_bufferstart))
16
17/**
18 *
19 * Common
20 *
21 */
22#define MIN(a,b) ((a) < (b) ? (a) : (b))
23
24#define __REG_SET(reg) (*((volatile uint32_t *)(&reg + 1)))
25#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2)))
26#define __REG_TOG(reg) (*((volatile uint32_t *)(&reg + 3)))
27
28#define __BLOCK_SFTRST (1 << 31)
29#define __BLOCK_CLKGATE (1 << 30)
30
31#define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP)
32#define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP)
33#define __FIELD_SET(reg, field, val) reg = (reg & ~reg##__##field##_BM) | (val << reg##__##field##_BP)
34
35/**
36 *
37 * Pin control
38 *
39 */
40
41#define HW_PINCTRL_BASE 0x80018000
42
43#define HW_PINCTRL_CTRL (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x0))
44#define HW_PINCTRL_MUXSEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x100 + (i) * 0x10))
45#define HW_PINCTRL_DRIVE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x200 + (i) * 0x10))
46#ifdef HAVE_STMP3700
47#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x300 + (i) * 0x10))
48#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
49#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
50#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
51#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
52#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
53#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
54#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
55#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
56#else
57#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
58#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
59#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
60#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
61#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
62#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
63#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
64#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
65#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xc00 + (i) * 0x10))
66#endif
67
68#define PINCTRL_FUNCTION_MAIN 0
69#define PINCTRL_FUNCTION_ALT1 1
70#define PINCTRL_FUNCTION_ALT2 2
71#define PINCTRL_FUNCTION_GPIO 3
72
73#define PINCTRL_DRIVE_4mA 0
74#define PINCTRL_DRIVE_8mA 1
75#define PINCTRL_DRIVE_12mA 2
76#define PINCTRL_DRIVE_16mA 3 /* not available on all pins */
77
78typedef void (*pin_irq_cb_t)(int bank, int pin);
79
80static inline void imx233_pinctrl_init(void)
81{
82 __REG_CLR(HW_PINCTRL_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
83}
84
85static inline void imx233_set_pin_drive_strength(unsigned bank, unsigned pin, unsigned strength)
86{
87 __REG_CLR(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = 3 << (4 * (pin % 8));
88 __REG_SET(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = strength << (4 * (pin % 8));
89}
90
91static inline void imx233_enable_gpio_output(unsigned bank, unsigned pin, bool enable)
92{
93 if(enable)
94 __REG_SET(HW_PINCTRL_DOE(bank)) = 1 << pin;
95 else
96 __REG_CLR(HW_PINCTRL_DOE(bank)) = 1 << pin;
97}
98
99static inline void imx233_enable_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool enable)
100{
101 if(enable)
102 __REG_SET(HW_PINCTRL_DOE(bank)) = pin_mask;
103 else
104 __REG_CLR(HW_PINCTRL_DOE(bank)) = pin_mask;
105}
106
107static inline void imx233_set_gpio_output(unsigned bank, unsigned pin, bool value)
108{
109 if(value)
110 __REG_SET(HW_PINCTRL_DOUT(bank)) = 1 << pin;
111 else
112 __REG_CLR(HW_PINCTRL_DOUT(bank)) = 1 << pin;
113}
114
115static inline void imx233_set_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool value)
116{
117 if(value)
118 __REG_SET(HW_PINCTRL_DOUT(bank)) = pin_mask;
119 else
120 __REG_CLR(HW_PINCTRL_DOUT(bank)) = pin_mask;
121}
122
123static inline uint32_t imx233_get_gpio_input_mask(unsigned bank, uint32_t pin_mask)
124{
125 return HW_PINCTRL_DIN(bank) & pin_mask;
126}
127
128static inline void imx233_set_pin_function(unsigned bank, unsigned pin, unsigned function)
129{
130 __REG_CLR(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = 3 << (2 * (pin % 16));
131 __REG_SET(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = function << (2 * (pin % 16));
132}
133
134static inline void imx233_enable_pin_pullup(unsigned bank, unsigned pin, bool enable)
135{
136 if(enable)
137 __REG_SET(HW_PINCTRL_PULL(bank)) = 1 << pin;
138 else
139 __REG_CLR(HW_PINCTRL_PULL(bank)) = 1 << pin;
140}
141
142static inline void imx233_enable_pin_pullup_mask(unsigned bank, uint32_t pin_msk, bool enable)
143{
144 if(enable)
145 __REG_SET(HW_PINCTRL_PULL(bank)) = pin_msk;
146 else
147 __REG_CLR(HW_PINCTRL_PULL(bank)) = pin_msk;
148}
149
150/**
151 *
152 * USB subsystem
153 *
154 */
155
156#define USB_BASE 0x80080000
157#define USB_NUM_ENDPOINTS 2
158#define MAX_PKT_SIZE 1024
159#define MAX_PKT_SIZE_EP0 64
160
161/* USB device mode registers (Little Endian) */
162#define REG_USBCMD (*(volatile unsigned int *)(USB_BASE+0x140))
163#define REG_DEVICEADDR (*(volatile unsigned int *)(USB_BASE+0x154))
164#define REG_ENDPOINTLISTADDR (*(volatile unsigned int *)(USB_BASE+0x158))
165#define REG_PORTSC1 (*(volatile unsigned int *)(USB_BASE+0x184))
166#define REG_USBMODE (*(volatile unsigned int *)(USB_BASE+0x1a8))
167#define REG_ENDPTSETUPSTAT (*(volatile unsigned int *)(USB_BASE+0x1ac))
168#define REG_ENDPTPRIME (*(volatile unsigned int *)(USB_BASE+0x1b0))
169#define REG_ENDPTSTATUS (*(volatile unsigned int *)(USB_BASE+0x1b8))
170#define REG_ENDPTCOMPLETE (*(volatile unsigned int *)(USB_BASE+0x1bc))
171#define REG_ENDPTCTRL0 (*(volatile unsigned int *)(USB_BASE+0x1c0))
172#define REG_ENDPTCTRL1 (*(volatile unsigned int *)(USB_BASE+0x1c4))
173#define REG_ENDPTCTRL2 (*(volatile unsigned int *)(USB_BASE+0x1c8))
174#define REG_ENDPTCTRL(_x_) (*(volatile unsigned int *)(USB_BASE+0x1c0+4*(_x_)))
175
176/* USB CMD Register Bit Masks */
177#define USBCMD_RUN (0x00000001)
178#define USBCMD_CTRL_RESET (0x00000002)
179#define USBCMD_PERIODIC_SCHEDULE_EN (0x00000010)
180#define USBCMD_ASYNC_SCHEDULE_EN (0x00000020)
181#define USBCMD_INT_AA_DOORBELL (0x00000040)
182#define USBCMD_ASP (0x00000300)
183#define USBCMD_ASYNC_SCH_PARK_EN (0x00000800)
184#define USBCMD_SUTW (0x00002000)
185#define USBCMD_ATDTW (0x00004000)
186#define USBCMD_ITC (0x00FF0000)
187
188/* Device Address bit masks */
189#define USBDEVICEADDRESS_MASK (0xFE000000)
190#define USBDEVICEADDRESS_BIT_POS (25)
191
192/* Endpoint Setup Status bit masks */
193#define EPSETUP_STATUS_EP0 (0x00000001)
194
195/* PORTSCX Register Bit Masks */
196#define PORTSCX_CURRENT_CONNECT_STATUS (0x00000001)
197#define PORTSCX_CONNECT_STATUS_CHANGE (0x00000002)
198#define PORTSCX_PORT_ENABLE (0x00000004)
199#define PORTSCX_PORT_EN_DIS_CHANGE (0x00000008)
200#define PORTSCX_OVER_CURRENT_ACT (0x00000010)
201#define PORTSCX_OVER_CURRENT_CHG (0x00000020)
202#define PORTSCX_PORT_FORCE_RESUME (0x00000040)
203#define PORTSCX_PORT_SUSPEND (0x00000080)
204#define PORTSCX_PORT_RESET (0x00000100)
205#define PORTSCX_LINE_STATUS_BITS (0x00000C00)
206#define PORTSCX_PORT_POWER (0x00001000)
207#define PORTSCX_PORT_INDICTOR_CTRL (0x0000C000)
208#define PORTSCX_PORT_TEST_CTRL (0x000F0000)
209#define PORTSCX_WAKE_ON_CONNECT_EN (0x00100000)
210#define PORTSCX_WAKE_ON_CONNECT_DIS (0x00200000)
211#define PORTSCX_WAKE_ON_OVER_CURRENT (0x00400000)
212#define PORTSCX_PHY_LOW_POWER_SPD (0x00800000)
213#define PORTSCX_PORT_FORCE_FULL_SPEED (0x01000000)
214#define PORTSCX_PORT_SPEED_MASK (0x0C000000)
215#define PORTSCX_PORT_WIDTH (0x10000000)
216#define PORTSCX_PHY_TYPE_SEL (0xC0000000)
217
218/* bit 11-10 are line status */
219#define PORTSCX_LINE_STATUS_SE0 (0x00000000)
220#define PORTSCX_LINE_STATUS_JSTATE (0x00000400)
221#define PORTSCX_LINE_STATUS_KSTATE (0x00000800)
222#define PORTSCX_LINE_STATUS_UNDEF (0x00000C00)
223#define PORTSCX_LINE_STATUS_BIT_POS (10)
224
225/* bit 15-14 are port indicator control */
226#define PORTSCX_PIC_OFF (0x00000000)
227#define PORTSCX_PIC_AMBER (0x00004000)
228#define PORTSCX_PIC_GREEN (0x00008000)
229#define PORTSCX_PIC_UNDEF (0x0000C000)
230#define PORTSCX_PIC_BIT_POS (14)
231
232/* bit 19-16 are port test control */
233#define PORTSCX_PTC_DISABLE (0x00000000)
234#define PORTSCX_PTC_JSTATE (0x00010000)
235#define PORTSCX_PTC_KSTATE (0x00020000)
236#define PORTSCX_PTC_SE0NAK (0x00030000)
237#define PORTSCX_PTC_PACKET (0x00040000)
238#define PORTSCX_PTC_FORCE_EN (0x00050000)
239#define PORTSCX_PTC_BIT_POS (16)
240
241/* bit 27-26 are port speed */
242#define PORTSCX_PORT_SPEED_FULL (0x00000000)
243#define PORTSCX_PORT_SPEED_LOW (0x04000000)
244#define PORTSCX_PORT_SPEED_HIGH (0x08000000)
245#define PORTSCX_PORT_SPEED_UNDEF (0x0C000000)
246#define PORTSCX_SPEED_BIT_POS (26)
247
248/* bit 28 is parallel transceiver width for UTMI interface */
249#define PORTSCX_PTW (0x10000000)
250#define PORTSCX_PTW_8BIT (0x00000000)
251#define PORTSCX_PTW_16BIT (0x10000000)
252
253/* bit 31-30 are port transceiver select */
254#define PORTSCX_PTS_UTMI (0x00000000)
255#define PORTSCX_PTS_CLASSIC (0x40000000)
256#define PORTSCX_PTS_ULPI (0x80000000)
257#define PORTSCX_PTS_FSLS (0xC0000000)
258#define PORTSCX_PTS_BIT_POS (30)
259
260/* USB MODE Register Bit Masks */
261#define USBMODE_CTRL_MODE_IDLE (0x00000000)
262#define USBMODE_CTRL_MODE_DEVICE (0x00000002)
263#define USBMODE_CTRL_MODE_HOST (0x00000003)
264#define USBMODE_CTRL_MODE_RSV (0x00000001)
265#define USBMODE_SETUP_LOCK_OFF (0x00000008)
266#define USBMODE_STREAM_DISABLE (0x00000010)
267
268/* ENDPOINTCTRLx Register Bit Masks */
269#define EPCTRL_TX_ENABLE (0x00800000)
270#define EPCTRL_TX_DATA_TOGGLE_RST (0x00400000) /* Not EP0 */
271#define EPCTRL_TX_DATA_TOGGLE_INH (0x00200000) /* Not EP0 */
272#define EPCTRL_TX_TYPE (0x000C0000)
273#define EPCTRL_TX_DATA_SOURCE (0x00020000) /* Not EP0 */
274#define EPCTRL_TX_EP_STALL (0x00010000)
275#define EPCTRL_RX_ENABLE (0x00000080)
276#define EPCTRL_RX_DATA_TOGGLE_RST (0x00000040) /* Not EP0 */
277#define EPCTRL_RX_DATA_TOGGLE_INH (0x00000020) /* Not EP0 */
278#define EPCTRL_RX_TYPE (0x0000000C)
279#define EPCTRL_RX_DATA_SINK (0x00000002) /* Not EP0 */
280#define EPCTRL_RX_EP_STALL (0x00000001)
281
282/* bit 19-18 and 3-2 are endpoint type */
283#define EPCTRL_TX_EP_TYPE_SHIFT (18)
284#define EPCTRL_RX_EP_TYPE_SHIFT (2)
285
286#define QH_MULT_POS (30)
287#define QH_ZLT_SEL (0x20000000)
288#define QH_MAX_PKT_LEN_POS (16)
289#define QH_IOS (0x00008000)
290#define QH_NEXT_TERMINATE (0x00000001)
291#define QH_IOC (0x00008000)
292#define QH_MULTO (0x00000C00)
293#define QH_STATUS_HALT (0x00000040)
294#define QH_STATUS_ACTIVE (0x00000080)
295#define EP_QUEUE_CURRENT_OFFSET_MASK (0x00000FFF)
296#define EP_QUEUE_HEAD_NEXT_POINTER_MASK (0xFFFFFFE0)
297#define EP_QUEUE_FRINDEX_MASK (0x000007FF)
298#define EP_MAX_LENGTH_TRANSFER (0x4000)
299
300#define DTD_NEXT_TERMINATE (0x00000001)
301#define DTD_IOC (0x00008000)
302#define DTD_STATUS_ACTIVE (0x00000080)
303#define DTD_STATUS_HALTED (0x00000040)
304#define DTD_STATUS_DATA_BUFF_ERR (0x00000020)
305#define DTD_STATUS_TRANSACTION_ERR (0x00000008)
306#define DTD_RESERVED_FIELDS (0x80007300)
307#define DTD_ADDR_MASK (0xFFFFFFE0)
308#define DTD_PACKET_SIZE (0x7FFF0000)
309#define DTD_LENGTH_BIT_POS (16)
310#define DTD_ERROR_MASK (DTD_STATUS_HALTED | \
311 DTD_STATUS_DATA_BUFF_ERR | \
312 DTD_STATUS_TRANSACTION_ERR)
313/*-------------------------------------------------------------------------*/
314/* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */
315struct transfer_descriptor {
316 unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set
317 indicate invalid */
318 unsigned int size_ioc_sts; /* Total bytes (30-16), IOC (15),
319 MultO(11-10), STS (7-0) */
320 unsigned int buff_ptr0; /* Buffer pointer Page 0 */
321 unsigned int buff_ptr1; /* Buffer pointer Page 1 */
322 unsigned int buff_ptr2; /* Buffer pointer Page 2 */
323 unsigned int buff_ptr3; /* Buffer pointer Page 3 */
324 unsigned int buff_ptr4; /* Buffer pointer Page 4 */
325 unsigned int reserved;
326} __attribute__ ((packed));
327
328static struct transfer_descriptor td_array[USB_NUM_ENDPOINTS*2]
329 __attribute__((aligned(32)));
330
331/* manual: 32.13.1 Endpoint Queue Head (dQH) */
332struct queue_head {
333 unsigned int max_pkt_length; /* Mult(31-30) , Zlt(29) , Max Pkt len
334 and IOS(15) */
335 unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */
336 struct transfer_descriptor dtd; /* dTD overlay */
337 unsigned int setup_buffer[2]; /* Setup data 8 bytes */
338 unsigned int reserved; /* for software use, pointer to the first TD */
339 unsigned int status; /* for software use, status of chain in progress */
340 unsigned int length; /* for software use, transfered bytes of chain in progress */
341 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
342} __attribute__((packed));
343
344static struct queue_head qh_array[USB_NUM_ENDPOINTS*2] __attribute__((aligned(2048)));
345
346static const unsigned int pipe2mask[] = {
347 0x01, 0x010000,
348 0x02, 0x020000,
349 0x04, 0x040000,
350 0x08, 0x080000,
351 0x10, 0x100000,
352};
353
354/* return transfered size if wait=true */
355static int prime_transfer(int ep_num, void *ptr, int len, bool send, bool wait)
356{
357 int pipe = ep_num * 2 + (send ? 1 : 0);
358 unsigned mask = pipe2mask[pipe];
359 struct transfer_descriptor *td = &td_array[pipe];
360 struct queue_head* qh = &qh_array[pipe];
361
362 /* prepare TD */
363 td->next_td_ptr = DTD_NEXT_TERMINATE;
364 td->size_ioc_sts = (len<< DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE;
365 td->buff_ptr0 = (unsigned int)ptr;
366 td->buff_ptr1 = ((unsigned int)ptr & 0xfffff000) + 0x1000;
367 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000;
368 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000;
369 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000;
370 td->reserved = 0;
371 /* prime */
372 qh->dtd.next_td_ptr = (unsigned int)td;
373 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE);
374 REG_ENDPTPRIME |= mask;
375 /* wait for priming to be taken into account */
376 while(!(REG_ENDPTSTATUS & mask));
377 /* wait for completion */
378 if(wait)
379 {
380 while(!(REG_ENDPTCOMPLETE & mask));
381 REG_ENDPTCOMPLETE = mask;
382 /* memory barrier */
383 asm volatile("":::"memory");
384 /* return transfered size */
385 return len - (td->size_ioc_sts >> DTD_LENGTH_BIT_POS);
386 }
387 else
388 return 0;
389}
390
391void usb_drv_set_address(int address)
392{
393 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS;
394}
395
396/* endpoints */
397#define EP_CONTROL 0
398
399#define DIR_OUT 0
400#define DIR_IN 1
401
402#define EP_DIR(ep) (((ep) & USB_ENDPOINT_DIR_MASK) ? DIR_IN : DIR_OUT)
403#define EP_NUM(ep) ((ep) & USB_ENDPOINT_NUMBER_MASK)
404
405static int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
406{
407 return prime_transfer(EP_NUM(endpoint), ptr, length, true, false);
408}
409
410static int usb_drv_send(int endpoint, void* ptr, int length)
411{
412 return prime_transfer(EP_NUM(endpoint), ptr, length, true, true);
413}
414
415static int usb_drv_recv(int endpoint, void* ptr, int length)
416{
417 return prime_transfer(EP_NUM(endpoint), ptr, length, false, true);
418}
419
420static int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length)
421{
422 return prime_transfer(EP_NUM(endpoint), ptr, length, false, false);
423}
424
425static int usb_drv_port_speed(void)
426{
427 return (REG_PORTSC1 & 0x08000000) ? 1 : 0;
428}
429
430static void usb_drv_stall(int endpoint, bool stall, bool in)
431{
432 int ep_num = EP_NUM(endpoint);
433
434 if(in)
435 {
436 if(stall)
437 REG_ENDPTCTRL(ep_num) |= EPCTRL_TX_EP_STALL;
438 else
439 REG_ENDPTCTRL(ep_num) &= ~EPCTRL_TX_EP_STALL;
440 }
441 else
442 {
443 if (stall)
444 REG_ENDPTCTRL(ep_num) |= EPCTRL_RX_EP_STALL;
445 else
446 REG_ENDPTCTRL(ep_num) &= ~EPCTRL_RX_EP_STALL;
447 }
448}
449
450static void usb_drv_configure_endpoint(int ep_num, int type)
451{
452 REG_ENDPTCTRL(ep_num) =
453 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
454 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
455 (type << EPCTRL_RX_EP_TYPE_SHIFT) |
456 (type << EPCTRL_TX_EP_TYPE_SHIFT);
457}
458
459/**
460 *
461 * Clock control
462 *
463 **/
464#define __CLK_CLKGATE (1 << 31)
465#define __CLK_BUSY (1 << 29)
466
467#define HW_CLKCTRL_BASE 0x80040000
468
469#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
470#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
471#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
472#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20
473#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20)
474
475#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
476
477#define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
478#define HW_CLKCTRL_CPU__DIV_CPU_BP 0
479#define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f
480#define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12)
481#define HW_CLKCTRL_CPU__DIV_XTAL_BP 16
482#define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16)
483#define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26)
484#define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28)
485
486#define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
487#define HW_CLKCTRL_HBUS__DIV_BP 0
488#define HW_CLKCTRL_HBUS__DIV_BM 0x1f
489#define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5)
490#define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16
491#define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16)
492#define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20)
493
494#define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
495#define HW_CLKCTRL_XBUS__DIV_BP 0
496#define HW_CLKCTRL_XBUS__DIV_BM 0x3ff
497#define HW_CLKCTRL_XBUS__BUSY (1 << 31)
498
499#define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50))
500#define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26)
501#define HW_CLKCTRL_XTAL__DRI_CLK24M_GATE (1 << 28)
502#define HW_CLKCTRL_XTAL__PWM_CLK24M_GATE (1 << 29)
503#define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30)
504
505#define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60))
506#define HW_CLKCTRL_PIX__DIV_BP 0
507#define HW_CLKCTRL_PIX__DIV_BM 0xfff
508
509#define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
510#define HW_CLKCTRL_SSP__DIV_BP 0
511#define HW_CLKCTRL_SSP__DIV_BM 0x1ff
512
513#define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0))
514#define HW_CLKCTRL_EMI__DIV_EMI_BP 0
515#define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f
516#define HW_CLKCTRL_EMI__DIV_XTAL_BP 8
517#define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8)
518#define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28)
519#define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30)
520#define HW_CLKCTRL_EMI__CLKGATE (1 << 31)
521
522#ifdef HAVE_STMP3770
523#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xe0))
524#else
525#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110))
526#endif
527#define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1)
528#define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5)
529#define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6)
530#define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7)
531
532#ifdef HAVE_STMP3770
533#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xd0))
534#else
535#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0))
536#endif
537#define HW_CLKCTRL_FRAC_CPU (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf0))
538#define HW_CLKCTRL_FRAC_EMI (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf1))
539#define HW_CLKCTRL_FRAC_PIX (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf2))
540#define HW_CLKCTRL_FRAC_IO (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf3))
541#define HW_CLKCTRL_FRAC_XX__XXDIV_BM 0x3f
542#define HW_CLKCTRL_FRAC_XX__XX_STABLE (1 << 6)
543#define HW_CLKCTRL_FRAC_XX__CLKGATEXX (1 << 7)
544
545#define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120))
546#define HW_CLKCTRL_RESET_CHIP 0x2
547#define HW_CLKCTRL_RESET_DIG 0x1
548
549/**
550 *
551 * DMA
552 *
553 */
554
555/********
556 * APHB *
557 ********/
558
559#define HW_APBH_BASE 0x80004000
560
561/* APHB channels */
562#define HW_APBH_SSP(ssp) ssp
563
564#define HW_APBH_CTRL0 (*(volatile uint32_t *)(HW_APBH_BASE + 0x0))
565#define HW_APBH_CTRL0__FREEZE_CHANNEL(i) (1 << (i))
566#define HW_APBH_CTRL0__CLKGATE_CHANNEL(i) (1 << ((i) + 8))
567#define HW_APBH_CTRL0__RESET_CHANNEL(i) (1 << ((i) + 16))
568#define HW_APBH_CTRL0__APB_BURST4_EN (1 << 28)
569#define HW_APBH_CTRL0__APB_BURST8_EN (1 << 29)
570
571#define HW_APBH_CTRL1 (*(volatile uint32_t *)(HW_APBH_BASE + 0x10))
572#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
573#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
574
575#define HW_APBH_CTRL2 (*(volatile uint32_t *)(HW_APBH_BASE + 0x20))
576#define HW_APBH_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
577#define HW_APBH_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
578
579#define HW_APBH_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x40 + 0x70 * (i)))
580
581#define HW_APBH_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x50 + 0x70 * (i)))
582
583#define HW_APBH_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x60 + 0x70 * (i)))
584
585#define HW_APBH_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x70 + 0x70 * (i)))
586
587#define HW_APBH_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x80 + 0x70 * (i)))
588
589#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i)))
590
591#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i)))
592#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0
593#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff
594#define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16
595#define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
596
597/********
598 * APHX *
599 ********/
600
601/* APHX channels */
602#define HW_APBX_AUDIO_ADC 0
603#define HW_APBX_AUDIO_DAC 1
604#define HW_APBX_I2C 3
605
606#define HW_APBX_BASE 0x80024000
607
608#define HW_APBX_CTRL0 (*(volatile uint32_t *)(HW_APBX_BASE + 0x0))
609
610#define HW_APBX_CTRL1 (*(volatile uint32_t *)(HW_APBX_BASE + 0x10))
611#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
612#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
613
614#define HW_APBX_CTRL2 (*(volatile uint32_t *)(HW_APBX_BASE + 0x20))
615#define HW_APBX_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
616#define HW_APBX_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
617
618#define HW_APBX_CHANNEL_CTRL (*(volatile uint32_t *)(HW_APBX_BASE + 0x30))
619#define HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(i) (1 << (i))
620#define HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(i) (1 << ((i) + 16))
621
622#define HW_APBX_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x100 + (i) * 0x70))
623
624#define HW_APBX_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x110 + (i) * 0x70))
625
626#define HW_APBX_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x120 + (i) * 0x70))
627
628#define HW_APBX_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x130 + (i) * 0x70))
629
630#define HW_APBX_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x140 + (i) * 0x70))
631
632#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70))
633
634#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70))
635#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0
636#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff
637#define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16
638#define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
639
640/**********
641 * COMMON *
642 **********/
643
644struct apb_dma_command_t
645{
646 struct apb_dma_command_t *next;
647 uint32_t cmd;
648 void *buffer;
649 /* PIO words follow */
650};
651
652#define APBH_DMA_CHANNEL(i) i
653#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
654#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
655#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf)
656
657#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp))
658#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC)
659#define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC)
660#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C)
661
662#define HW_APB_CHx_CMD__COMMAND_BM 0x3
663#define HW_APB_CHx_CMD__COMMAND__NO_XFER 0
664#define HW_APB_CHx_CMD__COMMAND__WRITE 1
665#define HW_APB_CHx_CMD__COMMAND__READ 2
666#define HW_APB_CHx_CMD__COMMAND__SENSE 3
667#define HW_APB_CHx_CMD__CHAIN (1 << 2)
668#define HW_APB_CHx_CMD__IRQONCMPLT (1 << 3)
669/* those two are only available on APHB */
670#define HW_APBH_CHx_CMD__NANDLOCK (1 << 4)
671#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5)
672#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6)
673#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7)
674/* An errata advise not to use it */
675//#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
676#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
677#define HW_APB_CHx_CMD__CMDWORDS_BP 12
678#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
679#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
680/* For software use */
681#define HW_APB_CHx_CMD__UNUSED_BP 8
682#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8)
683#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8)
684
685#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
686#define HW_APB_CHx_SEMA__PHORE_BP 16
687
688/* A single descriptor cannot transfer more than 2^16 bytes */
689#define IMX233_MAX_SINGLE_DMA_XFER_SIZE (1 << 16)
690
691static void imx233_dma_init(void)
692{
693 __REG_CLR(HW_APBH_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
694 __REG_CLR(HW_APBX_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
695}
696
697static void imx233_dma_reset_channel(unsigned chan)
698{
699 volatile uint32_t *ptr;
700 uint32_t bm;
701 if(APB_IS_APBX_CHANNEL(chan))
702 {
703 ptr = &HW_APBX_CHANNEL_CTRL;
704 bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
705 }
706 else
707 {
708 ptr = &HW_APBH_CTRL0;
709 bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
710 }
711 __REG_SET(*ptr) = bm;
712 /* wait for end of reset */
713 while(*ptr & bm)
714 ;
715}
716
717static void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
718{
719 if(APB_IS_APBX_CHANNEL(chan))
720 {
721 HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
722 HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
723 }
724 else
725 {
726 HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
727 HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
728 }
729}
730
731static void imx233_dma_wait_completion(unsigned chan)
732{
733 volatile uint32_t *sema;
734 if(APB_IS_APBX_CHANNEL(chan))
735 sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
736 else
737 sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
738
739 while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
740 ;
741}
742
743/**
744 *
745 * Digctl
746 *
747 */
748
749/* Digital control */
750#define HW_DIGCTL_BASE 0x8001C000
751#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
752#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
753
754#define HW_DIGCTL_HCLKCOUNT (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x20))
755
756#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
757
758#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
759#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16
760#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BM 0xffff0000
761#define HW_DIGCTL_CHIPID__REVISION_BP 0
762#define HW_DIGCTL_CHIPID__REVISION_BM 0xff
763
764static bool imx233_us_elapsed(uint32_t ref, unsigned us_delay)
765{
766 uint32_t cur = HW_DIGCTL_MICROSECONDS;
767 if(ref + us_delay <= ref)
768 return !(cur > ref) && !(cur < (ref + us_delay));
769 else
770 return (cur < ref) || cur >= (ref + us_delay);
771}
772
773static void udelay(unsigned us)
774{
775 uint32_t ref = HW_DIGCTL_MICROSECONDS;
776 while(!imx233_us_elapsed(ref, us));
777}
778
779#define HZ 1000000
780
781/**
782 *
783 * PWM
784 *
785 */
786
787#define HW_PWM_BASE 0x80064000
788
789#define HW_PWM_CTRL (*(volatile uint32_t *)(HW_PWM_BASE + 0x0))
790#define HW_PWM_CTRL__PWMx_ENABLE(x) (1 << (x))
791
792#define HW_PWM_ACTIVEx(x) (*(volatile uint32_t *)(HW_PWM_BASE + 0x10 + (x) * 0x20))
793#define HW_PWM_ACTIVEx__ACTIVE_BP 0
794#define HW_PWM_ACTIVEx__ACTIVE_BM 0xffff
795#define HW_PWM_ACTIVEx__INACTIVE_BP 16
796#define HW_PWM_ACTIVEx__INACTIVE_BM 0xffff0000
797
798#define HW_PWM_PERIODx(x) (*(volatile uint32_t *)(HW_PWM_BASE + 0x20 + (x) * 0x20))
799#define HW_PWM_PERIODx__PERIOD_BP 0
800#define HW_PWM_PERIODx__PERIOD_BM 0xffff
801#define HW_PWM_PERIODx__ACTIVE_STATE_BP 16
802#define HW_PWM_PERIODx__ACTIVE_STATE_BM (0x3 << 16)
803#define HW_PWM_PERIODx__INACTIVE_STATE_BP 18
804#define HW_PWM_PERIODx__INACTIVE_STATE_BM (0x3 << 18)
805#define HW_PWM_PERIODx__CDIV_BP 20
806#define HW_PWM_PERIODx__CDIV_BM (0x7 << 20)
807#define HW_PWM_PERIODx__CDIV__DIV_1 0
808#define HW_PWM_PERIODx__CDIV__DIV_2 1
809#define HW_PWM_PERIODx__CDIV__DIV_4 2
810#define HW_PWM_PERIODx__CDIV__DIV_8 3
811#define HW_PWM_PERIODx__CDIV__DIV_16 4
812#define HW_PWM_PERIODx__CDIV__DIV_64 5
813#define HW_PWM_PERIODx__CDIV__DIV_256 6
814#define HW_PWM_PERIODx__CDIV__DIV_1024 7
815
816#define HW_PWM_PERIODx__STATE__HI_Z 0
817#define HW_PWM_PERIODx__STATE__LOW 2
818#define HW_PWM_PERIODx__STATE__HIGH 3
819
820#define IMX233_PWM_PIN_BANK(channel) 2
821#define IMX233_PWM_PIN(channel) (0 + (channel))
822
823static void imx233_pwm_init(void)
824{
825 //__REG_SET(HW_PWM_CTRL) = __BLOCK_SFTRST;
826 __REG_CLR(HW_PWM_CTRL) = __BLOCK_SFTRST | __BLOCK_CLKGATE;
827 while(HW_PWM_CTRL & __BLOCK_CLKGATE);
828 __REG_CLR(HW_CLKCTRL_XTAL) = HW_CLKCTRL_XTAL__PWM_CLK24M_GATE;
829}
830
831static bool imx233_pwm_is_channel_enable(int channel)
832{
833 return HW_PWM_CTRL & HW_PWM_CTRL__PWMx_ENABLE(channel);
834}
835
836static void imx233_pwm_enable_channel(int channel, bool enable)
837{
838 if(enable)
839 __REG_SET(HW_PWM_CTRL) = HW_PWM_CTRL__PWMx_ENABLE(channel);
840 else
841 __REG_CLR(HW_PWM_CTRL) = HW_PWM_CTRL__PWMx_ENABLE(channel);
842}
843
844static void imx233_pwm_setup_channel(int channel, int period, int cdiv, int active,
845 int active_state, int inactive, int inactive_state)
846{
847 /* stop */
848 bool enable = imx233_pwm_is_channel_enable(channel);
849 if(enable)
850 imx233_pwm_enable_channel(channel, false);
851 /* setup pin */
852 imx233_set_pin_function(IMX233_PWM_PIN_BANK(channel), IMX233_PWM_PIN(channel),
853 PINCTRL_FUNCTION_MAIN);
854 imx233_set_pin_drive_strength(IMX233_PWM_PIN_BANK(channel), IMX233_PWM_PIN(channel),
855 PINCTRL_DRIVE_4mA);
856 /* watch the order ! active THEN period */
857 HW_PWM_ACTIVEx(channel) = active << HW_PWM_ACTIVEx__ACTIVE_BP |
858 inactive << HW_PWM_ACTIVEx__INACTIVE_BP;
859 HW_PWM_PERIODx(channel) = period | active_state << HW_PWM_PERIODx__ACTIVE_STATE_BP |
860 inactive_state << HW_PWM_PERIODx__INACTIVE_STATE_BP |
861 cdiv << HW_PWM_PERIODx__CDIV_BP;
862 /* restore */
863 imx233_pwm_enable_channel(channel, enable);
864}
865
866/**
867 *
868 * USB PHY
869 *
870 */
871/* USB Phy */
872#define HW_USBPHY_BASE 0x8007C000
873#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
874#define HW_USBPHY_PWD__ALL (7 << 10 | 0xf << 17)
875
876#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
877
878/**
879 *
880 * DCP
881 *
882 */
883#define HW_DCP_BASE 0x80028000
884
885#define HW_DCP_CTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x0))
886
887#define HW_DCP_STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x10))
888#define HW_DCP_STAT__IRQ(x) (1 << (x))
889
890#define HW_DCP_CHANNELCTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x20))
891#define HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(x) (1 << (x))
892
893#define HW_DCP_CH0CMDPTR (*(volatile unsigned long *)(HW_DCP_BASE + 0x100))
894
895#define HW_DCP_CH0SEMA (*(volatile unsigned long *)(HW_DCP_BASE + 0x110))
896#define HW_DCP_CH0SEMA__INCREMENT(x) (x)
897#define HW_DCP_CH0SEMA__VALUE_BP 16
898#define HW_DCP_CH0SEMA__VALUE_BM (0xff << 16)
899#define HW_DCP_CH0STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x120))
900
901#define HW_DCP_CTRL0__INTERRUPT_ENABLE (1 << 0)
902#define HW_DCP_CTRL0__DECR_SEMAPHORE (1 << 1)
903#define HW_DCP_CTRL0__ENABLE_MEMCOPY (1 << 4)
904#define HW_DCP_CTRL0__ENABLE_CIPHER (1 << 5)
905#define HW_DCP_CTRL0__ENABLE_HASH (1 << 6)
906#define HW_DCP_CTRL0__CIPHER_ENCRYPT (1 << 8)
907#define HW_DCP_CTRL0__CIPHER_INIT (1 << 9)
908#define HW_DCP_CTRL0__OTP_KEY (1 << 10)
909#define HW_DCP_CTRL0__HASH_INIT (1 << 12)
910#define HW_DCP_CTRL0__HASH_TERM (1 << 13)
911#define HW_DCP_CTRL0__HASH_OUTPUT (1 << 15)
912
913#define HW_DCP_CTRL1__CIPHER_SELECT_BP 0
914#define HW_DCP_CTRL1__CIPHER_SELECT_BM 0xf
915#define HW_DCP_CTRL1__CIPHER_SELECT__AES128 0
916#define HW_DCP_CTRL1__CIPHER_MODE_BP 4
917#define HW_DCP_CTRL1__CIPHER_MODE_BM 0xf0
918#define HW_DCP_CTRL1__CIPHER_MODE__CBC (1 << 4)
919#define HW_DCP_CTRL1__HASH_SELECT_BP 4
920#define HW_DCP_CTRL1__HASH_SELECT_BM 0xf00
921
922struct dcp_packet_t
923{
924 unsigned long next;
925 unsigned long ctrl0;
926 unsigned long ctrl1;
927 unsigned long src_buf;
928 unsigned long dst_buf;
929 unsigned long buf_sz;
930 unsigned long payload_ptr;
931 unsigned long status;
932} __attribute__((packed));
933
934/**
935 *
936 * Misc
937 *
938 */
939
940void memcpy(uint8_t *dst, const uint8_t *src, uint32_t length)
941{
942 for(uint32_t i = 0; i < length; i++)
943 dst[i] = src[i];
944}
945
946void memset(uint8_t *dst, uint8_t fill, uint32_t length)
947{
948 for(uint32_t i = 0; i < length; i++)
949 dst[i] = fill;
950}
951
952/**
953 *
954 * USB stack
955 *
956 */
957
958static struct usb_device_descriptor __attribute__((aligned(2)))
959 device_descriptor=
960{
961 .bLength = sizeof(struct usb_device_descriptor),
962 .bDescriptorType = USB_DT_DEVICE,
963 .bcdUSB = 0x0200,
964 .bDeviceClass = USB_CLASS_PER_INTERFACE,
965 .bDeviceSubClass = 0,
966 .bDeviceProtocol = 0,
967 .bMaxPacketSize0 = 64,
968 .idVendor = HWEMUL_USB_VID,
969 .idProduct = HWEMUL_USB_PID,
970 .bcdDevice = HWEMUL_VERSION_MAJOR << 8 | HWEMUL_VERSION_MINOR,
971 .iManufacturer = 1,
972 .iProduct = 2,
973 .iSerialNumber = 3,
974 .bNumConfigurations = 1
975};
976
977#define USB_MAX_CURRENT 200
978
979static struct usb_config_descriptor __attribute__((aligned(2)))
980 config_descriptor =
981{
982 .bLength = sizeof(struct usb_config_descriptor),
983 .bDescriptorType = USB_DT_CONFIG,
984 .wTotalLength = 0, /* will be filled in later */
985 .bNumInterfaces = 1,
986 .bConfigurationValue = 1,
987 .iConfiguration = 0,
988 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
989 .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */
990};
991
992/* main interface */
993static struct usb_interface_descriptor __attribute__((aligned(2)))
994 interface_descriptor =
995{
996 .bLength = sizeof(struct usb_interface_descriptor),
997 .bDescriptorType = USB_DT_INTERFACE,
998 .bInterfaceNumber = 0,
999 .bAlternateSetting = 0,
1000 .bNumEndpoints = 3,
1001 .bInterfaceClass = HWEMUL_CLASS,
1002 .bInterfaceSubClass = HWEMUL_SUBCLASS,
1003 .bInterfaceProtocol = HWEMUL_PROTOCOL,
1004 .iInterface = 4
1005};
1006
1007
1008static struct usb_endpoint_descriptor __attribute__((aligned(2)))
1009 endpoint_descriptor =
1010{
1011 .bLength = sizeof(struct usb_endpoint_descriptor),
1012 .bDescriptorType = USB_DT_ENDPOINT,
1013 .bEndpointAddress = 0,
1014 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1015 .wMaxPacketSize = 0,
1016 .bInterval = 0
1017};
1018
1019static const struct usb_string_descriptor __attribute__((aligned(2)))
1020 usb_string_iManufacturer =
1021{
1022 24,
1023 USB_DT_STRING,
1024 {'R', 'o', 'c', 'k', 'b', 'o', 'x', '.', 'o', 'r', 'g'}
1025};
1026
1027static const struct usb_string_descriptor __attribute__((aligned(2)))
1028 usb_string_iProduct =
1029{
1030 52,
1031 USB_DT_STRING,
1032 {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ',
1033 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ',
1034 'e', 'm', 'u', 'l', 'a', 't', 'e', 'r'}
1035};
1036
1037static struct usb_string_descriptor __attribute__((aligned(2)))
1038 usb_string_iSerial =
1039{
1040 84,
1041 USB_DT_STRING,
1042 {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
1043 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
1044 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
1045 '0', '0', '0', '0', '0', '0', '0', '0'}
1046};
1047
1048static struct usb_string_descriptor __attribute__((aligned(2)))
1049 usb_string_iInterface =
1050{
1051 28,
1052 USB_DT_STRING,
1053 {'A', 'c', 'i', 'd', ' ',
1054 '0' + (HWEMUL_VERSION_MAJOR >> 4), '0' + (HWEMUL_VERSION_MAJOR & 0xf), '.',
1055 '0' + (HWEMUL_VERSION_MINOR >> 4), '0' + (HWEMUL_VERSION_MINOR & 0xf), '.',
1056 '0' + (HWEMUL_VERSION_REV >> 4), '0' + (HWEMUL_VERSION_REV & 0xf) }
1057};
1058
1059/* this is stringid #0: languages supported */
1060static const struct usb_string_descriptor __attribute__((aligned(2)))
1061 lang_descriptor =
1062{
1063 4,
1064 USB_DT_STRING,
1065 {0x0409} /* LANGID US English */
1066};
1067
1068#define USB_NUM_STRINGS 5
1069
1070static const struct usb_string_descriptor* const usb_strings[USB_NUM_STRINGS] =
1071{
1072 &lang_descriptor,
1073 &usb_string_iManufacturer,
1074 &usb_string_iProduct,
1075 &usb_string_iSerial,
1076 &usb_string_iInterface
1077};
1078
1079uint8_t *usb_buffer = oc_bufferstart;
1080uint32_t usb_buffer_size = 0;
1081
1082#define EP_BULK 1
1083#define EP_INT 2
1084
1085static void set_config(void)
1086{
1087 usb_drv_configure_endpoint(EP_BULK, USB_ENDPOINT_XFER_BULK);
1088 usb_drv_configure_endpoint(EP_INT, USB_ENDPOINT_XFER_INT);
1089}
1090
1091static void handle_std_dev_desc(struct usb_ctrlrequest *req)
1092{
1093 int size;
1094 const void* ptr = NULL;
1095 unsigned index = req->wValue & 0xff;
1096
1097 switch(req->wValue >> 8)
1098 {
1099 case USB_DT_DEVICE:
1100 ptr = &device_descriptor;
1101 size = sizeof(struct usb_device_descriptor);
1102 break;
1103 case USB_DT_OTHER_SPEED_CONFIG:
1104 case USB_DT_CONFIG:
1105 {
1106 int max_packet_size;
1107
1108 /* config desc */
1109 if((req->wValue >> 8) ==USB_DT_CONFIG)
1110 {
1111 max_packet_size = (usb_drv_port_speed() ? 512 : 64);
1112 config_descriptor.bDescriptorType = USB_DT_CONFIG;
1113 }
1114 else
1115 {
1116 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
1117 config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
1118 }
1119 size = sizeof(struct usb_config_descriptor);
1120
1121 /* interface */
1122 memcpy(usb_buffer + size, (void *)&interface_descriptor,
1123 sizeof(interface_descriptor));
1124 size += sizeof(interface_descriptor);
1125 /* endpoint 1: bulk out */
1126 endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT;
1127 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
1128 endpoint_descriptor.wMaxPacketSize = 512;
1129 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
1130 sizeof(endpoint_descriptor));
1131 size += sizeof(endpoint_descriptor);
1132 /* endpoint 2: bulk in */
1133 endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN;
1134 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
1135 endpoint_descriptor.wMaxPacketSize = 512;
1136 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
1137 sizeof(endpoint_descriptor));
1138 size += sizeof(endpoint_descriptor);
1139 /* endpoint 3: int in */
1140 endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN;
1141 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT;
1142 endpoint_descriptor.wMaxPacketSize = 1024;
1143 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
1144 sizeof(endpoint_descriptor));
1145 size += sizeof(endpoint_descriptor);
1146
1147 /* fix config descriptor */
1148 config_descriptor.bNumInterfaces = 1;
1149 config_descriptor.wTotalLength = size;
1150 memcpy(usb_buffer, (void *)&config_descriptor, sizeof(config_descriptor));
1151
1152 ptr = usb_buffer;
1153 break;
1154 }
1155 case USB_DT_STRING:
1156 if(index < USB_NUM_STRINGS)
1157 {
1158 size = usb_strings[index]->bLength;
1159 ptr = usb_strings[index];
1160 }
1161 else
1162 usb_drv_stall(EP_CONTROL, true, true);
1163 break;
1164 default:
1165 break;
1166 }
1167
1168 if(ptr)
1169 {
1170 int length = MIN(size, req->wLength);
1171
1172 if(ptr != usb_buffer)
1173 memcpy(usb_buffer, ptr, length);
1174
1175 usb_drv_send(EP_CONTROL, usb_buffer, length);
1176 usb_drv_recv(EP_CONTROL, NULL, 0);
1177 }
1178 else
1179 usb_drv_stall(EP_CONTROL, true, true);
1180}
1181
1182static void handle_std_dev_req(struct usb_ctrlrequest *req)
1183{
1184 switch(req->bRequest)
1185 {
1186 case USB_REQ_GET_CONFIGURATION:
1187 usb_buffer[0] = 1;
1188 usb_drv_send(EP_CONTROL, usb_buffer, 1);
1189 usb_drv_recv(EP_CONTROL, NULL, 0);
1190 break;
1191 case USB_REQ_SET_CONFIGURATION:
1192 usb_drv_send(EP_CONTROL, NULL, 0);
1193 set_config();
1194 break;
1195 case USB_REQ_GET_DESCRIPTOR:
1196 handle_std_dev_desc(req);
1197 break;
1198 case USB_REQ_SET_ADDRESS:
1199 usb_drv_send(EP_CONTROL, NULL, 0);
1200 usb_drv_set_address(req->wValue);
1201 break;
1202 case USB_REQ_GET_STATUS:
1203 usb_buffer[0] = 0;
1204 usb_buffer[1] = 0;
1205 usb_drv_send(EP_CONTROL, usb_buffer, 2);
1206 usb_drv_recv(EP_CONTROL, NULL, 0);
1207 break;
1208 default:
1209 usb_drv_stall(EP_CONTROL, true, true);
1210 }
1211}
1212
1213static void handle_std_req(struct usb_ctrlrequest *req)
1214{
1215 switch(req->bRequestType & USB_RECIP_MASK)
1216 {
1217 case USB_RECIP_DEVICE:
1218 return handle_std_dev_req(req);
1219 default:
1220 usb_drv_stall(EP_CONTROL, true, true);
1221 }
1222}
1223
1224struct usb_resp_info_version_t g_version =
1225{
1226 .major = HWEMUL_VERSION_MAJOR,
1227 .minor = HWEMUL_VERSION_MINOR,
1228 .revision = HWEMUL_VERSION_REV
1229};
1230
1231struct usb_resp_info_layout_t g_layout;
1232
1233struct usb_resp_info_stmp_t g_stmp;
1234
1235struct usb_resp_info_features_t g_features =
1236{
1237 .feature_mask = HWEMUL_FEATURE_LOG | HWEMUL_FEATURE_MEM |
1238 HWEMUL_FEATURE_CALL | HWEMUL_FEATURE_JUMP | HWEMUL_FEATURE_AES_OTP
1239};
1240
1241static void fill_layout_info(void)
1242{
1243 g_layout.oc_code_start = (uint32_t)oc_codestart;
1244 g_layout.oc_code_size = oc_codesize;
1245 g_layout.oc_stack_start = (uint32_t)oc_stackstart;
1246 g_layout.oc_stack_size = oc_stacksize;
1247 g_layout.oc_buffer_start = (uint32_t)oc_bufferstart;
1248 g_layout.oc_buffer_size = oc_buffersize;
1249}
1250
1251static void fill_stmp_info(void)
1252{
1253 g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
1254 g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION);
1255 g_stmp.is_supported = g_stmp.chipid == 0x3780 || g_stmp.chipid == 0x3700 ||
1256 g_stmp.chipid == 0x3b00;
1257}
1258
1259static void handle_get_info(struct usb_ctrlrequest *req)
1260{
1261 void *ptr = NULL;
1262 int size = 0;
1263 switch(req->wIndex)
1264 {
1265 case HWEMUL_INFO_VERSION:
1266 ptr = &g_version;
1267 size = sizeof(g_version);
1268 break;
1269 case HWEMUL_INFO_LAYOUT:
1270 fill_layout_info();
1271 ptr = &g_layout;
1272 size = sizeof(g_layout);
1273 break;
1274 case HWEMUL_INFO_STMP:
1275 fill_stmp_info();
1276 ptr = &g_stmp;
1277 size = sizeof(g_stmp);
1278 break;
1279 case HWEMUL_INFO_FEATURES:
1280 ptr = &g_features;
1281 size = sizeof(g_features);
1282 break;
1283 default:
1284 usb_drv_stall(EP_CONTROL, true, true);
1285 }
1286
1287 if(ptr)
1288 {
1289 int length = MIN(size, req->wLength);
1290
1291 if(ptr != usb_buffer)
1292 memcpy(usb_buffer, ptr, length);
1293 usb_drv_send(EP_CONTROL, usb_buffer, length);
1294 usb_drv_recv(EP_CONTROL, NULL, 0);
1295 }
1296}
1297
1298static void handle_get_log(struct usb_ctrlrequest *req)
1299{
1300 enable_logf(false);
1301 int length = logf_readback(usb_buffer, MIN(req->wLength, usb_buffer_size));
1302 usb_drv_send(EP_CONTROL, usb_buffer, length);
1303 usb_drv_recv(EP_CONTROL, NULL, 0);
1304 enable_logf(true);
1305}
1306
1307static void handle_rw_mem(struct usb_ctrlrequest *req)
1308{
1309 uint32_t addr = req->wValue | req->wIndex << 16;
1310 uint16_t length = req->wLength;
1311
1312 if(req->bRequestType & USB_DIR_IN)
1313 {
1314 memcpy(usb_buffer, (void *)addr, length);
1315 asm volatile("nop" : : : "memory");
1316 usb_drv_send(EP_CONTROL, usb_buffer, length);
1317 usb_drv_recv(EP_CONTROL, NULL, 0);
1318 }
1319 else
1320 {
1321 int size = usb_drv_recv(EP_CONTROL, usb_buffer, length);
1322 asm volatile("nop" : : : "memory");
1323 if(size != length)
1324 usb_drv_stall(EP_CONTROL, true, true);
1325 else
1326 {
1327 memcpy((void *)addr, usb_buffer, length);
1328 usb_drv_send(EP_CONTROL, NULL, 0);
1329 }
1330 }
1331}
1332
1333static void handle_call_jump(struct usb_ctrlrequest *req)
1334{
1335 uint32_t addr = req->wValue | req->wIndex << 16;
1336
1337 if(req->bRequest == HWEMUL_CALL)
1338 ((void (*)(void))addr)();
1339 else
1340 asm volatile("bx %0\n" : : "r" (addr) : "memory");
1341}
1342
1343static void do_aes_otp(void *buffer, unsigned length, unsigned params)
1344{
1345 static struct dcp_packet_t dcp_packet;
1346
1347 bool encrypt = !!(params & HWEMUL_AES_OTP_ENCRYPT);
1348 /* reset DCP */
1349 __REG_SET(HW_DCP_CTRL) = 0x80000000;
1350 /* clear clock gate */
1351 __REG_CLR(HW_DCP_CTRL) = 0xc0000000;
1352 /* enable dma for channel 0 */
1353 __REG_SET(HW_DCP_CHANNELCTRL) = HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(0);
1354 /* prepare packet */
1355 dcp_packet.next = 0;
1356
1357 dcp_packet.ctrl0 = HW_DCP_CTRL0__INTERRUPT_ENABLE |
1358 HW_DCP_CTRL0__DECR_SEMAPHORE | HW_DCP_CTRL0__CIPHER_INIT |
1359 HW_DCP_CTRL0__ENABLE_CIPHER | HW_DCP_CTRL0__OTP_KEY |
1360 (encrypt ? HW_DCP_CTRL0__CIPHER_ENCRYPT : 0);
1361 dcp_packet.ctrl1 = HW_DCP_CTRL1__CIPHER_SELECT__AES128 |
1362 HW_DCP_CTRL1__CIPHER_MODE__CBC;
1363 dcp_packet.src_buf = (unsigned long)buffer + 16;
1364 dcp_packet.dst_buf = (unsigned long)buffer + 16;
1365 dcp_packet.buf_sz = length - 16;
1366 dcp_packet.payload_ptr = (unsigned long)buffer;
1367 dcp_packet.status = 0;
1368
1369 asm volatile("":::"memory");
1370 /* kick */
1371 HW_DCP_CH0CMDPTR = (unsigned long)&dcp_packet;
1372 HW_DCP_CH0SEMA = HW_DCP_CH0SEMA__INCREMENT(1);
1373 /* wait */
1374 while(!(HW_DCP_STAT & HW_DCP_STAT__IRQ(0)));
1375
1376 usb_drv_send_nonblocking(EP_INT, buffer, length);
1377}
1378
1379static void handle_aes_otp(struct usb_ctrlrequest *req)
1380{
1381 uint16_t length = req->wLength;
1382
1383 int size = usb_drv_recv(EP_CONTROL, usb_buffer, length);
1384 if(size != length)
1385 usb_drv_stall(EP_CONTROL, true, true);
1386 else
1387 usb_drv_send(EP_CONTROL, NULL, 0);
1388 do_aes_otp(usb_buffer, length, req->wValue);
1389}
1390
1391static void handle_class_dev_req(struct usb_ctrlrequest *req)
1392{
1393 switch(req->bRequest)
1394 {
1395 case HWEMUL_GET_INFO:
1396 handle_get_info(req);
1397 break;
1398 case HWEMUL_GET_LOG:
1399 handle_get_log(req);
1400 break;
1401 case HWEMUL_RW_MEM:
1402 handle_rw_mem(req);
1403 break;
1404 case HWEMUL_CALL:
1405 case HWEMUL_JUMP:
1406 handle_call_jump(req);
1407 break;
1408 case HWEMUL_AES_OTP:
1409 handle_aes_otp(req);
1410 break;
1411 default:
1412 usb_drv_stall(EP_CONTROL, true, true);
1413 }
1414}
1415
1416static void handle_class_req(struct usb_ctrlrequest *req)
1417{
1418 switch(req->bRequestType & USB_RECIP_MASK)
1419 {
1420 case USB_RECIP_DEVICE:
1421 return handle_class_dev_req(req);
1422 default:
1423 usb_drv_stall(EP_CONTROL, true, true);
1424 }
1425}
1426
1427/**
1428 *
1429 * Main
1430 *
1431 */
1432
1433static void flash_pwm(int chan, int v1, int v2)
1434{
1435 imx233_pwm_setup_channel(chan, 500, HW_PWM_PERIODx__CDIV__DIV_256,
1436 v1, HW_PWM_PERIODx__STATE__HIGH,
1437 v2, HW_PWM_PERIODx__STATE__LOW);
1438}
1439
1440void main(uint32_t arg)
1441{
1442 usb_buffer_size = oc_buffersize;
1443
1444 logf("hwemul %d.%d.%d\n", HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR,
1445 HWEMUL_VERSION_REV);
1446 logf("argument: 0x%08x\n", arg);
1447
1448 imx233_pwm_init();
1449
1450 flash_pwm(2, 0, 500);
1451 flash_pwm(4, 0, 0);
1452
1453 udelay(HZ / 2);
1454
1455 /* we don't know if USB was connected or not. In USB recovery mode it will
1456 * but in other cases it might not be. In doubt, disconnect */
1457 REG_USBCMD &= ~USBCMD_RUN;
1458 /* enable USB PHY PLL */
1459 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
1460 /* power up USB PHY */
1461 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
1462 //__REG_CLR(HW_USBPHY_PWD) = HW_USBPHY_PWD__ALL;
1463 HW_USBPHY_PWD = 0;
1464 /* enable USB controller */
1465 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
1466 /* reset the controller */
1467 REG_USBCMD |= USBCMD_CTRL_RESET;
1468 while (REG_USBCMD & USBCMD_CTRL_RESET);
1469 /* put it in device mode */
1470 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
1471 /* reset address */
1472 REG_DEVICEADDR = 0;
1473 /* prepare qh array */
1474 qh_array[0].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
1475 qh_array[1].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
1476 qh_array[2].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
1477 qh_array[3].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
1478 qh_array[5].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
1479 /* setup qh */
1480 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
1481 /* clear setup status */
1482 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1483 /* run! */
1484 REG_USBCMD |= USBCMD_RUN;
1485 /* infinite loop */
1486 flash_pwm(2, 0, 0);
1487 flash_pwm(4, 0, 500);
1488
1489 while(1)
1490 {
1491 /* wait for setup */
1492 while(!(REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0))
1493 ;
1494 /* clear setup status */
1495 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1496 /* check request */
1497 asm volatile("":::"memory");
1498 struct usb_ctrlrequest *req = (void *)&qh_array[0].setup_buffer[0];
1499
1500 switch(req->bRequestType & USB_TYPE_MASK)
1501 {
1502 case USB_TYPE_STANDARD:
1503 handle_std_req(req);
1504 break;
1505 case USB_TYPE_CLASS:
1506 handle_class_req(req);
1507 break;
1508 default:
1509 usb_drv_stall(EP_CONTROL, true, true);
1510 }
1511 }
1512}