AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Mem / NB / C32 / mnS3c32.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mns3c32.c
6  *
7  * C32 memory specific function to support S3 resume
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project: AGESA
11  * @e sub-project: (Mem/NB/C32)
12  * @e \$Revision: 59560 $ @e \$Date: 2011-09-26 11:43:44 -0600 (Mon, 26 Sep 2011) $
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 "AdvancedApi.h"
57 #include "amdlib.h"
58 #include "Ids.h"
59 #include "OptionMemory.h"
60 #include "mm.h"
61 #include "mn.h"
62 #include "S3.h"
63 #include "mfs3.h"
64 #include "mnc32.h"
65 #include "cpuRegisters.h"
66 #include "cpuFamRegisters.h"
67 #include "cpuFamilyTranslation.h"
68 #include "mnS3c32.h"
69 #include "heapManager.h"
70 #include "Filecode.h"
71 CODE_GROUP (G3_DXE)
72 RDATA_GROUP (G3_DXE)
73
74 #define FILECODE PROC_MEM_NB_C32_MNS3C32_FILECODE
75
76 /*----------------------------------------------------------------------------
77  *                           TYPEDEFS AND STRUCTURES
78  *
79  *----------------------------------------------------------------------------
80  */
81
82 /*----------------------------------------------------------------------------
83  *                        PROTOTYPES OF LOCAL FUNCTIONS
84  *
85  *----------------------------------------------------------------------------
86  */
87 BOOLEAN
88 MemS3ResumeConstructNBBlockC32 (
89   IN OUT   VOID *S3NBPtr,
90   IN OUT   MEM_DATA_STRUCT *MemPtr,
91   IN       UINT8 NodeID
92   );
93
94 UINT16
95 STATIC
96 MemNS3GetRegLstPtrC32 (
97   IN OUT   MEM_NB_BLOCK *NBPtr,
98   IN OUT   DESCRIPTOR_GROUP *DescriptPtr
99   );
100
101 AGESA_STATUS
102 STATIC
103 MemNS3GetDeviceRegLstC32 (
104   IN       UINT32 RegisterLstID,
105      OUT   VOID **RegisterHeader
106   );
107
108 VOID
109 STATIC
110 MemNS3SetSpecialPCIRegC32 (
111   IN       ACCESS_WIDTH AccessWidth,
112   IN       PCI_ADDR Address,
113   IN       VOID *Value,
114   IN OUT   VOID *ConfigPtr
115   );
116
117 VOID
118 STATIC
119 MemNS3ExitSelfRefRegC32 (
120   IN OUT   MEM_NB_BLOCK *NBPtr,
121   IN OUT   AMD_CONFIG_PARAMS *StdHeader
122   );
123
124 /*----------------------------------------------------------------------------
125  *                          DEFINITIONS AND MACROS
126  *
127  *----------------------------------------------------------------------------
128  */
129 PCI_SPECIAL_CASE PciSpecialCaseFuncC32[] = {
130   {MemNS3GetCSRNb, MemNS3SetCSRNb},
131   {MemNS3GetCSRNb, MemNS3SetSpecialPCIRegC32},
132   {MemNS3GetBitFieldNb, MemNS3SetBitFieldNb}
133 };
134
135 PCI_REG_DESCRIPTOR ROMDATA S3PciPreSelfRefDescriptorC32[] = {
136   {{0, 0, 0}, FUNC_2, 0x110, 0xFFFFFFFF},
137   {{0, 0, 0}, FUNC_1, 0x40,  0xFFFF3F03},
138   {{0, 0, 0}, FUNC_1, 0x48,  0xFFFF3F03},
139   {{0, 0, 0}, FUNC_1, 0x50,  0xFFFF3F03},
140   {{0, 0, 0}, FUNC_1, 0x58,  0xFFFF3F03},
141   {{0, 0, 0}, FUNC_1, 0x60,  0xFFFF3F03},
142   {{0, 0, 0}, FUNC_1, 0x68,  0xFFFF3F03},
143   {{0, 0, 0}, FUNC_1, 0x70,  0xFFFF3F03},
144   {{0, 0, 0}, FUNC_1, 0x78,  0xFFFF3F03},
145   {{0, 1, 0}, FUNC_1, 0x140, 0x000000FF},
146   {{0, 1, 0}, FUNC_1, 0x148, 0x000000FF},
147   {{0, 1, 0}, FUNC_1, 0x150, 0x000000FF},
148   {{0, 1, 0}, FUNC_1, 0x158, 0x000000FF},
149   {{0, 1, 0}, FUNC_1, 0x160, 0x000000FF},
150   {{0, 1, 0}, FUNC_1, 0x168, 0x000000FF},
151   {{0, 1, 0}, FUNC_1, 0x170, 0x000000FF},
152   {{0, 1, 0}, FUNC_1, 0x178, 0x000000FF},
153   {{0, 0, 0}, FUNC_1, 0x44,  0xFFFF07FF},
154   {{0, 0, 0}, FUNC_1, 0x4C,  0xFFFF07FF},
155   {{0, 0, 0}, FUNC_1, 0x54,  0xFFFF07FF},
156   {{0, 0, 0}, FUNC_1, 0x5C,  0xFFFF07FF},
157   {{0, 0, 0}, FUNC_1, 0x64,  0xFFFF07FF},
158   {{0, 0, 0}, FUNC_1, 0x6C,  0xFFFF07FF},
159   {{0, 0, 0}, FUNC_1, 0x74,  0xFFFF07FF},
160   {{0, 0, 0}, FUNC_1, 0x7C,  0xFFFF07FF},
161   {{0, 1, 0}, FUNC_1, 0x144, 0x000000FF},
162   {{0, 1, 0}, FUNC_1, 0x14C, 0x000000FF},
163   {{0, 1, 0}, FUNC_1, 0x154, 0x000000FF},
164   {{0, 1, 0}, FUNC_1, 0x15C, 0x000000FF},
165   {{0, 1, 0}, FUNC_1, 0x164, 0x000000FF},
166   {{0, 1, 0}, FUNC_1, 0x16C, 0x000000FF},
167   {{0, 1, 0}, FUNC_1, 0x174, 0x000000FF},
168   {{0, 1, 0}, FUNC_1, 0x17C, 0x000000FF},
169   {{0, 0, 0}, FUNC_1, 0xF0,  0xFF00FF83},
170   {{0, 0, 0}, FUNC_1, 0x120, 0x00FFFFFF},
171   {{0, 0, 0}, FUNC_1, 0x124, 0x07FFFFFF},
172   {{0, 0, 0}, FUNC_2, 0x114, 0xFFFFFC00},
173   {{0, 0, 0}, FUNC_2, 0x118, 0xF773FFFF},
174   {{0, 0, 0}, FUNC_2, 0x11C, 0xFFFFFFFF},
175   {{0, 0, 0}, FUNC_2, 0x1B0, 0xFFD3FF3F}
176 };
177
178 CONST PCI_REGISTER_BLOCK_HEADER ROMDATA S3PciPreSelfRefC32 = {
179   0,
180   (sizeof (S3PciPreSelfRefDescriptorC32) / sizeof (PCI_REG_DESCRIPTOR)),
181   S3PciPreSelfRefDescriptorC32,
182   NULL
183 };
184
185 CONDITIONAL_PCI_REG_DESCRIPTOR ROMDATA S3CPciPreSelfDescriptorC32[] = {
186    // DCT 0
187   {{0, 0, 0}, FUNC_2, 0x40,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
188   {{0, 0, 0}, FUNC_2, 0x44,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
189   {{0, 0, 0}, FUNC_2, 0x48,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
190   {{0, 0, 0}, FUNC_2, 0x4C,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
191   {{0, 0, 0}, FUNC_2, 0x50,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
192   {{0, 0, 0}, FUNC_2, 0x54,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
193   {{0, 0, 0}, FUNC_2, 0x58,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
194   {{0, 0, 0}, FUNC_2, 0x5C,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
195   {{0, 0, 0}, FUNC_2, 0x60,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
196   {{0, 0, 0}, FUNC_2, 0x64,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
197   {{0, 0, 0}, FUNC_2, 0x68,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
198   {{0, 0, 0}, FUNC_2, 0x6C,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
199   {{0, 0, 0}, FUNC_2, 0x78,  0xFFCDBF0F, DCT0_MASK, DCT0_ANY_DIMM_MASK},
200   {{0, 0, 0}, FUNC_2, 0x7C,  0xFFF7FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
201   {{0, 2, 0}, FUNC_2, 0x80,  0x0000FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
202   {{0, 0, 0}, FUNC_2, 0x84,  0x07FFEFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
203   {{0, 0, 0}, FUNC_2, 0x88,  0xFFFFFFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
204   {{0, 0, 0}, FUNC_2, 0x8C,  0xFFFF7FFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
205   {{0, 0, 0}, FUNC_2, 0x90,  0x00FFFFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
206   {{0, 0, 0}, FUNC_2, 0xA4,  0x000F7B00, DCT0_MASK, DCT0_ANY_DIMM_MASK},
207   {{0, 0, 0}, FUNC_2, 0xA8,  0x0007FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
208   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 0, 0x180), 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK},
209   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 0, 0x181), 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK},
210   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 0, 0x182), 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK},
211   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 0, 0x183), 0x0F0F0F0F, DCT0_MASK, DCT0_ANY_DIMM_MASK},
212   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x00),  0x30333333, DCT0_MASK, ANY_DIMM_MASK},
213   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0A),  0x3FFFFFFF, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK},
214   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0C),  0x001FBFFF, DCT0_MASK, ANY_DIMM_MASK},
215   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x04),  0x003F3F3F, DCT0_MASK, ANY_DIMM_MASK},
216   {{2, 2, 1}, DCT0,   BFPhyClkConfig0, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
217   {{2, 2, 1}, DCT0,   BFPhyClkConfig1, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
218   {{2, 2, 1}, DCT0,   BFPhyClkConfig2, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
219   {{2, 2, 1}, DCT0,   BFPhyClkConfig3, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
220   //errata 322
221   {{2, 2, 1}, DCT0,   BFErr322I, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
222   {{2, 2, 1}, DCT0,   BFErr322II, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
223   //errata 263
224   {{2, 2, 1}, DCT0,   BFErr263, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
225
226    // DCT 1
227   {{0, 0, 0}, FUNC_2, 0x140, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
228   {{0, 0, 0}, FUNC_2, 0x144, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
229   {{0, 0, 0}, FUNC_2, 0x148, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
230   {{0, 0, 0}, FUNC_2, 0x14C, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
231   {{0, 0, 0}, FUNC_2, 0x150, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
232   {{0, 0, 0}, FUNC_2, 0x154, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
233   {{0, 0, 0}, FUNC_2, 0x158, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
234   {{0, 0, 0}, FUNC_2, 0x15C, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
235   {{0, 0, 0}, FUNC_2, 0x160, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
236   {{0, 0, 0}, FUNC_2, 0x164, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
237   {{0, 0, 0}, FUNC_2, 0x168, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
238   {{0, 0, 0}, FUNC_2, 0x16C, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
239   {{0, 0, 0}, FUNC_2, 0x178, 0xFFCDBF0F, DCT1_MASK, DCT1_ANY_DIMM_MASK},
240   {{0, 0, 0}, FUNC_2, 0x17C, 0xFFF7FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
241   {{0, 2, 0}, FUNC_2, 0x180, 0x0000FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
242   {{0, 0, 0}, FUNC_2, 0x184, 0x07FFEFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
243   {{0, 0, 0}, FUNC_2, 0x188, 0xFFFFFFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
244   {{0, 0, 0}, FUNC_2, 0x18C, 0xFFF7FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
245   {{0, 0, 0}, FUNC_2, 0x190, 0x00FFFFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
246   {{0, 0, 0}, FUNC_2, 0x1A4, 0x000F7B00, DCT1_MASK, DCT1_ANY_DIMM_MASK},
247   {{0, 0, 0}, FUNC_2, 0x1A8, 0x0007FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
248   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 1, 0x180), 0x0F0F0F0F, DCT1_MASK, DCT1_ANY_DIMM_MASK},
249   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 1, 0x181), 0x0F0F0F0F, DCT1_MASK, DCT1_ANY_DIMM_MASK},
250   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 1, 0x182), 0x0F0F0F0F, DCT1_MASK, DCT1_ANY_DIMM_MASK},
251   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_EXTRA_FLAG, 1, 0x183), 0x0F0F0F0F, DCT1_MASK, DCT1_ANY_DIMM_MASK},
252   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x00), 0x30333333, DCT1_MASK, ANY_DIMM_MASK},
253   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x0C), 0x001FBFFF, DCT1_MASK, ANY_DIMM_MASK},
254   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x04), 0x003F3F3F, DCT1_MASK, ANY_DIMM_MASK},
255   {{2, 2, 1}, DCT1,   BFPhyClkConfig0, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
256   {{2, 2, 1}, DCT1,   BFPhyClkConfig1, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
257   {{2, 2, 1}, DCT1,   BFPhyClkConfig2, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
258   {{2, 2, 1}, DCT1,   BFPhyClkConfig3, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
259   // errata 322
260   {{2, 2, 1}, DCT1,   BFErr322I, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
261   {{2, 2, 1}, DCT1,   BFErr322II, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
262   // errata 263
263   {{2, 2, 1}, DCT1,   BFErr263, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
264
265   // Restore F2x[1,0]94 right before exit self refresh
266   {{0, 0, 0}, FUNC_2, 0x94,  0xFFFFFF07, ANY_DIMM_MASK, ANY_DIMM_MASK},
267   {{0, 0, 0}, FUNC_2, 0x194, 0xFFFFFF07, ANY_DIMM_MASK, ANY_DIMM_MASK}
268 };
269
270 CONST CPCI_REGISTER_BLOCK_HEADER ROMDATA S3CPciPreSelfRefC32 = {
271   0,
272   (sizeof (S3CPciPreSelfDescriptorC32) / sizeof (CONDITIONAL_PCI_REG_DESCRIPTOR)),
273   S3CPciPreSelfDescriptorC32,
274   PciSpecialCaseFuncC32
275 };
276
277 CONDITIONAL_PCI_REG_DESCRIPTOR ROMDATA S3CPciPostSelfDescriptorC32[] = {
278   // DCT0
279   {{2, 2, 1}, DCT0,   BFEccDLLPwrDnConf, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
280   {{2, 2, 1}, DCT0,   BFEccDLLConf, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
281   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x10),  0x01FF01FF, DCT0_MASK, 0x01},
282   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x11),  0x01FF01FF, DCT0_MASK, 0x01},
283   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x12),  0x000001FF, DCT0_MASK, 0x01},
284   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x13),  0x01FF01FF, DCT0_MASK, 0x04},
285   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x14),  0x01FF01FF, DCT0_MASK, 0x04},
286   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x15),  0x000001FF, DCT0_MASK, 0x04},
287   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x16),  0x01FF01FF, DCT0_MASK, 0x10},
288   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x17),  0x01FF01FF, DCT0_MASK, 0x10},
289   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x18),  0x000001FF, DCT0_MASK, 0x10},
290   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x19),  0x01FF01FF, DCT0_MASK, 0x40},
291   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x1A),  0x01FF01FF, DCT0_MASK, 0x40},
292   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x1B),  0x000001FF, DCT0_MASK, 0x40},
293   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x20),  0x01FF01FF, DCT0_MASK, 0x01},
294   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x21),  0x01FF01FF, DCT0_MASK, 0x01},
295   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x23),  0x01FF01FF, DCT0_MASK, 0x04},
296   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x24),  0x01FF01FF, DCT0_MASK, 0x04},
297   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x26),  0x01FF01FF, DCT0_MASK, 0x10},
298   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x27),  0x01FF01FF, DCT0_MASK, 0x10},
299   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x29),  0x01FF01FF, DCT0_MASK, 0x40},
300   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x2A),  0x01FF01FF, DCT0_MASK, 0x40},
301   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x01),  0x7F7F7F7F, DCT0_MASK, 0x01},
302   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x02),  0x7F7F7F7F, DCT0_MASK, 0x01},
303   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x03),  0x0000007F, DCT0_MASK, 0x01},
304   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x101), 0x7F7F7F7F, DCT0_MASK, 0x04},
305   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x102), 0x7F7F7F7F, DCT0_MASK, 0x04},
306   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x103), 0x0000007F, DCT0_MASK, 0x04},
307   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x201), 0x7F7F7F7F, DCT0_MASK, 0x10},
308   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x202), 0x7F7F7F7F, DCT0_MASK, 0x10},
309   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x203), 0x0000007F, DCT0_MASK, 0x10},
310   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x301), 0x7F7F7F7F, DCT0_MASK, 0x40},
311   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x302), 0x7F7F7F7F, DCT0_MASK, 0x40},
312   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x303), 0x0000007F, DCT0_MASK, 0x40},
313   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x05),  0x3F3F3F3F, DCT0_MASK, 0x01},
314   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x06),  0x3F3F3F3F, DCT0_MASK, 0x01},
315   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x07),  0x0000003F, DCT0_MASK, 0x01},
316   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x105), 0x3F3F3F3F, DCT0_MASK, 0x04},
317   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x106), 0x3F3F3F3F, DCT0_MASK, 0x04},
318   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x107), 0x0000003F, DCT0_MASK, 0x04},
319   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x205), 0x3F3F3F3F, DCT0_MASK, 0x10},
320   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x206), 0x3F3F3F3F, DCT0_MASK, 0x10},
321   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x207), 0x0000003F, DCT0_MASK, 0x10},
322   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x305), 0x3F3F3F3F, DCT0_MASK, 0x40},
323   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x306), 0x3F3F3F3F, DCT0_MASK, 0x40},
324   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x307), 0x0000003F, DCT0_MASK, 0x40},
325   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0A),  0xFFFFFFFF, DCT0_MASK, ANY_DIMM_MASK},
326   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0D),  0x23772377, DCT0_MASK, ANY_DIMM_MASK},
327   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x30),  0x00FF00FF, DCT0_DDR3_MASK, 0x01},
328   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x31),  0x00FF00FF, DCT0_DDR3_MASK, 0x01},
329   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x32),  0x000000FF, DCT0_DDR3_MASK, 0x01},
330   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x33),  0x00FF00FF, DCT0_DDR3_MASK, 0x04},
331   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x34),  0x00FF00FF, DCT0_DDR3_MASK, 0x04},
332   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x35),  0x000000FF, DCT0_DDR3_MASK, 0x04},
333   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x36),  0x00FF00FF, DCT0_DDR3_MASK, 0x10},
334   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x37),  0x00FF00FF, DCT0_DDR3_MASK, 0x10},
335   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x38),  0x000000FF, DCT0_DDR3_MASK, 0x10},
336   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x39),  0x00FF00FF, DCT0_DDR3_MASK, 0x40},
337   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x3A),  0x00FF00FF, DCT0_DDR3_MASK, 0x40},
338   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x3B),  0x000000FF, DCT0_DDR3_MASK, 0x40},
339   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x40),  0x00FF00FF, DCT0_DDR3_MASK, 0x01},
340   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x41),  0x00FF00FF, DCT0_DDR3_MASK, 0x01},
341   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x43),  0x00FF00FF, DCT0_DDR3_MASK, 0x04},
342   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x44),  0x00FF00FF, DCT0_DDR3_MASK, 0x04},
343   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x46),  0x00FF00FF, DCT0_DDR3_MASK, 0x10},
344   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x47),  0x00FF00FF, DCT0_DDR3_MASK, 0x10},
345   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x49),  0x00FF00FF, DCT0_DDR3_MASK, 0x40},
346   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x4A),  0x00FF00FF, DCT0_DDR3_MASK, 0x40},
347
348     // DCT1
349   {{2, 2, 1}, DCT0,   BFEccDLLPwrDnConf, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
350   {{2, 2, 1}, DCT0,   BFEccDLLConf, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
351   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x10),  0x01FF01FF, DCT1_MASK, 0x02},
352   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x11),  0x01FF01FF, DCT1_MASK, 0x02},
353   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x12),  0x000001FF, DCT1_MASK, 0x02},
354   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x13),  0x01FF01FF, DCT1_MASK, 0x08},
355   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x14),  0x01FF01FF, DCT1_MASK, 0x08},
356   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x15),  0x000001FF, DCT1_MASK, 0x08},
357   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x16),  0x01FF01FF, DCT1_MASK, 0x20},
358   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x17),  0x01FF01FF, DCT1_MASK, 0x20},
359   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x18),  0x000001FF, DCT1_MASK, 0x20},
360   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x19),  0x01FF01FF, DCT1_MASK, 0x80},
361   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x1A),  0x01FF01FF, DCT1_MASK, 0x80},
362   {{0, 2, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x1B),  0x000001FF, DCT1_MASK, 0x80},
363   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x20),  0x01FF01FF, DCT1_MASK, 0x02},
364   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x21),  0x01FF01FF, DCT1_MASK, 0x02},
365   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x23),  0x01FF01FF, DCT1_MASK, 0x08},
366   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x24),  0x01FF01FF, DCT1_MASK, 0x08},
367   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x26),  0x01FF01FF, DCT1_MASK, 0x20},
368   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x27),  0x01FF01FF, DCT1_MASK, 0x20},
369   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x29),  0x01FF01FF, DCT1_MASK, 0x80},
370   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x2A),  0x01FF01FF, DCT1_MASK, 0x80},
371   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x01),  0x7F7F7F7F, DCT1_MASK, 0x02},
372   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x02),  0x7F7F7F7F, DCT1_MASK, 0x02},
373   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x03),  0x0000007F, DCT1_MASK, 0x02},
374   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x101),  0x7F7F7F7F, DCT1_MASK, 0x08},
375   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x102),  0x7F7F7F7F, DCT1_MASK, 0x08},
376   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x103),  0x0000007F, DCT1_MASK, 0x08},
377   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x201),  0x7F7F7F7F, DCT1_MASK, 0x20},
378   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x202),  0x7F7F7F7F, DCT1_MASK, 0x20},
379   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x203),  0x0000007F, DCT1_MASK, 0x20},
380   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x301),  0x7F7F7F7F, DCT1_MASK, 0x80},
381   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x302),  0x7F7F7F7F, DCT1_MASK, 0x80},
382   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x303),  0x0000007F, DCT1_MASK, 0x80},
383   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x05),  0x3F3F3F3F, DCT1_MASK, 0x02},
384   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x06),  0x3F3F3F3F, DCT1_MASK, 0x02},
385   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x07),  0x0000003F, DCT1_MASK, 0x02},
386   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x105),  0x3F3F3F3F, DCT1_MASK, 0x08},
387   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x106),  0x3F3F3F3F, DCT1_MASK, 0x08},
388   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x107),  0x0000003F, DCT1_MASK, 0x08},
389   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x205),  0x3F3F3F3F, DCT1_MASK, 0x20},
390   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x206),  0x3F3F3F3F, DCT1_MASK, 0x20},
391   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x207),  0x0000003F, DCT1_MASK, 0x20},
392   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x305),  0x3F3F3F3F, DCT1_MASK, 0x80},
393   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x306),  0x3F3F3F3F, DCT1_MASK, 0x80},
394   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x307),  0x0000003F, DCT1_MASK, 0x80},
395   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x0D),  0x23772377, DCT1_MASK, ANY_DIMM_MASK},
396   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x30),  0x00FF00FF, DCT1_DDR3_MASK, 0x02},
397   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x31),  0x00FF00FF, DCT1_DDR3_MASK, 0x02},
398   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x32),  0x000000FF, DCT1_DDR3_MASK, 0x02},
399   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x33),  0x00FF00FF, DCT1_DDR3_MASK, 0x08},
400   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x34),  0x00FF00FF, DCT1_DDR3_MASK, 0x08},
401   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x35),  0x000000FF, DCT1_DDR3_MASK, 0x08},
402   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x36),  0x00FF00FF, DCT1_DDR3_MASK, 0x20},
403   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x37),  0x00FF00FF, DCT1_DDR3_MASK, 0x20},
404   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x38),  0x000000FF, DCT1_DDR3_MASK, 0x20},
405   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x39),  0x00FF00FF, DCT1_DDR3_MASK, 0x80},
406   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x3A),  0x00FF00FF, DCT1_DDR3_MASK, 0x80},
407   {{0, 1, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x3B),  0x000000FF, DCT1_DDR3_MASK, 0x80},
408   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x40),  0x00FF00FF, DCT1_DDR3_MASK, 0x02},
409   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x41),  0x00FF00FF, DCT1_DDR3_MASK, 0x02},
410   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x43),  0x00FF00FF, DCT1_DDR3_MASK, 0x08},
411   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x44),  0x00FF00FF, DCT1_DDR3_MASK, 0x08},
412   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x46),  0x00FF00FF, DCT1_DDR3_MASK, 0x20},
413   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x47),  0x00FF00FF, DCT1_DDR3_MASK, 0x20},
414   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x49),  0x00FF00FF, DCT1_DDR3_MASK, 0x80},
415   {{0, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x4A),  0x00FF00FF, DCT1_DDR3_MASK, 0x80},
416
417   // DllShutDown
418   {{2, 2, 1}, DCT0,   BFPhyPLLLockTime, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
419   {{2, 2, 1}, DCT0,   BFPhyDLLLockTime, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
420   {{2, 1, 1}, DCT0,   BFDisDllShutdownSR, 0x00000001, DCT0_MASK, ANY_DIMM_MASK},
421   {{2, 2, 1}, DCT1,   BFPhyPLLLockTime, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
422   {{2, 2, 1}, DCT1,   BFPhyDLLLockTime, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
423   {{2, 1, 1}, DCT1,   BFDisDllShutdownSR, 0x00000001, DCT1_MASK, ANY_DIMM_MASK},
424
425   // Restore scrubber related registers after restoring training related registers
426   {{0, 0, 0}, FUNC_3, 0x180, 0x027F7BFF, ANY_DIMM_MASK, ANY_DIMM_MASK},
427   {{0, 0, 0}, FUNC_3, 0x44,  0xFFFFFFFE, ANY_DIMM_MASK, ANY_DIMM_MASK},
428   {{0, 0, 0}, FUNC_3, 0x58,  0x1F1F1F1F, ANY_DIMM_MASK, ANY_DIMM_MASK},
429   {{2, 1, 1}, DCT0,   BFScrubReDirEn, 0x00000001, ANY_DIMM_MASK, ANY_DIMM_MASK}
430 };
431
432 CONST CPCI_REGISTER_BLOCK_HEADER ROMDATA S3CPciPostSelfRefC32 = {
433   0,
434   (sizeof (S3CPciPostSelfDescriptorC32) / sizeof (CONDITIONAL_PCI_REG_DESCRIPTOR)),
435   S3CPciPostSelfDescriptorC32,
436   PciSpecialCaseFuncC32
437 };
438
439 MSR_REG_DESCRIPTOR ROMDATA S3MSRPreSelfRefDescriptorC32[] = {
440   {{0, 0, 0}, 0xC0010010, 0x00000000007F07FF},
441   {{0, 0, 0}, 0xC001001A, 0x0000FFFFFF800000},
442   {{0, 0, 0}, 0xC001001D, 0x0000FFFFFF800000},
443   {{0, 0, 0}, 0xC001001F, 0xC047F87FFF527FFF}
444 };
445
446 CONST MSR_REGISTER_BLOCK_HEADER ROMDATA S3MSRPreSelfRefC32 = {
447   0,
448   (sizeof (S3MSRPreSelfRefDescriptorC32) / sizeof (MSR_REG_DESCRIPTOR)),
449   S3MSRPreSelfRefDescriptorC32,
450   NULL
451 };
452
453 VOID *MemS3RegListC32[] = {
454   (VOID *)&S3PciPreSelfRefC32,
455   NULL,
456   (VOID *)&S3CPciPreSelfRefC32,
457   (VOID *)&S3CPciPostSelfRefC32,
458   (VOID *)&S3MSRPreSelfRefC32,
459   NULL,
460   NULL,
461   NULL
462 };
463
464 CONST UINT16 ROMDATA SpecialCasePCIRegC32[] = {
465   SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x00),
466   SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0A),
467   SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0C),
468   SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x04),
469   SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x00),
470   SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x0C),
471   SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x04)
472 };
473 /*----------------------------------------------------------------------------
474  *                            EXPORTED FUNCTIONS
475  *
476  *----------------------------------------------------------------------------
477  */
478
479 /* -----------------------------------------------------------------------------*/
480 /**
481  *
482  *
483  *   This function initializes the northbridge block for S3 resume
484  *
485  *     @param[in,out]   *S3NBPtr   - Pointer to MEM_NB_BLOCK.
486  *     @param[in,out]   *MemPtr  - Pointer to MEM_DATA_STRUCT.
487  *     @param[in]       NodeID   - Node ID of the target node.
488  *
489  *     @return         BOOLEAN
490  *                         TRUE - This is the correct constructor for the targeted node.
491  *                         FALSE - This isn't the correct constructor for the targeted node.
492  */
493
494 BOOLEAN
495 MemS3ResumeConstructNBBlockC32 (
496   IN OUT   VOID *S3NBPtr,
497   IN OUT   MEM_DATA_STRUCT *MemPtr,
498   IN       UINT8 NodeID
499   )
500 {
501   INT32 i;
502   MEM_NB_BLOCK *NBPtr;
503
504   NBPtr = ((S3_MEM_NB_BLOCK *)S3NBPtr)->NBPtr;
505   //
506   // Determine if this is the expected NB Type
507   //
508   GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
509   if (!MemNIsIdSupportedC32 (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
510     return FALSE;
511   }
512
513   NBPtr->MemPtr = MemPtr;
514   NBPtr->MCTPtr = &(MemPtr->DiesPerSystem[NodeID]);
515   NBPtr->PciAddr.AddressValue = MemPtr->DiesPerSystem[NodeID].PciAddr.AddressValue;
516   InitNBRegTableC32 (NBPtr, NBPtr->NBRegTable);
517   NBPtr->Node = ((UINT8) NBPtr->PciAddr.Address.Device) - 24;
518   NBPtr->Dct = 0;
519   NBPtr->Channel = 0;
520   NBPtr->Ganged = FALSE;
521   NBPtr->NodeCount = MAX_NODES_SUPPORTED_C32;
522   NBPtr->DctCount = MAX_DCTS_PER_NODE_C32;
523
524   for (i = 0; i < EnumSize; i++) {
525     NBPtr->IsSupported[i] = FALSE;
526   }
527
528   for (i = 0; i < NumberOfHooks; i++) {
529     NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) memDefTrue;
530   }
531
532   LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &MemPtr->StdHeader);
533
534   NBPtr->IsSupported[CheckDllSpeedUp] = TRUE;
535   NBPtr->SwitchDCT = MemNSwitchDCTNb;
536   NBPtr->SwitchChannel = MemNSwitchChannelNb;
537   NBPtr->GetBitField = MemNGetBitFieldNb;
538   NBPtr->SetBitField = MemNSetBitFieldNb;
539   NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldC32;
540   NBPtr->MemNIsIdSupportedNb = MemNIsIdSupportedC32;
541   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3ExitSelfRefReg = MemNS3ExitSelfRefRegC32;
542   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConPCIMask = MemNS3GetConPCIMaskNb;
543   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConMSRMask = (VOID (*) (MEM_NB_BLOCK *, DESCRIPTOR_GROUP *)) memDefRet;
544   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3Resume = MemNS3ResumeNb;
545   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3RestoreScrub = MemNS3RestoreScrubNb;
546   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetRegLstPtr = MemNS3GetRegLstPtrC32;
547   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetDeviceRegLst = MemNS3GetDeviceRegLstC32;
548   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3SpecialCaseHeapSize = (sizeof (SpecialCasePCIRegC32) / sizeof (UINT16)) * sizeof (UINT32);
549
550   MemNSwitchDCTNb (NBPtr, 0);
551
552   return TRUE;
553 }
554
555 /*----------------------------------------------------------------------------
556  *                              LOCAL FUNCTIONS
557  *
558  *----------------------------------------------------------------------------*/
559
560 /* -----------------------------------------------------------------------------*/
561 /**
562  *
563  *
564  *   This function returns the register list for each device for C32
565  *
566  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
567  *     @param[in, out]  *DescriptPtr - Pointer to DESCRIPTOR_GROUP
568  *     @return          UINT16 - size of the device descriptor on the target node.
569  */
570 UINT16
571 STATIC
572 MemNS3GetRegLstPtrC32 (
573   IN OUT   MEM_NB_BLOCK *NBPtr,
574   IN OUT   DESCRIPTOR_GROUP *DescriptPtr
575   )
576 {
577   UINT8 i;
578   UINT16 Size;
579   Size = 0;
580   for (i = PRESELFREF; i <= POSTSELFREF; i ++) {
581     DescriptPtr->PCIDevice[i].Type = (UINT8) (DEV_TYPE_PCI_PRE_ESR + i);
582     DescriptPtr->PCIDevice[i].Node = NBPtr->Node;
583     DescriptPtr->PCIDevice[i].RegisterListID = 0xFFFFFFFF;
584     if ((PCI_REGISTER_BLOCK_HEADER *) MemS3RegListC32[PCI_LST_ESR_C32 - PCI_LST_ESR_C32 + i] != NULL) {
585       DescriptPtr->PCIDevice[i].RegisterListID = PCI_LST_ESR_C32 + i;
586       Size += sizeof (PCI_DEVICE_DESCRIPTOR);
587     }
588     DescriptPtr->CPCIDevice[i].Type = (UINT8) (DEV_TYPE_CPCI_PRE_ESR + i);
589     DescriptPtr->CPCIDevice[i].Node = NBPtr->Node;
590     DescriptPtr->CPCIDevice[i].RegisterListID = 0xFFFFFFFF;
591     if ((CPCI_REGISTER_BLOCK_HEADER *) MemS3RegListC32[CPCI_LST_ESR_C32 - PCI_LST_ESR_C32 + i] != NULL) {
592       DescriptPtr->CPCIDevice[i].RegisterListID = CPCI_LST_ESR_C32 + i;
593       Size += sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR);
594     }
595     DescriptPtr->MSRDevice[i].Type = (UINT8) (DEV_TYPE_MSR_PRE_ESR + i);
596     DescriptPtr->MSRDevice[i].RegisterListID = 0xFFFFFFFF;
597     if ((MSR_REGISTER_BLOCK_HEADER *) MemS3RegListC32[MSR_LST_ESR_C32 - PCI_LST_ESR_C32 + i] != NULL) {
598       DescriptPtr->MSRDevice[i].RegisterListID = MSR_LST_ESR_C32 + i;
599       Size += sizeof (MSR_DEVICE_DESCRIPTOR);
600     }
601     DescriptPtr->CMSRDevice[i].Type = (UINT8) (DEV_TYPE_CMSR_PRE_ESR + i);
602     DescriptPtr->CMSRDevice[i].RegisterListID = 0xFFFFFFFF;
603     if ((CMSR_REGISTER_BLOCK_HEADER *) MemS3RegListC32[CMSR_LST_ESR_C32 - PCI_LST_ESR_C32 + i] != NULL) {
604       DescriptPtr->CMSRDevice[i].RegisterListID = CMSR_LST_ESR_C32 + i;
605       Size += sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR);
606     }
607   }
608   return Size;
609 }
610
611 /* -----------------------------------------------------------------------------*/
612 /**
613  *
614  *
615  *   This function return the register list according to the register ID.
616  *
617  *     @param[in]   RegisterLstID - value of the Register list ID.
618  *     @param[out]  **RegisterHeader - pointer to the address of the register list.
619  *     @return      none
620  */
621 AGESA_STATUS
622 STATIC
623 MemNS3GetDeviceRegLstC32 (
624   IN       UINT32 RegisterLstID,
625      OUT   VOID **RegisterHeader
626   )
627 {
628   if (RegisterLstID >= (sizeof (MemS3RegListC32) / sizeof (VOID *))) {
629     ASSERT(FALSE); // RegisterListID exceeded size of Register list
630     return AGESA_FATAL;
631   }
632   if (MemS3RegListC32[RegisterLstID] != NULL) {
633     *RegisterHeader = MemS3RegListC32[RegisterLstID];
634     return AGESA_SUCCESS;
635   }
636   ASSERT(FALSE); // Device register list error
637   return AGESA_FATAL;
638 }
639
640 /* -----------------------------------------------------------------------------*/
641 /**
642  *
643  *
644  *   This function stores special case register on the heap.
645  *
646  *     @param[in]   AccessWidth - Access width of the register
647  *     @param[in]   Address - address of the CSR register in PCI_ADDR format.
648  *     @param[in, out]  *Value - Pointer to the value be read.
649  *     @param[in, out]  *ConfigPtr - Pointer to Config handle.
650  *     @return         none
651  */
652 VOID
653 STATIC
654 MemNS3SetSpecialPCIRegC32 (
655   IN       ACCESS_WIDTH AccessWidth,
656   IN       PCI_ADDR Address,
657   IN       VOID *Value,
658   IN OUT   VOID *ConfigPtr
659   )
660 {
661   LOCATE_HEAP_PTR LocateBufferPtr;
662   UINT8 i;
663   UINT8 NodeID;
664   UINT8 Offset;
665   S3_SPECIAL_CASE_HEAP_HEADER *SpecialHeapHeader;
666
667   Offset = 0;
668   LocateBufferPtr.BufferHandle = AMD_MEM_S3_DATA_HANDLE;
669   if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) {
670     SpecialHeapHeader = (S3_SPECIAL_CASE_HEAP_HEADER *) LocateBufferPtr.BufferPtr;
671     // Get the node ID of the target die.
672     NodeID = (UINT8) (Address.Address.Device - 24);
673     for (i = 0; i < MAX_NODES_SUPPORTED_C32; i ++) {
674       if (SpecialHeapHeader[i].Node == NodeID) {
675         // Get the offset in the heap for the target die.
676         Offset = SpecialHeapHeader[i].Offset;
677         break;
678       }
679     }
680     ASSERT (i < MAX_NODES_SUPPORTED_C32);
681     // Save the value in the heap at appropriate offset based on the index
682     // of the target register in the special case array.
683     if (Offset != 0) {
684       for (i = 0; i < (sizeof (SpecialCasePCIRegC32) / sizeof (UINT16)); i ++) {
685         if (SpecialCasePCIRegC32[i] == Address.Address.Register) {
686           *(UINT32 *) (LocateBufferPtr.BufferPtr + Offset + (i << 2)) = *(UINT32 *) Value;
687         }
688       }
689     }
690   }
691 }
692
693
694 /* -----------------------------------------------------------------------------*/
695 /**
696  *
697  *
698  *   This function stores special case register on the heap.
699  *
700  *     @param[in,out]  *NBPtr - Pointer to the northbridge block.
701  *     @param[in,out]  *StdHeader - Config handle for library and services.
702  *     @return         none
703  */
704 VOID
705 STATIC
706 MemNS3ExitSelfRefRegC32 (
707   IN OUT   MEM_NB_BLOCK *NBPtr,
708   IN OUT   AMD_CONFIG_PARAMS *StdHeader
709   )
710 {
711   LOCATE_HEAP_PTR LocateBufferPtr;
712   UINT8 i;
713   PCI_ADDR PciAddr;
714   UINT32 Value;
715   UINT8 NodeID;
716   UINT8 Offset;
717   S3_SPECIAL_CASE_HEAP_HEADER *SpecialHeapHeader;
718
719   Offset = 0;
720   PciAddr.Address.Device = NBPtr->PciAddr.Address.Device;
721   PciAddr.Address.Bus = NBPtr->PciAddr.Address.Bus;
722   PciAddr.Address.Segment = NBPtr->PciAddr.Address.Segment;
723   PciAddr.Address.Function = 2;
724   LocateBufferPtr.BufferHandle = AMD_MEM_S3_DATA_HANDLE;
725   if (HeapLocateBuffer (&LocateBufferPtr, StdHeader) == AGESA_SUCCESS) {
726     SpecialHeapHeader = (S3_SPECIAL_CASE_HEAP_HEADER *) LocateBufferPtr.BufferPtr;
727     // Get the node ID of the target die.
728     NodeID = (UINT8) (PciAddr.Address.Device - 24);
729     for (i = 0; i < MAX_NODES_SUPPORTED_C32; i ++) {
730       if (SpecialHeapHeader[i].Node == NodeID) {
731         // Get the offset in the heap for the target die.
732         Offset = SpecialHeapHeader[i].Offset;
733         break;
734       }
735     }
736     ASSERT (i < MAX_NODES_SUPPORTED_C32);
737     // Restore the value one by one in the sequence of the special case register array.
738     if (Offset != 0) {
739       for (i = 0; i < (sizeof (SpecialCasePCIRegC32) / sizeof (UINT16)); i ++) {
740         PciAddr.Address.Register = SpecialCasePCIRegC32[i];
741         Value = *(UINT32 *) (LocateBufferPtr.BufferPtr + Offset + (i << 2));
742         MemNS3SetCSRNb (AccessS3SaveWidth32, PciAddr, &Value, StdHeader);
743       }
744     }
745   }
746 }