Update AMD F14 Agesa to support Rev C0 cpus
[coreboot.git] / src / vendorcode / amd / agesa / f14 / Proc / CPU / Family / 0x10 / cpuF10EarlyInit.c
blobd9639c228f85c77cf8dace069689500f70af2ad9
1 /* $NoKeywords:$ */
2 /**
3 * @file
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"
11 * @e project: AGESA
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 *----------------------------------------------------------------------------------------
52 #include "AGESA.h"
53 #include "amdlib.h"
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"
61 #include "Filecode.h"
62 CODE_GROUP (G1_PEICC)
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
78 typedef enum {
79 EXIT_SEQUENCE, ///< Exit the sequence
80 STEP7, ///< Go to step 7
81 STEP17, ///< Go to step 17
82 STEP20 ///< Go to step 20
83 } GO_TO_STEP;
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 *----------------------------------------------------------------------------------------
89 VOID
90 STATIC
91 F10PmAfterResetCore (
92 IN AMD_CONFIG_PARAMS *StdHeader
95 VOID
96 STATIC
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.
153 VOID
154 F10PmAfterReset (
155 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
156 IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr,
157 IN AMD_CONFIG_PARAMS *StdHeader
160 UINT32 Socket;
161 UINT32 Module;
162 UINT32 PsMaxVal;
163 UINT32 CoreNum;
164 UINT32 MsrAddr;
165 UINT32 Core;
166 UINT32 AndMask;
167 UINT32 OrMask;
168 UINT64 MsrReg;
169 PCI_ADDR PciAddress;
170 AP_TASK TaskPtr;
171 AGESA_STATUS IgnoredSts;
173 IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts);
174 GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);
175 GetActiveCoresInCurrentSocket (&CoreNum, StdHeader);
177 ASSERT (Core == 0);
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) {
184 break;
187 PsMaxVal = MsrAddr - PS_REG_BASE;
188 PciAddress.Address.Function = FUNC_3;
189 PciAddress.Address.Register = CPTC2_REG;
190 AndMask = 0xFFFFFFFF;
191 OrMask = 0x00000000;
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.
219 VOID
220 STATIC
221 F10PmAfterResetCore (
222 IN AMD_CONFIG_PARAMS *StdHeader
225 UINT32 Socket;
226 UINT32 Module;
227 UINT32 Ignored;
228 UINT32 PsMaxVal;
229 UINT32 PciRegister;
230 UINT64 MsrReg;
231 UINT64 SavedMsr;
232 UINT64 CurrentLimitMsr;
233 PCI_ADDR PciAddress;
234 GO_TO_STEP GoToStep;
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);
246 MsrReg |= BIT62;
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) {
260 GoToStep = STEP20;
261 } else {
262 // Step 4 If F3xDC[PstateMaxVal] = 0 || F3xDC[PstateMaxVal] != 4, go to step 7
263 if ((PsMaxVal == 0) || (PsMaxVal != 4)) {
264 GoToStep = STEP7;
265 } else {
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)) {
269 GoToStep = STEP17;
273 switch (GoToStep) {
274 default:
275 case EXIT_SEQUENCE:
276 // Step 6 Exit the sequence
277 break;
278 case STEP7:
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);
316 MsrReg |= BIT62;
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);
335 break;
336 case STEP17:
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);
349 MsrReg |= BIT62;
350 LibAmdMsrWrite (NB_CFG, &MsrReg, StdHeader);
354 // Fall through from step 19 to step 20
355 case STEP20:
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
364 // the sequence
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);
369 MsrReg |= BIT62;
370 LibAmdMsrWrite (NB_CFG, &MsrReg, StdHeader);
371 break;
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
380 break;
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.
395 VOID
396 STATIC
397 WaitForCpuFidAndDidToMatch (
398 IN UINT32 PstateNumber,
399 IN AMD_CONFIG_PARAMS *StdHeader
402 UINT64 TargetPsMsr;
403 UINT64 CurrentStatus;
404 UINT32 PciRegister;
405 PCI_ADDR PciAddress;
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
420 do {
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));