2 Implementation of Usb Controller PPI.
4 Copyright (c) 2013-2015 Intel Corporation.
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
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.
17 #include <Ppi/UsbController.h>
18 #include <Library/DebugLib.h>
19 #include <Library/PeimEntryPoint.h>
20 #include <Library/PeiServicesLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/PcdLib.h>
23 #include <Library/PciLib.h>
24 #include <Library/IoLib.h>
33 EFI_PEI_PPI_DESCRIPTOR mPpiList
= {
34 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
35 &gPeiUsbControllerPpiGuid
,
39 UINTN mIohOhciPciReg
[IOH_MAX_OHCI_USB_CONTROLLERS
] = {
40 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER
, IOH_USB_OHCI_DEVICE_NUMBER
, IOH_OHCI_FUNCTION_NUMBER
, 0)
43 UINTN mIohEhciPciReg
[IOH_MAX_EHCI_USB_CONTROLLERS
] = {
44 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER
, IOH_USB_EHCI_DEVICE_NUMBER
, IOH_EHCI_FUNCTION_NUMBER
, 0),
48 When EHCI get started in DXE, OHCI couldn't get the ownership
49 of roothub after warm reset because CF@EHCI hasn't been cleared.
50 We should clear that reg before UpdateBootMode. But Reg@EHCI is
51 memory-mapped, so need assume a range of space without conflict
54 @param[in] PeiServices The pointer of EFI_PEI_SERVICES
60 IN EFI_PEI_SERVICES
**PeiServices
70 for (Index
= 0; Index
< IOH_MAX_EHCI_USB_CONTROLLERS
; Index
++) {
71 UsbBaseAddr
= PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress
);
73 // Manage EHCI on IOH, set UsbBaseAddr
75 SavBaseAddr
= PciRead32 (mIohEhciPciReg
[Index
] | R_IOH_USB_MEMBAR
);
76 PciWrite32 (mIohEhciPciReg
[Index
] | R_IOH_USB_MEMBAR
, UsbBaseAddr
);
80 SaveCmdData
= PciRead16 (mIohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
);
84 PciOr16 (mIohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
, B_IOH_USB_COMMAND_BME
| B_IOH_USB_COMMAND_MSE
);
86 // Clear CF register on EHCI
88 EhciCapLen
= MmioRead8 (UsbBaseAddr
+ R_IOH_EHCI_CAPLENGTH
);
89 MmioWrite32 (UsbBaseAddr
+ EhciCapLen
+ R_IOH_EHCI_CONFIGFLAGS
, 0);
91 DEBUG ((EFI_D_INFO
, "CF@EHCI = %x \n", UsbBaseAddr
+ EhciCapLen
+ R_IOH_EHCI_CONFIGFLAGS
));
93 // Restore EHCI UsbBaseAddr in PCI space
95 PciWrite32 (mIohEhciPciReg
[Index
] | R_IOH_USB_MEMBAR
, SavBaseAddr
);
97 // Restore EHCI Command register in PCI space
99 PciWrite16(mIohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
, SaveCmdData
);
103 Retrieved specified the USB controller information.
105 @param PeiServices The pointer of EFI_PEI_SERVICES.
106 @param This This PEI_USB_CONTROLLER_PPI instance.
107 @param UsbControllerId Indicate which usb controller information will be retrieved.
108 @param ControllerType Indicate the controller is Ehci, Ohci, OHCI
109 @param BaseAddress Indicate the memory bar of the controller
111 @retval EFI_SUCCESS The reset operation succeeded.
112 @retval EFI_INVALID_PARAMETER Attributes is not valid.
118 IN EFI_PEI_SERVICES
**PeiServices
,
119 IN PEI_USB_CONTROLLER_PPI
*This
,
120 IN UINT8 UsbControllerId
,
121 IN UINTN
*ControllerType
,
122 IN UINTN
*BaseAddress
125 IOH_OHCI_DEVICE
*PeiIohOhciDev
;
127 PeiIohOhciDev
= IOH_OHCI_DEVICE_FROM_THIS (This
);
129 if (UsbControllerId
>= IOH_MAX_OHCI_USB_CONTROLLERS
) {
130 return EFI_INVALID_PARAMETER
;
132 *ControllerType
= PEI_OHCI_CONTROLLER
;
133 *BaseAddress
= PeiIohOhciDev
->MmioBase
[UsbControllerId
];
138 Retrieved specified the USB controller information.
140 @param PeiServices The pointer of EFI_PEI_SERVICES.
141 @param This This PEI_USB_CONTROLLER_PPI instance.
142 @param UsbControllerId Indicate which usb controller information will be retrieved.
143 @param ControllerType Indicate the controller is Ehci, Ohci, OHCI
144 @param BaseAddress Indicate the memory bar of the controller
146 @retval EFI_SUCCESS The reset operation succeeded.
147 @retval EFI_INVALID_PARAMETER Attributes is not valid.
153 IN EFI_PEI_SERVICES
**PeiServices
,
154 IN PEI_USB_CONTROLLER_PPI
*This
,
155 IN UINT8 UsbControllerId
,
156 IN UINTN
*ControllerType
,
157 IN UINTN
*BaseAddress
160 IOH_EHCI_DEVICE
*PeiIohEhciDev
;
162 PeiIohEhciDev
= IOH_EHCI_DEVICE_FROM_THIS (This
);
164 if (UsbControllerId
>= IOH_MAX_EHCI_USB_CONTROLLERS
) {
165 return EFI_INVALID_PARAMETER
;
167 *ControllerType
= PEI_EHCI_CONTROLLER
;
168 *BaseAddress
= PeiIohEhciDev
->MmioBase
[UsbControllerId
];
174 Retrieved specified the USB controller information.
176 @param IohOhciPciReg Ohci device address list.
177 @param OhciCount The count of the OHCI
178 @param IohEhciPciReg Ehci device address list.
179 @param EhciCount The count of the EHCI
185 IN UINTN IohOhciPciReg
[],
187 IN UINTN IohEhciPciReg
[],
193 for (Index
= 0; Index
< OhciCount
; Index
++) {
194 CmdReg
= PciRead16 (IohOhciPciReg
[Index
] | R_IOH_USB_COMMAND
);
195 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_BME
);
196 PciWrite16 (IohOhciPciReg
[Index
] | R_IOH_USB_COMMAND
, CmdReg
);
198 for (Index
= 0; Index
< EhciCount
; Index
++) {
199 CmdReg
= PciRead16 (IohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
);
200 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_BME
);
201 PciWrite16 (IohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
, CmdReg
);
205 PEI_USB_CONTROLLER_PPI mUsbControllerPpi
[2] = { {GetOhciController
}, {GetEhciController
}};
208 @param FileHandle Handle of the file being invoked.
209 @param PeiServices Describes the list of possible PEI Services.
211 @retval EFI_SUCCESS PPI successfully installed
215 PeimInitializeIchUsb (
216 IN EFI_PEI_FILE_HANDLE FileHandle
,
217 IN CONST EFI_PEI_SERVICES
**PeiServices
222 EFI_PHYSICAL_ADDRESS AllocateAddress
;
223 IOH_OHCI_DEVICE
*PeiIohOhciDev
;
224 IOH_EHCI_DEVICE
*PeiIohEhciDev
;
227 Status
= PeiServicesAllocatePages (
232 ASSERT_EFI_ERROR (Status
);
236 IOH_MAX_OHCI_USB_CONTROLLERS
,
238 IOH_MAX_EHCI_USB_CONTROLLERS
241 if (FeaturePcdGet (PcdEhciRecoveryEnabled
)) {
242 DEBUG ((EFI_D_INFO
, "UsbPei:EHCI is used for recovery\n"));
244 // EHCI recovery is enabled
246 PeiIohEhciDev
= (IOH_EHCI_DEVICE
*)((UINTN
)AllocateAddress
);
247 ZeroMem (PeiIohEhciDev
, sizeof(IOH_EHCI_DEVICE
));
249 PeiIohEhciDev
->Signature
= PEI_IOH_EHCI_SIGNATURE
;
250 CopyMem(&(PeiIohEhciDev
->UsbControllerPpi
), &mUsbControllerPpi
[1], sizeof(PEI_USB_CONTROLLER_PPI
));
251 CopyMem(&(PeiIohEhciDev
->PpiList
), &mPpiList
, sizeof(mPpiList
));
252 PeiIohEhciDev
->PpiList
.Ppi
= &PeiIohEhciDev
->UsbControllerPpi
;
255 // Assign resources and enable Ehci controllers
257 for (i
= 0; i
< IOH_MAX_EHCI_USB_CONTROLLERS
; i
++) {
258 DEBUG ((EFI_D_INFO
, "UsbPei:Enable the %dth EHCI controller for recovery\n", i
));
259 PeiIohEhciDev
->MmioBase
[i
] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress
) + IOH_USB_CONTROLLER_MMIO_RANGE
* i
;
261 // Assign base address register, Enable Bus Master and Memory Io
263 PciWrite32 (mIohEhciPciReg
[i
] | R_IOH_USB_MEMBAR
, PeiIohEhciDev
->MmioBase
[i
]);
264 CmdReg
= PciRead16 (mIohEhciPciReg
[i
] | R_IOH_USB_COMMAND
);
265 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_MSE
| B_IOH_USB_COMMAND_BME
);
266 PciWrite16 (mIohEhciPciReg
[i
] | R_IOH_USB_COMMAND
, CmdReg
);
269 // Install USB Controller PPI
271 Status
= (**PeiServices
).InstallPpi (
273 &PeiIohEhciDev
->PpiList
276 ASSERT_EFI_ERROR (Status
);
278 DEBUG ((EFI_D_INFO
, "UsbPei:OHCI is used for recovery\n"));
280 // OHCI recovery is enabled
282 SwitchConfigFlag ((EFI_PEI_SERVICES
**)PeiServices
);
283 PeiIohOhciDev
= (IOH_OHCI_DEVICE
*)((UINTN
)AllocateAddress
);
284 ZeroMem (PeiIohOhciDev
, sizeof(IOH_OHCI_DEVICE
));
286 PeiIohOhciDev
->Signature
= PEI_IOH_OHCI_SIGNATURE
;
287 CopyMem(&(PeiIohOhciDev
->UsbControllerPpi
), &mUsbControllerPpi
[0], sizeof(PEI_USB_CONTROLLER_PPI
));
288 CopyMem(&(PeiIohOhciDev
->PpiList
), &mPpiList
, sizeof(mPpiList
));
289 PeiIohOhciDev
->PpiList
.Ppi
= &PeiIohOhciDev
->UsbControllerPpi
;
291 // Assign resources and enable OHCI controllers
293 for (i
= 0; i
< IOH_MAX_OHCI_USB_CONTROLLERS
; i
++) {
294 DEBUG ((EFI_D_INFO
, "UsbPei:Enable the %dth OHCI controller for recovery\n", i
));
295 PeiIohOhciDev
->MmioBase
[i
] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress
) + IOH_USB_CONTROLLER_MMIO_RANGE
* i
;
297 // Assign base address register, Enable Bus Master and Memory Io
299 PciWrite32 (mIohOhciPciReg
[i
] | R_IOH_USB_MEMBAR
, PeiIohOhciDev
->MmioBase
[i
]);
301 Status
= PeiServicesAllocatePages (
306 ASSERT_EFI_ERROR (Status
);
307 MmioWrite32(PeiIohOhciDev
->MmioBase
[i
] + R_IOH_USB_OHCI_HCCABAR
, (UINT32
)AllocateAddress
);
309 CmdReg
= PciRead16 (mIohOhciPciReg
[i
] | R_IOH_USB_COMMAND
);
310 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_MSE
| B_IOH_USB_COMMAND_BME
);
311 PciWrite16 (mIohOhciPciReg
[i
] | R_IOH_USB_COMMAND
, CmdReg
);
314 // Install USB Controller PPI
316 Status
= (**PeiServices
).InstallPpi (
318 &PeiIohOhciDev
->PpiList
321 ASSERT_EFI_ERROR (Status
);