1 
2 /*++
3 
4 Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
5 
6 
7   This program and the accompanying materials are licensed and made available under
8 
9   the terms and conditions of the BSD License that accompanies this distribution.
10 
11   The full text of the license may be found at
12 
13   http://opensource.org/licenses/bsd-license.php.
14 
15 
16 
17   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 
19   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 
21 
22 
23 
24 
25 Module Name:
26 
27   VlvPlatformInit.c
28 
29 Abstract:
30 
31   This is the driver that initializes the Intel ValleyView.
32 
33 --*/
34 
35 #include "VlvPlatformInit.h"
36 #include <Protocol/VlvPlatformPolicy.h>
37 
38 extern DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
39 UINT64            GTTMMADR;
40 
41 DXE_VLV_PLATFORM_POLICY_PROTOCOL  *DxePlatformSaPolicy;
42 
43 /**
44   "Poll Status" for GT Readiness
45 
PollGtReady_hang(UINT64 Base,UINT32 Offset,UINT32 Mask,UINT32 Result)46  @param  Base             Base address of MMIO
47  @param  Offset           MMIO Offset
48  @param  Mask             Mask
49  @param  Result           Value to wait for
50 
51  @retval None
52 
53 **/
54 VOID
55 PollGtReady_hang (
56   UINT64 Base,
57   UINT32 Offset,
58   UINT32 Mask,
59   UINT32 Result
60   )
61 {
62   UINT32  GtStatus;
63 
64   //
65   // Register read
66   //
67   GtStatus = MmioRead32 ((UINTN)Base+ Offset);
68 
69   while (((GtStatus & Mask) != Result)) {
70 
71     GtStatus = MmioRead32 ((UINTN)Base + Offset);
72   }
73 
74 }
75 
76 /**
77   Do Post GT PM Init Steps after VBIOS Initialization.
78 
PostPmInitCallBack(IN EFI_EVENT Event,IN VOID * Context)79   @param Event             A pointer to the Event that triggered the callback.
80   @param Context           A pointer to private data registered with the callback function.
81 
82   @retval EFI_SUCCESS        GC_TODO
83 
84 
85 **/
86 EFI_STATUS
87 EFIAPI
88 PostPmInitCallBack (
89   IN EFI_EVENT Event,
90   IN VOID      *Context
91   )
92 {
93   UINT64      OriginalGTTMMADR;
94   UINT32      LoGTBaseAddress;
95   UINT32      HiGTBaseAddress;
96 
97   //
98   // Enable Bus Master, I/O and Memory access on 0:2:0
99   //
100   PciOr8 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_CMD), (BIT2 | BIT1));
101 
102   //
103   // only 32bit read/write is legal for device 0:2:0
104   //
105   OriginalGTTMMADR  = (UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR));
106   OriginalGTTMMADR  = LShiftU64 ((UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR + 4)), 32) | (OriginalGTTMMADR);
107 
108   //
109   // 64bit GTTMADR does not work for S3 save script table since it is executed in PEIM phase
110   // Program temporarily 32bits GTTMMADR for POST and S3 resume
111   //
112   LoGTBaseAddress                   = (UINT32) (GTTMMADR & 0xFFFFFFFF);
113   HiGTBaseAddress                   = (UINT32) RShiftU64 ((GTTMMADR & 0xFFFFFFFF00000000), 32);
114   S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
115   S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);
116 
117 
118 
119   //
120   // Restore original GTTMMADR
121   //
122   LoGTBaseAddress                   = (UINT32) (OriginalGTTMMADR & 0xFFFFFFFF);
123   HiGTBaseAddress                   = (UINT32) RShiftU64 ((OriginalGTTMMADR & 0xFFFFFFFF00000000), 32);
124 
125   S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
126   S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);
127 
128 
129   //
130   // Lock the following registers, GGC, BDSM, BGSM
131   //
132   PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_MGGC_OFFSET), LockBit);
133   PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_BSM_OFFSET), LockBit);
134   PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_BGSM), LockBit);
135 
136   gBS->CloseEvent (Event);
137 
138   //
139   // Return final status
140   //
141   return EFI_SUCCESS;
142 }
143 
144 /**
145 
146   Routine Description:
147 
IgdPmHook(IN EFI_HANDLE ImageHandle,IN DXE_VLV_PLATFORM_POLICY_PROTOCOL * DxePlatformSaPolicy)148   Initialize GT Post Routines.
149 
150   @param ImageHandle              Handle for the image of this driver
151   @param DxePlatformSaPolicy      SA DxePlatformPolicy protocol
152 
153   @retval EFI_SUCCESS             GT POST initialization complete
154 
155 **/
156 EFI_STATUS
157 IgdPmHook (
158   IN EFI_HANDLE                      ImageHandle,
159   IN DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicy
160   )
161 {
162 
163   EFI_EVENT             mConOutEvent;
164   VOID                  *gConOutNotifyReg;
165 
166   EFI_STATUS            Status;
167 
168   EFI_PHYSICAL_ADDRESS  MemBaseAddress;
169   UINT32                LoGTBaseAddress;
170   UINT32                HiGTBaseAddress;
171 
172   GTTMMADR    = 0;
173   Status      = EFI_SUCCESS;
174 
175   //
176   // If device 0:2:0 (Internal Graphics Device, or GT) is enabled, then Program GTTMMADR,
177   //
178   if (PciRead16(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_VID))  != 0xFFFF) {
179 
180     ASSERT (gDS!=NULL);
181 
182     //
183     // Enable Bus Master, I/O and Memory access on 0:2:0
184     //
185     PciOr8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD), (BIT2 | BIT1 | BIT0));
186 
187     //
188     // Means Allocate 4MB for GTTMADDR
189     //
190     MemBaseAddress = 0x0ffffffff;
191 
192     Status = gDS->AllocateMemorySpace (
193                     EfiGcdAllocateMaxAddressSearchBottomUp,
194                     EfiGcdMemoryTypeMemoryMappedIo,
195                     GTT_MEM_ALIGN,
196                     GTTMMADR_SIZE_4MB,
197                     &MemBaseAddress,
198                     ImageHandle,
199                     NULL
200                     );
201     ASSERT_EFI_ERROR (Status);
202 
203     //
204     // Program GT PM Settings if GTTMMADR allocation is Successful
205     //
206     GTTMMADR                          = (UINTN) MemBaseAddress;
207 
208     LoGTBaseAddress                   = (UINT32) (MemBaseAddress & 0xFFFFFFFF);
209     HiGTBaseAddress                   = (UINT32) RShiftU64 ((MemBaseAddress & 0xFFFFFFFF00000000), 32);
210 
211     PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR), LoGTBaseAddress);
212     PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR+4), HiGTBaseAddress);
213 
214 
215     S3PciRead32(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR));
216 
217 
218     S3MmioRead32(IGD_R_GTTMMADR + 4);
219 
220 
221     S3PciRead8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD));
222 
223     //
224     // Do POST GT PM Init Steps after VBIOS Initialization in DoPostPmInitCallBack
225     //
226     Status = gBS->CreateEvent (
227                     EVT_NOTIFY_SIGNAL,
228                     TPL_CALLBACK,
229                     (EFI_EVENT_NOTIFY)PostPmInitCallBack,
230                     NULL,
231                     &mConOutEvent
232                     );
233 
234     ASSERT_EFI_ERROR (Status);
235     if (EFI_ERROR (Status)) {
236       return Status;
237     }
238 
239 
240     Status = gBS->RegisterProtocolNotify (
241                     &gEfiGraphicsOutputProtocolGuid,
242                     mConOutEvent,
243                     &gConOutNotifyReg
244                     );
245 
246 
247 
248     MmioWrite64 (IGD_R_GTTMMADR, 0);
249 
250     //
251     // Free allocated resources
252     //
253     gDS->FreeMemorySpace (
254            MemBaseAddress,
255            GTTMMADR_SIZE_4MB
256            );
257 
258   }
259 
260   return EFI_SUCCESS;
261 }
262 
263 /**
264 
265   This is the standard EFI driver point that detects
266   whether there is an ICH southbridge in the system
267   and if so, initializes the chip.
VlvPlatformInitEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)268 
269   @param  ImageHandle             Handle for the image of this driver
270   @param  SystemTable             Pointer to the EFI System Table
271 
272   @retval EFI_SUCCESS             The function completed successfully
273 
274 **/
275 EFI_STATUS
276 EFIAPI
277 VlvPlatformInitEntryPoint (
278   IN EFI_HANDLE       ImageHandle,
279   IN EFI_SYSTEM_TABLE *SystemTable
280   )
281 {
282   EFI_STATUS                        Status;
283 
284   Status = gBS->LocateProtocol (&gDxeVlvPlatformPolicyGuid, NULL, (void **)&DxePlatformSaPolicy);
285   ASSERT_EFI_ERROR (Status);
286 
287   //
288   // GtPostInit Initialization
289   //
290   DEBUG ((EFI_D_ERROR, "Initializing GT PowerManagement and other GT POST related\n"));
291   IgdPmHook (ImageHandle, DxePlatformSaPolicy);
292 
293   //
294   // IgdOpRegion Install Initialization
295   //
296   DEBUG ((EFI_D_ERROR, "Initializing IGD OpRegion\n"));
297   IgdOpRegionInit ();
298 
299   return EFI_SUCCESS;
300 }
301 
302