AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Mem / Feat / OLSPARE / mfspr.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mfspr.c
6  *
7  * Feature enable online spare
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project: AGESA
11  * @e sub-project: (Mem/Feat/Olspare)
12  * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 02:16:51 -0700 (Wed, 22 Dec 2010) $
13  *
14  **/
15 /*****************************************************************************
16   *
17  * Copyright (C) 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.
41   *
42   * ***************************************************************************
43   *
44  */
45
46 /*
47  *----------------------------------------------------------------------------
48  *                                MODULES USED
49  *
50  *----------------------------------------------------------------------------
51  */
52
53
54
55 #include "AGESA.h"
56 #include "mm.h"
57 #include "mn.h"
58 #include "mfspr.h"
59 #include "Ids.h"
60 #include "amdlib.h"
61 #include "Filecode.h"
62 #include "GeneralServices.h"
63 CODE_GROUP (G2_PEI)
64 RDATA_GROUP (G2_PEI)
65
66 #define FILECODE PROC_MEM_FEAT_OLSPARE_MFSPR_FILECODE
67 /*----------------------------------------------------------------------------
68  *                          DEFINITIONS AND MACROS
69  *
70  *----------------------------------------------------------------------------
71  */
72
73 /*----------------------------------------------------------------------------
74  *                           TYPEDEFS AND STRUCTURES
75  *
76  *----------------------------------------------------------------------------
77  */
78
79 /*----------------------------------------------------------------------------
80  *                        PROTOTYPES OF LOCAL FUNCTIONS
81  *
82  *----------------------------------------------------------------------------
83  */
84
85 /*----------------------------------------------------------------------------
86  *                            EXPORTED FUNCTIONS
87  *
88  *----------------------------------------------------------------------------
89  */
90
91 /* -----------------------------------------------------------------------------*/
92 /**
93  *
94  *  Enable online spare on current node if it is requested.
95  *
96  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
97  *
98  *     @return          TRUE -  This feature is enabled.
99  *     @return          FALSE - This feature is not enabled.
100  */
101
102 BOOLEAN
103 MemFOnlineSpare (
104   IN OUT   MEM_NB_BLOCK *NBPtr
105   )
106 {
107   UINT8 Dct;
108   UINT8 q;
109   UINT8  Value8;
110   BOOLEAN Flag;
111   BOOLEAN OnlineSprEnabled[MAX_CHANNELS_PER_SOCKET];
112
113   MEM_PARAMETER_STRUCT *RefPtr;
114   DIE_STRUCT *MCTPtr;
115
116   ASSERT (NBPtr != NULL);
117
118   RefPtr = NBPtr->RefPtr;
119   Flag = FALSE;
120   if (RefPtr->EnableOnLineSpareCtl != 0) {
121     RefPtr->GStatus[GsbEnDIMMSpareNW] = TRUE;
122     MCTPtr = NBPtr->MCTPtr;
123
124     // Check if online spare can be enabled on current node
125     for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
126       ASSERT (Dct < sizeof (OnlineSprEnabled));
127       NBPtr->SwitchDCT (NBPtr, Dct);
128       OnlineSprEnabled[Dct] = FALSE;
129       if ((MCTPtr->GangedMode == 0) || (MCTPtr->Dct == 0)) {
130         if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
131           // Make sure at least two chip-selects are available
132           Value8 = LibAmdBitScanReverse (NBPtr->DCTPtr->Timings.CsEnabled);
133           if (Value8 > LibAmdBitScanForward (NBPtr->DCTPtr->Timings.CsEnabled)) {
134             OnlineSprEnabled[Dct] = TRUE;
135             Flag = TRUE;
136           } else {
137             PutEventLog (AGESA_ERROR, MEM_ERROR_DIMM_SPARING_NOT_ENABLED, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
138             MCTPtr->ErrStatus[EsbSpareDis] = TRUE;
139           }
140         }
141       }
142     }
143
144     // If we don't have spared rank on any DCT, we don't run the rest part of the code.
145     if (!Flag) {
146       return FALSE;
147     }
148
149     MCTPtr->NodeMemSize = 0;
150     for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
151       NBPtr->SwitchDCT (NBPtr, Dct);
152       if (OnlineSprEnabled[Dct]) {
153         // Only run StitchMemory if we need to set a spare rank.
154         NBPtr->DCTPtr->Timings.DctMemSize = 0;
155         for (q = 0; q < MAX_CS_PER_CHANNEL; q++) {
156           NBPtr->SetBitField (NBPtr, BFCSBaseAddr0Reg + q, 0);
157         }
158         Flag = NBPtr->StitchMemory (NBPtr);
159         ASSERT (Flag == TRUE);
160       } else if ((MCTPtr->GangedMode == 0) && (NBPtr->DCTPtr->Timings.DctMemSize != 0)) {
161         // Otherwise, need to adjust the memory size on the node.
162         MCTPtr->NodeMemSize += NBPtr->DCTPtr->Timings.DctMemSize;
163         MCTPtr->NodeSysLimit = MCTPtr->NodeMemSize - 1;
164       }
165     }
166     return TRUE;
167   } else {
168     return FALSE;
169   }
170 }