c2536eda0de9fa5bc45b3cf8a4e067eb5b859df6
[coreboot.git] / src / vendorcode / amd / agesa / f14 / Proc / CPU / Family / 0x14 / F14IoCstate.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD Family_14 IO C-state feature support functions.
6  *
7  * Provides the functions necessary to initialize the IO C-state feature.
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  CPU/F14
12  * @e \$Revision: 34897 $   @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 Jul 2010) $
13  *
14  */
15 /*
16  *****************************************************************************
17  *
18  * Copyright (c) 2011, Advanced Micro Devices, Inc.
19  * All rights reserved.
20  * 
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.
31  * 
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.
42  * 
43  * ***************************************************************************
44  *
45  */
46 /*----------------------------------------------------------------------------------------
47  *                             M O D U L E S    U S E D
48  *----------------------------------------------------------------------------------------
49  */
50
51 #include "AGESA.h"
52 #include "amdlib.h"
53 #include "Ids.h"
54 #include "cpuRegisters.h"
55 #include "cpuServices.h"
56 #include "cpuFeatures.h"
57 #include "cpuIoCstate.h"
58 #include "cpuF14PowerMgmt.h"
59 #include "cpuLateInit.h"
60 #include "cpuApicUtilities.h"
61 #include "CommonReturns.h"
62 #include "Filecode.h"
63 #define FILECODE PROC_CPU_FAMILY_0X14_F14IOCSTATE_FILECODE
64
65 /*----------------------------------------------------------------------------------------
66  *                   D E F I N I T I O N S    A N D    M A C R O S
67  *----------------------------------------------------------------------------------------
68  */
69
70 /*----------------------------------------------------------------------------------------
71  *                  T Y P E D E F S     A N D     S T R U C T U R E S
72  *----------------------------------------------------------------------------------------
73  */
74
75 /*----------------------------------------------------------------------------------------
76  *           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
77  *----------------------------------------------------------------------------------------
78  */
79 VOID
80 STATIC
81 F14InitializeIoCstateOnCore (
82   IN       VOID *CstateBaseMsr,
83   IN       AMD_CONFIG_PARAMS *StdHeader
84   );
85
86
87 /*----------------------------------------------------------------------------------------
88  *                          E X P O R T E D    F U N C T I O N S
89  *----------------------------------------------------------------------------------------
90  */
91
92 /*---------------------------------------------------------------------------------------*/
93 /**
94  *  Enable IO Cstate on a family 14h CPU.
95  *  Implement steps 1 to 3 of BKDG section 2.5.4.2.9 BIOS Requirements for Initialization
96  *
97  * @param[in]    IoCstateServices   Pointer to this CPU's IO Cstate family services.
98  * @param[in]    EntryPoint         Timepoint designator.
99  * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
100  * @param[in]    StdHeader          Config Handle for library, services.
101  *
102  * @return       AGESA_SUCCESS      Always succeeds.
103  *
104  */
105 AGESA_STATUS
106 STATIC
107 F14InitializeIoCstate (
108   IN       IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
109   IN       UINT64                    EntryPoint,
110   IN       PLATFORM_CONFIGURATION    *PlatformConfig,
111   IN       AMD_CONFIG_PARAMS         *StdHeader
112   )
113 {
114
115   UINT32   i;
116   UINT32   MaxEnabledPstate;
117   UINT32   PciRegister;
118   UINT64   MsrReg;
119   AP_TASK  TaskPtr;
120   PCI_ADDR PciAddress;
121
122   if ((EntryPoint & CPU_FEAT_AFTER_PM_INIT) != 0) {
123     for (i = MSR_PSTATE_7; i > MSR_PSTATE_0; i--) {
124       LibAmdMsrRead (i, &MsrReg, StdHeader);
125       if (((PSTATE_MSR *) &MsrReg)->PsEnable == 1) {
126         break;
127       }
128     }
129     MaxEnabledPstate = i - MSR_PSTATE_0;
130     // Initialize MSRC001_0073[CstateAddr] on each core to a region of
131     // the IO address map with 8 consecutive available addresses.
132     MsrReg = 0;
133     ((CSTATE_ADDRESS_MSR *) &MsrReg)->CstateAddr = PlatformConfig->CStateIoBaseAddress;
134     ASSERT ((((CSTATE_ADDRESS_MSR *) &MsrReg)->CstateAddr != 0) &&
135             (((CSTATE_ADDRESS_MSR *) &MsrReg)->CstateAddr <= 0xFFF8));
136
137     TaskPtr.FuncAddress.PfApTaskI = F14InitializeIoCstateOnCore;
138     TaskPtr.DataTransfer.DataSizeInDwords = 2;
139     TaskPtr.DataTransfer.DataPtr = &MsrReg;
140     TaskPtr.DataTransfer.DataTransferFlags = 0;
141     TaskPtr.ExeFlags = WAIT_FOR_CORE;
142     ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL);
143
144     // Program D18F4x1A8[PService] to the index of lowest-performance
145     // P-state with MSRC001_00[6B:64][PstateEn]==1 on core 0.
146     PciAddress.AddressValue = CPU_STATE_PM_CTRL0_PCI_ADDR;
147     LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
148     ((CPU_STATE_PM_CTRL0_REGISTER *) &PciRegister)->PService = MaxEnabledPstate;
149     LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);
150
151     // Program D18F4x1AC[CstPminEn] to 1.
152     PciAddress.AddressValue = CPU_STATE_PM_CTRL1_PCI_ADDR;
153     LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
154     ((CPU_STATE_PM_CTRL1_REGISTER *) &PciRegister)->CstPminEn = 1;
155     LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);
156   }
157   return AGESA_SUCCESS;
158 }
159
160 /*---------------------------------------------------------------------------------------*/
161 /**
162  *  Enable C-State on a family 14h core.
163  *
164  * @param[in]    CstateBaseMsr      MSR value to write to C001_0073 as determined by core 0.
165  * @param[in]    StdHeader          Config Handle for library, services.
166  *
167  */
168 VOID
169 STATIC
170 F14InitializeIoCstateOnCore (
171   IN       VOID *CstateBaseMsr,
172   IN       AMD_CONFIG_PARAMS *StdHeader
173   )
174 {
175   // Initialize MSRC001_0073[CstateAddr] on each core
176   LibAmdMsrWrite (MSR_CSTATE_ADDRESS, (UINT64 *) CstateBaseMsr, StdHeader);
177 }
178
179 /*---------------------------------------------------------------------------------------*/
180 /**
181  *  Returns the size of CST object
182  *
183  * @param[in]    IoCstateServices   IO Cstate services.
184  * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data
185  * @param[in]    StdHeader          Config Handle for library, services.
186  *
187  * @retval       CstObjSize         Size of CST Object
188  *
189  */
190 UINT32
191 STATIC
192 F14GetAcpiCstObj (
193   IN       IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
194   IN       PLATFORM_CONFIGURATION    *PlatformConfig,
195   IN       AMD_CONFIG_PARAMS         *StdHeader
196   )
197 {
198   return (CST_HEADER_SIZE + CST_BODY_SIZE);
199 }
200
201 /*---------------------------------------------------------------------------------------*/
202 /**
203  *  Routine to generate the C-State ACPI objects
204  *
205  * @param[in]    IoCstateServices       IO Cstate services.
206  * @param[in]    LocalApicId            Local Apic Id for each core.
207  * @param[in]    **PstateAcpiBufferPtr  Pointer to the Acpi Buffer Pointer.
208  * @param[in]    StdHeader              Config Handle for library, services.
209  *
210  */
211 VOID
212 STATIC
213 F14CreateAcpiCstObj (
214   IN       IO_CSTATE_FAMILY_SERVICES *IoCstateServices,
215   IN       UINT8                     LocalApicId,
216   IN OUT   VOID                      **PstateAcpiBufferPtr,
217   IN       AMD_CONFIG_PARAMS         *StdHeader
218   )
219 {
220   UINT64            MsrData;
221   CST_HEADER_STRUCT *CstHeaderPtr;
222   CST_BODY_STRUCT   *CstBodyPtr;
223
224   // Read from MSR C0010073 to obtain CstateAddr
225   LibAmdMsrRead (MSR_CSTATE_ADDRESS, &MsrData, StdHeader);
226   ASSERT ((((CSTATE_ADDRESS_MSR *) &MsrData)->CstateAddr != 0) &&
227           (((CSTATE_ADDRESS_MSR *) &MsrData)->CstateAddr <= 0xFFF8));
228
229   // Typecast the pointer
230   CstHeaderPtr = (CST_HEADER_STRUCT *) *PstateAcpiBufferPtr;
231
232   // Set CST Header
233   CstHeaderPtr->NameOpcode  = NAME_OPCODE;
234   CstHeaderPtr->CstName_a__ = CST_NAME__;
235   CstHeaderPtr->CstName_a_C = CST_NAME_C;
236   CstHeaderPtr->CstName_a_S = CST_NAME_S;
237   CstHeaderPtr->CstName_a_T = CST_NAME_T;
238
239   // Typecast the pointer
240   CstHeaderPtr++;
241   CstBodyPtr = (CST_BODY_STRUCT *) CstHeaderPtr;
242
243   // Set CST Body
244   CstBodyPtr->PkgOpcode      = PACKAGE_OPCODE;
245   CstBodyPtr->PkgLength      = CST_LENGTH;
246   CstBodyPtr->PkgElements    = CST_NUM_OF_ELEMENTS;
247   CstBodyPtr->BytePrefix     = BYTE_PREFIX_OPCODE;
248   CstBodyPtr->Count          = CST_COUNT;
249   CstBodyPtr->PkgOpcode2     = PACKAGE_OPCODE;
250   CstBodyPtr->PkgLength2     = CST_PKG_LENGTH;
251   CstBodyPtr->PkgElements2   = CST_PKG_ELEMENTS;
252   CstBodyPtr->BufferOpcode   = BUFFER_OPCODE;
253   CstBodyPtr->BufferLength   = CST_SUBPKG_LENGTH;
254   CstBodyPtr->BufferElements = CST_SUBPKG_ELEMENTS;
255   CstBodyPtr->BufferOpcode2  = BUFFER_OPCODE;
256   CstBodyPtr->GdrOpcode      = GENERIC_REG_DESCRIPTION;
257   CstBodyPtr->GdrLength      = CST_GDR_LENGTH;
258   CstBodyPtr->AddrSpaceId    = GDR_ASI_SYSTEM_IO;
259   CstBodyPtr->RegBitWidth    = 0x08;
260   CstBodyPtr->RegBitOffset   = 0x00;
261   CstBodyPtr->AddressSize    = GDR_ASZ_BYTE_ACCESS;
262   CstBodyPtr->RegisterAddr   = ((CSTATE_ADDRESS_MSR *) &MsrData)->CstateAddr + 1;
263   CstBodyPtr->EndTag         = 0x0079;
264   CstBodyPtr->BytePrefix2    = BYTE_PREFIX_OPCODE;
265   CstBodyPtr->Type           = CST_C2_TYPE;
266   CstBodyPtr->WordPrefix     = WORD_PREFIX_OPCODE;
267   CstBodyPtr->Latency        = 0x64;
268   CstBodyPtr->DWordPrefix    = DWORD_PREFIX_OPCODE;
269   CstBodyPtr->Power          = 0;
270
271   CstBodyPtr++;
272
273   //Update the pointer
274   *PstateAcpiBufferPtr = CstBodyPtr;
275 }
276
277 CONST IO_CSTATE_FAMILY_SERVICES ROMDATA F14IoCstateSupport =
278 {
279   0,
280   (PF_IO_CSTATE_IS_SUPPORTED) CommonReturnTrue,
281   F14InitializeIoCstate,
282   F14GetAcpiCstObj,
283   F14CreateAcpiCstObj,
284   (PF_IO_CSTATE_IS_CSD_GENERATED) CommonReturnFalse
285 };