2 Clock generator setting for multiplatform.
4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
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.
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.
17 #include <BoardClkGens.h>
18 #include <Guid/SetupVariable.h>
19 #include <Ppi/ReadOnlyVariable2.h>
20 #include <Library/BaseMemoryLib.h>
23 #pragma optimize( "", off )
29 CLOCK_GENERATOR_DETAILS mSupportedClockGeneratorTable
[] =
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
}
36 Configure the clock generator using the SMBUS PPI services.
38 This function performs a block write, and dumps debug information.
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.
46 @retval EFI_SUCCESS - Operation success.
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
61 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
;
62 UINT8 Buffer
[MAX_CLOCK_GENERATOR_BUFFER_LENGTH
];
64 EFI_SMBUS_DEVICE_COMMAND Command
;
65 #if CLKGEN_CONFIG_EXTRA
70 // Verify input arguments
72 ASSERT (ConfigurationTableLength
>= 6);
73 ASSERT (ConfigurationTableLength
<= MAX_CLOCK_GENERATOR_BUFFER_LENGTH
);
74 ASSERT (ClockType
< ClockGeneratorMax
);
75 ASSERT (ConfigurationTable
!= NULL
);
78 // Read the clock generator
80 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
81 Length
= sizeof (Buffer
);
83 Status
= SmbusPpi
->Execute (
93 ASSERT_EFI_ERROR (Status
);
98 for (i
= 0; i
< sizeof (Buffer
); i
++) {
99 DEBUG((EFI_D_ERROR
, "CK505 default Clock Generator Byte %d: %x\n", i
, Buffer
[i
]));
102 for (i
= 0; i
< ConfigurationTableLength
; i
++) {
103 DEBUG((EFI_D_ERROR
, "BIOS structure Clock Generator Byte %d: %x\n", i
, ConfigurationTable
[i
]));
109 DEBUG((EFI_D_ERROR
, "Expected Clock Generator ID is %x, expecting %x\n", mSupportedClockGeneratorTable
[ClockType
].ClockId
,(Buffer
[7]&0xF)));
112 // Program clock generator
116 #if CLKGEN_CONFIG_EXTRA
117 for (j
= 0; j
< ConfigurationTableLength
; j
++) {
118 Buffer
[j
] = ConfigurationTable
[j
];
123 Status
= SmbusPpi
->Execute (
134 Status
= SmbusPpi
->Execute (
141 &ConfigurationTableLength
,
144 #endif // CLKGEN_CONFIG_EXTRA
146 ConfigurationTable
[4] = (ConfigurationTable
[4] & 0x3) | (Buffer
[4] & 0xFC);
149 Status
= SmbusPpi
->Execute (
157 &ConfigurationTable
[4]
160 ASSERT_EFI_ERROR (Status
);
163 // Dump contents after write
168 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
169 Length
= sizeof (Buffer
);
171 Status
= SmbusPpi
->Execute (
182 for (i
= 0; i
< ConfigurationTableLength
; i
++) {
183 DEBUG((EFI_D_ERROR
, "Clock Generator Byte %d: %x\n", i
, Buffer
[i
]));
192 Configure the clock generator using the SMBUS PPI services.
194 This function performs a block write, and dumps debug information.
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.
203 @retval EFI_SUCCESS Operation success.
207 ReadClockGeneratorID (
208 IN EFI_PEI_SERVICES
**PeiServices
,
209 IN EFI_PEI_SMBUS_PPI
*SmbusPpi
,
210 IN UINT8 ClockAddress
213 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
;
214 UINT8 Buffer
[MAX_CLOCK_GENERATOR_BUFFER_LENGTH
];
216 EFI_SMBUS_DEVICE_COMMAND Command
;
219 // Read the clock generator
221 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
222 Length
= sizeof (Buffer
);
236 // Sanity check that the requested clock type is present in our supported clocks table
238 DEBUG((EFI_D_ERROR
, "Expected Clock Generator ID is 0x%x\n", Buffer
[7]));
244 Configure the clock generator to enable free-running operation. This keeps
245 the clocks from being stopped when the system enters C3 or C4.
249 @retval EFI_SUCCESS The function completed successfully.
253 ConfigurePlatformClocks (
254 IN EFI_PEI_SERVICES
**PeiServices
,
255 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
260 // Comment it out for now
261 // Not supported by Hybrid model.
264 UINT8
*ConfigurationTable
;
266 CLOCK_GENERATOR_TYPE ClockType
= ClockGeneratorCk505
;
267 UINT8 ConfigurationTable_Desktop
[] = CLOCK_GENERATOR_SETTINGS_DESKTOP
;
268 UINT8 ConfigurationTable_Mobile
[] = CLOCK_GENERATOR_SETTINGS_MOBILE
;
269 UINT8 ConfigurationTable_Tablet
[] = CLOCK_GENERATOR_SEETINGS_TABLET
;
271 EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
;
272 BOOLEAN EnableSpreadSpectrum
;
273 SYSTEM_CONFIGURATION SystemConfiguration
;
276 EFI_SMBUS_DEVICE_COMMAND Command
;
277 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
;
280 UINT8 ClockAddress
= CLOCK_GENERATOR_ADDRESS
;
282 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
285 // Obtain Platform Info from HOB.
287 Status
= GetPlatformInfoHob ((CONST EFI_PEI_SERVICES
**) PeiServices
, &PlatformInfoHob
);
288 ASSERT_EFI_ERROR (Status
);
290 DEBUG((EFI_D_ERROR
, "PlatformInfo protocol is working in ConfigurePlatformClocks()...%x\n",PlatformInfoHob
->PlatformFlavor
));
295 Status
= (**PeiServices
).LocatePpi (
296 (CONST EFI_PEI_SERVICES
**) PeiServices
,
297 &gEfiPeiSmbusPpiGuid
,
302 ASSERT_EFI_ERROR (Status
);
305 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
307 Command
= 0x87; //Control Register 7 Vendor ID Check
308 Status
= ((EFI_PEI_SMBUS_PPI
*) SmbusPpi
)->Execute (
319 if (EFI_ERROR (Status
) || ((Data
& 0x0F) != CK505_GENERATOR_ID
)) {
320 DEBUG((EFI_D_ERROR
, "Clock Generator CK505 Not Present, vendor ID on board is %x\n",(Data
& 0x0F)));
324 EnableSpreadSpectrum
= FALSE
;
325 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
326 ZeroMem (&SystemConfiguration
, sizeof (SYSTEM_CONFIGURATION
));
328 Status
= (*PeiServices
)->LocatePpi (
329 (CONST EFI_PEI_SERVICES
**) PeiServices
,
330 &gEfiPeiReadOnlyVariable2PpiGuid
,
336 // Use normal setup default from NVRAM variable,
337 // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
339 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
340 Status
= Variable
->GetVariable (Variable
,
342 &gEfiSetupVariableGuid
,
345 &SystemConfiguration
);
346 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
347 //The setup variable is corrupted
348 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
349 Status
= Variable
->GetVariable(Variable
,
351 &gEfiSetupVariableGuid
,
356 ASSERT_EFI_ERROR (Status
);
358 if(!EFI_ERROR (Status
)){
359 EnableSpreadSpectrum
= SystemConfiguration
.EnableClockSpreadSpec
;
363 // Perform platform-specific intialization dependent upon Board ID:
365 DEBUG((EFI_D_ERROR
, "board id is %x, platform id is %x\n",PlatformInfoHob
->BoardId
,PlatformInfoHob
->PlatformFlavor
));
368 switch (PlatformInfoHob
->BoardId
) {
369 case BOARD_ID_MINNOW2
:
370 case BOARD_ID_MINNOW2_TURBOT
:
372 switch(PlatformInfoHob
->PlatformFlavor
) {
374 ConfigurationTable
= ConfigurationTable_Tablet
;
375 Length
= sizeof (ConfigurationTable_Tablet
);
378 ConfigurationTable
= ConfigurationTable_Mobile
;
379 Length
= sizeof (ConfigurationTable_Mobile
);
383 ConfigurationTable
= ConfigurationTable_Desktop
;
384 Length
= sizeof (ConfigurationTable_Desktop
);
391 // Perform common clock initialization:
393 // Program Spread Spectrum function.
395 if (EnableSpreadSpectrum
)
397 ConfigurationTable
[mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumByteOffset
] |= mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumBitOffset
;
399 ConfigurationTable
[mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumByteOffset
] &= ~(mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumBitOffset
);
404 Status
= ConfigureClockGenerator (PeiServices
, SmbusPpi
, ClockType
, ClockAddress
, Length
, ConfigurationTable
);
405 ASSERT_EFI_ERROR (Status
);
410 static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
412 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
413 &gEfiPeiSmbusPpiGuid
,
414 ConfigurePlatformClocks
419 InstallPlatformClocksNotify (
420 IN CONST EFI_PEI_SERVICES
**PeiServices
425 DEBUG ((EFI_D_INFO
, "InstallPlatformClocksNotify()...\n"));
427 Status
= (*PeiServices
)->NotifyPpi(PeiServices
, &mNotifyList
[0]);
428 ASSERT_EFI_ERROR (Status
);
434 #pragma optimize( "", on )