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