2
* "Inventra" High-speed Dual-Role Controller (MUSB-HDRC), Mentor Graphics,
3
* USB2.0 OTG compliant core used in various chips.
5
* Copyright (C) 2008 Nokia Corporation
6
* Written by Andrzej Zaborowski <andrew@openedhand.com>
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public License as
10
* published by the Free Software Foundation; either version 2 or
11
* (at your option) version 3 of the License.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License along
19
* with this program; if not, see <http://www.gnu.org/licenses/>.
21
* Only host-mode and non-DMA accesses are currently supported.
23
#include "qemu-common.h"
24
#include "qemu-timer.h"
29
/* Common USB registers */
30
#define MUSB_HDRC_FADDR 0x00 /* 8-bit */
31
#define MUSB_HDRC_POWER 0x01 /* 8-bit */
33
#define MUSB_HDRC_INTRTX 0x02 /* 16-bit */
34
#define MUSB_HDRC_INTRRX 0x04
35
#define MUSB_HDRC_INTRTXE 0x06
36
#define MUSB_HDRC_INTRRXE 0x08
37
#define MUSB_HDRC_INTRUSB 0x0a /* 8 bit */
38
#define MUSB_HDRC_INTRUSBE 0x0b /* 8 bit */
39
#define MUSB_HDRC_FRAME 0x0c /* 16-bit */
40
#define MUSB_HDRC_INDEX 0x0e /* 8 bit */
41
#define MUSB_HDRC_TESTMODE 0x0f /* 8 bit */
43
/* Per-EP registers in indexed mode */
44
#define MUSB_HDRC_EP_IDX 0x10 /* 8-bit */
47
#define MUSB_HDRC_FIFO 0x20
49
/* Additional Control Registers */
50
#define MUSB_HDRC_DEVCTL 0x60 /* 8 bit */
52
/* These are indexed */
53
#define MUSB_HDRC_TXFIFOSZ 0x62 /* 8 bit (see masks) */
54
#define MUSB_HDRC_RXFIFOSZ 0x63 /* 8 bit (see masks) */
55
#define MUSB_HDRC_TXFIFOADDR 0x64 /* 16 bit offset shifted right 3 */
56
#define MUSB_HDRC_RXFIFOADDR 0x66 /* 16 bit offset shifted right 3 */
58
/* Some more registers */
59
#define MUSB_HDRC_VCTRL 0x68 /* 8 bit */
60
#define MUSB_HDRC_HWVERS 0x6c /* 8 bit */
62
/* Added in HDRC 1.9(?) & MHDRC 1.4 */
63
/* ULPI pass-through */
64
#define MUSB_HDRC_ULPI_VBUSCTL 0x70
65
#define MUSB_HDRC_ULPI_REGDATA 0x74
66
#define MUSB_HDRC_ULPI_REGADDR 0x75
67
#define MUSB_HDRC_ULPI_REGCTL 0x76
68
#define MUSB_HDRC_ULPI_RAWDATA 0x77
70
/* Extended config & PHY control */
71
#define MUSB_HDRC_ENDCOUNT 0x78 /* 8 bit */
72
#define MUSB_HDRC_DMARAMCFG 0x79 /* 8 bit */
73
#define MUSB_HDRC_PHYWAIT 0x7a /* 8 bit */
74
#define MUSB_HDRC_PHYVPLEN 0x7b /* 8 bit */
75
#define MUSB_HDRC_HS_EOF1 0x7c /* 8 bit, units of 546.1 us */
76
#define MUSB_HDRC_FS_EOF1 0x7d /* 8 bit, units of 533.3 ns */
77
#define MUSB_HDRC_LS_EOF1 0x7e /* 8 bit, units of 1.067 us */
79
/* Per-EP BUSCTL registers */
80
#define MUSB_HDRC_BUSCTL 0x80
82
/* Per-EP registers in flat mode */
83
#define MUSB_HDRC_EP 0x100
85
/* offsets to registers in flat model */
86
#define MUSB_HDRC_TXMAXP 0x00 /* 16 bit apparently */
87
#define MUSB_HDRC_TXCSR 0x02 /* 16 bit apparently */
88
#define MUSB_HDRC_CSR0 MUSB_HDRC_TXCSR /* re-used for EP0 */
89
#define MUSB_HDRC_RXMAXP 0x04 /* 16 bit apparently */
90
#define MUSB_HDRC_RXCSR 0x06 /* 16 bit apparently */
91
#define MUSB_HDRC_RXCOUNT 0x08 /* 16 bit apparently */
92
#define MUSB_HDRC_COUNT0 MUSB_HDRC_RXCOUNT /* re-used for EP0 */
93
#define MUSB_HDRC_TXTYPE 0x0a /* 8 bit apparently */
94
#define MUSB_HDRC_TYPE0 MUSB_HDRC_TXTYPE /* re-used for EP0 */
95
#define MUSB_HDRC_TXINTERVAL 0x0b /* 8 bit apparently */
96
#define MUSB_HDRC_NAKLIMIT0 MUSB_HDRC_TXINTERVAL /* re-used for EP0 */
97
#define MUSB_HDRC_RXTYPE 0x0c /* 8 bit apparently */
98
#define MUSB_HDRC_RXINTERVAL 0x0d /* 8 bit apparently */
99
#define MUSB_HDRC_FIFOSIZE 0x0f /* 8 bit apparently */
100
#define MUSB_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */
102
/* "Bus control" registers */
103
#define MUSB_HDRC_TXFUNCADDR 0x00
104
#define MUSB_HDRC_TXHUBADDR 0x02
105
#define MUSB_HDRC_TXHUBPORT 0x03
107
#define MUSB_HDRC_RXFUNCADDR 0x04
108
#define MUSB_HDRC_RXHUBADDR 0x06
109
#define MUSB_HDRC_RXHUBPORT 0x07
112
* MUSBHDRC Register bit masks
116
#define MGC_M_POWER_ISOUPDATE 0x80
117
#define MGC_M_POWER_SOFTCONN 0x40
118
#define MGC_M_POWER_HSENAB 0x20
119
#define MGC_M_POWER_HSMODE 0x10
120
#define MGC_M_POWER_RESET 0x08
121
#define MGC_M_POWER_RESUME 0x04
122
#define MGC_M_POWER_SUSPENDM 0x02
123
#define MGC_M_POWER_ENSUSPEND 0x01
126
#define MGC_M_INTR_SUSPEND 0x01
127
#define MGC_M_INTR_RESUME 0x02
128
#define MGC_M_INTR_RESET 0x04
129
#define MGC_M_INTR_BABBLE 0x04
130
#define MGC_M_INTR_SOF 0x08
131
#define MGC_M_INTR_CONNECT 0x10
132
#define MGC_M_INTR_DISCONNECT 0x20
133
#define MGC_M_INTR_SESSREQ 0x40
134
#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */
135
#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */
138
#define MGC_M_DEVCTL_BDEVICE 0x80
139
#define MGC_M_DEVCTL_FSDEV 0x40
140
#define MGC_M_DEVCTL_LSDEV 0x20
141
#define MGC_M_DEVCTL_VBUS 0x18
142
#define MGC_S_DEVCTL_VBUS 3
143
#define MGC_M_DEVCTL_HM 0x04
144
#define MGC_M_DEVCTL_HR 0x02
145
#define MGC_M_DEVCTL_SESSION 0x01
148
#define MGC_M_TEST_FORCE_HOST 0x80
149
#define MGC_M_TEST_FIFO_ACCESS 0x40
150
#define MGC_M_TEST_FORCE_FS 0x20
151
#define MGC_M_TEST_FORCE_HS 0x10
152
#define MGC_M_TEST_PACKET 0x08
153
#define MGC_M_TEST_K 0x04
154
#define MGC_M_TEST_J 0x02
155
#define MGC_M_TEST_SE0_NAK 0x01
158
#define MGC_M_CSR0_FLUSHFIFO 0x0100
159
#define MGC_M_CSR0_TXPKTRDY 0x0002
160
#define MGC_M_CSR0_RXPKTRDY 0x0001
162
/* CSR0 in Peripheral mode */
163
#define MGC_M_CSR0_P_SVDSETUPEND 0x0080
164
#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040
165
#define MGC_M_CSR0_P_SENDSTALL 0x0020
166
#define MGC_M_CSR0_P_SETUPEND 0x0010
167
#define MGC_M_CSR0_P_DATAEND 0x0008
168
#define MGC_M_CSR0_P_SENTSTALL 0x0004
170
/* CSR0 in Host mode */
171
#define MGC_M_CSR0_H_NO_PING 0x0800
172
#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */
173
#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */
174
#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080
175
#define MGC_M_CSR0_H_STATUSPKT 0x0040
176
#define MGC_M_CSR0_H_REQPKT 0x0020
177
#define MGC_M_CSR0_H_ERROR 0x0010
178
#define MGC_M_CSR0_H_SETUPPKT 0x0008
179
#define MGC_M_CSR0_H_RXSTALL 0x0004
182
#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */
183
#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */
184
#define MGC_M_CONFIGDATA_BIGENDIAN 0x20
185
#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */
186
#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */
187
#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */
188
#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */
189
#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* Width, 0 => 8b, 1 => 16b */
191
/* TXCSR in Peripheral and Host mode */
192
#define MGC_M_TXCSR_AUTOSET 0x8000
193
#define MGC_M_TXCSR_ISO 0x4000
194
#define MGC_M_TXCSR_MODE 0x2000
195
#define MGC_M_TXCSR_DMAENAB 0x1000
196
#define MGC_M_TXCSR_FRCDATATOG 0x0800
197
#define MGC_M_TXCSR_DMAMODE 0x0400
198
#define MGC_M_TXCSR_CLRDATATOG 0x0040
199
#define MGC_M_TXCSR_FLUSHFIFO 0x0008
200
#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002
201
#define MGC_M_TXCSR_TXPKTRDY 0x0001
203
/* TXCSR in Peripheral mode */
204
#define MGC_M_TXCSR_P_INCOMPTX 0x0080
205
#define MGC_M_TXCSR_P_SENTSTALL 0x0020
206
#define MGC_M_TXCSR_P_SENDSTALL 0x0010
207
#define MGC_M_TXCSR_P_UNDERRUN 0x0004
209
/* TXCSR in Host mode */
210
#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200
211
#define MGC_M_TXCSR_H_DATATOGGLE 0x0100
212
#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080
213
#define MGC_M_TXCSR_H_RXSTALL 0x0020
214
#define MGC_M_TXCSR_H_ERROR 0x0004
216
/* RXCSR in Peripheral and Host mode */
217
#define MGC_M_RXCSR_AUTOCLEAR 0x8000
218
#define MGC_M_RXCSR_DMAENAB 0x2000
219
#define MGC_M_RXCSR_DISNYET 0x1000
220
#define MGC_M_RXCSR_DMAMODE 0x0800
221
#define MGC_M_RXCSR_INCOMPRX 0x0100
222
#define MGC_M_RXCSR_CLRDATATOG 0x0080
223
#define MGC_M_RXCSR_FLUSHFIFO 0x0010
224
#define MGC_M_RXCSR_DATAERROR 0x0008
225
#define MGC_M_RXCSR_FIFOFULL 0x0002
226
#define MGC_M_RXCSR_RXPKTRDY 0x0001
228
/* RXCSR in Peripheral mode */
229
#define MGC_M_RXCSR_P_ISO 0x4000
230
#define MGC_M_RXCSR_P_SENTSTALL 0x0040
231
#define MGC_M_RXCSR_P_SENDSTALL 0x0020
232
#define MGC_M_RXCSR_P_OVERRUN 0x0004
234
/* RXCSR in Host mode */
235
#define MGC_M_RXCSR_H_AUTOREQ 0x4000
236
#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400
237
#define MGC_M_RXCSR_H_DATATOGGLE 0x0200
238
#define MGC_M_RXCSR_H_RXSTALL 0x0040
239
#define MGC_M_RXCSR_H_REQPKT 0x0020
240
#define MGC_M_RXCSR_H_ERROR 0x0004
243
#define MGC_M_HUBADDR_MULTI_TT 0x80
245
/* ULPI: Added in HDRC 1.9(?) & MHDRC 1.4 */
246
#define MGC_M_ULPI_VBCTL_USEEXTVBUSIND 0x02
247
#define MGC_M_ULPI_VBCTL_USEEXTVBUS 0x01
248
#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08
249
#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04
250
#define MGC_M_ULPI_REGCTL_COMPLETE 0x02
251
#define MGC_M_ULPI_REGCTL_REG 0x01
253
/* #define MUSB_DEBUG */
256
#define TRACE(fmt,...) fprintf(stderr, "%s@%d: " fmt "\n", __FUNCTION__, \
257
__LINE__, ##__VA_ARGS__)
263
static void musb_attach(USBPort *port);
264
static void musb_detach(USBPort *port);
265
static void musb_child_detach(USBPort *port, USBDevice *child);
266
static void musb_schedule_cb(USBPort *port, USBPacket *p);
267
static void musb_async_cancel_device(MUSBState *s, USBDevice *dev);
269
static USBPortOps musb_port_ops = {
270
.attach = musb_attach,
271
.detach = musb_detach,
272
.child_detach = musb_child_detach,
273
.complete = musb_schedule_cb,
276
static USBBusOps musb_bus_ops = {
279
typedef struct MUSBPacket MUSBPacket;
280
typedef struct MUSBEndPoint MUSBEndPoint;
288
struct MUSBEndPoint {
299
int timeout[2]; /* Always in microframes */
305
MUSBPacket packey[2];
309
/* For callbacks' use */
313
USBCallback *delayed_cb[2];
314
QEMUTimer *intv_timer[2];
318
qemu_irq irqs[musb_irq_max];
339
/* Duplicating the world since 2008!... probably we should have 32
340
* logical, single endpoints instead. */
344
void musb_reset(MUSBState *s)
350
s->power = MGC_M_POWER_HSENAB;
361
memset(s->buf, 0, sizeof(s->buf));
364
s->ep[0].config = MGC_M_CONFIGDATA_SOFTCONE | MGC_M_CONFIGDATA_DYNFIFO;
365
for (i = 0; i < 16; i ++) {
366
s->ep[i].fifosize = 64;
367
s->ep[i].maxp[0] = 0x40;
368
s->ep[i].maxp[1] = 0x40;
371
usb_packet_init(&s->ep[i].packey[0].p);
372
usb_packet_init(&s->ep[i].packey[1].p);
376
struct MUSBState *musb_init(DeviceState *parent_device, int gpio_base)
378
MUSBState *s = g_malloc0(sizeof(*s));
381
for (i = 0; i < musb_irq_max; i++) {
382
s->irqs[i] = qdev_get_gpio_in(parent_device, gpio_base + i);
387
usb_bus_new(&s->bus, &musb_bus_ops, parent_device);
388
usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops,
389
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
394
static void musb_vbus_set(MUSBState *s, int level)
397
s->devctl |= 3 << MGC_S_DEVCTL_VBUS;
399
s->devctl &= ~MGC_M_DEVCTL_VBUS;
401
qemu_set_irq(s->irqs[musb_set_vbus], level);
404
static void musb_intr_set(MUSBState *s, int line, int level)
407
s->intr &= ~(1 << line);
408
qemu_irq_lower(s->irqs[line]);
409
} else if (s->mask & (1 << line)) {
410
s->intr |= 1 << line;
411
qemu_irq_raise(s->irqs[line]);
415
static void musb_tx_intr_set(MUSBState *s, int line, int level)
418
s->tx_intr &= ~(1 << line);
420
qemu_irq_lower(s->irqs[musb_irq_tx]);
421
} else if (s->tx_mask & (1 << line)) {
422
s->tx_intr |= 1 << line;
423
qemu_irq_raise(s->irqs[musb_irq_tx]);
427
static void musb_rx_intr_set(MUSBState *s, int line, int level)
431
s->rx_intr &= ~(1 << line);
433
qemu_irq_lower(s->irqs[musb_irq_rx]);
434
} else if (s->rx_mask & (1 << line)) {
435
s->rx_intr |= 1 << line;
436
qemu_irq_raise(s->irqs[musb_irq_rx]);
439
musb_tx_intr_set(s, line, level);
442
uint32_t musb_core_intr_get(MUSBState *s)
444
return (s->rx_intr << 15) | s->tx_intr;
447
void musb_core_intr_clear(MUSBState *s, uint32_t mask)
450
s->rx_intr &= mask >> 15;
452
qemu_irq_lower(s->irqs[musb_irq_rx]);
456
s->tx_intr &= mask & 0xffff;
458
qemu_irq_lower(s->irqs[musb_irq_tx]);
462
void musb_set_size(MUSBState *s, int epnum, int size, int is_tx)
464
s->ep[epnum].ext_size[!is_tx] = size;
465
s->ep[epnum].fifostart[0] = 0;
466
s->ep[epnum].fifostart[1] = 0;
467
s->ep[epnum].fifolen[0] = 0;
468
s->ep[epnum].fifolen[1] = 0;
471
static void musb_session_update(MUSBState *s, int prev_dev, int prev_sess)
473
int detect_prev = prev_dev && prev_sess;
474
int detect = !!s->port.dev && s->session;
476
if (detect && !detect_prev) {
477
/* Let's skip the ID pin sense and VBUS sense formalities and
478
* and signal a successful SRP directly. This should work at least
479
* for the Linux driver stack. */
480
musb_intr_set(s, musb_irq_connect, 1);
482
if (s->port.dev->speed == USB_SPEED_LOW) {
483
s->devctl &= ~MGC_M_DEVCTL_FSDEV;
484
s->devctl |= MGC_M_DEVCTL_LSDEV;
486
s->devctl |= MGC_M_DEVCTL_FSDEV;
487
s->devctl &= ~MGC_M_DEVCTL_LSDEV;
491
s->devctl &= ~MGC_M_DEVCTL_BDEVICE;
494
s->devctl |= MGC_M_DEVCTL_HM;
498
} else if (!detect && detect_prev) {
505
/* Attach or detach a device on our only port. */
506
static void musb_attach(USBPort *port)
508
MUSBState *s = (MUSBState *) port->opaque;
510
musb_intr_set(s, musb_irq_vbus_request, 1);
511
musb_session_update(s, 0, s->session);
514
static void musb_detach(USBPort *port)
516
MUSBState *s = (MUSBState *) port->opaque;
518
musb_async_cancel_device(s, port->dev);
520
musb_intr_set(s, musb_irq_disconnect, 1);
521
musb_session_update(s, 1, s->session);
524
static void musb_child_detach(USBPort *port, USBDevice *child)
526
MUSBState *s = (MUSBState *) port->opaque;
528
musb_async_cancel_device(s, child);
531
static void musb_cb_tick0(void *opaque)
533
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
535
ep->delayed_cb[0](&ep->packey[0].p, opaque);
538
static void musb_cb_tick1(void *opaque)
540
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
542
ep->delayed_cb[1](&ep->packey[1].p, opaque);
545
#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0)
547
static void musb_schedule_cb(USBPort *port, USBPacket *packey)
549
MUSBPacket *p = container_of(packey, MUSBPacket, p);
550
MUSBEndPoint *ep = p->ep;
554
if (ep->status[dir] == USB_RET_NAK)
555
timeout = ep->timeout[dir];
556
else if (ep->interrupt[dir])
559
return musb_cb_tick(ep);
561
if (!ep->intv_timer[dir])
562
ep->intv_timer[dir] = qemu_new_timer_ns(vm_clock, musb_cb_tick, ep);
564
qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock_ns(vm_clock) +
565
muldiv64(timeout, get_ticks_per_sec(), 8000));
568
static int musb_timeout(int ttype, int speed, int val)
575
case USB_ENDPOINT_XFER_CONTROL:
578
else if (speed == USB_SPEED_HIGH)
579
return 1 << (val - 1);
581
return 8 << (val - 1);
583
case USB_ENDPOINT_XFER_INT:
584
if (speed == USB_SPEED_HIGH)
588
return 1 << (val - 1);
592
case USB_ENDPOINT_XFER_BULK:
593
case USB_ENDPOINT_XFER_ISOC:
596
else if (speed == USB_SPEED_HIGH)
597
return 1 << (val - 1);
599
return 8 << (val - 1);
600
/* TODO: what with low-speed Bulk and Isochronous? */
603
hw_error("bad interval\n");
606
static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
607
int epnum, int pid, int len, USBCallback cb, int dir)
612
int idx = epnum && dir;
615
/* ep->type[0,1] contains:
616
* in bits 7:6 the speed (0 - invalid, 1 - high, 2 - full, 3 - slow)
617
* in bits 5:4 the transfer type (BULK / INT)
618
* in bits 3:0 the EP num
620
ttype = epnum ? (ep->type[idx] >> 4) & 3 : 0;
622
ep->timeout[dir] = musb_timeout(ttype,
623
ep->type[idx] >> 6, ep->interval[idx]);
624
ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT;
625
ep->delayed_cb[dir] = cb;
627
/* A wild guess on the FADDR semantics... */
628
dev = usb_find_device(&s->port, ep->faddr[idx]);
629
uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf);
630
usb_packet_setup(&ep->packey[dir].p, pid, uep);
631
usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len);
632
ep->packey[dir].ep = ep;
633
ep->packey[dir].dir = dir;
635
ret = usb_handle_packet(dev, &ep->packey[dir].p);
637
if (ret == USB_RET_ASYNC) {
638
ep->status[dir] = len;
642
ep->status[dir] = ret;
643
musb_schedule_cb(&s->port, &ep->packey[dir].p);
646
static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
648
/* Unfortunately we can't use packey->devep because that's the remote
649
* endpoint number and may be different than our local. */
650
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
651
int epnum = ep->epnum;
652
MUSBState *s = ep->musb;
654
ep->fifostart[0] = 0;
657
if (ep->status[0] != USB_RET_NAK) {
660
ep->csr[0] &= ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
662
ep->csr[0] &= ~MGC_M_CSR0_TXPKTRDY;
667
/* Clear all of the error bits first */
669
ep->csr[0] &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
670
MGC_M_TXCSR_H_NAKTIMEOUT);
672
ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
673
MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
675
if (ep->status[0] == USB_RET_STALL) {
676
/* Command not supported by target! */
680
ep->csr[0] |= MGC_M_TXCSR_H_RXSTALL;
682
ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
685
if (ep->status[0] == USB_RET_NAK) {
688
/* NAK timeouts are only generated in Bulk transfers and
689
* Data-errors in Isochronous. */
690
if (ep->interrupt[0]) {
695
ep->csr[0] |= MGC_M_TXCSR_H_NAKTIMEOUT;
697
ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
700
if (ep->status[0] < 0) {
701
if (ep->status[0] == USB_RET_BABBLE)
702
musb_intr_set(s, musb_irq_rst_babble, 1);
704
/* Pretend we've tried three times already and failed (in
705
* case of USB_TOKEN_SETUP). */
707
ep->csr[0] |= MGC_M_TXCSR_H_ERROR;
709
ep->csr[0] |= MGC_M_CSR0_H_ERROR;
711
musb_tx_intr_set(s, epnum, 1);
714
/* TODO: check len for over/underruns of an OUT packet? */
717
if (!epnum && ep->packey[0].pid == USB_TOKEN_SETUP)
718
s->setup_len = ep->packey[0].data[6];
721
/* In DMA mode: if no error, assert DMA request for this EP,
722
* and skip the interrupt. */
723
musb_tx_intr_set(s, epnum, 1);
726
static void musb_rx_packet_complete(USBPacket *packey, void *opaque)
728
/* Unfortunately we can't use packey->devep because that's the remote
729
* endpoint number and may be different than our local. */
730
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
731
int epnum = ep->epnum;
732
MUSBState *s = ep->musb;
734
ep->fifostart[1] = 0;
738
if (ep->status[1] != USB_RET_NAK) {
740
ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
742
ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
747
/* Clear all of the imaginable error bits first */
748
ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
749
MGC_M_RXCSR_DATAERROR);
751
ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
752
MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
754
if (ep->status[1] == USB_RET_STALL) {
758
ep->csr[1] |= MGC_M_RXCSR_H_RXSTALL;
760
ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
763
if (ep->status[1] == USB_RET_NAK) {
766
/* NAK timeouts are only generated in Bulk transfers and
767
* Data-errors in Isochronous. */
768
if (ep->interrupt[1])
769
return musb_packet(s, ep, epnum, USB_TOKEN_IN,
770
packey->iov.size, musb_rx_packet_complete, 1);
772
ep->csr[1] |= MGC_M_RXCSR_DATAERROR;
774
ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
777
if (ep->status[1] < 0) {
778
if (ep->status[1] == USB_RET_BABBLE) {
779
musb_intr_set(s, musb_irq_rst_babble, 1);
783
/* Pretend we've tried three times already and failed (in
784
* case of a control transfer). */
785
ep->csr[1] |= MGC_M_RXCSR_H_ERROR;
787
ep->csr[0] |= MGC_M_CSR0_H_ERROR;
789
musb_rx_intr_set(s, epnum, 1);
792
/* TODO: check len for over/underruns of an OUT packet? */
793
/* TODO: perhaps make use of e->ext_size[1] here. */
795
packey->result = ep->status[1];
797
if (!(ep->csr[1] & (MGC_M_RXCSR_H_RXSTALL | MGC_M_RXCSR_DATAERROR))) {
798
ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
800
ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
802
ep->rxcount = packey->result; /* XXX: MIN(packey->len, ep->maxp[1]); */
803
/* In DMA mode: assert DMA request for this EP */
806
/* Only if DMA has not been asserted */
807
musb_rx_intr_set(s, epnum, 1);
810
static void musb_async_cancel_device(MUSBState *s, USBDevice *dev)
814
for (ep = 0; ep < 16; ep++) {
815
for (dir = 0; dir < 2; dir++) {
816
if (!usb_packet_is_inflight(&s->ep[ep].packey[dir].p) ||
817
s->ep[ep].packey[dir].p.ep->dev != dev) {
820
usb_cancel_packet(&s->ep[ep].packey[dir].p);
821
/* status updates needed here? */
826
static void musb_tx_rdy(MUSBState *s, int epnum)
828
MUSBEndPoint *ep = s->ep + epnum;
830
int total, valid = 0;
831
TRACE("start %d, len %d", ep->fifostart[0], ep->fifolen[0] );
832
ep->fifostart[0] += ep->fifolen[0];
835
/* XXX: how's the total size of the packet retrieved exactly in
836
* the generic case? */
837
total = ep->maxp[0] & 0x3ff;
839
if (ep->ext_size[0]) {
840
total = ep->ext_size[0];
845
/* If the packet is not fully ready yet, wait for a next segment. */
846
if (epnum && (ep->fifostart[0]) < total)
850
total = ep->fifostart[0];
853
if (!epnum && (ep->csr[0] & MGC_M_CSR0_H_SETUPPKT)) {
854
pid = USB_TOKEN_SETUP;
856
TRACE("illegal SETUPPKT length of %i bytes", total);
858
/* Controller should retry SETUP packets three times on errors
859
* but it doesn't make sense for us to do that. */
862
return musb_packet(s, ep, epnum, pid,
863
total, musb_tx_packet_complete, 0);
866
static void musb_rx_req(MUSBState *s, int epnum)
868
MUSBEndPoint *ep = s->ep + epnum;
871
/* If we already have a packet, which didn't fit into the
872
* 64 bytes of the FIFO, only move the FIFO start and return. (Obsolete) */
873
if (ep->packey[1].p.pid == USB_TOKEN_IN && ep->status[1] >= 0 &&
874
(ep->fifostart[1]) + ep->rxcount <
875
ep->packey[1].p.iov.size) {
876
TRACE("0x%08x, %d", ep->fifostart[1], ep->rxcount );
877
ep->fifostart[1] += ep->rxcount;
880
ep->rxcount = MIN(ep->packey[0].p.iov.size - (ep->fifostart[1]),
883
ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
885
ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
887
/* Clear all of the error bits first */
888
ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
889
MGC_M_RXCSR_DATAERROR);
891
ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
892
MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
894
ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
896
ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
897
musb_rx_intr_set(s, epnum, 1);
901
/* The driver sets maxp[1] to 64 or less because it knows the hardware
902
* FIFO is this deep. Bigger packets get split in
903
* usb_generic_handle_packet but we can also do the splitting locally
904
* for performance. It turns out we can also have a bigger FIFO and
905
* ignore the limit set in ep->maxp[1]. The Linux MUSB driver deals
906
* OK with single packets of even 32KB and we avoid splitting, however
907
* usb_msd.c sometimes sends a packet bigger than what Linux expects
908
* (e.g. 8192 bytes instead of 4096) and we get an OVERRUN. Splitting
909
* hides this overrun from Linux. Up to 4096 everything is fine
910
* though. Currently this is disabled.
912
* XXX: mind ep->fifosize. */
913
total = MIN(ep->maxp[1] & 0x3ff, sizeof(s->buf));
916
/* Why should *we* do that instead of Linux? */
918
if (ep->packey[0].p.devaddr == 2) {
919
total = MIN(s->setup_len, 8);
921
total = MIN(s->setup_len, 64);
923
s->setup_len -= total;
927
return musb_packet(s, ep, epnum, USB_TOKEN_IN,
928
total, musb_rx_packet_complete, 1);
931
static uint8_t musb_read_fifo(MUSBEndPoint *ep)
934
if (ep->fifolen[1] >= 64) {
935
/* We have a FIFO underrun */
936
TRACE("EP%d FIFO is now empty, stop reading", ep->epnum);
939
/* In DMA mode clear RXPKTRDY and set REQPKT automatically
940
* (if AUTOREQ is set) */
942
ep->csr[1] &= ~MGC_M_RXCSR_FIFOFULL;
943
value=ep->buf[1][ep->fifostart[1] + ep->fifolen[1] ++];
944
TRACE("EP%d 0x%02x, %d", ep->epnum, value, ep->fifolen[1] );
948
static void musb_write_fifo(MUSBEndPoint *ep, uint8_t value)
950
TRACE("EP%d = %02x", ep->epnum, value);
951
if (ep->fifolen[0] >= 64) {
952
/* We have a FIFO overrun */
953
TRACE("EP%d FIFO exceeded 64 bytes, stop feeding data", ep->epnum);
957
ep->buf[0][ep->fifostart[0] + ep->fifolen[0] ++] = value;
958
ep->csr[0] |= MGC_M_TXCSR_FIFONOTEMPTY;
961
static void musb_ep_frame_cancel(MUSBEndPoint *ep, int dir)
963
if (ep->intv_timer[dir])
964
qemu_del_timer(ep->intv_timer[dir]);
968
static uint8_t musb_busctl_readb(void *opaque, int ep, int addr)
970
MUSBState *s = (MUSBState *) opaque;
973
/* For USB2.0 HS hubs only */
974
case MUSB_HDRC_TXHUBADDR:
975
return s->ep[ep].haddr[0];
976
case MUSB_HDRC_TXHUBPORT:
977
return s->ep[ep].hport[0];
978
case MUSB_HDRC_RXHUBADDR:
979
return s->ep[ep].haddr[1];
980
case MUSB_HDRC_RXHUBPORT:
981
return s->ep[ep].hport[1];
984
TRACE("unknown register 0x%02x", addr);
989
static void musb_busctl_writeb(void *opaque, int ep, int addr, uint8_t value)
991
MUSBState *s = (MUSBState *) opaque;
994
case MUSB_HDRC_TXFUNCADDR:
995
s->ep[ep].faddr[0] = value;
997
case MUSB_HDRC_RXFUNCADDR:
998
s->ep[ep].faddr[1] = value;
1000
case MUSB_HDRC_TXHUBADDR:
1001
s->ep[ep].haddr[0] = value;
1003
case MUSB_HDRC_TXHUBPORT:
1004
s->ep[ep].hport[0] = value;
1006
case MUSB_HDRC_RXHUBADDR:
1007
s->ep[ep].haddr[1] = value;
1009
case MUSB_HDRC_RXHUBPORT:
1010
s->ep[ep].hport[1] = value;
1014
TRACE("unknown register 0x%02x", addr);
1019
static uint16_t musb_busctl_readh(void *opaque, int ep, int addr)
1021
MUSBState *s = (MUSBState *) opaque;
1024
case MUSB_HDRC_TXFUNCADDR:
1025
return s->ep[ep].faddr[0];
1026
case MUSB_HDRC_RXFUNCADDR:
1027
return s->ep[ep].faddr[1];
1030
return musb_busctl_readb(s, ep, addr) |
1031
(musb_busctl_readb(s, ep, addr | 1) << 8);
1035
static void musb_busctl_writeh(void *opaque, int ep, int addr, uint16_t value)
1037
MUSBState *s = (MUSBState *) opaque;
1040
case MUSB_HDRC_TXFUNCADDR:
1041
s->ep[ep].faddr[0] = value;
1043
case MUSB_HDRC_RXFUNCADDR:
1044
s->ep[ep].faddr[1] = value;
1048
musb_busctl_writeb(s, ep, addr, value & 0xff);
1049
musb_busctl_writeb(s, ep, addr | 1, value >> 8);
1053
/* Endpoint control */
1054
static uint8_t musb_ep_readb(void *opaque, int ep, int addr)
1056
MUSBState *s = (MUSBState *) opaque;
1059
case MUSB_HDRC_TXTYPE:
1060
return s->ep[ep].type[0];
1061
case MUSB_HDRC_TXINTERVAL:
1062
return s->ep[ep].interval[0];
1063
case MUSB_HDRC_RXTYPE:
1064
return s->ep[ep].type[1];
1065
case MUSB_HDRC_RXINTERVAL:
1066
return s->ep[ep].interval[1];
1067
case (MUSB_HDRC_FIFOSIZE & ~1):
1069
case MUSB_HDRC_FIFOSIZE:
1070
return ep ? s->ep[ep].fifosize : s->ep[ep].config;
1071
case MUSB_HDRC_RXCOUNT:
1072
return s->ep[ep].rxcount;
1075
TRACE("unknown register 0x%02x", addr);
1080
static void musb_ep_writeb(void *opaque, int ep, int addr, uint8_t value)
1082
MUSBState *s = (MUSBState *) opaque;
1085
case MUSB_HDRC_TXTYPE:
1086
s->ep[ep].type[0] = value;
1088
case MUSB_HDRC_TXINTERVAL:
1089
s->ep[ep].interval[0] = value;
1090
musb_ep_frame_cancel(&s->ep[ep], 0);
1092
case MUSB_HDRC_RXTYPE:
1093
s->ep[ep].type[1] = value;
1095
case MUSB_HDRC_RXINTERVAL:
1096
s->ep[ep].interval[1] = value;
1097
musb_ep_frame_cancel(&s->ep[ep], 1);
1099
case (MUSB_HDRC_FIFOSIZE & ~1):
1101
case MUSB_HDRC_FIFOSIZE:
1102
TRACE("somebody messes with fifosize (now %i bytes)", value);
1103
s->ep[ep].fifosize = value;
1106
TRACE("unknown register 0x%02x", addr);
1111
static uint16_t musb_ep_readh(void *opaque, int ep, int addr)
1113
MUSBState *s = (MUSBState *) opaque;
1117
case MUSB_HDRC_TXMAXP:
1118
return s->ep[ep].maxp[0];
1119
case MUSB_HDRC_TXCSR:
1120
return s->ep[ep].csr[0];
1121
case MUSB_HDRC_RXMAXP:
1122
return s->ep[ep].maxp[1];
1123
case MUSB_HDRC_RXCSR:
1124
ret = s->ep[ep].csr[1];
1126
/* TODO: This and other bits probably depend on
1127
* ep->csr[1] & MGC_M_RXCSR_AUTOCLEAR. */
1128
if (s->ep[ep].csr[1] & MGC_M_RXCSR_AUTOCLEAR)
1129
s->ep[ep].csr[1] &= ~MGC_M_RXCSR_RXPKTRDY;
1132
case MUSB_HDRC_RXCOUNT:
1133
return s->ep[ep].rxcount;
1136
return musb_ep_readb(s, ep, addr) |
1137
(musb_ep_readb(s, ep, addr | 1) << 8);
1141
static void musb_ep_writeh(void *opaque, int ep, int addr, uint16_t value)
1143
MUSBState *s = (MUSBState *) opaque;
1146
case MUSB_HDRC_TXMAXP:
1147
s->ep[ep].maxp[0] = value;
1149
case MUSB_HDRC_TXCSR:
1151
s->ep[ep].csr[0] &= value & 0xa6;
1152
s->ep[ep].csr[0] |= value & 0xff59;
1154
s->ep[ep].csr[0] &= value & 0x85;
1155
s->ep[ep].csr[0] |= value & 0xf7a;
1158
musb_ep_frame_cancel(&s->ep[ep], 0);
1160
if ((ep && (value & MGC_M_TXCSR_FLUSHFIFO)) ||
1161
(!ep && (value & MGC_M_CSR0_FLUSHFIFO))) {
1162
s->ep[ep].fifolen[0] = 0;
1163
s->ep[ep].fifostart[0] = 0;
1166
~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
1169
~(MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_RXPKTRDY);
1174
(value & MGC_M_TXCSR_TXPKTRDY) &&
1175
!(value & MGC_M_TXCSR_H_NAKTIMEOUT)) ||
1177
(value & MGC_M_TXCSR_TXPKTRDY)) ||
1181
(value & MGC_M_CSR0_TXPKTRDY) &&
1182
!(value & MGC_M_CSR0_H_NAKTIMEOUT)))
1184
(value & MGC_M_CSR0_TXPKTRDY)))
1188
(value & MGC_M_CSR0_H_REQPKT) &&
1190
!(value & (MGC_M_CSR0_H_NAKTIMEOUT |
1191
MGC_M_CSR0_RXPKTRDY)))
1193
!(value & MGC_M_CSR0_RXPKTRDY))
1198
case MUSB_HDRC_RXMAXP:
1199
s->ep[ep].maxp[1] = value;
1201
case MUSB_HDRC_RXCSR:
1202
/* (DMA mode only) */
1204
(value & MGC_M_RXCSR_H_AUTOREQ) &&
1205
!(value & MGC_M_RXCSR_RXPKTRDY) &&
1206
(s->ep[ep].csr[1] & MGC_M_RXCSR_RXPKTRDY))
1207
value |= MGC_M_RXCSR_H_REQPKT;
1209
s->ep[ep].csr[1] &= 0x102 | (value & 0x4d);
1210
s->ep[ep].csr[1] |= value & 0xfeb0;
1212
musb_ep_frame_cancel(&s->ep[ep], 1);
1214
if (value & MGC_M_RXCSR_FLUSHFIFO) {
1215
s->ep[ep].fifolen[1] = 0;
1216
s->ep[ep].fifostart[1] = 0;
1217
s->ep[ep].csr[1] &= ~(MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY);
1218
/* If double buffering and we have two packets ready, flush
1219
* only the first one and set up the fifo at the second packet. */
1222
if ((value & MGC_M_RXCSR_H_REQPKT) && !(value & MGC_M_RXCSR_DATAERROR))
1224
if (value & MGC_M_RXCSR_H_REQPKT)
1228
case MUSB_HDRC_RXCOUNT:
1229
s->ep[ep].rxcount = value;
1233
musb_ep_writeb(s, ep, addr, value & 0xff);
1234
musb_ep_writeb(s, ep, addr | 1, value >> 8);
1238
/* Generic control */
1239
static uint32_t musb_readb(void *opaque, target_phys_addr_t addr)
1241
MUSBState *s = (MUSBState *) opaque;
1246
case MUSB_HDRC_FADDR:
1248
case MUSB_HDRC_POWER:
1250
case MUSB_HDRC_INTRUSB:
1252
for (i = 0; i < sizeof(ret) * 8; i ++)
1254
musb_intr_set(s, i, 0);
1256
case MUSB_HDRC_INTRUSBE:
1258
case MUSB_HDRC_INDEX:
1260
case MUSB_HDRC_TESTMODE:
1263
case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1264
return musb_ep_readb(s, s->idx, addr & 0xf);
1266
case MUSB_HDRC_DEVCTL:
1269
case MUSB_HDRC_TXFIFOSZ:
1270
case MUSB_HDRC_RXFIFOSZ:
1271
case MUSB_HDRC_VCTRL:
1275
case MUSB_HDRC_HWVERS:
1276
return (1 << 10) | 400;
1278
case (MUSB_HDRC_VCTRL | 1):
1279
case (MUSB_HDRC_HWVERS | 1):
1280
case (MUSB_HDRC_DEVCTL | 1):
1283
case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1284
ep = (addr >> 3) & 0xf;
1285
return musb_busctl_readb(s, ep, addr & 0x7);
1287
case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1288
ep = (addr >> 4) & 0xf;
1289
return musb_ep_readb(s, ep, addr & 0xf);
1291
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1292
ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1293
return musb_read_fifo(s->ep + ep);
1295
case MUSB_HDRC_ULPI_REGADDR:
1296
case MUSB_HDRC_ULPI_REGDATA:
1297
case MUSB_HDRC_ULPI_RAWDATA:
1301
case MUSB_HDRC_ULPI_REGCTL:
1306
TRACE("unknown register 0x%02x", (int) addr);
1311
static void musb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
1313
MUSBState *s = (MUSBState *) opaque;
1317
case MUSB_HDRC_FADDR:
1318
s->faddr = value & 0x7f;
1320
case MUSB_HDRC_POWER:
1321
s->power = (value & 0xef) | (s->power & 0x10);
1322
/* MGC_M_POWER_RESET is also read-only in Peripheral Mode */
1323
if ((value & MGC_M_POWER_RESET) && s->port.dev) {
1324
usb_device_reset(s->port.dev);
1325
/* Negotiate high-speed operation if MGC_M_POWER_HSENAB is set. */
1326
if ((value & MGC_M_POWER_HSENAB) &&
1327
s->port.dev->speed == USB_SPEED_HIGH)
1328
s->power |= MGC_M_POWER_HSMODE; /* Success */
1329
/* Restart frame counting. */
1331
if (value & MGC_M_POWER_SUSPENDM) {
1332
/* When all transfers finish, suspend and if MGC_M_POWER_ENSUSPEND
1333
* is set, also go into low power mode. Frame counting stops. */
1334
/* XXX: Cleared when the interrupt register is read */
1336
if (value & MGC_M_POWER_RESUME) {
1337
/* Wait 20ms and signal resuming on the bus. Frame counting
1341
case MUSB_HDRC_INTRUSB:
1343
case MUSB_HDRC_INTRUSBE:
1344
s->mask = value & 0xff;
1346
case MUSB_HDRC_INDEX:
1347
s->idx = value & 0xf;
1349
case MUSB_HDRC_TESTMODE:
1352
case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1353
musb_ep_writeb(s, s->idx, addr & 0xf, value);
1356
case MUSB_HDRC_DEVCTL:
1357
s->session = !!(value & MGC_M_DEVCTL_SESSION);
1358
musb_session_update(s,
1360
!!(s->devctl & MGC_M_DEVCTL_SESSION));
1362
/* It seems this is the only R/W bit in this register? */
1363
s->devctl &= ~MGC_M_DEVCTL_SESSION;
1364
s->devctl |= value & MGC_M_DEVCTL_SESSION;
1367
case MUSB_HDRC_TXFIFOSZ:
1368
case MUSB_HDRC_RXFIFOSZ:
1369
case MUSB_HDRC_VCTRL:
1373
case (MUSB_HDRC_VCTRL | 1):
1374
case (MUSB_HDRC_DEVCTL | 1):
1377
case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1378
ep = (addr >> 3) & 0xf;
1379
musb_busctl_writeb(s, ep, addr & 0x7, value);
1382
case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1383
ep = (addr >> 4) & 0xf;
1384
musb_ep_writeb(s, ep, addr & 0xf, value);
1387
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1388
ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1389
musb_write_fifo(s->ep + ep, value & 0xff);
1392
case MUSB_HDRC_ULPI_REGADDR:
1393
case MUSB_HDRC_ULPI_REGCTL:
1394
case MUSB_HDRC_ULPI_REGDATA:
1395
case MUSB_HDRC_ULPI_RAWDATA:
1400
TRACE("unknown register 0x%02x", (int) addr);
1405
static uint32_t musb_readh(void *opaque, target_phys_addr_t addr)
1407
MUSBState *s = (MUSBState *) opaque;
1412
case MUSB_HDRC_INTRTX:
1415
for (i = 0; i < sizeof(ret) * 8; i ++)
1417
musb_tx_intr_set(s, i, 0);
1419
case MUSB_HDRC_INTRRX:
1422
for (i = 0; i < sizeof(ret) * 8; i ++)
1424
musb_rx_intr_set(s, i, 0);
1426
case MUSB_HDRC_INTRTXE:
1428
case MUSB_HDRC_INTRRXE:
1431
case MUSB_HDRC_FRAME:
1434
case MUSB_HDRC_TXFIFOADDR:
1435
return s->ep[s->idx].fifoaddr[0];
1436
case MUSB_HDRC_RXFIFOADDR:
1437
return s->ep[s->idx].fifoaddr[1];
1439
case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1440
return musb_ep_readh(s, s->idx, addr & 0xf);
1442
case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1443
ep = (addr >> 3) & 0xf;
1444
return musb_busctl_readh(s, ep, addr & 0x7);
1446
case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1447
ep = (addr >> 4) & 0xf;
1448
return musb_ep_readh(s, ep, addr & 0xf);
1450
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1451
ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1452
return (musb_read_fifo(s->ep + ep) | musb_read_fifo(s->ep + ep) << 8);
1455
return musb_readb(s, addr) | (musb_readb(s, addr | 1) << 8);
1459
static void musb_writeh(void *opaque, target_phys_addr_t addr, uint32_t value)
1461
MUSBState *s = (MUSBState *) opaque;
1465
case MUSB_HDRC_INTRTXE:
1467
/* XXX: the masks seem to apply on the raising edge like with
1468
* edge-triggered interrupts, thus no need to update. I may be
1471
case MUSB_HDRC_INTRRXE:
1475
case MUSB_HDRC_FRAME:
1478
case MUSB_HDRC_TXFIFOADDR:
1479
s->ep[s->idx].fifoaddr[0] = value;
1480
s->ep[s->idx].buf[0] =
1481
s->buf + ((value << 3) & 0x7ff );
1483
case MUSB_HDRC_RXFIFOADDR:
1484
s->ep[s->idx].fifoaddr[1] = value;
1485
s->ep[s->idx].buf[1] =
1486
s->buf + ((value << 3) & 0x7ff);
1489
case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1490
musb_ep_writeh(s, s->idx, addr & 0xf, value);
1493
case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1494
ep = (addr >> 3) & 0xf;
1495
musb_busctl_writeh(s, ep, addr & 0x7, value);
1498
case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1499
ep = (addr >> 4) & 0xf;
1500
musb_ep_writeh(s, ep, addr & 0xf, value);
1503
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1504
ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1505
musb_write_fifo(s->ep + ep, value & 0xff);
1506
musb_write_fifo(s->ep + ep, (value >> 8) & 0xff);
1510
musb_writeb(s, addr, value & 0xff);
1511
musb_writeb(s, addr | 1, value >> 8);
1515
static uint32_t musb_readw(void *opaque, target_phys_addr_t addr)
1517
MUSBState *s = (MUSBState *) opaque;
1521
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1522
ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1523
return ( musb_read_fifo(s->ep + ep) |
1524
musb_read_fifo(s->ep + ep) << 8 |
1525
musb_read_fifo(s->ep + ep) << 16 |
1526
musb_read_fifo(s->ep + ep) << 24 );
1528
TRACE("unknown register 0x%02x", (int) addr);
1533
static void musb_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
1535
MUSBState *s = (MUSBState *) opaque;
1539
case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1540
ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1541
musb_write_fifo(s->ep + ep, value & 0xff);
1542
musb_write_fifo(s->ep + ep, (value >> 8 ) & 0xff);
1543
musb_write_fifo(s->ep + ep, (value >> 16) & 0xff);
1544
musb_write_fifo(s->ep + ep, (value >> 24) & 0xff);
1547
TRACE("unknown register 0x%02x", (int) addr);
1552
CPUReadMemoryFunc * const musb_read[] = {
1558
CPUWriteMemoryFunc * const musb_write[] = {