]> git.proxmox.com Git - mirror_qemu.git/blame - hw/usb/hcd-dwc2.c
Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20200716-pull-request' into...
[mirror_qemu.git] / hw / usb / hcd-dwc2.c
CommitLineData
153ef166
PZ
1/*
2 * dwc-hsotg (dwc2) USB host controller emulation
3 *
4 * Based on hw/usb/hcd-ehci.c and hw/usb/hcd-ohci.c
5 *
6 * Note that to use this emulation with the dwc-otg driver in the
7 * Raspbian kernel, you must pass the option "dwc_otg.fiq_fsm_enable=0"
8 * on the kernel command line.
9 *
10 * Some useful documentation used to develop this emulation can be
11 * found online (as of April 2020) at:
12 *
13 * http://www.capital-micro.com/PDF/CME-M7_Family_User_Guide_EN.pdf
14 * which has a pretty complete description of the controller starting
15 * on page 370.
16 *
17 * https://sourceforge.net/p/wive-ng/wive-ng-mt/ci/master/tree/docs/DataSheets/RT3050_5x_V2.0_081408_0902.pdf
18 * which has a description of the controller registers starting on
19 * page 130.
20 *
21 * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
22 *
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 */
33
34#include "qemu/osdep.h"
35#include "qemu/units.h"
36#include "qapi/error.h"
37#include "hw/usb/dwc2-regs.h"
38#include "hw/usb/hcd-dwc2.h"
39#include "migration/vmstate.h"
40#include "trace.h"
41#include "qemu/log.h"
42#include "qemu/error-report.h"
43#include "qemu/main-loop.h"
44#include "hw/qdev-properties.h"
45
46#define USB_HZ_FS 12000000
47#define USB_HZ_HS 96000000
48#define USB_FRMINTVL 12000
49
50/* nifty macros from Arnon's EHCI version */
51#define get_field(data, field) \
52 (((data) & field##_MASK) >> field##_SHIFT)
53
54#define set_field(data, newval, field) do { \
55 uint32_t val = *(data); \
56 val &= ~field##_MASK; \
57 val |= ((newval) << field##_SHIFT) & field##_MASK; \
58 *(data) = val; \
59} while (0)
60
61#define get_bit(data, bitmask) \
62 (!!((data) & (bitmask)))
63
64/* update irq line */
65static inline void dwc2_update_irq(DWC2State *s)
66{
67 static int oldlevel;
68 int level = 0;
69
70 if ((s->gintsts & s->gintmsk) && (s->gahbcfg & GAHBCFG_GLBL_INTR_EN)) {
71 level = 1;
72 }
73 if (level != oldlevel) {
74 oldlevel = level;
75 trace_usb_dwc2_update_irq(level);
76 qemu_set_irq(s->irq, level);
77 }
78}
79
80/* flag interrupt condition */
81static inline void dwc2_raise_global_irq(DWC2State *s, uint32_t intr)
82{
83 if (!(s->gintsts & intr)) {
84 s->gintsts |= intr;
85 trace_usb_dwc2_raise_global_irq(intr);
86 dwc2_update_irq(s);
87 }
88}
89
90static inline void dwc2_lower_global_irq(DWC2State *s, uint32_t intr)
91{
92 if (s->gintsts & intr) {
93 s->gintsts &= ~intr;
94 trace_usb_dwc2_lower_global_irq(intr);
95 dwc2_update_irq(s);
96 }
97}
98
99static inline void dwc2_raise_host_irq(DWC2State *s, uint32_t host_intr)
100{
101 if (!(s->haint & host_intr)) {
102 s->haint |= host_intr;
103 s->haint &= 0xffff;
104 trace_usb_dwc2_raise_host_irq(host_intr);
105 if (s->haint & s->haintmsk) {
106 dwc2_raise_global_irq(s, GINTSTS_HCHINT);
107 }
108 }
109}
110
111static inline void dwc2_lower_host_irq(DWC2State *s, uint32_t host_intr)
112{
113 if (s->haint & host_intr) {
114 s->haint &= ~host_intr;
115 trace_usb_dwc2_lower_host_irq(host_intr);
116 if (!(s->haint & s->haintmsk)) {
117 dwc2_lower_global_irq(s, GINTSTS_HCHINT);
118 }
119 }
120}
121
122static inline void dwc2_update_hc_irq(DWC2State *s, int index)
123{
124 uint32_t host_intr = 1 << (index >> 3);
125
126 if (s->hreg1[index + 2] & s->hreg1[index + 3]) {
127 dwc2_raise_host_irq(s, host_intr);
128 } else {
129 dwc2_lower_host_irq(s, host_intr);
130 }
131}
132
133/* set a timer for EOF */
134static void dwc2_eof_timer(DWC2State *s)
135{
136 timer_mod(s->eof_timer, s->sof_time + s->usb_frame_time);
137}
138
139/* Set a timer for EOF and generate SOF event */
140static void dwc2_sof(DWC2State *s)
141{
142 s->sof_time += s->usb_frame_time;
143 trace_usb_dwc2_sof(s->sof_time);
144 dwc2_eof_timer(s);
145 dwc2_raise_global_irq(s, GINTSTS_SOF);
146}
147
148/* Do frame processing on frame boundary */
149static void dwc2_frame_boundary(void *opaque)
150{
151 DWC2State *s = opaque;
152 int64_t now;
153 uint16_t frcnt;
154
155 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
156
157 /* Frame boundary, so do EOF stuff here */
158
159 /* Increment frame number */
160 frcnt = (uint16_t)((now - s->sof_time) / s->fi);
161 s->frame_number = (s->frame_number + frcnt) & 0xffff;
162 s->hfnum = s->frame_number & HFNUM_MAX_FRNUM;
163
164 /* Do SOF stuff here */
165 dwc2_sof(s);
166}
167
168/* Start sending SOF tokens on the USB bus */
169static void dwc2_bus_start(DWC2State *s)
170{
171 trace_usb_dwc2_bus_start();
172 s->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
173 dwc2_eof_timer(s);
174}
175
176/* Stop sending SOF tokens on the USB bus */
177static void dwc2_bus_stop(DWC2State *s)
178{
179 trace_usb_dwc2_bus_stop();
180 timer_del(s->eof_timer);
181}
182
183static USBDevice *dwc2_find_device(DWC2State *s, uint8_t addr)
184{
185 USBDevice *dev;
186
187 trace_usb_dwc2_find_device(addr);
188
189 if (!(s->hprt0 & HPRT0_ENA)) {
190 trace_usb_dwc2_port_disabled(0);
191 } else {
192 dev = usb_find_device(&s->uport, addr);
193 if (dev != NULL) {
194 trace_usb_dwc2_device_found(0);
195 return dev;
196 }
197 }
198
199 trace_usb_dwc2_device_not_found();
200 return NULL;
201}
202
203static const char *pstatus[] = {
204 "USB_RET_SUCCESS", "USB_RET_NODEV", "USB_RET_NAK", "USB_RET_STALL",
205 "USB_RET_BABBLE", "USB_RET_IOERROR", "USB_RET_ASYNC",
206 "USB_RET_ADD_TO_QUEUE", "USB_RET_REMOVE_FROM_QUEUE"
207};
208
209static uint32_t pintr[] = {
210 HCINTMSK_XFERCOMPL, HCINTMSK_XACTERR, HCINTMSK_NAK, HCINTMSK_STALL,
211 HCINTMSK_BBLERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR,
212 HCINTMSK_XACTERR
213};
214
215static const char *types[] = {
216 "Ctrl", "Isoc", "Bulk", "Intr"
217};
218
219static const char *dirs[] = {
220 "Out", "In"
221};
222
223static void dwc2_handle_packet(DWC2State *s, uint32_t devadr, USBDevice *dev,
224 USBEndpoint *ep, uint32_t index, bool send)
225{
226 DWC2Packet *p;
227 uint32_t hcchar = s->hreg1[index];
228 uint32_t hctsiz = s->hreg1[index + 4];
229 uint32_t hcdma = s->hreg1[index + 5];
230 uint32_t chan, epnum, epdir, eptype, mps, pid, pcnt, len, tlen, intr = 0;
231 uint32_t tpcnt, stsidx, actual = 0;
232 bool do_intr = false, done = false;
233
234 epnum = get_field(hcchar, HCCHAR_EPNUM);
235 epdir = get_bit(hcchar, HCCHAR_EPDIR);
236 eptype = get_field(hcchar, HCCHAR_EPTYPE);
237 mps = get_field(hcchar, HCCHAR_MPS);
238 pid = get_field(hctsiz, TSIZ_SC_MC_PID);
239 pcnt = get_field(hctsiz, TSIZ_PKTCNT);
240 len = get_field(hctsiz, TSIZ_XFERSIZE);
241 assert(len <= DWC2_MAX_XFER_SIZE);
242 chan = index >> 3;
243 p = &s->packet[chan];
244
245 trace_usb_dwc2_handle_packet(chan, dev, &p->packet, epnum, types[eptype],
246 dirs[epdir], mps, len, pcnt);
247
248 if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
249 pid = USB_TOKEN_SETUP;
250 } else {
251 pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
252 }
253
254 if (send) {
255 tlen = len;
256 if (p->small) {
257 if (tlen > mps) {
258 tlen = mps;
259 }
260 }
261
262 if (pid != USB_TOKEN_IN) {
263 trace_usb_dwc2_memory_read(hcdma, tlen);
264 if (dma_memory_read(&s->dma_as, hcdma,
265 s->usb_buf[chan], tlen) != MEMTX_OK) {
266 qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_read failed\n",
267 __func__);
268 }
269 }
270
271 usb_packet_init(&p->packet);
272 usb_packet_setup(&p->packet, pid, ep, 0, hcdma,
273 pid != USB_TOKEN_IN, true);
274 usb_packet_addbuf(&p->packet, s->usb_buf[chan], tlen);
275 p->async = DWC2_ASYNC_NONE;
276 usb_handle_packet(dev, &p->packet);
277 } else {
278 tlen = p->len;
279 }
280
281 stsidx = -p->packet.status;
282 assert(stsidx < sizeof(pstatus) / sizeof(*pstatus));
283 actual = p->packet.actual_length;
284 trace_usb_dwc2_packet_status(pstatus[stsidx], actual);
285
286babble:
287 if (p->packet.status != USB_RET_SUCCESS &&
288 p->packet.status != USB_RET_NAK &&
289 p->packet.status != USB_RET_STALL &&
290 p->packet.status != USB_RET_ASYNC) {
291 trace_usb_dwc2_packet_error(pstatus[stsidx]);
292 }
293
294 if (p->packet.status == USB_RET_ASYNC) {
295 trace_usb_dwc2_async_packet(&p->packet, chan, dev, epnum,
296 dirs[epdir], tlen);
297 usb_device_flush_ep_queue(dev, ep);
298 assert(p->async != DWC2_ASYNC_INFLIGHT);
299 p->devadr = devadr;
300 p->epnum = epnum;
301 p->epdir = epdir;
302 p->mps = mps;
303 p->pid = pid;
304 p->index = index;
305 p->pcnt = pcnt;
306 p->len = tlen;
307 p->async = DWC2_ASYNC_INFLIGHT;
308 p->needs_service = false;
309 return;
310 }
311
312 if (p->packet.status == USB_RET_SUCCESS) {
313 if (actual > tlen) {
314 p->packet.status = USB_RET_BABBLE;
315 goto babble;
316 }
317
318 if (pid == USB_TOKEN_IN) {
319 trace_usb_dwc2_memory_write(hcdma, actual);
320 if (dma_memory_write(&s->dma_as, hcdma, s->usb_buf[chan],
321 actual) != MEMTX_OK) {
322 qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_write failed\n",
323 __func__);
324 }
325 }
326
327 tpcnt = actual / mps;
328 if (actual % mps) {
329 tpcnt++;
330 if (pid == USB_TOKEN_IN) {
331 done = true;
332 }
333 }
334
335 pcnt -= tpcnt < pcnt ? tpcnt : pcnt;
336 set_field(&hctsiz, pcnt, TSIZ_PKTCNT);
337 len -= actual < len ? actual : len;
338 set_field(&hctsiz, len, TSIZ_XFERSIZE);
339 s->hreg1[index + 4] = hctsiz;
340 hcdma += actual;
341 s->hreg1[index + 5] = hcdma;
342
343 if (!pcnt || len == 0 || actual == 0) {
344 done = true;
345 }
346 } else {
347 intr |= pintr[stsidx];
348 if (p->packet.status == USB_RET_NAK &&
349 (eptype == USB_ENDPOINT_XFER_CONTROL ||
350 eptype == USB_ENDPOINT_XFER_BULK)) {
351 /*
352 * for ctrl/bulk, automatically retry on NAK,
353 * but send the interrupt anyway
354 */
355 intr &= ~HCINTMSK_RESERVED14_31;
356 s->hreg1[index + 2] |= intr;
357 do_intr = true;
358 } else {
359 intr |= HCINTMSK_CHHLTD;
360 done = true;
361 }
362 }
363
364 usb_packet_cleanup(&p->packet);
365
366 if (done) {
367 hcchar &= ~HCCHAR_CHENA;
368 s->hreg1[index] = hcchar;
369 if (!(intr & HCINTMSK_CHHLTD)) {
370 intr |= HCINTMSK_CHHLTD | HCINTMSK_XFERCOMPL;
371 }
372 intr &= ~HCINTMSK_RESERVED14_31;
373 s->hreg1[index + 2] |= intr;
374 p->needs_service = false;
375 trace_usb_dwc2_packet_done(pstatus[stsidx], actual, len, pcnt);
376 dwc2_update_hc_irq(s, index);
377 return;
378 }
379
380 p->devadr = devadr;
381 p->epnum = epnum;
382 p->epdir = epdir;
383 p->mps = mps;
384 p->pid = pid;
385 p->index = index;
386 p->pcnt = pcnt;
387 p->len = len;
388 p->needs_service = true;
389 trace_usb_dwc2_packet_next(pstatus[stsidx], len, pcnt);
390 if (do_intr) {
391 dwc2_update_hc_irq(s, index);
392 }
393}
394
395/* Attach or detach a device on root hub */
396
397static const char *speeds[] = {
398 "low", "full", "high"
399};
400
401static void dwc2_attach(USBPort *port)
402{
403 DWC2State *s = port->opaque;
404 int hispd = 0;
405
406 trace_usb_dwc2_attach(port);
407 assert(port->index == 0);
408
409 if (!port->dev || !port->dev->attached) {
410 return;
411 }
412
413 assert(port->dev->speed <= USB_SPEED_HIGH);
414 trace_usb_dwc2_attach_speed(speeds[port->dev->speed]);
415 s->hprt0 &= ~HPRT0_SPD_MASK;
416
417 switch (port->dev->speed) {
418 case USB_SPEED_LOW:
419 s->hprt0 |= HPRT0_SPD_LOW_SPEED << HPRT0_SPD_SHIFT;
420 break;
421 case USB_SPEED_FULL:
422 s->hprt0 |= HPRT0_SPD_FULL_SPEED << HPRT0_SPD_SHIFT;
423 break;
424 case USB_SPEED_HIGH:
425 s->hprt0 |= HPRT0_SPD_HIGH_SPEED << HPRT0_SPD_SHIFT;
426 hispd = 1;
427 break;
428 }
429
430 if (hispd) {
431 s->usb_frame_time = NANOSECONDS_PER_SECOND / 8000; /* 125000 */
432 if (NANOSECONDS_PER_SECOND >= USB_HZ_HS) {
433 s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_HS; /* 10.4 */
434 } else {
435 s->usb_bit_time = 1;
436 }
437 } else {
438 s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000; /* 1000000 */
439 if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
440 s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS; /* 83.3 */
441 } else {
442 s->usb_bit_time = 1;
443 }
444 }
445
446 s->fi = USB_FRMINTVL - 1;
447 s->hprt0 |= HPRT0_CONNDET | HPRT0_CONNSTS;
448
449 dwc2_bus_start(s);
450 dwc2_raise_global_irq(s, GINTSTS_PRTINT);
451}
452
453static void dwc2_detach(USBPort *port)
454{
455 DWC2State *s = port->opaque;
456
457 trace_usb_dwc2_detach(port);
458 assert(port->index == 0);
459
460 dwc2_bus_stop(s);
461
462 s->hprt0 &= ~(HPRT0_SPD_MASK | HPRT0_SUSP | HPRT0_ENA | HPRT0_CONNSTS);
463 s->hprt0 |= HPRT0_CONNDET | HPRT0_ENACHG;
464
465 dwc2_raise_global_irq(s, GINTSTS_PRTINT);
466}
467
468static void dwc2_child_detach(USBPort *port, USBDevice *child)
469{
470 trace_usb_dwc2_child_detach(port, child);
471 assert(port->index == 0);
472}
473
474static void dwc2_wakeup(USBPort *port)
475{
476 DWC2State *s = port->opaque;
477
478 trace_usb_dwc2_wakeup(port);
479 assert(port->index == 0);
480
481 if (s->hprt0 & HPRT0_SUSP) {
482 s->hprt0 |= HPRT0_RES;
483 dwc2_raise_global_irq(s, GINTSTS_PRTINT);
484 }
485
486 qemu_bh_schedule(s->async_bh);
487}
488
489static void dwc2_async_packet_complete(USBPort *port, USBPacket *packet)
490{
491 DWC2State *s = port->opaque;
492 DWC2Packet *p;
493 USBDevice *dev;
494 USBEndpoint *ep;
495
496 assert(port->index == 0);
497 p = container_of(packet, DWC2Packet, packet);
498 dev = dwc2_find_device(s, p->devadr);
499 ep = usb_ep_get(dev, p->pid, p->epnum);
500 trace_usb_dwc2_async_packet_complete(port, packet, p->index >> 3, dev,
501 p->epnum, dirs[p->epdir], p->len);
502 assert(p->async == DWC2_ASYNC_INFLIGHT);
503
504 if (packet->status == USB_RET_REMOVE_FROM_QUEUE) {
505 usb_cancel_packet(packet);
506 usb_packet_cleanup(packet);
507 return;
508 }
509
510 dwc2_handle_packet(s, p->devadr, dev, ep, p->index, false);
511
512 p->async = DWC2_ASYNC_FINISHED;
513 qemu_bh_schedule(s->async_bh);
514}
515
516static USBPortOps dwc2_port_ops = {
517 .attach = dwc2_attach,
518 .detach = dwc2_detach,
519 .child_detach = dwc2_child_detach,
520 .wakeup = dwc2_wakeup,
521 .complete = dwc2_async_packet_complete,
522};
523
524static uint32_t dwc2_get_frame_remaining(DWC2State *s)
525{
526 uint32_t fr = 0;
527 int64_t tks;
528
529 tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->sof_time;
530 if (tks < 0) {
531 tks = 0;
532 }
533
534 /* avoid muldiv if possible */
535 if (tks >= s->usb_frame_time) {
536 goto out;
537 }
538 if (tks < s->usb_bit_time) {
539 fr = s->fi;
540 goto out;
541 }
542
543 /* tks = number of ns since SOF, divided by 83 (fs) or 10 (hs) */
544 tks = tks / s->usb_bit_time;
545 if (tks >= (int64_t)s->fi) {
546 goto out;
547 }
548
549 /* remaining = frame interval minus tks */
550 fr = (uint32_t)((int64_t)s->fi - tks);
551
552out:
553 return fr;
554}
555
556static void dwc2_work_bh(void *opaque)
557{
558 DWC2State *s = opaque;
559 DWC2Packet *p;
560 USBDevice *dev;
561 USBEndpoint *ep;
562 int64_t t_now, expire_time;
563 int chan;
564 bool found = false;
565
566 trace_usb_dwc2_work_bh();
567 if (s->working) {
568 return;
569 }
570 s->working = true;
571
572 t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
573 chan = s->next_chan;
574
575 do {
576 p = &s->packet[chan];
577 if (p->needs_service) {
578 dev = dwc2_find_device(s, p->devadr);
579 ep = usb_ep_get(dev, p->pid, p->epnum);
580 trace_usb_dwc2_work_bh_service(s->next_chan, chan, dev, p->epnum);
581 dwc2_handle_packet(s, p->devadr, dev, ep, p->index, true);
582 found = true;
583 }
584 if (++chan == DWC2_NB_CHAN) {
585 chan = 0;
586 }
587 if (found) {
588 s->next_chan = chan;
589 trace_usb_dwc2_work_bh_next(chan);
590 }
591 } while (chan != s->next_chan);
592
593 if (found) {
594 expire_time = t_now + NANOSECONDS_PER_SECOND / 4000;
595 timer_mod(s->frame_timer, expire_time);
596 }
597 s->working = false;
598}
599
600static void dwc2_enable_chan(DWC2State *s, uint32_t index)
601{
602 USBDevice *dev;
603 USBEndpoint *ep;
604 uint32_t hcchar;
605 uint32_t hctsiz;
606 uint32_t devadr, epnum, epdir, eptype, pid, len;
607 DWC2Packet *p;
608
609 assert((index >> 3) < DWC2_NB_CHAN);
610 p = &s->packet[index >> 3];
611 hcchar = s->hreg1[index];
612 hctsiz = s->hreg1[index + 4];
613 devadr = get_field(hcchar, HCCHAR_DEVADDR);
614 epnum = get_field(hcchar, HCCHAR_EPNUM);
615 epdir = get_bit(hcchar, HCCHAR_EPDIR);
616 eptype = get_field(hcchar, HCCHAR_EPTYPE);
617 pid = get_field(hctsiz, TSIZ_SC_MC_PID);
618 len = get_field(hctsiz, TSIZ_XFERSIZE);
619
620 dev = dwc2_find_device(s, devadr);
621
622 trace_usb_dwc2_enable_chan(index >> 3, dev, &p->packet, epnum);
623 if (dev == NULL) {
624 return;
625 }
626
627 if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
628 pid = USB_TOKEN_SETUP;
629 } else {
630 pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
631 }
632
633 ep = usb_ep_get(dev, pid, epnum);
634
635 /*
636 * Hack: Networking doesn't like us delivering large transfers, it kind
637 * of works but the latency is horrible. So if the transfer is <= the mtu
638 * size, we take that as a hint that this might be a network transfer,
639 * and do the transfer packet-by-packet.
640 */
641 if (len > 1536) {
642 p->small = false;
643 } else {
644 p->small = true;
645 }
646
647 dwc2_handle_packet(s, devadr, dev, ep, index, true);
648 qemu_bh_schedule(s->async_bh);
649}
650
651static const char *glbregnm[] = {
652 "GOTGCTL ", "GOTGINT ", "GAHBCFG ", "GUSBCFG ", "GRSTCTL ",
653 "GINTSTS ", "GINTMSK ", "GRXSTSR ", "GRXSTSP ", "GRXFSIZ ",
654 "GNPTXFSIZ", "GNPTXSTS ", "GI2CCTL ", "GPVNDCTL ", "GGPIO ",
655 "GUID ", "GSNPSID ", "GHWCFG1 ", "GHWCFG2 ", "GHWCFG3 ",
656 "GHWCFG4 ", "GLPMCFG ", "GPWRDN ", "GDFIFOCFG", "GADPCTL ",
657 "GREFCLK ", "GINTMSK2 ", "GINTSTS2 "
658};
659
660static uint64_t dwc2_glbreg_read(void *ptr, hwaddr addr, int index,
661 unsigned size)
662{
663 DWC2State *s = ptr;
664 uint32_t val;
665
666 assert(addr <= GINTSTS2);
667 val = s->glbreg[index];
668
669 switch (addr) {
670 case GRSTCTL:
671 /* clear any self-clearing bits that were set */
672 val &= ~(GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH | GRSTCTL_IN_TKNQ_FLSH |
673 GRSTCTL_FRMCNTRRST | GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
674 s->glbreg[index] = val;
675 break;
676 default:
677 break;
678 }
679
680 trace_usb_dwc2_glbreg_read(addr, glbregnm[index], val);
681 return val;
682}
683
684static void dwc2_glbreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
685 unsigned size)
686{
687 DWC2State *s = ptr;
688 uint64_t orig = val;
689 uint32_t *mmio;
690 uint32_t old;
691 int iflg = 0;
692
693 assert(addr <= GINTSTS2);
694 mmio = &s->glbreg[index];
695 old = *mmio;
696
697 switch (addr) {
698 case GOTGCTL:
699 /* don't allow setting of read-only bits */
700 val &= ~(GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
701 GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
702 GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
703 /* don't allow clearing of read-only bits */
704 val |= old & (GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
705 GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
706 GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
707 break;
708 case GAHBCFG:
709 if ((val & GAHBCFG_GLBL_INTR_EN) && !(old & GAHBCFG_GLBL_INTR_EN)) {
710 iflg = 1;
711 }
712 break;
713 case GRSTCTL:
714 val |= GRSTCTL_AHBIDLE;
715 val &= ~GRSTCTL_DMAREQ;
716 if (!(old & GRSTCTL_TXFFLSH) && (val & GRSTCTL_TXFFLSH)) {
717 /* TODO - TX fifo flush */
718 qemu_log_mask(LOG_UNIMP, "Tx FIFO flush not implemented\n");
719 }
720 if (!(old & GRSTCTL_RXFFLSH) && (val & GRSTCTL_RXFFLSH)) {
721 /* TODO - RX fifo flush */
722 qemu_log_mask(LOG_UNIMP, "Rx FIFO flush not implemented\n");
723 }
724 if (!(old & GRSTCTL_IN_TKNQ_FLSH) && (val & GRSTCTL_IN_TKNQ_FLSH)) {
725 /* TODO - device IN token queue flush */
726 qemu_log_mask(LOG_UNIMP, "Token queue flush not implemented\n");
727 }
728 if (!(old & GRSTCTL_FRMCNTRRST) && (val & GRSTCTL_FRMCNTRRST)) {
729 /* TODO - host frame counter reset */
730 qemu_log_mask(LOG_UNIMP, "Frame counter reset not implemented\n");
731 }
732 if (!(old & GRSTCTL_HSFTRST) && (val & GRSTCTL_HSFTRST)) {
733 /* TODO - host soft reset */
734 qemu_log_mask(LOG_UNIMP, "Host soft reset not implemented\n");
735 }
736 if (!(old & GRSTCTL_CSFTRST) && (val & GRSTCTL_CSFTRST)) {
737 /* TODO - core soft reset */
738 qemu_log_mask(LOG_UNIMP, "Core soft reset not implemented\n");
739 }
740 /* don't allow clearing of self-clearing bits */
741 val |= old & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH |
742 GRSTCTL_IN_TKNQ_FLSH | GRSTCTL_FRMCNTRRST |
743 GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
744 break;
745 case GINTSTS:
746 /* clear the write-1-to-clear bits */
747 val |= ~old;
748 val = ~val;
749 /* don't allow clearing of read-only bits */
750 val |= old & (GINTSTS_PTXFEMP | GINTSTS_HCHINT | GINTSTS_PRTINT |
751 GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_GOUTNAKEFF |
752 GINTSTS_GINNAKEFF | GINTSTS_NPTXFEMP | GINTSTS_RXFLVL |
753 GINTSTS_OTGINT | GINTSTS_CURMODE_HOST);
754 iflg = 1;
755 break;
756 case GINTMSK:
757 iflg = 1;
758 break;
759 default:
760 break;
761 }
762
763 trace_usb_dwc2_glbreg_write(addr, glbregnm[index], orig, old, val);
764 *mmio = val;
765
766 if (iflg) {
767 dwc2_update_irq(s);
768 }
769}
770
771static uint64_t dwc2_fszreg_read(void *ptr, hwaddr addr, int index,
772 unsigned size)
773{
774 DWC2State *s = ptr;
775 uint32_t val;
776
777 assert(addr == HPTXFSIZ);
778 val = s->fszreg[index];
779
780 trace_usb_dwc2_fszreg_read(addr, val);
781 return val;
782}
783
784static void dwc2_fszreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
785 unsigned size)
786{
787 DWC2State *s = ptr;
788 uint64_t orig = val;
789 uint32_t *mmio;
790 uint32_t old;
791
792 assert(addr == HPTXFSIZ);
793 mmio = &s->fszreg[index];
794 old = *mmio;
795
796 trace_usb_dwc2_fszreg_write(addr, orig, old, val);
797 *mmio = val;
798}
799
800static const char *hreg0nm[] = {
801 "HCFG ", "HFIR ", "HFNUM ", "<rsvd> ", "HPTXSTS ",
802 "HAINT ", "HAINTMSK ", "HFLBADDR ", "<rsvd> ", "<rsvd> ",
803 "<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ",
804 "<rsvd> ", "HPRT0 "
805};
806
807static uint64_t dwc2_hreg0_read(void *ptr, hwaddr addr, int index,
808 unsigned size)
809{
810 DWC2State *s = ptr;
811 uint32_t val;
812
813 assert(addr >= HCFG && addr <= HPRT0);
814 val = s->hreg0[index];
815
816 switch (addr) {
817 case HFNUM:
818 val = (dwc2_get_frame_remaining(s) << HFNUM_FRREM_SHIFT) |
819 (s->hfnum << HFNUM_FRNUM_SHIFT);
820 break;
821 default:
822 break;
823 }
824
825 trace_usb_dwc2_hreg0_read(addr, hreg0nm[index], val);
826 return val;
827}
828
829static void dwc2_hreg0_write(void *ptr, hwaddr addr, int index, uint64_t val,
830 unsigned size)
831{
832 DWC2State *s = ptr;
833 USBDevice *dev = s->uport.dev;
834 uint64_t orig = val;
835 uint32_t *mmio;
836 uint32_t tval, told, old;
837 int prst = 0;
838 int iflg = 0;
839
840 assert(addr >= HCFG && addr <= HPRT0);
841 mmio = &s->hreg0[index];
842 old = *mmio;
843
844 switch (addr) {
845 case HFIR:
846 break;
847 case HFNUM:
848 case HPTXSTS:
849 case HAINT:
850 qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
851 __func__);
852 return;
853 case HAINTMSK:
854 val &= 0xffff;
855 break;
856 case HPRT0:
857 /* don't allow clearing of read-only bits */
858 val |= old & (HPRT0_SPD_MASK | HPRT0_LNSTS_MASK | HPRT0_OVRCURRACT |
859 HPRT0_CONNSTS);
860 /* don't allow clearing of self-clearing bits */
861 val |= old & (HPRT0_SUSP | HPRT0_RES);
862 /* don't allow setting of self-setting bits */
863 if (!(old & HPRT0_ENA) && (val & HPRT0_ENA)) {
864 val &= ~HPRT0_ENA;
865 }
866 /* clear the write-1-to-clear bits */
867 tval = val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
868 HPRT0_CONNDET);
869 told = old & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
870 HPRT0_CONNDET);
871 tval |= ~told;
872 tval = ~tval;
873 tval &= (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
874 HPRT0_CONNDET);
875 val &= ~(HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
876 HPRT0_CONNDET);
877 val |= tval;
878 if (!(val & HPRT0_RST) && (old & HPRT0_RST)) {
879 if (dev && dev->attached) {
880 val |= HPRT0_ENA | HPRT0_ENACHG;
881 prst = 1;
882 }
883 }
884 if (val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_CONNDET)) {
885 iflg = 1;
886 } else {
887 iflg = -1;
888 }
889 break;
890 default:
891 break;
892 }
893
894 if (prst) {
895 trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old,
896 val & ~HPRT0_CONNDET);
897 trace_usb_dwc2_hreg0_action("call usb_port_reset");
898 usb_port_reset(&s->uport);
899 val &= ~HPRT0_CONNDET;
900 } else {
901 trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old, val);
902 }
903
904 *mmio = val;
905
906 if (iflg > 0) {
907 trace_usb_dwc2_hreg0_action("enable PRTINT");
908 dwc2_raise_global_irq(s, GINTSTS_PRTINT);
909 } else if (iflg < 0) {
910 trace_usb_dwc2_hreg0_action("disable PRTINT");
911 dwc2_lower_global_irq(s, GINTSTS_PRTINT);
912 }
913}
914
915static const char *hreg1nm[] = {
916 "HCCHAR ", "HCSPLT ", "HCINT ", "HCINTMSK", "HCTSIZ ", "HCDMA ",
917 "<rsvd> ", "HCDMAB "
918};
919
920static uint64_t dwc2_hreg1_read(void *ptr, hwaddr addr, int index,
921 unsigned size)
922{
923 DWC2State *s = ptr;
924 uint32_t val;
925
926 assert(addr >= HCCHAR(0) && addr <= HCDMAB(DWC2_NB_CHAN - 1));
927 val = s->hreg1[index];
928
929 trace_usb_dwc2_hreg1_read(addr, hreg1nm[index & 7], addr >> 5, val);
930 return val;
931}
932
933static void dwc2_hreg1_write(void *ptr, hwaddr addr, int index, uint64_t val,
934 unsigned size)
935{
936 DWC2State *s = ptr;
937 uint64_t orig = val;
938 uint32_t *mmio;
939 uint32_t old;
940 int iflg = 0;
941 int enflg = 0;
942 int disflg = 0;
943
944 assert(addr >= HCCHAR(0) && addr <= HCDMAB(DWC2_NB_CHAN - 1));
945 mmio = &s->hreg1[index];
946 old = *mmio;
947
948 switch (HSOTG_REG(0x500) + (addr & 0x1c)) {
949 case HCCHAR(0):
950 if ((val & HCCHAR_CHDIS) && !(old & HCCHAR_CHDIS)) {
951 val &= ~(HCCHAR_CHENA | HCCHAR_CHDIS);
952 disflg = 1;
953 } else {
954 val |= old & HCCHAR_CHDIS;
955 if ((val & HCCHAR_CHENA) && !(old & HCCHAR_CHENA)) {
956 val &= ~HCCHAR_CHDIS;
957 enflg = 1;
958 } else {
959 val |= old & HCCHAR_CHENA;
960 }
961 }
962 break;
963 case HCINT(0):
964 /* clear the write-1-to-clear bits */
965 val |= ~old;
966 val = ~val;
967 val &= ~HCINTMSK_RESERVED14_31;
968 iflg = 1;
969 break;
970 case HCINTMSK(0):
971 val &= ~HCINTMSK_RESERVED14_31;
972 iflg = 1;
973 break;
974 case HCDMAB(0):
975 qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
976 __func__);
977 return;
978 default:
979 break;
980 }
981
982 trace_usb_dwc2_hreg1_write(addr, hreg1nm[index & 7], index >> 3, orig,
983 old, val);
984 *mmio = val;
985
986 if (disflg) {
987 /* set ChHltd in HCINT */
988 s->hreg1[(index & ~7) + 2] |= HCINTMSK_CHHLTD;
989 iflg = 1;
990 }
991
992 if (enflg) {
993 dwc2_enable_chan(s, index & ~7);
994 }
995
996 if (iflg) {
997 dwc2_update_hc_irq(s, index & ~7);
998 }
999}
1000
1001static const char *pcgregnm[] = {
1002 "PCGCTL ", "PCGCCTL1 "
1003};
1004
1005static uint64_t dwc2_pcgreg_read(void *ptr, hwaddr addr, int index,
1006 unsigned size)
1007{
1008 DWC2State *s = ptr;
1009 uint32_t val;
1010
1011 assert(addr >= PCGCTL && addr <= PCGCCTL1);
1012 val = s->pcgreg[index];
1013
1014 trace_usb_dwc2_pcgreg_read(addr, pcgregnm[index], val);
1015 return val;
1016}
1017
1018static void dwc2_pcgreg_write(void *ptr, hwaddr addr, int index,
1019 uint64_t val, unsigned size)
1020{
1021 DWC2State *s = ptr;
1022 uint64_t orig = val;
1023 uint32_t *mmio;
1024 uint32_t old;
1025
1026 assert(addr >= PCGCTL && addr <= PCGCCTL1);
1027 mmio = &s->pcgreg[index];
1028 old = *mmio;
1029
1030 trace_usb_dwc2_pcgreg_write(addr, pcgregnm[index], orig, old, val);
1031 *mmio = val;
1032}
1033
1034static uint64_t dwc2_hsotg_read(void *ptr, hwaddr addr, unsigned size)
1035{
1036 uint64_t val;
1037
1038 switch (addr) {
1039 case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
1040 val = dwc2_glbreg_read(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, size);
1041 break;
1042 case HSOTG_REG(0x100):
1043 val = dwc2_fszreg_read(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, size);
1044 break;
1045 case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
1046 /* Gadget-mode registers, just return 0 for now */
1047 val = 0;
1048 break;
1049 case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
1050 val = dwc2_hreg0_read(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, size);
1051 break;
1052 case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
1053 val = dwc2_hreg1_read(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, size);
1054 break;
1055 case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
1056 /* Gadget-mode registers, just return 0 for now */
1057 val = 0;
1058 break;
1059 case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
1060 val = dwc2_pcgreg_read(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, size);
1061 break;
1062 default:
1063 g_assert_not_reached();
1064 }
1065
1066 return val;
1067}
1068
1069static void dwc2_hsotg_write(void *ptr, hwaddr addr, uint64_t val,
1070 unsigned size)
1071{
1072 switch (addr) {
1073 case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
1074 dwc2_glbreg_write(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, val, size);
1075 break;
1076 case HSOTG_REG(0x100):
1077 dwc2_fszreg_write(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, val, size);
1078 break;
1079 case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
1080 /* Gadget-mode registers, do nothing for now */
1081 break;
1082 case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
1083 dwc2_hreg0_write(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, val, size);
1084 break;
1085 case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
1086 dwc2_hreg1_write(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, val, size);
1087 break;
1088 case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
1089 /* Gadget-mode registers, do nothing for now */
1090 break;
1091 case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
1092 dwc2_pcgreg_write(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, val, size);
1093 break;
1094 default:
1095 g_assert_not_reached();
1096 }
1097}
1098
1099static const MemoryRegionOps dwc2_mmio_hsotg_ops = {
1100 .read = dwc2_hsotg_read,
1101 .write = dwc2_hsotg_write,
1102 .impl.min_access_size = 4,
1103 .impl.max_access_size = 4,
1104 .endianness = DEVICE_LITTLE_ENDIAN,
1105};
1106
1107static uint64_t dwc2_hreg2_read(void *ptr, hwaddr addr, unsigned size)
1108{
1109 /* TODO - implement FIFOs to support slave mode */
1110 trace_usb_dwc2_hreg2_read(addr, addr >> 12, 0);
1111 qemu_log_mask(LOG_UNIMP, "FIFO read not implemented\n");
1112 return 0;
1113}
1114
1115static void dwc2_hreg2_write(void *ptr, hwaddr addr, uint64_t val,
1116 unsigned size)
1117{
1118 uint64_t orig = val;
1119
1120 /* TODO - implement FIFOs to support slave mode */
1121 trace_usb_dwc2_hreg2_write(addr, addr >> 12, orig, 0, val);
1122 qemu_log_mask(LOG_UNIMP, "FIFO write not implemented\n");
1123}
1124
1125static const MemoryRegionOps dwc2_mmio_hreg2_ops = {
1126 .read = dwc2_hreg2_read,
1127 .write = dwc2_hreg2_write,
1128 .impl.min_access_size = 4,
1129 .impl.max_access_size = 4,
1130 .endianness = DEVICE_LITTLE_ENDIAN,
1131};
1132
1133static void dwc2_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
1134 unsigned int stream)
1135{
1136 DWC2State *s = container_of(bus, DWC2State, bus);
1137
1138 trace_usb_dwc2_wakeup_endpoint(ep, stream);
1139
1140 /* TODO - do something here? */
1141 qemu_bh_schedule(s->async_bh);
1142}
1143
1144static USBBusOps dwc2_bus_ops = {
1145 .wakeup_endpoint = dwc2_wakeup_endpoint,
1146};
1147
1148static void dwc2_work_timer(void *opaque)
1149{
1150 DWC2State *s = opaque;
1151
1152 trace_usb_dwc2_work_timer();
1153 qemu_bh_schedule(s->async_bh);
1154}
1155
1156static void dwc2_reset_enter(Object *obj, ResetType type)
1157{
1158 DWC2Class *c = DWC2_GET_CLASS(obj);
1159 DWC2State *s = DWC2_USB(obj);
1160 int i;
1161
1162 trace_usb_dwc2_reset_enter();
1163
1164 if (c->parent_phases.enter) {
1165 c->parent_phases.enter(obj, type);
1166 }
1167
1168 timer_del(s->frame_timer);
1169 qemu_bh_cancel(s->async_bh);
1170
1171 if (s->uport.dev && s->uport.dev->attached) {
1172 usb_detach(&s->uport);
1173 }
1174
1175 dwc2_bus_stop(s);
1176
1177 s->gotgctl = GOTGCTL_BSESVLD | GOTGCTL_ASESVLD | GOTGCTL_CONID_B;
1178 s->gotgint = 0;
1179 s->gahbcfg = 0;
1180 s->gusbcfg = 5 << GUSBCFG_USBTRDTIM_SHIFT;
1181 s->grstctl = GRSTCTL_AHBIDLE;
1182 s->gintsts = GINTSTS_CONIDSTSCHNG | GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP |
1183 GINTSTS_CURMODE_HOST;
1184 s->gintmsk = 0;
1185 s->grxstsr = 0;
1186 s->grxstsp = 0;
1187 s->grxfsiz = 1024;
1188 s->gnptxfsiz = 1024 << FIFOSIZE_DEPTH_SHIFT;
1189 s->gnptxsts = (4 << FIFOSIZE_DEPTH_SHIFT) | 1024;
1190 s->gi2cctl = GI2CCTL_I2CDATSE0 | GI2CCTL_ACK;
1191 s->gpvndctl = 0;
1192 s->ggpio = 0;
1193 s->guid = 0;
1194 s->gsnpsid = 0x4f54294a;
1195 s->ghwcfg1 = 0;
1196 s->ghwcfg2 = (8 << GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT) |
1197 (4 << GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT) |
1198 (4 << GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT) |
1199 GHWCFG2_DYNAMIC_FIFO |
1200 GHWCFG2_PERIO_EP_SUPPORTED |
1201 ((DWC2_NB_CHAN - 1) << GHWCFG2_NUM_HOST_CHAN_SHIFT) |
1202 (GHWCFG2_INT_DMA_ARCH << GHWCFG2_ARCHITECTURE_SHIFT) |
1203 (GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST << GHWCFG2_OP_MODE_SHIFT);
1204 s->ghwcfg3 = (4096 << GHWCFG3_DFIFO_DEPTH_SHIFT) |
1205 (4 << GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT) |
1206 (4 << GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT);
1207 s->ghwcfg4 = 0;
1208 s->glpmcfg = 0;
1209 s->gpwrdn = GPWRDN_PWRDNRSTN;
1210 s->gdfifocfg = 0;
1211 s->gadpctl = 0;
1212 s->grefclk = 0;
1213 s->gintmsk2 = 0;
1214 s->gintsts2 = 0;
1215
1216 s->hptxfsiz = 500 << FIFOSIZE_DEPTH_SHIFT;
1217
1218 s->hcfg = 2 << HCFG_RESVALID_SHIFT;
1219 s->hfir = 60000;
1220 s->hfnum = 0x3fff;
1221 s->hptxsts = (16 << TXSTS_QSPCAVAIL_SHIFT) | 32768;
1222 s->haint = 0;
1223 s->haintmsk = 0;
1224 s->hprt0 = 0;
1225
1226 memset(s->hreg1, 0, sizeof(s->hreg1));
1227 memset(s->pcgreg, 0, sizeof(s->pcgreg));
1228
1229 s->sof_time = 0;
1230 s->frame_number = 0;
1231 s->fi = USB_FRMINTVL - 1;
1232 s->next_chan = 0;
1233 s->working = false;
1234
1235 for (i = 0; i < DWC2_NB_CHAN; i++) {
1236 s->packet[i].needs_service = false;
1237 }
1238}
1239
1240static void dwc2_reset_hold(Object *obj)
1241{
1242 DWC2Class *c = DWC2_GET_CLASS(obj);
1243 DWC2State *s = DWC2_USB(obj);
1244
1245 trace_usb_dwc2_reset_hold();
1246
1247 if (c->parent_phases.hold) {
1248 c->parent_phases.hold(obj);
1249 }
1250
1251 dwc2_update_irq(s);
1252}
1253
1254static void dwc2_reset_exit(Object *obj)
1255{
1256 DWC2Class *c = DWC2_GET_CLASS(obj);
1257 DWC2State *s = DWC2_USB(obj);
1258
1259 trace_usb_dwc2_reset_exit();
1260
1261 if (c->parent_phases.exit) {
1262 c->parent_phases.exit(obj);
1263 }
1264
1265 s->hprt0 = HPRT0_PWR;
1266 if (s->uport.dev && s->uport.dev->attached) {
1267 usb_attach(&s->uport);
1268 usb_device_reset(s->uport.dev);
1269 }
1270}
1271
1272static void dwc2_realize(DeviceState *dev, Error **errp)
1273{
1274 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1275 DWC2State *s = DWC2_USB(dev);
1276 Object *obj;
153ef166 1277
4d21fcd5 1278 obj = object_property_get_link(OBJECT(dev), "dma-mr", &error_abort);
153ef166
PZ
1279
1280 s->dma_mr = MEMORY_REGION(obj);
1281 address_space_init(&s->dma_as, s->dma_mr, "dwc2");
1282
1283 usb_bus_new(&s->bus, sizeof(s->bus), &dwc2_bus_ops, dev);
1284 usb_register_port(&s->bus, &s->uport, s, 0, &dwc2_port_ops,
1285 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
1286 (s->usb_version == 2 ? USB_SPEED_MASK_HIGH : 0));
1287 s->uport.dev = 0;
1288
1289 s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000; /* 1000000 */
1290 if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
1291 s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS; /* 83.3 */
1292 } else {
1293 s->usb_bit_time = 1;
1294 }
1295
1296 s->fi = USB_FRMINTVL - 1;
1297 s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s);
1298 s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s);
1299 s->async_bh = qemu_bh_new(dwc2_work_bh, s);
1300
1301 sysbus_init_irq(sbd, &s->irq);
1302}
1303
1304static void dwc2_init(Object *obj)
1305{
1306 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1307 DWC2State *s = DWC2_USB(obj);
1308
1309 memory_region_init(&s->container, obj, "dwc2", DWC2_MMIO_SIZE);
1310 sysbus_init_mmio(sbd, &s->container);
1311
1312 memory_region_init_io(&s->hsotg, obj, &dwc2_mmio_hsotg_ops, s,
1313 "dwc2-io", 4 * KiB);
1314 memory_region_add_subregion(&s->container, 0x0000, &s->hsotg);
1315
1316 memory_region_init_io(&s->fifos, obj, &dwc2_mmio_hreg2_ops, s,
1317 "dwc2-fifo", 64 * KiB);
1318 memory_region_add_subregion(&s->container, 0x1000, &s->fifos);
1319}
1320
1321static const VMStateDescription vmstate_dwc2_state_packet = {
1322 .name = "dwc2/packet",
1323 .version_id = 1,
1324 .minimum_version_id = 1,
1325 .fields = (VMStateField[]) {
1326 VMSTATE_UINT32(devadr, DWC2Packet),
1327 VMSTATE_UINT32(epnum, DWC2Packet),
1328 VMSTATE_UINT32(epdir, DWC2Packet),
1329 VMSTATE_UINT32(mps, DWC2Packet),
1330 VMSTATE_UINT32(pid, DWC2Packet),
1331 VMSTATE_UINT32(index, DWC2Packet),
1332 VMSTATE_UINT32(pcnt, DWC2Packet),
1333 VMSTATE_UINT32(len, DWC2Packet),
1334 VMSTATE_INT32(async, DWC2Packet),
1335 VMSTATE_BOOL(small, DWC2Packet),
1336 VMSTATE_BOOL(needs_service, DWC2Packet),
1337 VMSTATE_END_OF_LIST()
1338 },
1339};
1340
1341const VMStateDescription vmstate_dwc2_state = {
1342 .name = "dwc2",
1343 .version_id = 1,
1344 .minimum_version_id = 1,
1345 .fields = (VMStateField[]) {
1346 VMSTATE_UINT32_ARRAY(glbreg, DWC2State,
1347 DWC2_GLBREG_SIZE / sizeof(uint32_t)),
1348 VMSTATE_UINT32_ARRAY(fszreg, DWC2State,
1349 DWC2_FSZREG_SIZE / sizeof(uint32_t)),
1350 VMSTATE_UINT32_ARRAY(hreg0, DWC2State,
1351 DWC2_HREG0_SIZE / sizeof(uint32_t)),
1352 VMSTATE_UINT32_ARRAY(hreg1, DWC2State,
1353 DWC2_HREG1_SIZE / sizeof(uint32_t)),
1354 VMSTATE_UINT32_ARRAY(pcgreg, DWC2State,
1355 DWC2_PCGREG_SIZE / sizeof(uint32_t)),
1356
1357 VMSTATE_TIMER_PTR(eof_timer, DWC2State),
1358 VMSTATE_TIMER_PTR(frame_timer, DWC2State),
1359 VMSTATE_INT64(sof_time, DWC2State),
1360 VMSTATE_INT64(usb_frame_time, DWC2State),
1361 VMSTATE_INT64(usb_bit_time, DWC2State),
1362 VMSTATE_UINT32(usb_version, DWC2State),
1363 VMSTATE_UINT16(frame_number, DWC2State),
1364 VMSTATE_UINT16(fi, DWC2State),
1365 VMSTATE_UINT16(next_chan, DWC2State),
1366 VMSTATE_BOOL(working, DWC2State),
1367
1368 VMSTATE_STRUCT_ARRAY(packet, DWC2State, DWC2_NB_CHAN, 1,
1369 vmstate_dwc2_state_packet, DWC2Packet),
1370 VMSTATE_UINT8_2DARRAY(usb_buf, DWC2State, DWC2_NB_CHAN,
1371 DWC2_MAX_XFER_SIZE),
1372
1373 VMSTATE_END_OF_LIST()
1374 }
1375};
1376
1377static Property dwc2_usb_properties[] = {
1378 DEFINE_PROP_UINT32("usb_version", DWC2State, usb_version, 2),
1379 DEFINE_PROP_END_OF_LIST(),
1380};
1381
1382static void dwc2_class_init(ObjectClass *klass, void *data)
1383{
1384 DeviceClass *dc = DEVICE_CLASS(klass);
1385 DWC2Class *c = DWC2_CLASS(klass);
1386 ResettableClass *rc = RESETTABLE_CLASS(klass);
1387
1388 dc->realize = dwc2_realize;
1389 dc->vmsd = &vmstate_dwc2_state;
1390 set_bit(DEVICE_CATEGORY_USB, dc->categories);
1391 device_class_set_props(dc, dwc2_usb_properties);
1392 resettable_class_set_parent_phases(rc, dwc2_reset_enter, dwc2_reset_hold,
1393 dwc2_reset_exit, &c->parent_phases);
1394}
1395
1396static const TypeInfo dwc2_usb_type_info = {
1397 .name = TYPE_DWC2_USB,
1398 .parent = TYPE_SYS_BUS_DEVICE,
1399 .instance_size = sizeof(DWC2State),
1400 .instance_init = dwc2_init,
1401 .class_size = sizeof(DWC2Class),
1402 .class_init = dwc2_class_init,
1403};
1404
1405static void dwc2_usb_register_types(void)
1406{
1407 type_register_static(&dwc2_usb_type_info);
1408}
1409
1410type_init(dwc2_usb_register_types)