5 * Routines for re-ganging Links.
7 * Implement the reganging feature.
9 * @xrefitem bom "File Content Label" "Release Content"
11 * @e sub-project: HyperTransport
12 * @e \$Revision: 56279 $ @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
16 *****************************************************************************
18 * Copyright (C) 2012 Advanced Micro Devices, Inc.
19 * All rights reserved.
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.
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.
43 * ***************************************************************************
48 *----------------------------------------------------------------------------
51 *----------------------------------------------------------------------------
60 #include "htInterface.h"
62 #include "htFeatGanging.h"
67 #define FILECODE PROC_HT_FEATURES_HTFEATGANGING_FILECODE
68 /*----------------------------------------------------------------------------
69 * DEFINITIONS AND MACROS
71 *----------------------------------------------------------------------------
74 /*----------------------------------------------------------------------------
75 * TYPEDEFS AND STRUCTURES
77 *----------------------------------------------------------------------------
80 /*----------------------------------------------------------------------------
81 * PROTOTYPES OF LOCAL FUNCTIONS
83 *----------------------------------------------------------------------------
86 /*----------------------------------------------------------------------------
89 *----------------------------------------------------------------------------
92 /*----------------------------------------------------------------------------
95 *----------------------------------------------------------------------------
98 /***************************************************************************
99 *** Link Optimization ***
100 ***************************************************************************/
102 /*----------------------------------------------------------------------------------------*/
104 * Test the subLinks of a Link to see if they qualify to be reganged.
106 * @HtFeatMethod{::F_REGANG_LINKS}
108 * If they do, update the port list data to indicate that this should be done.
109 * @note no actual hardware state is changed in this routine.
111 * @param[in,out] State Our global state
115 IN OUT STATE_DATA *State
118 FINAL_LINK_STATE FinalLinkState;
121 for (i = 0; i < (State->TotalLinks * 2); i += 2) {
123 ASSERT ((*State->PortList)[i].Type < 2 && (*State->PortList)[i].Link < State->Nb->MaxLinks);
124 ASSERT ((*State->PortList)[i + 1].Type < 2 && (*State->PortList)[i + 1].Link < State->Nb->MaxLinks);
126 // Regang is false unless we pass all conditions below
127 (*State->PortList)[i].SelRegang = FALSE;
128 (*State->PortList)[i + 1].SelRegang = FALSE;
130 // Only process cpu to cpu Links
131 if ( ((*State->PortList)[i].Type != PORTLIST_TYPE_CPU) ||
132 ((*State->PortList)[i + 1].Type != PORTLIST_TYPE_CPU)) {
136 for (j = i + 2; j < State->TotalLinks*2; j += 2) {
137 // Only process cpu to cpu Links
138 if ( ((*State->PortList)[j].Type != PORTLIST_TYPE_CPU) ||
139 ((*State->PortList)[j + 1].Type != PORTLIST_TYPE_CPU) ) {
143 // Links must be from the same source
144 if ((*State->PortList)[i].NodeID != (*State->PortList)[j].NodeID) {
148 // Link must be to the same target
149 if ((*State->PortList)[i + 1].NodeID != (*State->PortList)[j + 1].NodeID) {
153 // Ensure same source base port
154 if (((*State->PortList)[i].Link & 3) != ((*State->PortList)[j].Link & 3)) {
158 // Ensure same destination base port
159 if (((*State->PortList)[i + 1].Link & 3) != ((*State->PortList)[j + 1].Link & 3)) {
163 // Ensure subLink0 routes to subLink0
164 if (((*State->PortList)[i].Link & 4) != ((*State->PortList)[i + 1].Link & 4)) {
168 // (therefore subLink1 routes to subLink1)
169 ASSERT (((*State->PortList)[j].Link & 4) == ((*State->PortList)[j + 1].Link & 4));
171 FinalLinkState = State->HtInterface->GetSkipRegang ((*State->PortList)[i].NodeID,
172 (*State->PortList)[i].Link & 0x03,
173 (*State->PortList)[i + 1].NodeID,
174 (*State->PortList)[i + 1].Link & 0x03,
176 if (FinalLinkState == MATCHED) {
178 } else if (FinalLinkState == POWERED_OFF) {
179 // StopLink will be done on the sublink 1, thus OR in 4 to the link to ensure it.
180 State->Nb->StopLink ((*State->PortList)[i].NodeID, ((*State->PortList)[i].Link | 4), State, State->Nb);
181 State->Nb->StopLink ((*State->PortList)[i + 1].NodeID, ((*State->PortList)[i + 1].Link | 4), State, State->Nb);
185 // Create a ganged portlist entry for the two regang-able subLinks.
187 // All info will be that of subLink zero.
188 // (If Link discovery order was other than ascending, fix the .Pointer field too.)
191 if (((*State->PortList)[i].Link & 4) != 0) {
192 (*State->PortList)[i].Pointer = (*State->PortList)[j].Pointer;
193 (*State->PortList)[i + 1].Pointer = (*State->PortList)[j + 1].Pointer;
195 (*State->PortList)[i].Link &= 0x03; // Force to point to subLink0
196 (*State->PortList)[i + 1].Link &= 0x03;
197 // If powered off, sublink 1 is removed but the link is still 8 bits.
198 if (FinalLinkState != POWERED_OFF) {
199 (*State->PortList)[i].SelRegang = TRUE; // Enable Link reganging
200 (*State->PortList)[i + 1].SelRegang = TRUE;
201 (*State->PortList)[i].PrvWidthOutCap = HT_WIDTH_16_BITS;
202 (*State->PortList)[i + 1].PrvWidthOutCap = HT_WIDTH_16_BITS;
203 (*State->PortList)[i].PrvWidthInCap = HT_WIDTH_16_BITS;
204 (*State->PortList)[i + 1].PrvWidthInCap = HT_WIDTH_16_BITS;
207 // Delete PortList[j, j + 1], slow but easy to debug implementation
209 LibAmdMemCopy (&((*State->PortList)[j]),
210 &((*State->PortList)[j + 2]),
211 sizeof (PORT_DESCRIPTOR)*(State->TotalLinks* 2 - j),
212 State->ConfigHandle);
213 LibAmdMemFill (&((*State->PortList)[State->TotalLinks * 2]), INVALID_LINK, (sizeof (PORT_DESCRIPTOR) * 2), State->ConfigHandle);
215 break; // Exit loop, advance to PortList[i + 2]