1 #include "usb3_hw.h"
2 #include "usb3_drv.h"
3 #include <cpu_func.h>
4
5 extern void usb3_handle_dev_intr(usb3_pcd_t *pcd, uint32_t event);
6 extern int usb3_handle_ep_intr(usb3_pcd_t *pcd, uint32_t physep, uint32_t event);
7 int usb_connected = 0;
8
ena_eventbuf_intr(usb3_device_t * dev)9 void ena_eventbuf_intr(usb3_device_t *dev)
10 {
11 uint32_t eventsiz;
12
13 eventsiz =
14 usb3_rd32(&dev->core_global_regs->geventbuf[0].geventsiz);
15 eventsiz &= ~USB3_EVENTSIZ_INT_MSK_BIT;
16 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventsiz,
17 eventsiz);
18 }
19
dis_eventbuf_intr(usb3_device_t * dev)20 void dis_eventbuf_intr(usb3_device_t *dev)
21 {
22 uint32_t eventsiz;
23
24 eventsiz =
25 usb3_rd32(&dev->core_global_regs->geventbuf[0].geventsiz);
26 eventsiz |= USB3_EVENTSIZ_INT_MSK_BIT;
27 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventsiz,
28 eventsiz);
29 }
30
usb3_dis_flush_eventbuf_intr(usb3_device_t * dev)31 void usb3_dis_flush_eventbuf_intr(usb3_device_t *dev)
32 {
33 uint32_t cnt;
34 uint32_t gevntsize;
35
36 dis_eventbuf_intr(dev);
37 cnt = usb3_rd32(&dev->core_global_regs->geventbuf[0].geventcnt);
38 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventcnt, cnt);
39
40 if (0 != cnt) {
41 gevntsize = sizeof(dev->event_buf[0]) * USB3_EVENT_BUF_SIZE;
42 usb_info("evnt count 0x%x, evnt buf size 0x%x\n", cnt, gevntsize);
43 dev->event_ptr += cnt % gevntsize;
44 }
45 }
46
get_eventbuf_count(usb3_device_t * dev)47 int get_eventbuf_count(usb3_device_t *dev)
48 {
49 uint32_t cnt;
50
51 cnt = usb3_rd32(&dev->core_global_regs->geventbuf[0].geventcnt);
52
53 return cnt & USB3_EVENTCNT_CNT_BITS;
54 }
55
update_eventbuf_count(usb3_device_t * dev,int cnt)56 void update_eventbuf_count(usb3_device_t *dev, int cnt)
57 {
58 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventcnt, cnt);
59 }
60
get_eventbuf_event(usb3_device_t * dev,int size)61 uint32_t get_eventbuf_event(usb3_device_t *dev, int size)
62 {
63 uint32_t event;
64
65 event = *dev->event_ptr++;
66
67 if (dev->event_ptr >= dev->event_buf + size)
68 dev->event_ptr = dev->event_buf;
69 return event;
70 }
71
usb3_init_eventbuf(usb3_device_t * dev,uint32_t size,phys_addr_t dma_addr)72 void usb3_init_eventbuf(usb3_device_t *dev, uint32_t size, phys_addr_t dma_addr)
73 {
74 dma_addr = map_to_dma_addr(dma_addr);
75
76 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventadr_lo,
77 dma_addr & 0xffffffff);
78
79 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventadr_hi, 0);
80 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventsiz,
81 size << 2);
82
83 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventcnt, 0);
84 }
85
usb3_enable_device_interrupts(usb3_device_t * dev)86 void usb3_enable_device_interrupts(usb3_device_t *dev)
87 {
88 uint32_t eventsiz;
89
90 /* Clear any pending interrupts */
91 usb3_dis_flush_eventbuf_intr(dev);
92 /**
93 * This routine enables the Event Buffer interrupt.
94 */
95 eventsiz =
96 usb3_rd32(&dev->core_global_regs->geventbuf[0].geventsiz);
97 eventsiz &= ~USB3_EVENTSIZ_INT_MSK_BIT;
98 usb3_wr32(&dev->core_global_regs->geventbuf[0].geventsiz,
99 eventsiz);
100 /* Enable device interrupts */
101 usb3_wr32(&dev->pcd.dev_global_regs->devten,
102 USB3_DEVTEN_DISCONN_BIT | USB3_DEVTEN_CONNDONE_BIT | USB3_DEVTEN_USBRESET_BIT | USB3_DEVTEN_HIBER_REQ_EVT_BIT | USB3_DEVTEN_WKUP_BIT | USB3_DEVTEN_EOPF_BIT);
103 }
104
usb3_handle_event(usb3_device_t * dev)105 void usb3_handle_event(usb3_device_t *dev)
106 {
107 usb3_pcd_t *pcd = &dev->pcd;
108 uint32_t event, count, physep;
109 int intr, i;
110 intr=0;
111
112 invalidate_dcache_all();
113 count = get_eventbuf_count(dev);
114 if ((count & USB3_EVENTCNT_CNT_BITS) == USB3_EVENTCNT_CNT_BITS
115 || count >= USB3_EVENT_BUF_SIZE * 4) {
116 update_eventbuf_count(dev, count);
117 count = 0;
118 }
119
120 for (i = 0; i < count; i += 4) {
121 event = get_eventbuf_event(dev, USB3_EVENT_BUF_SIZE);
122 update_eventbuf_count(dev, 4);
123 if (event == 0) {
124 /* Ignore null events */
125 continue;
126 }
127
128 if (event & USB3_EVENT_NON_EP_BIT) {
129 intr = event & USB3_EVENT_INTTYPE_BITS;
130
131 if (intr ==
132 (USB3_EVENT_DEV_INT << USB3_EVENT_INTTYPE_SHIFT)) {
133 usb3_handle_dev_intr(pcd, event);
134 } else {
135 /* @todo Handle non-Device interrupts
136 * (OTG, CarKit, I2C)
137 */
138 }
139 } else {
140 physep = (event >> USB3_DEPEVT_EPNUM_SHIFT) &
141 (USB3_DEPEVT_EPNUM_BITS >> USB3_DEPEVT_EPNUM_SHIFT);
142 usb3_handle_ep_intr(pcd, physep, event);
143 }
144 }
145 }
146
147