]>
Commit | Line | Data |
---|---|---|
9b6bbcdb MK |
1 | /** @file\r |
2 | Implementation of Usb Controller PPI.\r | |
3 | \r | |
4 | Copyright (c) 2013-2015 Intel Corporation.\r | |
5 | \r | |
c9f231d0 | 6 | SPDX-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 | |
27 | EFI_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 | |
33 | UINTN 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 | |
37 | UINTN 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 | |
52 | VOID\r | |
53 | SwitchConfigFlag (\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 | |
110 | EFI_STATUS\r | |
111 | GetOhciController (\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 | |
145 | EFI_STATUS\r | |
146 | GetEhciController (\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 | |
177 | VOID\r | |
178 | EnableBusMaster (\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 | |
199 | PEI_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 | |
208 | EFI_STATUS\r | |
209 | PeimInitializeIchUsb (\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 |