]> git.proxmox.com Git - mirror_edk2.git/blame - Omap35xxPkg/PciEmulation/PciEmulation.c
ARM Packages: Removed trailing spaces
[mirror_edk2.git] / Omap35xxPkg / PciEmulation / PciEmulation.c
CommitLineData
1e57a462 1/** @file\r
2\r
3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
3402aac7 4\r
1e57a462 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "PciEmulation.h"\r
16\r
17EMBEDDED_EXTERNAL_DEVICE *gTPS65950;\r
18\r
19#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44\r
20\r
21typedef struct {\r
22 ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
23 PCI_DEVICE_PATH PciDevicePath;\r
24 EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
25} EFI_PCI_IO_DEVICE_PATH;\r
26\r
27typedef struct {\r
28 UINT32 Signature;\r
29 EFI_PCI_IO_DEVICE_PATH DevicePath;\r
30 EFI_PCI_IO_PROTOCOL PciIoProtocol;\r
31 PCI_TYPE00 *ConfigSpace;\r
32 PCI_ROOT_BRIDGE RootBridge;\r
33 UINTN Segment;\r
34} EFI_PCI_IO_PRIVATE_DATA;\r
35\r
36#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o')\r
37#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE)\r
38\r
3402aac7 39EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate =\r
1e57a462 40{\r
41 {\r
b0fdce95 42 { ACPI_DEVICE_PATH, ACPI_DP, { sizeof (ACPI_HID_DEVICE_PATH), 0 } },\r
1e57a462 43 EISA_PNP_ID(0x0A03), // HID\r
44 0 // UID\r
45 },\r
46 {\r
b0fdce95 47 { HARDWARE_DEVICE_PATH, HW_PCI_DP, { sizeof (PCI_DEVICE_PATH), 0 } },\r
1e57a462 48 0,\r
49 0\r
50 },\r
b0fdce95 51 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} }\r
1e57a462 52};\r
53\r
54STATIC\r
55VOID\r
56ConfigureUSBHost (\r
57 VOID\r
58 )\r
59{\r
60 EFI_STATUS Status;\r
61 UINT8 Data = 0;\r
62\r
63 // Take USB host out of force-standby mode\r
64 MmioWrite32 (UHH_SYSCONFIG, UHH_SYSCONFIG_MIDLEMODE_NO_STANDBY\r
65 | UHH_SYSCONFIG_CLOCKACTIVITY_ON\r
66 | UHH_SYSCONFIG_SIDLEMODE_NO_STANDBY\r
67 | UHH_SYSCONFIG_ENAWAKEUP_ENABLE\r
68 | UHH_SYSCONFIG_AUTOIDLE_ALWAYS_RUN);\r
69 MmioWrite32 (UHH_HOSTCONFIG, UHH_HOSTCONFIG_P3_CONNECT_STATUS_DISCONNECT\r
70 | UHH_HOSTCONFIG_P2_CONNECT_STATUS_DISCONNECT\r
71 | UHH_HOSTCONFIG_P1_CONNECT_STATUS_DISCONNECT\r
72 | UHH_HOSTCONFIG_ENA_INCR_ALIGN_DISABLE\r
73 | UHH_HOSTCONFIG_ENA_INCR16_ENABLE\r
74 | UHH_HOSTCONFIG_ENA_INCR8_ENABLE\r
75 | UHH_HOSTCONFIG_ENA_INCR4_ENABLE\r
76 | UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN_ON\r
77 | UHH_HOSTCONFIG_P1_ULPI_BYPASS_ULPI_MODE);\r
78\r
79 // USB reset (GPIO 147 - Port 5 pin 19) output high\r
80 MmioAnd32 (GPIO5_BASE + GPIO_OE, ~BIT19);\r
81 MmioWrite32 (GPIO5_BASE + GPIO_SETDATAOUT, BIT19);\r
82\r
83 // Get the Power IC protocol\r
84 Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);\r
3402aac7 85 ASSERT_EFI_ERROR (Status);\r
1e57a462 86\r
87 // Power the USB PHY\r
88 Data = VAUX_DEV_GRP_P1;\r
89 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEV_GRP), 1, &Data);\r
90 ASSERT_EFI_ERROR(Status);\r
91\r
92 Data = VAUX_DEDICATED_18V;\r
93 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEDICATED), 1, &Data);\r
3402aac7 94 ASSERT_EFI_ERROR (Status);\r
1e57a462 95\r
96 // Enable power to the USB hub\r
97 Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data);\r
98 ASSERT_EFI_ERROR (Status);\r
99\r
100 // LEDAON controls the power to the USB host, PWM is disabled\r
101 Data &= ~LEDAPWM;\r
102 Data |= LEDAON;\r
103\r
104 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data);\r
105 ASSERT_EFI_ERROR (Status);\r
106}\r
107\r
108\r
109EFI_STATUS\r
110PciIoPollMem (\r
111 IN EFI_PCI_IO_PROTOCOL *This,\r
112 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
113 IN UINT8 BarIndex,\r
114 IN UINT64 Offset,\r
115 IN UINT64 Mask,\r
116 IN UINT64 Value,\r
117 IN UINT64 Delay,\r
118 OUT UINT64 *Result\r
119 )\r
120{\r
121 ASSERT (FALSE);\r
122 return EFI_UNSUPPORTED;\r
123}\r
124\r
125EFI_STATUS\r
126PciIoPollIo (\r
127 IN EFI_PCI_IO_PROTOCOL *This,\r
128 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
129 IN UINT8 BarIndex,\r
130 IN UINT64 Offset,\r
131 IN UINT64 Mask,\r
132 IN UINT64 Value,\r
133 IN UINT64 Delay,\r
134 OUT UINT64 *Result\r
135 )\r
136{\r
137 ASSERT (FALSE);\r
138 return EFI_UNSUPPORTED;\r
139}\r
140\r
141EFI_STATUS\r
142PciIoMemRead (\r
143 IN EFI_PCI_IO_PROTOCOL *This,\r
144 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
145 IN UINT8 BarIndex,\r
146 IN UINT64 Offset,\r
147 IN UINTN Count,\r
148 IN OUT VOID *Buffer\r
149 )\r
150{\r
151 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
152\r
3402aac7 153 return PciRootBridgeIoMemRead (&Private->RootBridge.Io,\r
1e57a462 154 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
155 Private->ConfigSpace->Device.Bar[BarIndex] + Offset,\r
156 Count,\r
157 Buffer\r
158 );\r
159}\r
160\r
161EFI_STATUS\r
162PciIoMemWrite (\r
163 IN EFI_PCI_IO_PROTOCOL *This,\r
164 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
165 IN UINT8 BarIndex,\r
166 IN UINT64 Offset,\r
167 IN UINTN Count,\r
168 IN OUT VOID *Buffer\r
169 )\r
170{\r
171 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
172\r
3402aac7 173 return PciRootBridgeIoMemWrite (&Private->RootBridge.Io,\r
1e57a462 174 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
175 Private->ConfigSpace->Device.Bar[BarIndex] + Offset,\r
176 Count,\r
177 Buffer\r
178 );\r
179}\r
180\r
181EFI_STATUS\r
182PciIoIoRead (\r
183 IN EFI_PCI_IO_PROTOCOL *This,\r
184 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
185 IN UINT8 BarIndex,\r
186 IN UINT64 Offset,\r
187 IN UINTN Count,\r
188 IN OUT VOID *Buffer\r
189 )\r
190{\r
191 ASSERT (FALSE);\r
192 return EFI_UNSUPPORTED;\r
193}\r
194\r
195EFI_STATUS\r
196PciIoIoWrite (\r
197 IN EFI_PCI_IO_PROTOCOL *This,\r
198 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
199 IN UINT8 BarIndex,\r
200 IN UINT64 Offset,\r
201 IN UINTN Count,\r
202 IN OUT VOID *Buffer\r
203 )\r
204{\r
205 ASSERT (FALSE);\r
206 return EFI_UNSUPPORTED;\r
207}\r
208\r
209EFI_STATUS\r
210PciIoPciRead (\r
211 IN EFI_PCI_IO_PROTOCOL *This,\r
212 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
213 IN UINT32 Offset,\r
214 IN UINTN Count,\r
215 IN OUT VOID *Buffer\r
216 )\r
217{\r
218 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
219\r
3402aac7
RC
220 return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,\r
221 Count,\r
222 TRUE,\r
223 (PTR)(UINTN)Buffer,\r
224 TRUE,\r
1e57a462 225 (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset)\r
226 );\r
227}\r
228\r
229EFI_STATUS\r
230PciIoPciWrite (\r
231 IN EFI_PCI_IO_PROTOCOL *This,\r
232 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
233 IN UINT32 Offset,\r
234 IN UINTN Count,\r
235 IN OUT VOID *Buffer\r
236 )\r
237{\r
238 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
239\r
3402aac7
RC
240 return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
241 Count,\r
242 TRUE,\r
243 (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset),\r
244 TRUE,\r
1e57a462 245 (PTR)(UINTN)Buffer\r
246 );\r
247}\r
248\r
249EFI_STATUS\r
250PciIoCopyMem (\r
251 IN EFI_PCI_IO_PROTOCOL *This,\r
252 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
253 IN UINT8 DestBarIndex,\r
254 IN UINT64 DestOffset,\r
255 IN UINT8 SrcBarIndex,\r
256 IN UINT64 SrcOffset,\r
257 IN UINTN Count\r
258 )\r
259{\r
260 ASSERT (FALSE);\r
261 return EFI_UNSUPPORTED;\r
262}\r
263\r
264EFI_STATUS\r
265PciIoMap (\r
266 IN EFI_PCI_IO_PROTOCOL *This,\r
267 IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
268 IN VOID *HostAddress,\r
269 IN OUT UINTN *NumberOfBytes,\r
270 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
271 OUT VOID **Mapping\r
272 )\r
273{\r
274 DMA_MAP_OPERATION DmaOperation;\r
275\r
276 if (Operation == EfiPciIoOperationBusMasterRead) {\r
277 DmaOperation = MapOperationBusMasterRead;\r
278 } else if (Operation == EfiPciIoOperationBusMasterWrite) {\r
279 DmaOperation = MapOperationBusMasterWrite;\r
280 } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {\r
281 DmaOperation = MapOperationBusMasterCommonBuffer;\r
282 } else {\r
283 return EFI_INVALID_PARAMETER;\r
284 }\r
285 return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);\r
286}\r
287\r
288EFI_STATUS\r
289PciIoUnmap (\r
290 IN EFI_PCI_IO_PROTOCOL *This,\r
291 IN VOID *Mapping\r
292 )\r
293{\r
294 return DmaUnmap (Mapping);\r
295}\r
296\r
297EFI_STATUS\r
298PciIoAllocateBuffer (\r
299 IN EFI_PCI_IO_PROTOCOL *This,\r
300 IN EFI_ALLOCATE_TYPE Type,\r
301 IN EFI_MEMORY_TYPE MemoryType,\r
302 IN UINTN Pages,\r
303 OUT VOID **HostAddress,\r
304 IN UINT64 Attributes\r
305 )\r
306{\r
307 if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {\r
308 // Check this\r
309 return EFI_UNSUPPORTED;\r
310 }\r
311\r
312 return DmaAllocateBuffer (MemoryType, Pages, HostAddress);\r
313}\r
314\r
315\r
316EFI_STATUS\r
317PciIoFreeBuffer (\r
318 IN EFI_PCI_IO_PROTOCOL *This,\r
319 IN UINTN Pages,\r
320 IN VOID *HostAddress\r
321 )\r
322{\r
323 return DmaFreeBuffer (Pages, HostAddress);\r
324}\r
325\r
326\r
327EFI_STATUS\r
328PciIoFlush (\r
329 IN EFI_PCI_IO_PROTOCOL *This\r
330 )\r
331{\r
332 return EFI_SUCCESS;\r
333}\r
334\r
335EFI_STATUS\r
336PciIoGetLocation (\r
337 IN EFI_PCI_IO_PROTOCOL *This,\r
338 OUT UINTN *SegmentNumber,\r
339 OUT UINTN *BusNumber,\r
340 OUT UINTN *DeviceNumber,\r
341 OUT UINTN *FunctionNumber\r
342 )\r
343{\r
344 EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
345\r
346 if (SegmentNumber != NULL) {\r
347 *SegmentNumber = Private->Segment;\r
348 }\r
349\r
350 if (BusNumber != NULL) {\r
351 *BusNumber = 0xff;\r
352 }\r
353\r
354 if (DeviceNumber != NULL) {\r
355 *DeviceNumber = 0;\r
356 }\r
357\r
358 if (FunctionNumber != NULL) {\r
359 *FunctionNumber = 0;\r
360 }\r
361\r
362 return EFI_SUCCESS;\r
363}\r
364\r
365EFI_STATUS\r
366PciIoAttributes (\r
367 IN EFI_PCI_IO_PROTOCOL *This,\r
368 IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
369 IN UINT64 Attributes,\r
370 OUT UINT64 *Result OPTIONAL\r
371 )\r
372{\r
373 switch (Operation) {\r
374 case EfiPciIoAttributeOperationGet:\r
375 case EfiPciIoAttributeOperationSupported:\r
376 if (Result == NULL) {\r
377 return EFI_INVALID_PARAMETER;\r
378 }\r
379 // We are not a real PCI device so just say things we kind of do\r
380 *Result = EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_DEVICE_ENABLE;\r
381 break;\r
382\r
383 case EfiPciIoAttributeOperationSet:\r
384 case EfiPciIoAttributeOperationEnable:\r
385 case EfiPciIoAttributeOperationDisable:\r
386 // Since we are not a real PCI device no enable/set or disable operations exist.\r
387 return EFI_SUCCESS;\r
3402aac7 388\r
1e57a462 389 default:\r
390 ASSERT (FALSE);\r
391 return EFI_INVALID_PARAMETER;\r
392 };\r
393 return EFI_SUCCESS;\r
394}\r
395\r
396EFI_STATUS\r
397PciIoGetBarAttributes (\r
398 IN EFI_PCI_IO_PROTOCOL *This,\r
399 IN UINT8 BarIndex,\r
400 OUT UINT64 *Supports, OPTIONAL\r
401 OUT VOID **Resources OPTIONAL\r
402 )\r
403{\r
404 ASSERT (FALSE);\r
405 return EFI_UNSUPPORTED;\r
406}\r
407\r
408EFI_STATUS\r
409PciIoSetBarAttributes (\r
410 IN EFI_PCI_IO_PROTOCOL *This,\r
411 IN UINT64 Attributes,\r
412 IN UINT8 BarIndex,\r
413 IN OUT UINT64 *Offset,\r
414 IN OUT UINT64 *Length\r
415 )\r
416{\r
417 ASSERT (FALSE);\r
418 return EFI_UNSUPPORTED;\r
419}\r
420\r
3402aac7 421EFI_PCI_IO_PROTOCOL PciIoTemplate =\r
1e57a462 422{\r
423 PciIoPollMem,\r
424 PciIoPollIo,\r
b0fdce95
OM
425 { PciIoMemRead, PciIoMemWrite },\r
426 { PciIoIoRead, PciIoIoWrite },\r
427 { PciIoPciRead, PciIoPciWrite },\r
1e57a462 428 PciIoCopyMem,\r
429 PciIoMap,\r
430 PciIoUnmap,\r
431 PciIoAllocateBuffer,\r
432 PciIoFreeBuffer,\r
433 PciIoFlush,\r
434 PciIoGetLocation,\r
435 PciIoAttributes,\r
436 PciIoGetBarAttributes,\r
437 PciIoSetBarAttributes,\r
438 0,\r
439 0\r
440};\r
441\r
442EFI_STATUS\r
443EFIAPI\r
444PciEmulationEntryPoint (\r
445 IN EFI_HANDLE ImageHandle,\r
446 IN EFI_SYSTEM_TABLE *SystemTable\r
447 )\r
448{\r
449 EFI_STATUS Status;\r
450 EFI_HANDLE Handle;\r
451 EFI_PCI_IO_PRIVATE_DATA *Private;\r
452 UINT8 CapabilityLength;\r
453 UINT8 PhysicalPorts;\r
454 UINTN Count;\r
455\r
456\r
457 //Configure USB host for OMAP3530.\r
458 ConfigureUSBHost();\r
459\r
460 // Create a private structure\r
461 Private = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA));\r
462 if (Private == NULL) {\r
463 Status = EFI_OUT_OF_RESOURCES;\r
464 return Status;\r
465 }\r
3402aac7 466\r
1e57a462 467 Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature\r
468 Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too\r
469 Private->RootBridge.MemoryStart = USB_EHCI_HCCAPBASE; // Get the USB capability register base\r
470 Private->Segment = 0; // Default to segment zero\r
471\r
472 // Find out the capability register length and number of physical ports.\r
473 CapabilityLength = MmioRead8(Private->RootBridge.MemoryStart);\r
474 PhysicalPorts = (MmioRead32 (Private->RootBridge.MemoryStart + 0x4)) & 0x0000000F;\r
475\r
476 // Calculate the total size of the USB registers.\r
477 Private->RootBridge.MemorySize = CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1));\r
478\r
479 // Enable Port Power bit in Port status and control registers in EHCI register space.\r
480 // Port Power Control (PPC) bit in the HCSPARAMS register is already set which indicates\r
481 // host controller implementation includes port power control.\r
482 for (Count = 0; Count < PhysicalPorts; Count++) {\r
483 MmioOr32 ((Private->RootBridge.MemoryStart + CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE + 4*Count), 0x00001000);\r
484 }\r
485\r
486 // Create fake PCI config space.\r
487 Private->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00));\r
488 if (Private->ConfigSpace == NULL) {\r
489 Status = EFI_OUT_OF_RESOURCES;\r
490 FreePool(Private);\r
491 return Status;\r
492 }\r
493\r
494 // Configure PCI config space\r
495 Private->ConfigSpace->Hdr.VendorId = 0x3530;\r
496 Private->ConfigSpace->Hdr.DeviceId = 0x3530;\r
497 Private->ConfigSpace->Hdr.ClassCode[0] = 0x20;\r
498 Private->ConfigSpace->Hdr.ClassCode[1] = 0x03;\r
499 Private->ConfigSpace->Hdr.ClassCode[2] = 0x0C;\r
500 Private->ConfigSpace->Device.Bar[0] = Private->RootBridge.MemoryStart;\r
501\r
502 Handle = NULL;\r
503\r
504 // Unique device path.\r
505 CopyMem(&Private->DevicePath, &PciIoDevicePathTemplate, sizeof(PciIoDevicePathTemplate));\r
506 Private->DevicePath.AcpiDevicePath.UID = 0;\r
3402aac7 507\r
1e57a462 508 // Copy protocol structure\r
509 CopyMem(&Private->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate));\r
510\r
511 Status = gBS->InstallMultipleProtocolInterfaces(&Handle,\r
512 &gEfiPciIoProtocolGuid, &Private->PciIoProtocol,\r
513 &gEfiDevicePathProtocolGuid, &Private->DevicePath,\r
514 NULL);\r
515 if (EFI_ERROR(Status)) {\r
516 DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n"));\r
517 }\r
518\r
519 return Status;\r
520}\r
521\r