5 * AMD Family_10 after warm reset sequence
7 * Performs the "CPU Core Minimum P-State Transition Sequence After Warm Reset"
8 * as described in the BKDG.
10 * @xrefitem bom "File Content Label" "Release Content"
12 * @e sub-project: CPU/Family/0x10
13 * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
17 *****************************************************************************
19 * Copyright (c) 2011, Advanced Micro Devices, Inc.
20 * All rights reserved.
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 * * Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * * Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
30 * its contributors may be used to endorse or promote products derived
31 * from this software without specific prior written permission.
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
37 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 * ***************************************************************************
48 /*----------------------------------------------------------------------------------------
49 * M O D U L E S U S E D
50 *----------------------------------------------------------------------------------------
54 #include "cpuF10PowerMgmt.h"
55 #include "cpuRegisters.h"
56 #include "cpuApicUtilities.h"
57 #include "cpuFamilyTranslation.h"
58 #include "cpuF10Utilities.h"
59 #include "GeneralServices.h"
60 #include "cpuServices.h"
63 RDATA_GROUP (G1_PEICC
)
65 #define FILECODE PROC_CPU_FAMILY_0X10_CPUF10EARLYINIT_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 *----------------------------------------------------------------------------------------
76 /// Enum for handling code branching while transitioning to the
77 /// minimum P-state after a warm reset
79 EXIT_SEQUENCE
, ///< Exit the sequence
80 STEP7
, ///< Go to step 7
81 STEP17
, ///< Go to step 17
82 STEP20
///< Go to step 20
85 /*----------------------------------------------------------------------------------------
86 * 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
87 *----------------------------------------------------------------------------------------
92 IN AMD_CONFIG_PARAMS
*StdHeader
97 WaitForCpuFidAndDidToMatch (
98 IN UINT32 PstateNumber
,
99 IN AMD_CONFIG_PARAMS
*StdHeader
102 /*----------------------------------------------------------------------------------------
103 * E X P O R T E D F U N C T I O N S
104 *----------------------------------------------------------------------------------------
107 /*---------------------------------------------------------------------------------------*/
109 * Family 10h core 0 entry point for performing the necessary steps after
110 * a warm reset has occurred.
112 * The steps are as follows:
113 * 1. Modify F3xDC[PstateMaxVal] to reflect the lowest performance P-state
114 * supported, as indicated in MSRC001_00[68:64][PstateEn]
115 * 2. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis]
116 * 3. If MSRC001_0071[CurPstate] != F3xDC[PstateMaxVal], go to step 20
117 * 4. If F3xDC[PstateMaxVal] = 0 or F3xDC[PstateMaxVal] != 4, go to step 7
118 * 5. If MSRC001_0061[CurPstateLimit] <= F3xDC[PstateMaxVal]-1, go to step 17
119 * 6. Exit the sequence
120 * 7. Copy the P-state register pointed to by F3xDC[PstateMaxVal] to the P-state
121 * register pointed to by F3xDC[PstateMaxVal]+1
122 * 8. Write F3xDC[PstateMaxVal]+1 to F3xDC[PstateMaxVal]
123 * 9. Write (the new) F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd]
124 * 10. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
125 * register pointed to by (the new) F3xDC[PstateMaxVal]
126 * 11. Copy (the new) F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd]
127 * 12. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
128 * register pointed to by (the new) F3xDC[PstateMaxVal]-1
129 * 13. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis]
130 * 14. If required, transition the NB COF and VID to the NbDid and NbVid from the
131 * P-state register pointed to by MSRC001_0061[CurPstateLimit] using the NB COF
132 * and VID transition sequence after a warm reset
133 * 15. Write MSRC001_00[68:64][PstateEn]=0 for the P-state pointed to by F3xDC[PstateMaxVal]
134 * 16. Write (the new) F3xDC[PstateMaxVal]-1 to F3xDC[PstateMaxVal] and exit the sequence
135 * 17. Copy F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd]
136 * 18. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
137 * register pointed to by F3xDC[PstateMaxVal]-1
138 * 19. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis]
139 * 20. Copy F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd]
140 * 21. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
141 * register pointed to by F3xDC[PstateMaxVal]
142 * 22. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis]
143 * 23. Issue an LDTSTOP assertion in the IO hub and exit sequence
144 * 24. If required, transition the NB COF and VID to the NbDid and NbVid from the
145 * P-state register pointed to by F3xDC[PstateMaxVal] using the NB COF and VID
146 * transition sequence after a warm reset
148 * @param[in] FamilySpecificServices The current Family Specific Services.
149 * @param[in] CpuEarlyParamsPtr Service parameters
150 * @param[in] StdHeader Config handle for library and services.
155 IN CPU_SPECIFIC_SERVICES
*FamilySpecificServices
,
156 IN AMD_CPU_EARLY_PARAMS
*CpuEarlyParamsPtr
,
157 IN AMD_CONFIG_PARAMS
*StdHeader
171 AGESA_STATUS IgnoredSts
;
173 IdentifyCore (StdHeader
, &Socket
, &Module
, &Core
, &IgnoredSts
);
174 GetPciAddress (StdHeader
, Socket
, Module
, &PciAddress
, &IgnoredSts
);
175 GetActiveCoresInCurrentSocket (&CoreNum
, StdHeader
);
179 // Step 1 Modify F3xDC[PstateMaxVal] to reflect the lowest performance
180 // P-state supported, as indicated in MSRC001_00[68:64][PstateEn]
181 for (MsrAddr
= PS_MAX_REG
; MsrAddr
> PS_REG_BASE
; --MsrAddr
) {
182 LibAmdMsrRead (MsrAddr
, &MsrReg
, StdHeader
);
183 if (((PSTATE_MSR
*) &MsrReg
)->PsEnable
== 1) {
187 PsMaxVal
= MsrAddr
- PS_REG_BASE
;
188 PciAddress
.Address
.Function
= FUNC_3
;
189 PciAddress
.Address
.Register
= CPTC2_REG
;
190 AndMask
= 0xFFFFFFFF;
192 ((CLK_PWR_TIMING_CTRL2_REGISTER
*) &AndMask
)->PstateMaxVal
= 0;
193 ((CLK_PWR_TIMING_CTRL2_REGISTER
*) &OrMask
)->PstateMaxVal
= PsMaxVal
;
194 ModifyCurrentSocketPci (&PciAddress
, AndMask
, OrMask
, StdHeader
);
196 // Launch each local core to perform the remaining steps.
197 TaskPtr
.FuncAddress
.PfApTask
= F10PmAfterResetCore
;
198 TaskPtr
.DataTransfer
.DataSizeInDwords
= 0;
199 TaskPtr
.ExeFlags
= WAIT_FOR_CORE
;
200 ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr
, StdHeader
, CpuEarlyParamsPtr
);
204 /*---------------------------------------------------------------------------------------
205 * L O C A L F U N C T I O N S
206 *---------------------------------------------------------------------------------------
209 /*---------------------------------------------------------------------------------------*/
211 * Support routine for F10PmAfterReset to perform MSR initialization on all
212 * cores of a family 10h socket.
214 * This function implements steps 2 - 24 on each core.
216 * @param[in] StdHeader Config handle for library and services.
221 F10PmAfterResetCore (
222 IN AMD_CONFIG_PARAMS
*StdHeader
232 UINT64 CurrentLimitMsr
;
235 AGESA_STATUS IgnoredSts
;
236 CPU_LOGICAL_ID LogicalId
;
237 CPU_SPECIFIC_SERVICES
*FamilySpecificServices
;
239 // Step 2 If MSR C001_0071[CurNbDid] = 0, set MSR C001_001F[GfxNbPstateDis]
240 GetLogicalIdOfCurrentCore (&LogicalId
, StdHeader
);
241 GetCpuServicesFromLogicalId (&LogicalId
, (const CPU_SPECIFIC_SERVICES
**)&FamilySpecificServices
, StdHeader
);
242 if ((LogicalId
.Revision
& (AMD_F10_C3
| AMD_F10_DA_C2
)) != 0) {
243 LibAmdMsrRead (MSR_COFVID_STS
, &MsrReg
, StdHeader
);
244 if (((COFVID_STS_MSR
*) &MsrReg
)->CurNbDid
== 0) {
245 LibAmdMsrRead (NB_CFG
, &MsrReg
, StdHeader
);
247 LibAmdMsrWrite (NB_CFG
, &MsrReg
, StdHeader
);
251 GoToStep
= EXIT_SEQUENCE
;
253 LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT
, &CurrentLimitMsr
, StdHeader
);
254 PsMaxVal
= (UINT32
) (((PSTATE_CURLIM_MSR
*) &CurrentLimitMsr
)->PstateMaxVal
);
256 // Step 3 If MSRC001_0071[CurPstate] != F3xDC[PstateMaxVal], go to step 20
257 LibAmdMsrRead (MSR_COFVID_STS
, &MsrReg
, StdHeader
);
258 if (((COFVID_STS_MSR
*) &MsrReg
)->CurPstate
!=
259 ((PSTATE_CURLIM_MSR
*) &CurrentLimitMsr
)->PstateMaxVal
) {
262 // Step 4 If F3xDC[PstateMaxVal] = 0 || F3xDC[PstateMaxVal] != 4, go to step 7
263 if ((PsMaxVal
== 0) || (PsMaxVal
!= 4)) {
266 // Step 5 If MSRC001_0061[CurPstateLimit] <= F3xDC[PstateMaxVal]-1, go to step 17
267 if (((PSTATE_CURLIM_MSR
*) &CurrentLimitMsr
)->CurPstateLimit
<=
268 (((PSTATE_CURLIM_MSR
*) &CurrentLimitMsr
)->PstateMaxVal
- 1)) {
276 // Step 6 Exit the sequence
279 // Workaround for S3 ----Save the value of [The PState[4:0] Registers] MSRC001_00[68:64]
280 // pointed to by F3xDC[PstateMaxVal] + 1
281 LibAmdMsrRead ((MSR_PSTATE_0
+ (PsMaxVal
+ 1)), &SavedMsr
, StdHeader
);
283 // Step 7 Copy the P-state register pointed to by F3xDC[PstateMaxVal] to the P-state
284 // register pointed to by F3xDC[PstateMaxVal]+1
285 LibAmdMsrRead ((MSR_PSTATE_0
+ PsMaxVal
), &MsrReg
, StdHeader
);
286 LibAmdMsrWrite ((MSR_PSTATE_0
+ (PsMaxVal
+ 1)), &MsrReg
, StdHeader
);
288 // Step 8 Write F3xDC[PstateMaxVal]+1 to F3xDC[PstateMaxVal]
289 IdentifyCore (StdHeader
, &Socket
, &Module
, &Ignored
, &IgnoredSts
);
290 GetPciAddress (StdHeader
, Socket
, Module
, &PciAddress
, &IgnoredSts
);
291 PciAddress
.Address
.Function
= FUNC_3
;
292 PciAddress
.Address
.Register
= CPTC2_REG
;
293 LibAmdPciRead (AccessWidth32
, PciAddress
, &PciRegister
, StdHeader
);
294 ((CLK_PWR_TIMING_CTRL2_REGISTER
*) &PciRegister
)->PstateMaxVal
= PsMaxVal
+ 1;
295 LibAmdPciWrite (AccessWidth32
, PciAddress
, &PciRegister
, StdHeader
);
297 // Step 9 Write (the new) F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd]
298 FamilySpecificServices
->TransitionPstate (FamilySpecificServices
, (UINT8
) (PsMaxVal
+ 1), (BOOLEAN
) FALSE
, StdHeader
);
300 // Step 10 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
301 // register pointed to by (the new) F3xDC[PstateMaxVal]
302 WaitForCpuFidAndDidToMatch ((UINT32
) (PsMaxVal
+ 1), StdHeader
);
304 // Step 11 Copy (the new) F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd]
305 FamilySpecificServices
->TransitionPstate (FamilySpecificServices
, (UINT8
) PsMaxVal
, (BOOLEAN
) FALSE
, StdHeader
);
307 // Step 12 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
308 // register pointed to by (the new) F3xDC[PstateMaxVal]-1
309 WaitForCpuFidAndDidToMatch (PsMaxVal
, StdHeader
);
311 // Step 13 If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis]
312 if ((LogicalId
.Revision
& (AMD_F10_C3
| AMD_F10_DA_C2
)) != 0) {
313 LibAmdMsrRead (MSR_COFVID_STS
, &MsrReg
, StdHeader
);
314 if (((COFVID_STS_MSR
*) &MsrReg
)->CurNbDid
== 1) {
315 LibAmdMsrRead (NB_CFG
, &MsrReg
, StdHeader
);
317 LibAmdMsrWrite (NB_CFG
, &MsrReg
, StdHeader
);
321 // Step 14 If required, transition the NB COF and VID to the NbDid and NbVid from the
322 // P-state register pointed to by MSRC001_0061[CurPstateLimit] using the NB COF
323 // and VID transition sequence after a warm reset
325 // Step 15 Write 0 to PstateEn of the P-state register pointed to by (the new) F3xDC[PstateMaxVal]
326 // Workaround for S3----Restore the value of [The PState[4:0] Registers] MSRC001_00[68:64]
327 // pointed to by F3xDC[PstateMaxVal] + 1
328 ((PSTATE_MSR
*) &SavedMsr
)->PsEnable
= 0;
329 LibAmdMsrWrite ((MSR_PSTATE_0
+ (PsMaxVal
+ 1)), &SavedMsr
, StdHeader
);
331 // Step 16 Write (the new) F3xDC[PstateMaxVal]-1 to F3xDC[PstateMaxVal]
332 LibAmdPciRead (AccessWidth32
, PciAddress
, &PciRegister
, StdHeader
);
333 ((CLK_PWR_TIMING_CTRL2_REGISTER
*) &PciRegister
)->PstateMaxVal
= PsMaxVal
;
334 LibAmdPciWrite (AccessWidth32
, PciAddress
, &PciRegister
, StdHeader
);
337 // Step 17 Copy F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd]
338 FamilySpecificServices
->TransitionPstate (FamilySpecificServices
, (UINT8
) (PsMaxVal
- 1), (BOOLEAN
) FALSE
, StdHeader
);
340 // Step 18 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
341 // register pointed to by F3xDC[PstateMaxVal]-1
342 WaitForCpuFidAndDidToMatch ((UINT32
) (PsMaxVal
- 1), StdHeader
);
344 // Step 19 If MSR C001_0071[CurNbDid] = 0, set MSR C001_001F[GfxNbPstateDis]
345 if ((LogicalId
.Revision
& (AMD_F10_C3
| AMD_F10_DA_C2
)) != 0) {
346 LibAmdMsrRead (MSR_COFVID_STS
, &MsrReg
, StdHeader
);
347 if (((COFVID_STS_MSR
*) &MsrReg
)->CurNbDid
== 0) {
348 LibAmdMsrRead (NB_CFG
, &MsrReg
, StdHeader
);
350 LibAmdMsrWrite (NB_CFG
, &MsrReg
, StdHeader
);
354 // Fall through from step 19 to step 20
356 // Step 20 Copy F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd]
357 FamilySpecificServices
->TransitionPstate (FamilySpecificServices
, (UINT8
) PsMaxVal
, (BOOLEAN
) FALSE
, StdHeader
);
359 // Step 21 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
360 // register pointed to by F3xDC[PstateMaxVal]
361 WaitForCpuFidAndDidToMatch (PsMaxVal
, StdHeader
);
363 // Step 22 If MSR C001_0071[CurNbDid] = 1, set MSR C001_001F[GfxNbPstateDis] and exit
365 if ((LogicalId
.Revision
& (AMD_F10_C3
| AMD_F10_DA_C2
)) != 0) {
366 LibAmdMsrRead (MSR_COFVID_STS
, &MsrReg
, StdHeader
);
367 if (((COFVID_STS_MSR
*) &MsrReg
)->CurNbDid
== 1) {
368 LibAmdMsrRead (NB_CFG
, &MsrReg
, StdHeader
);
370 LibAmdMsrWrite (NB_CFG
, &MsrReg
, StdHeader
);
375 // Step 23 Issue an LDTSTOP and exit the sequence
377 // Step 24 If required, transition the NB COF and VID to the NbDid and NbVid from the
378 // P-state register pointed to by F3xDC[PstateMaxVal] using the NB COF and VID
379 // transition sequence after a warm reset
384 /*---------------------------------------------------------------------------------------*/
386 * Support routine for F10PmAfterResetCore to wait for Cpu FID and DID to
387 * match a specific P-state.
389 * This function implements steps 11, 13, 18, and 20 on each core as needed.
391 * @param[in] PstateNumber P-state settings to match
392 * @param[in] StdHeader Config handle for library and services.
397 WaitForCpuFidAndDidToMatch (
398 IN UINT32 PstateNumber
,
399 IN AMD_CONFIG_PARAMS
*StdHeader
403 UINT64 CurrentStatus
;
406 CPUID_DATA CpuidData
;
408 // Check if CPB is supported. if yes, skip boosted p-state. The boosted p-state number = F4x15C[NumBoostStates].
409 LibAmdCpuidRead (AMD_CPUID_APM
, &CpuidData
, StdHeader
);
410 if (((CpuidData
.EDX_Reg
& 0x00000200) >> 9) == 1) {
411 PciAddress
.AddressValue
= CPB_CTRL_PCI_ADDR
;
412 LibAmdPciRead (AccessWidth32
, PciAddress
, &PciRegister
, StdHeader
); // F4x15C
413 PstateNumber
+= (UINT32
) (((CPB_CTRL_REGISTER
*) &PciRegister
)->NumBoostStates
);
416 // Get target P-state settings
417 LibAmdMsrRead ((MSR_PSTATE_0
+ PstateNumber
), &TargetPsMsr
, StdHeader
);
419 // Wait for current CPU FID/DID to match target FID/DID
421 LibAmdMsrRead (MSR_COFVID_STS
, &CurrentStatus
, StdHeader
);
422 } while ((((COFVID_STS_MSR
*) &CurrentStatus
)->CurCpuFid
!= ((PSTATE_MSR
*) &TargetPsMsr
)->CpuFid
) ||
423 (((COFVID_STS_MSR
*) &CurrentStatus
)->CurCpuDid
!= ((PSTATE_MSR
*) &TargetPsMsr
)->CpuDid
));