blob: 65ee6eeacb5745c4e689d1245f654dbc48a68035 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * mprtt.c
6 *
7 * A sub-engine which extracts RttNom and RttWr (Dram Term and Dynamic Dram Term) value.
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: (Mem/Ps)
12 * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
13 *
14 **/
15/*****************************************************************************
16*
Siyuan Wang641f00c2013-06-08 11:50:55 +080017 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 * * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zbao7d94cf92012-07-02 14:19:14 +080041* ***************************************************************************
42*
43*/
44/*
45 *----------------------------------------------------------------------------
46 * MODULES USED
47 *
48 *----------------------------------------------------------------------------
49 */
50
51
52
53#include "AGESA.h"
54#include "AdvancedApi.h"
55#include "amdlib.h"
56#include "Ids.h"
57#include "cpuFamRegisters.h"
58#include "cpuRegisters.h"
59#include "OptionMemory.h"
60#include "PlatformMemoryConfiguration.h"
61#include "mu.h"
62#include "ma.h"
63#include "mp.h"
64#include "merrhdl.h"
65#include "GeneralServices.h"
66#include "Filecode.h"
67CODE_GROUP (G2_PEI)
68RDATA_GROUP (G2_PEI)
69
70#define FILECODE PROC_MEM_PS_MPRTT_FILECODE
71
72
73/*----------------------------------------------------------------------------
74 * DEFINITIONS AND MACROS
75 *
76 *----------------------------------------------------------------------------
77 */
78#define _DONT_CARE 0xFF
79
80/*----------------------------------------------------------------------------
81 * TYPEDEFS AND STRUCTURES
82 *
83 *----------------------------------------------------------------------------
84 */
85/*----------------------------------------------------------------------------
86 * PROTOTYPES OF LOCAL FUNCTIONS
87 *
88 *----------------------------------------------------------------------------
89 */
90BOOLEAN
91MemPGetRttNomWr (
92 IN OUT MEM_NB_BLOCK *NBPtr,
93 IN MEM_PSC_TABLE_BLOCK *EntryOfTables
94 );
95/*----------------------------------------------------------------------------
96 * EXPORTED FUNCTIONS
97 *
98 *----------------------------------------------------------------------------
99 */
100/* -----------------------------------------------------------------------------*/
101/**
102 *
103 * A sub-function which extracts RttNom and RttWr value from a input table and stores extracted
104 * value to a specific address.
105 *
106 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
107 * @param[in] *EntryOfTables - Pointer to MEM_PSC_TABLE_BLOCK
108 *
109 * @return TRUE - Table values can be extracted for all present dimms/ranks
110 * @return FALSE - Table values cannot be extracted for all present dimms/ranks
111 *
112 */
113BOOLEAN
114MemPGetRttNomWr (
115 IN OUT MEM_NB_BLOCK *NBPtr,
116 IN MEM_PSC_TABLE_BLOCK *EntryOfTables
117 )
118{
119 UINT8 i;
120 UINT8 MaxDimmPerCh;
121 UINT8 MaxDimmSlotPerCh;
122 UINT8 NOD;
123 UINT8 TableSize;
124 UINT32 CurDDRrate;
125 UINT8 DDR3Voltage;
126 UINT16 RankTypeOfPopulatedDimm;
127 UINT16 RankTypeInTable;
128 DIMM_TYPE DimmType;
129 CPU_LOGICAL_ID LogicalCpuid;
130 UINT8 PackageType;
131 UINT8 TgtDimmType;
132 UINT8 TgtRank;
133 UINT8 Chipsel;
134 UINT8 PsoCsMaskRtt;
135 UINT16 PsoCsMaskRtt16;
136 UINT8 NoEntryCsMask;
137 PSCFG_RTT_ENTRY *TblPtr;
138 PSCFG_RTT_ENTRY *OrgTblPtr;
139 CH_DEF_STRUCT *CurrentChannel;
140
141 CurrentChannel = NBPtr->ChannelPtr;
142
143 PsoCsMaskRtt = 0;
144 NoEntryCsMask = 0;
145 TblPtr = NULL;
146 TableSize = 0;
147 PackageType = 0;
148 LogicalCpuid.Family = AMD_FAMILY_UNKNOWN;
149
150 MaxDimmPerCh = GetMaxDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
151 MaxDimmSlotPerCh = MaxDimmPerCh - GetMaxSolderedDownDimmsPerChannel (NBPtr->RefPtr->PlatformMemoryConfiguration,
152 NBPtr->MCTPtr->SocketId, CurrentChannel->ChannelID);
153
154 if (CurrentChannel->RegDimmPresent != 0) {
155 DimmType = RDIMM_TYPE;
156 } else if (CurrentChannel->SODimmPresent != 0) {
157 DimmType = SODIMM_TYPE;
158 } else if (CurrentChannel->LrDimmPresent != 0) {
159 DimmType = LRDIMM_TYPE;
160 } else {
161 DimmType = UDIMM_TYPE;
162 }
163
164 // Check if it is "SODIMM plus soldered-down DRAM" or "Soldered-down DRAM only" configuration,
165 // DimmType is changed to 'SODWN_SODIMM_TYPE' if soldered-down DRAM exist
166 if (MaxDimmSlotPerCh != MaxDimmPerCh) {
167 // SODIMM plus soldered-down DRAM
168 DimmType = SODWN_SODIMM_TYPE;
169 } else if (FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_SOLDERED_DOWN_SODIMM_TYPE, NBPtr->MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID, 0, NULL, NULL) != NULL) {
170 // Soldered-down DRAM only
171 DimmType = SODWN_SODIMM_TYPE;
172 MaxDimmSlotPerCh = 0;
173 }
174 NOD = (UINT8) (MaxDimmSlotPerCh != 0) ? (1 << (MaxDimmSlotPerCh - 1)) : _DIMM_NONE;
175
176 i = 0;
177 // Obtain table pointer, table size, Logical Cpuid and PSC type according to Dimm, NB and package type.
178 while (EntryOfTables->TblEntryOfDramTerm[i] != NULL) {
179 if (((EntryOfTables->TblEntryOfDramTerm[i])->Header.DimmType & DimmType) != 0) {
180 if (((EntryOfTables->TblEntryOfDramTerm[i])->Header.NumOfDimm & NOD) != 0) {
181 //
182 // Determine if this is the expected NB Type
183 //
184 LogicalCpuid = (EntryOfTables->TblEntryOfDramTerm[i])->Header.LogicalCpuid;
185 PackageType = (EntryOfTables->TblEntryOfDramTerm[i])->Header.PackageType;
186 if (MemPIsIdSupported (NBPtr, LogicalCpuid, PackageType)) {
187 TblPtr = (PSCFG_RTT_ENTRY *) ((EntryOfTables->TblEntryOfDramTerm[i])->TBLPtr);
188 TableSize = (EntryOfTables->TblEntryOfDramTerm[i])->TableSize;
189 break;
190 }
191 }
192 }
193 i++;
194 }
195
196 // Check whether no table entry is found.
197 if (EntryOfTables->TblEntryOfDramTerm[i] == NULL) {
198 IDS_HDT_CONSOLE (MEM_FLOW, "\nNo RTT table\n");
199 return FALSE;
200 }
201
202 CurDDRrate = (UINT32) (1 << (CurrentChannel->DCTPtr->Timings.Speed / 66));
203 DDR3Voltage = (UINT8) (1 << CONVERT_VDDIO_TO_ENCODED (NBPtr->RefPtr->DDR3Voltage));
204 RankTypeOfPopulatedDimm = MemPGetPsRankType (CurrentChannel);
205
206 OrgTblPtr = TblPtr;
207 for (Chipsel = 0; Chipsel < MAX_CS_PER_CHANNEL; Chipsel++) {
208 TblPtr = OrgTblPtr;
209 if ((NBPtr->DCTPtr->Timings.CsPresent & (UINT16) (1 << Chipsel)) != 0) {
210 if ((CurrentChannel->DimmQrPresent & (UINT8) (1 << (Chipsel >> 1))) != 0) {
211 TgtDimmType = DIMM_QR;
212 TgtRank = (UINT8) ((Chipsel < 4) ? 1 << (Chipsel & 1) : 4 << (Chipsel & 1));
213 } else if ((CurrentChannel->DimmDrPresent & (UINT8) (1 << (Chipsel >> 1))) != 0) {
214 TgtDimmType = DIMM_DR;
215 TgtRank = (UINT8) 1 << (Chipsel & 1);
216 } else {
217 TgtDimmType = DIMM_SR;
218 TgtRank = (UINT8) 1 << (Chipsel & 1);
219 }
220
221 if (DimmType == LRDIMM_TYPE) {
222 TgtDimmType = _DONT_CARE;
223 TgtRank = _DONT_CARE;
224 }
225
226 for (i = 0; i < TableSize; i++) {
227 MemPConstructRankTypeMap ((UINT16) TblPtr->Dimm0, (UINT16) TblPtr->Dimm1, (UINT16) TblPtr->Dimm2, &RankTypeInTable);
228 if ((TblPtr->DimmPerCh & NOD) != 0) {
229 if ((TblPtr->DDRrate & CurDDRrate) != 0) {
230 if ((TblPtr->VDDIO & DDR3Voltage) != 0) {
231 if ((RankTypeInTable & RankTypeOfPopulatedDimm) == RankTypeOfPopulatedDimm) {
232 if (((TblPtr->Dimm & TgtDimmType) != 0) || (TgtDimmType == _DONT_CARE)) {
233 if (((TblPtr->Rank & TgtRank) != 0) || (TgtRank == _DONT_CARE)) {
234 NBPtr->PsPtr->RttNom[Chipsel] = (UINT8) TblPtr->RttNom;
235 NBPtr->PsPtr->RttWr[Chipsel] = (UINT8) TblPtr->RttWr;
236 break;
237 }
238 }
239 }
240 }
241 }
242 }
243 TblPtr++;
244 }
245 // Record which Cs(s) have no entries. Later on, we will check if there are overriding values for them.
246 if ((i == TableSize) && (NBPtr->SharedPtr->VoltageMap == VDDIO_DETERMINED)) {
247 NoEntryCsMask |= (UINT8) 1 << Chipsel;
248 }
249 }
250 }
251
252 PsoCsMaskRtt16 = MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_ODT_RTTNOM);
253 PsoCsMaskRtt16 &= MemPProceedTblDrvOverride (NBPtr, NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_TBLDRV_ODT_RTTWR);
254 //
255 // Check to see if invalid entry exist ?
256 //
257 if ((PsoCsMaskRtt16 & INVALID_CONFIG_FLAG) != 0) {
258 IDS_HDT_CONSOLE (MEM_FLOW, "\nInvalid entry is found\n\n");
259 return FALSE;
260 }
261
262 //
263 // If there are no entries for certain Cs(s), we need to check if overriding values (both RttNom and RttWr) existed for them.
264 // Otherwise, return FALSE.
265 //
266 PsoCsMaskRtt = (UINT8) PsoCsMaskRtt16;
267 if (NoEntryCsMask != 0) {
268 if ((PsoCsMaskRtt & NoEntryCsMask) != NoEntryCsMask) {
269 IDS_HDT_CONSOLE (MEM_FLOW, "\nNo Rtt entries\n");
270 PutEventLog (AGESA_ERROR, MEM_ERROR_RTT_NOT_FOUND, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
271 SetMemError (AGESA_ERROR, NBPtr->MCTPtr);
272 if (!NBPtr->MemPtr->ErrorHandling (NBPtr->MCTPtr, NBPtr->Dct, EXCLUDE_ALL_CHIPSEL, &NBPtr->MemPtr->StdHeader)) {
273 ASSERT (FALSE);
274 }
275 return FALSE;
276 }
277 }
278
279 return TRUE;
280}