AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / Family / 0x15 / OR / cpuF15OrCoreAfterReset.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD Family_15 Orochi after warm reset sequence for core P-states
6  *
7  * Performs the "Core Minimum P-State Transition Sequence After Warm Reset"
8  * as described in the BKDG.
9  *
10  * @xrefitem bom "File Content Label" "Release Content"
11  * @e project:      AGESA
12  * @e sub-project:  CPU/Family/0x15/OR
13  * @e \$Revision: 55600 $   @e \$Date: 2011-06-23 12:39:18 -0600 (Thu, 23 Jun 2011) $
14  *
15  */
16 /*
17  ******************************************************************************
18  *
19  * Copyright (C) 2012 Advanced Micro Devices, Inc.
20  * All rights reserved.
21  *
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.
32  *
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.
43  *
44  ******************************************************************************
45  */
46
47 /*----------------------------------------------------------------------------------------
48  *                             M O D U L E S    U S E D
49  *----------------------------------------------------------------------------------------
50  */
51 #include "AGESA.h"
52 #include "amdlib.h"
53 #include "cpuF15PowerMgmt.h"
54 #include "cpuF15OrPowerMgmt.h"
55 #include "cpuRegisters.h"
56 #include "GeneralServices.h"
57 #include "cpuApicUtilities.h"
58 #include "cpuFamilyTranslation.h"
59 #include "OptionMultiSocket.h"
60 #include "cpuF15OrCoreAfterReset.h"
61 #include "Filecode.h"
62 CODE_GROUP (G3_DXE)
63 RDATA_GROUP (G3_DXE)
64
65
66 #define FILECODE PROC_CPU_FAMILY_0X15_OR_CPUF15ORCOREAFTERRESET_FILECODE
67
68 /*----------------------------------------------------------------------------------------
69  *                   D E F I N I T I O N S    A N D    M A C R O S
70  *----------------------------------------------------------------------------------------
71  */
72
73 /*----------------------------------------------------------------------------------------
74  *                  T Y P E D E F S     A N D     S T R U C T U R E S
75  *----------------------------------------------------------------------------------------
76  */
77
78 /*----------------------------------------------------------------------------------------
79  *           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
80  *----------------------------------------------------------------------------------------
81  */
82 VOID
83 STATIC
84 F15OrPmCoreAfterResetPhase1OnCore (
85   IN       AMD_CONFIG_PARAMS *StdHeader
86   );
87
88 VOID
89 STATIC
90 F15OrPmCoreAfterResetPhase2OnCore (
91   IN       VOID              *HwPsMaxVal,
92   IN       AMD_CONFIG_PARAMS *StdHeader
93   );
94
95 /*----------------------------------------------------------------------------------------
96  *                          E X P O R T E D    F U N C T I O N S
97  *----------------------------------------------------------------------------------------
98  */
99 extern OPTION_MULTISOCKET_CONFIGURATION OptionMultiSocketConfiguration;
100 /*---------------------------------------------------------------------------------------*/
101 /**
102  * Family 15h Orochi core 0 entry point for performing the necessary steps for core
103  * P-states after a warm reset has occurred.
104  *
105  * The steps are as follows:
106  *    1. Write 0 to MSRC001_0062[PstateCmd] on all cores in the processor.
107  *    2. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from
108  *       MSRC001_00[6B:64] indexed by MSRC001_0071[CurPstateLimit].
109  *    3. Write MSRC001_0061[PstateMaxVal] to MSRC001_0062[PstateCmd] on all
110  *       cores in the processor.
111  *    4. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from
112  *       MSRC001_00[6B:64] indexed by MSRC001_0061[PstateMaxVal].
113  *    5. If MSRC001_0071[CurPstateLimit] != MSRC001_0071[CurPstate], wait for
114  *       MSRC001_0071[CurCpuVid] = [CpuVid] from MSRC001_00[6B:64] indexed by
115  *       MSRC001_0061[PstateMaxVal].
116  *    6. Wait for MSRC001_0063[CurPstate] = MSRC001_0062[PstateCmd].
117  *
118  * @param[in]  FamilySpecificServices  The current Family Specific Services.
119  * @param[in]  CpuEarlyParamsPtr       Service parameters
120  * @param[in]  StdHeader               Config handle for library and services.
121  *
122  */
123 VOID
124 F15OrPmCoreAfterReset (
125   IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
126   IN       AMD_CPU_EARLY_PARAMS  *CpuEarlyParamsPtr,
127   IN       AMD_CONFIG_PARAMS     *StdHeader
128   )
129 {
130   UINT32       Core;
131   UINT32       HwPsMaxVal;
132   PCI_ADDR     PciAddress;
133   AP_TASK      TaskPtr;
134   IDS_SKIP_HOOK (IDS_SKIP_PM_TRANSITION_STEP, CpuEarlyParamsPtr, StdHeader) {
135
136     OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader);
137     GetCurrentCore (&Core, StdHeader);
138     ASSERT (Core == 0);
139
140     PciAddress.Address.Function = FUNC_3;
141     PciAddress.Address.Register = CPTC2_REG;
142     LibAmdPciRead (AccessWidth32, PciAddress, &HwPsMaxVal, StdHeader);
143     HwPsMaxVal = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &HwPsMaxVal)->PstateMaxVal;
144
145     // Launch each local core to perform steps 1 through 3.
146     TaskPtr.FuncAddress.PfApTask = F15OrPmCoreAfterResetPhase1OnCore;
147     TaskPtr.DataTransfer.DataSizeInDwords = 0;
148     TaskPtr.ExeFlags = WAIT_FOR_CORE;
149     ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr);
150
151     // Launch each local core to perform steps 4 through 6.
152     TaskPtr.FuncAddress.PfApTaskI = F15OrPmCoreAfterResetPhase2OnCore;
153     TaskPtr.DataTransfer.DataSizeInDwords = 1;
154     TaskPtr.DataTransfer.DataPtr = &HwPsMaxVal;
155     TaskPtr.DataTransfer.DataTransferFlags = 0;
156     TaskPtr.ExeFlags = WAIT_FOR_CORE;
157     ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr);
158   }
159 }
160
161
162 /*---------------------------------------------------------------------------------------
163  *                          L O C A L    F U N C T I O N S
164  *---------------------------------------------------------------------------------------
165  */
166
167 /*---------------------------------------------------------------------------------------*/
168 /**
169  * Support routine for F15OrPmCoreAfterReset to perform MSR initialization on all
170  * cores of a family 15h socket.
171  *
172  * This function implements steps 1 - 3 on each core.
173  *
174  * @param[in]  StdHeader          Config handle for library and services.
175  *
176  */
177 VOID
178 STATIC
179 F15OrPmCoreAfterResetPhase1OnCore (
180   IN       AMD_CONFIG_PARAMS *StdHeader
181   )
182 {
183   UINT64 CofvidSts;
184   UINT64 LocalMsrRegister;
185   UINT64 PstateCtrl;
186
187   // 1. Write 0 to MSRC001_0062[PstateCmd] on all cores in the processor.
188   PstateCtrl = 0;
189   LibAmdMsrWrite (MSR_PSTATE_CTL, &PstateCtrl, StdHeader);
190
191   // 2. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from
192   //    MSRC001_00[6B:64] indexed by MSRC001_0071[CurPstateLimit].
193   do {
194     LibAmdMsrRead (MSR_COFVID_STS, &CofvidSts, StdHeader);
195     LibAmdMsrRead ((UINT32) (MSR_PSTATE_0 + (UINT32) (((COFVID_STS_MSR *) &CofvidSts)->CurPstateLimit)), &LocalMsrRegister, StdHeader);
196   } while ((((COFVID_STS_MSR *) &CofvidSts)->CurCpuFid != ((PSTATE_MSR *) &LocalMsrRegister)->CpuFid) ||
197            (((COFVID_STS_MSR *) &CofvidSts)->CurCpuDid != ((PSTATE_MSR *) &LocalMsrRegister)->CpuDid));
198
199   // 3. Write MSRC001_0061[PstateMaxVal] to MSRC001_0062[PstateCmd] on all
200   //    cores in the processor.
201   LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &LocalMsrRegister, StdHeader);
202   ((PSTATE_CTRL_MSR *) &PstateCtrl)->PstateCmd = ((PSTATE_CURLIM_MSR *) &LocalMsrRegister)->PstateMaxVal;
203   LibAmdMsrWrite (MSR_PSTATE_CTL, &PstateCtrl, StdHeader);
204 }
205
206 /*---------------------------------------------------------------------------------------*/
207 /**
208  * Support routine for F15OrPmCoreAfterReset to perform MSR initialization on all
209  * cores of a family 15h socket.
210  *
211  * This function implements steps 4 - 6 on each core.
212  *
213  * @param[in]  HwPsMaxVal         Index of the highest enabled HW P-state.
214  * @param[in]  StdHeader          Config handle for library and services.
215  *
216  */
217 VOID
218 STATIC
219 F15OrPmCoreAfterResetPhase2OnCore (
220   IN       VOID              *HwPsMaxVal,
221   IN       AMD_CONFIG_PARAMS *StdHeader
222   )
223 {
224   UINT64 TargetPsMsr;
225   UINT64 LocalMsrRegister;
226   UINT64 PstateCtrl;
227
228   // 4. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from
229   //    MSRC001_00[6B:64] indexed by D18F3xDC[PstateMaxVal].
230   LibAmdMsrRead ((*(UINT32 *) HwPsMaxVal) + MSR_PSTATE_0, &TargetPsMsr, StdHeader);
231   do {
232     LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader);
233   } while ((((COFVID_STS_MSR *) &LocalMsrRegister)->CurCpuFid != ((PSTATE_MSR *) &TargetPsMsr)->CpuFid) ||
234            (((COFVID_STS_MSR *) &LocalMsrRegister)->CurCpuDid != ((PSTATE_MSR *) &TargetPsMsr)->CpuDid));
235
236   // 5. If MSRC001_0071[CurPstateLimit] != MSRC001_0071[CurPstate], wait for
237   //    MSRC001_0071[CurCpuVid] = [CpuVid] from MSRC001_00[6B:64] indexed by
238   //    MSRC001_0061[PstateMaxVal].
239   if (((COFVID_STS_MSR *) &LocalMsrRegister)->CurPstateLimit != ((COFVID_STS_MSR *) &LocalMsrRegister)->CurPstate) {
240     do {
241       LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader);
242     } while ((((COFVID_STS_MSR *) &LocalMsrRegister)->CurCpuVid != ((PSTATE_MSR *) &TargetPsMsr)->CpuVid));
243   }
244
245   // 6. Wait for MSRC001_0063[CurPstate] = MSRC001_0062[PstateCmd].
246   LibAmdMsrRead (MSR_PSTATE_CTL, &PstateCtrl, StdHeader);
247   do {
248     LibAmdMsrRead (MSR_PSTATE_STS, &LocalMsrRegister, StdHeader);
249   } while (((PSTATE_STS_MSR *) &LocalMsrRegister)->CurPstate != ((PSTATE_CTRL_MSR *) &PstateCtrl)->PstateCmd);
250 }