]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Usb / Common / Pei / UsbPei.c
CommitLineData
9b6bbcdb
MK
1/** @file\r
2Implementation of Usb Controller PPI.\r
3\r
4Copyright (c) 2013-2015 Intel Corporation.\r
5\r
c9f231d0 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
9b6bbcdb
MK
7\r
8**/\r
9\r
10#include <PiPei.h>\r
11#include <Ppi/UsbController.h>\r
12#include <Library/DebugLib.h>\r
13#include <Library/PeimEntryPoint.h>\r
14#include <Library/PeiServicesLib.h>\r
15#include <Library/BaseMemoryLib.h>\r
16#include <Library/PcdLib.h>\r
17#include <Library/PciLib.h>\r
18#include <Library/IoLib.h>\r
19\r
20#include "UsbPei.h"\r
21\r
22//\r
23// Globals\r
24//\r
25//\r
26\r
27EFI_PEI_PPI_DESCRIPTOR mPpiList = {\r
28 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
29 &gPeiUsbControllerPpiGuid,\r
30 NULL\r
31};\r
32\r
33UINTN mIohOhciPciReg[IOH_MAX_OHCI_USB_CONTROLLERS] = {\r
34 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_OHCI_DEVICE_NUMBER, IOH_OHCI_FUNCTION_NUMBER, 0)\r
35};\r
36\r
37UINTN mIohEhciPciReg[IOH_MAX_EHCI_USB_CONTROLLERS] = {\r
38 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, 0),\r
39};\r
40\r
41/**\r
42 When EHCI get started in DXE, OHCI couldn't get the ownership\r
43 of roothub after warm reset because CF@EHCI hasn't been cleared.\r
44 We should clear that reg before UpdateBootMode. But Reg@EHCI is\r
45 memory-mapped, so need assume a range of space without conflict\r
46 in PCI memory space.\r
47\r
48 @param[in] PeiServices The pointer of EFI_PEI_SERVICES\r
49\r
50**/\r
51\r
52VOID\r
53SwitchConfigFlag (\r
54 IN EFI_PEI_SERVICES **PeiServices\r
55 )\r
56{\r
57 UINT32 SavBaseAddr;\r
58 UINT32 UsbBaseAddr;\r
59 UINT16 SaveCmdData;\r
60 UINT8 EhciCapLen;\r
61 UINT8 Index;\r
62 UsbBaseAddr = 0;\r
63\r
64 for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++) {\r
65 UsbBaseAddr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress);\r
66 //\r
67 // Manage EHCI on IOH, set UsbBaseAddr\r
68 //\r
69 SavBaseAddr = PciRead32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR);\r
70 PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, UsbBaseAddr);\r
71 //\r
72 // Save Cmd register\r
73 //\r
74 SaveCmdData = PciRead16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND);\r
75 //\r
76 // Enable EHCI on IOH\r
77 //\r
78 PciOr16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, B_IOH_USB_COMMAND_BME | B_IOH_USB_COMMAND_MSE );\r
79 //\r
80 // Clear CF register on EHCI\r
81 //\r
82 EhciCapLen = MmioRead8 (UsbBaseAddr + R_IOH_EHCI_CAPLENGTH);\r
83 MmioWrite32 (UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS, 0);\r
84\r
85 DEBUG ((EFI_D_INFO, "CF@EHCI = %x \n", UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS));\r
86 //\r
87 // Restore EHCI UsbBaseAddr in PCI space\r
88 //\r
89 PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, SavBaseAddr);\r
90 //\r
91 // Restore EHCI Command register in PCI space\r
92 //\r
93 PciWrite16(mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, SaveCmdData);\r
94 }\r
95}\r
96/**\r
97 Retrieved specified the USB controller information.\r
98\r
99 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
100 @param This This PEI_USB_CONTROLLER_PPI instance.\r
101 @param UsbControllerId Indicate which usb controller information will be retrieved.\r
102 @param ControllerType Indicate the controller is Ehci, Ohci, OHCI\r
103 @param BaseAddress Indicate the memory bar of the controller\r
104\r
105 @retval EFI_SUCCESS The reset operation succeeded.\r
106 @retval EFI_INVALID_PARAMETER Attributes is not valid.\r
107\r
108**/\r
109\r
110EFI_STATUS\r
111GetOhciController (\r
112 IN EFI_PEI_SERVICES **PeiServices,\r
113 IN PEI_USB_CONTROLLER_PPI *This,\r
114 IN UINT8 UsbControllerId,\r
115 IN UINTN *ControllerType,\r
116 IN UINTN *BaseAddress\r
117 )\r
118{\r
119 IOH_OHCI_DEVICE *PeiIohOhciDev;\r
120\r
121 PeiIohOhciDev = IOH_OHCI_DEVICE_FROM_THIS (This);\r
122\r
123 if (UsbControllerId >= IOH_MAX_OHCI_USB_CONTROLLERS) {\r
124 return EFI_INVALID_PARAMETER;\r
125 }\r
126 *ControllerType = PEI_OHCI_CONTROLLER;\r
127 *BaseAddress = PeiIohOhciDev->MmioBase[UsbControllerId];\r
128\r
129 return EFI_SUCCESS;\r
130}\r
131/**\r
132 Retrieved specified the USB controller information.\r
133\r
134 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
135 @param This This PEI_USB_CONTROLLER_PPI instance.\r
136 @param UsbControllerId Indicate which usb controller information will be retrieved.\r
137 @param ControllerType Indicate the controller is Ehci, Ohci, OHCI\r
138 @param BaseAddress Indicate the memory bar of the controller\r
139\r
140 @retval EFI_SUCCESS The reset operation succeeded.\r
141 @retval EFI_INVALID_PARAMETER Attributes is not valid.\r
142\r
143**/\r
144\r
145EFI_STATUS\r
146GetEhciController (\r
147 IN EFI_PEI_SERVICES **PeiServices,\r
148 IN PEI_USB_CONTROLLER_PPI *This,\r
149 IN UINT8 UsbControllerId,\r
150 IN UINTN *ControllerType,\r
151 IN UINTN *BaseAddress\r
152 )\r
153{\r
154 IOH_EHCI_DEVICE *PeiIohEhciDev;\r
155\r
156 PeiIohEhciDev = IOH_EHCI_DEVICE_FROM_THIS (This);\r
157\r
158 if (UsbControllerId >= IOH_MAX_EHCI_USB_CONTROLLERS) {\r
159 return EFI_INVALID_PARAMETER;\r
160 }\r
161 *ControllerType = PEI_EHCI_CONTROLLER;\r
162 *BaseAddress = PeiIohEhciDev->MmioBase[UsbControllerId];\r
163\r
164 return EFI_SUCCESS;\r
165}\r
166\r
167/**\r
168 Retrieved specified the USB controller information.\r
169\r
170 @param IohOhciPciReg Ohci device address list.\r
171 @param OhciCount The count of the OHCI\r
172 @param IohEhciPciReg Ehci device address list.\r
173 @param EhciCount The count of the EHCI\r
174\r
175**/\r
176\r
177VOID\r
178EnableBusMaster (\r
179 IN UINTN IohOhciPciReg[],\r
180 IN UINT8 OhciCount,\r
181 IN UINTN IohEhciPciReg[],\r
182 IN UINT8 EhciCount\r
183 )\r
184{\r
185 UINT8 Index;\r
186 UINT16 CmdReg;\r
187 for (Index = 0; Index < OhciCount; Index ++) {\r
188 CmdReg = PciRead16 (IohOhciPciReg[Index] | R_IOH_USB_COMMAND);\r
189 CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_BME );\r
190 PciWrite16 (IohOhciPciReg[Index] | R_IOH_USB_COMMAND, CmdReg);\r
191 }\r
192 for (Index = 0; Index < EhciCount; Index ++) {\r
193 CmdReg = PciRead16 (IohEhciPciReg[Index] | R_IOH_USB_COMMAND);\r
194 CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_BME );\r
195 PciWrite16 (IohEhciPciReg[Index] | R_IOH_USB_COMMAND, CmdReg);\r
196 }\r
197}\r
198\r
199PEI_USB_CONTROLLER_PPI mUsbControllerPpi[2] = { {GetOhciController}, {GetEhciController}};\r
200\r
201/**\r
202 @param FileHandle Handle of the file being invoked.\r
203 @param PeiServices Describes the list of possible PEI Services.\r
204\r
205 @retval EFI_SUCCESS PPI successfully installed\r
206\r
207**/\r
208EFI_STATUS\r
209PeimInitializeIchUsb (\r
210 IN EFI_PEI_FILE_HANDLE FileHandle,\r
211 IN CONST EFI_PEI_SERVICES **PeiServices\r
212 )\r
213{\r
214 EFI_STATUS Status;\r
215 UINTN i;\r
216 EFI_PHYSICAL_ADDRESS AllocateAddress;\r
217 IOH_OHCI_DEVICE *PeiIohOhciDev;\r
218 IOH_EHCI_DEVICE *PeiIohEhciDev;\r
219 UINT16 CmdReg;\r
220\r
221 Status = PeiServicesAllocatePages (\r
222 EfiBootServicesCode,\r
223 1,\r
224 &AllocateAddress\r
225 );\r
226 ASSERT_EFI_ERROR (Status);\r
227\r
228 EnableBusMaster (\r
229 mIohOhciPciReg,\r
230 IOH_MAX_OHCI_USB_CONTROLLERS,\r
231 mIohEhciPciReg,\r
232 IOH_MAX_EHCI_USB_CONTROLLERS\r
233 );\r
234\r
235 if (FeaturePcdGet (PcdEhciRecoveryEnabled)) {\r
236 DEBUG ((EFI_D_INFO, "UsbPei:EHCI is used for recovery\n"));\r
237 //\r
238 // EHCI recovery is enabled\r
239 //\r
240 PeiIohEhciDev = (IOH_EHCI_DEVICE *)((UINTN)AllocateAddress);\r
241 ZeroMem (PeiIohEhciDev, sizeof(IOH_EHCI_DEVICE));\r
242\r
243 PeiIohEhciDev->Signature = PEI_IOH_EHCI_SIGNATURE;\r
244 CopyMem(&(PeiIohEhciDev->UsbControllerPpi), &mUsbControllerPpi[1], sizeof(PEI_USB_CONTROLLER_PPI));\r
245 CopyMem(&(PeiIohEhciDev->PpiList), &mPpiList, sizeof(mPpiList));\r
246 PeiIohEhciDev->PpiList.Ppi = &PeiIohEhciDev->UsbControllerPpi;\r
247\r
248 //\r
249 // Assign resources and enable Ehci controllers\r
250 //\r
251 for (i = 0; i < IOH_MAX_EHCI_USB_CONTROLLERS; i++) {\r
252 DEBUG ((EFI_D_INFO, "UsbPei:Enable the %dth EHCI controller for recovery\n", i));\r
253 PeiIohEhciDev->MmioBase[i] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress) + IOH_USB_CONTROLLER_MMIO_RANGE * i;\r
254 //\r
255 // Assign base address register, Enable Bus Master and Memory Io\r
256 //\r
257 PciWrite32 (mIohEhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohEhciDev->MmioBase[i]);\r
258 CmdReg = PciRead16 (mIohEhciPciReg[i] | R_IOH_USB_COMMAND);\r
259 CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_MSE | B_IOH_USB_COMMAND_BME );\r
260 PciWrite16 (mIohEhciPciReg[i] | R_IOH_USB_COMMAND, CmdReg);\r
261 }\r
262 //\r
263 // Install USB Controller PPI\r
264 //\r
265 Status = (**PeiServices).InstallPpi (\r
266 PeiServices,\r
267 &PeiIohEhciDev->PpiList\r
268 );\r
269\r
270 ASSERT_EFI_ERROR (Status);\r
271 } else {\r
272 DEBUG ((EFI_D_INFO, "UsbPei:OHCI is used for recovery\n"));\r
273 //\r
274 // OHCI recovery is enabled\r
275 //\r
276 SwitchConfigFlag ((EFI_PEI_SERVICES**)PeiServices);\r
277 PeiIohOhciDev = (IOH_OHCI_DEVICE *)((UINTN)AllocateAddress);\r
278 ZeroMem (PeiIohOhciDev, sizeof(IOH_OHCI_DEVICE));\r
279\r
280 PeiIohOhciDev->Signature = PEI_IOH_OHCI_SIGNATURE;\r
281 CopyMem(&(PeiIohOhciDev->UsbControllerPpi), &mUsbControllerPpi[0], sizeof(PEI_USB_CONTROLLER_PPI));\r
282 CopyMem(&(PeiIohOhciDev->PpiList), &mPpiList, sizeof(mPpiList));\r
283 PeiIohOhciDev->PpiList.Ppi = &PeiIohOhciDev->UsbControllerPpi;\r
284 //\r
285 // Assign resources and enable OHCI controllers\r
286 //\r
287 for (i = 0; i < IOH_MAX_OHCI_USB_CONTROLLERS; i++) {\r
288 DEBUG ((EFI_D_INFO, "UsbPei:Enable the %dth OHCI controller for recovery\n", i));\r
289 PeiIohOhciDev->MmioBase[i] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress) + IOH_USB_CONTROLLER_MMIO_RANGE * i;\r
290 //\r
291 // Assign base address register, Enable Bus Master and Memory Io\r
292 //\r
293 PciWrite32 (mIohOhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohOhciDev->MmioBase[i]);\r
294\r
295 Status = PeiServicesAllocatePages (\r
296 EfiBootServicesCode,\r
297 1,\r
298 &AllocateAddress\r
299 );\r
300 ASSERT_EFI_ERROR (Status);\r
301 MmioWrite32(PeiIohOhciDev->MmioBase[i] + R_IOH_USB_OHCI_HCCABAR, (UINT32)AllocateAddress);\r
302\r
303 CmdReg = PciRead16 (mIohOhciPciReg[i] | R_IOH_USB_COMMAND);\r
304 CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_MSE | B_IOH_USB_COMMAND_BME );\r
305 PciWrite16 (mIohOhciPciReg[i] | R_IOH_USB_COMMAND, CmdReg);\r
306 }\r
307 //\r
308 // Install USB Controller PPI\r
309 //\r
310 Status = (**PeiServices).InstallPpi (\r
311 PeiServices,\r
312 &PeiIohOhciDev->PpiList\r
313 );\r
314\r
315 ASSERT_EFI_ERROR (Status);\r
316 }\r
317\r
318 return Status;\r
319}\r
320\r