AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Mem / NB / PH / mnS3Ph.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mns3Ph.c
6  *
7  * Ph 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/PH)
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 "mnPh.h"
66 #include "cpuRegisters.h"
67 #include "cpuFamRegisters.h"
68 #include "cpuFamilyTranslation.h"
69 #include "mnS3Ph.h"
70 #include "heapManager.h"
71 #include "Filecode.h"
72 CODE_GROUP (G3_DXE)
73 RDATA_GROUP (G3_DXE)
74
75 #define FILECODE PROC_MEM_NB_PH_MNS3PH_FILECODE
76
77 /*----------------------------------------------------------------------------
78  *                           TYPEDEFS AND STRUCTURES
79  *
80  *----------------------------------------------------------------------------
81  */
82
83 /*----------------------------------------------------------------------------
84  *                        PROTOTYPES OF LOCAL FUNCTIONS
85  *
86  *----------------------------------------------------------------------------
87  */
88 UINT16
89 STATIC
90 MemNS3GetRegLstPtrPh (
91   IN OUT   MEM_NB_BLOCK *NBPtr,
92   IN OUT   DESCRIPTOR_GROUP *DescriptPtr
93   );
94
95 AGESA_STATUS
96 STATIC
97 MemNS3GetDeviceRegLstPh (
98   IN       UINT32 RegisterLstID,
99      OUT   VOID **RegisterHeader
100   );
101
102 VOID
103 STATIC
104 MemNS3SetSpecialPCIRegPh (
105   IN       ACCESS_WIDTH AccessWidth,
106   IN       PCI_ADDR Address,
107   IN       VOID *Value,
108   IN OUT   VOID *ConfigPtr
109   );
110
111 VOID
112 STATIC
113 MemNS3ExitSelfRefRegPh (
114   IN OUT   MEM_NB_BLOCK *NBPtr,
115   IN OUT   AMD_CONFIG_PARAMS *StdHeader
116   );
117
118 /*----------------------------------------------------------------------------
119  *                          DEFINITIONS AND MACROS
120  *
121  *----------------------------------------------------------------------------
122  */
123 PCI_SPECIAL_CASE PciSpecialCaseFuncPh[] = {
124   {MemNS3GetCSRNb, MemNS3SetCSRNb},
125   {MemNS3GetCSRNb, MemNS3SetSpecialPCIRegPh},
126   {MemNS3GetBitFieldNb, MemNS3SetBitFieldNb}
127 };
128
129 PCI_REG_DESCRIPTOR ROMDATA S3PciPreSelfRefDescriptorPh[] = {
130   {{0, 0, 0}, FUNC_2, 0x110, 0xFFFFFFFF},
131   {{0, 0, 0}, FUNC_1, 0x40,  0xFFFF3F03},
132   {{0, 0, 0}, FUNC_1, 0x48,  0xFFFF3F03},
133   {{0, 0, 0}, FUNC_1, 0x50,  0xFFFF3F03},
134   {{0, 0, 0}, FUNC_1, 0x58,  0xFFFF3F03},
135   {{0, 0, 0}, FUNC_1, 0x60,  0xFFFF3F03},
136   {{0, 0, 0}, FUNC_1, 0x68,  0xFFFF3F03},
137   {{0, 0, 0}, FUNC_1, 0x70,  0xFFFF3F03},
138   {{0, 0, 0}, FUNC_1, 0x78,  0xFFFF3F03},
139   {{0, 1, 0}, FUNC_1, 0x140, 0x000000FF},
140   {{0, 1, 0}, FUNC_1, 0x148, 0x000000FF},
141   {{0, 1, 0}, FUNC_1, 0x150, 0x000000FF},
142   {{0, 1, 0}, FUNC_1, 0x158, 0x000000FF},
143   {{0, 1, 0}, FUNC_1, 0x160, 0x000000FF},
144   {{0, 1, 0}, FUNC_1, 0x168, 0x000000FF},
145   {{0, 1, 0}, FUNC_1, 0x170, 0x000000FF},
146   {{0, 1, 0}, FUNC_1, 0x178, 0x000000FF},
147   {{0, 0, 0}, FUNC_1, 0x44,  0xFFFF07FF},
148   {{0, 0, 0}, FUNC_1, 0x4C,  0xFFFF07FF},
149   {{0, 0, 0}, FUNC_1, 0x54,  0xFFFF07FF},
150   {{0, 0, 0}, FUNC_1, 0x5C,  0xFFFF07FF},
151   {{0, 0, 0}, FUNC_1, 0x64,  0xFFFF07FF},
152   {{0, 0, 0}, FUNC_1, 0x6C,  0xFFFF07FF},
153   {{0, 0, 0}, FUNC_1, 0x74,  0xFFFF07FF},
154   {{0, 0, 0}, FUNC_1, 0x7C,  0xFFFF07FF},
155   {{0, 1, 0}, FUNC_1, 0x144, 0x000000FF},
156   {{0, 1, 0}, FUNC_1, 0x14C, 0x000000FF},
157   {{0, 1, 0}, FUNC_1, 0x154, 0x000000FF},
158   {{0, 1, 0}, FUNC_1, 0x15C, 0x000000FF},
159   {{0, 1, 0}, FUNC_1, 0x164, 0x000000FF},
160   {{0, 1, 0}, FUNC_1, 0x16C, 0x000000FF},
161   {{0, 1, 0}, FUNC_1, 0x174, 0x000000FF},
162   {{0, 1, 0}, FUNC_1, 0x17C, 0x000000FF},
163   {{0, 0, 0}, FUNC_1, 0xF0,  0xFF00FF83},
164   {{0, 0, 0}, FUNC_1, 0x120, 0x00FFFFFF},
165   {{0, 0, 0}, FUNC_1, 0x124, 0x07FFFFFF},
166   {{0, 0, 0}, FUNC_2, 0x10C, 0x07F3FBF9},
167   {{0, 0, 0}, FUNC_2, 0x114, 0xFFFFFC00},
168   {{0, 0, 0}, FUNC_2, 0x118, 0xF773FFFF},
169   {{0, 0, 0}, FUNC_2, 0x11C, 0xFFFFFFFF},
170   {{0, 0, 0}, FUNC_2, 0x1B0, 0xFFD3FF3F}
171 };
172
173 CONST PCI_REGISTER_BLOCK_HEADER ROMDATA S3PciPreSelfRefPh = {
174   0,
175   (sizeof (S3PciPreSelfRefDescriptorPh) / sizeof (PCI_REG_DESCRIPTOR)),
176   S3PciPreSelfRefDescriptorPh,
177   NULL
178 };
179
180 CONDITIONAL_PCI_REG_DESCRIPTOR ROMDATA S3CPciPreSelfDescriptorPh[] = {
181    // DCT 0
182   {{0, 0, 0}, FUNC_2, 0x40,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
183   {{0, 0, 0}, FUNC_2, 0x44,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
184   {{0, 0, 0}, FUNC_2, 0x48,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
185   {{0, 0, 0}, FUNC_2, 0x4C,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
186   {{0, 0, 0}, FUNC_2, 0x50,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
187   {{0, 0, 0}, FUNC_2, 0x54,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
188   {{0, 0, 0}, FUNC_2, 0x58,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
189   {{0, 0, 0}, FUNC_2, 0x5C,  0x1FF83FEF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
190   {{0, 0, 0}, FUNC_2, 0x60,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
191   {{0, 0, 0}, FUNC_2, 0x64,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
192   {{0, 0, 0}, FUNC_2, 0x68,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
193   {{0, 0, 0}, FUNC_2, 0x6C,  0x1FF83FE0, DCT0_MASK, DCT0_ANY_DIMM_MASK},
194   {{0, 0, 0}, FUNC_2, 0x78,  0xFFCDBF0F, DCT0_MASK, DCT0_ANY_DIMM_MASK},
195   {{0, 0, 0}, FUNC_2, 0x7C,  0xFFF7FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
196   {{0, 2, 0}, FUNC_2, 0x80,  0x0000FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
197   {{0, 0, 0}, FUNC_2, 0x84,  0x07FFEFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
198   {{0, 0, 0}, FUNC_2, 0x88,  0xFFFFFFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
199   {{0, 0, 0}, FUNC_2, 0x8C,  0xFFFF7FFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
200   {{0, 0, 0}, FUNC_2, 0x90,  0x00FFFFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
201   {{0, 0, 0}, FUNC_2, 0xA8,  0x0007FFFF, DCT0_MASK, DCT0_ANY_DIMM_MASK},
202   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x00),  0x30333333, DCT0_MASK, ANY_DIMM_MASK},
203   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0A),  0x3FFFFFFF, DCT0_MASK + DCT1_MASK, ANY_DIMM_MASK},
204   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x0C),  0x001FBFFF, DCT0_MASK, ANY_DIMM_MASK},
205   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 0, 0x04),  0x003F3F3F, DCT0_MASK, ANY_DIMM_MASK},
206   {{2, 2, 1}, DCT0,   BFPhyClkConfig0, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
207   {{2, 2, 1}, DCT0,   BFPhyClkConfig1, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
208   {{2, 2, 1}, DCT0,   BFPhyClkConfig2, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
209   {{2, 2, 1}, DCT0,   BFPhyClkConfig3, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
210   //errata 322
211   {{2, 2, 1}, DCT0,   BFErr322I, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
212   {{2, 2, 1}, DCT0,   BFErr322II, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
213   //errata 263
214   {{2, 2, 1}, DCT0,   BFErr263, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
215   // Dll regulator disable
216   {{2, 2, 1}, DCT0,   BFPhy0x0D040F3E, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
217   {{2, 2, 1}, DCT0,   BFPhy0x0D042F3E, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
218   {{2, 2, 1}, DCT0,   BFPhy0x0D048F3E, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
219   {{2, 2, 1}, DCT0,   BFPhy0x0D04DF3E, 0x0000FFFF, DCT0_MASK, ANY_DIMM_MASK},
220
221    // DCT 1
222   {{0, 0, 0}, FUNC_2, 0x140, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
223   {{0, 0, 0}, FUNC_2, 0x144, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
224   {{0, 0, 0}, FUNC_2, 0x148, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
225   {{0, 0, 0}, FUNC_2, 0x14C, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
226   {{0, 0, 0}, FUNC_2, 0x150, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
227   {{0, 0, 0}, FUNC_2, 0x154, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
228   {{0, 0, 0}, FUNC_2, 0x158, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
229   {{0, 0, 0}, FUNC_2, 0x15C, 0x1FF83FEF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
230   {{0, 0, 0}, FUNC_2, 0x160, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
231   {{0, 0, 0}, FUNC_2, 0x164, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
232   {{0, 0, 0}, FUNC_2, 0x168, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
233   {{0, 0, 0}, FUNC_2, 0x16C, 0x1FF83FE0, DCT1_MASK, DCT1_ANY_DIMM_MASK},
234   {{0, 0, 0}, FUNC_2, 0x178, 0xFFCDBF0F, DCT1_MASK, DCT1_ANY_DIMM_MASK},
235   {{0, 0, 0}, FUNC_2, 0x17C, 0xFFF7FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
236   {{0, 2, 0}, FUNC_2, 0x180, 0x0000FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
237   {{0, 0, 0}, FUNC_2, 0x184, 0x07FFEFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
238   {{0, 0, 0}, FUNC_2, 0x188, 0xFFFFFFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
239   {{0, 0, 0}, FUNC_2, 0x18C, 0xFFF7FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
240   {{0, 0, 0}, FUNC_2, 0x190, 0x00FFFFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
241   {{0, 0, 0}, FUNC_2, 0x1A8, 0x0007FFFF, DCT1_MASK, DCT1_ANY_DIMM_MASK},
242   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x00), 0x30333333, DCT1_MASK, ANY_DIMM_MASK},
243   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x0C), 0x001FBFFF, DCT1_MASK, ANY_DIMM_MASK},
244   {{1, 0, 1}, FUNC_2, SET_S3_SPECIAL_OFFSET (DCT_PHY_FLAG, 1, 0x04), 0x003F3F3F, DCT1_MASK, ANY_DIMM_MASK},
245   {{2, 2, 1}, DCT1,   BFPhyClkConfig0, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
246   {{2, 2, 1}, DCT1,   BFPhyClkConfig1, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
247   {{2, 2, 1}, DCT1,   BFPhyClkConfig2, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
248   {{2, 2, 1}, DCT1,   BFPhyClkConfig3, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
249   // errata 322
250   {{2, 2, 1}, DCT1,   BFErr322I, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
251   {{2, 2, 1}, DCT1,   BFErr322II, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
252   // errata 263
253   {{2, 2, 1}, DCT1,   BFErr263, 0x0000FFFF, DCT1_MASK, ANY_DIMM_MASK},
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 S3CPciPreSelfRefPh = {
266   0,
267   (sizeof (S3CPciPreSelfDescriptorPh) / sizeof (CONDITIONAL_PCI_REG_DESCRIPTOR)),
268   S3CPciPreSelfDescriptorPh,
269   PciSpecialCaseFuncPh
270 };
271
272 CONDITIONAL_PCI_REG_DESCRIPTOR ROMDATA S3CPciPostSelfDescriptorPh[] = {
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 S3CPciPostSelfRefPh = {
435   0,
436   (sizeof (S3CPciPostSelfDescriptorPh) / sizeof (CONDITIONAL_PCI_REG_DESCRIPTOR)),
437   S3CPciPostSelfDescriptorPh,
438   PciSpecialCaseFuncPh
439 };
440
441 MSR_REG_DESCRIPTOR ROMDATA S3MSRPreSelfRefDescriptorPh[] = {
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 S3MSRPreSelfRefPh = {
449   0,
450   (sizeof (S3MSRPreSelfRefDescriptorPh) / sizeof (MSR_REG_DESCRIPTOR)),
451   S3MSRPreSelfRefDescriptorPh,
452   NULL
453 };
454
455 VOID *MemS3RegListPh[] = {
456   (VOID *)&S3PciPreSelfRefPh,
457   NULL,
458   (VOID *)&S3CPciPreSelfRefPh,
459   (VOID *)&S3CPciPostSelfRefPh,
460   (VOID *)&S3MSRPreSelfRefPh,
461   NULL,
462   NULL,
463   NULL
464 };
465
466 CONST UINT16 ROMDATA SpecialCasePCIRegPh[] = {
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  *     MemNIsIdSupportedPh
484  *      This function matches the CPU_LOGICAL_ID with certain criteria to
485  *      determine if it is supported by this NBBlock.
486  *
487  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
488  *     @param[in]       *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
489  *
490  *     @return          TRUE -  This node is a PH.
491  *     @return          FALSE - This node is not a PH.
492  *
493  */
494 BOOLEAN
495 MemNIsIdSupportedPh (
496   IN OUT   MEM_NB_BLOCK *NBPtr,
497   IN       CPU_LOGICAL_ID *LogicalIdPtr
498   )
499 {
500
501   if (((LogicalIdPtr->Family & AMD_FAMILY_10_PH) != 0)
502       && ((LogicalIdPtr->Revision & AMD_F10_PH_ALL) != 0)) {
503     return TRUE;
504   } else {
505     return FALSE;
506   }
507 }
508
509 /* -----------------------------------------------------------------------------*/
510 /**
511  *
512  *
513  *   This function initializes the northbridge block for S3 resume
514  *
515  *     @param[in,out]   *S3NBPtr   - Pointer to MEM_NB_BLOCK.
516  *     @param[in,out]   *MemPtr  - Pointer to MEM_DATA_STRUCT.
517  *     @param[in]       NodeID   - Node ID of the target node.
518  *
519  *      @return         BOOLEAN
520  *                         TRUE - This is the correct constructor for the targeted node.
521  *                         FALSE - This isn't the correct constructor for the targeted node.
522  */
523 BOOLEAN
524 MemS3ResumeConstructNBBlockPh (
525   IN OUT   VOID *S3NBPtr,
526   IN OUT   MEM_DATA_STRUCT *MemPtr,
527   IN       UINT8 NodeID
528   )
529 {
530   INT32 i;
531   MEM_NB_BLOCK *NBPtr;
532
533   NBPtr = ((S3_MEM_NB_BLOCK *)S3NBPtr)->NBPtr;
534
535   //
536   // Determine if this is the expected NB Type
537   //
538   GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
539   if (!MemNIsIdSupportedPh (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
540     return FALSE;
541   }
542
543   NBPtr->MemPtr = MemPtr;
544   NBPtr->MCTPtr = &(MemPtr->DiesPerSystem[NodeID]);
545   NBPtr->PciAddr.AddressValue = MemPtr->DiesPerSystem[NodeID].PciAddr.AddressValue;
546   InitNBRegTableDA (NBPtr, NBPtr->NBRegTable);
547   NBPtr->Node = ((UINT8) NBPtr->PciAddr.Address.Device) - 24;
548   NBPtr->Dct = 0;
549   NBPtr->Channel = 0;
550   NBPtr->Ganged = FALSE;
551   NBPtr->NodeCount = MAX_NODES_SUPPORTED_DA;
552   NBPtr->DctCount = MAX_DCTS_PER_NODE_DA;
553
554   for (i = 0; i < EnumSize; i++) {
555     NBPtr->IsSupported[i] = FALSE;
556   }
557
558   for (i = 0; i < NumberOfHooks; i++) {
559     NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) memDefTrue;
560   }
561
562   LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &MemPtr->StdHeader);
563
564   NBPtr->IsSupported[CheckDllSpeedUp] = TRUE;
565   NBPtr->SwitchDCT = MemNSwitchDCTNb;
566   NBPtr->SwitchChannel = MemNSwitchChannelNb;
567   NBPtr->GetBitField = MemNGetBitFieldNb;
568   NBPtr->SetBitField = MemNSetBitFieldNb;
569   NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldDA;
570   NBPtr->MemNIsIdSupportedNb = MemNIsIdSupportedPh;
571   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3ExitSelfRefReg = MemNS3ExitSelfRefRegPh;
572   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConPCIMask = MemNS3GetConPCIMaskNb;
573   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConMSRMask = (VOID (*) (MEM_NB_BLOCK*, DESCRIPTOR_GROUP*)) memDefRet;
574   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3Resume = MemNS3ResumeNb;
575   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3RestoreScrub = MemNS3RestoreScrubNb;
576   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetRegLstPtr = MemNS3GetRegLstPtrPh;
577   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetDeviceRegLst = MemNS3GetDeviceRegLstPh;
578   ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3SpecialCaseHeapSize = (sizeof (SpecialCasePCIRegPh) / sizeof (UINT16)) * sizeof (UINT32);
579
580   MemNSwitchDCTNb (NBPtr, 0);
581
582   return TRUE;
583 }
584
585 /*----------------------------------------------------------------------------
586  *                              LOCAL FUNCTIONS
587  *
588  *----------------------------------------------------------------------------*/
589
590 /* -----------------------------------------------------------------------------*/
591 /**
592  *
593  *
594  *   This function returns the register list for each device for Ph
595  *
596  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
597  *     @param[in, out]  *DescriptPtr - Pointer to DESCRIPTOR_GROUP
598  *     @return          UINT16 - size of the device descriptor on the target node.
599  */
600 UINT16
601 STATIC
602 MemNS3GetRegLstPtrPh (
603   IN OUT   MEM_NB_BLOCK *NBPtr,
604   IN OUT   DESCRIPTOR_GROUP *DescriptPtr
605   )
606 {
607   UINT8 i;
608   UINT16 Size;
609   Size = 0;
610   for (i = PRESELFREF; i <= POSTSELFREF; i ++) {
611     DescriptPtr->PCIDevice[i].Type = (UINT8) (DEV_TYPE_PCI_PRE_ESR + i);
612     DescriptPtr->PCIDevice[i].Node = NBPtr->Node;
613     DescriptPtr->PCIDevice[i].RegisterListID = 0xFFFFFFFF;
614     if ((PCI_REGISTER_BLOCK_HEADER *) MemS3RegListPh[PCI_LST_ESR_DA - PCI_LST_ESR_DA + i] != NULL) {
615       DescriptPtr->PCIDevice[i].RegisterListID = PCI_LST_ESR_DA + i;
616       Size += sizeof (PCI_DEVICE_DESCRIPTOR);
617     }
618     DescriptPtr->CPCIDevice[i].Type = (UINT8) (DEV_TYPE_CPCI_PRE_ESR + i);
619     DescriptPtr->CPCIDevice[i].Node = NBPtr->Node;
620     DescriptPtr->CPCIDevice[i].RegisterListID = 0xFFFFFFFF;
621     if ((CPCI_REGISTER_BLOCK_HEADER *) MemS3RegListPh[CPCI_LST_ESR_DA - PCI_LST_ESR_DA + i] != NULL) {
622       DescriptPtr->CPCIDevice[i].RegisterListID = CPCI_LST_ESR_DA + i;
623       Size += sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR);
624     }
625     DescriptPtr->MSRDevice[i].Type = (UINT8) (DEV_TYPE_MSR_PRE_ESR + i);
626     DescriptPtr->MSRDevice[i].RegisterListID = 0xFFFFFFFF;
627     if ((MSR_REGISTER_BLOCK_HEADER *) MemS3RegListPh[MSR_LST_ESR_DA - PCI_LST_ESR_DA + i] != NULL) {
628       DescriptPtr->MSRDevice[i].RegisterListID = MSR_LST_ESR_DA + i;
629       Size += sizeof (MSR_DEVICE_DESCRIPTOR);
630     }
631     DescriptPtr->CMSRDevice[i].Type = (UINT8) (DEV_TYPE_CMSR_PRE_ESR + i);
632     DescriptPtr->CMSRDevice[i].RegisterListID = 0xFFFFFFFF;
633     if ((CMSR_REGISTER_BLOCK_HEADER *) MemS3RegListPh[CMSR_LST_ESR_DA - PCI_LST_ESR_DA + i] != NULL) {
634       DescriptPtr->CMSRDevice[i].RegisterListID = CMSR_LST_ESR_DA + i;
635       Size += sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR);
636     }
637   }
638   return Size;
639 }
640
641 /* -----------------------------------------------------------------------------*/
642 /**
643  *
644  *
645  *   This function return the register list according to the register ID.
646  *
647  *     @param[in]   RegisterLstID - value of the Register list ID.
648  *     @param[out]  **RegisterHeader - pointer to the address of the register list.
649  *     @return      none
650  */
651 AGESA_STATUS
652 STATIC
653 MemNS3GetDeviceRegLstPh (
654   IN       UINT32 RegisterLstID,
655      OUT   VOID **RegisterHeader
656   )
657 {
658   if (RegisterLstID >= (sizeof (MemS3RegListPh) / sizeof (VOID *))) {
659     ASSERT(FALSE); // RegisterListID exceeded size of Register list
660     return AGESA_FATAL;
661   }
662   if (MemS3RegListPh[RegisterLstID] != NULL) {
663     *RegisterHeader = MemS3RegListPh[RegisterLstID];
664     return AGESA_SUCCESS;
665   }
666   ASSERT(FALSE); // Device register list error
667   return AGESA_FATAL;
668 }
669 /* -----------------------------------------------------------------------------*/
670 /**
671  *
672  *
673  *   This function stores special case register on the heap.
674  *
675  *     @param[in]   AccessWidth - Access width of the register
676  *     @param[in]   Address - address of the CSR register in PCI_ADDR format.
677  *     @param[in]   *Value - Pointer to the value be read.
678  *     @param[in, out]  *ConfigPtr - Pointer to Config handle.
679  *      @return         none
680  */
681 VOID
682 STATIC
683 MemNS3SetSpecialPCIRegPh (
684   IN       ACCESS_WIDTH AccessWidth,
685   IN       PCI_ADDR Address,
686   IN       VOID *Value,
687   IN OUT   VOID *ConfigPtr
688   )
689 {
690   LOCATE_HEAP_PTR LocateBufferPtr;
691   UINT8 i;
692   UINT8 NodeID;
693   UINT8 Offset;
694   S3_SPECIAL_CASE_HEAP_HEADER *SpecialHeapHeader;
695
696   Offset = 0;
697   LocateBufferPtr.BufferHandle = AMD_MEM_S3_DATA_HANDLE;
698   if (HeapLocateBuffer (&LocateBufferPtr, ConfigPtr) == AGESA_SUCCESS) {
699     SpecialHeapHeader = (S3_SPECIAL_CASE_HEAP_HEADER *) LocateBufferPtr.BufferPtr;
700     // Get the node ID of the target die.
701     NodeID = (UINT8) (Address.Address.Device - 24);
702     for (i = 0; i < MAX_NODES_SUPPORTED_DA; i ++) {
703       if (SpecialHeapHeader[i].Node == NodeID) {
704         // Get the offset in the heap for the target die.
705         Offset = SpecialHeapHeader[i].Offset;
706         break;
707       }
708     }
709     ASSERT (i < MAX_NODES_SUPPORTED_DA);
710     // Save the value in the heap at appropriate offset based on the index
711     // of the target register in the special case array.
712     if (Offset != 0) {
713       for (i = 0; i < (sizeof (SpecialCasePCIRegPh) / sizeof (UINT16)); i ++) {
714         if (SpecialCasePCIRegPh[i] == Address.Address.Register) {
715           *(UINT32 *) (LocateBufferPtr.BufferPtr + Offset + (i << 2)) = *(UINT32 *) Value;
716         }
717       }
718     }
719   }
720 }
721
722
723 /* -----------------------------------------------------------------------------*/
724 /**
725  *
726  *
727  *   This function stores special case register on the heap.
728  *
729  *     @param[in,out]  *NBPtr - Pointer to the northbridge block.
730  *     @param[in,out]  *StdHeader - Config handle for library and services.
731  *     @return         none
732  */
733 VOID
734 STATIC
735 MemNS3ExitSelfRefRegPh (
736   IN OUT   MEM_NB_BLOCK *NBPtr,
737   IN OUT   AMD_CONFIG_PARAMS *StdHeader
738   )
739 {
740   LOCATE_HEAP_PTR LocateBufferPtr;
741   UINT8 i;
742   PCI_ADDR PciAddr;
743   UINT32 Value;
744   UINT8 NodeID;
745   UINT8 Offset;
746   S3_SPECIAL_CASE_HEAP_HEADER *SpecialHeapHeader;
747
748   Offset = 0;
749   PciAddr.Address.Device = NBPtr->PciAddr.Address.Device;
750   PciAddr.Address.Bus = NBPtr->PciAddr.Address.Bus;
751   PciAddr.Address.Segment = NBPtr->PciAddr.Address.Segment;
752   PciAddr.Address.Function = 2;
753   LocateBufferPtr.BufferHandle = AMD_MEM_S3_DATA_HANDLE;
754   if (HeapLocateBuffer (&LocateBufferPtr, StdHeader) == AGESA_SUCCESS) {
755     SpecialHeapHeader = (S3_SPECIAL_CASE_HEAP_HEADER *) LocateBufferPtr.BufferPtr;
756     // Get the node ID of the target die.
757     NodeID = (UINT8) (PciAddr.Address.Device - 24);
758     for (i = 0; i < MAX_NODES_SUPPORTED_DA; i ++) {
759       if (SpecialHeapHeader[i].Node == NodeID) {
760         // Get the offset in the heap for the target die.
761         Offset = SpecialHeapHeader[i].Offset;
762         break;
763       }
764     }
765     ASSERT (i < MAX_NODES_SUPPORTED_DA);
766     // Restore the value one by one in the sequence of the special case register array.
767     if (Offset != 0) {
768       for (i = 0; i < (sizeof (SpecialCasePCIRegPh) / sizeof (UINT16)); i ++) {
769         PciAddr.Address.Register = SpecialCasePCIRegPh[i];
770         Value = *(UINT32 *) (LocateBufferPtr.BufferPtr + Offset + (i << 2));
771         MemNS3SetCSRNb (AccessS3SaveWidth32, PciAddr, &Value, StdHeader);
772       }
773     }
774   }
775 }