blob: 356730fedf85e73ee13fa0a11c084e6175d9b52d [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * Config Hudson2 AB
6 *
7 * Init AB bridge.
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: FCH
12 * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
13 *
14 */
15/*
16*****************************************************************************
17*
Siyuan Wang641f00c2013-06-08 11:50:55 +080018 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zbao7d94cf92012-07-02 14:19:14 +080042****************************************************************************
43*/
44#include "FchPlatform.h"
45#include "Filecode.h"
46#define FILECODE PROC_FCH_PCIE_FAMILY_HUDSON2_HUDSON2ABENVSERVICE_FILECODE
47
48//
49// Declaration of local functions
50//
51VOID AbCfgTbl (IN AB_TBL_ENTRY *ABTbl, IN AMD_CONFIG_PARAMS *StdHeader);
52
53/**
54 * Hudson2PcieOrderRule - AB-Link Configuration Table for ablink
55 * Post Pass Np Downstream/Upstream Feature
56 *
57 */
58AB_TBL_ENTRY Hudson2PcieOrderRule[] =
59{
60 //
61 // abPostPassNpDownStreamTbl
62 //
63 {ABCFG, FCH_ABCFG_REG10060, BIT31, BIT31},
64 {ABCFG, FCH_ABCFG_REG1009C, BIT4 + BIT5, BIT4 + BIT5},
65 {ABCFG, FCH_ABCFG_REG9C, BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7, BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7},
66 {ABCFG, FCH_ABCFG_REG90, BIT21 + BIT22 + BIT23, BIT21 + BIT22 + BIT23},
67 {ABCFG, FCH_ABCFG_REGF0, BIT6 + BIT5, BIT6 + BIT5},
68 {AXINDC, FCH_AX_INDXC_REG02, BIT9, BIT9},
69 {ABCFG, FCH_ABCFG_REG10090, BIT9 + BIT10 + BIT11 + BIT12, BIT9 + BIT10 + BIT11 + BIT12},
70
71 //
72 // abPostPassNpUpStreamTbl
73 //
74 {ABCFG, FCH_ABCFG_REG58, BIT10, BIT10},
75 {ABCFG, FCH_ABCFG_REGF0, BIT3 + BIT4, BIT3 + BIT4},
76 {ABCFG, FCH_ABCFG_REG54, BIT1, BIT1},
77 { (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF},
78};
79
80/**
81 * Hudson2InitEnvAbTable - AB-Link Configuration Table for Hudson2
82 *
83 */
84AB_TBL_ENTRY Hudson2InitEnvAbTable[] =
85{
86 //
87 // Enable downstream posted transactions to pass non-posted transactions.
88 //
89 {ABCFG, FCH_ABCFG_REG10090, BIT8 + BIT16, BIT8 + BIT16},
90
91 //
92 // Enable Hudson-2 to issue memory read/write requests in the upstream direction.
93 //
94 {AXCFG, FCH_AB_REG04, BIT2, BIT2},
95
96 //
97 // Enabling IDE/PCIB Prefetch for Performance Enhancement
98 // PCIB prefetch ABCFG 0x10060 [20] = 1 ABCFG 0x10064 [20] = 1
99 //
100 {ABCFG, FCH_ABCFG_REG10060, BIT20, BIT20}, /// PCIB prefetch enable
101 {ABCFG, FCH_ABCFG_REG10064, BIT20, BIT20}, /// PCIB prefetch enable
102
103 //
104 // Controls the USB OHCI controller prefetch used for enhancing performance of ISO out devices.
105 // Setting B-Link Prefetch Mode (ABCFG 0x80 [18:17] = 11)
106 //
107 {ABCFG, FCH_ABCFG_REG80, BIT0 + BIT17 + BIT18, BIT0 + BIT17 + BIT18},
108
109 //
110 // Enabled SMI ordering enhancement. ABCFG 0x90[21]
111 // USB Delay A-Link Express L1 State. ABCFG 0x90[17]
112 //
113 {ABCFG, FCH_ABCFG_REG90, BIT21 + BIT17, BIT21 + BIT17},
114
115 //
116 // Disable the credit variable in the downstream arbitration equation
117 // Register bit to qualify additional address bits into downstream register programming. (A12 BIT1 default is set)
118 //
119 {ABCFG, FCH_ABCFG_REG9C, BIT0, BIT0},
120
121 //
122 // Enabling Detection of Upstream Interrupts ABCFG 0x94 [20] = 1
123 // ABCFG 0x94 [19:0] = cpu interrupt delivery address [39:20]
124 //
125 {ABCFG, FCH_ABCFG_REG94, BIT20, BIT20 + 0x00FEE},
126
127 //
128 // Programming cycle delay for AB and BIF clock gating
129 // Enable the AB and BIF clock-gating logic.
130 // Enable the A-Link int_arbiter enhancement to allow the A-Link bandwidth to be used more efficiently
131 // Enable the requester ID for upstream traffic. [16]: SB/NB link [17]: GPP
132 //
133 {ABCFG, FCH_ABCFG_REG10054, 0x00FFFFFF, 0x010407FF},
134 {ABCFG, FCH_ABCFG_REG98, 0xFFFC00FF, 0x00034700},
135 {ABCFG, FCH_ABCFG_REG54, 0x00FF0000, 0x00040000},
136
137 //
138 // Non-Posted Memory Write Support
139 //
140 {AXINDC, FCH_AX_INDXC_REG10, BIT9, BIT9},
141
142 //
143 // UMI L1 Configuration
144 //Step 1: AXINDC_Reg 0x02[0] = 0x1 Set REGS_DLP_IGNORE_IN_L1_EN to ignore DLLPs during L1 so that txclk can be turned off.
145 //Step 2: AXINDP_Reg 0x02[15] = 0x1 Sets REGS_LC_ALLOW_TX_L1_CONTROL to allow TX to prevent LC from going to L1 when there are outstanding completions.
146 //
147 {AXINDC, FCH_AX_INDXC_REG02, BIT0, BIT0},
148 {AXINDP, FCH_AX_INDXP_REG02, BIT15, BIT15},
149 {ABCFG, 0, 0, (UINT8) 0xFF}, /// This dummy entry is to clear ab index
150 { (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF},
151};
152
153/**
154 * FchInitEnvAbLinkInit - Set ABCFG registers before PCI
155 * emulation.
156 *
157 *
158 * @param[in] FchDataPtr Fch configuration structure pointer.
159 *
160 */
161VOID
162FchInitEnvAbLinkInit (
163 IN VOID *FchDataPtr
164 )
165{
166 UINT32 AbValue;
167 UINT16 AbTempVar;
168 UINT8 AbValue8;
169 UINT8 FchALinkClkGateOff;
170 UINT8 FchBLinkClkGateOff;
171 UINT32 FchResetCpuOnSyncFlood;
172 AB_TBL_ENTRY *AbTblPtr;
173 FCH_DATA_BLOCK *LocalCfgPtr;
174 AMD_CONFIG_PARAMS *StdHeader;
175
176 LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
177 StdHeader = LocalCfgPtr->StdHeader;
178
179 FchALinkClkGateOff = (UINT8) LocalCfgPtr->Ab.ALinkClkGateOff;
180 FchBLinkClkGateOff = (UINT8) LocalCfgPtr->Ab.BLinkClkGateOff;
181 //
182 // AB CFG programming
183 //
184 if ( LocalCfgPtr->Ab.SlowSpeedAbLinkClock ) {
185 RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, (UINT32)~BIT1, BIT1);
186 } else {
187 RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, (UINT32)~BIT1, 0);
188 }
189
190 //
191 // Read Arbiter address, Arbiter address is in PMIO 6Ch
192 //
193 ReadMem (ACPI_MMIO_BASE + PMIO_BASE + 0x6C , AccessWidth16, &AbTempVar);
194 /// Write 0 to enable the arbiter
195 AbValue8 = 0;
196 LibAmdIoWrite (AccessWidth8, AbTempVar, &AbValue8, StdHeader);
197
198
199 FchResetCpuOnSyncFlood = LocalCfgPtr->Ab.ResetCpuOnSyncFlood;
200
201 if ( LocalCfgPtr->Ab.PcieOrderRule == 1 ) {
202 AbTblPtr = (AB_TBL_ENTRY *) (&Hudson2PcieOrderRule[0]);
203 AbCfgTbl (AbTblPtr, StdHeader);
204 }
205
206 if ( LocalCfgPtr->Ab.PcieOrderRule == 2 ) {
207 RwAlink (FCH_ABCFG_REG10090 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x7 << 10), (UINT32) (0x7 << 10), StdHeader);
208 RwAlink (FCH_ABCFG_REG58 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1F << 11), (UINT32) (0x1C << 11), StdHeader);
209 RwAlink (FCH_ABCFG_REGB4 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 0), (UINT32) (0x3 << 0), StdHeader);
210 }
211
212 AbTblPtr = (AB_TBL_ENTRY *) (&Hudson2InitEnvAbTable[0]);
213 AbCfgTbl (AbTblPtr, StdHeader);
214
215 if ( FchResetCpuOnSyncFlood ) {
216 RwAlink (FCH_ABCFG_REG10050 | (UINT32) (ABCFG << 29), (UINT32)~BIT2, BIT2, StdHeader);
217 }
218
219 if ( LocalCfgPtr->Ab.AbClockGating ) {
220 RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16), StdHeader);
221 RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16), StdHeader);
222 RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x1 << 24), StdHeader);
223 RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x1 << 24), StdHeader);
224 } else {
225 RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x0 << 24), StdHeader);
226 RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x0 << 24), StdHeader);
227 }
228
229
230 if ( LocalCfgPtr->Ab.GppClockGating ) {
231 RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 12), (UINT32) (0x4 << 12), StdHeader);
232 RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 8), (UINT32) (0x7 << 8), StdHeader);
233 RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x1 << 0), StdHeader);
234 } else {
235 RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 8), (UINT32) (0x0 << 8), StdHeader);
236 RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x0 << 0), StdHeader);
237 }
238
239 if ( LocalCfgPtr->Ab.UmiL1TimerOverride ) {
240 RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x7 << 12), (UINT32) (LocalCfgPtr->Ab.UmiL1TimerOverride << 12), StdHeader);
241 RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 15), (UINT32) (0x1 << 15), StdHeader);
242 }
243
244 if ( LocalCfgPtr->Ab.UmiLinkWidth ) {
245// RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
246 }
247
248 if ( LocalCfgPtr->Ab.UmiDynamicSpeedChange ) {
249 RwAlink ((UINT32) FCH_AX_INDXP_REGA4, ~ (UINT32) (0x1 << 0), (UINT32) (0x1 << 0), StdHeader);
250 RwAlink ((UINT32) FCH_AX_CFG_REG88, ~ (UINT32) (0xF << 0), (UINT32) (0x2 << 0), StdHeader);
251 RwAlink ((UINT32) FCH_AX_INDXP_REGA4, ~ (UINT32) (0x1 << 18), (UINT32) (0x1 << 18), StdHeader);
252 }
253
254 if ( LocalCfgPtr->Ab.PcieRefClockOverClocking ) {
255// RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
256 }
257
258 if ( LocalCfgPtr->Ab.UmiGppTxDriverStrength ) {
259 RwAlink (FCH_ABCFG_REGA8 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 18), (UINT32) ((LocalCfgPtr->Ab.UmiGppTxDriverStrength - 1) << 18), StdHeader);
260 RwAlink (FCH_ABCFG_REGA0 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 8), (UINT32) (0x1 << 8), StdHeader);
261 }
262
263 if ( LocalCfgPtr->Gpp.PcieAer ) {
264// RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
265 }
266
267 if ( LocalCfgPtr->Gpp.PcieRas ) {
268// RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
269 }
270
271 //
272 // Ab Bridge MSI
273 //
274 if ( LocalCfgPtr->Ab.AbMsiEnable) {
275 AbValue = ReadAlink (FCH_ABCFG_REG94 | (UINT32) (ABCFG << 29), StdHeader);
276 AbValue = AbValue | BIT20;
277 WriteAlink (FCH_ABCFG_REG94 | (UINT32) (ABCFG << 29), AbValue, StdHeader);
278 }
279
280 //
281 // A/B Clock Gate-OFF
282 //
283 if ( FchALinkClkGateOff ) {
284 RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFE, BIT0);
285 } else {
286 RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFE, 0x00);
287 }
288
289 if ( FchBLinkClkGateOff ) {
290 //RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2D, AccessWidth8, 0xEF, 0x10); /// A11 Only
291 RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFD, BIT1);
292 } else {
293 RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFD, 0x00);
294 }
295}
296
297/**
298 * AbCfgTbl - Program ABCFG by input table.
299 *
300 *
301 * @param[in] ABTbl ABCFG config table.
302 * @param[in] StdHeader
303 *
304 */
305VOID
306AbCfgTbl (
307 IN AB_TBL_ENTRY *ABTbl,
308 IN AMD_CONFIG_PARAMS *StdHeader
309 )
310{
311 UINT32 AbValue;
312
313 while ( (ABTbl->RegType) != 0xFF ) {
314 if ( ABTbl->RegType == AXINDC ) {
315 AbValue = 0x30 | (ABTbl->RegType << 29);
316 WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader);
317 AbValue = 0x34 | (ABTbl->RegType << 29);
318 WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
319 } else if ( ABTbl->RegType == AXINDP ) {
320 AbValue = 0x38 | (ABTbl->RegType << 29);
321 WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader);
322 AbValue = 0x3C | (ABTbl->RegType << 29);
323 WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
324 } else {
325 AbValue = ABTbl->RegIndex | (ABTbl->RegType << 29);
326 WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
327 }
328
329 ++ABTbl;
330 }
331
332 //
333 //Clear ALink Access Index
334 //
335 AbValue = 0;
336 LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &AbValue, StdHeader);
337}
338
339/**
340 * Is UMI One Lane GEN1 Mode?
341 *
342 *
343 * @retval TRUE or FALSE
344 *
345 */
346BOOLEAN
347IsUmiOneLaneGen1Mode (
348 IN AMD_CONFIG_PARAMS *StdHeader
349 )
350{
351 UINT32 AbValue;
352
353 AbValue = ReadAlink ((UINT32) (FCH_AX_CFG_REG68), StdHeader);
354 AbValue >>= 16;
355 if (((AbValue & 0x0f) == 1) && ((AbValue & 0x03f0) == 0x0010)) {
356 return (TRUE);
357 } else {
358 return (FALSE);
359 }
360}