libpayload: Remove bitfield use from OHCI data structures
[coreboot.git] / payloads / libpayload / drivers / usb / ohci_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 __OHCI_PRIVATE_H
31 #define __OHCI_PRIVATE_H
32
33 #include <pci.h>
34 #include <usb/usb.h>
35
36 #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
37
38         // FIXME: fake
39         typedef enum { CMD} reg;
40
41         enum {
42                 NumberDownstreamPorts = 1<<0,
43                 PowerSwitchingMode = 1<<8,
44                 NoPowerSwitching = 1<<9,
45                 DeviceType = 1<<10,
46                 OverCurrentProtectionMode = 1<<11,
47                 NoOverCurrentProtection = 1<<12,
48                 PowerOnToPowerGoodTime = 1<<24
49         } HcRhDescriptorAReg;
50
51         enum {
52                 NumberDownstreamPortsMask = MASK(0, 8),
53                 PowerOnToPowerGoodTimeMask = MASK(24, 8)
54         } HcRhDescriptorAMask;
55
56         enum {
57                 DeviceRemovable = 1<<0,
58                 PortPowerControlMask = 1<<16
59         } HcRhDescriptorBReg;
60
61         enum {
62                 CurrentConnectStatus            = 1<<0,
63                 PortEnableStatus                = 1<<1,
64                 PortSuspendStatus               = 1<<2,
65                 PortOverCurrentIndicator        = 1<<3,
66                 PortResetStatus                 = 1<<4,
67                 PortPowerStatus                 = 1<<8,
68                 LowSpeedDeviceAttached          = 1<<9,
69                 ConnectStatusChange             = 1<<16,
70                 PortEnableStatusChange          = 1<<17,
71                 PortSuspendStatusChange         = 1<<18,
72                 PortOverCurrentIndicatorChange  = 1<<19,
73                 PortResetStatusChange           = 1<<20
74         } HcRhPortStatusRead;
75         enum {
76                 ClearPortEnable                 = 1<<0,
77                 SetPortEnable                   = 1<<1,
78                 SetPortSuspend                  = 1<<2,
79                 ClearSuspendStatus              = 1<<3,
80                 SetPortReset                    = 1<<4,
81                 SetPortPower                    = 1<<8,
82                 ClearPortPower                  = 1<<9,
83         } HcRhPortStatusSet;
84
85         enum {
86                 LocalPowerStatus = 1<<0,
87                 OverCurrentIndicator = 1<<1,
88                 DeviceRemoteWakeupEnable = 1<<15,
89                 LocalPowerStatusChange = 1<<16,
90                 OverCurrentIndicatorChange = 1<<17,
91                 ClearRemoteWakeupEnable = 1<<31
92         } HcRhStatusReg;
93
94         enum {
95                 FrameInterval = 1<<0,
96                 FSLargestDataPacket = 1<<16,
97                 FrameIntervalToggle = 1<<31
98         } HcFmIntervalOffset;
99         enum {
100                 FrameIntervalMask = MASK(0, 14),
101                 FSLargestDataPacketMask = MASK(16, 15),
102                 FrameIntervalToggleMask = MASK(31, 1)
103         } HcFmIntervalMask;
104
105         enum {
106                 ControlBulkServiceRatio = 1<<0,
107                 PeriodicListEnable = 1<<2,
108                 IsochronousEnable = 1<<3,
109                 ControlListEnable = 1<<4,
110                 BulkListEnable = 1<<5,
111                 HostControllerFunctionalState = 1<<6,
112                 InterruptRouting = 1<<8,
113                 RemoteWakeupConnected = 1<<9,
114                 RemoteWakeupEnable = 1<<10
115         } HcControlReg;
116
117         enum {
118                 ControlBulkServiceRatioMask = MASK(0, 2),
119                 HostControllerFunctionalStateMask = MASK(6, 2)
120         } HcControlMask;
121
122         enum {
123                 USBReset = 0*HostControllerFunctionalState,
124                 USBResume = 1*HostControllerFunctionalState,
125                 USBOperational = 2*HostControllerFunctionalState,
126                 USBSuspend = 3*HostControllerFunctionalState
127         };
128
129         enum {
130                 HostControllerReset = 1<<0,
131                 ControlListFilled = 1<<1,
132                 BulkListFilled = 1<<2,
133                 OwnershipChangeRequest = 1<<3,
134                 SchedulingOverrunCount = 1<<16
135         } HcCommandStatusReg;
136
137         enum {
138                 SchedulingOverrunCountMask = MASK(16, 2)
139         } HcCommandStatusMask;
140
141         enum {
142                 FrameRemaining = 1<<0,
143                 FrameRemainingToggle = 1<<31
144         } HcFmRemainingReg;
145
146         enum {
147                 SchedulingOverrung = 1<<0,
148                 WritebackDoneHead = 1<<1,
149                 StartofFrame = 1<<2,
150                 ResumeDetected = 1<<3,
151                 UnrecoverableError = 1<<4,
152                 FrameNumberOverflow = 1<<5,
153                 RootHubStatusChange = 1<<6,
154                 OwnershipChange = 1<<30
155         } HcInterruptStatusReg;
156
157      typedef struct {
158         // Control and Status Partition
159         volatile u32 HcRevision;
160         volatile u32 HcControl;
161         volatile u32 HcCommandStatus;
162         volatile u32 HcInterruptStatus;
163         volatile u32 HcInterruptEnable;
164         volatile u32 HcInterruptDisable;
165
166         // Memory Pointer Partition
167         volatile u32 HcHCCA;
168         volatile u32 HcPeriodCurrentED;
169         volatile u32 HcControlHeadED;
170         volatile u32 HcControlCurrentED;
171         volatile u32 HcBulkHeadED;
172         volatile u32 HcBulkCurrentED;
173         volatile u32 HcDoneHead;
174
175         // Frame Counter Partition
176         volatile u32 HcFmInterval;
177         volatile u32 HcFmRemaining;
178         volatile u32 HcFmNumber;
179         volatile u32 HcPeriodicStart;
180         volatile u32 HcLSThreshold;
181
182         // Root Hub Partition
183         volatile u32 HcRhDescriptorA;
184         volatile u32 HcRhDescriptorB;
185         volatile u32 HcRhStatus;
186         /* all bits in HcRhPortStatus registers are R/WC, so
187            _DO NOT_ use |= to set the bits,
188            this clears the entire state */
189         volatile u32 HcRhPortStatus[];
190      } __attribute__ ((packed)) opreg_t;
191
192         typedef struct {
193                 u32 HccaInterruptTable[32];
194                 u16 HccaFrameNumber;
195                 u16 HccaPad1;
196                 u32 HccaDoneHead;
197                 u8 reserved[116]; // pad to 256 byte
198         } __attribute__ ((packed)) hcca_t;
199
200         typedef struct ohci {
201                 opreg_t *opreg;
202                 hcca_t *hcca;
203                 usbdev_t *roothub;
204         } ohci_t;
205
206         typedef enum { OHCI_SETUP=0, OHCI_OUT=1, OHCI_IN=2, OHCI_FROM_TD=3 } ohci_pid_t;
207
208         typedef volatile struct {
209                 u32 config;
210                 u32 tail_pointer;
211                 u32 head_pointer;
212                 u32 next_ed;
213         } __attribute__ ((packed)) ed_t;
214 #define ED_HALTED 1
215 #define ED_TOGGLE 2
216
217 #define ED_FUNC_SHIFT 0
218 #define ED_FUNC_MASK MASK(7, 0)
219 #define ED_EP_SHIFT 7
220 #define ED_EP_MASK MASK(4, 7)
221 #define ED_DIR_SHIFT 11
222 #define ED_DIR_MASK MASK(2, 11)
223 #define ED_LOWSPEED (1 << 13)
224 #define ED_MPS_SHIFT 16
225
226         typedef volatile struct {
227                 u32 config;
228                 u32 current_buffer_pointer;
229                 u32 next_td;
230                 u32 buffer_end;
231         } __attribute__ ((packed)) td_t;
232 #define TD_DIRECTION_SHIFT 19
233 #define TD_DIRECTION_MASK MASK(2, TD_DIRECTION_SHIFT)
234 #define TD_DIRECTION_SETUP OHCI_SETUP << TD_DIRECTION_SHIFT
235 #define TD_DIRECTION_IN OHCI_IN << TD_DIRECTION_SHIFT
236 #define TD_DIRECTION_OUT OHCI_OUT << TD_DIRECTION_SHIFT
237 #define TD_DELAY_INTERRUPT_NODELAY (7 << 21)
238 #define TD_TOGGLE_DATA0 0
239 #define TD_TOGGLE_DATA1 (1 << 24)
240 #define TD_TOGGLE_FROM_ED 0
241 #define TD_TOGGLE_FROM_TD (1 << 25)
242 #define TD_CC_SHIFT 28
243 #define TD_CC_MASK MASK(4, TD_CC_SHIFT)
244 #define TD_CC_NOERR 0
245 #define TD_CC_NOACCESS (14 << TD_CC_SHIFT) /* the lower of the two values, so "no access" can be tested with >= */
246
247 #define OHCI_INST(controller) ((ohci_t*)((controller)->instance))
248
249 #endif