5 * SubLink management Routines.
7 * Contains routines for subLink frequency ratios.
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 *----------------------------------------------------------------------------
62 #include "htFeatSublinks.h"
67 #define FILECODE PROC_HT_FEATURES_HTFEATSUBLINKS_FILECODE
68 /*----------------------------------------------------------------------------
69 * DEFINITIONS AND MACROS
71 *----------------------------------------------------------------------------
74 /*----------------------------------------------------------------------------
75 * TYPEDEFS AND STRUCTURES
77 *----------------------------------------------------------------------------
85 STATIC CONST VALID_RATIO_ITEM ROMDATA ValidRatioList[] =
87 {HT_FREQUENCY_3200M, HT_FREQUENCY_1600M}, // 3200MHz / 1600MHz 2:1
88 {HT_FREQUENCY_3200M, HT_FREQUENCY_800M}, // 3200MHz / 800MHz 4:1
89 {HT_FREQUENCY_3200M, HT_FREQUENCY_400M}, // 3200MHz / 400MHz 8:1
90 {HT_FREQUENCY_2800M, HT_FREQUENCY_1400M}, // 2800MHz / 1400MHz 2:1
91 {HT_FREQUENCY_2400M, HT_FREQUENCY_1200M}, // 2400MHz / 1200MHz 2:1
92 {HT_FREQUENCY_2400M, HT_FREQUENCY_600M}, // 2400MHz / 600MHz 4:1
93 {HT_FREQUENCY_2400M, HT_FREQUENCY_400M}, // 2400MHz / 400MHz 6:1
94 {HT_FREQUENCY_2000M, HT_FREQUENCY_1000M}, // 2000MHz / 1000MHz 2:1
95 {HT_FREQUENCY_1600M, HT_FREQUENCY_800M}, // 1600MHz / 800MHz 2:1
96 {HT_FREQUENCY_1600M, HT_FREQUENCY_400M}, // 1600MHz / 400MHz 4:1
97 {HT_FREQUENCY_1600M, HT_FREQUENCY_200M}, // 1600MHz / 200Mhz 8:1
98 {HT_FREQUENCY_1200M, HT_FREQUENCY_600M}, // 1200MHz / 600MHz 2:1
99 {HT_FREQUENCY_1200M, HT_FREQUENCY_200M}, // 1200MHz / 200MHz 6:1
100 {HT_FREQUENCY_800M, HT_FREQUENCY_400M}, // 800MHz / 400MHz 2:1
101 {HT_FREQUENCY_800M, HT_FREQUENCY_200M}, // 800MHz / 200MHz 4:1
102 {HT_FREQUENCY_400M, HT_FREQUENCY_200M} // 400MHz / 200MHz 2:1
105 /*----------------------------------------------------------------------------
106 * PROTOTYPES OF LOCAL FUNCTIONS
108 *----------------------------------------------------------------------------
111 /*----------------------------------------------------------------------------
114 *----------------------------------------------------------------------------
117 /*----------------------------------------------------------------------------
120 *----------------------------------------------------------------------------
123 /***************************************************************************
124 *** Link Optimization ***
125 ***************************************************************************/
127 /*----------------------------------------------------------------------------------------*/
129 * Iterate through all Links, checking the frequency of each subLink pair.
131 * @HtFeatMethod{::F_SUBLINK_RATIO_FIXUP}
133 * Make the adjustment to the port list data so that the frequencies
134 * are at a valid ratio, reducing frequency as needed to achieve
135 * this. (All Links support the minimum 200 MHz frequency.) Repeat
136 * the above until no adjustments are needed.
137 * @note no hardware state changes in this routine.
139 * @param[in,out] State Link state and port list
144 IN OUT STATE_DATA *State
149 UINT8 ValidRatioItem;
160 for (i = 0; i < State->TotalLinks*2; i++) {
161 // Must be a CPU Link
162 if ((*State->PortList)[i].Type != PORTLIST_TYPE_CPU) {
165 // Only look for subLink1's
166 if ((*State->PortList)[i].Link < 4) {
170 for (j = 0; j < State->TotalLinks*2; j++) {
171 // Step 1. Find the matching subLink0
172 if ((*State->PortList)[j].Type != PORTLIST_TYPE_CPU) {
175 if ((*State->PortList)[j].NodeID != (*State->PortList)[i].NodeID) {
178 if ((*State->PortList)[j].Link != ((*State->PortList)[i].Link & 0x03)) {
182 // Step 2. Check for an illegal frequency ratio
183 if ((*State->PortList)[i].SelFrequency >= (*State->PortList)[j].SelFrequency) {
185 HiFreq = (*State->PortList)[i].SelFrequency;
186 LoFreq = (*State->PortList)[j].SelFrequency;
189 HiFreq = (*State->PortList)[j].SelFrequency;
190 LoFreq = (*State->PortList)[i].SelFrequency;
193 // The frequencies are 1:1, no need to do anything
194 if (HiFreq == LoFreq) {
200 for (ValidRatioItem = 0; ValidRatioItem < (sizeof (ValidRatioList) / sizeof (VALID_RATIO_ITEM)); ValidRatioItem++) {
201 if ((HiFreq == ValidRatioList[ValidRatioItem].HiFreq) &&
202 (LoFreq == ValidRatioList[ValidRatioItem].LoFreq)) {
208 // Step 3. Downgrade the higher of the two frequencies, and set Changes to FALSE
210 // Although the problem was with the port specified by hiIndex, we need to
211 // Downgrade both ends of the Link.
212 HiIndex = HiIndex & 0xFE; // Select the 'upstream' (i.e. even) port
214 Temp = (*State->PortList)[HiIndex].CompositeFrequencyCap;
216 // Remove HiFreq from the list of valid frequencies
217 Temp = Temp & ~((UINT32)1 << HiFreq);
219 (*State->PortList)[HiIndex].CompositeFrequencyCap = (UINT32)Temp;
220 (*State->PortList)[HiIndex + 1].CompositeFrequencyCap = (UINT32)Temp;
222 HiFreq = LibAmdBitScanReverse (Temp);
224 (*State->PortList)[HiIndex].SelFrequency = HiFreq;
225 (*State->PortList)[HiIndex + 1].SelFrequency = HiFreq;
231 } while (Changes); // Repeat until a valid configuration is reached