]> git.proxmox.com Git - mirror_edk2.git/blame - Omap35xxPkg/PciEmulation/PciEmulation.c
ARM Packages: Fixed line endings
[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
4 \r
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
39EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate = \r
40{\r
41 {\r
42 { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0},\r
43 EISA_PNP_ID(0x0A03), // HID\r
44 0 // UID\r
45 },\r
46 {\r
47 { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0},\r
48 0,\r
49 0\r
50 },\r
51 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}\r
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
85 ASSERT_EFI_ERROR (Status); \r
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
94 ASSERT_EFI_ERROR (Status); \r
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
153 return PciRootBridgeIoMemRead (&Private->RootBridge.Io, \r
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
173 return PciRootBridgeIoMemWrite (&Private->RootBridge.Io, \r
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
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
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
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
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
388 \r
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
421EFI_PCI_IO_PROTOCOL PciIoTemplate = \r
422{\r
423 PciIoPollMem,\r
424 PciIoPollIo,\r
425 PciIoMemRead,\r
426 PciIoMemWrite,\r
427 PciIoIoRead,\r
428 PciIoIoWrite,\r
429 PciIoPciRead,\r
430 PciIoPciWrite,\r
431 PciIoCopyMem,\r
432 PciIoMap,\r
433 PciIoUnmap,\r
434 PciIoAllocateBuffer,\r
435 PciIoFreeBuffer,\r
436 PciIoFlush,\r
437 PciIoGetLocation,\r
438 PciIoAttributes,\r
439 PciIoGetBarAttributes,\r
440 PciIoSetBarAttributes,\r
441 0,\r
442 0\r
443};\r
444\r
445EFI_STATUS\r
446EFIAPI\r
447PciEmulationEntryPoint (\r
448 IN EFI_HANDLE ImageHandle,\r
449 IN EFI_SYSTEM_TABLE *SystemTable\r
450 )\r
451{\r
452 EFI_STATUS Status;\r
453 EFI_HANDLE Handle;\r
454 EFI_PCI_IO_PRIVATE_DATA *Private;\r
455 UINT8 CapabilityLength;\r
456 UINT8 PhysicalPorts;\r
457 UINTN Count;\r
458\r
459\r
460 //Configure USB host for OMAP3530.\r
461 ConfigureUSBHost();\r
462\r
463 // Create a private structure\r
464 Private = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA));\r
465 if (Private == NULL) {\r
466 Status = EFI_OUT_OF_RESOURCES;\r
467 return Status;\r
468 }\r
469 \r
470 Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature\r
471 Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too\r
472 Private->RootBridge.MemoryStart = USB_EHCI_HCCAPBASE; // Get the USB capability register base\r
473 Private->Segment = 0; // Default to segment zero\r
474\r
475 // Find out the capability register length and number of physical ports.\r
476 CapabilityLength = MmioRead8(Private->RootBridge.MemoryStart);\r
477 PhysicalPorts = (MmioRead32 (Private->RootBridge.MemoryStart + 0x4)) & 0x0000000F;\r
478\r
479 // Calculate the total size of the USB registers.\r
480 Private->RootBridge.MemorySize = CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1));\r
481\r
482 // Enable Port Power bit in Port status and control registers in EHCI register space.\r
483 // Port Power Control (PPC) bit in the HCSPARAMS register is already set which indicates\r
484 // host controller implementation includes port power control.\r
485 for (Count = 0; Count < PhysicalPorts; Count++) {\r
486 MmioOr32 ((Private->RootBridge.MemoryStart + CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE + 4*Count), 0x00001000);\r
487 }\r
488\r
489 // Create fake PCI config space.\r
490 Private->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00));\r
491 if (Private->ConfigSpace == NULL) {\r
492 Status = EFI_OUT_OF_RESOURCES;\r
493 FreePool(Private);\r
494 return Status;\r
495 }\r
496\r
497 // Configure PCI config space\r
498 Private->ConfigSpace->Hdr.VendorId = 0x3530;\r
499 Private->ConfigSpace->Hdr.DeviceId = 0x3530;\r
500 Private->ConfigSpace->Hdr.ClassCode[0] = 0x20;\r
501 Private->ConfigSpace->Hdr.ClassCode[1] = 0x03;\r
502 Private->ConfigSpace->Hdr.ClassCode[2] = 0x0C;\r
503 Private->ConfigSpace->Device.Bar[0] = Private->RootBridge.MemoryStart;\r
504\r
505 Handle = NULL;\r
506\r
507 // Unique device path.\r
508 CopyMem(&Private->DevicePath, &PciIoDevicePathTemplate, sizeof(PciIoDevicePathTemplate));\r
509 Private->DevicePath.AcpiDevicePath.UID = 0;\r
510 \r
511 // Copy protocol structure\r
512 CopyMem(&Private->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate));\r
513\r
514 Status = gBS->InstallMultipleProtocolInterfaces(&Handle,\r
515 &gEfiPciIoProtocolGuid, &Private->PciIoProtocol,\r
516 &gEfiDevicePathProtocolGuid, &Private->DevicePath,\r
517 NULL);\r
518 if (EFI_ERROR(Status)) {\r
519 DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n"));\r
520 }\r
521\r
522 return Status;\r
523}\r
524\r