xref: /aosp_15_r20/external/coreboot/payloads/libpayload/drivers/usb/ohci_private.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /*
2  *
3  * Copyright (C) 2010 Patrick Georgi
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #ifndef __OHCI_PRIVATE_H
30 #define __OHCI_PRIVATE_H
31 
32 #include <usb/usb.h>
33 
34 #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
35 
36 	// FIXME: fake
37 	typedef enum { CMD} reg;
38 
39 	enum HcRhDescriptorAReg {
40 		NumberDownstreamPorts = 1 << 0,
41 		PowerSwitchingMode = 1 << 8,
42 		NoPowerSwitching = 1 << 9,
43 		DeviceType = 1 << 10,
44 		OverCurrentProtectionMode = 1 << 11,
45 		NoOverCurrentProtection = 1 << 12,
46 		PowerOnToPowerGoodTime = 1 << 24
47 	};
48 
49 	enum HcRhDescriptorAMask {
50 		NumberDownstreamPortsMask = MASK(0, 8),
51 		PowerOnToPowerGoodTimeMask = MASK(24, 8)
52 	};
53 
54 	enum HcRhDescriptorBReg {
55 		DeviceRemovable = 1 << 0,
56 		PortPowerControlMask = 1 << 16
57 	};
58 
59 	enum HcRhPortStatusRead {
60 		CurrentConnectStatus		= 1 << 0,
61 		PortEnableStatus		= 1 << 1,
62 		PortSuspendStatus		= 1 << 2,
63 		PortOverCurrentIndicator	= 1 << 3,
64 		PortResetStatus			= 1 << 4,
65 		PortPowerStatus			= 1 << 8,
66 		LowSpeedDeviceAttached		= 1 << 9,
67 		ConnectStatusChange		= 1 << 16,
68 		PortEnableStatusChange		= 1 << 17,
69 		PortSuspendStatusChange		= 1 << 18,
70 		PortOverCurrentIndicatorChange	= 1 << 19,
71 		PortResetStatusChange		= 1 << 20
72 	};
73 
74 	enum HcRhPortStatusSet {
75 		ClearPortEnable			= 1 << 0,
76 		SetPortEnable			= 1 << 1,
77 		SetPortSuspend			= 1 << 2,
78 		ClearSuspendStatus		= 1 << 3,
79 		SetPortReset			= 1 << 4,
80 		SetPortPower			= 1 << 8,
81 		ClearPortPower			= 1 << 9,
82 	};
83 
84 	enum HcRhStatusReg {
85 		LocalPowerStatus = 1 << 0,
86 		OverCurrentIndicator = 1 << 1,
87 		DeviceRemoteWakeupEnable = 1 << 15,
88 		LocalPowerStatusChange = 1 << 16,
89 		OverCurrentIndicatorChange = 1 << 17,
90 		ClearRemoteWakeupEnable = 1 << 31
91 	};
92 
93 	enum HcFmIntervalOffset {
94 		FrameInterval = 1 << 0,
95 		FSLargestDataPacket = 1 << 16,
96 		FrameIntervalToggle = 1 << 31
97 	};
98 
99 	enum HcFmIntervalMask {
100 		FrameIntervalMask = MASK(0, 14),
101 		FSLargestDataPacketMask = MASK(16, 15),
102 		FrameIntervalToggleMask = MASK(31, 1)
103 	};
104 
105 	enum HcControlReg {
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 	};
116 
117 	enum HcControlMask {
118 		ControlBulkServiceRatioMask = MASK(0, 2),
119 		HostControllerFunctionalStateMask = MASK(6, 2)
120 	};
121 
122 	enum {
123 		USBReset = 0*HostControllerFunctionalState,
124 		USBResume = 1*HostControllerFunctionalState,
125 		USBOperational = 2*HostControllerFunctionalState,
126 		USBSuspend = 3*HostControllerFunctionalState
127 	};
128 
129 	enum HcCommandStatusReg {
130 		HostControllerReset = 1 << 0,
131 		ControlListFilled = 1 << 1,
132 		BulkListFilled = 1 << 2,
133 		OwnershipChangeRequest = 1 << 3,
134 		SchedulingOverrunCount = 1 << 16
135 	};
136 
137 	enum HcCommandStatusMask {
138 		SchedulingOverrunCountMask = MASK(16, 2)
139 	};
140 
141 	enum HcFmRemainingReg {
142 		FrameRemaining = 1 << 0,
143 		FrameRemainingToggle = 1 << 31
144 	};
145 
146 	enum HcInterruptStatusReg {
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 	};
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      } __packed opreg_t;
191 
192 	typedef struct { /* should be 256 bytes according to spec */
193 		u32 HccaInterruptTable[32];
194 		volatile u16 HccaFrameNumber;
195 		volatile u16 HccaPad1;
196 		volatile u32 HccaDoneHead;
197 		u8 reserved[116]; /* pad according to spec */
198 		u8 what[4]; /* really pad to 256 as spec only covers 252 */
199 	} __packed hcca_t;
200 
201 	typedef volatile struct {
202 		u32 config;
203 		u32 tail_pointer;
204 		u32 head_pointer;
205 		u32 next_ed;
206 	} __packed ed_t;
207 #define ED_HALTED 1
208 #define ED_TOGGLE 2
209 
210 #define ED_FUNC_SHIFT 0
211 #define ED_FUNC_MASK MASK(0, 7)
212 #define ED_EP_SHIFT 7
213 #define ED_EP_MASK MASK(7, 4)
214 #define ED_DIR_SHIFT 11
215 #define ED_DIR_MASK MASK(11, 2)
216 #define ED_LOWSPEED (1 << 13)
217 #define ED_MPS_SHIFT 16
218 
219 	typedef volatile struct {
220 		u32 config;
221 		u32 current_buffer_pointer;
222 		u32 next_td;
223 		u32 buffer_end;
224 	} __packed td_t;
225 /*
226  * Bits 0 through 17 of .config won't be interpreted by the host controller
227  * (HC) and, after processing the TD, the HC has to ensure those bits have
228  * the same state as before. So we are free to use those bits for our own
229  * purpose.
230  */
231 #define TD_QUEUETYPE_SHIFT	0
232 #define TD_QUEUETYPE_MASK	MASK(TD_QUEUETYPE_SHIFT, 2)
233 #define TD_QUEUETYPE_ASYNC	(0 << TD_QUEUETYPE_SHIFT)
234 #define TD_QUEUETYPE_INTR	(1 << TD_QUEUETYPE_SHIFT)
235 
236 #define TD_DIRECTION_SHIFT 19
237 #define TD_DIRECTION_MASK MASK(TD_DIRECTION_SHIFT, 2)
238 #define TD_DIRECTION_SETUP (OHCI_SETUP << TD_DIRECTION_SHIFT)
239 #define TD_DIRECTION_IN (OHCI_IN << TD_DIRECTION_SHIFT)
240 #define TD_DIRECTION_OUT (OHCI_OUT << TD_DIRECTION_SHIFT)
241 #define TD_DELAY_INTERRUPT_SHIFT	21
242 #define TD_DELAY_INTERRUPT_MASK		MASK(TD_DELAY_INTERRUPT_SHIFT, 3)
243 #define TD_DELAY_INTERRUPT_ZERO		0
244 #define TD_DELAY_INTERRUPT_NOINTR	(7 << TD_DELAY_INTERRUPT_SHIFT)
245 #define TD_TOGGLE_DATA0 0
246 #define TD_TOGGLE_DATA1 (1 << 24)
247 #define TD_TOGGLE_FROM_ED 0
248 #define TD_TOGGLE_FROM_TD (1 << 25)
249 #define TD_CC_SHIFT 28
250 #define TD_CC_MASK MASK(TD_CC_SHIFT, 4)
251 #define TD_CC_NOERR 0
252 #define TD_CC_NOACCESS (14 << TD_CC_SHIFT) /* the lower of the two values, so "no access" can be tested with >= */
253 
254 #define OHCI_INST(controller) ((ohci_t*)((controller)->instance))
255 
256 	typedef struct ohci {
257 		opreg_t *opreg;
258 		hcca_t *hcca;
259 		usbdev_t *roothub;
260 		ed_t *periodic_ed;
261 #define DMA_SIZE (64 * 1024)
262 		void *dma_buffer;
263 	} ohci_t;
264 
265 	typedef enum { OHCI_SETUP = 0, OHCI_OUT = 1, OHCI_IN = 2, OHCI_FROM_TD = 3 } ohci_pid_t;
266 
267 #endif
268