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"
42
#include "qemu/error-report.h"
43
#include "qemu/main-loop.h"
44
#include "hw/qdev-properties.h"
46
#define USB_HZ_FS 12000000
47
#define USB_HZ_HS 96000000
48
#define USB_FRMINTVL 12000
51
#define get_field(data, field) \
52
(((data) & field##_MASK) >> field##_SHIFT)
54
#define set_field(data, newval, field) do { \
55
uint32_t val = *(data); \
56
val &= ~field##_MASK; \
57
val |= ((newval) << field##_SHIFT) & field##_MASK; \
61
#define get_bit(data, bitmask) \
62
(!!((data) & (bitmask)))
65
static inline void dwc2_update_irq(DWC2State *s)
70
if ((s->gintsts & s->gintmsk) && (s->gahbcfg & GAHBCFG_GLBL_INTR_EN)) {
73
if (level != oldlevel) {
75
trace_usb_dwc2_update_irq(level);
76
qemu_set_irq(s->irq, level);
81
static inline void dwc2_raise_global_irq(DWC2State *s, uint32_t intr)
83
if (!(s->gintsts & intr)) {
85
trace_usb_dwc2_raise_global_irq(intr);
90
static inline void dwc2_lower_global_irq(DWC2State *s, uint32_t intr)
92
if (s->gintsts & intr) {
94
trace_usb_dwc2_lower_global_irq(intr);
99
static inline void dwc2_raise_host_irq(DWC2State *s, uint32_t host_intr)
101
if (!(s->haint & host_intr)) {
102
s->haint |= host_intr;
104
trace_usb_dwc2_raise_host_irq(host_intr);
105
if (s->haint & s->haintmsk) {
106
dwc2_raise_global_irq(s, GINTSTS_HCHINT);
111
static inline void dwc2_lower_host_irq(DWC2State *s, uint32_t host_intr)
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);
122
static inline void dwc2_update_hc_irq(DWC2State *s, int index)
124
uint32_t host_intr = 1 << (index >> 3);
126
if (s->hreg1[index + 2] & s->hreg1[index + 3]) {
127
dwc2_raise_host_irq(s, host_intr);
129
dwc2_lower_host_irq(s, host_intr);
134
static void dwc2_eof_timer(DWC2State *s)
136
timer_mod(s->eof_timer, s->sof_time + s->usb_frame_time);
140
static void dwc2_sof(DWC2State *s)
142
s->sof_time += s->usb_frame_time;
143
trace_usb_dwc2_sof(s->sof_time);
145
dwc2_raise_global_irq(s, GINTSTS_SOF);
149
static void dwc2_frame_boundary(void *opaque)
151
DWC2State *s = opaque;
155
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
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;
169
static void dwc2_bus_start(DWC2State *s)
171
trace_usb_dwc2_bus_start();
172
s->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
177
static void dwc2_bus_stop(DWC2State *s)
179
trace_usb_dwc2_bus_stop();
180
timer_del(s->eof_timer);
183
static USBDevice *dwc2_find_device(DWC2State *s, uint8_t addr)
187
trace_usb_dwc2_find_device(addr);
189
if (!(s->hprt0 & HPRT0_ENA)) {
190
trace_usb_dwc2_port_disabled(0);
192
dev = usb_find_device(&s->uport, addr);
194
trace_usb_dwc2_device_found(0);
199
trace_usb_dwc2_device_not_found();
203
static 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"
209
static uint32_t pintr[] = {
210
HCINTMSK_XFERCOMPL, HCINTMSK_XACTERR, HCINTMSK_NAK, HCINTMSK_STALL,
211
HCINTMSK_BBLERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR,
215
static const char *types[] = {
216
"Ctrl", "Isoc", "Bulk", "Intr"
219
static const char *dirs[] = {
223
static void dwc2_handle_packet(DWC2State *s, uint32_t devadr, USBDevice *dev,
224
USBEndpoint *ep, uint32_t index, bool send)
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;
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
if (len > DWC2_MAX_XFER_SIZE) {
242
qemu_log_mask(LOG_GUEST_ERROR,
243
"%s: HCTSIZ transfer size too large\n", __func__);
248
p = &s->packet[chan];
250
trace_usb_dwc2_handle_packet(chan, dev, &p->packet, epnum, types[eptype],
251
dirs[epdir], mps, len, pcnt);
254
qemu_log_mask(LOG_GUEST_ERROR,
255
"%s: Bad HCCHAR_MPS set to zero\n", __func__);
259
if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
260
pid = USB_TOKEN_SETUP;
262
pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
273
if (pid != USB_TOKEN_IN) {
274
trace_usb_dwc2_memory_read(hcdma, tlen);
275
if (dma_memory_read(&s->dma_as, hcdma, s->usb_buf[chan], tlen,
276
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
277
qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_read failed\n",
282
usb_packet_init(&p->packet);
283
usb_packet_setup(&p->packet, pid, ep, 0, hcdma,
284
pid != USB_TOKEN_IN, true);
285
usb_packet_addbuf(&p->packet, s->usb_buf[chan], tlen);
286
p->async = DWC2_ASYNC_NONE;
287
usb_handle_packet(dev, &p->packet);
292
stsidx = -p->packet.status;
293
assert(stsidx < sizeof(pstatus) / sizeof(*pstatus));
294
actual = p->packet.actual_length;
295
trace_usb_dwc2_packet_status(pstatus[stsidx], actual);
298
if (p->packet.status != USB_RET_SUCCESS &&
299
p->packet.status != USB_RET_NAK &&
300
p->packet.status != USB_RET_STALL &&
301
p->packet.status != USB_RET_ASYNC) {
302
trace_usb_dwc2_packet_error(pstatus[stsidx]);
305
if (p->packet.status == USB_RET_ASYNC) {
306
trace_usb_dwc2_async_packet(&p->packet, chan, dev, epnum,
308
usb_device_flush_ep_queue(dev, ep);
309
assert(p->async != DWC2_ASYNC_INFLIGHT);
318
p->async = DWC2_ASYNC_INFLIGHT;
319
p->needs_service = false;
323
if (p->packet.status == USB_RET_SUCCESS) {
325
p->packet.status = USB_RET_BABBLE;
329
if (pid == USB_TOKEN_IN) {
330
trace_usb_dwc2_memory_write(hcdma, actual);
331
if (dma_memory_write(&s->dma_as, hcdma, s->usb_buf[chan], actual,
332
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
333
qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_write failed\n",
338
tpcnt = actual / mps;
341
if (pid == USB_TOKEN_IN) {
346
pcnt -= tpcnt < pcnt ? tpcnt : pcnt;
347
set_field(&hctsiz, pcnt, TSIZ_PKTCNT);
348
len -= actual < len ? actual : len;
349
set_field(&hctsiz, len, TSIZ_XFERSIZE);
350
s->hreg1[index + 4] = hctsiz;
352
s->hreg1[index + 5] = hcdma;
354
if (!pcnt || len == 0 || actual == 0) {
358
intr |= pintr[stsidx];
359
if (p->packet.status == USB_RET_NAK &&
360
(eptype == USB_ENDPOINT_XFER_CONTROL ||
361
eptype == USB_ENDPOINT_XFER_BULK)) {
366
intr &= ~HCINTMSK_RESERVED14_31;
367
s->hreg1[index + 2] |= intr;
370
intr |= HCINTMSK_CHHLTD;
375
usb_packet_cleanup(&p->packet);
378
hcchar &= ~HCCHAR_CHENA;
379
s->hreg1[index] = hcchar;
380
if (!(intr & HCINTMSK_CHHLTD)) {
381
intr |= HCINTMSK_CHHLTD | HCINTMSK_XFERCOMPL;
383
intr &= ~HCINTMSK_RESERVED14_31;
384
s->hreg1[index + 2] |= intr;
385
p->needs_service = false;
386
trace_usb_dwc2_packet_done(pstatus[stsidx], actual, len, pcnt);
387
dwc2_update_hc_irq(s, index);
399
p->needs_service = true;
400
trace_usb_dwc2_packet_next(pstatus[stsidx], len, pcnt);
402
dwc2_update_hc_irq(s, index);
408
static const char *speeds[] = {
409
"low", "full", "high"
412
static void dwc2_attach(USBPort *port)
414
DWC2State *s = port->opaque;
417
trace_usb_dwc2_attach(port);
418
assert(port->index == 0);
420
if (!port->dev || !port->dev->attached) {
424
assert(port->dev->speed <= USB_SPEED_HIGH);
425
trace_usb_dwc2_attach_speed(speeds[port->dev->speed]);
426
s->hprt0 &= ~HPRT0_SPD_MASK;
428
switch (port->dev->speed) {
430
s->hprt0 |= HPRT0_SPD_LOW_SPEED << HPRT0_SPD_SHIFT;
433
s->hprt0 |= HPRT0_SPD_FULL_SPEED << HPRT0_SPD_SHIFT;
436
s->hprt0 |= HPRT0_SPD_HIGH_SPEED << HPRT0_SPD_SHIFT;
442
s->usb_frame_time = NANOSECONDS_PER_SECOND / 8000;
443
if (NANOSECONDS_PER_SECOND >= USB_HZ_HS) {
444
s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_HS;
449
s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000;
450
if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
451
s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS;
457
s->fi = USB_FRMINTVL - 1;
458
s->hprt0 |= HPRT0_CONNDET | HPRT0_CONNSTS;
461
dwc2_raise_global_irq(s, GINTSTS_PRTINT);
464
static void dwc2_detach(USBPort *port)
466
DWC2State *s = port->opaque;
468
trace_usb_dwc2_detach(port);
469
assert(port->index == 0);
473
s->hprt0 &= ~(HPRT0_SPD_MASK | HPRT0_SUSP | HPRT0_ENA | HPRT0_CONNSTS);
474
s->hprt0 |= HPRT0_CONNDET | HPRT0_ENACHG;
476
dwc2_raise_global_irq(s, GINTSTS_PRTINT);
479
static void dwc2_child_detach(USBPort *port, USBDevice *child)
481
trace_usb_dwc2_child_detach(port, child);
482
assert(port->index == 0);
485
static void dwc2_wakeup(USBPort *port)
487
DWC2State *s = port->opaque;
489
trace_usb_dwc2_wakeup(port);
490
assert(port->index == 0);
492
if (s->hprt0 & HPRT0_SUSP) {
493
s->hprt0 |= HPRT0_RES;
494
dwc2_raise_global_irq(s, GINTSTS_PRTINT);
497
qemu_bh_schedule(s->async_bh);
500
static void dwc2_async_packet_complete(USBPort *port, USBPacket *packet)
502
DWC2State *s = port->opaque;
507
assert(port->index == 0);
508
p = container_of(packet, DWC2Packet, packet);
509
dev = dwc2_find_device(s, p->devadr);
510
ep = usb_ep_get(dev, p->pid, p->epnum);
511
trace_usb_dwc2_async_packet_complete(port, packet, p->index >> 3, dev,
512
p->epnum, dirs[p->epdir], p->len);
513
assert(p->async == DWC2_ASYNC_INFLIGHT);
515
if (packet->status == USB_RET_REMOVE_FROM_QUEUE) {
516
usb_cancel_packet(packet);
517
usb_packet_cleanup(packet);
521
dwc2_handle_packet(s, p->devadr, dev, ep, p->index, false);
523
p->async = DWC2_ASYNC_FINISHED;
524
qemu_bh_schedule(s->async_bh);
527
static USBPortOps dwc2_port_ops = {
528
.attach = dwc2_attach,
529
.detach = dwc2_detach,
530
.child_detach = dwc2_child_detach,
531
.wakeup = dwc2_wakeup,
532
.complete = dwc2_async_packet_complete,
535
static uint32_t dwc2_get_frame_remaining(DWC2State *s)
540
tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->sof_time;
546
if (tks >= s->usb_frame_time) {
549
if (tks < s->usb_bit_time) {
555
tks = tks / s->usb_bit_time;
556
if (tks >= (int64_t)s->fi) {
561
fr = (uint32_t)((int64_t)s->fi - tks);
567
static void dwc2_work_bh(void *opaque)
569
DWC2State *s = opaque;
573
int64_t t_now, expire_time;
577
trace_usb_dwc2_work_bh();
583
t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
587
p = &s->packet[chan];
588
if (p->needs_service) {
589
dev = dwc2_find_device(s, p->devadr);
590
ep = usb_ep_get(dev, p->pid, p->epnum);
591
trace_usb_dwc2_work_bh_service(s->next_chan, chan, dev, p->epnum);
592
dwc2_handle_packet(s, p->devadr, dev, ep, p->index, true);
595
if (++chan == DWC2_NB_CHAN) {
600
trace_usb_dwc2_work_bh_next(chan);
602
} while (chan != s->next_chan);
605
expire_time = t_now + NANOSECONDS_PER_SECOND / 4000;
606
timer_mod(s->frame_timer, expire_time);
611
static void dwc2_enable_chan(DWC2State *s, uint32_t index)
617
uint32_t devadr, epnum, epdir, eptype, pid, len;
620
assert((index >> 3) < DWC2_NB_CHAN);
621
p = &s->packet[index >> 3];
622
hcchar = s->hreg1[index];
623
hctsiz = s->hreg1[index + 4];
624
devadr = get_field(hcchar, HCCHAR_DEVADDR);
625
epnum = get_field(hcchar, HCCHAR_EPNUM);
626
epdir = get_bit(hcchar, HCCHAR_EPDIR);
627
eptype = get_field(hcchar, HCCHAR_EPTYPE);
628
pid = get_field(hctsiz, TSIZ_SC_MC_PID);
629
len = get_field(hctsiz, TSIZ_XFERSIZE);
631
dev = dwc2_find_device(s, devadr);
633
trace_usb_dwc2_enable_chan(index >> 3, dev, &p->packet, epnum);
638
if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
639
pid = USB_TOKEN_SETUP;
641
pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
644
ep = usb_ep_get(dev, pid, epnum);
658
dwc2_handle_packet(s, devadr, dev, ep, index, true);
659
qemu_bh_schedule(s->async_bh);
662
static const char *glbregnm[] = {
663
"GOTGCTL ", "GOTGINT ", "GAHBCFG ", "GUSBCFG ", "GRSTCTL ",
664
"GINTSTS ", "GINTMSK ", "GRXSTSR ", "GRXSTSP ", "GRXFSIZ ",
665
"GNPTXFSIZ", "GNPTXSTS ", "GI2CCTL ", "GPVNDCTL ", "GGPIO ",
666
"GUID ", "GSNPSID ", "GHWCFG1 ", "GHWCFG2 ", "GHWCFG3 ",
667
"GHWCFG4 ", "GLPMCFG ", "GPWRDN ", "GDFIFOCFG", "GADPCTL ",
668
"GREFCLK ", "GINTMSK2 ", "GINTSTS2 "
671
static uint64_t dwc2_glbreg_read(void *ptr, hwaddr addr, int index,
677
if (addr > GINTSTS2) {
678
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
683
val = s->glbreg[index];
688
val &= ~(GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH | GRSTCTL_IN_TKNQ_FLSH |
689
GRSTCTL_FRMCNTRRST | GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
690
s->glbreg[index] = val;
696
trace_usb_dwc2_glbreg_read(addr, glbregnm[index], val);
700
static void dwc2_glbreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
709
if (addr > GINTSTS2) {
710
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
715
mmio = &s->glbreg[index];
721
val &= ~(GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
722
GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
723
GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
725
val |= old & (GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
726
GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
727
GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
730
if ((val & GAHBCFG_GLBL_INTR_EN) && !(old & GAHBCFG_GLBL_INTR_EN)) {
735
val |= GRSTCTL_AHBIDLE;
736
val &= ~GRSTCTL_DMAREQ;
737
if (!(old & GRSTCTL_TXFFLSH) && (val & GRSTCTL_TXFFLSH)) {
739
qemu_log_mask(LOG_UNIMP, "%s: Tx FIFO flush not implemented\n",
742
if (!(old & GRSTCTL_RXFFLSH) && (val & GRSTCTL_RXFFLSH)) {
744
qemu_log_mask(LOG_UNIMP, "%s: Rx FIFO flush not implemented\n",
747
if (!(old & GRSTCTL_IN_TKNQ_FLSH) && (val & GRSTCTL_IN_TKNQ_FLSH)) {
749
qemu_log_mask(LOG_UNIMP, "%s: Token queue flush not implemented\n",
752
if (!(old & GRSTCTL_FRMCNTRRST) && (val & GRSTCTL_FRMCNTRRST)) {
754
qemu_log_mask(LOG_UNIMP,
755
"%s: Frame counter reset not implemented\n",
758
if (!(old & GRSTCTL_HSFTRST) && (val & GRSTCTL_HSFTRST)) {
760
qemu_log_mask(LOG_UNIMP, "%s: Host soft reset not implemented\n",
763
if (!(old & GRSTCTL_CSFTRST) && (val & GRSTCTL_CSFTRST)) {
765
qemu_log_mask(LOG_UNIMP, "%s: Core soft reset not implemented\n",
769
val |= old & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH |
770
GRSTCTL_IN_TKNQ_FLSH | GRSTCTL_FRMCNTRRST |
771
GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
778
val |= old & (GINTSTS_PTXFEMP | GINTSTS_HCHINT | GINTSTS_PRTINT |
779
GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_GOUTNAKEFF |
780
GINTSTS_GINNAKEFF | GINTSTS_NPTXFEMP | GINTSTS_RXFLVL |
781
GINTSTS_OTGINT | GINTSTS_CURMODE_HOST);
791
trace_usb_dwc2_glbreg_write(addr, glbregnm[index], orig, old, val);
799
static uint64_t dwc2_fszreg_read(void *ptr, hwaddr addr, int index,
805
if (addr != HPTXFSIZ) {
806
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
811
val = s->fszreg[index];
813
trace_usb_dwc2_fszreg_read(addr, val);
817
static void dwc2_fszreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
825
if (addr != HPTXFSIZ) {
826
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
831
mmio = &s->fszreg[index];
834
trace_usb_dwc2_fszreg_write(addr, orig, old, val);
838
static const char *hreg0nm[] = {
839
"HCFG ", "HFIR ", "HFNUM ", "<rsvd> ", "HPTXSTS ",
840
"HAINT ", "HAINTMSK ", "HFLBADDR ", "<rsvd> ", "<rsvd> ",
841
"<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ", "<rsvd> ",
845
static uint64_t dwc2_hreg0_read(void *ptr, hwaddr addr, int index,
851
if (addr < HCFG || addr > HPRT0) {
852
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
857
val = s->hreg0[index];
861
val = (dwc2_get_frame_remaining(s) << HFNUM_FRREM_SHIFT) |
862
(s->hfnum << HFNUM_FRNUM_SHIFT);
868
trace_usb_dwc2_hreg0_read(addr, hreg0nm[index], val);
872
static void dwc2_hreg0_write(void *ptr, hwaddr addr, int index, uint64_t val,
876
USBDevice *dev = s->uport.dev;
879
uint32_t tval, told, old;
883
if (addr < HCFG || addr > HPRT0) {
884
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
889
mmio = &s->hreg0[index];
898
qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
906
val |= old & (HPRT0_SPD_MASK | HPRT0_LNSTS_MASK | HPRT0_OVRCURRACT |
909
val |= old & (HPRT0_SUSP | HPRT0_RES);
911
if (!(old & HPRT0_ENA) && (val & HPRT0_ENA)) {
915
tval = val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
917
told = old & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
921
tval &= (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
923
val &= ~(HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
926
if (!(val & HPRT0_RST) && (old & HPRT0_RST)) {
927
if (dev && dev->attached) {
928
val |= HPRT0_ENA | HPRT0_ENACHG;
932
if (val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_CONNDET)) {
943
trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old,
944
val & ~HPRT0_CONNDET);
945
trace_usb_dwc2_hreg0_action("call usb_port_reset");
946
usb_port_reset(&s->uport);
947
val &= ~HPRT0_CONNDET;
949
trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old, val);
955
trace_usb_dwc2_hreg0_action("enable PRTINT");
956
dwc2_raise_global_irq(s, GINTSTS_PRTINT);
957
} else if (iflg < 0) {
958
trace_usb_dwc2_hreg0_action("disable PRTINT");
959
dwc2_lower_global_irq(s, GINTSTS_PRTINT);
963
static const char *hreg1nm[] = {
964
"HCCHAR ", "HCSPLT ", "HCINT ", "HCINTMSK", "HCTSIZ ", "HCDMA ",
968
static uint64_t dwc2_hreg1_read(void *ptr, hwaddr addr, int index,
974
if (addr < HCCHAR(0) || addr > HCDMAB(DWC2_NB_CHAN - 1)) {
975
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
980
val = s->hreg1[index];
982
trace_usb_dwc2_hreg1_read(addr, hreg1nm[index & 7], addr >> 5, val);
986
static void dwc2_hreg1_write(void *ptr, hwaddr addr, int index, uint64_t val,
997
if (addr < HCCHAR(0) || addr > HCDMAB(DWC2_NB_CHAN - 1)) {
998
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
1003
mmio = &s->hreg1[index];
1006
switch (HSOTG_REG(0x500) + (addr & 0x1c)) {
1008
if ((val & HCCHAR_CHDIS) && !(old & HCCHAR_CHDIS)) {
1009
val &= ~(HCCHAR_CHENA | HCCHAR_CHDIS);
1012
val |= old & HCCHAR_CHDIS;
1013
if ((val & HCCHAR_CHENA) && !(old & HCCHAR_CHENA)) {
1014
val &= ~HCCHAR_CHDIS;
1017
val |= old & HCCHAR_CHENA;
1025
val &= ~HCINTMSK_RESERVED14_31;
1029
val &= ~HCINTMSK_RESERVED14_31;
1033
qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
1040
trace_usb_dwc2_hreg1_write(addr, hreg1nm[index & 7], index >> 3, orig,
1046
s->hreg1[(index & ~7) + 2] |= HCINTMSK_CHHLTD;
1051
dwc2_enable_chan(s, index & ~7);
1055
dwc2_update_hc_irq(s, index & ~7);
1059
static const char *pcgregnm[] = {
1060
"PCGCTL ", "PCGCCTL1 "
1063
static uint64_t dwc2_pcgreg_read(void *ptr, hwaddr addr, int index,
1069
if (addr < PCGCTL || addr > PCGCCTL1) {
1070
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
1075
val = s->pcgreg[index];
1077
trace_usb_dwc2_pcgreg_read(addr, pcgregnm[index], val);
1081
static void dwc2_pcgreg_write(void *ptr, hwaddr addr, int index,
1082
uint64_t val, unsigned size)
1085
uint64_t orig = val;
1089
if (addr < PCGCTL || addr > PCGCCTL1) {
1090
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
1095
mmio = &s->pcgreg[index];
1098
trace_usb_dwc2_pcgreg_write(addr, pcgregnm[index], orig, old, val);
1102
static uint64_t dwc2_hsotg_read(void *ptr, hwaddr addr, unsigned size)
1107
case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
1108
val = dwc2_glbreg_read(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, size);
1110
case HSOTG_REG(0x100):
1111
val = dwc2_fszreg_read(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, size);
1113
case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
1117
case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
1118
val = dwc2_hreg0_read(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, size);
1120
case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
1121
val = dwc2_hreg1_read(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, size);
1123
case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
1127
case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
1128
val = dwc2_pcgreg_read(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, size);
1131
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
1140
static void dwc2_hsotg_write(void *ptr, hwaddr addr, uint64_t val,
1144
case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
1145
dwc2_glbreg_write(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, val, size);
1147
case HSOTG_REG(0x100):
1148
dwc2_fszreg_write(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, val, size);
1150
case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
1153
case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
1154
dwc2_hreg0_write(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, val, size);
1156
case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
1157
dwc2_hreg1_write(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, val, size);
1159
case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
1162
case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
1163
dwc2_pcgreg_write(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, val, size);
1166
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
1172
static const MemoryRegionOps dwc2_mmio_hsotg_ops = {
1173
.read = dwc2_hsotg_read,
1174
.write = dwc2_hsotg_write,
1175
.impl.min_access_size = 4,
1176
.impl.max_access_size = 4,
1177
.endianness = DEVICE_LITTLE_ENDIAN,
1180
static uint64_t dwc2_hreg2_read(void *ptr, hwaddr addr, unsigned size)
1183
trace_usb_dwc2_hreg2_read(addr, addr >> 12, 0);
1184
qemu_log_mask(LOG_UNIMP, "%s: FIFO read not implemented\n", __func__);
1188
static void dwc2_hreg2_write(void *ptr, hwaddr addr, uint64_t val,
1191
uint64_t orig = val;
1194
trace_usb_dwc2_hreg2_write(addr, addr >> 12, orig, 0, val);
1195
qemu_log_mask(LOG_UNIMP, "%s: FIFO write not implemented\n", __func__);
1198
static const MemoryRegionOps dwc2_mmio_hreg2_ops = {
1199
.read = dwc2_hreg2_read,
1200
.write = dwc2_hreg2_write,
1201
.impl.min_access_size = 4,
1202
.impl.max_access_size = 4,
1203
.endianness = DEVICE_LITTLE_ENDIAN,
1206
static void dwc2_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
1207
unsigned int stream)
1209
DWC2State *s = container_of(bus, DWC2State, bus);
1211
trace_usb_dwc2_wakeup_endpoint(ep, stream);
1214
qemu_bh_schedule(s->async_bh);
1217
static USBBusOps dwc2_bus_ops = {
1218
.wakeup_endpoint = dwc2_wakeup_endpoint,
1221
static void dwc2_work_timer(void *opaque)
1223
DWC2State *s = opaque;
1225
trace_usb_dwc2_work_timer();
1226
qemu_bh_schedule(s->async_bh);
1229
static void dwc2_reset_enter(Object *obj, ResetType type)
1231
DWC2Class *c = DWC2_USB_GET_CLASS(obj);
1232
DWC2State *s = DWC2_USB(obj);
1235
trace_usb_dwc2_reset_enter();
1237
if (c->parent_phases.enter) {
1238
c->parent_phases.enter(obj, type);
1241
timer_del(s->frame_timer);
1242
qemu_bh_cancel(s->async_bh);
1244
if (s->uport.dev && s->uport.dev->attached) {
1245
usb_detach(&s->uport);
1250
s->gotgctl = GOTGCTL_BSESVLD | GOTGCTL_ASESVLD | GOTGCTL_CONID_B;
1253
s->gusbcfg = 5 << GUSBCFG_USBTRDTIM_SHIFT;
1254
s->grstctl = GRSTCTL_AHBIDLE;
1255
s->gintsts = GINTSTS_CONIDSTSCHNG | GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP |
1256
GINTSTS_CURMODE_HOST;
1261
s->gnptxfsiz = 1024 << FIFOSIZE_DEPTH_SHIFT;
1262
s->gnptxsts = (4 << FIFOSIZE_DEPTH_SHIFT) | 1024;
1263
s->gi2cctl = GI2CCTL_I2CDATSE0 | GI2CCTL_ACK;
1267
s->gsnpsid = 0x4f54294a;
1269
s->ghwcfg2 = (8 << GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT) |
1270
(4 << GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT) |
1271
(4 << GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT) |
1272
GHWCFG2_DYNAMIC_FIFO |
1273
GHWCFG2_PERIO_EP_SUPPORTED |
1274
((DWC2_NB_CHAN - 1) << GHWCFG2_NUM_HOST_CHAN_SHIFT) |
1275
(GHWCFG2_INT_DMA_ARCH << GHWCFG2_ARCHITECTURE_SHIFT) |
1276
(GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST << GHWCFG2_OP_MODE_SHIFT);
1277
s->ghwcfg3 = (4096 << GHWCFG3_DFIFO_DEPTH_SHIFT) |
1278
(4 << GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT) |
1279
(4 << GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT);
1282
s->gpwrdn = GPWRDN_PWRDNRSTN;
1289
s->hptxfsiz = 500 << FIFOSIZE_DEPTH_SHIFT;
1291
s->hcfg = 2 << HCFG_RESVALID_SHIFT;
1294
s->hptxsts = (16 << TXSTS_QSPCAVAIL_SHIFT) | 32768;
1299
memset(s->hreg1, 0, sizeof(s->hreg1));
1300
memset(s->pcgreg, 0, sizeof(s->pcgreg));
1303
s->frame_number = 0;
1304
s->fi = USB_FRMINTVL - 1;
1308
for (i = 0; i < DWC2_NB_CHAN; i++) {
1309
s->packet[i].needs_service = false;
1313
static void dwc2_reset_hold(Object *obj, ResetType type)
1315
DWC2Class *c = DWC2_USB_GET_CLASS(obj);
1316
DWC2State *s = DWC2_USB(obj);
1318
trace_usb_dwc2_reset_hold();
1320
if (c->parent_phases.hold) {
1321
c->parent_phases.hold(obj, type);
1327
static void dwc2_reset_exit(Object *obj, ResetType type)
1329
DWC2Class *c = DWC2_USB_GET_CLASS(obj);
1330
DWC2State *s = DWC2_USB(obj);
1332
trace_usb_dwc2_reset_exit();
1334
if (c->parent_phases.exit) {
1335
c->parent_phases.exit(obj, type);
1338
s->hprt0 = HPRT0_PWR;
1339
if (s->uport.dev && s->uport.dev->attached) {
1340
usb_attach(&s->uport);
1341
usb_device_reset(s->uport.dev);
1345
static void dwc2_realize(DeviceState *dev, Error **errp)
1347
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1348
DWC2State *s = DWC2_USB(dev);
1351
obj = object_property_get_link(OBJECT(dev), "dma-mr", &error_abort);
1353
s->dma_mr = MEMORY_REGION(obj);
1354
address_space_init(&s->dma_as, s->dma_mr, "dwc2");
1356
usb_bus_new(&s->bus, sizeof(s->bus), &dwc2_bus_ops, dev);
1357
usb_register_port(&s->bus, &s->uport, s, 0, &dwc2_port_ops,
1358
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
1359
(s->usb_version == 2 ? USB_SPEED_MASK_HIGH : 0));
1362
s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000;
1363
if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
1364
s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS;
1366
s->usb_bit_time = 1;
1369
s->fi = USB_FRMINTVL - 1;
1370
s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s);
1371
s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s);
1372
s->async_bh = qemu_bh_new_guarded(dwc2_work_bh, s,
1373
&dev->mem_reentrancy_guard);
1375
sysbus_init_irq(sbd, &s->irq);
1378
static void dwc2_init(Object *obj)
1380
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1381
DWC2State *s = DWC2_USB(obj);
1383
memory_region_init(&s->container, obj, "dwc2", DWC2_MMIO_SIZE);
1384
sysbus_init_mmio(sbd, &s->container);
1386
memory_region_init_io(&s->hsotg, obj, &dwc2_mmio_hsotg_ops, s,
1387
"dwc2-io", 4 * KiB);
1388
memory_region_add_subregion(&s->container, 0x0000, &s->hsotg);
1390
memory_region_init_io(&s->fifos, obj, &dwc2_mmio_hreg2_ops, s,
1391
"dwc2-fifo", 64 * KiB);
1392
memory_region_add_subregion(&s->container, 0x1000, &s->fifos);
1395
static const VMStateDescription vmstate_dwc2_state_packet = {
1396
.name = "dwc2/packet",
1398
.minimum_version_id = 1,
1399
.fields = (const VMStateField[]) {
1400
VMSTATE_UINT32(devadr, DWC2Packet),
1401
VMSTATE_UINT32(epnum, DWC2Packet),
1402
VMSTATE_UINT32(epdir, DWC2Packet),
1403
VMSTATE_UINT32(mps, DWC2Packet),
1404
VMSTATE_UINT32(pid, DWC2Packet),
1405
VMSTATE_UINT32(index, DWC2Packet),
1406
VMSTATE_UINT32(pcnt, DWC2Packet),
1407
VMSTATE_UINT32(len, DWC2Packet),
1408
VMSTATE_INT32(async, DWC2Packet),
1409
VMSTATE_BOOL(small, DWC2Packet),
1410
VMSTATE_BOOL(needs_service, DWC2Packet),
1411
VMSTATE_END_OF_LIST()
1415
const VMStateDescription vmstate_dwc2_state = {
1418
.minimum_version_id = 1,
1419
.fields = (const VMStateField[]) {
1420
VMSTATE_UINT32_ARRAY(glbreg, DWC2State,
1421
DWC2_GLBREG_SIZE / sizeof(uint32_t)),
1422
VMSTATE_UINT32_ARRAY(fszreg, DWC2State,
1423
DWC2_FSZREG_SIZE / sizeof(uint32_t)),
1424
VMSTATE_UINT32_ARRAY(hreg0, DWC2State,
1425
DWC2_HREG0_SIZE / sizeof(uint32_t)),
1426
VMSTATE_UINT32_ARRAY(hreg1, DWC2State,
1427
DWC2_HREG1_SIZE / sizeof(uint32_t)),
1428
VMSTATE_UINT32_ARRAY(pcgreg, DWC2State,
1429
DWC2_PCGREG_SIZE / sizeof(uint32_t)),
1431
VMSTATE_TIMER_PTR(eof_timer, DWC2State),
1432
VMSTATE_TIMER_PTR(frame_timer, DWC2State),
1433
VMSTATE_INT64(sof_time, DWC2State),
1434
VMSTATE_INT64(usb_frame_time, DWC2State),
1435
VMSTATE_INT64(usb_bit_time, DWC2State),
1436
VMSTATE_UINT32(usb_version, DWC2State),
1437
VMSTATE_UINT16(frame_number, DWC2State),
1438
VMSTATE_UINT16(fi, DWC2State),
1439
VMSTATE_UINT16(next_chan, DWC2State),
1440
VMSTATE_BOOL(working, DWC2State),
1442
VMSTATE_STRUCT_ARRAY(packet, DWC2State, DWC2_NB_CHAN, 1,
1443
vmstate_dwc2_state_packet, DWC2Packet),
1444
VMSTATE_UINT8_2DARRAY(usb_buf, DWC2State, DWC2_NB_CHAN,
1445
DWC2_MAX_XFER_SIZE),
1447
VMSTATE_END_OF_LIST()
1451
static Property dwc2_usb_properties[] = {
1452
DEFINE_PROP_UINT32("usb_version", DWC2State, usb_version, 2),
1453
DEFINE_PROP_END_OF_LIST(),
1456
static void dwc2_class_init(ObjectClass *klass, void *data)
1458
DeviceClass *dc = DEVICE_CLASS(klass);
1459
DWC2Class *c = DWC2_USB_CLASS(klass);
1460
ResettableClass *rc = RESETTABLE_CLASS(klass);
1462
dc->realize = dwc2_realize;
1463
dc->vmsd = &vmstate_dwc2_state;
1464
set_bit(DEVICE_CATEGORY_USB, dc->categories);
1465
device_class_set_props(dc, dwc2_usb_properties);
1466
resettable_class_set_parent_phases(rc, dwc2_reset_enter, dwc2_reset_hold,
1467
dwc2_reset_exit, &c->parent_phases);
1470
static const TypeInfo dwc2_usb_type_info = {
1471
.name = TYPE_DWC2_USB,
1472
.parent = TYPE_SYS_BUS_DEVICE,
1473
.instance_size = sizeof(DWC2State),
1474
.instance_init = dwc2_init,
1475
.class_size = sizeof(DWC2Class),
1476
.class_init = dwc2_class_init,
1479
static void dwc2_usb_register_types(void)
1481
type_register_static(&dwc2_usb_type_info);
1484
type_init(dwc2_usb_register_types)