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