2 Implementation of Usb Controller PPI.
4 Copyright (c) 2013-2015 Intel Corporation.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Ppi/UsbController.h>
12 #include <Library/DebugLib.h>
13 #include <Library/PeimEntryPoint.h>
14 #include <Library/PeiServicesLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/PcdLib.h>
17 #include <Library/PciLib.h>
18 #include <Library/IoLib.h>
27 EFI_PEI_PPI_DESCRIPTOR mPpiList
= {
28 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
29 &gPeiUsbControllerPpiGuid
,
33 UINTN mIohOhciPciReg
[IOH_MAX_OHCI_USB_CONTROLLERS
] = {
34 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER
, IOH_USB_OHCI_DEVICE_NUMBER
, IOH_OHCI_FUNCTION_NUMBER
, 0)
37 UINTN mIohEhciPciReg
[IOH_MAX_EHCI_USB_CONTROLLERS
] = {
38 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER
, IOH_USB_EHCI_DEVICE_NUMBER
, IOH_EHCI_FUNCTION_NUMBER
, 0),
42 When EHCI get started in DXE, OHCI couldn't get the ownership
43 of roothub after warm reset because CF@EHCI hasn't been cleared.
44 We should clear that reg before UpdateBootMode. But Reg@EHCI is
45 memory-mapped, so need assume a range of space without conflict
48 @param[in] PeiServices The pointer of EFI_PEI_SERVICES
54 IN EFI_PEI_SERVICES
**PeiServices
64 for (Index
= 0; Index
< IOH_MAX_EHCI_USB_CONTROLLERS
; Index
++) {
65 UsbBaseAddr
= PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress
);
67 // Manage EHCI on IOH, set UsbBaseAddr
69 SavBaseAddr
= PciRead32 (mIohEhciPciReg
[Index
] | R_IOH_USB_MEMBAR
);
70 PciWrite32 (mIohEhciPciReg
[Index
] | R_IOH_USB_MEMBAR
, UsbBaseAddr
);
74 SaveCmdData
= PciRead16 (mIohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
);
78 PciOr16 (mIohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
, B_IOH_USB_COMMAND_BME
| B_IOH_USB_COMMAND_MSE
);
80 // Clear CF register on EHCI
82 EhciCapLen
= MmioRead8 (UsbBaseAddr
+ R_IOH_EHCI_CAPLENGTH
);
83 MmioWrite32 (UsbBaseAddr
+ EhciCapLen
+ R_IOH_EHCI_CONFIGFLAGS
, 0);
85 DEBUG ((EFI_D_INFO
, "CF@EHCI = %x \n", UsbBaseAddr
+ EhciCapLen
+ R_IOH_EHCI_CONFIGFLAGS
));
87 // Restore EHCI UsbBaseAddr in PCI space
89 PciWrite32 (mIohEhciPciReg
[Index
] | R_IOH_USB_MEMBAR
, SavBaseAddr
);
91 // Restore EHCI Command register in PCI space
93 PciWrite16(mIohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
, SaveCmdData
);
97 Retrieved specified the USB controller information.
99 @param PeiServices The pointer of EFI_PEI_SERVICES.
100 @param This This PEI_USB_CONTROLLER_PPI instance.
101 @param UsbControllerId Indicate which usb controller information will be retrieved.
102 @param ControllerType Indicate the controller is Ehci, Ohci, OHCI
103 @param BaseAddress Indicate the memory bar of the controller
105 @retval EFI_SUCCESS The reset operation succeeded.
106 @retval EFI_INVALID_PARAMETER Attributes is not valid.
112 IN EFI_PEI_SERVICES
**PeiServices
,
113 IN PEI_USB_CONTROLLER_PPI
*This
,
114 IN UINT8 UsbControllerId
,
115 IN UINTN
*ControllerType
,
116 IN UINTN
*BaseAddress
119 IOH_OHCI_DEVICE
*PeiIohOhciDev
;
121 PeiIohOhciDev
= IOH_OHCI_DEVICE_FROM_THIS (This
);
123 if (UsbControllerId
>= IOH_MAX_OHCI_USB_CONTROLLERS
) {
124 return EFI_INVALID_PARAMETER
;
126 *ControllerType
= PEI_OHCI_CONTROLLER
;
127 *BaseAddress
= PeiIohOhciDev
->MmioBase
[UsbControllerId
];
132 Retrieved specified the USB controller information.
134 @param PeiServices The pointer of EFI_PEI_SERVICES.
135 @param This This PEI_USB_CONTROLLER_PPI instance.
136 @param UsbControllerId Indicate which usb controller information will be retrieved.
137 @param ControllerType Indicate the controller is Ehci, Ohci, OHCI
138 @param BaseAddress Indicate the memory bar of the controller
140 @retval EFI_SUCCESS The reset operation succeeded.
141 @retval EFI_INVALID_PARAMETER Attributes is not valid.
147 IN EFI_PEI_SERVICES
**PeiServices
,
148 IN PEI_USB_CONTROLLER_PPI
*This
,
149 IN UINT8 UsbControllerId
,
150 IN UINTN
*ControllerType
,
151 IN UINTN
*BaseAddress
154 IOH_EHCI_DEVICE
*PeiIohEhciDev
;
156 PeiIohEhciDev
= IOH_EHCI_DEVICE_FROM_THIS (This
);
158 if (UsbControllerId
>= IOH_MAX_EHCI_USB_CONTROLLERS
) {
159 return EFI_INVALID_PARAMETER
;
161 *ControllerType
= PEI_EHCI_CONTROLLER
;
162 *BaseAddress
= PeiIohEhciDev
->MmioBase
[UsbControllerId
];
168 Retrieved specified the USB controller information.
170 @param IohOhciPciReg Ohci device address list.
171 @param OhciCount The count of the OHCI
172 @param IohEhciPciReg Ehci device address list.
173 @param EhciCount The count of the EHCI
179 IN UINTN IohOhciPciReg
[],
181 IN UINTN IohEhciPciReg
[],
187 for (Index
= 0; Index
< OhciCount
; Index
++) {
188 CmdReg
= PciRead16 (IohOhciPciReg
[Index
] | R_IOH_USB_COMMAND
);
189 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_BME
);
190 PciWrite16 (IohOhciPciReg
[Index
] | R_IOH_USB_COMMAND
, CmdReg
);
192 for (Index
= 0; Index
< EhciCount
; Index
++) {
193 CmdReg
= PciRead16 (IohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
);
194 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_BME
);
195 PciWrite16 (IohEhciPciReg
[Index
] | R_IOH_USB_COMMAND
, CmdReg
);
199 PEI_USB_CONTROLLER_PPI mUsbControllerPpi
[2] = { {GetOhciController
}, {GetEhciController
}};
202 @param FileHandle Handle of the file being invoked.
203 @param PeiServices Describes the list of possible PEI Services.
205 @retval EFI_SUCCESS PPI successfully installed
209 PeimInitializeIchUsb (
210 IN EFI_PEI_FILE_HANDLE FileHandle
,
211 IN CONST EFI_PEI_SERVICES
**PeiServices
216 EFI_PHYSICAL_ADDRESS AllocateAddress
;
217 IOH_OHCI_DEVICE
*PeiIohOhciDev
;
218 IOH_EHCI_DEVICE
*PeiIohEhciDev
;
221 Status
= PeiServicesAllocatePages (
226 ASSERT_EFI_ERROR (Status
);
230 IOH_MAX_OHCI_USB_CONTROLLERS
,
232 IOH_MAX_EHCI_USB_CONTROLLERS
235 if (FeaturePcdGet (PcdEhciRecoveryEnabled
)) {
236 DEBUG ((EFI_D_INFO
, "UsbPei:EHCI is used for recovery\n"));
238 // EHCI recovery is enabled
240 PeiIohEhciDev
= (IOH_EHCI_DEVICE
*)((UINTN
)AllocateAddress
);
241 ZeroMem (PeiIohEhciDev
, sizeof(IOH_EHCI_DEVICE
));
243 PeiIohEhciDev
->Signature
= PEI_IOH_EHCI_SIGNATURE
;
244 CopyMem(&(PeiIohEhciDev
->UsbControllerPpi
), &mUsbControllerPpi
[1], sizeof(PEI_USB_CONTROLLER_PPI
));
245 CopyMem(&(PeiIohEhciDev
->PpiList
), &mPpiList
, sizeof(mPpiList
));
246 PeiIohEhciDev
->PpiList
.Ppi
= &PeiIohEhciDev
->UsbControllerPpi
;
249 // Assign resources and enable Ehci controllers
251 for (i
= 0; i
< IOH_MAX_EHCI_USB_CONTROLLERS
; i
++) {
252 DEBUG ((EFI_D_INFO
, "UsbPei:Enable the %dth EHCI controller for recovery\n", i
));
253 PeiIohEhciDev
->MmioBase
[i
] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress
) + IOH_USB_CONTROLLER_MMIO_RANGE
* i
;
255 // Assign base address register, Enable Bus Master and Memory Io
257 PciWrite32 (mIohEhciPciReg
[i
] | R_IOH_USB_MEMBAR
, PeiIohEhciDev
->MmioBase
[i
]);
258 CmdReg
= PciRead16 (mIohEhciPciReg
[i
] | R_IOH_USB_COMMAND
);
259 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_MSE
| B_IOH_USB_COMMAND_BME
);
260 PciWrite16 (mIohEhciPciReg
[i
] | R_IOH_USB_COMMAND
, CmdReg
);
263 // Install USB Controller PPI
265 Status
= (**PeiServices
).InstallPpi (
267 &PeiIohEhciDev
->PpiList
270 ASSERT_EFI_ERROR (Status
);
272 DEBUG ((EFI_D_INFO
, "UsbPei:OHCI is used for recovery\n"));
274 // OHCI recovery is enabled
276 SwitchConfigFlag ((EFI_PEI_SERVICES
**)PeiServices
);
277 PeiIohOhciDev
= (IOH_OHCI_DEVICE
*)((UINTN
)AllocateAddress
);
278 ZeroMem (PeiIohOhciDev
, sizeof(IOH_OHCI_DEVICE
));
280 PeiIohOhciDev
->Signature
= PEI_IOH_OHCI_SIGNATURE
;
281 CopyMem(&(PeiIohOhciDev
->UsbControllerPpi
), &mUsbControllerPpi
[0], sizeof(PEI_USB_CONTROLLER_PPI
));
282 CopyMem(&(PeiIohOhciDev
->PpiList
), &mPpiList
, sizeof(mPpiList
));
283 PeiIohOhciDev
->PpiList
.Ppi
= &PeiIohOhciDev
->UsbControllerPpi
;
285 // Assign resources and enable OHCI controllers
287 for (i
= 0; i
< IOH_MAX_OHCI_USB_CONTROLLERS
; i
++) {
288 DEBUG ((EFI_D_INFO
, "UsbPei:Enable the %dth OHCI controller for recovery\n", i
));
289 PeiIohOhciDev
->MmioBase
[i
] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress
) + IOH_USB_CONTROLLER_MMIO_RANGE
* i
;
291 // Assign base address register, Enable Bus Master and Memory Io
293 PciWrite32 (mIohOhciPciReg
[i
] | R_IOH_USB_MEMBAR
, PeiIohOhciDev
->MmioBase
[i
]);
295 Status
= PeiServicesAllocatePages (
300 ASSERT_EFI_ERROR (Status
);
301 MmioWrite32(PeiIohOhciDev
->MmioBase
[i
] + R_IOH_USB_OHCI_HCCABAR
, (UINT32
)AllocateAddress
);
303 CmdReg
= PciRead16 (mIohOhciPciReg
[i
] | R_IOH_USB_COMMAND
);
304 CmdReg
= (UINT16
) (CmdReg
| B_IOH_USB_COMMAND_MSE
| B_IOH_USB_COMMAND_BME
);
305 PciWrite16 (mIohOhciPciReg
[i
] | R_IOH_USB_COMMAND
, CmdReg
);
308 // Install USB Controller PPI
310 Status
= (**PeiServices
).InstallPpi (
312 &PeiIohOhciDev
->PpiList
315 ASSERT_EFI_ERROR (Status
);