1 /** @file
2 *
3 * Copyright (c) 2015, Hisilicon Limited. All rights reserved.
4 * Copyright (c) 2015, Linaro Limited. All rights reserved.
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
17 #include <PiDxe.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/UefiRuntimeLib.h>
22 #include <Library/DxeServicesTableLib.h>
23 #include <Guid/EventGroup.h>
24
25 #include <Library/PlatformSysCtrlLib.h>
26 #include "I2CLibInternal.h"
27
28 STATIC EFI_EVENT mI2cLibVirtualAddrChangeEvent;
29
30 STATIC UINTN gI2cBase[MAX_SOCKET][I2C_PORT_MAX];
31
GetI2cBase(UINT32 Socket,UINT8 Port)32 UINTN GetI2cBase (UINT32 Socket, UINT8 Port)
33 {
34 if (gI2cBase[Socket][Port] == 0) {
35 gI2cBase[Socket][Port] = PlatformGetI2cBase(Socket, Port);
36 }
37
38 return gI2cBase[Socket][Port];
39 }
40
41 VOID
42 EFIAPI
I2cLibVirtualNotifyEvent(IN EFI_EVENT Event,IN VOID * Context)43 I2cLibVirtualNotifyEvent (
44 IN EFI_EVENT Event,
45 IN VOID *Context
46 )
47 {
48 UINT32 Socket;
49 UINT8 Port;
50
51 // We assume that all I2C ports used in one runtime driver need to be
52 // converted into virtual address.
53 for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
54 for (Port = 0; Port < I2C_PORT_MAX; Port++) {
55 if (gI2cBase[Socket][Port] != 0) {
56 EfiConvertPointer (0x0, (VOID **)&gI2cBase[Socket][Port]);
57 }
58 }
59 }
60
61 return;
62 }
63
64 EFI_STATUS
I2cLibRuntimeSetup(UINT32 Socket,UINT8 Port)65 I2cLibRuntimeSetup (UINT32 Socket, UINT8 Port)
66 {
67 EFI_STATUS Status;
68
69 UINTN Base = GetI2cBase (Socket, Port);
70
71 // Declare the controller as EFI_MEMORY_RUNTIME
72 Status = gDS->AddMemorySpace (
73 EfiGcdMemoryTypeMemoryMappedIo,
74 Base, SIZE_64KB,
75 EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
76 );
77 if (EFI_ERROR (Status)) {
78 DEBUG ((EFI_D_WARN, "[%a:%d] AddMemorySpace failed: %r\n", __FUNCTION__, __LINE__, Status));
79 }
80
81 Status = gDS->SetMemorySpaceAttributes (Base, SIZE_64KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
82 if (EFI_ERROR (Status)) {
83 DEBUG ((EFI_D_ERROR, "[%a:%d] SetMemorySpaceAttributes failed: %r\n", __FUNCTION__, __LINE__, Status));
84 return Status;
85 }
86
87 //
88 // Register for the virtual address change event
89 //
90 // Only create event once
91 if (mI2cLibVirtualAddrChangeEvent == NULL) {
92 Status = gBS->CreateEventEx (
93 EVT_NOTIFY_SIGNAL,
94 TPL_NOTIFY,
95 I2cLibVirtualNotifyEvent,
96 NULL,
97 &gEfiEventVirtualAddressChangeGuid,
98 &mI2cLibVirtualAddrChangeEvent
99 );
100 if (EFI_ERROR (Status)) {
101 DEBUG ((EFI_D_ERROR, "[%a:%d] Create event failed: %r\n", __FUNCTION__, __LINE__, Status));
102 return Status;
103 }
104 }
105
106 return EFI_SUCCESS;
107 }
108
109
110