]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
f393aa8643f08ebb27327a9fda2df077dc5ff14b
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Usb / Common / Pei / UsbPei.c
1 /** @file
2 Implementation of Usb Controller PPI.
3
4 Copyright (c) 2013-2015 Intel Corporation.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiPei.h>
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>
19
20 #include "UsbPei.h"
21
22 //
23 // Globals
24 //
25 //
26
27 EFI_PEI_PPI_DESCRIPTOR mPpiList = {
28 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
29 &gPeiUsbControllerPpiGuid,
30 NULL
31 };
32
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)
35 };
36
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),
39 };
40
41 /**
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
46 in PCI memory space.
47
48 @param[in] PeiServices The pointer of EFI_PEI_SERVICES
49
50 **/
51
52 VOID
53 SwitchConfigFlag (
54 IN EFI_PEI_SERVICES **PeiServices
55 )
56 {
57 UINT32 SavBaseAddr;
58 UINT32 UsbBaseAddr;
59 UINT16 SaveCmdData;
60 UINT8 EhciCapLen;
61 UINT8 Index;
62 UsbBaseAddr = 0;
63
64 for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++) {
65 UsbBaseAddr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress);
66 //
67 // Manage EHCI on IOH, set UsbBaseAddr
68 //
69 SavBaseAddr = PciRead32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR);
70 PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, UsbBaseAddr);
71 //
72 // Save Cmd register
73 //
74 SaveCmdData = PciRead16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND);
75 //
76 // Enable EHCI on IOH
77 //
78 PciOr16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, B_IOH_USB_COMMAND_BME | B_IOH_USB_COMMAND_MSE );
79 //
80 // Clear CF register on EHCI
81 //
82 EhciCapLen = MmioRead8 (UsbBaseAddr + R_IOH_EHCI_CAPLENGTH);
83 MmioWrite32 (UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS, 0);
84
85 DEBUG ((EFI_D_INFO, "CF@EHCI = %x \n", UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS));
86 //
87 // Restore EHCI UsbBaseAddr in PCI space
88 //
89 PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, SavBaseAddr);
90 //
91 // Restore EHCI Command register in PCI space
92 //
93 PciWrite16(mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, SaveCmdData);
94 }
95 }
96 /**
97 Retrieved specified the USB controller information.
98
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
104
105 @retval EFI_SUCCESS The reset operation succeeded.
106 @retval EFI_INVALID_PARAMETER Attributes is not valid.
107
108 **/
109
110 EFI_STATUS
111 GetOhciController (
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
117 )
118 {
119 IOH_OHCI_DEVICE *PeiIohOhciDev;
120
121 PeiIohOhciDev = IOH_OHCI_DEVICE_FROM_THIS (This);
122
123 if (UsbControllerId >= IOH_MAX_OHCI_USB_CONTROLLERS) {
124 return EFI_INVALID_PARAMETER;
125 }
126 *ControllerType = PEI_OHCI_CONTROLLER;
127 *BaseAddress = PeiIohOhciDev->MmioBase[UsbControllerId];
128
129 return EFI_SUCCESS;
130 }
131 /**
132 Retrieved specified the USB controller information.
133
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
139
140 @retval EFI_SUCCESS The reset operation succeeded.
141 @retval EFI_INVALID_PARAMETER Attributes is not valid.
142
143 **/
144
145 EFI_STATUS
146 GetEhciController (
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
152 )
153 {
154 IOH_EHCI_DEVICE *PeiIohEhciDev;
155
156 PeiIohEhciDev = IOH_EHCI_DEVICE_FROM_THIS (This);
157
158 if (UsbControllerId >= IOH_MAX_EHCI_USB_CONTROLLERS) {
159 return EFI_INVALID_PARAMETER;
160 }
161 *ControllerType = PEI_EHCI_CONTROLLER;
162 *BaseAddress = PeiIohEhciDev->MmioBase[UsbControllerId];
163
164 return EFI_SUCCESS;
165 }
166
167 /**
168 Retrieved specified the USB controller information.
169
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
174
175 **/
176
177 VOID
178 EnableBusMaster (
179 IN UINTN IohOhciPciReg[],
180 IN UINT8 OhciCount,
181 IN UINTN IohEhciPciReg[],
182 IN UINT8 EhciCount
183 )
184 {
185 UINT8 Index;
186 UINT16 CmdReg;
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);
191 }
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);
196 }
197 }
198
199 PEI_USB_CONTROLLER_PPI mUsbControllerPpi[2] = { {GetOhciController}, {GetEhciController}};
200
201 /**
202 @param FileHandle Handle of the file being invoked.
203 @param PeiServices Describes the list of possible PEI Services.
204
205 @retval EFI_SUCCESS PPI successfully installed
206
207 **/
208 EFI_STATUS
209 PeimInitializeIchUsb (
210 IN EFI_PEI_FILE_HANDLE FileHandle,
211 IN CONST EFI_PEI_SERVICES **PeiServices
212 )
213 {
214 EFI_STATUS Status;
215 UINTN i;
216 EFI_PHYSICAL_ADDRESS AllocateAddress;
217 IOH_OHCI_DEVICE *PeiIohOhciDev;
218 IOH_EHCI_DEVICE *PeiIohEhciDev;
219 UINT16 CmdReg;
220
221 Status = PeiServicesAllocatePages (
222 EfiBootServicesCode,
223 1,
224 &AllocateAddress
225 );
226 ASSERT_EFI_ERROR (Status);
227
228 EnableBusMaster (
229 mIohOhciPciReg,
230 IOH_MAX_OHCI_USB_CONTROLLERS,
231 mIohEhciPciReg,
232 IOH_MAX_EHCI_USB_CONTROLLERS
233 );
234
235 if (FeaturePcdGet (PcdEhciRecoveryEnabled)) {
236 DEBUG ((EFI_D_INFO, "UsbPei:EHCI is used for recovery\n"));
237 //
238 // EHCI recovery is enabled
239 //
240 PeiIohEhciDev = (IOH_EHCI_DEVICE *)((UINTN)AllocateAddress);
241 ZeroMem (PeiIohEhciDev, sizeof(IOH_EHCI_DEVICE));
242
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;
247
248 //
249 // Assign resources and enable Ehci controllers
250 //
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;
254 //
255 // Assign base address register, Enable Bus Master and Memory Io
256 //
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);
261 }
262 //
263 // Install USB Controller PPI
264 //
265 Status = (**PeiServices).InstallPpi (
266 PeiServices,
267 &PeiIohEhciDev->PpiList
268 );
269
270 ASSERT_EFI_ERROR (Status);
271 } else {
272 DEBUG ((EFI_D_INFO, "UsbPei:OHCI is used for recovery\n"));
273 //
274 // OHCI recovery is enabled
275 //
276 SwitchConfigFlag ((EFI_PEI_SERVICES**)PeiServices);
277 PeiIohOhciDev = (IOH_OHCI_DEVICE *)((UINTN)AllocateAddress);
278 ZeroMem (PeiIohOhciDev, sizeof(IOH_OHCI_DEVICE));
279
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;
284 //
285 // Assign resources and enable OHCI controllers
286 //
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;
290 //
291 // Assign base address register, Enable Bus Master and Memory Io
292 //
293 PciWrite32 (mIohOhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohOhciDev->MmioBase[i]);
294
295 Status = PeiServicesAllocatePages (
296 EfiBootServicesCode,
297 1,
298 &AllocateAddress
299 );
300 ASSERT_EFI_ERROR (Status);
301 MmioWrite32(PeiIohOhciDev->MmioBase[i] + R_IOH_USB_OHCI_HCCABAR, (UINT32)AllocateAddress);
302
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);
306 }
307 //
308 // Install USB Controller PPI
309 //
310 Status = (**PeiServices).InstallPpi (
311 PeiServices,
312 &PeiIohOhciDev->PpiList
313 );
314
315 ASSERT_EFI_ERROR (Status);
316 }
317
318 return Status;
319 }
320