5 * AMD Family_15 Orochi 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/Family/0x15/OR
12 * @e \$Revision: 55600 $ @e \$Date: 2011-06-23 12:39:18 -0600 (Thu, 23 Jun 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"
54 #include "cpuRegisters.h"
56 #include "cpuFamilyTranslation.h"
57 #include "cpuFamRegisters.h"
58 #include "cpuF15Utilities.h"
59 #include "cpuF15PowerMgmt.h"
60 #include "cpuF15OrPowerMgmt.h"
61 #include "OptionMultiSocket.h"
66 #define FILECODE PROC_CPU_FAMILY_0X15_OR_CPUF15ORPSTATE_FILECODE
69 /*----------------------------------------------------------------------------------------
70 * D E F I N I T I O N S A N D M A C R O S
71 *----------------------------------------------------------------------------------------
74 /*----------------------------------------------------------------------------------------
75 * T Y P E D E F S A N D S T R U C T U R E S
76 *----------------------------------------------------------------------------------------
79 /*----------------------------------------------------------------------------------------
80 * 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
81 *----------------------------------------------------------------------------------------
85 F15OrGetPowerStepValueInTime (
86 IN OUT UINT32 *PowerStepPtr
91 F15OrGetPllValueInTime (
92 IN OUT UINT32 *PllLockTimePtr
97 F15OrGetFrequencyXlatRegInfo (
98 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
99 IN UINT8 PStateNumber,
101 OUT UINT32 *CpuFidPtr,
102 OUT UINT32 *CpuDidPtr1,
103 OUT UINT32 *CpuDidPtr2,
104 IN AMD_CONFIG_PARAMS *StdHeader
108 F15OrGetPstateTransLatency (
109 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
110 IN PSTATE_LEVELING *PStateLevelingBufferStructPtr,
111 IN PCI_ADDR *PciAddress,
112 OUT UINT32 *TransitionLatency,
113 IN AMD_CONFIG_PARAMS *StdHeader
117 F15OrGetPstateFrequency (
118 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
119 IN UINT8 StateNumber,
120 OUT UINT32 *FrequencyInMHz,
121 IN AMD_CONFIG_PARAMS *StdHeader
125 F15OrPstateLevelingCoreMsrModify (
126 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
127 IN S_CPU_AMD_PSTATE *CpuAmdPState,
128 IN AMD_CONFIG_PARAMS *StdHeader
132 F15OrGetPstatePower (
133 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
134 IN UINT8 StateNumber,
135 OUT UINT32 *PowerInMw,
136 IN AMD_CONFIG_PARAMS *StdHeader
140 F15OrGetPstateMaxState (
141 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
142 OUT UINT32 *MaxPStateNumber,
143 OUT UINT8 *NumberOfBoostStates,
144 IN AMD_CONFIG_PARAMS *StdHeader
148 F15OrGetPstateRegisterInfo (
149 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
151 OUT BOOLEAN *PStateEnabled,
152 IN OUT UINT32 *IddVal,
153 IN OUT UINT32 *IddDiv,
154 OUT UINT32 *SwPstateNumber,
155 IN AMD_CONFIG_PARAMS *StdHeader
160 /*----------------------------------------------------------------------------------------
161 * E X P O R T E D F U N C T I O N S
162 *----------------------------------------------------------------------------------------
164 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
166 /*---------------------------------------------------------------------------------------*/
168 * Family specific call to check if PSD need to be generated.
170 * @param[in] PstateCpuServices Pstate CPU services.
171 * @param[in,out] PlatformConfig Contains the runtime modifiable feature input data.
172 * @param[in] StdHeader Config Handle for library, services.
174 * @retval TRUE PSD need to be generated
175 * @retval FALSE PSD does NOT need to be generated
180 F15OrIsPstatePsdNeeded (
181 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
182 IN OUT PLATFORM_CONFIGURATION *PlatformConfig,
183 IN AMD_CONFIG_PARAMS *StdHeader
186 UINT32 LocalPciRegister;
188 PLATFORM_FEATS Features;
190 // Initialize the union
191 Features.PlatformValue = 0;
192 GetPlatformFeatures (&Features, PlatformConfig, StdHeader);
195 // For Single link processor, PSD needs to be generated
196 // For other processor, if D18F5x80[DualCore][0]=0, the _PSD object does not need to be generated.
198 OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
199 PciAddress.Address.Register = COMPUTE_UNIT_STATUS;
200 PciAddress.Address.Function = FUNC_5;
201 LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
202 if ((!Features.PlatformFeatures.PlatformSingleLink) && ((LocalPciRegister & 0x10000) == 0)) {
209 /*---------------------------------------------------------------------------------------*/
211 * Family specific call to check if Pstate PSD is dependent.
213 * @param[in] PstateCpuServices Pstate CPU services.
214 * @param[in,out] PlatformConfig Contains the runtime modifiable feature input data.
215 * @param[in] StdHeader Config Handle for library, services.
217 * @retval TRUE PSD is dependent.
218 * @retval FALSE PSD is independent.
223 F15OrIsPstatePsdDependent (
224 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
225 IN OUT PLATFORM_CONFIGURATION *PlatformConfig,
226 IN AMD_CONFIG_PARAMS *StdHeader
229 PLATFORM_FEATS Features;
231 // Initialize the union
232 Features.PlatformValue = 0;
233 GetPlatformFeatures (&Features, PlatformConfig, StdHeader);
236 // For Single link has PSD option, default is dependent.
237 // If multi-link, always return independent.
239 if (Features.PlatformFeatures.PlatformSingleLink) {
240 if (PlatformConfig->ForcePstateIndependent) {
249 * Family specific call to set core TscFreqSel.
251 * @param[in] PstateCpuServices Pstate CPU services.
252 * @param[in] StdHeader Config Handle for library, services.
258 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
259 IN AMD_CONFIG_PARAMS *StdHeader
262 //TscFreqSel: TSC frequency select. Read-only. Reset: 1. 1=The TSC increments at the P0 frequency.
263 //This field uses software P-state numbering.
267 /*---------------------------------------------------------------------------------------*/
269 * Family specific call to get Pstate Transition Latency.
271 * Calculate TransitionLatency by power step value and pll value.
273 * @param[in] PstateCpuServices Pstate CPU services.
274 * @param[in] PStateLevelingBufferStructPtr Pstate row data buffer pointer
275 * @param[in] PciAddress Pci address
276 * @param[out] TransitionLatency The transition latency.
277 * @param[in] StdHeader Header for library and services
279 * @retval AGESA_SUCCESS Always succeeds.
282 F15OrGetPstateTransLatency (
283 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
284 IN PSTATE_LEVELING *PStateLevelingBufferStructPtr,
285 IN PCI_ADDR *PciAddress,
286 OUT UINT32 *TransitionLatency,
287 IN AMD_CONFIG_PARAMS *StdHeader
297 UINT32 CpuFidSameFlag;
298 UINT8 PStateMaxValueOnCurrentCore;
299 UINT32 TransAndBusMastLatency;
303 F15OrGetFrequencyXlatRegInfo (
306 PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[0].CoreFreq,
313 TempVar_d = TempVar_b;
314 PStateMaxValueOnCurrentCore = PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateMaxValue;
317 //Check if MSRC001_00[6B:64][CpuFid] is the same value for all P-states where
318 //MSRC001_00[6B:64][PstateEn]=1
320 for (k = 1; k <= PStateMaxValueOnCurrentCore; k++) {
321 if (PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].PStateEnable != 0) {
322 F15OrGetFrequencyXlatRegInfo (
325 PStateLevelingBufferStructPtr->PStateCoreStruct[0].PStateStruct[k].CoreFreq,
333 if (TempVar_d != TempVar_b) {
339 PciAddress->Address.Register = 0xD4;
340 PciAddress->Address.Function = FUNC_3;
341 LibAmdPciRead (AccessWidth32, *PciAddress, &TempVar_d, StdHeader);
343 // PowerStepDown - Bits 20:23
344 TempVar8_a = (TempVar_d & 0x00F00000) >> 20;
346 // PowerStepUp - Bits 24:27
347 TempVar8_b = (TempVar_d & 0x0F000000) >> 24;
349 // Convert the raw numbers in TempVar8_a and TempVar8_b into time
350 F15OrGetPowerStepValueInTime (&TempVar8_a);
351 F15OrGetPowerStepValueInTime (&TempVar8_b);
354 //(12 * (F3xD4[PowerStepDown] + F3xD4[PowerStepUp]) /1000) us
356 TransAndBusMastLatency =
357 (12 * (TempVar8_a + TempVar8_b) + 999) / 1000;
359 if (CpuFidSameFlag == 0) {
361 //+ F3xA0[PllLockTime]
363 PciAddress->Address.Register = 0xA0;
364 LibAmdPciRead (AccessWidth32, *PciAddress, &TempVar_d, StdHeader);
366 TempVar8_a = (0x00003800 & TempVar_d) >> 11;
367 F15OrGetPllValueInTime (&TempVar8_a);
368 TransAndBusMastLatency += TempVar8_a;
371 *TransitionLatency = TransAndBusMastLatency;
373 return (AGESA_SUCCESS);
376 /*---------------------------------------------------------------------------------------*/
378 * Family specific call to calculates the frequency in megahertz of the desired P-state.
380 * @param[in] PstateCpuServices Pstate CPU services.
381 * @param[in] StateNumber The hardware P-State to analyze.
382 * @param[out] FrequencyInMHz The P-State's frequency in MegaHertz
383 * @param[in] StdHeader Header for library and services
385 * @retval AGESA_SUCCESS Always Succeeds.
388 F15OrGetPstateFrequency (
389 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
390 IN UINT8 StateNumber,
391 OUT UINT32 *FrequencyInMHz,
392 IN AMD_CONFIG_PARAMS *StdHeader
398 UINT64 LocalMsrRegister;
400 ASSERT (StateNumber < NM_PS_REG);
401 LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader);
402 ASSERT (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1);
403 CpuDid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuDid);
404 CpuFid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuFid);
423 // CpuDid is set to an undefined value. This is due to either a misfused CPU, or
424 // an invalid P-state MSR write.
429 *FrequencyInMHz = (100 * (CpuFid + 0x10) / TempValue);
430 return (AGESA_SUCCESS);
433 /*---------------------------------------------------------------------------------------*/
435 * Family specific call to sets the Pstate MSR to each APs base on Pstate Buffer.
437 * @param[in] PstateCpuServices Pstate CPU services.
438 * @param[in] CpuAmdPState Gathered P-state data structure for whole system.
439 * @param[in] StdHeader Config for library and services.
441 * @retval AGESA_STATUS AGESA_SUCCESS Always succeeds.
445 F15OrPstateLevelingCoreMsrModify (
446 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
447 IN S_CPU_AMD_PSTATE *CpuAmdPState,
448 IN AMD_CONFIG_PARAMS *StdHeader
457 UINT32 LogicalSocketCount;
458 UINT32 LocalPciRegister;
465 PSTATE_LEVELING *PStateBufferPtr;
466 PSTATE_LEVELING *PStateBufferPtrTmp;
467 S_CPU_AMD_PSTATE *CpuAmdPstatePtr;
469 CPU_SPECIFIC_SERVICES *FamilySpecificServices;
471 GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader);
472 ASSERT (FamilySpecificServices != NULL);
475 CpuAmdPstatePtr = (S_CPU_AMD_PSTATE *) CpuAmdPState;
476 PStateBufferPtrTmp = CpuAmdPstatePtr->PStateLevelingStruc;
477 PStateBufferPtr = CpuAmdPstatePtr->PStateLevelingStruc;
478 LogicalSocketCount = CpuAmdPstatePtr->TotalSocketInSystem;
479 PciAddress.AddressValue = 0;
480 SwP0 = PStateBufferPtrTmp->PStateCoreStruct[0].NumberOfBoostedStates;
483 //Try to find the Pstate buffer specific to this core(socket).
485 IdentifyCore (StdHeader, &Socket, &Module, &Core, &Status);
486 GetPciAddress (StdHeader, Socket, Module, &PciAddress, &Status);
487 for (i = 0; i < LogicalSocketCount; i++) {
488 CpuGetPStateLevelStructure (&PStateBufferPtrTmp, CpuAmdPstatePtr, i, StdHeader);
489 if (PStateBufferPtrTmp->SocketNumber == Socket) {
494 if (PStateBufferPtr[0].OnlyOneEnabledPState) {
496 //If all processors have only 1 enabled P-state, the following sequence should be performed on all cores:
499 //1. Write the appropriate CpuFid value resulting from the matched CPU COF to 'software P0'.
500 LibAmdMsrRead (MSR_PSTATE_0 + (UINT32) SwP0, &MsrValue, StdHeader);
501 Status = F15OrGetFrequencyXlatRegInfo (PstateCpuServices, SwP0, PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].CoreFreq, &TempVar_d, &TempVar_e, &Ignored, StdHeader);
503 ((PSTATE_MSR *) &MsrValue)->CpuFid = TempVar_d;
505 ((PSTATE_MSR *) &MsrValue)->CpuDid = TempVar_e;
507 ((PSTATE_MSR *) &MsrValue)->IddValue = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddValue;
509 ((PSTATE_MSR *) &MsrValue)->IddDiv = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[0].IddDiv;
510 // Enable the P-State
511 ((PSTATE_MSR *) &MsrValue)->PsEnable = 1;
512 LibAmdMsrWrite (MSR_PSTATE_0 + (UINT32) SwP0, &MsrValue, StdHeader);
515 LibAmdMsrWrite (MSR_PSTATE_1 + (UINT32) SwP0, &MsrValue, StdHeader);
517 //3. Increment F3xDC[PstatemaxVal] by 1.
518 PciAddress.Address.Register = CPTC2_REG;
519 PciAddress.Address.Function = FUNC_3;
520 LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
521 ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal++;
522 LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
524 //4. Write 001b to MSRC001_0062[PstateCmd].
525 FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 1, (BOOLEAN) FALSE, StdHeader);
527 //5. Wait for MSRC001_0071[CurCpuFid] = P1[CpuFid].
529 LibAmdMsrRead (MSR_COFVID_STS, &MsrValue, StdHeader);
530 } while (((COFVID_STS_MSR *) &MsrValue)->CurCpuFid != TempVar_d);
532 //6. Write 000b to MSRC001_0062[PstateCmd].
533 FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader);
535 //7. Wait for MSRC001_0071[CurPstate] = MSRC001_0071[CurPstateLimit].
537 LibAmdMsrRead (MSR_COFVID_STS, &MsrValue, StdHeader);
538 } while (((COFVID_STS_MSR *) &MsrValue)->CurPstate != ((COFVID_STS_MSR *) &MsrValue)->CurPstateLimit);
540 //8. Write 0b to P1[PstateEn].
541 LibAmdMsrRead (MSR_PSTATE_1 + (UINT32) SwP0, &MsrValue, StdHeader);
542 ((PSTATE_MSR *) &MsrValue)->PsEnable = 0;
543 LibAmdMsrWrite (MSR_PSTATE_1 + (UINT32) SwP0, &MsrValue, StdHeader);
545 //9. Decrement F3xDC[PstateMaxVal] by 1 and exit the sequence (no further steps are required).
546 LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
547 ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal--;
548 LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
552 TempVar_f = MSR_PSTATE_0 + (UINT32) SwP0;
554 for (k = SwP0; k <= PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; k++, TempVar_f++) {
555 // If pState is not disabled then do update
556 LibAmdMsrRead (TempVar_f, &MsrValue, StdHeader);
558 if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable == 1) {
559 Status = F15OrGetFrequencyXlatRegInfo (PstateCpuServices, (UINT8) k, PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].CoreFreq, &TempVar_d, &TempVar_e, &Ignored, StdHeader);
560 if (Status != AGESA_ERROR) {
562 ((PSTATE_MSR *) &MsrValue)->CpuFid = TempVar_d;
564 ((PSTATE_MSR *) &MsrValue)->CpuDid = TempVar_e;
568 ((PSTATE_MSR *) &MsrValue)->IddValue = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].IddValue;
570 ((PSTATE_MSR *) &MsrValue)->IddDiv = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].IddDiv;
571 // Enable the P-State
572 ((PSTATE_MSR *) &MsrValue)->PsEnable = 1;
573 LibAmdMsrWrite (TempVar_f, &MsrValue, StdHeader);
575 // Disable the P-State
576 ((PSTATE_MSR *) &MsrValue)->PsEnable = 0;
577 LibAmdMsrWrite (TempVar_f, &MsrValue, StdHeader);
581 return AGESA_SUCCESS;
584 /*---------------------------------------------------------------------------------------*/
586 * Family specific call to calculates the power in milliWatts of the desired P-state.
588 * @param[in] PstateCpuServices Pstate CPU services.
589 * @param[in] StateNumber Which P-state to analyze
590 * @param[out] PowerInMw The Power in milliWatts of that P-State
591 * @param[in] StdHeader Header for library and services
593 * @retval AGESA_SUCCESS Always succeeds.
596 F15OrGetPstatePower (
597 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
598 IN UINT8 StateNumber,
599 OUT UINT32 *PowerInMw,
600 IN AMD_CONFIG_PARAMS *StdHeader
608 UINT64 LocalMsrRegister;
610 ASSERT (StateNumber < NM_PS_REG);
611 LibAmdMsrRead (PS_REG_BASE + (UINT32) StateNumber, &LocalMsrRegister, StdHeader);
612 ASSERT (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1);
613 CpuVid = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->CpuVid);
614 IddValue = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->IddValue);
615 IddDiv = (UINT32) (((PSTATE_MSR *) &LocalMsrRegister)->IddDiv);
617 if (CpuVid >= 0x7C) {
620 V_x10000 = 15500L - (125L * CpuVid);
623 Power = V_x10000 * IddValue;
627 *PowerInMw = Power / 10L;
630 *PowerInMw = Power / 100L;
633 *PowerInMw = Power / 1000L;
636 // IddDiv is set to an undefined value. This is due to either a misfused CPU, or
637 // an invalid P-state MSR write.
642 return (AGESA_SUCCESS);
645 /*---------------------------------------------------------------------------------------*/
647 * Family specific call to get CPU pstate max state.
649 * @param[in] PstateCpuServices Pstate CPU services.
650 * @param[out] MaxPStateNumber The max hw pstate value on the current socket.
651 * @param[out] NumberOfBoostStates The number of boosted P-states on the current socket.
652 * @param[in] StdHeader Handle of Header for calling lib functions and services.
654 * @retval AGESA_SUCCESS Always succeeds.
657 F15OrGetPstateMaxState (
658 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
659 OUT UINT32 *MaxPStateNumber,
660 OUT UINT8 *NumberOfBoostStates,
661 IN AMD_CONFIG_PARAMS *StdHeader
664 UINT32 NumBoostStates;
666 UINT32 LocalPciRegister;
669 LocalPciRegister = 0;
671 // For F15 Orochi CPU, skip boosted p-state. The boosted p-state number = D[1F:18]F4x15C[NumBoostStates].
672 OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
673 PciAddress.Address.Register = CPB_CTRL_REG;
674 PciAddress.Address.Function = FUNC_4;
675 LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F4x15C
677 NumBoostStates = ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates;
678 *NumberOfBoostStates = (UINT8) NumBoostStates;
681 // Read PstateMaxVal [6:4] from MSR C001_0061
682 // So, we will know the max pstate state in this socket.
684 LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &MsrValue, StdHeader);
685 *MaxPStateNumber = (UINT32) (((PSTATE_CURLIM_MSR *) &MsrValue)->PstateMaxVal) + NumBoostStates;
687 return (AGESA_SUCCESS);
690 /*---------------------------------------------------------------------------------------*/
692 * Family specific call to get CPU pstate register information.
694 * @param[in] PstateCpuServices Pstate CPU services.
695 * @param[in] PState Input Pstate number for query.
696 * @param[out] PStateEnabled Boolean flag return pstate enable.
697 * @param[in,out] IddVal Pstate current value.
698 * @param[in,out] IddDiv Pstate current divisor.
699 * @param[out] SwPstateNumber Software P-state number.
700 * @param[in] StdHeader Handle of Header for calling lib functions and services.
702 * @retval AGESA_SUCCESS Always succeeds.
705 F15OrGetPstateRegisterInfo (
706 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
708 OUT BOOLEAN *PStateEnabled,
709 IN OUT UINT32 *IddVal,
710 IN OUT UINT32 *IddDiv,
711 OUT UINT32 *SwPstateNumber,
712 IN AMD_CONFIG_PARAMS *StdHeader
715 UINT32 LocalPciRegister;
716 UINT64 LocalMsrRegister;
719 ASSERT (PState < NM_PS_REG);
721 // For F15 Orochi CPU, skip boosted p-state. The boosted p-state number = D[1F:18]F4x15C[NumBoostStates].
722 OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
723 PciAddress.Address.Register = CPB_CTRL_REG;
724 PciAddress.Address.Function = FUNC_4;
725 LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F4x15C
728 LibAmdMsrRead (PS_REG_BASE + (UINT32) PState, &LocalMsrRegister, StdHeader);
730 *SwPstateNumber = PState;
732 if (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1) {
733 // PState enable = bit 63
734 *PStateEnabled = TRUE;
736 // Check input pstate belongs to Boosted-Pstate, if yes, return *PStateEnabled = FALSE.
738 if (PState < ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates) {
739 *PStateEnabled = FALSE;
741 *SwPstateNumber = PState - ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates;
744 *PStateEnabled = FALSE;
747 // Bits 39:32 (high 32 bits [7:0])
748 *IddVal = (UINT32) ((PSTATE_MSR *) &LocalMsrRegister)->IddValue;
749 // Bits 41:40 (high 32 bits [9:8])
750 *IddDiv = (UINT32) ((PSTATE_MSR *) &LocalMsrRegister)->IddDiv;
752 return (AGESA_SUCCESS);
756 CONST PSTATE_CPU_FAMILY_SERVICES ROMDATA F15OrPstateServices =
759 F15OrIsPstatePsdNeeded,
760 F15OrIsPstatePsdDependent,
762 F15OrGetPstateTransLatency,
763 F15OrGetPstateFrequency,
764 F15OrPstateLevelingCoreMsrModify,
766 F15OrGetPstateMaxState,
767 F15OrGetPstateRegisterInfo
771 /*---------------------------------------------------------------------------------------
772 * L O C A L F U N C T I O N S
773 *---------------------------------------------------------------------------------------
778 *---------------------------------------------------------------------------------------
780 * F15OrGetPowerStepValueInTime
783 * Convert power step value in time
786 * @param[out] *PowerStepPtr
790 *---------------------------------------------------------------------------------------
794 F15OrGetPowerStepValueInTime (
795 IN OUT UINT32 *PowerStepPtr
800 TempVar_a = *PowerStepPtr;
802 if (TempVar_a < 0x4) {
803 *PowerStepPtr = 400 - (TempVar_a * 100);
804 } else if (TempVar_a < 0x9) {
805 *PowerStepPtr = 130 - (TempVar_a * 10);
807 *PowerStepPtr = 90 - (TempVar_a * 5);
812 *---------------------------------------------------------------------------------------
814 * F15OrGetPllValueInTime
817 * Convert PLL Value in time
820 * @param[out] *PllLockTimePtr
824 *---------------------------------------------------------------------------------------
828 F15OrGetPllValueInTime (
829 IN OUT UINT32 *PllLockTimePtr
832 if (*PllLockTimePtr < 4) {
833 *PllLockTimePtr = *PllLockTimePtr + 1;
834 } else if (*PllLockTimePtr == 4) {
836 } else if (*PllLockTimePtr == 5) {
837 *PllLockTimePtr = 16;
842 /*---------------------------------------------------------------------------------------*/
844 * This function will return the CpuFid and CpuDid in MHz, using the formula
845 * described in the BKDG MSRC001_00[68:64] P-State [4:0] Registers:bit 8:0
847 * @param[in] PstateCpuServices The current Family Specific Services.
848 * @param[in] PStateNumber P-state number to check.
849 * @param[in] Frequency Leveled target frequency for PStateNumber.
850 * @param[out] *CpuFidPtr New leveled FID.
851 * @param[out] *CpuDidPtr1 New leveled DID info 1.
852 * @param[out] *CpuDidPtr2 New leveled DID info 2.
853 * @param[in] *StdHeader Header for library and services.
855 * @retval AGESA_WARNING This P-State does not need to be modified.
856 * @retval AGESA_SUCCESS This P-State must be modified to be level.
860 F15OrGetFrequencyXlatRegInfo (
861 IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices,
862 IN UINT8 PStateNumber,
864 OUT UINT32 *CpuFidPtr,
865 OUT UINT32 *CpuDidPtr1,
866 OUT UINT32 *CpuDidPtr2,
867 IN AMD_CONFIG_PARAMS *StdHeader
873 UINT32 FrequencyInMHz;
876 *CpuDidPtr2 = 0xFFFF;
878 Status = AGESA_SUCCESS;
880 PstateCpuServices->GetPstateFrequency (PstateCpuServices, PStateNumber, &FrequencyInMHz, StdHeader);
881 if (FrequencyInMHz == Frequency) {
882 Status |= AGESA_WARNING;
885 // CPU Frequency = 100 MHz * (CpuFid + 10h) / (2^CpuDid)
886 // In this for loop i = 2^CpuDid
889 for (i = 1; i < 17; (i += i)) {
890 for (j = 0; j < 64; j++) {
891 if (Frequency == ((100 * (j + 0x10)) / i )) {
901 } else if (i == 16) {
905 *CpuDidPtr1 = 0xFFFF;
915 *CpuDidPtr1 = 0x00FF;
916 *CpuDidPtr2 = 0x00FF;