blob: e1694564c6803e77bc5d1d232a1654b1ef95094f [file] [log] [blame]
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007 Advanced Micro Devices, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef H3FINIT_H
#define H3FINIT_H
/*----------------------------------------------------------------------------
* Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
*
*----------------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------------
* DEFINITIONS AND MACROS
*
*-----------------------------------------------------------------------------
*/
/* Width equates for call backs */
#define HT_WIDTH_8_BITS 8
#define HT_WIDTH_16_BITS 16
#define HT_WIDTH_4_BITS 4
#define HT_WIDTH_2_BITS 2
/* Frequency equates for call backs which take an actual frequency setting */
#define HT_FREQUENCY_200M 0
#define HT_FREQUENCY_400M 2
#define HT_FREQUENCY_600M 4
#define HT_FREQUENCY_800M 5
#define HT_FREQUENCY_1000M 6
#define HT_FREQUENCY_1200M 7
#define HT_FREQUENCY_1400M 8
#define HT_FREQUENCY_1600M 9
#define HT_FREQUENCY_1800M 10
#define HT_FREQUENCY_2000M 11
#define HT_FREQUENCY_2200M 12
#define HT_FREQUENCY_2400M 13
#define HT_FREQUENCY_2600M 14
/* Frequency Limit equates for call backs which take a frequency supported mask. */
#define HT_FREQUENCY_LIMIT_200M 1
#define HT_FREQUENCY_LIMIT_400M 7
#define HT_FREQUENCY_LIMIT_600M 0x1F
#define HT_FREQUENCY_LIMIT_800M 0x3F
#define HT_FREQUENCY_LIMIT_1000M 0x7F
#define HT_FREQUENCY_LIMIT_HT1_ONLY 0x7F
#define HT_FREQUENCY_LIMIT_1200M 0xFF
#define HT_FREQUENCY_LIMIT_1400M 0x1FF
#define HT_FREQUENCY_LIMIT_1600M 0x3FF
#define HT_FREQUENCY_LIMIT_1800M 0x7FF
#define HT_FREQUENCY_LIMIT_2000M 0xFFF
#define HT_FREQUENCY_LIMIT_2200M 0x1FFF
#define HT_FREQUENCY_LIMIT_2400M 0x3FFF
#define HT_FREQUENCY_LIMIT_2600M 0x7FFF
/*
* Event Notify definitions
*/
/* Event Class definitions */
#define HT_EVENT_CLASS_CRITICAL 1
#define HT_EVENT_CLASS_ERROR 2
#define HT_EVENT_CLASS_HW_FAULT 3
#define HT_EVENT_CLASS_WARNING 4
#define HT_EVENT_CLASS_INFO 5
/* Event definitions. */
/* Coherent subfunction events */
#define HT_EVENT_COH_EVENTS 0x1000
#define HT_EVENT_COH_NO_TOPOLOGY 0x1001
#define HT_EVENT_COH_LINK_EXCEED 0x1002
#define HT_EVENT_COH_FAMILY_FEUD 0x1003
#define HT_EVENT_COH_NODE_DISCOVERED 0x1004
#define HT_EVENT_COH_MPCAP_MISMATCH 0x1005
/* Non-coherent subfunction events */
#define HT_EVENT_NCOH_EVENTS 0x2000
#define HT_EVENT_NCOH_BUID_EXCEED 0x2001
#define HT_EVENT_NCOH_LINK_EXCEED 0x2002
#define HT_EVENT_NCOH_BUS_MAX_EXCEED 0x2003
#define HT_EVENT_NCOH_CFG_MAP_EXCEED 0x2004
#define HT_EVENT_NCOH_DEVICE_FAILED 0x2005
#define HT_EVENT_NCOH_AUTO_DEPTH 0x2006
/* Optimization subfunction events */
#define HT_EVENT_OPT_EVENTS 0x3000
#define HT_EVENT_OPT_REQUIRED_CAP_RETRY 0x3001
#define HT_EVENT_OPT_REQUIRED_CAP_GEN3 0x3002
/* HW Fault events */
#define HT_EVENT_HW_EVENTS 0x4000
#define HT_EVENT_HW_SYNCHFLOOD 0x4001
#define HT_EVENT_HW_HTCRC 0x4002
/* The bbHT component (hb*) uses 0x5000 for events.
* For consistency, we avoid that range here.
*/
/*----------------------------------------------------------------------------
* TYPEDEFS, STRUCTURES, ENUMS
*
*----------------------------------------------------------------------------
*/
typedef struct {
u8 **topolist;
u8 AutoBusStart;
/* Note: This should always be the form AutoBusCurrent+N*AutoBusIncrement, also bus 253-255 are reserved */
u8 AutoBusMax;
u8 AutoBusIncrement;
/**----------------------------------------------------------------------------------------
*
* BOOL
* AMD_CB_IgnoreLink(u8 Node, u8 Link)
*
* Description:
* This routine is called every time a coherent link is found and then every
* time a non-coherent link from a CPU is found.
* Any coherent or non-coherent link from a CPU can be ignored and not used
* for discovery or initialization. Useful for connection based systems.
* (Note: not called for IO device to IO Device links.)
*
* Parameters:
* @param[in] u8 node = The node on which this link is located
* @param[in] u8 link = The link about to be initialized
* @param[out] BOOL result = true to ignore this link and skip it
* false to initialize the link normally
*
* ---------------------------------------------------------------------------------------
*/
BOOL (*AMD_CB_IgnoreLink)(u8 Node, u8 Link);
/**----------------------------------------------------------------------------------------
*
* BOOL
* AMD_CB_OverrideBusNumbers(u8 Node, u8 Link, u8 *SecBus, u8 *SubBus)
*
* Description:
* This routine is called every time a non-coherent chain is processed.
* If a system can not use the auto Bus numbering feature for non-coherent chain bus
* assignments, this routine can provide explicit control. For each chain, provide
* the bus number range to use.
*
* Parameters:
* @param[in] u8 node = The node on which this chain is located
* @param[in] u8 link = The link on the host for this chain
* @param[out] u8 secBus = Secondary Bus number for this non-coherent chain
* @param[out] u8* subBus = Subordinate Bus number
* @param[out] BOOL result = true this routine is supplying the bus numbers
* false use auto Bus numbering
*
* ---------------------------------------------------------------------------------------
*/
BOOL (*AMD_CB_OverrideBusNumbers)(u8 Node, u8 Link, u8 *SecBus, u8 *SubBus);
/**----------------------------------------------------------------------------------------
*
* BOOL
* AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List)
*
* Description:
* This routine is called every time a non-coherent chain is processed.
* BUID assignment may be controlled explicitly on a non-coherent chain. Provide a
* swap list. The first part of the list controls the BUID assignment and the
* second part of the list provides the device to device linking. Device orientation
* can be detected automatically, or explicitly. See documentation for more details.
*
* Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially
* based on each device's unit count.
*
* Parameters:
* @param[in] u8 node = The node on which this chain is located
* @param[in] u8 link = The link on the host for this chain
* @param[out] u8** list = supply a pointer to a list
* @param[out] BOOL result = true to use a manual list
* false to initialize the link automatically
*
* ---------------------------------------------------------------------------------------
*/
BOOL (*AMD_CB_ManualBUIDSwapList)(u8 Node, u8 Link, const u8 **List);
/**----------------------------------------------------------------------------------------
*
* void
* AMD_CB_DeviceCapOverride(u8 HostNode, u8 HostLink, u8 Depth, u8 Segment,
* u8 Bus, u8 Dev, u32 DevVenID, u8 Link,
* u8 *LinkWidthIn, u8 *LinkWidthOut, u16 *FreqCap)
*
* Description:
* This routine is called once for every link on every IO device.
* Update the width and frequency capability if needed for this device.
* This is used along with device capabilities, the limit call backs, and northbridge
* limits to compute the default settings. The components of the device's PCI config
* address are provided, so its settings can be consulted if need be. The input width
* and frequency are the reported device capabilities.
*
* Parameters:
* @param[in] u8 hostNode = The node on which this chain is located
* @param[in] u8 hostLink = The link on the host for this chain
* @param[in] u8 Depth = The depth in the I/O chain from the Host
* @param[in] u8 Segment = The Device's PCI Bus Segment number
* @param[in] u8 Bus = The Device's PCI Bus number
* @param[in] u8 Dev = The Device's PCI device Number
* @param[in] u32 DevVenID = The Device's PCI Vendor + Device ID (offset 0x00)
* @param[in] u8 Link = The Device's link number (0 or 1)
* @param[in,out] u8* LinkWidthIn = modify to change the Link Witdh In
* @param[in,out] u8* LinkWidthOut = modify to change the Link Witdh Out
* @param[in,out] u16* FreqCap = modify to change the link's frequency capability
*
* ---------------------------------------------------------------------------------------
*/
void (*AMD_CB_DeviceCapOverride)(
u8 HostNode,
u8 HostLink,
u8 Depth,
u8 Segment,
u8 Bus,
u8 Dev,
u32 DevVenID,
u8 Link,
u8 *LinkWidthIn,
u8 *LinkWidthOut,
u16 *FreqCap
);
/**----------------------------------------------------------------------------------------
*
* void
* AMD_CB_Cpu2CpuPCBLimits(u8 NodeA, u8 LinkA, u8 NodeB, u8 LinkB,
* u8 *ABLinkWidthLimit, u8 *BALinkWidthLimit, u16 *PCBFreqCap)
*
* Description:
* For each coherent connection this routine is called once.
* Update the frequency and width if needed for this link (usually based on board
* restriction). This is used with CPU device capabilities and northbridge limits
* to compute the default settings. The input width and frequency are valid, but do
* not necessarily reflect the minimum setting that will be chosen.
*
* Parameters:
* @param[in] u8 nodeA = One node on which this link is located
* @param[in] u8 linkA = The link on this node
* @param[in] u8 nodeB = The other node on which this link is located
* @param[in] u8 linkB = The link on that node
* @param[in,out] u8* ABLinkWidthLimit = modify to change the Link Witdh In
* @param[in,out] u8* BALinkWidthLimit = modify to change the Link Witdh Out
* @param[in,out] u16* PCBFreqCap = modify to change the link's frequency capability
*
* ---------------------------------------------------------------------------------------
*/
void (*AMD_CB_Cpu2CpuPCBLimits)(
u8 NodeA,
u8 LinkA,
u8 NodeB,
u8 LinkB,
u8 *ABLinkWidthLimit,
u8 *BALinkWidthLimit,
u16 *PCBFreqCap
);
/**----------------------------------------------------------------------------------------
*
* void
* AMD_CB_IOPCBLimits(u8 HostNode, u8 HostLink, u8 Depth, u8 *DownstreamLinkWidthLimit,
* u8 *UpstreamLinkWidthLimit, u16 *PCBFreqCap)
*
* Description:
* For each non-coherent connection this routine is called once.
* Update the frequency and width if needed for this link (usually based on board
* restriction). This is used with device capabilities, device overrides, and northbridge limits
* to compute the default settings. The input width and frequency are valid, but do
* not necessarily reflect the minimum setting that will be chosen.
*
* Parameters:
* @param[in] u8 hostNode = The node on which this link is located
* @param[in] u8 hostLink = The link about to be initialized
* @param[in] u8 Depth = The depth in the I/O chain from the Host
* @param[in,out] u8* DownstreamLinkWidthLimit = modify to change the Link Witdh In
* @param[in,out] u8* UpstreamLinkWidthLimit = modify to change the Link Witdh Out
* @param[in,out] u16* PCBFreqCap = modify to change the link's frequency capability
*
* ---------------------------------------------------------------------------------------
*/
void (*AMD_CB_IOPCBLimits)(
u8 HostNode,
u8 HostLink,
u8 Depth,
u8 *DownstreamLinkWidthLimit,
u8 *UpstreamLinkWidthLimit,
u16 *PCBFreqCap
);
/**----------------------------------------------------------------------------------------
*
* BOOL
* AMD_CB_SkipRegang(u8 NodeA, u8 LinkA, u8 NodeB, u8 LinkB)
*
* Description:
* This routine is called whenever two sublinks are both connected to the same CPUs.
* Normally, unganged subsinks between the same two CPUs are reganged.
* Return true from this routine to leave the links unganged.
*
* Parameters:
* @param[in] u8 nodeA = One node on which this link is located
* @param[in] u8 linkA = The link on this node
* @param[in] u8 nodeB = The other node on which this link is located
* @param[in] u8 linkB = The link on that node
* @param[out] BOOL result = true to leave link unganged
* false to regang link automatically
*
* ---------------------------------------------------------------------------------------
*/
BOOL (*AMD_CB_SkipRegang)(
u8 NodeA,
u8 LinkA,
u8 NodeB,
u8 LinkB
);
/**----------------------------------------------------------------------------------------
*
* BOOL
* AMD_CB_CustomizeTrafficDistribution()
*
* Description:
* Near the end of HT initialization, this routine is called once.
* If this routine will handle traffic distribution in a proprietary way,
* after detecting which links to distribute traffic on and configuring the system,
* return true. Return false to let the HT code detect and do traffic distribution
* This routine can also be used to simply turn this feature off, or to pre-process
* the system before normal traffic distribution.
*
* Parameters:
* @param[out] BOOL result = true skip traffic distribution
* false do normal traffic distribution
*
* ---------------------------------------------------------------------------------------
*/
BOOL (*AMD_CB_CustomizeTrafficDistribution)( void );
/**----------------------------------------------------------------------------------------
*
* BOOL
* AMD_CB_CustomizeBuffers(u8 Node)
*
* Description:
* Near the end of HT initialization, this routine is called once per CPU node.
* Implement proprietary buffer tuning and return true, or return false for normal tuning.
* This routine can also be used to simply turn this feature off, or to pre-process
* the system before normal tuning.
*
* Parameters:
* @param[in] u8 node = buffer allocation may apply to this node
* @param[out] BOOL result = true skip buffer allocation on this node
* false tune buffers normally
*
* ---------------------------------------------------------------------------------------
*/
BOOL (*AMD_CB_CustomizeBuffers)( u8 node );
/**----------------------------------------------------------------------------------------
*
* void
* AMD_CB_OverrideDevicePort(u8 HostNode, u8 HostLink, u8 Depth, u8 *LinkWidthIn,
* u8 *LinkWidthOut, u16 *LinkFrequency)
*
* Description:
* Called once for each active link on each IO device.
* Provides an opportunity to directly control the frequency and width,
* intended for test and debug. The input frequency and width will be used
* if not overridden.
*
* Parameters:
* @param[in] u8 hostNode = The node on which this link is located
* @param[in] u8 hostLink = The link about to be initialized
* @param[in] u8 Depth = The depth in the I/O chain from the Host
* @param[in] u8 Link = the link on the device (0 or 1)
* @param[in,out] u8* LinkWidthIn = modify to change the Link Witdh In
* @param[in,out] u8* LinkWidthOut = modify to change the Link Witdh Out
* @param[in,out] u16* LinkFrequency = modify to change the link's frequency capability
*
* ---------------------------------------------------------------------------------------
*/
void (*AMD_CB_OverrideDevicePort)(
u8 HostNode,
u8 HostLink,
u8 Depth,
u8 Link,
u8 *LinkWidthIn,
u8 *LinkWidthOut,
u8 *LinkFrequency
);
/**----------------------------------------------------------------------------------------
*
* void
* AMD_CB_OverrideCpuPort(u8 Node, u8 Link, u8 *LinkWidthIn, u8 *LinkWidthOut,
* u16 *LinkFrequency)
*
* Description:
* Called once for each active link on each CPU.
* Provides an opportunity to directly control the frequency and width,
* intended for test and debug. The input frequency and width will be used
* if not overridden.
*
* Parameters:
* @param[in] u8 node = One node on which this link is located
* @param[in] u8 link = The link on this node
* @param[in,out] u8* LinkWidthIn = modify to change the Link Witdh In
* @param[in,out] u8* LinkWidthOut = modify to change the Link Witdh Out
* @param[in,out] u16* LinkFrequency = modify to change the link's frequency capability
*
*---------------------------------------------------------------------------------------
*/
void (*AMD_CB_OverrideCpuPort)(
u8 Node,
u8 Link,
u8 *LinkWidthIn,
u8 *LinkWidthOut,
u8 *LinkFrequency
);
/**----------------------------------------------------------------------------------------
*
* void
* AMD_CB_EventNotify(u8 evtClass, u16 event, const u8 *pEventData0)
*
* Description:
* Errors, events, faults, warnings, and useful information are provided by
* calling this routine as often as necessary, once for each notification.
* See elsewhere in this file for class, event, and event data definitions.
* See the documentation for more details.
*
* Parameters:
* @param[in] u8 evtClass = What level event is this
* @param[in] u16 event = A unique ID of this event
* @param[in] u8* pEventData0 = useful data associated with the event.
*
* ---------------------------------------------------------------------------------------
*/
void (*AMD_CB_EventNotify) (
u8 evtClass,
u16 event,
const u8 *pEventData0
);
} AMD_HTBLOCK;
/*
* Event Notification Structures
* These structures are passed to AMD_CB_EventNotify as *pEventData0.
*/
/* For event HT_EVENT_HW_SYNCHFLOOD */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
} sHtEventHWSynchFlood;
/* For event HT_EVENT_HW_HTCRC */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 laneMask;
} sHtEventHWHtCrc;
/* For event HT_EVENT_NCOH_BUS_MAX_EXCEED */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 bus;
} sHTEventNcohBusMaxExceed;
/* For event HT_EVENT_NCOH_LINK_EXCEED */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 depth;
u8 maxLinks;
} sHtEventNcohLinkExceed;
/* For event HT_EVENT_NCOH_CFG_MAP_EXCEED */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
} sHtEventNcohCfgMapExceed;
/* For event HT_EVENT_NCOH_BUID_EXCEED */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 depth;
u8 currentBUID;
u8 unitCount;
} sHtEventNcohBuidExceed;
/* For event HT_EVENT_NCOH_DEVICE_FAILED */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 depth;
u8 attemptedBUID;
} sHtEventNcohDeviceFailed;
/* For event HT_EVENT_NCOH_AUTO_DEPTH */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 depth;
} sHtEventNcohAutoDepth;
/* For event HT_EVENT_OPT_REQUIRED_CAP_RETRY,
* HT_EVENT_OPT_REQUIRED_CAP_GEN3
*/
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 depth;
} sHtEventOptRequiredCap;
/* For event HT_EVENT_COH_NO_TOPOLOGY */
typedef struct
{
u8 eSize;
u8 totalNodes;
} sHtEventCohNoTopology;
/* For event HT_EVENT_COH_LINK_EXCEED */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 targetNode;
u8 totalNodes;
u8 maxLinks;
} sHtEventCohLinkExceed;
/* For event HT_EVENT_COH_FAMILY_FEUD */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 totalNodes;
} sHtEventCohFamilyFeud;
/* For event HT_EVENT_COH_NODE_DISCOVERED */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 newNode;
} sHtEventCohNodeDiscovered;
/* For event HT_EVENT_COH_MPCAP_MISMATCH */
typedef struct
{
u8 eSize;
u8 node;
u8 link;
u8 sysMpCap;
u8 totalNodes;
} sHtEventCohMpCapMismatch;
/*----------------------------------------------------------------------------
* FUNCTIONS PROTOTYPE
*
*----------------------------------------------------------------------------
*/
void amdHtInitialize(AMD_HTBLOCK *pBlock);
#endif /* H3FINIT_H */