2 * This file is part of the libpayload project.
4 * Copyright (C) 2010 Patrick Georgi
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
30 #ifndef __OHCI_PRIVATE_H
31 #define __OHCI_PRIVATE_H
36 #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
39 typedef enum { CMD} reg;
42 NumberDownstreamPorts = 1<<0,
43 PowerSwitchingMode = 1<<8,
44 NoPowerSwitching = 1<<9,
46 OverCurrentProtectionMode = 1<<11,
47 NoOverCurrentProtection = 1<<12,
48 PowerOnToPowerGoodTime = 1<<24
52 NumberDownstreamPortsMask = MASK(0, 8),
53 PowerOnToPowerGoodTimeMask = MASK(24, 8)
54 } HcRhDescriptorAMask;
57 DeviceRemovable = 1<<0,
58 PortPowerControlMask = 1<<16
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
76 ClearPortEnable = 1<<0,
78 SetPortSuspend = 1<<2,
79 ClearSuspendStatus = 1<<3,
82 ClearPortPower = 1<<9,
86 LocalPowerStatus = 1<<0,
87 OverCurrentIndicator = 1<<1,
88 DeviceRemoteWakeupEnable = 1<<15,
89 LocalPowerStatusChange = 1<<16,
90 OverCurrentIndicatorChange = 1<<17,
91 ClearRemoteWakeupEnable = 1<<31
96 FSLargestDataPacket = 1<<16,
97 FrameIntervalToggle = 1<<31
100 FrameIntervalMask = MASK(0, 14),
101 FSLargestDataPacketMask = MASK(16, 15),
102 FrameIntervalToggleMask = MASK(31, 1)
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
118 ControlBulkServiceRatioMask = MASK(0, 2),
119 HostControllerFunctionalStateMask = MASK(6, 2)
123 USBReset = 0*HostControllerFunctionalState,
124 USBResume = 1*HostControllerFunctionalState,
125 USBOperational = 2*HostControllerFunctionalState,
126 USBSuspend = 3*HostControllerFunctionalState
130 HostControllerReset = 1<<0,
131 ControlListFilled = 1<<1,
132 BulkListFilled = 1<<2,
133 OwnershipChangeRequest = 1<<3,
134 SchedulingOverrunCount = 1<<16
135 } HcCommandStatusReg;
138 SchedulingOverrunCountMask = MASK(16, 2)
139 } HcCommandStatusMask;
142 FrameRemaining = 1<<0,
143 FrameRemainingToggle = 1<<31
147 SchedulingOverrung = 1<<0,
148 WritebackDoneHead = 1<<1,
150 ResumeDetected = 1<<3,
151 UnrecoverableError = 1<<4,
152 FrameNumberOverflow = 1<<5,
153 RootHubStatusChange = 1<<6,
154 OwnershipChange = 1<<30
155 } HcInterruptStatusReg;
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;
166 // Memory Pointer Partition
168 volatile u32 HcPeriodCurrentED;
169 volatile u32 HcControlHeadED;
170 volatile u32 HcControlCurrentED;
171 volatile u32 HcBulkHeadED;
172 volatile u32 HcBulkCurrentED;
173 volatile u32 HcDoneHead;
175 // Frame Counter Partition
176 volatile u32 HcFmInterval;
177 volatile u32 HcFmRemaining;
178 volatile u32 HcFmNumber;
179 volatile u32 HcPeriodicStart;
180 volatile u32 HcLSThreshold;
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;
193 u32 HccaInterruptTable[32];
197 u8 reserved[116]; // pad to 256 byte
198 } __attribute__ ((packed)) hcca_t;
200 typedef struct ohci {
206 typedef enum { OHCI_SETUP=0, OHCI_OUT=1, OHCI_IN=2, OHCI_FROM_TD=3 } ohci_pid_t;
208 typedef volatile struct {
212 unsigned long function_address:7;
213 unsigned long endpoint_number:4;
214 unsigned long direction:2;
215 unsigned long lowspeed:1;
216 unsigned long skip:1;
217 unsigned long format:1;
218 unsigned long maximum_packet_size:11;
220 } __attribute__ ((packed));
226 unsigned long halted:1;
227 unsigned long toggle:1;
229 } __attribute__ ((packed));
232 } __attribute__ ((packed)) ed_t;
234 typedef volatile struct {
239 unsigned long buffer_rounding:1;
240 unsigned long direction:2;
241 unsigned long delay_interrupt:3;
242 unsigned long toggle:1;
243 unsigned long toggle_from_td:1;
244 unsigned long error_count:2;
245 unsigned long condition_code:4;
246 } __attribute__ ((packed));
248 u32 current_buffer_pointer;
251 } __attribute__ ((packed)) td_t;
253 #define OHCI_INST(controller) ((ohci_t*)((controller)->instance))