1 /** @file
2 The OHCI register operation routines.
3
4 Copyright (c) 2013-2015 Intel Corporation.
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include "OhcPeim.h"
18
19 /**
20
21 Get OHCI operational reg value
22
23 @param Ohc UHC private data
24 @param Offset Offset of the operational reg
25
26 @retval Value of the register
27
28 **/
29 UINT32
OhciGetOperationalReg(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Offset)30 OhciGetOperationalReg (
31 IN USB_OHCI_HC_DEV *Ohc,
32 IN UINT32 Offset
33 )
34 {
35
36 return MmioRead32 (Ohc->UsbHostControllerBaseAddress + Offset);
37
38 }
39 /**
40
41 Set OHCI operational reg value
42
43 @param Ohc UHC private data
44 @param Offset Offset of the operational reg
45 @param Value Value to set
46
47 @retval EFI_SUCCESS Value set to the reg
48
49 **/
50
51
52 EFI_STATUS
OhciSetOperationalReg(USB_OHCI_HC_DEV * Ohc,IN UINT32 Offset,IN UINT32 * Value)53 OhciSetOperationalReg (
54 USB_OHCI_HC_DEV *Ohc,
55 IN UINT32 Offset,
56 IN UINT32 *Value
57 )
58 {
59 MmioWrite32(Ohc->UsbHostControllerBaseAddress + Offset, *Value);
60 return EFI_SUCCESS;
61 }
62 /**
63
64 Get HcRevision reg value
65
66 @param Ohc UHC private data
67
68 @retval Value of the register
69
70 **/
71
72
73 UINT32
OhciGetHcRevision(USB_OHCI_HC_DEV * Ohc)74 OhciGetHcRevision (
75 USB_OHCI_HC_DEV *Ohc
76 )
77 {
78 return OhciGetOperationalReg (Ohc, HC_REVISION);
79 }
80 /**
81
82 Set HcReset reg value
83
84
85 @param Ohc UHC private data
86 @param Field Field to set
87 @param Value Value to set
88
89 @retval EFI_SUCCESS Value set
90
91 **/
92
93 EFI_STATUS
OhciSetHcReset(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Field,IN UINT32 Value)94 OhciSetHcReset (
95 IN USB_OHCI_HC_DEV *Ohc,
96 IN UINT32 Field,
97 IN UINT32 Value
98 )
99 {
100 EFI_STATUS Status;
101 HcRESET Reset;
102
103 Status = EFI_SUCCESS;
104 *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR);
105
106 if (Field & RESET_SYSTEM_BUS) {
107 Reset.FSBIR = Value;
108 }
109
110 if (Field & RESET_HOST_CONTROLLER) {
111 Reset.FHR = Value;
112 }
113
114 if (Field & RESET_CLOCK_GENERATION) {
115 Reset.CGR = Value;
116 }
117
118 if (Field & RESET_SSE_GLOBAL) {
119 Reset.SSE = Value;
120 }
121
122 if (Field & RESET_PSPL) {
123 Reset.PSPL = Value;
124 }
125
126 if (Field & RESET_PCPL) {
127 Reset.PCPL = Value;
128 }
129
130 if (Field & RESET_SSEP1) {
131 Reset.SSEP1 = Value;
132 }
133
134 if (Field & RESET_SSEP2) {
135 Reset.SSEP2 = Value;
136 }
137
138 if (Field & RESET_SSEP3) {
139 Reset.SSEP3 = Value;
140 }
141
142 OhciSetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR, (UINT32*)&Reset);
143
144 return EFI_SUCCESS;
145 }
146
147 /**
148
149 Get specific field of HcReset reg value
150
151 @param Ohc UHC private data
152 @param Field Field to get
153
154 @retval Value of the field
155
156 **/
157
158 UINT32
OhciGetHcReset(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Field)159 OhciGetHcReset (
160 IN USB_OHCI_HC_DEV *Ohc,
161 IN UINT32 Field
162 )
163 {
164 HcRESET Reset;
165 UINT32 Value;
166
167
168 *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc, USBHOST_OFFSET_UHCHR);
169 Value = 0;
170
171 switch (Field) {
172 case RESET_SYSTEM_BUS:
173 Value = Reset.FSBIR;
174 break;
175
176 case RESET_HOST_CONTROLLER:
177 Value = Reset.FHR;
178 break;
179
180 case RESET_CLOCK_GENERATION:
181 Value = Reset.CGR;
182 break;
183
184 case RESET_SSE_GLOBAL:
185 Value = Reset.SSE;
186 break;
187
188 case RESET_PSPL:
189 Value = Reset.PSPL;
190 break;
191
192 case RESET_PCPL:
193 Value = Reset.PCPL;
194 break;
195
196 case RESET_SSEP1:
197 Value = Reset.SSEP1;
198 break;
199
200 case RESET_SSEP2:
201 Value = Reset.SSEP2;
202 break;
203
204 case RESET_SSEP3:
205 Value = Reset.SSEP3;
206 break;
207
208 default:
209 ASSERT (FALSE);
210 }
211
212
213 return Value;
214 }
215
216 /**
217
218 Set HcControl reg value
219
220 @param Ohc UHC private data
221 @param Field Field to set
222 @param Value Value to set
223
224 @retval EFI_SUCCESS Value set
225
226 **/
227
228 EFI_STATUS
OhciSetHcControl(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)229 OhciSetHcControl (
230 IN USB_OHCI_HC_DEV *Ohc,
231 IN UINTN Field,
232 IN UINT32 Value
233 )
234 {
235 EFI_STATUS Status;
236 HcCONTROL Control;
237
238
239
240 *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL);
241
242 if (Field & CONTROL_BULK_RATIO) {
243 Control.ControlBulkRatio = Value;
244 }
245
246 if (Field & HC_FUNCTIONAL_STATE) {
247 Control.FunctionalState = Value;
248 }
249
250 if (Field & PERIODIC_ENABLE) {
251 Control.PeriodicEnable = Value;
252 }
253
254 if (Field & CONTROL_ENABLE) {
255 Control.ControlEnable = Value;
256 }
257
258 if (Field & ISOCHRONOUS_ENABLE) {
259 Control.IsochronousEnable = Value;
260 }
261
262 if (Field & BULK_ENABLE) {
263 Control.BulkEnable = Value;
264 }
265
266 if (Field & INTERRUPT_ROUTING) {
267 Control.InterruptRouting = Value;
268 }
269
270 Status = OhciSetOperationalReg (Ohc, HC_CONTROL, (UINT32*)&Control);
271
272 return Status;
273 }
274
275
276 /**
277
278 Get specific field of HcControl reg value
279
280 @param Ohc UHC private data
281 @param Field Field to get
282
283 @retval Value of the field
284
285 **/
286
287
288 UINT32
OhciGetHcControl(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)289 OhciGetHcControl (
290 IN USB_OHCI_HC_DEV *Ohc,
291 IN UINTN Field
292 )
293 {
294 HcCONTROL Control;
295
296 *(UINT32 *) &Control = OhciGetOperationalReg (Ohc, HC_CONTROL);
297
298 switch (Field) {
299 case CONTROL_BULK_RATIO:
300 return Control.ControlBulkRatio;
301 break;
302 case PERIODIC_ENABLE:
303 return Control.PeriodicEnable;
304 break;
305 case CONTROL_ENABLE:
306 return Control.ControlEnable;
307 break;
308 case BULK_ENABLE:
309 return Control.BulkEnable;
310 break;
311 case ISOCHRONOUS_ENABLE:
312 return Control.IsochronousEnable;
313 break;
314 case HC_FUNCTIONAL_STATE:
315 return Control.FunctionalState;
316 break;
317 case INTERRUPT_ROUTING:
318 return Control.InterruptRouting;
319 break;
320 default:
321 ASSERT (FALSE);
322 }
323
324 return 0;
325 }
326
327 /**
328
329 Set HcCommand reg value
330
331 @param Ohc UHC private data
332 @param Field Field to set
333 @param Value Value to set
334
335 @retval EFI_SUCCESS Value set
336
337 **/
338
339 EFI_STATUS
OhciSetHcCommandStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)340 OhciSetHcCommandStatus (
341 IN USB_OHCI_HC_DEV *Ohc,
342 IN UINTN Field,
343 IN UINT32 Value
344 )
345 {
346 EFI_STATUS Status;
347 HcCOMMAND_STATUS CommandStatus;
348
349 ZeroMem (&CommandStatus, sizeof (HcCOMMAND_STATUS));
350
351 if(Field & HC_RESET){
352 CommandStatus.HcReset = Value;
353 }
354
355 if(Field & CONTROL_LIST_FILLED){
356 CommandStatus.ControlListFilled = Value;
357 }
358
359 if(Field & BULK_LIST_FILLED){
360 CommandStatus.BulkListFilled = Value;
361 }
362
363 if(Field & CHANGE_OWNER_REQUEST){
364 CommandStatus.ChangeOwnerRequest = Value;
365 }
366
367 if(Field & SCHEDULE_OVERRUN_COUNT){
368 CommandStatus.ScheduleOverrunCount = Value;
369 }
370
371 Status = OhciSetOperationalReg (Ohc, HC_COMMAND_STATUS, (UINT32*)&CommandStatus);
372
373 return Status;
374 }
375
376 /**
377
378 Get specific field of HcCommand reg value
379
380 @param Ohc UHC private data
381 @param Field Field to get
382
383 @retval Value of the field
384
385 **/
386
387 UINT32
OhciGetHcCommandStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)388 OhciGetHcCommandStatus (
389 IN USB_OHCI_HC_DEV *Ohc,
390 IN UINTN Field
391 )
392 {
393 HcCOMMAND_STATUS CommandStatus;
394
395 *(UINT32 *) &CommandStatus = OhciGetOperationalReg (Ohc, HC_COMMAND_STATUS);
396
397 switch (Field){
398 case HC_RESET:
399 return CommandStatus.HcReset;
400 break;
401 case CONTROL_LIST_FILLED:
402 return CommandStatus.ControlListFilled;
403 break;
404 case BULK_LIST_FILLED:
405 return CommandStatus.BulkListFilled;
406 break;
407 case CHANGE_OWNER_REQUEST:
408 return CommandStatus.ChangeOwnerRequest;
409 break;
410 case SCHEDULE_OVERRUN_COUNT:
411 return CommandStatus.ScheduleOverrunCount;
412 break;
413 default:
414 ASSERT (FALSE);
415 }
416
417 return 0;
418 }
419
420 /**
421
422 Clear specific fields of Interrupt Status
423
424 @param Ohc UHC private data
425 @param Field Field to clear
426
427 @retval EFI_SUCCESS Fields cleared
428
429 **/
430
431 EFI_STATUS
OhciClearInterruptStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)432 OhciClearInterruptStatus (
433 IN USB_OHCI_HC_DEV *Ohc,
434 IN UINTN Field
435 )
436 {
437 EFI_STATUS Status;
438 HcINTERRUPT_STATUS InterruptStatus;
439
440 ZeroMem (&InterruptStatus, sizeof (HcINTERRUPT_STATUS));
441
442 if(Field & SCHEDULE_OVERRUN){
443 InterruptStatus.SchedulingOverrun = 1;
444 }
445
446 if(Field & WRITEBACK_DONE_HEAD){
447 InterruptStatus.WriteBackDone = 1;
448 }
449 if(Field & START_OF_FRAME){
450 InterruptStatus.Sof = 1;
451 }
452
453 if(Field & RESUME_DETECT){
454 InterruptStatus.ResumeDetected = 1;
455 }
456
457 if(Field & UNRECOVERABLE_ERROR){
458 InterruptStatus.UnrecoverableError = 1;
459 }
460
461 if(Field & FRAME_NUMBER_OVERFLOW){
462 InterruptStatus.FrameNumOverflow = 1;
463 }
464
465 if(Field & ROOTHUB_STATUS_CHANGE){
466 InterruptStatus.RHStatusChange = 1;
467 }
468
469 if(Field & OWNERSHIP_CHANGE){
470 InterruptStatus.OwnerChange = 1;
471 }
472
473 Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_STATUS, (UINT32*)&InterruptStatus);
474
475 return Status;
476 }
477
478 /**
479
480 Get fields of HcInterrupt reg value
481
482 @param Ohc UHC private data
483 @param Field Field to get
484
485 @retval Value of the field
486
487 **/
488
489 UINT32
OhciGetHcInterruptStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)490 OhciGetHcInterruptStatus (
491 IN USB_OHCI_HC_DEV *Ohc,
492 IN UINTN Field
493 )
494 {
495 HcINTERRUPT_STATUS InterruptStatus;
496
497 *(UINT32 *) &InterruptStatus = OhciGetOperationalReg (Ohc, HC_INTERRUPT_STATUS);
498
499 switch (Field){
500 case SCHEDULE_OVERRUN:
501 return InterruptStatus.SchedulingOverrun;
502 break;
503
504 case WRITEBACK_DONE_HEAD:
505 return InterruptStatus.WriteBackDone;
506 break;
507
508 case START_OF_FRAME:
509 return InterruptStatus.Sof;
510 break;
511
512 case RESUME_DETECT:
513 return InterruptStatus.ResumeDetected;
514 break;
515
516 case UNRECOVERABLE_ERROR:
517 return InterruptStatus.UnrecoverableError;
518 break;
519
520 case FRAME_NUMBER_OVERFLOW:
521 return InterruptStatus.FrameNumOverflow;
522 break;
523
524 case ROOTHUB_STATUS_CHANGE:
525 return InterruptStatus.RHStatusChange;
526 break;
527
528 case OWNERSHIP_CHANGE:
529 return InterruptStatus.OwnerChange;
530 break;
531
532 default:
533 ASSERT (FALSE);
534 }
535
536 return 0;
537 }
538
539 /**
540
541 Set Interrupt Control reg value
542
543 @param Ohc UHC private data
544 @param StatEnable Enable or Disable
545 @param Field Field to set
546 @param Value Value to set
547
548 @retval EFI_SUCCESS Value set
549
550 **/
551
552 EFI_STATUS
OhciSetInterruptControl(IN USB_OHCI_HC_DEV * Ohc,IN BOOLEAN StatEnable,IN UINTN Field,IN UINT32 Value)553 OhciSetInterruptControl (
554 IN USB_OHCI_HC_DEV *Ohc,
555 IN BOOLEAN StatEnable,
556 IN UINTN Field,
557 IN UINT32 Value
558 )
559 {
560 EFI_STATUS Status;
561 HcINTERRUPT_CONTROL InterruptState;
562
563
564 ZeroMem (&InterruptState, sizeof (HcINTERRUPT_CONTROL));
565
566 if(Field & SCHEDULE_OVERRUN) {
567 InterruptState.SchedulingOverrunInt = Value;
568 }
569
570 if(Field & WRITEBACK_DONE_HEAD) {
571 InterruptState.WriteBackDoneInt = Value;
572 }
573 if(Field & START_OF_FRAME) {
574 InterruptState.SofInt = Value;
575 }
576
577 if(Field & RESUME_DETECT) {
578 InterruptState.ResumeDetectedInt = Value;
579 }
580
581 if(Field & UNRECOVERABLE_ERROR) {
582 InterruptState.UnrecoverableErrorInt = Value;
583 }
584
585 if(Field & FRAME_NUMBER_OVERFLOW) {
586 InterruptState.FrameNumOverflowInt = Value;
587 }
588
589 if(Field & ROOTHUB_STATUS_CHANGE) {
590 InterruptState.RHStatusChangeInt = Value;
591 }
592
593 if(Field & OWNERSHIP_CHANGE) {
594 InterruptState.OwnerChangedInt = Value;
595 }
596
597 if(Field & MASTER_INTERRUPT) {
598 InterruptState.MasterInterruptEnable = Value;
599 }
600
601 if (StatEnable) {
602 Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_ENABLE, (UINT32*)&InterruptState);
603 } else {
604 Status = OhciSetOperationalReg (Ohc, HC_INTERRUPT_DISABLE, (UINT32*)&InterruptState);
605 }
606
607 return Status;
608 }
609
610 /**
611
612 Get field of HcInterruptControl reg value
613
614 @param Ohc UHC private data
615 @param Field Field to get
616
617 @retval Value of the field
618
619 **/
620
621 UINT32
OhciGetHcInterruptControl(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)622 OhciGetHcInterruptControl (
623 IN USB_OHCI_HC_DEV *Ohc,
624 IN UINTN Field
625 )
626 {
627 HcINTERRUPT_CONTROL InterruptState;
628
629 *(UINT32 *) &InterruptState = OhciGetOperationalReg (Ohc, HC_INTERRUPT_ENABLE);
630
631 switch (Field){
632 case SCHEDULE_OVERRUN:
633 return InterruptState.SchedulingOverrunInt;
634 break;
635
636 case WRITEBACK_DONE_HEAD:
637 return InterruptState.WriteBackDoneInt;
638 break;
639
640 case START_OF_FRAME:
641 return InterruptState.SofInt;
642 break;
643
644 case RESUME_DETECT:
645 return InterruptState.ResumeDetectedInt;
646 break;
647
648 case UNRECOVERABLE_ERROR:
649 return InterruptState.UnrecoverableErrorInt;
650 break;
651
652 case FRAME_NUMBER_OVERFLOW:
653 return InterruptState.FrameNumOverflowInt;
654 break;
655
656 case ROOTHUB_STATUS_CHANGE:
657 return InterruptState.RHStatusChangeInt;
658 break;
659
660 case OWNERSHIP_CHANGE:
661 return InterruptState.OwnerChangedInt;
662 break;
663
664 case MASTER_INTERRUPT:
665 return InterruptState.MasterInterruptEnable;
666 break;
667
668 default:
669 ASSERT (FALSE);
670 }
671
672 return 0;
673 }
674
675 /**
676
677 Set memory pointer of specific type
678
679 @param Ohc UHC private data
680 @param PointerType Type of the pointer to set
681 @param Value Value to set
682
683 @retval EFI_SUCCESS Memory pointer set
684
685 **/
686
687 EFI_STATUS
OhciSetMemoryPointer(IN USB_OHCI_HC_DEV * Ohc,IN UINTN PointerType,IN VOID * Value)688 OhciSetMemoryPointer(
689 IN USB_OHCI_HC_DEV *Ohc,
690 IN UINTN PointerType,
691 IN VOID *Value
692 )
693 {
694 EFI_STATUS Status;
695 UINT32 Verify;
696
697 Status = OhciSetOperationalReg (Ohc, PointerType, (UINT32*)&Value);
698
699 if (EFI_ERROR (Status)) {
700 return Status;
701 }
702
703 Verify = OhciGetOperationalReg (Ohc, PointerType);
704
705 while (Verify != (UINT32) Value) {
706 MicroSecondDelay (HC_1_MILLISECOND);
707 Verify = OhciGetOperationalReg (Ohc, PointerType);
708 };
709
710
711 return Status;
712 }
713
714 /**
715
716 Get memory pointer of specific type
717
718 @param Ohc UHC private data
719 @param PointerType Type of pointer
720
721 @retval Memory pointer of the specific type
722
723 **/
724
725 VOID *
OhciGetMemoryPointer(IN USB_OHCI_HC_DEV * Ohc,IN UINTN PointerType)726 OhciGetMemoryPointer (
727 IN USB_OHCI_HC_DEV *Ohc,
728 IN UINTN PointerType
729 )
730 {
731
732 return (VOID *) OhciGetOperationalReg (Ohc, PointerType);
733 }
734
735
736 /**
737
738 Set Frame Interval value
739
740 @param Ohc UHC private data
741 @param Field Field to set
742 @param Value Value to set
743
744 @retval EFI_SUCCESS Value set
745
746 **/
747
748 EFI_STATUS
OhciSetFrameInterval(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)749 OhciSetFrameInterval (
750 IN USB_OHCI_HC_DEV *Ohc,
751 IN UINTN Field,
752 IN UINT32 Value
753 )
754 {
755 EFI_STATUS Status;
756 HcFRM_INTERVAL FrameInterval;
757
758
759 *(UINT32 *) &FrameInterval = OhciGetOperationalReg(Ohc, HC_FRM_INTERVAL);
760
761 if (Field & FRAME_INTERVAL) {
762 FrameInterval.FrmIntervalToggle = !FrameInterval.FrmIntervalToggle;
763 FrameInterval.FrameInterval = Value;
764 }
765
766 if (Field & FS_LARGEST_DATA_PACKET) {
767 FrameInterval.FSMaxDataPacket = Value;
768 }
769
770 if (Field & FRMINT_TOGGLE) {
771 FrameInterval.FrmIntervalToggle = Value;
772 }
773
774 Status = OhciSetOperationalReg (
775 Ohc,
776 HC_FRM_INTERVAL,
777 (UINT32*)&FrameInterval
778 );
779
780 return Status;
781 }
782
783
784 /**
785
786 Get field of frame interval reg value
787
788 @param Ohc UHC private data
789 @param Field Field to get
790
791 @retval Value of the field
792
793 **/
794
795 UINT32
OhciGetFrameInterval(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)796 OhciGetFrameInterval (
797 IN USB_OHCI_HC_DEV *Ohc,
798 IN UINTN Field
799 )
800 {
801 HcFRM_INTERVAL FrameInterval;
802
803 *(UINT32 *) &FrameInterval = OhciGetOperationalReg (Ohc, HC_FRM_INTERVAL);
804
805 switch (Field){
806 case FRAME_INTERVAL:
807 return FrameInterval.FrameInterval;
808 break;
809
810 case FS_LARGEST_DATA_PACKET:
811 return FrameInterval.FSMaxDataPacket;
812 break;
813
814 case FRMINT_TOGGLE:
815 return FrameInterval.FrmIntervalToggle;
816 break;
817
818 default:
819 ASSERT (FALSE);
820 }
821
822 return 0;
823 }
824
825 /**
826
827 Set Frame Remaining reg value
828
829 @param Ohc UHC private data
830 @param Value Value to set
831
832 @retval EFI_SUCCESS Value set
833
834 **/
835
836 EFI_STATUS
OhciSetFrameRemaining(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)837 OhciSetFrameRemaining (
838 IN USB_OHCI_HC_DEV *Ohc,
839 IN UINT32 Value
840 )
841 {
842 EFI_STATUS Status;
843 HcFRAME_REMAINING FrameRemaining;
844
845
846 *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING);
847
848 FrameRemaining.FrameRemaining = Value;
849 FrameRemaining.FrameRemainingToggle = !FrameRemaining.FrameRemainingToggle;
850
851 Status = OhciSetOperationalReg (Ohc, HC_FRM_REMAINING, (UINT32*)&FrameRemaining);
852
853 return Status;
854 }
855 /**
856
857 Get value of frame remaining reg
858
859 @param Ohc UHC private data
860 @param Field Field to get
861
862 @retval Value of frame remaining reg
863
864 **/
865 UINT32
OhciGetFrameRemaining(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)866 OhciGetFrameRemaining (
867 IN USB_OHCI_HC_DEV *Ohc,
868 IN UINTN Field
869 )
870
871 {
872 HcFRAME_REMAINING FrameRemaining;
873
874
875 *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc, HC_FRM_REMAINING);
876
877 switch (Field){
878 case FRAME_REMAINING:
879 return FrameRemaining.FrameRemaining;
880 break;
881
882 case FRAME_REMAIN_TOGGLE:
883 return FrameRemaining.FrameRemainingToggle;
884 break;
885
886 default:
887 ASSERT (FALSE);
888 }
889
890 return 0;
891 }
892
893 /**
894
895 Set frame number reg value
896
897 @param Ohc UHC private data
898 @param Value Value to set
899
900 @retval EFI_SUCCESS Value set
901
902 **/
903
904 EFI_STATUS
OhciSetFrameNumber(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)905 OhciSetFrameNumber(
906 IN USB_OHCI_HC_DEV *Ohc,
907 IN UINT32 Value
908 )
909 {
910 EFI_STATUS Status;
911
912 Status = OhciSetOperationalReg (Ohc, HC_FRM_NUMBER, &Value);
913
914 return Status;
915 }
916
917 /**
918
919 Get frame number reg value
920
921 @param Ohc UHC private data
922
923 @retval Value of frame number reg
924
925 **/
926
927 UINT32
OhciGetFrameNumber(IN USB_OHCI_HC_DEV * Ohc)928 OhciGetFrameNumber (
929 IN USB_OHCI_HC_DEV *Ohc
930 )
931 {
932 return OhciGetOperationalReg(Ohc, HC_FRM_NUMBER);
933 }
934
935 /**
936
937 Set period start reg value
938
939 @param Ohc UHC private data
940 @param Value Value to set
941
942 @retval EFI_SUCCESS Value set
943
944 **/
945
946 EFI_STATUS
OhciSetPeriodicStart(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)947 OhciSetPeriodicStart (
948 IN USB_OHCI_HC_DEV *Ohc,
949 IN UINT32 Value
950 )
951 {
952 EFI_STATUS Status;
953
954
955 Status = OhciSetOperationalReg (Ohc, HC_PERIODIC_START, &Value);
956
957 return Status;
958 }
959
960
961 /**
962
963 Get periodic start reg value
964
965 @param Ohc UHC private data
966
967 @param Value of periodic start reg
968
969 **/
970
971 UINT32
OhciGetPeriodicStart(IN USB_OHCI_HC_DEV * Ohc)972 OhciGetPeriodicStart (
973 IN USB_OHCI_HC_DEV *Ohc
974 )
975 {
976 return OhciGetOperationalReg(Ohc, HC_PERIODIC_START);
977 }
978
979
980 /**
981
982 Set Ls Threshold reg value
983
984 @param Ohc UHC private data
985 @param Value Value to set
986
987 @retval EFI_SUCCESS Value set
988
989 **/
990
991 EFI_STATUS
OhciSetLsThreshold(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)992 OhciSetLsThreshold (
993 IN USB_OHCI_HC_DEV *Ohc,
994 IN UINT32 Value
995 )
996 {
997 EFI_STATUS Status;
998
999
1000 Status = OhciSetOperationalReg (Ohc, HC_LS_THREASHOLD, &Value);
1001
1002 return Status;
1003 }
1004
1005
1006 /**
1007
1008 Get Ls Threshold reg value
1009
1010 @param Ohc UHC private data
1011
1012 @retval Value of Ls Threshold reg
1013
1014 **/
1015
1016 UINT32
OhciGetLsThreshold(IN USB_OHCI_HC_DEV * Ohc)1017 OhciGetLsThreshold (
1018 IN USB_OHCI_HC_DEV *Ohc
1019 )
1020 {
1021 return OhciGetOperationalReg(Ohc, HC_LS_THREASHOLD);
1022 }
1023
1024 /**
1025
1026 Set Root Hub Descriptor reg value
1027
1028 @param Ohc UHC private data
1029 @param Field Field to set
1030 @param Value Value to set
1031
1032 @retval EFI_SUCCESS Value set
1033
1034 **/
1035 EFI_STATUS
OhciSetRootHubDescriptor(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)1036 OhciSetRootHubDescriptor (
1037 IN USB_OHCI_HC_DEV *Ohc,
1038 IN UINTN Field,
1039 IN UINT32 Value
1040 )
1041 {
1042 EFI_STATUS Status;
1043 HcRH_DESC_A DescriptorA;
1044 HcRH_DESC_B DescriptorB;
1045
1046
1047 if (Field & (RH_DEV_REMOVABLE || RH_PORT_PWR_CTRL_MASK)) {
1048 *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B);
1049
1050 if(Field & RH_DEV_REMOVABLE) {
1051 DescriptorB.DeviceRemovable = Value;
1052 }
1053 if(Field & RH_PORT_PWR_CTRL_MASK) {
1054 DescriptorB.PortPowerControlMask = Value;
1055 }
1056
1057 Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_B, (UINT32*)&DescriptorB);
1058
1059 return Status;
1060 }
1061
1062 *(UINT32 *)&DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A);
1063
1064 if(Field & RH_NUM_DS_PORTS) {
1065 DescriptorA.NumDownStrmPorts = Value;
1066 }
1067 if(Field & RH_NO_PSWITCH) {
1068 DescriptorA.NoPowerSwitch = Value;
1069 }
1070 if(Field & RH_PSWITCH_MODE) {
1071 DescriptorA.PowerSwitchMode = Value;
1072 }
1073 if(Field & RH_DEVICE_TYPE) {
1074 DescriptorA.DeviceType = Value;
1075 }
1076 if(Field & RH_OC_PROT_MODE) {
1077 DescriptorA.OverCurrentProtMode = Value;
1078 }
1079 if(Field & RH_NOC_PROT) {
1080 DescriptorA.NoOverCurrentProtMode = Value;
1081 }
1082 if(Field & RH_NO_POTPGT) {
1083 DescriptorA.PowerOnToPowerGoodTime = Value;
1084 }
1085
1086 Status = OhciSetOperationalReg (Ohc, HC_RH_DESC_A, (UINT32*)&DescriptorA);
1087
1088 return Status;
1089 }
1090
1091
1092 /**
1093
1094 Get Root Hub Descriptor reg value
1095
1096 @param Ohc UHC private data
1097 @param Field Field to get
1098
1099 @retval Value of the field
1100
1101 **/
1102
1103 UINT32
OhciGetRootHubDescriptor(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)1104 OhciGetRootHubDescriptor (
1105 IN USB_OHCI_HC_DEV *Ohc,
1106 IN UINTN Field
1107 )
1108 {
1109 HcRH_DESC_A DescriptorA;
1110 HcRH_DESC_B DescriptorB;
1111
1112
1113 *(UINT32 *) &DescriptorA = OhciGetOperationalReg (Ohc, HC_RH_DESC_A);
1114 *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc, HC_RH_DESC_B);
1115
1116 switch (Field){
1117 case RH_DEV_REMOVABLE:
1118 return DescriptorB.DeviceRemovable;
1119 break;
1120
1121 case RH_PORT_PWR_CTRL_MASK:
1122 return DescriptorB.PortPowerControlMask;
1123 break;
1124
1125 case RH_NUM_DS_PORTS:
1126 return DescriptorA.NumDownStrmPorts;
1127 break;
1128
1129 case RH_NO_PSWITCH:
1130 return DescriptorA.NoPowerSwitch;
1131 break;
1132
1133 case RH_PSWITCH_MODE:
1134 return DescriptorA.PowerSwitchMode;
1135 break;
1136
1137 case RH_DEVICE_TYPE:
1138 return DescriptorA.DeviceType;
1139 break;
1140
1141 case RH_OC_PROT_MODE:
1142 return DescriptorA.OverCurrentProtMode;
1143 break;
1144
1145 case RH_NOC_PROT:
1146 return DescriptorA.NoOverCurrentProtMode;
1147 break;
1148
1149 case RH_NO_POTPGT:
1150 return DescriptorA.PowerOnToPowerGoodTime;
1151 break;
1152
1153 default:
1154 ASSERT (FALSE);
1155 }
1156
1157 return 0;
1158 }
1159
1160
1161 /**
1162
1163 Set Root Hub Status reg value
1164
1165 @param Ohc UHC private data
1166 @param Field Field to set
1167
1168 @retval EFI_SUCCESS Value set
1169
1170 **/
1171
1172 EFI_STATUS
OhciSetRootHubStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)1173 OhciSetRootHubStatus (
1174 IN USB_OHCI_HC_DEV *Ohc,
1175 IN UINTN Field
1176 )
1177 {
1178 EFI_STATUS Status;
1179 HcRH_STATUS RootHubStatus;
1180
1181
1182 ZeroMem (&RootHubStatus, sizeof(HcRH_STATUS));
1183
1184 if(Field & RH_LOCAL_PSTAT){
1185 RootHubStatus.LocalPowerStat = 1;
1186 }
1187 if(Field & RH_OC_ID){
1188 RootHubStatus.OverCurrentIndicator = 1;
1189 }
1190 if(Field & RH_REMOTE_WK_ENABLE){
1191 RootHubStatus.DevRemoteWakeupEnable = 1;
1192 }
1193 if(Field & RH_LOCAL_PSTAT_CHANGE){
1194 RootHubStatus.LocalPowerStatChange = 1;
1195 }
1196 if(Field & RH_OC_ID_CHANGE){
1197 RootHubStatus.OverCurrentIndicatorChange = 1;
1198 }
1199 if(Field & RH_CLR_RMT_WK_ENABLE){
1200 RootHubStatus.ClearRemoteWakeupEnable = 1;
1201 }
1202
1203 Status = OhciSetOperationalReg (Ohc, HC_RH_STATUS, (UINT32*)&RootHubStatus);
1204
1205 return Status;
1206 }
1207
1208
1209 /**
1210
1211 Get Root Hub Status reg value
1212
1213 @param Ohc UHC private data
1214 @param Field Field to get
1215
1216 @retval Value of the field
1217
1218 **/
1219
1220 UINT32
OhciGetRootHubStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)1221 OhciGetRootHubStatus (
1222 IN USB_OHCI_HC_DEV *Ohc,
1223 IN UINTN Field
1224 )
1225 {
1226 HcRH_STATUS RootHubStatus;
1227
1228
1229 *(UINT32 *) &RootHubStatus = OhciGetOperationalReg (Ohc, HC_RH_STATUS);
1230
1231 switch (Field) {
1232 case RH_LOCAL_PSTAT:
1233 return RootHubStatus.LocalPowerStat;
1234 break;
1235 case RH_OC_ID:
1236 return RootHubStatus.OverCurrentIndicator;
1237 break;
1238 case RH_REMOTE_WK_ENABLE:
1239 return RootHubStatus.DevRemoteWakeupEnable;
1240 break;
1241 case RH_LOCAL_PSTAT_CHANGE:
1242 return RootHubStatus.LocalPowerStatChange;
1243 break;
1244 case RH_OC_ID_CHANGE:
1245 return RootHubStatus.OverCurrentIndicatorChange;
1246 break;
1247 case RH_CLR_RMT_WK_ENABLE:
1248 return RootHubStatus.ClearRemoteWakeupEnable;
1249 break;
1250 default:
1251 ASSERT (FALSE);
1252 }
1253
1254 return 0;
1255 }
1256
1257
1258 /**
1259
1260 Set Root Hub Port Status reg value
1261
1262 @param Ohc UHC private data
1263 @param Index Index of the port
1264 @param Field Field to set
1265
1266 @retval EFI_SUCCESS Value set
1267
1268 **/
1269
1270 EFI_STATUS
OhciSetRootHubPortStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Index,IN UINTN Field)1271 OhciSetRootHubPortStatus (
1272 IN USB_OHCI_HC_DEV *Ohc,
1273 IN UINT32 Index,
1274 IN UINTN Field
1275 )
1276 {
1277 EFI_STATUS Status;
1278 HcRHPORT_STATUS PortStatus;
1279
1280
1281 ZeroMem (&PortStatus, sizeof(HcRHPORT_STATUS));
1282
1283 if (Field & RH_CLEAR_PORT_ENABLE) {
1284 PortStatus.CurrentConnectStat = 1;
1285 }
1286 if (Field & RH_SET_PORT_ENABLE) {
1287 PortStatus.EnableStat = 1;
1288 }
1289 if (Field & RH_SET_PORT_SUSPEND) {
1290 PortStatus.SuspendStat = 1;
1291 }
1292 if (Field & RH_CLEAR_SUSPEND_STATUS) {
1293 PortStatus.OCIndicator = 1;
1294 }
1295 if (Field & RH_SET_PORT_RESET) {
1296 PortStatus.ResetStat = 1;
1297 }
1298 if (Field & RH_SET_PORT_POWER) {
1299 PortStatus.PowerStat = 1;
1300 }
1301 if (Field & RH_CLEAR_PORT_POWER) {
1302 PortStatus.LsDeviceAttached = 1;
1303 }
1304 if (Field & RH_CONNECT_STATUS_CHANGE) {
1305 PortStatus.ConnectStatChange = 1;
1306 }
1307 if (Field & RH_PORT_ENABLE_STAT_CHANGE) {
1308 PortStatus.EnableStatChange = 1;
1309 }
1310 if (Field & RH_PORT_SUSPEND_STAT_CHANGE) {
1311 PortStatus.SuspendStatChange = 1;
1312 }
1313 if (Field & RH_OC_INDICATOR_CHANGE) {
1314 PortStatus.OCIndicatorChange = 1;
1315 }
1316 if (Field & RH_PORT_RESET_STAT_CHANGE ) {
1317 PortStatus.ResetStatChange = 1;
1318 }
1319
1320 Status = OhciSetOperationalReg (Ohc, HC_RH_PORT_STATUS + (Index * 4), (UINT32*)&PortStatus);
1321
1322 return Status;
1323 }
1324
1325
1326 /**
1327
1328 Get Root Hub Port Status reg value
1329
1330 @param Ohc UHC private data
1331 @param Index Index of the port
1332 @param Field Field to get
1333
1334 @retval Value of the field and index
1335
1336 **/
1337
1338 UINT32
OhciReadRootHubPortStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Index,IN UINTN Field)1339 OhciReadRootHubPortStatus (
1340 IN USB_OHCI_HC_DEV *Ohc,
1341 IN UINT32 Index,
1342 IN UINTN Field
1343 )
1344 {
1345 HcRHPORT_STATUS PortStatus;
1346
1347 *(UINT32 *) &PortStatus = OhciGetOperationalReg (
1348 Ohc,
1349 HC_RH_PORT_STATUS + (Index * 4)
1350 );
1351
1352 switch (Field){
1353 case RH_CURR_CONNECT_STAT:
1354 return PortStatus.CurrentConnectStat;
1355 break;
1356 case RH_PORT_ENABLE_STAT:
1357 return PortStatus.EnableStat;
1358 break;
1359 case RH_PORT_SUSPEND_STAT:
1360 return PortStatus.SuspendStat;
1361 break;
1362 case RH_PORT_OC_INDICATOR:
1363 return PortStatus.OCIndicator;
1364 break;
1365 case RH_PORT_RESET_STAT:
1366 return PortStatus.ResetStat;
1367 break;
1368 case RH_PORT_POWER_STAT:
1369 return PortStatus.PowerStat;
1370 break;
1371 case RH_LSDEVICE_ATTACHED:
1372 return PortStatus.LsDeviceAttached;
1373 break;
1374 case RH_CONNECT_STATUS_CHANGE:
1375 return PortStatus.ConnectStatChange;
1376 break;
1377 case RH_PORT_ENABLE_STAT_CHANGE:
1378 return PortStatus.EnableStatChange;
1379 break;
1380 case RH_PORT_SUSPEND_STAT_CHANGE:
1381 return PortStatus.SuspendStatChange;
1382 break;
1383 case RH_OC_INDICATOR_CHANGE:
1384 return PortStatus.OCIndicatorChange;
1385 break;
1386 case RH_PORT_RESET_STAT_CHANGE:
1387 return PortStatus.ResetStatChange;
1388 break;
1389 default:
1390 ASSERT (FALSE);
1391 }
1392
1393 return 0;
1394 }
1395