blob: fe5430672ef17aab2e53784d4d5004e96468ff81 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * Configure Max Payload
6 *
7 *
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: GNB
12 * @e \$Revision:
13 *
14 */
15/*
16*****************************************************************************
17*
18* Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
19*
20* AMD is granting you permission to use this software (the Materials)
21* pursuant to the terms and conditions of your Software License Agreement
22* with AMD. This header does *NOT* give you permission to use the Materials
23* or any rights under AMD's intellectual property. Your use of any portion
24* of these Materials shall constitute your acceptance of those terms and
25* conditions. If you do not agree to the terms and conditions of the Software
26* License Agreement, please do not use any portion of these Materials.
27*
28* CONFIDENTIALITY: The Materials and all other information, identified as
29* confidential and provided to you by AMD shall be kept confidential in
30* accordance with the terms and conditions of the Software License Agreement.
31*
32* LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION
33* PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
34* WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
35* MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE,
36* OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE.
37* IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER
38* (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
39* INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE,
40* GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER
41* RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF
42* THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE
43* EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES,
44* THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
45*
46* AMD does not assume any responsibility for any errors which may appear in
47* the Materials or any other related information provided to you by AMD, or
48* result from use of the Materials or any related information.
49*
50* You agree that you will not reverse engineer or decompile the Materials.
51*
52* NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
53* further information, software, technical information, know-how, or show-how
54* available to you. Additionally, AMD retains the right to modify the
55* Materials at any time, without notice, and is not obligated to provide such
56* modified Materials to you.
57*
58* U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
59* "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is
60* subject to the restrictions as set forth in FAR 52.227-14 and
61* DFAR252.227-7013, et seq., or its successor. Use of the Materials by the
62* Government constitutes acknowledgement of AMD's proprietary rights in them.
63*
64* EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any
65* direct product thereof will be exported directly or indirectly, into any
66* country prohibited by the United States Export Administration Act and the
67* regulations thereunder, without the required authorization from the U.S.
68* government nor will be used for any purpose prohibited by the same.
69* ***************************************************************************
70*
71*/
72
73/*----------------------------------------------------------------------------------------
74 * M O D U L E S U S E D
75 *----------------------------------------------------------------------------------------
76 */
77#include "AGESA.h"
78#include "Ids.h"
79#include "amdlib.h"
80#include "Gnb.h"
81#include "GnbPcie.h"
82#include "GnbCommonLib.h"
83#include "GnbPcieConfig.h"
84#include "GnbPcieInitLibV1.h"
85#include "GnbPcieInitLibV4.h"
86#include "PcieMaxPayloadV4.h"
87#include "GnbRegistersTN.h"
88#include "Filecode.h"
89#define FILECODE PROC_GNB_MODULES_GNBPCIEINITLIBV4_PCIEMAXPAYLOADV4_FILECODE
90
91/*----------------------------------------------------------------------------------------
92 * D E F I N I T I O N S A N D M A C R O S
93 *----------------------------------------------------------------------------------------
94 */
95
96
97/*----------------------------------------------------------------------------------------
98 * T Y P E D E F S A N D S T R U C T U R E S
99 *----------------------------------------------------------------------------------------
100 */
101typedef struct {
102 GNB_PCI_SCAN_DATA ScanData;
103 UINT8 MaxPayload;
104} PCIE_MAX_PAYLOAD_DATA;
105
106
107/*----------------------------------------------------------------------------------------
108 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
109 *----------------------------------------------------------------------------------------
110 */
111
112
113SCAN_STATUS
114PcieGetMaxPayloadCallback (
115 IN PCI_ADDR Device,
116 IN OUT GNB_PCI_SCAN_DATA *ScanData
117 );
118
119SCAN_STATUS
120PcieSetMaxPayloadCallback (
121 IN PCI_ADDR Device,
122 IN OUT GNB_PCI_SCAN_DATA *ScanData
123 );
124
125AGESA_STATUS
126PciePayloadBlackListFeature (
127 IN PCI_ADDR Device,
128 IN UINT8 *MaxPayload,
129 IN AMD_CONFIG_PARAMS *StdHeader
130 );
131
132/*----------------------------------------------------------------------------------------*/
133/**
134 * Determine maximum payload size for PCIe segment
135 *
136 * Scan through all link in segment to determine maximum payload by EPs.
137 *
138 * @param[in] DownstreamPort PCI address of PCIe port
139 * @param[in] StdHeader Standard configuration header
140 *
141 */
142
143VOID
144PcieSetMaxPayload (
145 IN PCI_ADDR DownstreamPort,
146 IN AMD_CONFIG_PARAMS *StdHeader
147 )
148{
149 PCIE_MAX_PAYLOAD_DATA PcieMaxPayloadData;
150
151 IDS_HDT_CONSOLE (GNB_TRACE, " PcieSetMaxPayload for Device = %d:%d:%d\n",
152 DownstreamPort.Address.Bus,
153 DownstreamPort.Address.Device,
154 DownstreamPort.Address.Function
155 );
156 PcieMaxPayloadData.MaxPayload = MAX_PAYLOAD;
157 PcieMaxPayloadData.ScanData.StdHeader = StdHeader;
158 PcieMaxPayloadData.ScanData.GnbScanCallback = PcieGetMaxPayloadCallback;
159 GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieMaxPayloadData.ScanData);
160 PcieMaxPayloadData.ScanData.GnbScanCallback = PcieSetMaxPayloadCallback;
161 GnbLibPciScan (DownstreamPort, DownstreamPort, &PcieMaxPayloadData.ScanData);
162 IDS_HDT_CONSOLE (GNB_TRACE, " PcieSetMaxPayloadExit\n");
163}
164
165/*----------------------------------------------------------------------------------------*/
166/**
167 * Evaluate device Max Payload - save SMALLEST Max Payload for PCIe Segment
168 *
169 *
170 *
171 * @param[in] Device PCI Address
172 * @param[in,out] ScanData Scan configuration data
173 * @retval Scan Status of 0
174 */
175
176SCAN_STATUS
177PcieGetMaxPayloadCallback (
178 IN PCI_ADDR Device,
179 IN OUT GNB_PCI_SCAN_DATA *ScanData
180 )
181{
182 SCAN_STATUS ScanStatus;
183 PCIE_MAX_PAYLOAD_DATA *PcieMaxPayloadData;
184 PCIE_DEVICE_TYPE DeviceType;
185 UINT32 Value;
186 UINT8 PcieCapPtr;
187 UINT8 DeviceMaxPayload;
188
189 PcieMaxPayloadData = (PCIE_MAX_PAYLOAD_DATA*) ScanData;
190 ScanStatus = SCAN_SUCCESS;
191 IDS_HDT_CONSOLE (GNB_TRACE, " PcieGetMaxPayloadCallback for Device = %d:%d:%d\n",
192 Device.Address.Bus,
193 Device.Address.Device,
194 Device.Address.Function
195 );
196 PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, ScanData->StdHeader);
197 if (PcieCapPtr != 0) {
198 GnbLibPciRead (
199 Device.AddressValue | (PcieCapPtr + PCIE_DEVICE_CAP_REGISTER),
200 AccessWidth32,
201 &Value,
202 ScanData->StdHeader
203 );
204 DeviceMaxPayload = (UINT8) (Value & 0x7);
205 PciePayloadBlackListFeature (Device, &DeviceMaxPayload, ScanData->StdHeader);
206 IDS_HDT_CONSOLE (GNB_TRACE, " Found DeviceMaxPayload as %d (Value = %x\n", DeviceMaxPayload, Value);
207 if (DeviceMaxPayload < PcieMaxPayloadData->MaxPayload) {
208 PcieMaxPayloadData->MaxPayload = DeviceMaxPayload;
209 }
210 }
211 DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader);
212 switch (DeviceType) {
213 case PcieDeviceRootComplex:
214 case PcieDeviceDownstreamPort:
215 case PcieDeviceUpstreamPort:
216 GnbLibPciScanSecondaryBus (Device, &PcieMaxPayloadData->ScanData);
217 break;
218 case PcieDeviceEndPoint:
219 case PcieDeviceLegacyEndPoint:
220 break;
221 default:
222 break;
223 }
224 return SCAN_SUCCESS;
225}
226
227/*----------------------------------------------------------------------------------------*/
228/**
229 * Configure the Max Payload setting to all devices in the PCIe Segment
230 *
231 *
232 *
233 * @param[in] Device PCI Address
234 * @param[in,out] ScanData Scan configuration data
235 * @retval Scan Status of 0
236 */
237
238SCAN_STATUS
239PcieSetMaxPayloadCallback (
240 IN PCI_ADDR Device,
241 IN OUT GNB_PCI_SCAN_DATA *ScanData
242 )
243{
244 SCAN_STATUS ScanStatus;
245 PCIE_MAX_PAYLOAD_DATA *PcieMaxPayloadData;
246 PCIE_DEVICE_TYPE DeviceType;
247 UINT8 PcieCapPtr;
248
249 PcieMaxPayloadData = (PCIE_MAX_PAYLOAD_DATA*) ScanData;
250 ScanStatus = SCAN_SUCCESS;
251 IDS_HDT_CONSOLE (GNB_TRACE, " PcieSetMaxPayloadCallback for Device = %d:%d:%d to %d\n",
252 Device.Address.Bus,
253 Device.Address.Device,
254 Device.Address.Function,
255 PcieMaxPayloadData->MaxPayload
256 );
257 PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, ScanData->StdHeader);
258 if (PcieCapPtr != 0) {
259 GnbLibPciRMW (
260 Device.AddressValue | (PcieCapPtr + PCIE_DEVICE_CTRL_REGISTER),
261 AccessWidth32,
262 ~(UINT32) (0x7 << 5),
263 ((UINT32)PcieMaxPayloadData->MaxPayload << 5),
264 ScanData->StdHeader
265 );
266 }
267 DeviceType = GnbLibGetPcieDeviceType (Device, ScanData->StdHeader);
268 switch (DeviceType) {
269 case PcieDeviceRootComplex:
270 case PcieDeviceDownstreamPort:
271 case PcieDeviceUpstreamPort:
272 GnbLibPciScanSecondaryBus (Device, &PcieMaxPayloadData->ScanData);
273 break;
274 case PcieDeviceEndPoint:
275 case PcieDeviceLegacyEndPoint:
276 break;
277 default:
278 break;
279 }
280 return SCAN_SUCCESS;
281}
282
283UINT16 PayloadBlacklistDeviceTable[] = {
284 0x1969, 0x1083, (UINT16) MAX_PAYLOAD_128
285};
286
287/*----------------------------------------------------------------------------------------*/
288/**
289 * Pcie Max_Payload_Size Black List
290 *
291 *
292 *
293 * @param[in] Device PCI_ADDR of PCIe Device to evaluate
294 * @param[in] MaxPayload Pointer to Max_Payload_Size value
295 * @param[in] StdHeader Standard configuration header
296 * @retval AGESA_STATUS
297 */
298
299AGESA_STATUS
300PciePayloadBlackListFeature (
301 IN PCI_ADDR Device,
302 IN UINT8 *MaxPayload,
303 IN AMD_CONFIG_PARAMS *StdHeader
304 )
305{
306 UINT32 TargetDeviceId;
307 UINTN i;
308 UINT32 DeviceId;
309 UINT32 VendorId;
310
311 GnbLibPciRead (Device.AddressValue, AccessWidth32, &TargetDeviceId, StdHeader);
312 for (i = 0; i < (sizeof (PayloadBlacklistDeviceTable) / sizeof (UINT16)); i = i + 3) {
313 VendorId = PayloadBlacklistDeviceTable[i];
314 DeviceId = PayloadBlacklistDeviceTable[i + 1];
315 if (VendorId == (UINT16)TargetDeviceId) {
316 if (DeviceId == 0xFFFF || DeviceId == (TargetDeviceId >> 16)) {
317 *MaxPayload = (UINT8) PayloadBlacklistDeviceTable[i + 2];
318 }
319 }
320 }
321 return AGESA_SUCCESS;
322}