summaryrefslogtreecommitdiff
path: root/utils/hwstub/stmp/main.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-06-12 19:46:04 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-06-12 19:46:04 +0200
commit11da9d23fe323ce452fcd04a10a0ddf78eaa63ea (patch)
tree7ab4d162b2a944214bb01d498d5a0400dec031a0 /utils/hwstub/stmp/main.c
parent3f4eeb850e91fd026a99f2b17bd7e0837f112bb5 (diff)
downloadrockbox-11da9d23fe323ce452fcd04a10a0ddf78eaa63ea.tar.gz
rockbox-11da9d23fe323ce452fcd04a10a0ddf78eaa63ea.zip
imxtools: move hwemul to its own directory
The hwemul is only partly imx specific: the stub is stmp specific but could be ported to other targets, the computer side and the protocol are mostly stmp independent (or should be). Change-Id: If88febffe591b0de86ea11cb740455ba20ddc401
Diffstat (limited to 'utils/hwstub/stmp/main.c')
-rw-r--r--utils/hwstub/stmp/main.c1409
1 files changed, 1409 insertions, 0 deletions
diff --git a/utils/hwstub/stmp/main.c b/utils/hwstub/stmp/main.c
new file mode 100644
index 0000000000..09bb6c7714
--- /dev/null
+++ b/utils/hwstub/stmp/main.c
@@ -0,0 +1,1409 @@
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 * USB PHY
784 *
785 */
786/* USB Phy */
787#define HW_USBPHY_BASE 0x8007C000
788#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
789#define HW_USBPHY_PWD__ALL (7 << 10 | 0xf << 17)
790
791#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
792
793/**
794 *
795 * DCP
796 *
797 */
798#define HW_DCP_BASE 0x80028000
799
800#define HW_DCP_CTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x0))
801
802#define HW_DCP_STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x10))
803#define HW_DCP_STAT__IRQ(x) (1 << (x))
804
805#define HW_DCP_CHANNELCTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x20))
806#define HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(x) (1 << (x))
807
808#define HW_DCP_CH0CMDPTR (*(volatile unsigned long *)(HW_DCP_BASE + 0x100))
809
810#define HW_DCP_CH0SEMA (*(volatile unsigned long *)(HW_DCP_BASE + 0x110))
811#define HW_DCP_CH0SEMA__INCREMENT(x) (x)
812#define HW_DCP_CH0SEMA__VALUE_BP 16
813#define HW_DCP_CH0SEMA__VALUE_BM (0xff << 16)
814#define HW_DCP_CH0STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x120))
815
816#define HW_DCP_CTRL0__INTERRUPT_ENABLE (1 << 0)
817#define HW_DCP_CTRL0__DECR_SEMAPHORE (1 << 1)
818#define HW_DCP_CTRL0__ENABLE_MEMCOPY (1 << 4)
819#define HW_DCP_CTRL0__ENABLE_CIPHER (1 << 5)
820#define HW_DCP_CTRL0__ENABLE_HASH (1 << 6)
821#define HW_DCP_CTRL0__CIPHER_ENCRYPT (1 << 8)
822#define HW_DCP_CTRL0__CIPHER_INIT (1 << 9)
823#define HW_DCP_CTRL0__OTP_KEY (1 << 10)
824#define HW_DCP_CTRL0__HASH_INIT (1 << 12)
825#define HW_DCP_CTRL0__HASH_TERM (1 << 13)
826#define HW_DCP_CTRL0__HASH_OUTPUT (1 << 15)
827
828#define HW_DCP_CTRL1__CIPHER_SELECT_BP 0
829#define HW_DCP_CTRL1__CIPHER_SELECT_BM 0xf
830#define HW_DCP_CTRL1__CIPHER_SELECT__AES128 0
831#define HW_DCP_CTRL1__CIPHER_MODE_BP 4
832#define HW_DCP_CTRL1__CIPHER_MODE_BM 0xf0
833#define HW_DCP_CTRL1__CIPHER_MODE__CBC (1 << 4)
834#define HW_DCP_CTRL1__HASH_SELECT_BP 4
835#define HW_DCP_CTRL1__HASH_SELECT_BM 0xf00
836
837struct dcp_packet_t
838{
839 unsigned long next;
840 unsigned long ctrl0;
841 unsigned long ctrl1;
842 unsigned long src_buf;
843 unsigned long dst_buf;
844 unsigned long buf_sz;
845 unsigned long payload_ptr;
846 unsigned long status;
847} __attribute__((packed));
848
849/**
850 *
851 * Misc
852 *
853 */
854
855void memcpy(uint8_t *dst, const uint8_t *src, uint32_t length)
856{
857 for(uint32_t i = 0; i < length; i++)
858 dst[i] = src[i];
859}
860
861void memset(uint8_t *dst, uint8_t fill, uint32_t length)
862{
863 for(uint32_t i = 0; i < length; i++)
864 dst[i] = fill;
865}
866
867/**
868 *
869 * USB stack
870 *
871 */
872
873static struct usb_device_descriptor __attribute__((aligned(2)))
874 device_descriptor=
875{
876 .bLength = sizeof(struct usb_device_descriptor),
877 .bDescriptorType = USB_DT_DEVICE,
878 .bcdUSB = 0x0200,
879 .bDeviceClass = USB_CLASS_PER_INTERFACE,
880 .bDeviceSubClass = 0,
881 .bDeviceProtocol = 0,
882 .bMaxPacketSize0 = 64,
883 .idVendor = HWEMUL_USB_VID,
884 .idProduct = HWEMUL_USB_PID,
885 .bcdDevice = HWEMUL_VERSION_MAJOR << 8 | HWEMUL_VERSION_MINOR,
886 .iManufacturer = 1,
887 .iProduct = 2,
888 .iSerialNumber = 3,
889 .bNumConfigurations = 1
890};
891
892#define USB_MAX_CURRENT 200
893
894static struct usb_config_descriptor __attribute__((aligned(2)))
895 config_descriptor =
896{
897 .bLength = sizeof(struct usb_config_descriptor),
898 .bDescriptorType = USB_DT_CONFIG,
899 .wTotalLength = 0, /* will be filled in later */
900 .bNumInterfaces = 1,
901 .bConfigurationValue = 1,
902 .iConfiguration = 0,
903 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
904 .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */
905};
906
907/* main interface */
908static struct usb_interface_descriptor __attribute__((aligned(2)))
909 interface_descriptor =
910{
911 .bLength = sizeof(struct usb_interface_descriptor),
912 .bDescriptorType = USB_DT_INTERFACE,
913 .bInterfaceNumber = 0,
914 .bAlternateSetting = 0,
915 .bNumEndpoints = 3,
916 .bInterfaceClass = HWEMUL_CLASS,
917 .bInterfaceSubClass = HWEMUL_SUBCLASS,
918 .bInterfaceProtocol = HWEMUL_PROTOCOL,
919 .iInterface = 4
920};
921
922
923static struct usb_endpoint_descriptor __attribute__((aligned(2)))
924 endpoint_descriptor =
925{
926 .bLength = sizeof(struct usb_endpoint_descriptor),
927 .bDescriptorType = USB_DT_ENDPOINT,
928 .bEndpointAddress = 0,
929 .bmAttributes = USB_ENDPOINT_XFER_BULK,
930 .wMaxPacketSize = 0,
931 .bInterval = 0
932};
933
934static const struct usb_string_descriptor __attribute__((aligned(2)))
935 usb_string_iManufacturer =
936{
937 24,
938 USB_DT_STRING,
939 {'R', 'o', 'c', 'k', 'b', 'o', 'x', '.', 'o', 'r', 'g'}
940};
941
942static const struct usb_string_descriptor __attribute__((aligned(2)))
943 usb_string_iProduct =
944{
945 52,
946 USB_DT_STRING,
947 {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ',
948 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ',
949 'e', 'm', 'u', 'l', 'a', 't', 'e', 'r'}
950};
951
952static struct usb_string_descriptor __attribute__((aligned(2)))
953 usb_string_iSerial =
954{
955 84,
956 USB_DT_STRING,
957 {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
958 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
959 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
960 '0', '0', '0', '0', '0', '0', '0', '0'}
961};
962
963static struct usb_string_descriptor __attribute__((aligned(2)))
964 usb_string_iInterface =
965{
966 28,
967 USB_DT_STRING,
968 {'A', 'c', 'i', 'd', ' ',
969 '0' + (HWEMUL_VERSION_MAJOR >> 4), '0' + (HWEMUL_VERSION_MAJOR & 0xf), '.',
970 '0' + (HWEMUL_VERSION_MINOR >> 4), '0' + (HWEMUL_VERSION_MINOR & 0xf), '.',
971 '0' + (HWEMUL_VERSION_REV >> 4), '0' + (HWEMUL_VERSION_REV & 0xf) }
972};
973
974/* this is stringid #0: languages supported */
975static const struct usb_string_descriptor __attribute__((aligned(2)))
976 lang_descriptor =
977{
978 4,
979 USB_DT_STRING,
980 {0x0409} /* LANGID US English */
981};
982
983#define USB_NUM_STRINGS 5
984
985static const struct usb_string_descriptor* const usb_strings[USB_NUM_STRINGS] =
986{
987 &lang_descriptor,
988 &usb_string_iManufacturer,
989 &usb_string_iProduct,
990 &usb_string_iSerial,
991 &usb_string_iInterface
992};
993
994uint8_t *usb_buffer = oc_bufferstart;
995uint32_t usb_buffer_size = 0;
996
997#define EP_BULK 1
998#define EP_INT 2
999
1000static void set_config(void)
1001{
1002 usb_drv_configure_endpoint(EP_BULK, USB_ENDPOINT_XFER_BULK);
1003 usb_drv_configure_endpoint(EP_INT, USB_ENDPOINT_XFER_INT);
1004}
1005
1006static void handle_std_dev_desc(struct usb_ctrlrequest *req)
1007{
1008 int size;
1009 const void* ptr = NULL;
1010 unsigned index = req->wValue & 0xff;
1011
1012 switch(req->wValue >> 8)
1013 {
1014 case USB_DT_DEVICE:
1015 ptr = &device_descriptor;
1016 size = sizeof(struct usb_device_descriptor);
1017 break;
1018 case USB_DT_OTHER_SPEED_CONFIG:
1019 case USB_DT_CONFIG:
1020 {
1021 int max_packet_size;
1022
1023 /* config desc */
1024 if((req->wValue >> 8) ==USB_DT_CONFIG)
1025 {
1026 max_packet_size = (usb_drv_port_speed() ? 512 : 64);
1027 config_descriptor.bDescriptorType = USB_DT_CONFIG;
1028 }
1029 else
1030 {
1031 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
1032 config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
1033 }
1034 size = sizeof(struct usb_config_descriptor);
1035
1036 /* interface */
1037 memcpy(usb_buffer + size, (void *)&interface_descriptor,
1038 sizeof(interface_descriptor));
1039 size += sizeof(interface_descriptor);
1040 /* endpoint 1: bulk out */
1041 endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT;
1042 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
1043 endpoint_descriptor.wMaxPacketSize = 512;
1044 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
1045 sizeof(endpoint_descriptor));
1046 size += sizeof(endpoint_descriptor);
1047 /* endpoint 2: bulk in */
1048 endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN;
1049 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
1050 endpoint_descriptor.wMaxPacketSize = 512;
1051 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
1052 sizeof(endpoint_descriptor));
1053 size += sizeof(endpoint_descriptor);
1054 /* endpoint 3: int in */
1055 endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN;
1056 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT;
1057 endpoint_descriptor.wMaxPacketSize = 1024;
1058 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
1059 sizeof(endpoint_descriptor));
1060 size += sizeof(endpoint_descriptor);
1061
1062 /* fix config descriptor */
1063 config_descriptor.bNumInterfaces = 1;
1064 config_descriptor.wTotalLength = size;
1065 memcpy(usb_buffer, (void *)&config_descriptor, sizeof(config_descriptor));
1066
1067 ptr = usb_buffer;
1068 break;
1069 }
1070 case USB_DT_STRING:
1071 if(index < USB_NUM_STRINGS)
1072 {
1073 size = usb_strings[index]->bLength;
1074 ptr = usb_strings[index];
1075 }
1076 else
1077 usb_drv_stall(EP_CONTROL, true, true);
1078 break;
1079 default:
1080 break;
1081 }
1082
1083 if(ptr)
1084 {
1085 int length = MIN(size, req->wLength);
1086
1087 if(ptr != usb_buffer)
1088 memcpy(usb_buffer, ptr, length);
1089
1090 usb_drv_send(EP_CONTROL, usb_buffer, length);
1091 usb_drv_recv(EP_CONTROL, NULL, 0);
1092 }
1093 else
1094 usb_drv_stall(EP_CONTROL, true, true);
1095}
1096
1097static void handle_std_dev_req(struct usb_ctrlrequest *req)
1098{
1099 switch(req->bRequest)
1100 {
1101 case USB_REQ_GET_CONFIGURATION:
1102 usb_buffer[0] = 1;
1103 usb_drv_send(EP_CONTROL, usb_buffer, 1);
1104 usb_drv_recv(EP_CONTROL, NULL, 0);
1105 break;
1106 case USB_REQ_SET_CONFIGURATION:
1107 usb_drv_send(EP_CONTROL, NULL, 0);
1108 set_config();
1109 break;
1110 case USB_REQ_GET_DESCRIPTOR:
1111 handle_std_dev_desc(req);
1112 break;
1113 case USB_REQ_SET_ADDRESS:
1114 usb_drv_send(EP_CONTROL, NULL, 0);
1115 usb_drv_set_address(req->wValue);
1116 break;
1117 case USB_REQ_GET_STATUS:
1118 usb_buffer[0] = 0;
1119 usb_buffer[1] = 0;
1120 usb_drv_send(EP_CONTROL, usb_buffer, 2);
1121 usb_drv_recv(EP_CONTROL, NULL, 0);
1122 break;
1123 default:
1124 usb_drv_stall(EP_CONTROL, true, true);
1125 }
1126}
1127
1128static void handle_std_req(struct usb_ctrlrequest *req)
1129{
1130 switch(req->bRequestType & USB_RECIP_MASK)
1131 {
1132 case USB_RECIP_DEVICE:
1133 return handle_std_dev_req(req);
1134 default:
1135 usb_drv_stall(EP_CONTROL, true, true);
1136 }
1137}
1138
1139struct usb_resp_info_version_t g_version =
1140{
1141 .major = HWEMUL_VERSION_MAJOR,
1142 .minor = HWEMUL_VERSION_MINOR,
1143 .revision = HWEMUL_VERSION_REV
1144};
1145
1146struct usb_resp_info_layout_t g_layout;
1147
1148struct usb_resp_info_stmp_t g_stmp;
1149
1150struct usb_resp_info_features_t g_features =
1151{
1152 .feature_mask = HWEMUL_FEATURE_LOG | HWEMUL_FEATURE_MEM |
1153 HWEMUL_FEATURE_CALL | HWEMUL_FEATURE_JUMP | HWEMUL_FEATURE_AES_OTP
1154};
1155
1156static void fill_layout_info(void)
1157{
1158 g_layout.oc_code_start = (uint32_t)oc_codestart;
1159 g_layout.oc_code_size = oc_codesize;
1160 g_layout.oc_stack_start = (uint32_t)oc_stackstart;
1161 g_layout.oc_stack_size = oc_stacksize;
1162 g_layout.oc_buffer_start = (uint32_t)oc_bufferstart;
1163 g_layout.oc_buffer_size = oc_buffersize;
1164}
1165
1166static void fill_stmp_info(void)
1167{
1168 g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
1169 g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION);
1170 g_stmp.is_supported = g_stmp.chipid == 0x3780 || g_stmp.chipid == 0x3700 ||
1171 g_stmp.chipid == 0x3b00;
1172}
1173
1174static void handle_get_info(struct usb_ctrlrequest *req)
1175{
1176 void *ptr = NULL;
1177 int size = 0;
1178 switch(req->wIndex)
1179 {
1180 case HWEMUL_INFO_VERSION:
1181 ptr = &g_version;
1182 size = sizeof(g_version);
1183 break;
1184 case HWEMUL_INFO_LAYOUT:
1185 fill_layout_info();
1186 ptr = &g_layout;
1187 size = sizeof(g_layout);
1188 break;
1189 case HWEMUL_INFO_STMP:
1190 fill_stmp_info();
1191 ptr = &g_stmp;
1192 size = sizeof(g_stmp);
1193 break;
1194 case HWEMUL_INFO_FEATURES:
1195 ptr = &g_features;
1196 size = sizeof(g_features);
1197 break;
1198 default:
1199 usb_drv_stall(EP_CONTROL, true, true);
1200 }
1201
1202 if(ptr)
1203 {
1204 int length = MIN(size, req->wLength);
1205
1206 if(ptr != usb_buffer)
1207 memcpy(usb_buffer, ptr, length);
1208 usb_drv_send(EP_CONTROL, usb_buffer, length);
1209 usb_drv_recv(EP_CONTROL, NULL, 0);
1210 }
1211}
1212
1213static void handle_get_log(struct usb_ctrlrequest *req)
1214{
1215 enable_logf(false);
1216 int length = logf_readback(usb_buffer, MIN(req->wLength, usb_buffer_size));
1217 usb_drv_send(EP_CONTROL, usb_buffer, length);
1218 usb_drv_recv(EP_CONTROL, NULL, 0);
1219 enable_logf(true);
1220}
1221
1222static void handle_rw_mem(struct usb_ctrlrequest *req)
1223{
1224 uint32_t addr = req->wValue | req->wIndex << 16;
1225 uint16_t length = req->wLength;
1226
1227 if(req->bRequestType & USB_DIR_IN)
1228 {
1229 memcpy(usb_buffer, (void *)addr, length);
1230 asm volatile("nop" : : : "memory");
1231 usb_drv_send(EP_CONTROL, usb_buffer, length);
1232 usb_drv_recv(EP_CONTROL, NULL, 0);
1233 }
1234 else
1235 {
1236 int size = usb_drv_recv(EP_CONTROL, usb_buffer, length);
1237 asm volatile("nop" : : : "memory");
1238 if(size != length)
1239 usb_drv_stall(EP_CONTROL, true, true);
1240 else
1241 {
1242 memcpy((void *)addr, usb_buffer, length);
1243 usb_drv_send(EP_CONTROL, NULL, 0);
1244 }
1245 }
1246}
1247
1248static void handle_call_jump(struct usb_ctrlrequest *req)
1249{
1250 uint32_t addr = req->wValue | req->wIndex << 16;
1251
1252 if(req->bRequest == HWEMUL_CALL)
1253 ((void (*)(void))addr)();
1254 else
1255 asm volatile("bx %0\n" : : "r" (addr) : "memory");
1256}
1257
1258static void do_aes_otp(void *buffer, unsigned length, unsigned params)
1259{
1260 static struct dcp_packet_t dcp_packet;
1261
1262 bool encrypt = !!(params & HWEMUL_AES_OTP_ENCRYPT);
1263 /* reset DCP */
1264 __REG_SET(HW_DCP_CTRL) = 0x80000000;
1265 /* clear clock gate */
1266 __REG_CLR(HW_DCP_CTRL) = 0xc0000000;
1267 /* enable dma for channel 0 */
1268 __REG_SET(HW_DCP_CHANNELCTRL) = HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(0);
1269 /* prepare packet */
1270 dcp_packet.next = 0;
1271
1272 dcp_packet.ctrl0 = HW_DCP_CTRL0__INTERRUPT_ENABLE |
1273 HW_DCP_CTRL0__DECR_SEMAPHORE | HW_DCP_CTRL0__CIPHER_INIT |
1274 HW_DCP_CTRL0__ENABLE_CIPHER | HW_DCP_CTRL0__OTP_KEY |
1275 (encrypt ? HW_DCP_CTRL0__CIPHER_ENCRYPT : 0);
1276 dcp_packet.ctrl1 = HW_DCP_CTRL1__CIPHER_SELECT__AES128 |
1277 HW_DCP_CTRL1__CIPHER_MODE__CBC;
1278 dcp_packet.src_buf = (unsigned long)buffer + 16;
1279 dcp_packet.dst_buf = (unsigned long)buffer + 16;
1280 dcp_packet.buf_sz = length - 16;
1281 dcp_packet.payload_ptr = (unsigned long)buffer;
1282 dcp_packet.status = 0;
1283
1284 asm volatile("":::"memory");
1285 /* kick */
1286 HW_DCP_CH0CMDPTR = (unsigned long)&dcp_packet;
1287 HW_DCP_CH0SEMA = HW_DCP_CH0SEMA__INCREMENT(1);
1288 /* wait */
1289 while(!(HW_DCP_STAT & HW_DCP_STAT__IRQ(0)));
1290
1291 usb_drv_send_nonblocking(EP_INT, buffer, length);
1292}
1293
1294static void handle_aes_otp(struct usb_ctrlrequest *req)
1295{
1296 uint16_t length = req->wLength;
1297
1298 int size = usb_drv_recv(EP_CONTROL, usb_buffer, length);
1299 if(size != length)
1300 usb_drv_stall(EP_CONTROL, true, true);
1301 else
1302 usb_drv_send(EP_CONTROL, NULL, 0);
1303 do_aes_otp(usb_buffer, length, req->wValue);
1304}
1305
1306static void handle_class_dev_req(struct usb_ctrlrequest *req)
1307{
1308 switch(req->bRequest)
1309 {
1310 case HWEMUL_GET_INFO:
1311 handle_get_info(req);
1312 break;
1313 case HWEMUL_GET_LOG:
1314 handle_get_log(req);
1315 break;
1316 case HWEMUL_RW_MEM:
1317 handle_rw_mem(req);
1318 break;
1319 case HWEMUL_CALL:
1320 case HWEMUL_JUMP:
1321 handle_call_jump(req);
1322 break;
1323 case HWEMUL_AES_OTP:
1324 handle_aes_otp(req);
1325 break;
1326 default:
1327 usb_drv_stall(EP_CONTROL, true, true);
1328 }
1329}
1330
1331static void handle_class_req(struct usb_ctrlrequest *req)
1332{
1333 switch(req->bRequestType & USB_RECIP_MASK)
1334 {
1335 case USB_RECIP_DEVICE:
1336 return handle_class_dev_req(req);
1337 default:
1338 usb_drv_stall(EP_CONTROL, true, true);
1339 }
1340}
1341
1342/**
1343 *
1344 * Main
1345 *
1346 */
1347
1348void main(uint32_t arg)
1349{
1350 usb_buffer_size = oc_buffersize;
1351
1352 logf("hwemul %d.%d.%d\n", HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR,
1353 HWEMUL_VERSION_REV);
1354 logf("argument: 0x%08x\n", arg);
1355
1356 /* we don't know if USB was connected or not. In USB recovery mode it will
1357 * but in other cases it might not be. In doubt, disconnect */
1358 REG_USBCMD &= ~USBCMD_RUN;
1359 /* enable USB PHY PLL */
1360 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
1361 /* power up USB PHY */
1362 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
1363 //__REG_CLR(HW_USBPHY_PWD) = HW_USBPHY_PWD__ALL;
1364 HW_USBPHY_PWD = 0;
1365 /* enable USB controller */
1366 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
1367 /* reset the controller */
1368 REG_USBCMD |= USBCMD_CTRL_RESET;
1369 while (REG_USBCMD & USBCMD_CTRL_RESET);
1370 /* put it in device mode */
1371 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
1372 /* reset address */
1373 REG_DEVICEADDR = 0;
1374 /* prepare qh array */
1375 qh_array[0].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
1376 qh_array[1].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
1377 qh_array[2].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
1378 qh_array[3].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
1379 /* setup qh */
1380 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
1381 /* clear setup status */
1382 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1383 /* run! */
1384 REG_USBCMD |= USBCMD_RUN;
1385
1386 while(1)
1387 {
1388 /* wait for setup */
1389 while(!(REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0))
1390 ;
1391 /* clear setup status */
1392 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1393 /* check request */
1394 asm volatile("":::"memory");
1395 struct usb_ctrlrequest *req = (void *)&qh_array[0].setup_buffer[0];
1396
1397 switch(req->bRequestType & USB_TYPE_MASK)
1398 {
1399 case USB_TYPE_STANDARD:
1400 handle_std_req(req);
1401 break;
1402 case USB_TYPE_CLASS:
1403 handle_class_req(req);
1404 break;
1405 default:
1406 usb_drv_stall(EP_CONTROL, true, true);
1407 }
1408 }
1409}