5 * System Tuning Family 10h specific routines
7 * Support for Traffic Distribution and buffer tunings which
8 * can not be done in a register table.
10 * @xrefitem bom "File Content Label" "Release Content"
12 * @e sub-project: HyperTransport
13 * @e \$Revision: 56279 $ @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
17 *****************************************************************************
19 * Copyright (C) 2012 Advanced Micro Devices, Inc.
20 * All rights reserved.
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 * * Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * * Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
30 * its contributors may be used to endorse or promote products derived
31 * from this software without specific prior written permission.
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
37 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 * ***************************************************************************
49 *----------------------------------------------------------------------------
52 *----------------------------------------------------------------------------
62 #include "htInterface.h"
64 #include "htNbCommonHardware.h"
65 #include "htNbSystemFam10.h"
70 #define FILECODE PROC_HT_FAM10_HTNBSYSTEMFAM10_FILECODE
71 /*----------------------------------------------------------------------------
72 * DEFINITIONS AND MACROS
74 *----------------------------------------------------------------------------
77 /*----------------------------------------------------------------------------
78 * TYPEDEFS AND STRUCTURES
80 *----------------------------------------------------------------------------
83 * Register Fields for an individual link pair.
86 UINT32 Enable:1; ///< Enable distribution on this pair.
87 UINT32 Asymmetric:1; ///< Links are different widths.
88 UINT32 MasterSelect:3; ///< The master link.
89 UINT32 AlternateSelect:3; ///< The alternate link.
93 * Register access union for ::PAIR_SELECT_FIELDS.
96 UINT32 Value; ///< access as a 32 bit value or register.
97 PAIR_SELECT_FIELDS Fields; ///< access individual fields.
100 /*----------------------------------------------------------------------------
101 * PROTOTYPES OF LOCAL FUNCTIONS
103 *----------------------------------------------------------------------------
106 /***************************************************************************
107 *** FAMILY/NORTHBRIDGE SPECIFIC FUNCTIONS ***
108 ***************************************************************************/
110 /*----------------------------------------------------------------------------------------*/
112 * Set the traffic distribution register for the Links provided.
114 * @HtNbMethod{::F_WRITE_TRAFFIC_DISTRIBUTION}
116 * @param[in] Links01 coherent Links from Node 0 to 1
117 * @param[in] Links10 coherent Links from Node 1 to 0
118 * @param[in] Nb this northbridge
121 Fam10WriteTrafficDistribution (
128 PCI_ADDR TrafficDistReg;
130 TrafficDistReg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (0),
131 MakePciBusFromNode (0),
132 MakePciDeviceFromNode (0),
134 REG_HT_TRAFFIC_DIST_0X164);
138 LibAmdPciWriteBits (TrafficDistReg, 23, 16, &Links01, Nb->ConfigHandle);
139 // DstNode = 1, cHTPrbDistEn = 1, cHTRspDistEn = 1, cHTReqDistEn = 1
141 LibAmdPciWriteBits (TrafficDistReg, 15, 0, &Temp, Nb->ConfigHandle);
143 TrafficDistReg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (1),
144 MakePciBusFromNode (1),
145 MakePciDeviceFromNode (1),
147 REG_HT_TRAFFIC_DIST_0X164);
151 LibAmdPciWriteBits (TrafficDistReg, 23, 16, &Links10, Nb->ConfigHandle);
152 // DstNode = 0, cHTPrbDistEn = 1, cHTRspDistEn = 1, cHTReqDistEn = 1
154 LibAmdPciWriteBits (TrafficDistReg, 15, 0, &Temp, Nb->ConfigHandle);
157 /*----------------------------------------------------------------------------------------*/
159 * Write a link pair to the link pair distribution and fixups.
161 * @HtNbMethod{::F_WRITE_LINK_PAIR_DISTRIBUTION}
163 * Set the links as a pair using the link pair index provided. Set asymmetric attribute as
164 * provided. If the Master Link is not currently used as the route, fixup the routes for all
165 * nodes which specify the alternate link.
167 * @param[in] Node Set the pair on this node
168 * @param[in] ConnectedNode The Node to which this link pair directly connects.
169 * @param[in] Pair Using this pair set in the register
170 * @param[in] Asymmetric True if different widths
171 * @param[in] MasterLink Set this as the master link and in the route
172 * @param[in] AlternateLink Set this as the alternate link
173 * @param[in] Nb this northbridge
177 Fam10WriteLinkPairDistribution (
179 IN UINT8 ConnectedNode,
181 IN BOOLEAN Asymmetric,
183 IN UINT8 AlternateLink,
190 UINT32 AlternateRoute;
191 PAIR_SELECT Selection;
194 ASSERT ((Node < MAX_NODES) && (ConnectedNode < MAX_NODES));
195 ASSERT (Pair < MAX_LINK_PAIRS);
196 ASSERT (MasterLink < Nb->MaxLinks);
197 ASSERT (AlternateLink < Nb->MaxLinks);
199 // Make the master link the route for all routes to or through NodeB, by replacing all occurrences of
200 // Alternate link with Master link. If routing used the master link, no update is necessary.
201 MasterRoute = (((1 << Nb->BroadcastSelfBit) | Nb->SelfRouteResponseMask | Nb->SelfRouteRequestMask) << (MasterLink + 1));
202 AlternateRoute = (((1 << Nb->BroadcastSelfBit) | Nb->SelfRouteResponseMask | Nb->SelfRouteRequestMask) << (AlternateLink + 1));
203 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
204 MakePciBusFromNode (Node),
205 MakePciDeviceFromNode (Node),
208 for (RouteIndex = 0; RouteIndex < MAX_NODES; RouteIndex++) {
209 Reg.Address.Register = REG_ROUTE0_0X40 + (RouteIndex * 4);
210 LibAmdPciReadBits (Reg, 31, 0, &CurrentRoute, Nb->ConfigHandle);
211 if ((CurrentRoute & AlternateRoute) != 0) {
212 // Since Master and Alternate are redundant, the route must use one or the other but not both.
213 ASSERT ((CurrentRoute & MasterRoute) == 0);
214 // Set the master route for Request, Response or Broadcast only if the alternate was used for that case.
215 // Example, use of a link as a broadcast link is typically not the same route register as its use for Request, Response.
216 CurrentRoute = ((CurrentRoute & ~AlternateRoute) |
217 ((((CurrentRoute & AlternateRoute) >> (AlternateLink + 1)) << (MasterLink + 1)) & MasterRoute));
218 LibAmdPciWriteBits (Reg, 31, 0, &CurrentRoute, Nb->ConfigHandle);
222 // Set the Link Pair and Enable it
223 Selection.Fields.Enable = 1;
224 Selection.Fields.Asymmetric = Asymmetric;
225 Selection.Fields.MasterSelect = MasterLink;
226 Selection.Fields.AlternateSelect = AlternateLink;
227 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
228 MakePciBusFromNode (Node),
229 MakePciDeviceFromNode (Node),
231 REG_HT_LINK_PAIR_DIST_0X1E0);
234 ((PAIR_SELECT_OFFSET * (Pair + 1)) - 1),
235 (PAIR_SELECT_OFFSET * Pair),
241 /*----------------------------------------------------------------------------------------*/
243 * Family 10h specific tunings.
245 * @HtNbMethod{::F_BUFFER_OPTIMIZATIONS}
247 * Buffer tunings are inherently northbridge specific. Check for specific configs
248 * which require adjustments and apply any standard workarounds to this Node.
250 * @param[in] Node the Node to tune
251 * @param[in] State global state
252 * @param[in] Nb this northbridge
255 Fam10BufferOptimizations (
257 IN STATE_DATA *State,
266 ASSERT (Node < MAX_NODES);
269 // Link to XCS Token Count Tuning
271 // For each active Link that we reganged (so this unfortunately can't go into the PCI reg
272 // table), we have to switch the Link to XCS Token Counts to the ganged state.
273 // We do this here for the non - uma case, which is to write the values that would have
274 // been power on defaults if the Link was ganged at cold reset.
276 for (i = 0; i < (State->TotalLinks * 2); i++) {
277 if (((*State->PortList)[i].NodeID == Node) && ((*State->PortList)[i].Type == PORTLIST_TYPE_CPU)) {
278 // If the Link is greater than 4, this is a subLink 1, so it is not reganged.
279 if ((*State->PortList)[i].Link < 4) {
280 currentPtr.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
281 MakePciBusFromNode (Node),
282 MakePciDeviceFromNode (Node),
284 REG_NB_LINK_XCS_TOKEN0_3X148 + (4 * (*State->PortList)[i].Link)
286 if ((*State->PortList)[i].SelRegang) {
287 // Handle all the regang Token count adjustments
289 // SubLink 0: [Probe0tok] = 2 [Rsp0tok] = 2 [PReq0tok] = 2 [Req0tok] = 2
291 LibAmdPciWriteBits (currentPtr, 7, 0, &Temp, Nb->ConfigHandle);
292 // SubLink 1: [Probe1tok] = 0 [Rsp1tok] = 0 [PReq1tok] = 0 [Req1tok] = 0
294 LibAmdPciWriteBits (currentPtr, 23, 16, &Temp, Nb->ConfigHandle);
297 LibAmdPciWriteBits (currentPtr, 15, 14, &Temp, Nb->ConfigHandle);
300 // Read the regang bit in hardware
301 GangedReg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode ((*State->PortList)[i].NodeID),
302 MakePciBusFromNode ((*State->PortList)[i].NodeID),
303 MakePciDeviceFromNode ((*State->PortList)[i].NodeID),
305 REG_HT_LINK_EXT_CONTROL0_0X170 + (4 * (*State->PortList)[i].Link));
306 LibAmdPciReadBits (GangedReg, 0, 0, &Temp, Nb->ConfigHandle);
308 // handle a minor adjustment for strapped ganged Links. If SelRegang is false we
309 // didn't do the regang, so if the bit is on then it's hardware strapped.
314 LibAmdPciWriteBits (currentPtr, 15, 14, &Temp, Nb->ConfigHandle);
322 /*----------------------------------------------------------------------------------------*/
324 * Family 10h specific tunings.
326 * @HtNbMethod{::F_BUFFER_OPTIMIZATIONS}
328 * Buffer tunings are inherently northbridge specific. Check for specific configs
329 * which require adjustments and apply any standard workarounds to this Node.
331 * @param[in] Node the Node to tune
332 * @param[in] State global state
333 * @param[in] Nb this northbridge
336 Fam10RevDBufferOptimizations (
338 IN STATE_DATA *State,
345 FINAL_LINK_STATE FinalLinkState;
349 ASSERT (Node < MAX_NODES);
352 // Internal link fixup.
353 // When powering off internal link 2, a performance optimization may be possible where its buffers
354 // can be made available to the external paired sublink. If the conditions are met, do the fix up here.
356 for (i = 0; i < (State->TotalLinks * 2); i++) {
357 if (((*State->PortList)[i].NodeID == Node) && ((*State->PortList)[i].Type == PORTLIST_TYPE_CPU)) {
358 // Is this a sublink 0 paired with internal link 2?
359 if (((*State->PortList)[i].Link < 4) &&
360 (Nb->GetPackageLink (Node, ((*State->PortList)[i].Link + 4), Nb) == HT_LIST_MATCH_INTERNAL_LINK_2)) {
361 FinalLinkState = State->HtInterface->GetIgnoreLink (Node, ((*State->PortList)[i].Link + 4), Nb->DefaultIgnoreLinkList, State);
362 // Are we ignoring the internal link 2 with Power Off?
363 if (FinalLinkState == POWERED_OFF) {
364 // Read the regang bit in hardware.
365 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
366 MakePciBusFromNode (Node),
367 MakePciDeviceFromNode (Node),
369 REG_HT_LINK_EXT_CONTROL0_0X170 + (4 * (*State->PortList)[i].Link));
370 LibAmdPciReadBits (Reg, 0, 0, &Temp, Nb->ConfigHandle);
371 // If it's already ganged, skip to the width fix up.
373 // Clear EndOfChain / XmitOff on internal sublink
374 Reg = Nb->MakeLinkBase (Node, ((*State->PortList)[i].Link + 4), Nb);
375 Reg.Address.Register += HTHOST_LINK_CONTROL_REG;
377 State->HtFeatures->SetHtControlRegisterBits (Reg, 7, 6, &Temp, State);
380 Nb->SetLinkRegang (Node, (*State->PortList)[i].Link, Nb);
383 // Set InLnSt = PHY_OFF in register table.
384 // Set sublink 0 widths to 8 bits
385 if ((*State->PortList)[i].SelWidthOut > 8) {
386 (*State->PortList)[i].SelWidthOut = 8;
388 if ((*State->PortList)[i].SelWidthIn > 8) {
389 (*State->PortList)[i].SelWidthIn = 8;
391 WidthOut = State->HtFeatures->ConvertWidthToBits ((*State->PortList)[i].SelWidthOut);
392 WidthIn = State->HtFeatures->ConvertWidthToBits ((*State->PortList)[i].SelWidthIn);
393 Temp = (WidthIn & 7) | ((WidthOut & 7) << 4);
394 Reg = Nb->MakeLinkBase (Node, (*State->PortList)[i].Link, Nb);
395 Reg.Address.Register += HTHOST_LINK_CONTROL_REG;
396 State->HtFeatures->SetHtControlRegisterBits (Reg, 31, 24, &Temp, State);