Print a warning when an unknow USB controller type is detected.
[coreboot.git] / payloads / libpayload / drivers / usb / xhci_private.h
1 /*
2  * This file is part of the libpayload project.
3  *
4  * Copyright (C) 2010 Patrick Georgi
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #ifndef __XHCI_PRIVATE_H
31 #define __XHCI_PRIVATE_H
32
33 #include <usb/usb.h>
34
35 #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
36
37 typedef volatile union trb {
38         // transfer
39
40         // events
41 #define TRB_EV_CMD_CMPL 33
42         struct {
43                 u32 Cmd_TRB_Pointer_lo;
44                 u32 Cmd_TRB_Pointer_hi;
45                 struct {
46                         unsigned long:24;
47                         unsigned long Completion_Code:8;
48                 } __attribute__ ((packed));
49                 struct {
50                         unsigned long C:1;
51                         unsigned long:9;
52                         unsigned long TRB_Type:6;
53                         unsigned long VF_ID:8;
54                         unsigned long Slot_ID:8;
55                 } __attribute__ ((packed));
56         } __attribute__ ((packed)) event_cmd_cmpl;
57
58 #define TRB_EV_PORTSC 34
59         struct {
60                 struct {
61                         unsigned long:24;
62                         unsigned long Port:8;
63                 } __attribute__ ((packed));
64                 u32 rsvd;
65                 struct {
66                         unsigned long:24;
67                         unsigned long Completion_Code:8;
68                 } __attribute__ ((packed));
69                 struct {
70                         unsigned long C:1;
71                         unsigned long:9;
72                         unsigned long TRB_Type:6;
73                         unsigned long:16;
74                 } __attribute__ ((packed));
75         } __attribute__ ((packed)) event_portsc;
76
77         // commands
78 #define TRB_CMD_NOOP 23
79         struct {
80                 u32 rsvd[3];
81                 struct {
82                         unsigned long C:1;
83                         unsigned long:9;
84                         unsigned long TRB_Type:6;
85                         unsigned long:16;
86                 } __attribute__ ((packed));
87         } __attribute__ ((packed)) cmd_No_Op;
88
89         // "others"
90         struct {
91                 u32 Ring_Segment_Ptr_lo;
92                 u32 Ring_Segment_Ptr_hi;
93                 struct {
94                         unsigned long:22;
95                         unsigned long Interrupter_Target;
96                 } __attribute__ ((packed));
97                 struct {
98                         unsigned long C:1;
99                         unsigned long TC:1;
100                         unsigned long:2;
101                         unsigned long CH:1;
102                         unsigned long IOC:1;
103                         unsigned long:4;
104                         unsigned long TRB_Type:6;
105                         unsigned long:16;
106                 } __attribute__ ((packed));
107         } __attribute__ ((packed)) link;
108 } trb_t;
109
110 typedef struct slotctx {
111         struct {
112                 unsigned long Route_String:20;
113                 unsigned long Speed:4;
114                 unsigned long:1;
115                 unsigned long MTT:1;
116                 unsigned long Hub:1;
117                 unsigned long Context_Entries:5;
118         } __attribute__ ((packed));
119         struct {
120                 unsigned long Max_Exit_Latency:16;
121                 unsigned long Root_Hub_Port_Number:8;
122                 unsigned long Number_of_Ports:8;
123         } __attribute__ ((packed));
124         struct {
125                 unsigned long TT_Hub_Slot_ID:8;
126                 unsigned long TT_Port_Number:8;
127                 unsigned long TTT:2;
128                 unsigned long:4;
129                 unsigned long Interrupter_Target:10;
130         } __attribute__ ((packed));
131         struct {
132                 unsigned long USB_Device_Address:8;
133                 unsigned long:19;
134                 unsigned long Slot_State:5;
135         } __attribute__ ((packed));
136         u32 rsvd[4];
137 } slotctx_t;
138
139 typedef struct epctx {
140         struct {
141                 unsigned long EP_State:3;
142                 unsigned long:5;
143                 unsigned long Mult:2;
144                 unsigned long MaxPStreams:5;
145                 unsigned long LSA:1;
146                 unsigned long Interval:8;
147                 unsigned long:8;
148         } __attribute__ ((packed));
149         struct {
150                 unsigned long:1;
151                 unsigned long CErr:2;
152                 unsigned long EP_Type:3;
153                 unsigned long:1;
154                 unsigned long HID:1;
155                 unsigned long Max_Burst_Size:8;
156                 unsigned long Max_Packet_Size:16;
157         } __attribute__ ((packed));
158         union {
159                 u32 TR_Dequeue_Pointer_lo;
160                 struct {
161                         unsigned long DCS:1;
162                         unsigned long:3;
163                 } __attribute__ ((packed));
164         } __attribute__ ((packed));
165         u32 TR_Dequeue_Pointer_hi;
166         struct {
167                 unsigned long Average_TRB_Length:16;
168                 unsigned long Max_ESIT_Payload:16;
169         } __attribute__ ((packed));
170         u32 rsvd[3];
171 } epctx_t;
172
173 typedef struct devctx {
174         slotctx_t slot;
175         epctx_t ep0;
176         struct {
177                 epctx_t out;
178                 epctx_t in;
179         } eps[15];
180 } devctx_t;
181
182 typedef struct devctxp {
183         devctx_t *ptr;
184         void *upper;
185 } devctxp_t;
186
187 typedef struct erst_entry {
188         u32 seg_base_lo;
189         u32 seg_base_hi;
190         u32 seg_size;
191         u32 rsvd;
192 } erst_entry_t;
193
194 typedef struct xhci {
195         /* capreg is read-only, so no need for volatile,
196            and thus 32bit accesses can be assumed. */
197         struct capreg {
198                 u8 caplength;
199                 u8 res1;
200                 union {
201                         u16 hciversion;
202                         struct {
203                                 u8 hciver_lo;
204                                 u8 hciver_hi;
205                         } __attribute__ ((packed));
206                 } __attribute__ ((packed));
207                 union {
208                         u32 hcsparams1;
209                         struct {
210                                 unsigned long MaxSlots:7;
211                                 unsigned long MaxIntrs:11;
212                                 unsigned long:6;
213                                 unsigned long MaxPorts:8;
214                         } __attribute__ ((packed));
215                 } __attribute__ ((packed));
216                 union {
217                         u32 hcsparams2;
218                         struct {
219                                 unsigned long IST:4;
220                                 unsigned long ERST_Max:4;
221                                 unsigned long:18;
222                                 unsigned long SPR:1;
223                                 unsigned long Max_Scratchpad_Bufs:5;
224                         } __attribute__ ((packed));
225                 } __attribute__ ((packed));
226                 union {
227                         u32 hcsparams3;
228                         struct {
229                                 unsigned long u1latency:8;
230                                 unsigned long:8;
231                                 unsigned long u2latency:16;
232                         } __attribute__ ((packed));
233                 } __attribute__ ((packed));
234                 union {
235                         u32 hccparams;
236                         struct {
237                                 unsigned long ac64:1;
238                                 unsigned long bnc:1;
239                                 unsigned long csz:1;
240                                 unsigned long ppc:1;
241                                 unsigned long pind:1;
242                                 unsigned long lhrc:1;
243                                 unsigned long ltc:1;
244                                 unsigned long nss:1;
245                                 unsigned long:4;
246                                 unsigned long MaxPSASize:4;
247                                 unsigned long xECP:16;
248                         } __attribute__ ((packed));
249                 } __attribute__ ((packed));
250                 u32 dboff;
251                 u32 rtsoff;
252         } __attribute__ ((packed)) *capreg;
253
254         /* opreg is R/W is most places, so volatile access is necessary.
255            volatile means that the compiler seeks byte writes if possible,
256            making bitfields unusable for MMIO register blocks. Yay C :-( */
257         volatile struct opreg {
258                 u32 usbcmd;
259 #define USBCMD_RS 1<<0
260 #define USBCMD_HCRST 1<<1
261                 u32 usbsts;
262 #define USBSTS_HCH 1<<0
263 #define USBSTS_HSE 1<<2
264 #define USBSTS_EINT 1<<3
265 #define USBSTS_PCD 1<<4
266 #define USBSTS_CNR 1<<11
267                 u32 pagesize;
268                 u8 res1[0x13-0x0c+1];
269                 u32 dnctrl;
270                 u32 crcr_lo;
271                 u32 crcr_hi;
272 #define CRCR_RCS 1<<0
273 #define CRCR_CS 1<<1
274 #define CRCR_CA 1<<2
275 #define CRCR_CRR 1<<3
276                 u8 res2[0x2f-0x20+1];
277                 u32 dcbaap_lo;
278                 u32 dcbaap_hi;
279                 u32 config;
280 #define CONFIG_MASK_MaxSlotsEn 0xff
281                 u8 res3[0x3ff-0x3c+1];
282                 struct {
283                         u32 portsc;
284 #define PORTSC_CCS 1<<0
285 #define PORTSC_PED 1<<1
286         // BIT 2 rsvdZ
287 #define PORTSC_OCA 1<<3
288 #define PORTSC_PR 1<<4
289 #define PORTSC_PLS 1<<5
290 #define PORTSC_PLS_MASK MASK(5, 4)
291 #define PORTSC_PP 1<<9
292 #define PORTSC_PORT_SPEED 1<<10
293 #define PORTSC_PORT_SPEED_MASK MASK(10, 4)
294 #define PORTSC_PIC 1<<14
295 #define PORTSC_PIC_MASK MASK(14, 2)
296 #define PORTSC_LWS 1<<16
297 #define PORTSC_CSC 1<<17
298 #define PORTSC_PEC 1<<18
299 #define PORTSC_WRC 1<<19
300 #define PORTSC_OCC 1<<20
301 #define PORTSC_PRC 1<<21
302 #define PORTSC_PLC 1<<22
303 #define PORTSC_CEC 1<<23
304 #define PORTSC_CAS 1<<24
305 #define PORTSC_WCE 1<<25
306 #define PORTSC_WDE 1<<26
307 #define PORTSC_WOE 1<<27
308         // BIT 29:28 rsvdZ
309 #define PORTSC_DR 1<<30
310 #define PORTSC_WPR 1<<31
311 #define PORTSC_RW_MASK PORTSC_PR | PORTSC_PLS_MASK | PORTSC_PP | PORTSC_PIC_MASK | PORTSC_LWS | PORTSC_WCE | PORTSC_WDE | PORTSC_WOE
312                         u32 portpmsc;
313                         u32 portli;
314                         u32 res;
315                 } __attribute__ ((packed)) prs[];
316         } __attribute__ ((packed)) *opreg;
317
318         /* R/W, volatile, MMIO -> no bitfields */
319         volatile struct hcrreg {
320                 u32 mfindex;
321                 u8 res1[0x20-0x4];
322                 struct {
323                         u32 iman;
324                         u32 imod;
325                         u32 erstsz;
326                         u32 res;
327                         u32 erstba_lo;
328                         u32 erstba_hi;
329                         u32 erdp_lo;
330                         u32 erdp_hi;
331                 } __attribute__ ((packed)) intrrs[]; // up to 1024, but maximum host specific, given in capreg->MaxIntrs
332         } __attribute__ ((packed)) *hcrreg;
333
334         /* R/W, volatile, MMIO -> no bitfields */
335         volatile u32 *dbreg;
336
337         /* R/W, volatile, Memory -> bitfields allowed */
338         volatile devctxp_t *dcbaa;
339
340         trb_t *cmd_ring;
341         trb_t *ev_ring;
342         volatile erst_entry_t *ev_ring_table;
343         int cmd_ccs, ev_ccs;
344
345         usbdev_t *roothub;
346 } xhci_t;
347
348 #define XHCI_INST(controller) ((xhci_t*)((controller)->instance))
349
350 #endif