blob: 1694a93cd9be17ee11e7d11f3f5bb5f1d90a4ee5 [file] [log] [blame]
Frank Vibrans2b4c8312011-02-14 18:30:54 +00001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD Family_14 Power Plane Initialization
6 *
7 * Performs the "BIOS Requirements for Power Plane Initialization" as described
8 * in the BKDG.
9 *
10 * @xrefitem bom "File Content Label" "Release Content"
11 * @e project: AGESA
12 * @e sub-project: CPU/F14
13 * @e \$Revision: 39275 $ @e \$Date: 2010-10-09 08:22:05 +0800 (Sat, 09 Oct 2010) $
14 *
15 */
16/*
17 *****************************************************************************
18 *
19 * Copyright (c) 2011, Advanced Micro Devices, Inc.
20 * All rights reserved.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100021 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000022 * 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.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100029 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
30 * its contributors may be used to endorse or promote products derived
Frank Vibrans2b4c8312011-02-14 18:30:54 +000031 * from this software without specific prior written permission.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100032 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000033 * 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.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100043 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000044 * ***************************************************************************
45 *
46 */
47
48/*----------------------------------------------------------------------------------------
49 * M O D U L E S U S E D
50 *----------------------------------------------------------------------------------------
51 */
52#include "AGESA.h"
53#include "amdlib.h"
54#include "Ids.h"
55#include "cpuCacheInit.h"
56#include "cpuRegisters.h"
57#include "cpuFamilyTranslation.h"
58#include "cpuServices.h"
59#include "cpuF14PowerMgmt.h"
efdesign9884cbce22011-08-04 12:09:17 -060060#include "cpuF14PowerPlane.h"
Frank Vibrans2b4c8312011-02-14 18:30:54 +000061#include "OptionFamily14hEarlySample.h"
62#include "NbSmuLib.h"
63#include "GnbRegistersON.h"
64#include "Filecode.h"
65#define FILECODE PROC_CPU_FAMILY_0X14_CPUF14POWERPLANE_FILECODE
66
67/*----------------------------------------------------------------------------------------
68 * D E F I N I T I O N S A N D M A C R O S
69 *----------------------------------------------------------------------------------------
70 */
71extern F14_ES_CORE_SUPPORT F14EarlySampleCoreSupport;
72
73// Register encodings for D18F3xD8[VSRampSlamTime]
74STATIC CONST UINT32 ROMDATA F14VSRampSlamWaitTimes[8] =
75{
76 625, // 000b: 6.25us
77 500, // 001b: 5.00us
78 417, // 010b: 4.17us
79 313, // 011b: 3.13us
80 250, // 100b: 2.50us
81 167, // 101b: 1.67us
82 125, // 110b: 1.25us
83 100 // 111b: 1.00us
84};
85
86/*----------------------------------------------------------------------------------------
87 * T Y P E D E F S A N D S T R U C T U R E S
88 *----------------------------------------------------------------------------------------
89 */
90
91/*----------------------------------------------------------------------------------------
92 * 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
93 *----------------------------------------------------------------------------------------
94 */
95VOID
96STATIC
97F14PmVrmLowPowerModeEnable (
98 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
99 IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams,
100 IN AMD_CONFIG_PARAMS *StdHeader
101 );
102
103
104/*----------------------------------------------------------------------------------------
105 * E X P O R T E D F U N C T I O N S
106 *----------------------------------------------------------------------------------------
107 */
108
109/*---------------------------------------------------------------------------------------*/
110/**
111 * Family 14h core 0 entry point for performing power plane initialization.
112 *
113 * The steps are as follows:
114 * 1. BIOS must initialize D18F3xD8[VSRampSlamTime].
115 * 2. BIOS must configure D18F3xA0[PsiVidEn & PsiVid] and
116 * D18F3x128[NbPsiVidEn & NbPsiVid].
117 * 3. BIOS must program D18F3xDC[NbPs0Vid] = FCRxFE00_6000[NbPs0Vid] - 1.
118 * BIOS must program D18F3xDC[NbPs0Vid] = FCRxFE00_6000[NbPs0Vid].
119 *
120 * @param[in] FamilySpecificServices The current Family Specific Services.
121 * @param[in] CpuEarlyParams Service parameters
122 * @param[in] StdHeader Config handle for library and services.
123 *
124 */
125VOID
126F14PmPwrPlaneInit (
127 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
128 IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams,
129 IN AMD_CONFIG_PARAMS *StdHeader
130 )
131{
132 UINT32 SystemSlewRate;
efdesign9884cbce22011-08-04 12:09:17 -0600133 UINT32 PciReg;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000134 UINT32 WaitTime;
135 UINT32 VSRampSlamTime;
136 PCI_ADDR PciAddress;
137 FCRxFE00_6000_STRUCT FCRxFE00_6000;
138
139 // Step 1 - Configure D18F3xD8[VSRampSlamTime] based on platform requirements.
140 // Voltage Ramp Time = maximum time to change voltage by 12.5mV rounded to the next higher encoding.
141 SystemSlewRate = (CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].SlewRate <=
142 CpuEarlyParams->PlatformConfig.VrmProperties[NbVrm].SlewRate) ?
143 CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].SlewRate :
144 CpuEarlyParams->PlatformConfig.VrmProperties[NbVrm].SlewRate;
145
146 ASSERT (SystemSlewRate != 0);
147
148 // First, calculate the time it takes to change 12.5mV using the VRM slew rate.
149 WaitTime = (12500 * 100) / SystemSlewRate;
150 if (((12500 * 100) % SystemSlewRate) != 0) {
151 WaitTime++;
152 }
153
154 // Next, round it to the appropriate encoded value. We will start from encoding 111b which corresponds
155 // to the fastest slew rate, and work our way down to 000b, which represents the slowest an acceptable
156 // VRM can be.
Patrick Georgi6b688f52021-02-12 13:49:11 +0100157 for (VSRampSlamTime = (ARRAY_SIZE(F14VSRampSlamWaitTimes)- 1); VSRampSlamTime > 0; VSRampSlamTime--) {
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000158 if (WaitTime <= F14VSRampSlamWaitTimes[VSRampSlamTime]) {
159 break;
160 }
161 }
162
163 if (WaitTime > F14VSRampSlamWaitTimes[0]) {
164 // The VRMs on this motherboard are too slow for this CPU.
165 IDS_ERROR_TRAP;
166 }
167
168 // Lastly, program D18F3xD8[VSRampSlamTime] with the appropriate encoded value.
169 PciAddress.AddressValue = CPTC1_PCI_ADDR;
efdesign9884cbce22011-08-04 12:09:17 -0600170 LibAmdPciRead (AccessWidth32, PciAddress, &PciReg, StdHeader);
171 ((CLK_PWR_TIMING_CTRL1_REGISTER *) &PciReg)->VSRampSlamTime = VSRampSlamTime;
172 LibAmdPciWrite (AccessWidth32, PciAddress, &PciReg, StdHeader);
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000173
174 // Step 2 - Configure D18F3xA0[PsiVidEn & PsiVid] and D18F3x128[NbPsiVidEn & NbPsiVid].
175 F14PmVrmLowPowerModeEnable (FamilySpecificServices, CpuEarlyParams, StdHeader);
176
177 // Step 3 - Program D18F3xDC[NbPs0Vid] = FCRxFE00_6000[NbPs0Vid] - 1.
178 // Program D18F3xDC[NbPs0Vid] = FCRxFE00_6000[NbPs0Vid].
179 FCRxFE00_6000.Value = NbSmuReadEfuse (FCRxFE00_6000_ADDRESS, StdHeader);
180
181 F14EarlySampleCoreSupport.F14PowerPlaneInitHook (&FCRxFE00_6000, StdHeader);
182
183 PciAddress.AddressValue = CPTC2_PCI_ADDR;
efdesign9884cbce22011-08-04 12:09:17 -0600184 LibAmdPciRead (AccessWidth32, PciAddress, &PciReg, StdHeader);
185 ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciReg)->NbPs0Vid = FCRxFE00_6000.Field.NbPs0Vid - 1;
186 LibAmdPciWrite (AccessWidth32, PciAddress, &PciReg, StdHeader);
187 ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciReg)->NbPs0Vid = FCRxFE00_6000.Field.NbPs0Vid;
188 LibAmdPciWrite (AccessWidth32, PciAddress, &PciReg, StdHeader);
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000189}
190
191/*---------------------------------------------------------------------------------------*/
192/**
193 * Sets up PSI_L operation.
194 *
195 * This function implements the AMD_CPU_EARLY_PARAMS.VrmLowPowerThreshold parameter.
196 *
197 * @param[in] FamilySpecificServices The current Family Specific Services.
198 * @param[in] CpuEarlyParams Contains VrmLowPowerThreshold parameter.
199 * @param[in] StdHeader Config handle for library and services.
200 *
201 */
202VOID
203STATIC
204F14PmVrmLowPowerModeEnable (
205 IN CPU_SPECIFIC_SERVICES *FamilySpecificServices,
206 IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams,
207 IN AMD_CONFIG_PARAMS *StdHeader
208 )
209{
210 UINT32 Pstate;
211 UINT32 PstateMaxVal;
212 UINT32 PstateCurrent;
213 UINT32 NextPstateCurrent;
214 UINT32 NextPstateCurrentRaw;
efdesign9884cbce22011-08-04 12:09:17 -0600215 UINT32 PciReg;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000216 UINT32 PreviousVid;
217 UINT32 CurrentVid;
218 UINT64 PstateMsr;
219 UINT64 PstateLimitMsr;
220 BOOLEAN IsPsiEnabled;
221 PCI_ADDR PciAddress;
222
223 // Set up PSI_L for VDD
224 IsPsiEnabled = FALSE;
225 PreviousVid = 0x7F;
226 CurrentVid = 0x7F;
227 if (CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].LowPowerThreshold != 0) {
228 LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &PstateLimitMsr, StdHeader);
229 PstateMaxVal = (UINT32) ((PSTATE_CURLIM_MSR *) &PstateLimitMsr)->PstateMaxVal;
230 FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) 0, &PstateCurrent, StdHeader);
231 for (Pstate = 0; Pstate <= PstateMaxVal; Pstate++) {
232 LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), &PstateMsr, StdHeader);
233 CurrentVid = (UINT32) ((PSTATE_MSR *) &PstateMsr)->CpuVid;
234 if (Pstate == PstateMaxVal) {
235 NextPstateCurrentRaw = 0;
236 NextPstateCurrent = 0;
237 } else {
238 FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrentRaw, StdHeader);
239 NextPstateCurrent = NextPstateCurrentRaw + CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].InrushCurrentLimit;
240 }
241 if ((PstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].LowPowerThreshold) &&
242 (NextPstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].LowPowerThreshold) &&
243 (CurrentVid != PreviousVid)) {
244 IsPsiEnabled = TRUE;
245 break;
246 } else {
247 PstateCurrent = NextPstateCurrentRaw;
248 PreviousVid = CurrentVid;
249 }
250 }
251 }
252 PciAddress.AddressValue = PW_CTL_MISC_PCI_ADDR;
efdesign9884cbce22011-08-04 12:09:17 -0600253 LibAmdPciRead (AccessWidth32, PciAddress, &PciReg, StdHeader);
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000254 if (IsPsiEnabled) {
efdesign9884cbce22011-08-04 12:09:17 -0600255 ((POWER_CTRL_MISC_REGISTER *) &PciReg)->PsiVid = CurrentVid;
256 ((POWER_CTRL_MISC_REGISTER *) &PciReg)->PsiVidEn = 1;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000257 } else {
efdesign9884cbce22011-08-04 12:09:17 -0600258 ((POWER_CTRL_MISC_REGISTER *) &PciReg)->PsiVidEn = 0;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000259 }
efdesign9884cbce22011-08-04 12:09:17 -0600260 LibAmdPciWrite (AccessWidth32, PciAddress, &PciReg, StdHeader);
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000261
262
263 // Set up NBPSI_L for VDDNB
264 PciAddress.AddressValue = CPTC3_PCI_ADDR;
efdesign9884cbce22011-08-04 12:09:17 -0600265 LibAmdPciRead (AccessWidth32, PciAddress, &PciReg, StdHeader);
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000266 if (CpuEarlyParams->PlatformConfig.VrmProperties[NbVrm].LowPowerThreshold != 0) {
efdesign9884cbce22011-08-04 12:09:17 -0600267 ((CLK_PWR_TIMING_CTRL3_REGISTER *) &PciReg)->NbPsiVid = 0;
268 ((CLK_PWR_TIMING_CTRL3_REGISTER *) &PciReg)->NbPsiVidEn = 1;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000269 } else {
efdesign9884cbce22011-08-04 12:09:17 -0600270 ((CLK_PWR_TIMING_CTRL3_REGISTER *) &PciReg)->NbPsiVidEn = 0;
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000271 }
efdesign9884cbce22011-08-04 12:09:17 -0600272 LibAmdPciWrite (AccessWidth32, PciAddress, &PciReg, StdHeader);
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000273}