]>
Commit | Line | Data |
---|---|---|
913cb9dc | 1 | /** @file\r |
2 | \r | |
78c2ffb5 | 3 | The EHCI register operation routines.\r |
4 | \r | |
597f4ee2 | 5 | Copyright (c) 2007 - 2009, Intel Corporation\r |
913cb9dc | 6 | All rights reserved. This program and the accompanying materials\r |
7 | are licensed and made available under the terms and conditions of the BSD License\r | |
8 | which accompanies this distribution. The full text of the license may be found at\r | |
9 | http://opensource.org/licenses/bsd-license.php\r | |
10 | \r | |
11 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | \r | |
913cb9dc | 14 | **/\r |
15 | \r | |
16 | \r | |
17 | #include "Ehci.h"\r | |
18 | \r | |
19 | \r | |
20 | /**\r | |
78c2ffb5 | 21 | Read EHCI capability register.\r |
913cb9dc | 22 | \r |
78c2ffb5 | 23 | @param Ehc The EHCI device.\r |
24 | @param Offset Capability register address.\r | |
913cb9dc | 25 | \r |
78c2ffb5 | 26 | @return The register content read.\r |
27 | @retval If err, return 0xffff.\r | |
913cb9dc | 28 | \r |
29 | **/\r | |
30 | UINT32\r | |
31 | EhcReadCapRegister (\r | |
32 | IN USB2_HC_DEV *Ehc,\r | |
33 | IN UINT32 Offset\r | |
34 | )\r | |
35 | {\r | |
36 | UINT32 Data;\r | |
37 | EFI_STATUS Status;\r | |
38 | \r | |
39 | Status = Ehc->PciIo->Mem.Read (\r | |
40 | Ehc->PciIo,\r | |
41 | EfiPciIoWidthUint32,\r | |
42 | EHC_BAR_INDEX,\r | |
43 | (UINT64) Offset,\r | |
44 | 1,\r | |
45 | &Data\r | |
46 | );\r | |
47 | \r | |
48 | if (EFI_ERROR (Status)) {\r | |
1c619535 | 49 | DEBUG ((EFI_D_ERROR, "EhcReadCapRegister: Pci Io read error - %r at %d\n", Status, Offset));\r |
913cb9dc | 50 | Data = 0xFFFF;\r |
51 | }\r | |
52 | \r | |
53 | return Data;\r | |
54 | }\r | |
55 | \r | |
56 | \r | |
57 | /**\r | |
78c2ffb5 | 58 | Read EHCI Operation register.\r |
913cb9dc | 59 | \r |
78c2ffb5 | 60 | @param Ehc The EHCI device.\r |
61 | @param Offset The operation register offset.\r | |
913cb9dc | 62 | \r |
78c2ffb5 | 63 | @return The register content read.\r |
64 | @retval If err, return 0xffff.\r | |
913cb9dc | 65 | \r |
66 | **/\r | |
67 | UINT32\r | |
68 | EhcReadOpReg (\r | |
69 | IN USB2_HC_DEV *Ehc,\r | |
70 | IN UINT32 Offset\r | |
71 | )\r | |
72 | {\r | |
73 | UINT32 Data;\r | |
74 | EFI_STATUS Status;\r | |
75 | \r | |
76 | ASSERT (Ehc->CapLen != 0);\r | |
77 | \r | |
78 | Status = Ehc->PciIo->Mem.Read (\r | |
79 | Ehc->PciIo,\r | |
80 | EfiPciIoWidthUint32,\r | |
81 | EHC_BAR_INDEX,\r | |
82 | (UINT64) (Ehc->CapLen + Offset),\r | |
83 | 1,\r | |
84 | &Data\r | |
85 | );\r | |
86 | \r | |
87 | if (EFI_ERROR (Status)) {\r | |
1c619535 | 88 | DEBUG ((EFI_D_ERROR, "EhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r |
913cb9dc | 89 | Data = 0xFFFF;\r |
90 | }\r | |
91 | \r | |
92 | return Data;\r | |
93 | }\r | |
94 | \r | |
95 | \r | |
96 | /**\r | |
78c2ffb5 | 97 | Write the data to the EHCI operation register.\r |
913cb9dc | 98 | \r |
78c2ffb5 | 99 | @param Ehc The EHCI device.\r |
100 | @param Offset EHCI operation register offset.\r | |
101 | @param Data The data to write.\r | |
913cb9dc | 102 | \r |
913cb9dc | 103 | **/\r |
104 | VOID\r | |
105 | EhcWriteOpReg (\r | |
106 | IN USB2_HC_DEV *Ehc,\r | |
107 | IN UINT32 Offset,\r | |
108 | IN UINT32 Data\r | |
109 | )\r | |
110 | {\r | |
111 | EFI_STATUS Status;\r | |
112 | \r | |
113 | ASSERT (Ehc->CapLen != 0);\r | |
114 | \r | |
115 | Status = Ehc->PciIo->Mem.Write (\r | |
116 | Ehc->PciIo,\r | |
117 | EfiPciIoWidthUint32,\r | |
118 | EHC_BAR_INDEX,\r | |
119 | (UINT64) (Ehc->CapLen + Offset),\r | |
120 | 1,\r | |
121 | &Data\r | |
122 | );\r | |
123 | \r | |
124 | if (EFI_ERROR (Status)) {\r | |
1c619535 | 125 | DEBUG ((EFI_D_ERROR, "EhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r |
913cb9dc | 126 | }\r |
127 | }\r | |
128 | \r | |
129 | \r | |
130 | /**\r | |
78c2ffb5 | 131 | Set one bit of the operational register while keeping other bits.\r |
913cb9dc | 132 | \r |
78c2ffb5 | 133 | @param Ehc The EHCI device.\r |
134 | @param Offset The offset of the operational register.\r | |
135 | @param Bit The bit mask of the register to set.\r | |
913cb9dc | 136 | \r |
913cb9dc | 137 | **/\r |
913cb9dc | 138 | VOID\r |
139 | EhcSetOpRegBit (\r | |
140 | IN USB2_HC_DEV *Ehc,\r | |
141 | IN UINT32 Offset,\r | |
142 | IN UINT32 Bit\r | |
143 | )\r | |
144 | {\r | |
145 | UINT32 Data;\r | |
146 | \r | |
147 | Data = EhcReadOpReg (Ehc, Offset);\r | |
148 | Data |= Bit;\r | |
149 | EhcWriteOpReg (Ehc, Offset, Data);\r | |
150 | }\r | |
151 | \r | |
152 | \r | |
153 | /**\r | |
78c2ffb5 | 154 | Clear one bit of the operational register while keeping other bits.\r |
913cb9dc | 155 | \r |
78c2ffb5 | 156 | @param Ehc The EHCI device.\r |
157 | @param Offset The offset of the operational register.\r | |
158 | @param Bit The bit mask of the register to clear.\r | |
913cb9dc | 159 | \r |
913cb9dc | 160 | **/\r |
913cb9dc | 161 | VOID\r |
162 | EhcClearOpRegBit (\r | |
163 | IN USB2_HC_DEV *Ehc,\r | |
164 | IN UINT32 Offset,\r | |
165 | IN UINT32 Bit\r | |
166 | )\r | |
167 | {\r | |
168 | UINT32 Data;\r | |
169 | \r | |
170 | Data = EhcReadOpReg (Ehc, Offset);\r | |
171 | Data &= ~Bit;\r | |
172 | EhcWriteOpReg (Ehc, Offset, Data);\r | |
173 | }\r | |
174 | \r | |
175 | \r | |
176 | /**\r | |
177 | Wait the operation register's bit as specified by Bit\r | |
78c2ffb5 | 178 | to become set (or clear).\r |
913cb9dc | 179 | \r |
78c2ffb5 | 180 | @param Ehc The EHCI device.\r |
181 | @param Offset The offset of the operation register.\r | |
182 | @param Bit The bit of the register to wait for.\r | |
183 | @param WaitToSet Wait the bit to set or clear.\r | |
184 | @param Timeout The time to wait before abort (in millisecond).\r | |
913cb9dc | 185 | \r |
78c2ffb5 | 186 | @retval EFI_SUCCESS The bit successfully changed by host controller.\r |
187 | @retval EFI_TIMEOUT The time out occurred.\r | |
913cb9dc | 188 | \r |
189 | **/\r | |
913cb9dc | 190 | EFI_STATUS\r |
191 | EhcWaitOpRegBit (\r | |
192 | IN USB2_HC_DEV *Ehc,\r | |
193 | IN UINT32 Offset,\r | |
194 | IN UINT32 Bit,\r | |
195 | IN BOOLEAN WaitToSet,\r | |
196 | IN UINT32 Timeout\r | |
197 | )\r | |
198 | {\r | |
199 | UINT32 Index;\r | |
200 | \r | |
41e8ff27 | 201 | for (Index = 0; Index < Timeout / EHC_SYNC_POLL_INTERVAL + 1; Index++) {\r |
913cb9dc | 202 | if (EHC_REG_BIT_IS_SET (Ehc, Offset, Bit) == WaitToSet) {\r |
203 | return EFI_SUCCESS;\r | |
204 | }\r | |
205 | \r | |
41e8ff27 | 206 | gBS->Stall (EHC_SYNC_POLL_INTERVAL);\r |
913cb9dc | 207 | }\r |
208 | \r | |
209 | return EFI_TIMEOUT;\r | |
210 | }\r | |
211 | \r | |
212 | \r | |
213 | /**\r | |
214 | Add support for UEFI Over Legacy (UoL) feature, stop\r | |
78c2ffb5 | 215 | the legacy USB SMI support.\r |
913cb9dc | 216 | \r |
217 | @param Ehc The EHCI device.\r | |
218 | \r | |
913cb9dc | 219 | **/\r |
220 | VOID\r | |
221 | EhcClearLegacySupport (\r | |
222 | IN USB2_HC_DEV *Ehc\r | |
223 | )\r | |
224 | {\r | |
225 | UINT32 ExtendCap;\r | |
226 | EFI_PCI_IO_PROTOCOL *PciIo;\r | |
227 | UINT32 Value;\r | |
228 | UINT32 TimeOut;\r | |
229 | \r | |
1c619535 | 230 | DEBUG ((EFI_D_INFO, "EhcClearLegacySupport: called to clear legacy support\n"));\r |
913cb9dc | 231 | \r |
232 | PciIo = Ehc->PciIo;\r | |
233 | ExtendCap = (Ehc->HcCapParams >> 8) & 0xFF;\r | |
234 | \r | |
235 | PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r | |
236 | PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value);\r | |
237 | \r | |
238 | PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r | |
239 | Value |= (0x1 << 24);\r | |
240 | PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r | |
241 | \r | |
242 | TimeOut = 40;\r | |
78c2ffb5 | 243 | while (TimeOut-- != 0) {\r |
913cb9dc | 244 | gBS->Stall (500);\r |
245 | \r | |
246 | PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r | |
247 | \r | |
248 | if ((Value & 0x01010000) == 0x01000000) {\r | |
249 | break;\r | |
250 | }\r | |
251 | }\r | |
252 | \r | |
253 | PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r | |
254 | PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value);\r | |
255 | }\r | |
256 | \r | |
257 | \r | |
258 | \r | |
259 | /**\r | |
260 | Set door bell and wait it to be ACKed by host controller.\r | |
261 | This function is used to synchronize with the hardware.\r | |
262 | \r | |
78c2ffb5 | 263 | @param Ehc The EHCI device.\r |
264 | @param Timeout The time to wait before abort (in millisecond, ms).\r | |
913cb9dc | 265 | \r |
78c2ffb5 | 266 | @retval EFI_SUCCESS Synchronized with the hardware.\r |
267 | @retval EFI_TIMEOUT Time out happened while waiting door bell to set.\r | |
913cb9dc | 268 | \r |
269 | **/\r | |
270 | EFI_STATUS\r | |
271 | EhcSetAndWaitDoorBell (\r | |
272 | IN USB2_HC_DEV *Ehc,\r | |
273 | IN UINT32 Timeout\r | |
274 | )\r | |
275 | {\r | |
276 | EFI_STATUS Status;\r | |
277 | UINT32 Data;\r | |
278 | \r | |
279 | EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_IAAD);\r | |
280 | \r | |
281 | Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_IAA, TRUE, Timeout);\r | |
282 | \r | |
283 | //\r | |
284 | // ACK the IAA bit in USBSTS register. Make sure other\r | |
285 | // interrupt bits are not ACKed. These bits are WC (Write Clean).\r | |
286 | //\r | |
287 | Data = EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET);\r | |
288 | Data &= ~USBSTS_INTACK_MASK;\r | |
289 | Data |= USBSTS_IAA;\r | |
290 | \r | |
291 | EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, Data);\r | |
292 | \r | |
293 | return Status;\r | |
294 | }\r | |
295 | \r | |
296 | \r | |
297 | /**\r | |
298 | Clear all the interrutp status bits, these bits\r | |
78c2ffb5 | 299 | are Write-Clean.\r |
913cb9dc | 300 | \r |
78c2ffb5 | 301 | @param Ehc The EHCI device.\r |
913cb9dc | 302 | \r |
913cb9dc | 303 | **/\r |
304 | VOID\r | |
305 | EhcAckAllInterrupt (\r | |
306 | IN USB2_HC_DEV *Ehc\r | |
307 | )\r | |
308 | {\r | |
309 | EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, USBSTS_INTACK_MASK);\r | |
310 | }\r | |
311 | \r | |
312 | \r | |
313 | /**\r | |
314 | Enable the periodic schedule then wait EHC to\r | |
315 | actually enable it.\r | |
316 | \r | |
78c2ffb5 | 317 | @param Ehc The EHCI device.\r |
318 | @param Timeout The time to wait before abort (in millisecond, ms).\r | |
913cb9dc | 319 | \r |
78c2ffb5 | 320 | @retval EFI_SUCCESS The periodical schedule is enabled.\r |
321 | @retval EFI_TIMEOUT Time out happened while enabling periodic schedule.\r | |
913cb9dc | 322 | \r |
323 | **/\r | |
913cb9dc | 324 | EFI_STATUS\r |
325 | EhcEnablePeriodSchd (\r | |
326 | IN USB2_HC_DEV *Ehc,\r | |
327 | IN UINT32 Timeout\r | |
328 | )\r | |
329 | {\r | |
330 | EFI_STATUS Status;\r | |
331 | \r | |
332 | EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD);\r | |
333 | \r | |
334 | Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, TRUE, Timeout);\r | |
335 | return Status;\r | |
336 | }\r | |
337 | \r | |
338 | \r | |
913cb9dc | 339 | /**\r |
78c2ffb5 | 340 | Disable periodic schedule.\r |
913cb9dc | 341 | \r |
78c2ffb5 | 342 | @param Ehc The EHCI device.\r |
343 | @param Timeout Time to wait before abort (in millisecond, ms).\r | |
913cb9dc | 344 | \r |
78c2ffb5 | 345 | @retval EFI_SUCCESS Periodic schedule is disabled.\r |
346 | @retval EFI_DEVICE_ERROR Fail to disable periodic schedule.\r | |
913cb9dc | 347 | \r |
348 | **/\r | |
913cb9dc | 349 | EFI_STATUS\r |
350 | EhcDisablePeriodSchd (\r | |
351 | IN USB2_HC_DEV *Ehc,\r | |
352 | IN UINT32 Timeout\r | |
353 | )\r | |
354 | {\r | |
355 | EFI_STATUS Status;\r | |
356 | \r | |
357 | EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD);\r | |
358 | \r | |
359 | Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, FALSE, Timeout);\r | |
360 | return Status;\r | |
361 | }\r | |
362 | \r | |
363 | \r | |
364 | \r | |
365 | /**\r | |
78c2ffb5 | 366 | Enable asynchrounous schedule.\r |
913cb9dc | 367 | \r |
78c2ffb5 | 368 | @param Ehc The EHCI device.\r |
369 | @param Timeout Time to wait before abort.\r | |
913cb9dc | 370 | \r |
78c2ffb5 | 371 | @retval EFI_SUCCESS The EHCI asynchronous schedule is enabled.\r |
372 | @return Others Failed to enable the asynchronous scheudle.\r | |
913cb9dc | 373 | \r |
374 | **/\r | |
913cb9dc | 375 | EFI_STATUS\r |
376 | EhcEnableAsyncSchd (\r | |
377 | IN USB2_HC_DEV *Ehc,\r | |
378 | IN UINT32 Timeout\r | |
379 | )\r | |
380 | {\r | |
381 | EFI_STATUS Status;\r | |
382 | \r | |
383 | EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC);\r | |
384 | \r | |
385 | Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, TRUE, Timeout);\r | |
386 | return Status;\r | |
387 | }\r | |
388 | \r | |
389 | \r | |
390 | \r | |
391 | /**\r | |
78c2ffb5 | 392 | Disable asynchrounous schedule.\r |
913cb9dc | 393 | \r |
78c2ffb5 | 394 | @param Ehc The EHCI device.\r |
395 | @param Timeout Time to wait before abort (in millisecond, ms).\r | |
913cb9dc | 396 | \r |
78c2ffb5 | 397 | @retval EFI_SUCCESS The asynchronous schedule is disabled.\r |
398 | @return Others Failed to disable the asynchronous schedule.\r | |
913cb9dc | 399 | \r |
400 | **/\r | |
913cb9dc | 401 | EFI_STATUS\r |
402 | EhcDisableAsyncSchd (\r | |
403 | IN USB2_HC_DEV *Ehc,\r | |
404 | IN UINT32 Timeout\r | |
405 | )\r | |
406 | {\r | |
407 | EFI_STATUS Status;\r | |
408 | \r | |
409 | EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC);\r | |
410 | \r | |
411 | Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, FALSE, Timeout);\r | |
412 | return Status;\r | |
413 | }\r | |
414 | \r | |
415 | \r | |
416 | \r | |
417 | /**\r | |
78c2ffb5 | 418 | Whether Ehc is halted.\r |
913cb9dc | 419 | \r |
78c2ffb5 | 420 | @param Ehc The EHCI device.\r |
913cb9dc | 421 | \r |
78c2ffb5 | 422 | @retval TRUE The controller is halted.\r |
423 | @retval FALSE It isn't halted.\r | |
913cb9dc | 424 | \r |
425 | **/\r | |
426 | BOOLEAN\r | |
427 | EhcIsHalt (\r | |
428 | IN USB2_HC_DEV *Ehc\r | |
429 | )\r | |
430 | {\r | |
431 | return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT);\r | |
432 | }\r | |
433 | \r | |
434 | \r | |
435 | /**\r | |
78c2ffb5 | 436 | Whether system error occurred.\r |
913cb9dc | 437 | \r |
78c2ffb5 | 438 | @param Ehc The EHCI device.\r |
913cb9dc | 439 | \r |
78c2ffb5 | 440 | @return TRUE System error happened.\r |
441 | @return FALSE No system error.\r | |
913cb9dc | 442 | \r |
443 | **/\r | |
444 | BOOLEAN\r | |
445 | EhcIsSysError (\r | |
446 | IN USB2_HC_DEV *Ehc\r | |
447 | )\r | |
448 | {\r | |
449 | return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR);\r | |
450 | }\r | |
451 | \r | |
452 | \r | |
453 | /**\r | |
78c2ffb5 | 454 | Reset the host controller.\r |
913cb9dc | 455 | \r |
78c2ffb5 | 456 | @param Ehc The EHCI device.\r |
457 | @param Timeout Time to wait before abort (in millisecond, ms).\r | |
913cb9dc | 458 | \r |
78c2ffb5 | 459 | @retval EFI_SUCCESS The host controller is reset.\r |
460 | @return Others Failed to reset the host.\r | |
913cb9dc | 461 | \r |
462 | **/\r | |
463 | EFI_STATUS\r | |
464 | EhcResetHC (\r | |
465 | IN USB2_HC_DEV *Ehc,\r | |
466 | IN UINT32 Timeout\r | |
467 | )\r | |
468 | {\r | |
469 | EFI_STATUS Status;\r | |
470 | \r | |
471 | //\r | |
472 | // Host can only be reset when it is halt. If not so, halt it\r | |
473 | //\r | |
474 | if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r | |
475 | Status = EhcHaltHC (Ehc, Timeout);\r | |
476 | \r | |
477 | if (EFI_ERROR (Status)) {\r | |
478 | return Status;\r | |
479 | }\r | |
480 | }\r | |
481 | \r | |
482 | EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET);\r | |
483 | Status = EhcWaitOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET, FALSE, Timeout);\r | |
484 | return Status;\r | |
485 | }\r | |
486 | \r | |
487 | \r | |
488 | /**\r | |
78c2ffb5 | 489 | Halt the host controller.\r |
913cb9dc | 490 | \r |
78c2ffb5 | 491 | @param Ehc The EHCI device.\r |
492 | @param Timeout Time to wait before abort.\r | |
913cb9dc | 493 | \r |
78c2ffb5 | 494 | @retval EFI_SUCCESS The EHCI is halt.\r |
495 | @retval EFI_TIMEOUT Failed to halt the controller before Timeout.\r | |
913cb9dc | 496 | \r |
497 | **/\r | |
498 | EFI_STATUS\r | |
499 | EhcHaltHC (\r | |
500 | IN USB2_HC_DEV *Ehc,\r | |
501 | IN UINT32 Timeout\r | |
502 | )\r | |
503 | {\r | |
504 | EFI_STATUS Status;\r | |
505 | \r | |
506 | EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r | |
507 | Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, TRUE, Timeout);\r | |
508 | return Status;\r | |
509 | }\r | |
510 | \r | |
511 | \r | |
512 | /**\r | |
78c2ffb5 | 513 | Set the EHCI to run.\r |
913cb9dc | 514 | \r |
78c2ffb5 | 515 | @param Ehc The EHCI device.\r |
516 | @param Timeout Time to wait before abort.\r | |
913cb9dc | 517 | \r |
78c2ffb5 | 518 | @retval EFI_SUCCESS The EHCI is running.\r |
519 | @return Others Failed to set the EHCI to run.\r | |
913cb9dc | 520 | \r |
521 | **/\r | |
522 | EFI_STATUS\r | |
523 | EhcRunHC (\r | |
524 | IN USB2_HC_DEV *Ehc,\r | |
525 | IN UINT32 Timeout\r | |
526 | )\r | |
527 | {\r | |
528 | EFI_STATUS Status;\r | |
529 | \r | |
530 | EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r | |
531 | Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, FALSE, Timeout);\r | |
532 | return Status;\r | |
533 | }\r | |
534 | \r | |
535 | \r | |
536 | /**\r | |
537 | Initialize the HC hardware.\r | |
78c2ffb5 | 538 | EHCI spec lists the five things to do to initialize the hardware:\r |
913cb9dc | 539 | 1. Program CTRLDSSEGMENT\r |
540 | 2. Set USBINTR to enable interrupts\r | |
541 | 3. Set periodic list base\r | |
542 | 4. Set USBCMD, interrupt threshold, frame list size etc\r | |
543 | 5. Write 1 to CONFIGFLAG to route all ports to EHCI\r | |
544 | \r | |
78c2ffb5 | 545 | @param Ehc The EHCI device.\r |
913cb9dc | 546 | \r |
78c2ffb5 | 547 | @return EFI_SUCCESS The EHCI has come out of halt state.\r |
548 | @return EFI_TIMEOUT Time out happened.\r | |
913cb9dc | 549 | \r |
550 | **/\r | |
551 | EFI_STATUS\r | |
552 | EhcInitHC (\r | |
553 | IN USB2_HC_DEV *Ehc\r | |
554 | )\r | |
555 | {\r | |
556 | EFI_STATUS Status;\r | |
557 | \r | |
f147a39e A |
558 | // This ASSERT crashes the BeagleBoard. There is some issue in the USB stack.\r |
559 | // This ASSERT needs to be removed so the BeagleBoard will boot. When we fix\r | |
560 | // the USB stack we can put this ASSERT back in\r | |
561 | // ASSERT (EhcIsHalt (Ehc));\r | |
913cb9dc | 562 | \r |
563 | //\r | |
564 | // Allocate the periodic frame and associated memeory\r | |
565 | // management facilities if not already done.\r | |
566 | //\r | |
739802e4 | 567 | if (Ehc->PeriodFrameHost != NULL) {\r |
913cb9dc | 568 | EhcFreeSched (Ehc);\r |
569 | }\r | |
570 | \r | |
571 | Status = EhcInitSched (Ehc);\r | |
572 | \r | |
573 | if (EFI_ERROR (Status)) {\r | |
574 | return Status;\r | |
575 | }\r | |
576 | //\r | |
577 | // 1. Program the CTRLDSSEGMENT register with the high 32 bit addr\r | |
578 | //\r | |
579 | EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, Ehc->High32bitAddr);\r | |
580 | \r | |
581 | //\r | |
582 | // 2. Clear USBINTR to disable all the interrupt. UEFI works by polling\r | |
583 | //\r | |
584 | EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0);\r | |
585 | \r | |
586 | //\r | |
587 | // 3. Program periodic frame list, already done in EhcInitSched\r | |
588 | // 4. Start the Host Controller\r | |
589 | //\r | |
590 | EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r | |
591 | \r | |
592 | //\r | |
593 | // 5. Set all ports routing to EHC\r | |
594 | //\r | |
595 | EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);\r | |
596 | \r | |
41e8ff27 | 597 | //\r |
598 | // Wait roothub port power stable\r | |
599 | //\r | |
600 | gBS->Stall (EHC_ROOT_PORT_RECOVERY_STALL);\r | |
601 | \r | |
602 | Status = EhcEnablePeriodSchd (Ehc, EHC_GENERIC_TIMEOUT);\r | |
913cb9dc | 603 | \r |
604 | if (EFI_ERROR (Status)) {\r | |
1c619535 | 605 | DEBUG ((EFI_D_ERROR, "EhcInitHC: failed to enable period schedule\n"));\r |
913cb9dc | 606 | return Status;\r |
607 | }\r | |
608 | \r | |
41e8ff27 | 609 | Status = EhcEnableAsyncSchd (Ehc, EHC_GENERIC_TIMEOUT);\r |
913cb9dc | 610 | \r |
611 | if (EFI_ERROR (Status)) {\r | |
1c619535 | 612 | DEBUG ((EFI_D_ERROR, "EhcInitHC: failed to enable async schedule\n"));\r |
913cb9dc | 613 | return Status;\r |
614 | }\r | |
615 | \r | |
616 | return EFI_SUCCESS;\r | |
617 | }\r |