5 * AMD Family_10 Pstate feature support functions.
7 * Provides the functions necessary to initialize the Pstate feature.
9 * @xrefitem bom "File Content Label" "Release Content"
11 * @e sub-project: CPU/F10
12 * @e \$Revision: 56279 $ @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
16 ******************************************************************************
18 * Copyright (C) 2012 Advanced Micro Devices, Inc.
19 * All rights reserved.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 ******************************************************************************
46 /*----------------------------------------------------------------------------------------
47 * M O D U L E S U S E D
48 *----------------------------------------------------------------------------------------
52 #include "GeneralServices.h"
53 #include "cpuPstateTables.h"
55 #include "cpuFamilyTranslation.h"
56 #include "cpuFamRegisters.h"
57 #include "cpuF10Utilities.h"
58 #include "cpuF10PowerMgmt.h"
59 #include "CommonReturns.h"
60 #include "OptionMultiSocket.h"
65 #define FILECODE PROC_CPU_FAMILY_0X10_CPUF10PSTATE_FILECODE
67 /*----------------------------------------------------------------------------------------
68 * D E F I N I T I O N S A N D M A C R O S
69 *----------------------------------------------------------------------------------------
72 /*----------------------------------------------------------------------------------------
73 * T Y P E D E F S A N D S T R U C T U R E S
74 *----------------------------------------------------------------------------------------
77 /*----------------------------------------------------------------------------------------
78 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
79 *----------------------------------------------------------------------------------------
83 F10GetPstateTransLatency (
84 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
85 IN PSTATE_LEVELING *PStateLevelingBufferStructPtr,
86 IN PCI_ADDR *PciAddress,
87 OUT UINT32 *TransitionLatency,
88 IN AMD_CONFIG_PARAMS *StdHeader
92 F10GetPstateFrequency (
93 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
95 OUT UINT32 *FrequencyInMHz,
96 IN AMD_CONFIG_PARAMS *StdHeader
100 F10PstateLevelingCoreMsrModify (
101 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
102 IN S_CPU_AMD_PSTATE *CpuAmdPState,
103 IN AMD_CONFIG_PARAMS *StdHeader
108 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
109 IN UINT8 StateNumber,
110 OUT UINT32 *PowerInMw,
111 IN AMD_CONFIG_PARAMS *StdHeader
115 F10GetPstateMaxState (
116 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
117 OUT UINT32 *MaxPStateNumber,
118 OUT UINT8 *NumberOfBoostStates,
119 IN AMD_CONFIG_PARAMS *StdHeader
123 F10GetPstateRegisterInfo (
124 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
126 OUT BOOLEAN *PStateEnabled,
127 IN OUT UINT32 *IddVal,
128 IN OUT UINT32 *IddDiv,
129 OUT UINT32 *SwPstateNumber,
130 IN AMD_CONFIG_PARAMS *StdHeader
135 F10GetPowerStepValueInTime (
136 IN OUT UINT32 *PowerStepPtr
141 F10GetPllValueInTime (
142 IN OUT UINT32 *PllLockTimePtr
147 F10GetFrequencyXlatRegInfo (
148 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
149 IN UINT8 PStateNumber,
151 OUT UINT32 *CpuFidPtr,
152 OUT UINT32 *CpuDidPtr1,
153 OUT UINT32 *CpuDidPtr2,
154 IN AMD_CONFIG_PARAMS *StdHeader
157 /*----------------------------------------------------------------------------------------
158 * E X P O R T E D F U N C T I O N S
159 *----------------------------------------------------------------------------------------
161 extern BUILD_OPT_CFG UserOptions;
162 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
163 /*---------------------------------------------------------------------------------------*/
165 * Family specific call to check if Pstate PSD is dependent.
167 * @param[in] PstateCpuServices Pstate CPU services.
168 * @param[in,out] PlatformConfig Contains the runtime modifiable feature input data.
169 * @param[in] StdHeader Config Handle for library, services.
171 * @retval TRUE PSD is dependent.
172 * @retval FALSE PSD is independent.
177 F10IsPstatePsdDependent (
178 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
179 IN OUT PLATFORM_CONFIGURATION *PlatformConfig,
180 IN AMD_CONFIG_PARAMS *StdHeader
183 CPU_LOGICAL_ID CpuLogicalId;
184 PLATFORM_FEATS Features;
186 // Initialize the union
187 Features.PlatformValue = 0;
188 GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader);
189 GetPlatformFeatures (&Features, PlatformConfig, StdHeader);
192 // RevC and later Single link has PSD option, default is dependent.
193 // If multi-link, always return independent.
195 if ((Features.PlatformFeatures.PlatformSingleLink) && ((CpuLogicalId.Revision & AMD_F10_GT_Bx) != 0)) {
196 if (PlatformConfig->ForcePstateIndependent) {
205 * Family specific call to set core TscFreqSel.
207 * @param[in] PstateCpuServices Pstate CPU services.
208 * @param[in] StdHeader Config Handle for library, services.
214 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
215 IN AMD_CONFIG_PARAMS *StdHeader
220 LibAmdMsrRead (MSR_HWCR, &MsrValue, StdHeader);
221 if (UserOptions.OptionMultisocket) {
223 // If Agesa need to do p-state leveling on multi-socket, changing the P0
224 // frequency after setting this bit has no effect on the TSC rate.
226 ASSERT ((MsrValue & BIT24) == 0);
228 MsrValue = MsrValue | BIT24;
229 LibAmdMsrWrite (MSR_HWCR, &MsrValue, StdHeader);
232 /*---------------------------------------------------------------------------------------*/
234 * Family specific call to get Pstate Transition Latency.
236 * Calculate TransitionLatency by power step value and pll value.
238 * @param[in] PstateCpuServices Pstate CPU services.
239 * @param[in] PStateLevelingBufferStructPtr Pstate row data buffer pointer
240 * @param[in] PciAddress Pci address
241 * @param[out] TransitionLatency The transition latency.
242 * @param[in] StdHeader Header for library and services
244 * @retval AGESA_SUCCESS Always succeeds.
247 F10GetPstateTransLatency (
248 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
249 IN PSTATE_LEVELING *PStateLevelingBufferStructPtr,
250 IN PCI_ADDR *PciAddress,
251 OUT UINT32 *TransitionLatency,
252 IN AMD_CONFIG_PARAMS *StdHeader
262 UINT32 CpuFidSameFlag;
263 UINT8 PStateMaxValueOnCurrentCore;
264 UINT32 TransAndBusMastLatency;
268 F10GetFrequencyXlatRegInfo (
271 PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[0].CoreFreq,
278 TempVar_d = TempVar_b;
279 PStateMaxValueOnCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue;
282 //Check if MSRC001_00[68:64][CpuFid] is the same value for all P-states where
283 //MSRC001_00[68:64][PstateEn]=1
285 for (k = 1; k <= PStateMaxValueOnCurrentCore; k++) {
286 if (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].PStateEnable != 0) {
287 F10GetFrequencyXlatRegInfo (
290 PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq,
298 if (TempVar_d != TempVar_b) {
304 PciAddress->Address.Register = 0xD4;
305 PciAddress->Address.Function = FUNC_3;
306 LibAmdPciRead (AccessWidth32, *PciAddress, &TempVar_d, StdHeader);
308 // PowerStepDown - Bits 20:23
309 TempVar8_a = (TempVar_d & 0x00F00000) >> 20;
311 // PowerStepUp - Bits 24:27
312 TempVar8_b = (TempVar_d & 0x0F000000) >> 24;
314 // Convert the raw numbers in TempVar8_a and TempVar8_b into time
315 F10GetPowerStepValueInTime (&TempVar8_a);
316 F10GetPowerStepValueInTime (&TempVar8_b);
319 //(12 * (F3xD4[PowerStepDown] + F3xD4[PowerStepUp]) /1000) us
321 TransAndBusMastLatency =
322 (12 * (TempVar8_a + TempVar8_b) + 999) / 1000;
324 if (CpuFidSameFlag == 0) {
326 //+ F3xA0[PllLockTime]
328 PciAddress->Address.Register = 0xA0;
329 LibAmdPciRead (AccessWidth32, *PciAddress, &TempVar_d, StdHeader);
331 TempVar8_a = (0x00003800 & TempVar_d) >> 11;
332 F10GetPllValueInTime (&TempVar8_a);
333 TransAndBusMastLatency += TempVar8_a;
336 *TransitionLatency = TransAndBusMastLatency;
338 return (AGESA_SUCCESS);
341 /*---------------------------------------------------------------------------------------*/
343 * Family specific call to calculates the frequency in megahertz of the desired P-state.
345 * @param[in] PstateCpuServices Pstate CPU services.
346 * @param[in] StateNumber The P-State to analyze.
347 * @param[out] FrequencyInMHz The P-State's frequency in MegaHertz
348 * @param[in] StdHeader Header for library and services
350 * @retval AGESA_SUCCESS Always Succeeds.
353 F10GetPstateFrequency (
354 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
355 IN UINT8 StateNumber,
356 OUT UINT32 *FrequencyInMHz,
357 IN AMD_CONFIG_PARAMS *StdHeader
363 UINT64 LocalMsrRegister;
365 ASSERT (StateNumber < NM_PS_REG);
366 LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader);
367 ASSERT (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1);
368 CpuDid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuDid);
369 CpuFid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuFid);
388 // CpuDid is set to an undefined value. This is due to either a misfused CPU, or
389 // an invalid P-state MSR write.
394 *FrequencyInMHz = (100 * (CpuFid + 0x10) / TempValue);
395 return (AGESA_SUCCESS);
398 /*---------------------------------------------------------------------------------------*/
400 * Family specific call to sets the Pstate MSR to each APs base on Pstate Buffer.
402 * @param[in] PstateCpuServices Pstate CPU services.
403 * @param[in] CpuAmdPState Gathered P-state data structure for whole system.
404 * @param[in] StdHeader Config for library and services.
406 * @retval AGESA_SUCCESS Always succeeds.
410 F10PstateLevelingCoreMsrModify (
411 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
412 IN S_CPU_AMD_PSTATE *CpuAmdPState,
413 IN AMD_CONFIG_PARAMS *StdHeader
422 UINT32 LogicalSocketCount;
423 UINT32 LocalPciRegister;
429 PSTATE_LEVELING *PStateBufferPtr;
430 PSTATE_LEVELING *PStateBufferPtrTmp;
431 S_CPU_AMD_PSTATE *CpuAmdPstatePtr;
433 CPU_SPECIFIC_SERVICES *FamilySpecificServices;
435 GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
436 ASSERT (FamilySpecificServices != NULL);
439 CpuAmdPstatePtr = (S_CPU_AMD_PSTATE *) CpuAmdPState;
440 PStateBufferPtrTmp = CpuAmdPstatePtr->PStateLevelingStruc;
441 PStateBufferPtr = CpuAmdPstatePtr->PStateLevelingStruc;
442 LogicalSocketCount = CpuAmdPstatePtr->TotalSocketInSystem;
443 PciAddress.AddressValue = 0;
446 //Try to find the Pstate buffer specific to this core(socket).
448 IdentifyCore (StdHeader, &Socket, &Module, &Core, &Status);
449 for (i = 0; i < LogicalSocketCount; i++) {
450 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, CpuAmdPstatePtr, i, StdHeader);
451 if (PStateBufferPtrTmp->SocketNumber == Socket) {
456 if (PStateBufferPtr[0].OnlyOneEnabledPState) {
458 //If all processors have only 1 enabled P-state, the following sequence should be performed on all cores:
461 //1. Write the appropriate CpuFid value resulting from the matched CPU COF to MSRC001_0064[CpuFid].
462 LibAmdMsrRead (MSR_PSTATE_0, &MsrValue, StdHeader);
463 Status = F10GetFrequencyXlatRegInfo (PstateCpuServices, 0, PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].CoreFreq, &TempVar_d, &TempVar_e, &Ignored, StdHeader);
465 ((PSTATE_MSR *) &MsrValue)->CpuFid = TempVar_d;
467 ((PSTATE_MSR *) &MsrValue)->CpuDid = TempVar_e;
469 ((PSTATE_MSR *) &MsrValue)->IddValue = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddValue;
471 ((PSTATE_MSR *) &MsrValue)->IddDiv = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddDiv;
472 // Enable the P-State
473 ((PSTATE_MSR *) &MsrValue)->PsEnable = 1;
474 LibAmdMsrWrite (MSR_PSTATE_0, &MsrValue, StdHeader);
476 //2. Copy MSRC001_0064 to MSRC001_0065.
477 LibAmdMsrWrite (MSR_PSTATE_1, &MsrValue, StdHeader);
479 //3. Write 001b to F3xDC[PstatemaxVal].
480 GetPciAddress (StdHeader, Socket, Module, &PciAddress, &Status);
481 PciAddress.Address.Register = CPTC2_REG;
482 PciAddress.Address.Function = FUNC_3;
483 LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
484 ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal = 1;
485 LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
487 //4. Write 001b to MSRC001_0062[PstateCmd].
488 FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 1, (BOOLEAN) FALSE, StdHeader);
490 //5. Wait for MSRC001_0071[CurCpuFid] = MSRC001_0065[CpuFid].
492 LibAmdMsrRead (MSR_COFVID_STS, &MsrValue, StdHeader);
493 } while (((COFVID_STS_MSR *) &MsrValue)->CurCpuFid != TempVar_d);
495 //6. Write 000b to MSRC001_0062[PstateCmd].
496 FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader);
498 //7. Wait for MSRC001_0071[CurCpuFid] = MSRC001_0064[CpuFid].
500 LibAmdMsrRead (MSR_COFVID_STS, &MsrValue, StdHeader);
501 } while (((COFVID_STS_MSR *) &MsrValue)->CurCpuFid != TempVar_d);
503 //8. Write 0b to MSRC001_0065[PstateEn].
504 LibAmdMsrRead (MSR_PSTATE_1, &MsrValue, StdHeader);
505 ((PSTATE_MSR *) &MsrValue)->PsEnable = 0;
506 LibAmdMsrWrite (MSR_PSTATE_1, &MsrValue, StdHeader);
508 //9. Write 000b to F3xDC[PstateMaxVal] and exit the sequence (no further steps are required).
509 LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
510 ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal = 0;
511 LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
514 TempVar_f = MSR_PSTATE_0;
516 for (k = 0; k <= PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; k++, TempVar_f++) {
517 // If pState is not disabled then do update
518 LibAmdMsrRead (TempVar_f, &MsrValue, StdHeader);
520 if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable == 1) {
521 Status = F10GetFrequencyXlatRegInfo (PstateCpuServices, (UINT8) k, PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].CoreFreq, &TempVar_d, &TempVar_e, &Ignored, StdHeader);
522 if (Status != AGESA_ERROR) {
524 ((PSTATE_MSR *) &MsrValue)->CpuFid = TempVar_d;
526 ((PSTATE_MSR *) &MsrValue)->CpuDid = TempVar_e;
530 ((PSTATE_MSR *) &MsrValue)->IddValue = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].IddValue;
532 ((PSTATE_MSR *) &MsrValue)->IddDiv = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].IddDiv;
533 // Enable the P-State
534 ((PSTATE_MSR *) &MsrValue)->PsEnable = 1;
535 LibAmdMsrWrite (TempVar_f, &MsrValue, StdHeader);
537 // Disable the P-State
538 ((PSTATE_MSR *) &MsrValue)->PsEnable = 0;
539 LibAmdMsrWrite (TempVar_f, &MsrValue, StdHeader);
543 return AGESA_SUCCESS;
546 /*---------------------------------------------------------------------------------------*/
548 * Family specific call to calculates the power in milliWatts of the desired P-state.
550 * @param[in] PstateCpuServices Pstate CPU services.
551 * @param[in] StateNumber Which P-state to analyze
552 * @param[out] PowerInMw The Power in milliWatts of that P-State
553 * @param[in] StdHeader Header for library and services
555 * @retval AGESA_SUCCESS Always succeeds.
559 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
560 IN UINT8 StateNumber,
561 OUT UINT32 *PowerInMw,
562 IN AMD_CONFIG_PARAMS *StdHeader
573 UINT64 LocalMsrRegister;
575 ASSERT (StateNumber < NM_PS_REG);
576 LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader);
577 ASSERT (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1);
578 CpuVid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuVid);
579 IddValue = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->IddValue);
580 IddDiv = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->IddDiv);
582 OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
584 PciAddress.Address.Function = FUNC_3;
585 PciAddress.Address.Register = POWER_CTRL_MISCELLANEOUS_REG;
586 LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_a, StdHeader);
587 if ((TempVar_a & 0x00000100) != 0) {
593 // Set CpuVid value in case CPU is in PVI mode
596 } else if (CpuVid > 0x3E) {
597 CpuVid = CpuVid - 0x1F;
599 CpuVid = (CpuVid >> 1);
603 if (CpuVid >= 0x20) {
604 V_x10000 = 7625L - (125L * (CpuVid - 0x20));
606 V_x10000 = 15500L - (250L * CpuVid);
609 if (CpuVid >= 0x7C) {
612 V_x10000 = 15500L - (125L * CpuVid);
616 Power = V_x10000 * IddValue;
620 *PowerInMw = Power / 10L;
623 *PowerInMw = Power / 100L;
626 *PowerInMw = Power / 1000L;
629 // IddDiv is set to an undefined value. This is due to either a misfused CPU, or
630 // an invalid P-state MSR write.
635 return (AGESA_SUCCESS);
638 /*---------------------------------------------------------------------------------------*/
640 * Family specific call to get CPU pstate max state.
642 * @param[in] PstateCpuServices Pstate CPU services.
643 * @param[out] MaxPStateNumber The max hw pstate value on the current socket.
644 * @param[out] NumberOfBoostStates The number of boosted P-states on the current socket.
645 * @param[in] StdHeader Handle of Header for calling lib functions and services.
647 * @retval AGESA_SUCCESS Always succeeds.
650 F10GetPstateMaxState (
651 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
652 OUT UINT32 *MaxPStateNumber,
653 OUT UINT8 *NumberOfBoostStates,
654 IN AMD_CONFIG_PARAMS *StdHeader
657 UINT8 NumBoostStates;
660 NumBoostStates = F10GetNumberOfBoostedPstatesOnCore (StdHeader);
662 // Read PstateMaxVal [6:4] from MSR C001_0061
663 // So, we will know the max pstate state in this socket.
665 LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &MsrValue, StdHeader);
666 *MaxPStateNumber = (UINT32) (((PSTATE_CURLIM_MSR *) &MsrValue)->PstateMaxVal) + (UINT32) (NumBoostStates);
667 *NumberOfBoostStates = NumBoostStates;
669 return (AGESA_SUCCESS);
672 /*---------------------------------------------------------------------------------------*/
674 * Family specific call to get CPU pstate register information.
676 * @param[in] PstateCpuServices Pstate CPU services.
677 * @param[in] PState Input Pstate number for query.
678 * @param[out] PStateEnabled Boolean flag return pstate enable.
679 * @param[in,out] IddVal Pstate current value.
680 * @param[in,out] IddDiv Pstate current divisor.
681 * @param[out] SwPstateNumber Software P-state number.
682 * @param[in] StdHeader Handle of Header for calling lib functions and services.
684 * @retval AGESA_SUCCESS Always succeeds.
687 F10GetPstateRegisterInfo (
688 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
690 OUT BOOLEAN *PStateEnabled,
691 IN OUT UINT32 *IddVal,
692 IN OUT UINT32 *IddDiv,
693 OUT UINT32 *SwPstateNumber,
694 IN AMD_CONFIG_PARAMS *StdHeader
697 UINT8 NumBoostStates;
698 UINT64 LocalMsrRegister;
700 ASSERT (PState < NM_PS_REG);
702 // Check if CPB is supported. if yes, skip boosted p-state. The boosted p-state number = F4x15C[NumBoostStates].
703 NumBoostStates = F10GetNumberOfBoostedPstatesOnCore (StdHeader);
706 LibAmdMsrRead (PS_REG_BASE + (UINT32) PState, &LocalMsrRegister, StdHeader);
708 if (PState < NumBoostStates) {
710 *PStateEnabled = FALSE;
712 *SwPstateNumber = PState - NumBoostStates;
713 if (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1) {
714 // PState enable = bit 63
715 *PStateEnabled = TRUE;
717 *PStateEnabled = FALSE;
721 // Bits 39:32 (high 32 bits [7:0])
722 *IddVal = (UINT32) ((PSTATE_MSR *) &LocalMsrRegister)->IddValue;
723 // Bits 41:40 (high 32 bits [9:8])
724 *IddDiv = (UINT32) ((PSTATE_MSR *) &LocalMsrRegister)->IddDiv;
726 return (AGESA_SUCCESS);
729 CONST PSTATE_CPU_FAMILY_SERVICES ROMDATA F10PstateServices =
732 (PF_PSTATE_PSD_IS_NEEDED) CommonReturnTrue,
733 F10IsPstatePsdDependent,
735 F10GetPstateTransLatency,
736 F10GetPstateFrequency,
737 F10PstateLevelingCoreMsrModify,
739 F10GetPstateMaxState,
740 F10GetPstateRegisterInfo
744 /*---------------------------------------------------------------------------------------
745 * L O C A L F U N C T I O N S
746 *---------------------------------------------------------------------------------------
751 *---------------------------------------------------------------------------------------
753 * F10GetPowerStepValueInTime
756 * Convert power step value in time
759 * @param[out] *PowerStepPtr
763 *---------------------------------------------------------------------------------------
767 F10GetPowerStepValueInTime (
768 IN OUT UINT32 *PowerStepPtr
773 TempVar_a = *PowerStepPtr;
775 if (TempVar_a < 0x4) {
776 *PowerStepPtr = 400 - (TempVar_a * 100);
777 } else if (TempVar_a < 0x9) {
778 *PowerStepPtr = 130 - (TempVar_a * 10);
780 *PowerStepPtr = 90 - (TempVar_a * 5);
786 *---------------------------------------------------------------------------------------
788 * F10GetPllValueInTime
791 * Convert PLL Value in time
794 * @param[out] *PllLockTimePtr
798 *---------------------------------------------------------------------------------------
802 F10GetPllValueInTime (
803 IN OUT UINT32 *PllLockTimePtr
806 if (*PllLockTimePtr < 4) {
807 *PllLockTimePtr = *PllLockTimePtr + 1;
808 } else if (*PllLockTimePtr == 4) {
810 } else if (*PllLockTimePtr == 5) {
811 *PllLockTimePtr = 16;
816 /*---------------------------------------------------------------------------------------*/
818 * This function will return the CpuFid and CpuDid in MHz, using the formula
819 * described in the BKDG MSRC001_00[68:64] P-State [4:0] Registers:bit 8:0
821 * @param[in] PstateCpuServices The current Family Specific Services.
822 * @param[in] PStateNumber P-state number to check.
823 * @param[in] Frequency Leveled target frequency for PStateNumber.
824 * @param[out] *CpuFidPtr New leveled FID.
825 * @param[out] *CpuDidPtr1 New leveled DID info 1.
826 * @param[out] *CpuDidPtr2 New leveled DID info 2.
827 * @param[in] *StdHeader Header for library and services.
829 * @retval AGESA_WARNING This P-State does not need to be modified.
830 * @retval AGESA_SUCCESS This P-State must be modified to be level.
834 F10GetFrequencyXlatRegInfo (
835 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
836 IN UINT8 PStateNumber,
838 OUT UINT32 *CpuFidPtr,
839 OUT UINT32 *CpuDidPtr1,
840 OUT UINT32 *CpuDidPtr2,
841 IN AMD_CONFIG_PARAMS *StdHeader
847 UINT32 FrequencyInMHz;
850 *CpuDidPtr2 = 0xFFFF;
852 Status = AGESA_SUCCESS;
854 PstateCpuServices->GetPstateFrequency (PstateCpuServices, PStateNumber, &FrequencyInMHz, StdHeader);
855 if (FrequencyInMHz == Frequency) {
856 Status |= AGESA_WARNING;
859 // CPU Frequency = 100 MHz * (CpuFid + 10h) / (2^CpuDid)
860 // In this for loop i = 2^CpuDid
863 for (i = 1; i < 17; (i += i)) {
864 for (j = 0; j < 64; j++) {
865 if (Frequency == ((100 * (j + 0x10)) / i )) {
875 } else if (i == 16) {
879 *CpuDidPtr1 = 0xFFFF;
889 *CpuDidPtr1 = 0x00FF;
890 *CpuDidPtr2 = 0x00FF;