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