]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/MultiPlatformLib/BoardClkGens/BoardClkGens.c
Vlv2TbltDevicePkg: fix ASSERT_EFI_ERROR() typos
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / MultiPlatformLib / BoardClkGens / BoardClkGens.c
1 /** @file
2 Clock generator setting for multiplatform.
3
4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
5
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 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 <BoardClkGens.h>
18 #include <Guid/SetupVariable.h>
19 #include <Ppi/ReadOnlyVariable2.h>
20 #include <Library/BaseMemoryLib.h>
21
22 #ifndef __GNUC__
23 #pragma optimize( "", off )
24 #endif
25
26 #define CLKGEN_EN 1
27 #define EFI_DEBUG 1
28
29 CLOCK_GENERATOR_DETAILS mSupportedClockGeneratorTable[] =
30 {
31 { ClockGeneratorCk410, CK410_GENERATOR_ID , CK410_GENERATOR_SPREAD_SPECTRUM_BYTE, CK410_GENERATOR_SPREAD_SPECTRUM_BIT },
32 { ClockGeneratorCk505, CK505_GENERATOR_ID , CK505_GENERATOR_SPREAD_SPECTRUM_BYTE, CK505_GENERATOR_SPREAD_SPECTRUM_BIT }
33 };
34
35 /**
36 Configure the clock generator using the SMBUS PPI services.
37
38 This function performs a block write, and dumps debug information.
39
40 @param PeiServices General purpose services available to every PEIM.
41 @param ClockType Clock generator's model name.
42 @param ClockAddress SMBUS address of clock generator.
43 @param ConfigurationTableLength Length of configuration table.
44 @param ConfigurationTable Pointer of configuration table.
45
46 @retval EFI_SUCCESS - Operation success.
47
48 **/
49 EFI_STATUS
50 ConfigureClockGenerator (
51 IN EFI_PEI_SERVICES **PeiServices,
52 IN EFI_PEI_SMBUS_PPI *SmbusPpi,
53 IN CLOCK_GENERATOR_TYPE ClockType,
54 IN UINT8 ClockAddress,
55 IN UINTN ConfigurationTableLength,
56 IN OUT UINT8 *ConfigurationTable
57 )
58 {
59
60 EFI_STATUS Status;
61 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
62 UINT8 Buffer[MAX_CLOCK_GENERATOR_BUFFER_LENGTH];
63 UINTN Length;
64 EFI_SMBUS_DEVICE_COMMAND Command;
65 #if CLKGEN_CONFIG_EXTRA
66 UINT8 j;
67 #endif
68
69 //
70 // Verify input arguments
71 //
72 ASSERT (ConfigurationTableLength >= 6);
73 ASSERT (ConfigurationTableLength <= MAX_CLOCK_GENERATOR_BUFFER_LENGTH);
74 ASSERT (ClockType < ClockGeneratorMax);
75 ASSERT (ConfigurationTable != NULL);
76
77 //
78 // Read the clock generator
79 //
80 SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
81 Length = sizeof (Buffer);
82 Command = 0;
83 Status = SmbusPpi->Execute (
84 PeiServices,
85 SmbusPpi,
86 SlaveAddress,
87 Command,
88 EfiSmbusReadBlock,
89 FALSE,
90 &Length,
91 Buffer
92 );
93 ASSERT_EFI_ERROR (Status);
94
95 #ifdef EFI_DEBUG
96 {
97 UINT8 i;
98 for (i = 0; i < sizeof (Buffer); i++) {
99 DEBUG((EFI_D_ERROR, "CK505 default Clock Generator Byte %d: %x\n", i, Buffer[i]));
100 }
101 #if CLKGEN_EN
102 for (i = 0; i < ConfigurationTableLength; i++) {
103 DEBUG((EFI_D_ERROR, "BIOS structure Clock Generator Byte %d: %x\n", i, ConfigurationTable[i]));
104 }
105 #endif
106 }
107 #endif
108
109 DEBUG((EFI_D_ERROR, "Expected Clock Generator ID is %x, expecting %x\n", mSupportedClockGeneratorTable[ClockType].ClockId,(Buffer[7]&0xF)));
110
111 //
112 // Program clock generator
113 //
114 Command = 0;
115 #if CLKGEN_EN
116 #if CLKGEN_CONFIG_EXTRA
117 for (j = 0; j < ConfigurationTableLength; j++) {
118 Buffer[j] = ConfigurationTable[j];
119 }
120
121 Buffer[30] = 0x00;
122
123 Status = SmbusPpi->Execute (
124 PeiServices,
125 SmbusPpi,
126 SlaveAddress,
127 Command,
128 EfiSmbusWriteBlock,
129 FALSE,
130 &Length,
131 Buffer
132 );
133 #else
134 Status = SmbusPpi->Execute (
135 PeiServices,
136 SmbusPpi,
137 SlaveAddress,
138 Command,
139 EfiSmbusWriteBlock,
140 FALSE,
141 &ConfigurationTableLength,
142 ConfigurationTable
143 );
144 #endif // CLKGEN_CONFIG_EXTRA
145 #else
146 ConfigurationTable[4] = (ConfigurationTable[4] & 0x3) | (Buffer[4] & 0xFC);
147 Command = 4;
148 Length = 1;
149 Status = SmbusPpi->Execute (
150 PeiServices,
151 SmbusPpi,
152 SlaveAddress,
153 Command,
154 EfiSmbusWriteBlock,
155 FALSE,
156 &Length,
157 &ConfigurationTable[4]
158 );
159 #endif //CLKGEN_EN
160 ASSERT_EFI_ERROR (Status);
161
162 //
163 // Dump contents after write
164 //
165 #ifdef EFI_DEBUG
166 {
167 UINT8 i;
168 SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
169 Length = sizeof (Buffer);
170 Command = 0;
171 Status = SmbusPpi->Execute (
172 PeiServices,
173 SmbusPpi,
174 SlaveAddress,
175 Command,
176 EfiSmbusReadBlock,
177 FALSE,
178 &Length,
179 Buffer
180 );
181
182 for (i = 0; i < ConfigurationTableLength; i++) {
183 DEBUG((EFI_D_ERROR, "Clock Generator Byte %d: %x\n", i, Buffer[i]));
184 }
185 }
186 #endif
187
188 return EFI_SUCCESS;
189 }
190
191 /**
192 Configure the clock generator using the SMBUS PPI services.
193
194 This function performs a block write, and dumps debug information.
195
196 @param PeiServices General purpose services available to every PEIM.
197 @param ClockType Clock generator's model name.
198 @param ClockAddress SMBUS address of clock generator.
199 @param ConfigurationTableLength Length of configuration table.
200 @param ConfigurationTable Pointer of configuration table.
201
202
203 @retval EFI_SUCCESS Operation success.
204
205 **/
206 UINT8
207 ReadClockGeneratorID (
208 IN EFI_PEI_SERVICES **PeiServices,
209 IN EFI_PEI_SMBUS_PPI *SmbusPpi,
210 IN UINT8 ClockAddress
211 )
212 {
213 EFI_STATUS Status;
214 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
215 UINT8 Buffer[MAX_CLOCK_GENERATOR_BUFFER_LENGTH];
216 UINTN Length;
217 EFI_SMBUS_DEVICE_COMMAND Command;
218
219 //
220 // Read the clock generator
221 //
222 SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
223 Length = sizeof (Buffer);
224 Command = 0;
225 Status = SmbusPpi->Execute (
226 PeiServices,
227 SmbusPpi,
228 SlaveAddress,
229 Command,
230 EfiSmbusReadBlock,
231 FALSE,
232 &Length,
233 Buffer
234 );
235
236 //
237 // Sanity check that the requested clock type is present in our supported clocks table
238 //
239 DEBUG((EFI_D_ERROR, "Expected Clock Generator ID is 0x%x\n", Buffer[7]));
240
241 return (Buffer[7]);
242 }
243
244 /**
245 Configure the clock generator to enable free-running operation. This keeps
246 the clocks from being stopped when the system enters C3 or C4.
247
248 @param None
249
250 @retval EFI_SUCCESS The function completed successfully.
251
252 **/
253 EFI_STATUS
254 ConfigurePlatformClocks (
255 IN EFI_PEI_SERVICES **PeiServices,
256 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
257 IN VOID *SmbusPpi
258 )
259 {
260 //
261 // Comment it out for now
262 // Not supported by Hybrid model.
263 //
264 EFI_STATUS Status;
265 UINT8 *ConfigurationTable;
266
267 CLOCK_GENERATOR_TYPE ClockType = ClockGeneratorCk505;
268 UINT8 ConfigurationTable_Desktop[] = CLOCK_GENERATOR_SETTINGS_DESKTOP;
269 UINT8 ConfigurationTable_Mobile[] = CLOCK_GENERATOR_SETTINGS_MOBILE;
270 UINT8 ConfigurationTable_Tablet[] = CLOCK_GENERATOR_SEETINGS_TABLET;
271
272 EFI_PLATFORM_INFO_HOB *PlatformInfoHob;
273 BOOLEAN EnableSpreadSpectrum;
274 UINT8 ClockGenID=0;
275 SYSTEM_CONFIGURATION SystemConfiguration;
276
277 UINTN Length;
278 EFI_SMBUS_DEVICE_COMMAND Command;
279 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
280 UINT8 Data;
281
282 UINT8 ClockAddress = CLOCK_GENERATOR_ADDRESS;
283 UINTN VariableSize;
284 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
285
286 //
287 // Obtain Platform Info from HOB.
288 //
289 Status = GetPlatformInfoHob ((CONST EFI_PEI_SERVICES **) PeiServices, &PlatformInfoHob);
290 ASSERT_EFI_ERROR (Status);
291
292 DEBUG((EFI_D_ERROR, "PlatformInfo protocol is working in ConfigurePlatformClocks()...%x\n",PlatformInfoHob->PlatformFlavor));
293
294 //
295 // Locate SMBUS PPI
296 //
297 Status = (**PeiServices).LocatePpi (
298 (CONST EFI_PEI_SERVICES **) PeiServices,
299 &gEfiPeiSmbusPpiGuid,
300 0,
301 NULL,
302 &SmbusPpi
303 );
304 ASSERT_EFI_ERROR (Status);
305
306 Data = 0;
307 SlaveAddress.SmbusDeviceAddress = ClockAddress >> 1;
308 Length = 1;
309 Command = 0x87; //Control Register 7 Vendor ID Check
310 Status = ((EFI_PEI_SMBUS_PPI *) SmbusPpi)->Execute (
311 PeiServices,
312 SmbusPpi,
313 SlaveAddress,
314 Command,
315 EfiSmbusReadByte,
316 FALSE,
317 &Length,
318 &Data
319 );
320
321 if (EFI_ERROR (Status) || ((Data & 0x0F) != CK505_GENERATOR_ID)) {
322 DEBUG((EFI_D_ERROR, "Clock Generator CK505 Not Present, vendor ID on board is %x\n",(Data & 0x0F)));
323 return EFI_SUCCESS;
324 }
325 ClockGenID = Data & 0x0F;
326
327 EnableSpreadSpectrum = FALSE;
328 VariableSize = sizeof (SYSTEM_CONFIGURATION);
329 ZeroMem (&SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
330
331 Status = (*PeiServices)->LocatePpi (
332 (CONST EFI_PEI_SERVICES **) PeiServices,
333 &gEfiPeiReadOnlyVariable2PpiGuid,
334 0,
335 NULL,
336 (VOID **) &Variable
337 );
338 //
339 // Use normal setup default from NVRAM variable,
340 // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
341 //
342 VariableSize = sizeof(SYSTEM_CONFIGURATION);
343 Status = Variable->GetVariable (Variable,
344 L"Setup",
345 &gEfiSetupVariableGuid,
346 NULL,
347 &VariableSize,
348 &SystemConfiguration);
349 if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
350 //The setup variable is corrupted
351 VariableSize = sizeof(SYSTEM_CONFIGURATION);
352 Status = Variable->GetVariable(Variable,
353 L"SetupRecovery",
354 &gEfiSetupVariableGuid,
355 NULL,
356 &VariableSize,
357 &SystemConfiguration
358 );
359 ASSERT_EFI_ERROR (Status);
360 }
361 if(!EFI_ERROR (Status)){
362 EnableSpreadSpectrum = SystemConfiguration.EnableClockSpreadSpec;
363 }
364
365 //
366 // Perform platform-specific intialization dependent upon Board ID:
367 //
368 DEBUG((EFI_D_ERROR, "board id is %x, platform id is %x\n",PlatformInfoHob->BoardId,PlatformInfoHob->PlatformFlavor));
369
370
371 switch (PlatformInfoHob->BoardId) {
372 case BOARD_ID_MINNOW2:
373 case BOARD_ID_MINNOW2_TURBOT:
374 default:
375 switch(PlatformInfoHob->PlatformFlavor) {
376 case FlavorTablet:
377 ConfigurationTable = ConfigurationTable_Tablet;
378 Length = sizeof (ConfigurationTable_Tablet);
379 break;
380 case FlavorMobile:
381 ConfigurationTable = ConfigurationTable_Mobile;
382 Length = sizeof (ConfigurationTable_Mobile);
383 break;
384 case FlavorDesktop:
385 default:
386 ConfigurationTable = ConfigurationTable_Desktop;
387 Length = sizeof (ConfigurationTable_Desktop);
388 break;
389 }
390 break;
391 }
392
393 //
394 // Perform common clock initialization:
395 //
396 // Program Spread Spectrum function.
397 //
398 if (EnableSpreadSpectrum)
399 {
400 ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] |= mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset;
401 } else {
402 ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] &= ~(mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset);
403 }
404
405
406 #if CLKGEN_EN
407 Status = ConfigureClockGenerator (PeiServices, SmbusPpi, ClockType, ClockAddress, Length, ConfigurationTable);
408 ASSERT_EFI_ERROR (Status);
409 #endif // CLKGEN_EN
410 return EFI_SUCCESS;
411 }
412
413 static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
414 {
415 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
416 &gEfiPeiSmbusPpiGuid,
417 ConfigurePlatformClocks
418 }
419 };
420
421 EFI_STATUS
422 InstallPlatformClocksNotify (
423 IN CONST EFI_PEI_SERVICES **PeiServices
424 )
425 {
426 EFI_STATUS Status;
427
428 DEBUG ((EFI_D_INFO, "InstallPlatformClocksNotify()...\n"));
429
430 Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
431 ASSERT_EFI_ERROR (Status);
432 return EFI_SUCCESS;
433
434 }
435
436 #ifndef __GNUC__
437 #pragma optimize( "", on )
438 #endif