]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c
QuarkSocPkg: Add new package for Quark SoC X1000
[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 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
10
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.
13
14 **/
15
16 #include <PiPei.h>
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>
25
26 #include "UsbPei.h"
27
28 //
29 // Globals
30 //
31 //
32
33 EFI_PEI_PPI_DESCRIPTOR mPpiList = {
34 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
35 &gPeiUsbControllerPpiGuid,
36 NULL
37 };
38
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)
41 };
42
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),
45 };
46
47 /**
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
52 in PCI memory space.
53
54 @param[in] PeiServices The pointer of EFI_PEI_SERVICES
55
56 **/
57
58 VOID
59 SwitchConfigFlag (
60 IN EFI_PEI_SERVICES **PeiServices
61 )
62 {
63 UINT32 SavBaseAddr;
64 UINT32 UsbBaseAddr;
65 UINT16 SaveCmdData;
66 UINT8 EhciCapLen;
67 UINT8 Index;
68 UsbBaseAddr = 0;
69
70 for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++) {
71 UsbBaseAddr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress);
72 //
73 // Manage EHCI on IOH, set UsbBaseAddr
74 //
75 SavBaseAddr = PciRead32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR);
76 PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, UsbBaseAddr);
77 //
78 // Save Cmd register
79 //
80 SaveCmdData = PciRead16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND);
81 //
82 // Enable EHCI on IOH
83 //
84 PciOr16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, B_IOH_USB_COMMAND_BME | B_IOH_USB_COMMAND_MSE );
85 //
86 // Clear CF register on EHCI
87 //
88 EhciCapLen = MmioRead8 (UsbBaseAddr + R_IOH_EHCI_CAPLENGTH);
89 MmioWrite32 (UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS, 0);
90
91 DEBUG ((EFI_D_INFO, "CF@EHCI = %x \n", UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS));
92 //
93 // Restore EHCI UsbBaseAddr in PCI space
94 //
95 PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, SavBaseAddr);
96 //
97 // Restore EHCI Command register in PCI space
98 //
99 PciWrite16(mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, SaveCmdData);
100 }
101 }
102 /**
103 Retrieved specified the USB controller information.
104
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
110
111 @retval EFI_SUCCESS The reset operation succeeded.
112 @retval EFI_INVALID_PARAMETER Attributes is not valid.
113
114 **/
115
116 EFI_STATUS
117 GetOhciController (
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
123 )
124 {
125 IOH_OHCI_DEVICE *PeiIohOhciDev;
126
127 PeiIohOhciDev = IOH_OHCI_DEVICE_FROM_THIS (This);
128
129 if (UsbControllerId >= IOH_MAX_OHCI_USB_CONTROLLERS) {
130 return EFI_INVALID_PARAMETER;
131 }
132 *ControllerType = PEI_OHCI_CONTROLLER;
133 *BaseAddress = PeiIohOhciDev->MmioBase[UsbControllerId];
134
135 return EFI_SUCCESS;
136 }
137 /**
138 Retrieved specified the USB controller information.
139
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
145
146 @retval EFI_SUCCESS The reset operation succeeded.
147 @retval EFI_INVALID_PARAMETER Attributes is not valid.
148
149 **/
150
151 EFI_STATUS
152 GetEhciController (
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
158 )
159 {
160 IOH_EHCI_DEVICE *PeiIohEhciDev;
161
162 PeiIohEhciDev = IOH_EHCI_DEVICE_FROM_THIS (This);
163
164 if (UsbControllerId >= IOH_MAX_EHCI_USB_CONTROLLERS) {
165 return EFI_INVALID_PARAMETER;
166 }
167 *ControllerType = PEI_EHCI_CONTROLLER;
168 *BaseAddress = PeiIohEhciDev->MmioBase[UsbControllerId];
169
170 return EFI_SUCCESS;
171 }
172
173 /**
174 Retrieved specified the USB controller information.
175
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
180
181 **/
182
183 VOID
184 EnableBusMaster (
185 IN UINTN IohOhciPciReg[],
186 IN UINT8 OhciCount,
187 IN UINTN IohEhciPciReg[],
188 IN UINT8 EhciCount
189 )
190 {
191 UINT8 Index;
192 UINT16 CmdReg;
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);
197 }
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);
202 }
203 }
204
205 PEI_USB_CONTROLLER_PPI mUsbControllerPpi[2] = { {GetOhciController}, {GetEhciController}};
206
207 /**
208 @param FileHandle Handle of the file being invoked.
209 @param PeiServices Describes the list of possible PEI Services.
210
211 @retval EFI_SUCCESS PPI successfully installed
212
213 **/
214 EFI_STATUS
215 PeimInitializeIchUsb (
216 IN EFI_PEI_FILE_HANDLE FileHandle,
217 IN CONST EFI_PEI_SERVICES **PeiServices
218 )
219 {
220 EFI_STATUS Status;
221 UINTN i;
222 EFI_PHYSICAL_ADDRESS AllocateAddress;
223 IOH_OHCI_DEVICE *PeiIohOhciDev;
224 IOH_EHCI_DEVICE *PeiIohEhciDev;
225 UINT16 CmdReg;
226
227 Status = PeiServicesAllocatePages (
228 EfiBootServicesCode,
229 1,
230 &AllocateAddress
231 );
232 ASSERT_EFI_ERROR (Status);
233
234 EnableBusMaster (
235 mIohOhciPciReg,
236 IOH_MAX_OHCI_USB_CONTROLLERS,
237 mIohEhciPciReg,
238 IOH_MAX_EHCI_USB_CONTROLLERS
239 );
240
241 if (FeaturePcdGet (PcdEhciRecoveryEnabled)) {
242 DEBUG ((EFI_D_INFO, "UsbPei:EHCI is used for recovery\n"));
243 //
244 // EHCI recovery is enabled
245 //
246 PeiIohEhciDev = (IOH_EHCI_DEVICE *)((UINTN)AllocateAddress);
247 ZeroMem (PeiIohEhciDev, sizeof(IOH_EHCI_DEVICE));
248
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;
253
254 //
255 // Assign resources and enable Ehci controllers
256 //
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;
260 //
261 // Assign base address register, Enable Bus Master and Memory Io
262 //
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);
267 }
268 //
269 // Install USB Controller PPI
270 //
271 Status = (**PeiServices).InstallPpi (
272 PeiServices,
273 &PeiIohEhciDev->PpiList
274 );
275
276 ASSERT_EFI_ERROR (Status);
277 } else {
278 DEBUG ((EFI_D_INFO, "UsbPei:OHCI is used for recovery\n"));
279 //
280 // OHCI recovery is enabled
281 //
282 SwitchConfigFlag ((EFI_PEI_SERVICES**)PeiServices);
283 PeiIohOhciDev = (IOH_OHCI_DEVICE *)((UINTN)AllocateAddress);
284 ZeroMem (PeiIohOhciDev, sizeof(IOH_OHCI_DEVICE));
285
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;
290 //
291 // Assign resources and enable OHCI controllers
292 //
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;
296 //
297 // Assign base address register, Enable Bus Master and Memory Io
298 //
299 PciWrite32 (mIohOhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohOhciDev->MmioBase[i]);
300
301 Status = PeiServicesAllocatePages (
302 EfiBootServicesCode,
303 1,
304 &AllocateAddress
305 );
306 ASSERT_EFI_ERROR (Status);
307 MmioWrite32(PeiIohOhciDev->MmioBase[i] + R_IOH_USB_OHCI_HCCABAR, (UINT32)AllocateAddress);
308
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);
312 }
313 //
314 // Install USB Controller PPI
315 //
316 Status = (**PeiServices).InstallPpi (
317 PeiServices,
318 &PeiIohOhciDev->PpiList
319 );
320
321 ASSERT_EFI_ERROR (Status);
322 }
323
324 return Status;
325 }
326