2 Clock generator setting for multiplatform.
4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <BoardClkGens.h>
13 #include <Guid/SetupVariable.h>
14 #include <Ppi/ReadOnlyVariable2.h>
15 #include <Library/BaseMemoryLib.h>
18 #pragma optimize( "", off )
24 CLOCK_GENERATOR_DETAILS mSupportedClockGeneratorTable
[] =
26 { ClockGeneratorCk410
, CK410_GENERATOR_ID
, CK410_GENERATOR_SPREAD_SPECTRUM_BYTE
, CK410_GENERATOR_SPREAD_SPECTRUM_BIT
},
27 { ClockGeneratorCk505
, CK505_GENERATOR_ID
, CK505_GENERATOR_SPREAD_SPECTRUM_BYTE
, CK505_GENERATOR_SPREAD_SPECTRUM_BIT
}
31 Configure the clock generator using the SMBUS PPI services.
33 This function performs a block write, and dumps debug information.
35 @param PeiServices General purpose services available to every PEIM.
36 @param ClockType Clock generator's model name.
37 @param ClockAddress SMBUS address of clock generator.
38 @param ConfigurationTableLength Length of configuration table.
39 @param ConfigurationTable Pointer of configuration table.
41 @retval EFI_SUCCESS - Operation success.
45 ConfigureClockGenerator (
46 IN EFI_PEI_SERVICES
**PeiServices
,
47 IN EFI_PEI_SMBUS_PPI
*SmbusPpi
,
48 IN CLOCK_GENERATOR_TYPE ClockType
,
49 IN UINT8 ClockAddress
,
50 IN UINTN ConfigurationTableLength
,
51 IN OUT UINT8
*ConfigurationTable
56 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
;
57 UINT8 Buffer
[MAX_CLOCK_GENERATOR_BUFFER_LENGTH
];
59 EFI_SMBUS_DEVICE_COMMAND Command
;
60 #if CLKGEN_CONFIG_EXTRA
65 // Verify input arguments
67 ASSERT (ConfigurationTableLength
>= 6);
68 ASSERT (ConfigurationTableLength
<= MAX_CLOCK_GENERATOR_BUFFER_LENGTH
);
69 ASSERT (ClockType
< ClockGeneratorMax
);
70 ASSERT (ConfigurationTable
!= NULL
);
73 // Read the clock generator
75 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
76 Length
= sizeof (Buffer
);
78 Status
= SmbusPpi
->Execute (
88 ASSERT_EFI_ERROR (Status
);
93 for (i
= 0; i
< sizeof (Buffer
); i
++) {
94 DEBUG((EFI_D_ERROR
, "CK505 default Clock Generator Byte %d: %x\n", i
, Buffer
[i
]));
97 for (i
= 0; i
< ConfigurationTableLength
; i
++) {
98 DEBUG((EFI_D_ERROR
, "BIOS structure Clock Generator Byte %d: %x\n", i
, ConfigurationTable
[i
]));
104 DEBUG((EFI_D_ERROR
, "Expected Clock Generator ID is %x, expecting %x\n", mSupportedClockGeneratorTable
[ClockType
].ClockId
,(Buffer
[7]&0xF)));
107 // Program clock generator
111 #if CLKGEN_CONFIG_EXTRA
112 for (j
= 0; j
< ConfigurationTableLength
; j
++) {
113 Buffer
[j
] = ConfigurationTable
[j
];
118 Status
= SmbusPpi
->Execute (
129 Status
= SmbusPpi
->Execute (
136 &ConfigurationTableLength
,
139 #endif // CLKGEN_CONFIG_EXTRA
141 ConfigurationTable
[4] = (ConfigurationTable
[4] & 0x3) | (Buffer
[4] & 0xFC);
144 Status
= SmbusPpi
->Execute (
152 &ConfigurationTable
[4]
155 ASSERT_EFI_ERROR (Status
);
158 // Dump contents after write
163 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
164 Length
= sizeof (Buffer
);
166 Status
= SmbusPpi
->Execute (
177 for (i
= 0; i
< ConfigurationTableLength
; i
++) {
178 DEBUG((EFI_D_ERROR
, "Clock Generator Byte %d: %x\n", i
, Buffer
[i
]));
187 Configure the clock generator using the SMBUS PPI services.
189 This function performs a block write, and dumps debug information.
191 @param PeiServices General purpose services available to every PEIM.
192 @param ClockType Clock generator's model name.
193 @param ClockAddress SMBUS address of clock generator.
194 @param ConfigurationTableLength Length of configuration table.
195 @param ConfigurationTable Pointer of configuration table.
198 @retval EFI_SUCCESS Operation success.
202 ReadClockGeneratorID (
203 IN EFI_PEI_SERVICES
**PeiServices
,
204 IN EFI_PEI_SMBUS_PPI
*SmbusPpi
,
205 IN UINT8 ClockAddress
208 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
;
209 UINT8 Buffer
[MAX_CLOCK_GENERATOR_BUFFER_LENGTH
];
211 EFI_SMBUS_DEVICE_COMMAND Command
;
214 // Read the clock generator
216 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
217 Length
= sizeof (Buffer
);
231 // Sanity check that the requested clock type is present in our supported clocks table
233 DEBUG((EFI_D_ERROR
, "Expected Clock Generator ID is 0x%x\n", Buffer
[7]));
239 Configure the clock generator to enable free-running operation. This keeps
240 the clocks from being stopped when the system enters C3 or C4.
244 @retval EFI_SUCCESS The function completed successfully.
248 ConfigurePlatformClocks (
249 IN EFI_PEI_SERVICES
**PeiServices
,
250 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
255 // Comment it out for now
256 // Not supported by Hybrid model.
259 UINT8
*ConfigurationTable
;
261 CLOCK_GENERATOR_TYPE ClockType
= ClockGeneratorCk505
;
262 UINT8 ConfigurationTable_Desktop
[] = CLOCK_GENERATOR_SETTINGS_DESKTOP
;
263 UINT8 ConfigurationTable_Mobile
[] = CLOCK_GENERATOR_SETTINGS_MOBILE
;
264 UINT8 ConfigurationTable_Tablet
[] = CLOCK_GENERATOR_SEETINGS_TABLET
;
266 EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
;
267 BOOLEAN EnableSpreadSpectrum
;
268 SYSTEM_CONFIGURATION SystemConfiguration
;
271 EFI_SMBUS_DEVICE_COMMAND Command
;
272 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
;
275 UINT8 ClockAddress
= CLOCK_GENERATOR_ADDRESS
;
277 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
280 // Obtain Platform Info from HOB.
282 Status
= GetPlatformInfoHob ((CONST EFI_PEI_SERVICES
**) PeiServices
, &PlatformInfoHob
);
283 ASSERT_EFI_ERROR (Status
);
285 DEBUG((EFI_D_ERROR
, "PlatformInfo protocol is working in ConfigurePlatformClocks()...%x\n",PlatformInfoHob
->PlatformFlavor
));
290 Status
= (**PeiServices
).LocatePpi (
291 (CONST EFI_PEI_SERVICES
**) PeiServices
,
292 &gEfiPeiSmbusPpiGuid
,
297 ASSERT_EFI_ERROR (Status
);
300 SlaveAddress
.SmbusDeviceAddress
= ClockAddress
>> 1;
302 Command
= 0x87; //Control Register 7 Vendor ID Check
303 Status
= ((EFI_PEI_SMBUS_PPI
*) SmbusPpi
)->Execute (
314 if (EFI_ERROR (Status
) || ((Data
& 0x0F) != CK505_GENERATOR_ID
)) {
315 DEBUG((EFI_D_ERROR
, "Clock Generator CK505 Not Present, vendor ID on board is %x\n",(Data
& 0x0F)));
319 EnableSpreadSpectrum
= FALSE
;
320 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
321 ZeroMem (&SystemConfiguration
, sizeof (SYSTEM_CONFIGURATION
));
323 Status
= (*PeiServices
)->LocatePpi (
324 (CONST EFI_PEI_SERVICES
**) PeiServices
,
325 &gEfiPeiReadOnlyVariable2PpiGuid
,
331 // Use normal setup default from NVRAM variable,
332 // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
334 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
335 Status
= Variable
->GetVariable (Variable
,
337 &gEfiSetupVariableGuid
,
340 &SystemConfiguration
);
341 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
342 //The setup variable is corrupted
343 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
344 Status
= Variable
->GetVariable(Variable
,
346 &gEfiSetupVariableGuid
,
351 ASSERT_EFI_ERROR (Status
);
353 if(!EFI_ERROR (Status
)){
354 EnableSpreadSpectrum
= SystemConfiguration
.EnableClockSpreadSpec
;
358 // Perform platform-specific intialization dependent upon Board ID:
360 DEBUG((EFI_D_ERROR
, "board id is %x, platform id is %x\n",PlatformInfoHob
->BoardId
,PlatformInfoHob
->PlatformFlavor
));
363 switch (PlatformInfoHob
->BoardId
) {
364 case BOARD_ID_MINNOW2
:
365 case BOARD_ID_MINNOW2_TURBOT
:
367 switch(PlatformInfoHob
->PlatformFlavor
) {
369 ConfigurationTable
= ConfigurationTable_Tablet
;
370 Length
= sizeof (ConfigurationTable_Tablet
);
373 ConfigurationTable
= ConfigurationTable_Mobile
;
374 Length
= sizeof (ConfigurationTable_Mobile
);
378 ConfigurationTable
= ConfigurationTable_Desktop
;
379 Length
= sizeof (ConfigurationTable_Desktop
);
386 // Perform common clock initialization:
388 // Program Spread Spectrum function.
390 if (EnableSpreadSpectrum
)
392 ConfigurationTable
[mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumByteOffset
] |= mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumBitOffset
;
394 ConfigurationTable
[mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumByteOffset
] &= ~(mSupportedClockGeneratorTable
[ClockType
].SpreadSpectrumBitOffset
);
399 Status
= ConfigureClockGenerator (PeiServices
, SmbusPpi
, ClockType
, ClockAddress
, Length
, ConfigurationTable
);
400 ASSERT_EFI_ERROR (Status
);
405 static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
407 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
408 &gEfiPeiSmbusPpiGuid
,
409 ConfigurePlatformClocks
414 InstallPlatformClocksNotify (
415 IN CONST EFI_PEI_SERVICES
**PeiServices
420 DEBUG ((EFI_D_INFO
, "InstallPlatformClocksNotify()...\n"));
422 Status
= (*PeiServices
)->NotifyPpi(PeiServices
, &mNotifyList
[0]);
423 ASSERT_EFI_ERROR (Status
);
429 #pragma optimize( "", on )