1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
/* $NetBSD: uhcireg.h,v 1.22 2016/04/23 10:15:32 skrll Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhcireg.h,v 1.12 1999/11/17 22:33:42 n_hibma Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Lennart Augustsson (lennart@augustsson.net) at
* Carlstedt Research & Technology.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DEV_USB_UHCIREG_H_
#define _DEV_USB_UHCIREG_H_
/*** PCI config registers ***/
#define PCI_USBREV 0x60 /* USB protocol revision */
#define PCI_USBREV_MASK 0xff
#define PCI_USBREV_PRE_1_0 0x00
#define PCI_USBREV_1_0 0x10
#define PCI_USBREV_1_1 0x11
#define PCI_LEGSUP 0xc0 /* Legacy Support register */
#define PCI_LEGSUP_A20PTS __BIT(15) /* End of A20GATE passthru status */
#define PCI_LEGSUP_USBPIRQDEN __BIT(13) /* USB PIRQ D Enable */
#define PCI_LEGSUP_USBIRQS __BIT(12) /* USB IRQ status */
#define PCI_LEGSUP_TBY64W __BIT(11) /* Trap by 64h write status */
#define PCI_LEGSUP_TBY64R __BIT(10) /* Trap by 64h read status */
#define PCI_LEGSUP_TBY60W __BIT(9) /* Trap by 60h write status */
#define PCI_LEGSUP_TBY60R __BIT(8) /* Trap by 60h read status */
#define PCI_LEGSUP_SMIEPTE __BIT(7) /* SMI at end of passthru enable */
#define PCI_LEGSUP_PSS __BIT(6) /* Passthru status */
#define PCI_LEGSUP_A20PTEN __BIT(5) /* A20GATE passthru enable */
#define PCI_LEGSUP_USBSMIEN __BIT(4) /* Enable SMI# generation */
#define PCI_CBIO 0x20 /* configuration base IO */
#define PCI_INTERFACE_UHCI 0x00
/*** UHCI registers ***/
#define UHCI_CMD 0x00
#define UHCI_CMD_RS __BIT(0)
#define UHCI_CMD_HCRESET __BIT(1)
#define UHCI_CMD_GRESET __BIT(2)
#define UHCI_CMD_EGSM __BIT(3)
#define UHCI_CMD_FGR __BIT(4)
#define UHCI_CMD_SWDBG __BIT(5)
#define UHCI_CMD_CF __BIT(6)
#define UHCI_CMD_MAXP __BIT(7)
#define UHCI_STS 0x02
#define UHCI_STS_USBINT __BIT(0)
#define UHCI_STS_USBEI __BIT(1)
#define UHCI_STS_RD __BIT(2)
#define UHCI_STS_HSE __BIT(3)
#define UHCI_STS_HCPE __BIT(4)
#define UHCI_STS_HCH __BIT(5)
#define UHCI_STS_ALLINTRS __BITS(5,0)
#define UHCI_INTR 0x04
#define UHCI_INTR_TOCRCIE __BIT(0)
#define UHCI_INTR_RIE __BIT(1)
#define UHCI_INTR_IOCE __BIT(2)
#define UHCI_INTR_SPIE __BIT(3)
#define UHCI_FRNUM 0x06
#define UHCI_FRNUM_MASK __BITS(9,0)
#define UHCI_FLBASEADDR 0x08
#define UHCI_SOF 0x0c
#define UHCI_SOF_MASK __BITS(6,0)
#define UHCI_PORTSC1 0x010
#define UHCI_PORTSC2 0x012
#define UHCI_PORTSC_CCS __BIT(0)
#define UHCI_PORTSC_CSC __BIT(1)
#define UHCI_PORTSC_PE __BIT(2)
#define UHCI_PORTSC_POEDC __BIT(3)
#define UHCI_PORTSC_LS_MASK __BITS(5,4)
#define UHCI_PORTSC_GET_LS(p) __SHIFTOUT((p), UHCI_PORTSC_LS_MASK)
#define UHCI_PORTSC_RD __BIT(6)
#define UHCI_PORTSC_LSDA __BIT(8)
#define UHCI_PORTSC_PR __BIT(9)
#define UHCI_PORTSC_OCI __BIT(10)
#define UHCI_PORTSC_OCIC __BIT(11)
#define UHCI_PORTSC_SUSP __BIT(12)
#define URWMASK(x) \
((x) & (UHCI_PORTSC_SUSP | UHCI_PORTSC_PR | UHCI_PORTSC_RD | UHCI_PORTSC_PE))
#define UHCI_FRAMELIST_COUNT 1024
#define UHCI_FRAMELIST_ALIGN 4096
#define UHCI_TD_ALIGN 16
#define UHCI_QH_ALIGN 16
typedef uint32_t uhci_physaddr_t;
#define UHCI_PTR_T __BIT(0)
#define UHCI_PTR_TD 0x00000000
#define UHCI_PTR_QH __BIT(1)
#define UHCI_PTR_VF __BIT(2)
/*
* Wait this long after a QH has been removed. This gives that HC a
* chance to stop looking at it before it's recycled.
*/
#define UHCI_QH_REMOVE_DELAY 5
/*
* The Queue Heads and Transfer Descriptors are accessed
* by both the CPU and the USB controller which run
* concurrently. This means that they have to be accessed
* with great care. As long as the data structures are
* not linked into the controller's frame list they cannot
* be accessed by it and anything goes. As soon as a
* TD is accessible by the controller it "owns" the td_status
* field; it will not be written by the CPU. Similarly
* the controller "owns" the qh_elink field.
*/
typedef struct {
volatile uhci_physaddr_t td_link;
volatile uint32_t td_status;
#define UHCI_TD_ACTLEN_MASK __BITS(10,0)
#define UHCI_TD_GET_ACTLEN(s) \
((__SHIFTOUT((s), UHCI_TD_ACTLEN_MASK) + 1) & __SHIFTOUT_MASK(UHCI_TD_ACTLEN_MASK))
#define UHCI_TD_ZERO_ACTLEN(t) ((t) | 0x3ff)
#define UHCI_TD_BITSTUFF __BIT(17)
#define UHCI_TD_CRCTO __BIT(18)
#define UHCI_TD_NAK __BIT(19)
#define UHCI_TD_BABBLE __BIT(20)
#define UHCI_TD_DBUFFER __BIT(21)
#define UHCI_TD_STALLED __BIT(22)
#define UHCI_TD_ACTIVE __BIT(23)
#define UHCI_TD_STATUS_MASK __BITS(16,23)
#define UHCI_TD_IOC __BIT(24)
#define UHCI_TD_IOS __BIT(25)
#define UHCI_TD_LS __BIT(26)
#define UHCI_TD_ERRCNT_MASK __BITS(28,27)
#define UHCI_TD_GET_ERRCNT(s) __SHIFTOUT((s), UHCI_TD_ERRCNT_MASK)
#define UHCI_TD_SET_ERRCNT(n) __SHIFTIN((n), UHCI_TD_ERRCNT_MASK)
#define UHCI_TD_SPD __BIT(29)
volatile uint32_t td_token;
#define UHCI_TD_PID_IN 0x69
#define UHCI_TD_PID_OUT 0xe1
#define UHCI_TD_PID_SETUP 0x2d
#define UHCI_TD_PID_MASK __BITS(7,0)
#define UHCI_TD_SET_PID(p) __SHIFTIN((p), UHCI_TD_PID_MASK)
#define UHCI_TD_GET_PID(s) __SHIFTOUT((s), UHCI_TD_PID_MASK)
#define UHCI_TD_DEVADDR_MASK __BITS(14,8)
#define UHCI_TD_SET_DEVADDR(a) __SHIFTIN((a), UHCI_TD_DEVADDR_MASK)
#define UHCI_TD_GET_DEVADDR(s) __SHIFTOUT((s), UHCI_TD_DEVADDR_MASK)
#define UHCI_TD_ENDPT_MASK __BITS(18,15)
#define UHCI_TD_SET_ENDPT(e) __SHIFTIN((e), UHCI_TD_ENDPT_MASK)
#define UHCI_TD_GET_ENDPT(s) __SHIFTOUT((s), UHCI_TD_ENDPT_MASK)
#define UHCI_TD_DT_MASK __BIT(19)
#define UHCI_TD_SET_DT(t) __SHIFTIN((t), UHCI_TD_DT_MASK)
#define UHCI_TD_GET_DT(s) __SHIFTOUT((s), UHCI_TD_DT_MASK)
#define UHCI_TD_MAXLEN_MASK __BITS(31,21)
#define UHCI_TD_SET_MAXLEN(l) \
__SHIFTIN((((l)-1) & __SHIFTOUT_MASK(UHCI_TD_MAXLEN_MASK)), UHCI_TD_MAXLEN_MASK)
#define UHCI_TD_GET_MAXLEN(s) \
(__SHIFTOUT((s), UHCI_TD_MAXLEN_MASK) + 1)
volatile uint32_t td_buffer;
} uhci_td_t;
#define UHCI_TD_ERROR \
(UHCI_TD_BITSTUFF|UHCI_TD_CRCTO|UHCI_TD_BABBLE|UHCI_TD_DBUFFER|UHCI_TD_STALLED)
#define UHCI_TD_SETUP(len, endp, dev) \
(UHCI_TD_SET_MAXLEN(len) | UHCI_TD_SET_ENDPT(endp) | \
UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_SETUP)
#define UHCI_TD_OUT(len, endp, dev, dt) \
(UHCI_TD_SET_MAXLEN(len) | UHCI_TD_SET_ENDPT(endp) | \
UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_OUT | UHCI_TD_SET_DT(dt))
#define UHCI_TD_IN(len, endp, dev, dt) \
(UHCI_TD_SET_MAXLEN(len) | UHCI_TD_SET_ENDPT(endp) | \
UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_IN | UHCI_TD_SET_DT(dt))
typedef struct {
volatile uhci_physaddr_t qh_hlink;
volatile uhci_physaddr_t qh_elink;
} uhci_qh_t;
#endif /* _DEV_USB_UHCIREG_H_ */
|