aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdht/h3ncmn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdht/h3ncmn.c')
-rw-r--r--src/northbridge/amd/amdht/h3ncmn.c2549
1 files changed, 0 insertions, 2549 deletions
diff --git a/src/northbridge/amd/amdht/h3ncmn.c b/src/northbridge/amd/amdht/h3ncmn.c
deleted file mode 100644
index 830e9888c9..0000000000
--- a/src/northbridge/amd/amdht/h3ncmn.c
+++ /dev/null
@@ -1,2549 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-
-/*----------------------------------------------------------------------------
- * MODULES USED
- *
- *----------------------------------------------------------------------------
- */
-
-#include "h3ncmn.h"
-#include "h3finit.h"
-#include "h3ffeat.h"
-#include "AsPsNb.h"
-
-#include <arch/cpu.h>
-#include <device/pci.h>
-#include <cpu/amd/msr.h>
-#include <device/pci_def.h>
-#include <northbridge/amd/amdfam10/raminit.h>
-#include <northbridge/amd/amdfam10/amdfam10.h>
-
-/*----------------------------------------------------------------------------
- * DEFINITIONS AND MACROS
- *
- *----------------------------------------------------------------------------
- */
-
-/* CPU Northbridge Functions */
-#define CPU_HTNB_FUNC_00 0
-#define CPU_HTNB_FUNC_04 4
-#define CPU_ADDR_FUNC_01 1
-#define CPU_NB_FUNC_03 3
-#define CPU_NB_FUNC_05 5
-
-/* Function 0 registers */
-#define REG_ROUTE0_0X40 0x40
-#define REG_ROUTE1_0X44 0x44
-#define REG_NODE_ID_0X60 0x60
-#define REG_UNIT_ID_0X64 0x64
-#define REG_LINK_TRANS_CONTROL_0X68 0x68
-#define REG_LINK_INIT_CONTROL_0X6C 0x6c
-#define REG_HT_CAP_BASE_0X80 0x80
-#define REG_NORTHBRIDGE_CFG_3X8C 0x8c
-#define REG_HT_LINK_RETRY0_0X130 0x130
-#define REG_HT_TRAFFIC_DIST_0X164 0x164
-#define REG_HT_LINK_EXT_CONTROL0_0X170 0x170
-
-#define HT_CONTROL_CLEAR_CRC (~(3 << 8))
-
-/* Function 1 registers */
-#define REG_ADDR_CONFIG_MAP0_1XE0 0xE0
-#define CPU_ADDR_NUM_CONFIG_MAPS 4
-
-/* Function 3 registers */
-#define REG_NB_SRI_XBAR_BUF_3X70 0x70
-#define REG_NB_MCT_XBAR_BUF_3X78 0x78
-#define REG_NB_FIFOPTR_3XDC 0xDC
-#define REG_NB_CAPABILITY_3XE8 0xE8
-#define REG_NB_CPUID_3XFC 0xFC
-#define REG_NB_LINK_XCS_TOKEN0_3X148 0x148
-#define REG_NB_DOWNCORE_3X190 0x190
-#define REG_NB_CAPABILITY_5X84 0x84
-
-/* Function 4 registers */
-
-
-/*----------------------------------------------------------------------------
- * TYPEDEFS AND STRUCTURES
- *
- *----------------------------------------------------------------------------
- */
-/*----------------------------------------------------------------------------
- * PROTOTYPES OF LOCAL FUNCTIONS
- *
- *----------------------------------------------------------------------------
- */
-
-/***************************************************************************
- *** FAMILY/NORTHBRIDGE SPECIFIC FUNCTIONS ***
- ***************************************************************************/
-
-inline uint8_t is_gt_rev_d(void)
-{
- uint8_t fam15h = 0;
- uint8_t rev_gte_d = 0;
- uint32_t family;
- uint32_t model;
-
- family = model = cpuid_eax(0x80000001);
- model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- if ((model >= 0x8) || fam15h)
- /* Revision D or later */
- rev_gte_d = 1;
-
- return rev_gte_d;
-}
-
-/***************************************************************************//**
- *
- * SBDFO
- * makeLinkBase(u8 currentNode, u8 currentLink)
- *
- * Description:
- * Private to northbridge implementation. Return the HT Host capability base
- * PCI config address for a link.
- *
- * Parameters:
- * @param[in] node = the node this link is on
- * @param[in] link = the link
- *
- *****************************************************************************/
-static SBDFO makeLinkBase(u8 node, u8 link)
-{
- SBDFO linkBase;
-
- /* With rev F can not be called with a 4th link or with the sublinks */
- if (link < 4)
- linkBase = MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_HT_CAP_BASE_0X80 + link*HT_HOST_CAP_SIZE);
- else
- linkBase = MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_04,
- REG_HT_CAP_BASE_0X80 + (link-4)*HT_HOST_CAP_SIZE);
- return linkBase;
-}
-
-/***************************************************************************//**
- *
- * void
- * setHtControlRegisterBits(SBDFO reg, u8 hiBit, u8 loBit, u32 *pValue)
- *
- * Description:
- * Private to northbridge implementation. Provide a common routine for accessing the
- * HT Link Control registers (84, a4, c4, e4), to enforce not clearing the
- * HT CRC error bits. Replaces direct use of AmdPCIWriteBits().
- * NOTE: This routine is called for IO Devices as well as CPUs!
- *
- * Parameters:
- * @param[in] reg = the PCI config address the control register
- * @param[in] hiBit = the high bit number
- * @param[in] loBit = the low bit number
- * @param[in] pValue = the value to write to that bit range. Bit 0 => loBit.
- *
- *****************************************************************************/
-static void setHtControlRegisterBits(SBDFO reg, u8 hiBit, u8 loBit, u32 *pValue)
-{
- u32 temp, mask;
-
- ASSERT((hiBit < 32) && (loBit < 32) && (hiBit >= loBit) && ((reg & 0x3) == 0));
- ASSERT((hiBit < 8) || (loBit > 9));
-
- /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
- if ((hiBit-loBit) != 31)
- mask = (((u32)1 << (hiBit-loBit+1))-1);
- else
- mask = (u32)0xFFFFFFFF;
-
- AmdPCIRead(reg, &temp);
- temp &= ~(mask << loBit);
- temp |= (*pValue & mask) << loBit;
- temp &= (u32)HT_CONTROL_CLEAR_CRC;
- AmdPCIWrite(reg, &temp);
-}
-
-/***************************************************************************//**
- *
- * static void
- * writeRoutingTable(u8 node, u8 target, u8 Link, cNorthBridge *nb)
- *
- * Description:
- * This routine will modify the routing tables on the
- * SourceNode to cause it to route both request and response traffic to the
- * targetNode through the specified Link.
- *
- * NOTE: This routine is to be used for early discovery and initialization. The
- * final routing tables must be loaded some other way because this
- * routine does not address the issue of probes, or independent request
- * response paths.
- *
- * Parameters:
- * @param[in] node = the node that will have it's routing tables modified.
- * @param[in] target = For routing to node target
- * @param[in] link = Link from node to target
- * @param[in] *nb = this northbridge
- *
- *****************************************************************************/
-
-static void writeRoutingTable(u8 node, u8 target, u8 link, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 temp = (nb->selfRouteResponseMask | nb->selfRouteRequestMask) << (link + 1);
- ASSERT((node < nb->maxNodes) && (target < nb->maxNodes) && (link < nb->maxLinks));
- AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_ROUTE0_0X40 + target*4),
- &temp);
-#else
- STOP_HERE;
-#endif
-}
-
-/***************************************************************************//**
- *
- * static void
- * writeNodeID(u8 node, u8 nodeID, cNorthBridge *nb)
- *
- * Description:
- * Modifies the NodeID register on the target node
- *
- * Parameters:
- * @param[in] node = the node that will have its NodeID altered.
- * @param[in] nodeID = the new value for NodeID
- * @param[in] *nb = this northbridge
- *
- *****************************************************************************/
-
-static void writeNodeID(u8 node, u8 nodeID, cNorthBridge *nb)
-{
- u32 temp;
- ASSERT((node < nb->maxNodes) && (nodeID < nb->maxNodes));
- if (is_fam15h()) {
- temp = 1;
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NORTHBRIDGE_CFG_3X8C),
- 22, 22, &temp);
- }
- temp = nodeID;
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_NODE_ID_0X60),
- 2, 0, &temp);
-}
-
-/***************************************************************************//**
- *
- * static void
- * readDefLnk(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Read the DefLnk (the source link of the current packet)
- * from node
- *
- * Parameters:
- * @param[in] node = the node that will have its NodeID altered.
- * @param[in] *nb = this northbridge
- * @return The HyperTransport link where the request to
- * read the default link came from. Since this
- * code is running on the BSP, this should be the link
- * pointing back towards the BSP.
- *
- *****************************************************************************/
-
-static u8 readDefLnk(u8 node, cNorthBridge *nb)
-{
- u32 deflink = 0;
- SBDFO licr;
- u32 temp;
-
- licr = MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_LINK_INIT_CONTROL_0X6C);
-
- ASSERT((node < nb->maxNodes));
- AmdPCIReadBits(licr, 3, 2, &deflink);
- AmdPCIReadBits(licr, 8, 8, &temp); /* on rev F, this bit is reserved == 0 */
- deflink |= temp << 2;
- return (u8)deflink;
-}
-
-/***************************************************************************//**
- *
- * static void
- * enableRoutingTables(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Turns routing tables on for a given node
- *
- * Parameters:
- * @param[in] node = the node that will have it's routing tables enabled
- * @param[in] *nb = this northbridge
- *
- *****************************************************************************/
-
-static void enableRoutingTables(u8 node, cNorthBridge *nb)
-{
- u32 temp = 0;
- ASSERT((node < nb->maxNodes));
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_LINK_INIT_CONTROL_0X6C),
- 0, 0, &temp);
-}
-
-
-/***************************************************************************//**
- *
- * static BOOL
- * verifyLinkIsCoherent(u8 node, u8 Link, cNorthBridge *nbk)
- *
- * Description:
- * Verify that the link is coherent, connected, and ready
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] link = the link on that Node to examine
- * @param[in] *nb = this northbridge
- * @return true - The link has the following status
- * linkCon = 1, Link is connected
- * InitComplete = 1, Link initialization is complete
- * NC = 0, Link is coherent
- * UniP-cLDT = 0, Link is not Uniprocessor cLDT
- * LinkConPend = 0 Link connection is not pending
- * false- The link has some other status
- *
- *****************************************************************************/
-
-static BOOL verifyLinkIsCoherent(u8 node, u8 link, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
-
- u32 linkType;
- SBDFO linkBase;
-
- ASSERT((node < nb->maxNodes) && (link < nb->maxLinks));
-
- linkBase = makeLinkBase(node, link);
-
- /* FN0_98/A4/C4 = LDT Type Register */
- AmdPCIRead(linkBase + HTHOST_LINK_TYPE_REG, &linkType);
-
- /* Verify LinkCon = 1, InitComplete = 1, NC = 0, UniP-cLDT = 0, LinkConPend = 0 */
- return (linkType & HTHOST_TYPE_MASK) == HTHOST_TYPE_COHERENT;
-#else
- return 0;
-#endif /* HT_BUILD_NC_ONLY */
-}
-
-/***************************************************************************//**
- *
- * static bool
- * readTrueLinkFailStatus(u8 node, u8 link, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Return the LinkFailed status AFTER an attempt is made to clear the bit.
- * Also, call event notify if a Hardware Fault caused a synch flood on a previous boot.
- *
- * The table below summarizes correct responses of this routine.
- * Family before after unconnected Notify? return
- * 0F 0 0 0 No 0
- * 0F 1 0 0 Yes 0
- * 0F 1 1 X No 1
- * 10 0 0 0 No 0
- * 10 1 0 0 Yes 0
- * 10 1 0 3 No 1
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] link = the link on that node to examine
- * @param[in] *pDat = access to call back routine
- * @param[in] *nb = this northbridge
- * @return true - the link is not connected or has hard error
- * false- if the link is connected
- *
- *****************************************************************************/
-
-static BOOL readTrueLinkFailStatus(u8 node, u8 link, sMainData *pDat, cNorthBridge *nb)
-{
- u32 before, after, unconnected, crc;
- SBDFO linkBase;
-
- ASSERT((node < nb->maxNodes) && (link < nb->maxLinks));
-
- linkBase = makeLinkBase(node, link);
-
- /* Save the CRC status before doing anything else.
- * Read, Clear, the Re-read the error bits in the Link Control Register
- * FN0_84/A4/C4[4] = LinkFail bit
- * and the connection status, TransOff and EndOfChain
- */
- AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 9, 8, &crc);
- AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 4, 4, &before);
- setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 4, 4, &before);
- AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 4, 4, &after);
- AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 7, 6, &unconnected);
-
- if (before != after)
- {
- if (!unconnected)
- {
- if (crc != 0)
- {
- /* A synch flood occurred due to HT CRC */
- if (pDat->HtBlock->AMD_CB_EventNotify)
- {
- /* Pass the node and link on which the generic synch flood event occurred. */
- sHtEventHWHtCrc evt;
- evt.eSize = sizeof(sHtEventHWHtCrc);
- evt.node = node;
- evt.link = link;
- evt.laneMask = (uint8)crc;
-
- pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_HW_FAULT,
- HT_EVENT_HW_HTCRC,
- (u8 *)&evt);
- }
- }
- else
- {
- /* Some synch flood occurred */
- if (pDat->HtBlock->AMD_CB_EventNotify)
- {
- /* Pass the node and link on which the generic synch flood event occurred. */
- sHtEventHWSynchFlood evt;
- evt.eSize = sizeof(sHtEventHWSynchFlood);
- evt.node = node;
- evt.link = link;
-
- pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_HW_FAULT,
- HT_EVENT_HW_SYNCHFLOOD,
- (u8 *)&evt);
- }
- }
- }
- }
- return ((after != 0) || unconnected);
-}
-
-
-/***************************************************************************//**
- *
- * static u8
- * readToken(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Read the token stored in the scratchpad register
- * NOTE: The location used to store the token is arbitrary. The only
- * requirement is that the location warm resets to zero, and that
- * using it will have no ill-effects during HyperTransport initialization.
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] *nb = this northbridge
- * @return the Token read from the node
- *
- *****************************************************************************/
-static u8 readToken(u8 node, cNorthBridge *nb)
-{
- u32 temp;
-
- ASSERT((node < nb->maxNodes));
- /* Use CpuCnt as a scratch register */
- /* Limiting use to 4 bits makes code GH to rev F compatible. */
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_NODE_ID_0X60),
- 19, 16, &temp);
-
- return (u8)temp;
-}
-
-
-/***************************************************************************//**
- *
- * static void
- * writeToken(u8 node, u8 Value, cNorthBridge *nb)
- *
- * Description:
- * Write the token stored in the scratchpad register
- * NOTE: The location used to store the token is arbitrary. The only
- * requirement is that the location warm resets to zero, and that
- * using it will have no ill-effects during HyperTransport initialization.
- * Limiting use to 4 bits makes code GH to rev F compatible.
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param value
- * @param[in] *nb = this northbridge
- *
- *****************************************************************************/
-static void writeToken(u8 node, u8 value, cNorthBridge *nb)
-{
- u32 temp = value;
- ASSERT((node < nb->maxNodes));
- /* Use CpuCnt as a scratch register */
- /* Limiting use to 4 bits makes code GH to rev F compatible. */
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_NODE_ID_0X60),
- 19, 16, &temp);
-}
-
-/***************************************************************************//**
- *
- * static u8
- * fam0FGetNumCoresOnNode(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Return the number of cores (1 based count) on node.
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] *nb = this northbridge
- * @return = the number of cores
- *
- * ---------------------------------------------------------------------------------------
- */
-static u8 fam0FGetNumCoresOnNode(u8 node, cNorthBridge *nb)
-{
- u32 temp;
-
- ASSERT((node < nb->maxNodes));
- /* Read CmpCap */
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CAPABILITY_3XE8),
- 13, 12, &temp);
-
- /* and add one */
- return (u8)(temp+1);
-}
-
-/***************************************************************************//**
- *
- * static u8
- * fam10GetNumCoresOnNode(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Return the number of cores (1 based count) on node.
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] *nb = this northbridge
- * @return = the number of cores
- *
- *
- */
-static u8 fam10GetNumCoresOnNode(u8 node, cNorthBridge *nb)
-{
- u32 temp, leveling, cores;
- u8 i;
-
- ASSERT((node < nb->maxNodes));
- /* Read CmpCap [2][1:0] */
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CAPABILITY_3XE8),
- 15, 12, &temp);
-
- /* bits[15,13,12] specify the cores */
- temp = ((temp & 8) >> 1) + (temp & 3);
- cores = temp + 1;
-
- /* Support Downcoring */
- AmdPCIReadBits (MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_DOWNCORE_3X190),
- 3, 0, &leveling);
- for (i = 0; i < cores; i++)
- {
- if (leveling & ((u32) 1 << i))
- {
- temp--;
- }
- }
- return (u8)(temp+1);
-}
-
-/***************************************************************************//**
- *
- * static u8
- * fam15GetNumCoresOnNode(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Return the number of cores (1 based count) on node.
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] *nb = this northbridge
- * @return = the number of cores
- *
- *
- */
-static u8 fam15GetNumCoresOnNode(u8 node, cNorthBridge *nb)
-{
- u32 temp, leveling, cores;
- u8 i;
-
- ASSERT((node < nb->maxNodes));
- /* Read CmpCap [7:0] */
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_05,
- REG_NB_CAPABILITY_5X84),
- 7, 0, &temp);
-
- /* bits[7:0] specify the cores */
- temp = temp & 0xff;
- cores = temp + 1;
-
- /* Support Downcoring */
- AmdPCIReadBits (MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_DOWNCORE_3X190),
- 31, 0, &leveling);
- for (i = 0; i < cores; i++)
- {
- if (leveling & ((u32) 1 << i))
- {
- temp--;
- }
- }
- return (u8)(temp+1);
-}
-
-/***************************************************************************//**
- *
- * static void
- * setTotalNodesAndCores(u8 node, u8 totalNodes, u8 totalCores, cNorthBridge *nb)
- *
- * Description:
- * Write the total number of cores and nodes to the node
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] totalNodes = the total number of nodes
- * @param[in] totalCores = the total number of cores
- * @param[in] *nb = this northbridge
- *
- * ---------------------------------------------------------------------------------------
- */
-static void setTotalNodesAndCores(u8 node, u8 totalNodes, u8 totalCores, cNorthBridge *nb)
-{
- SBDFO nodeIDReg;
- u32 temp;
-
- ASSERT((node < nb->maxNodes) && (totalNodes <= nb->maxNodes));
- nodeIDReg = MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_NODE_ID_0X60);
-
- temp = totalCores-1;
- /* Rely on max number of nodes:cores for rev F and GH to make
- * this code work, even though we write reserved bit 20 on rev F it will be
- * zero in that case.
- */
- AmdPCIWriteBits(nodeIDReg, 20, 16, &temp);
- temp = totalNodes-1;
- AmdPCIWriteBits(nodeIDReg, 6, 4, &temp);
-}
-
-/***************************************************************************//**
- *
- * static void
- * limitNodes(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Limit coherent config accesses to cpus as indicated by nodecnt.
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] *nb = this northbridge
- *
- * ---------------------------------------------------------------------------------------
- */
-static void limitNodes(u8 node, cNorthBridge *nb)
-{
- u32 temp = 1;
- ASSERT((node < nb->maxNodes));
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_LINK_TRANS_CONTROL_0X68),
- 15, 15, &temp);
-}
-
-/***************************************************************************//**
- *
- * static void
- * writeFullRoutingTable(u8 node, u8 target, u8 reqLink, u8 rspLink, u32 BClinks, cNorthBridge *nb)
- *
- * Description:
- * Write the routing table entry for node to target, using the request link, response
- * link, and broadcast links provided.
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] target = the target node for these routes
- * @param[in] reqLink = the link for requests to target
- * @param[in] rspLink = the link for responses to target
- * @param[in] bClinks = the broadcast links
- * @param[in] *nb = this northbridge
- *
- * ---------------------------------------------------------------------------------------
- */
-static void writeFullRoutingTable(u8 node, u8 target, u8 reqLink, u8 rspLink, u32 bClinks, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 value = 0;
-
- ASSERT((node < nb->maxNodes) && (target < nb->maxNodes));
- if (reqLink == ROUTETOSELF)
- value |= nb->selfRouteRequestMask;
- else
- value |= nb->selfRouteRequestMask << (reqLink+1);
-
- if (rspLink == ROUTETOSELF)
- value |= nb->selfRouteResponseMask;
- else
- value |= nb->selfRouteResponseMask << (rspLink+1);
-
- /* Allow us to accept a Broadcast ourselves, then set broadcasts for routes */
- value |= (u32)1 << nb->broadcastSelfBit;
- value |= (u32)bClinks << (nb->broadcastSelfBit + 1);
-
- AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_HTNB_FUNC_00,
- REG_ROUTE0_0X40 + target*4), &value);
-#else
- STOP_HERE;
-#endif /* HT_BUILD_NC_ONLY */
-}
-
-/***************************************************************************//**
- *
- * static u32
- * makeKey(u8 currentNode)
- *
- * Description:
- * Private routine to northbridge code.
- * Determine whether a node is compatible with the discovered configuration so
- * far. Currently, that means the family, extended family of the new node are the
- * same as the BSP's.
- *
- * Parameters:
- * @param[in] node = the node
- * @return = the key value
- *
- * ---------------------------------------------------------------------------------------
- */
-static u32 makeKey(u8 node)
-{
- u32 extFam, baseFam;
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CPUID_3XFC),
- 27, 20, &extFam);
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CPUID_3XFC),
- 11, 8, &baseFam);
- return ((u32)(baseFam << 8) | extFam);
-}
-
-
-/***************************************************************************//**
- *
- * static BOOL
- * isCompatible(u8 currentNode, cNorthBridge *nb)
- *
- * Description:
- * Determine whether a node is compatible with the discovered configuration so
- * far. Currently, that means the family, extended family of the new node are the
- * same as the BSP's.
- *
- * Parameters:
- * @param[in] node = the node
- * @param[in] *nb = this northbridge
- * @return = true: the new is compatible, false: it is not
- *
- * ---------------------------------------------------------------------------------------
- */
-static BOOL isCompatible(u8 node, cNorthBridge *nb)
-{
- return (makeKey(node) == nb->compatibleKey);
-}
-
-/***************************************************************************//**
- *
- * static BOOL
- * fam0fIsCapable(u8 node, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Get node capability and update the minimum supported system capability.
- * Return whether the current configuration exceeds the capability.
- *
- * Parameters:
- * @param[in] node = the node
- * @param[in,out] *pDat = sysMpCap (updated) and NodesDiscovered
- * @param[in] *nb = this northbridge
- * @return true: system is capable of current config.
- * false: system is not capable of current config.
- *
- * ---------------------------------------------------------------------------------------
- */
-static BOOL fam0fIsCapable(u8 node, sMainData *pDat, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 temp;
- u8 maxNodes;
-
- ASSERT(node < nb->maxNodes);
-
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CAPABILITY_3XE8),
- 2, 1, &temp);
- if (temp > 1)
- {
- maxNodes = 8;
- } else {
- if (temp == 1)
- {
- maxNodes = 2;
- } else {
- maxNodes = 1;
- }
- }
- if (pDat->sysMpCap > maxNodes)
- {
- pDat->sysMpCap = maxNodes;
- }
- /* Note since sysMpCap is one based and NodesDiscovered is zero based, equal is false */
- return (pDat->sysMpCap > pDat->NodesDiscovered);
-#else
- return 1;
-#endif
-}
-
-/***************************************************************************//**
- *
- * static BOOL
- * fam10IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Get node capability and update the minimum supported system capability.
- * Return whether the current configuration exceeds the capability.
- *
- * Parameters:
- * @param[in] node = the node
- * @param[in,out] *pDat = sysMpCap (updated) and NodesDiscovered
- * @param[in] *nb = this northbridge
- * @return true: system is capable of current config.
- * false: system is not capable of current config.
- *
- * ---------------------------------------------------------------------------------------
- */
-static BOOL fam10IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 temp;
- u8 maxNodes;
-
- ASSERT(node < nb->maxNodes);
-
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CAPABILITY_3XE8),
- 18, 16, &temp);
-
- if (temp != 0)
- {
- maxNodes = (1 << (~temp & 0x3)); /* That is, 1, 2, 4, or 8 */
- }
- else
- {
- maxNodes = 8;
- }
-
- if (pDat->sysMpCap > maxNodes)
- {
- pDat->sysMpCap = maxNodes;
- }
- /* Note since sysMpCap is one based and NodesDiscovered is zero based, equal is false */
- return (pDat->sysMpCap > pDat->NodesDiscovered);
-#else
- return 1;
-#endif
-}
-
-/***************************************************************************//**
- *
- * static BOOL
- * fam15IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Get node capability and update the minimum supported system capability.
- * Return whether the current configuration exceeds the capability.
- *
- * Parameters:
- * @param[in] node = the node
- * @param[in,out] *pDat = sysMpCap (updated) and NodesDiscovered
- * @param[in] *nb = this northbridge
- * @return true: system is capable of current config.
- * false: system is not capable of current config.
- *
- * ---------------------------------------------------------------------------------------
- */
-static BOOL fam15IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 temp;
- u8 maxNodes;
-
- ASSERT(node < nb->maxNodes);
-
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CAPABILITY_3XE8),
- 18, 16, &temp);
-
- if (temp != 0)
- {
- maxNodes = (1 << (~temp & 0x3)); /* That is, 1, 2, 4, or 8 */
- }
- else
- {
- /* Check if CPU package is dual node */
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CAPABILITY_3XE8),
- 29, 29, &temp);
- if (temp)
- maxNodes = 4;
- else
- maxNodes = 8;
- }
-
- if (pDat->sysMpCap > maxNodes)
- {
- pDat->sysMpCap = maxNodes;
- }
- /* Note since sysMpCap is one based and NodesDiscovered is zero based, equal is false */
- return (pDat->sysMpCap > pDat->NodesDiscovered);
-#else
- return 1;
-#endif
-}
-
-/***************************************************************************//**
- *
- * static void
- * fam0fStopLink(u8 currentNode, u8 currentLink, cNorthBridge *nb)
- *
- * Description:
- * Disable a cHT link on node by setting F0x[E4, C4, A4, 84][TransOff, EndOfChain]=1
- *
- * Parameters:
- * @param[in] node = the node this link is on
- * @param[in] link = the link to stop
- * @param[in] *nb = this northbridge
- *
- * ---------------------------------------------------------------------------------------
- */
-static void fam0fStopLink(u8 node, u8 link, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 temp;
- SBDFO linkBase;
-
- ASSERT((node < nb->maxNodes) && (link < nb->maxLinks));
-
- linkBase = makeLinkBase(node, link);
-
- /* Set TransOff, EndOfChain */
- temp = 3;
- setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 7, 6, &temp);
-#endif
-}
-
-/***************************************************************************//**
- *
- * static void
- * commonVoid()
- *
- * Description:
- * Nothing.
- *
- * Parameters:
- * None.
- *
- * ---------------------------------------------------------------------------------------
- */
-static void commonVoid(void)
-{
-}
-
-/***************************************************************************//**
- *
- * static BOOL
- * commonReturnFalse()
- *
- * Description:
- * Return False.
- *
- * Parameters:
- * @return = false
- *
- */
-static BOOL commonReturnFalse(void)
-{
- return 0;
-}
-
-/***************************************************************************
- *** Non-coherent init code ***
- *** Northbridge access routines ***
- ***************************************************************************/
-
-/***************************************************************************//**
- *
- * static u8
- * readSbLink(cNorthBridge *nb)
- *
- * Description:
- * Return the link to the Southbridge
- *
- * Parameters:
- * @param[in] *nb = this northbridge
- * @return the link to the southbridge
- *
- * ---------------------------------------------------------------------------------------
- */
-static u8 readSbLink(cNorthBridge *nb)
-{
- u32 temp;
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(0),
- makePCIBusFromNode(0),
- makePCIDeviceFromNode(0),
- CPU_HTNB_FUNC_00,
- REG_UNIT_ID_0X64),
- 10, 8, &temp);
- return (u8)temp;
-}
-
-/***************************************************************************//**
- *
- * static BOOL
- * verifyLinkIsNonCoherent(u8 node, u8 link, cNorthBridge *nb)
- *
- * Description:
- * Verify that the link is non-coherent, connected, and ready
- *
- * Parameters:
- * @param[in] node = the node that will be examined
- * @param[in] link = the Link on that node to examine
- * @param[in] *nb = this northbridge
- * @return = true - The link has the following status
- * LinkCon = 1, Link is connected
- * InitComplete = 1,Link initialization is complete
- * NC = 1, Link is coherent
- * UniP-cLDT = 0, Link is not Uniprocessor cLDT
- * LinkConPend = 0 Link connection is not pending
- * false- The link has some other status
- *
- * ---------------------------------------------------------------------------------------
- */
-static BOOL verifyLinkIsNonCoherent(u8 node, u8 link, cNorthBridge *nb)
-{
- u32 linkType;
- SBDFO linkBase;
-
- ASSERT((node < nb->maxNodes) && (link < nb->maxLinks));
-
- linkBase = makeLinkBase(node, link);
-
- /* FN0_98/A4/C4 = LDT Type Register */
- AmdPCIRead(linkBase + HTHOST_LINK_TYPE_REG, &linkType);
-
- /* Verify linkCon = 1, InitComplete = 1, NC = 0, UniP-cLDT = 0, LinkConPend = 0 */
- return (linkType & HTHOST_TYPE_MASK) == HTHOST_TYPE_NONCOHERENT;
-}
-
-/***************************************************************************//**
- *
- * static void
- * ht3SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Configure and enable config access to a non-coherent chain for the given bus range.
- *
- * Parameters:
- * @param[in] cfgMapIndex = the map entry to set
- * @param[in] secBus = The secondary bus number to use
- * @param[in] subBus = The subordinate bus number to use
- * @param[in] targetNode = The node that shall be the recipient of the traffic
- * @param[in] targetLink = The link that shall be the recipient of the traffic
- * @param[in] pDat = our global state
- * @param[in] *nb = this northbridge
- *
- * ---------------------------------------------------------------------------------------
- */
-static void ht3SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb)
-{
- u8 curNode;
- SBDFO linkBase;
- u32 temp;
-
- linkBase = makeLinkBase(targetNode, targetLink);
-
- ASSERT(secBus <= subBus);
- temp = secBus;
- AmdPCIWriteBits(linkBase + HTHOST_ISOC_REG, 15, 8, &temp);
-
- /* For target link, note that rev F uses bits 9:8 and only with GH is bit 10
- * set to indicate a sublink. For node, we are currently not supporting Extended
- * routing tables.
- */
- temp = ((u32)subBus << 24) + ((u32)secBus << 16) + ((u32)targetLink << 8)
- + ((u32)targetNode << 4) + (u32)3;
- for (curNode = 0; curNode < pDat->NodesDiscovered+1; curNode++)
- AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(curNode),
- makePCIBusFromNode(curNode),
- makePCIDeviceFromNode(curNode),
- CPU_ADDR_FUNC_01,
- REG_ADDR_CONFIG_MAP0_1XE0 + 4*cfgMapIndex),
- &temp);
-}
-
-/***************************************************************************//**
- *
- * static void
- * ht1SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Configure and enable config access to a non-coherent chain for the given bus range.
- *
- * Parameters:
- * @param[in] cfgMapIndex = the map entry to set
- * @param[in] secBus = The secondary bus number to use
- * @param[in] subBus = The subordinate bus number to use
- * @param[in] targetNode = The node that shall be the recipient of the traffic
- * @param[in] targetLink = The link that shall be the recipient of the traffic
- * @param[in] pDat = our global state
- * @param[in] *nb = this northbridge
- *
- ******************************************************************************/
-static void ht1SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb)
-{
- u8 curNode;
- SBDFO linkBase;
- u32 temp;
-
- linkBase = makeLinkBase(targetNode, targetLink);
-
- ASSERT(secBus <= subBus);
- temp = secBus;
- AmdPCIWriteBits(linkBase + HTHOST_ISOC_REG, 15, 8, &temp);
-
- temp = subBus;
- AmdPCIWriteBits(linkBase + HTHOST_ISOC_REG, 23, 16, &temp);
-
- /* For target link, note that rev F uses bits 9:8 and only with GH is bit 10
- * set to indicate a sublink. For node, we are currently not supporting Extended
- * routing tables.
- */
- temp = ((u32)subBus << 24) + ((u32)secBus << 16) + ((u32)targetLink << 8)
- + ((u32)targetNode << 4) + (u32)3;
- for (curNode = 0; curNode < pDat->NodesDiscovered+1; curNode++)
- AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(curNode),
- makePCIBusFromNode(curNode),
- makePCIDeviceFromNode(curNode),
- CPU_ADDR_FUNC_01,
- REG_ADDR_CONFIG_MAP0_1XE0 + 4*cfgMapIndex),
- &temp);
-}
-
-/***************************************************************************
- *** Link Optimization ***
- ***************************************************************************/
-
-/**
- * static u8
- * convertBitsToWidth(u8 value, cNorthBridge *nb)
- *
- * Description:
- * Given the bits set in the register field, return the width it represents
- *
- * Parameters:
- * @param[in] value = The bits for the register
- * @param[in] *nb = this northbridge
- * @return The width
- *
- ******************************************************************************/
-static u8 convertBitsToWidth(u8 value, cNorthBridge *nb)
-{
- switch (value) {
- case 1: return 16;
- case 0: return 8;
- case 5: return 4;
- case 4: return 2;
- default: STOP_HERE; /* This is an error internal condition */
- }
- return 0; // shut up GCC.
-}
-
-/***************************************************************************//**
- *
- * static u8
- * convertWidthToBits(u8 value, cNorthBridge *nb)
- *
- * Description:
- * Translate a desired width setting to the bits to set in the register field
- *
- * Parameters:
- * @param[in] value = The width
- * @param[in] *nb = this northbridge
- * @return The bits for the register
- *
- ******************************************************************************/
-static u8 convertWidthToBits(u8 value, cNorthBridge *nb)
-{
- switch (value) {
- case 16: return 1;
- case 8: return 0;
- case 4: return 5;
- case 2: return 4;
- default: STOP_HERE; /* This is an internal error condition */
- }
- return 0; // shut up GCC
-}
-
-/***************************************************************************//**
- *
- * static u16
- * ht1NorthBridgeFreqMask(u8 NodeID, cNorthBridge *nb)
- *
- * Description:
- * Return a mask that eliminates HT frequencies that cannot be used due to a slow
- * northbridge frequency.
- *
- * Parameters:
- * @param[in] node = Result could (later) be for a specific node
- * @param[in] *nb = this northbridge
- * @return Frequency mask
- *
- ******************************************************************************/
-static uint32_t ht1NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
-{
- /* only up to HT1 speeds */
- return (HT_FREQUENCY_LIMIT_HT1_ONLY);
-}
-
-/***************************************************************************//**
- *
- * static u16
- * fam10NorthBridgeFreqMask(u8 NodeID, cNorthBridge *nb)
- *
- * Description:
- * Return a mask that eliminates HT frequencies that cannot be used due to a slow
- * northbridge frequency.
- *
- * Parameters:
- * @param[in] node = Result could (later) be for a specific node
- * @param[in] *nb = this northbridge
- * @return = Frequency mask
- *
- ******************************************************************************/
-static uint32_t fam10NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
-{
- u8 nbCOF;
- uint32_t supported;
-
- nbCOF = getMinNbCOF();
- /*
- * nbCOF is minimum northbridge speed in hundreds of MHz.
- * HT can not go faster than the minimum speed of the northbridge.
- */
- if ((nbCOF >= 6) && (nbCOF < 10))
- {
- /* Generation 1 HT link frequency */
- /* Convert frequency to bit and all less significant bits,
- * by setting next power of 2 and subtracting 1.
- */
- supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1;
- }
- else if ((nbCOF >= 10) && (nbCOF <= 32))
- {
- /* Generation 3 HT link frequency
- * Assume error retry is enabled on all Gen 3 links
- */
- if (is_gt_rev_d()) {
- nbCOF *= 2;
- if (nbCOF > 32)
- nbCOF = 32;
- }
-
- /* Convert frequency to bit and all less significant bits,
- * by setting next power of 2 and subtracting 1.
- */
- supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1;
- }
- else if (nbCOF > 32)
- {
- supported = HT_FREQUENCY_LIMIT_3200M;
- }
- /* unlikely cases, but include as a defensive measure, also avoid trick above */
- else if (nbCOF == 4)
- {
- supported = HT_FREQUENCY_LIMIT_400M;
- }
- else if (nbCOF == 2)
- {
- supported = HT_FREQUENCY_LIMIT_200M;
- }
- else
- {
- STOP_HERE;
- supported = HT_FREQUENCY_LIMIT_200M;
- }
-
- return (fixEarlySampleFreqCapability(supported));
-}
-
-/***************************************************************************//**
- *
- * static u16
- * fam15NorthBridgeFreqMask(u8 NodeID, cNorthBridge *nb)
- *
- * Description:
- * Return a mask that eliminates HT frequencies that cannot be used due to a slow
- * northbridge frequency.
- *
- * Parameters:
- * @param[in] node = Result could (later) be for a specific node
- * @param[in] *nb = this northbridge
- * @return = Frequency mask
- *
- ******************************************************************************/
-static uint32_t fam15NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
-{
- u8 nbCOF;
- uint32_t supported;
-
- nbCOF = getMinNbCOF();
- /*
- * nbCOF is minimum northbridge speed in hundreds of MHz.
- * HT can not go faster than the minimum speed of the northbridge.
- */
- if ((nbCOF >= 6) && (nbCOF < 10))
- {
- /* Generation 1 HT link frequency */
- /* Convert frequency to bit and all less significant bits,
- * by setting next power of 2 and subtracting 1.
- */
- supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1;
- }
- else if ((nbCOF >= 10) && (nbCOF <= 32))
- {
- /* Generation 3 HT link frequency
- * Assume error retry is enabled on all Gen 3 links
- */
- nbCOF *= 2;
- if (nbCOF > 32)
- nbCOF = 32;
-
- /* Convert frequency to bit and all less significant bits,
- * by setting next power of 2 and subtracting 1.
- */
- supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1;
- }
- else if (nbCOF > 32)
- {
- supported = HT_FREQUENCY_LIMIT_3200M;
- }
- /* unlikely cases, but include as a defensive measure, also avoid trick above */
- else if (nbCOF == 4)
- {
- supported = HT_FREQUENCY_LIMIT_400M;
- }
- else if (nbCOF == 2)
- {
- supported = HT_FREQUENCY_LIMIT_200M;
- }
- else
- {
- STOP_HERE;
- supported = HT_FREQUENCY_LIMIT_200M;
- }
-
- return (fixEarlySampleFreqCapability(supported));
-}
-
-/***************************************************************************//**
- *
- * static void
- * gatherLinkData(sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * For all discovered links, populate the port list with the frequency and width
- * capabilities.
- *
- * Parameters:
- * @param[in,out] pDat = our global state, port list
- * @param[in] *nb = this northbridge
- *
- ******************************************************************************/
-static void gatherLinkData(sMainData *pDat, cNorthBridge *nb)
-{
- u8 i;
- SBDFO linkBase;
- u32 temp;
-
- for (i = 0; i < pDat->TotalLinks*2; i++)
- {
- if (pDat->PortList[i].Type == PORTLIST_TYPE_CPU)
- {
- linkBase = makeLinkBase(pDat->PortList[i].NodeID, pDat->PortList[i].Link);
-
- pDat->PortList[i].Pointer = linkBase;
-
- AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 22, 20, &temp);
- pDat->PortList[i].PrvWidthOutCap = convertBitsToWidth((u8)temp, pDat->nb);
-
- AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 18, 16, &temp);
- pDat->PortList[i].PrvWidthInCap = convertBitsToWidth((u8)temp, pDat->nb);
-
- AmdPCIReadBits(linkBase + HTHOST_FREQ_REV_REG, 31, 16, &temp);
- pDat->PortList[i].PrvFrequencyCap = temp & 0x7FFF /* Mask off bit 15, reserved value */
- & nb->northBridgeFreqMask(pDat->PortList[i].NodeID, pDat->nb);
- if (is_gt_rev_d()) {
- AmdPCIReadBits(linkBase + HTHOST_FREQ_REV_REG_2, 15, 1, &temp);
- temp &= 0x7; /* Mask off reserved values */
- pDat->PortList[i].PrvFrequencyCap |= (temp << 17);
- }
-
- AmdPCIReadBits(linkBase + HTHOST_FEATURE_CAP_REG, 9, 0, &temp);
- pDat->PortList[i].PrvFeatureCap = (u16)temp;
- }
- else
- {
- linkBase = pDat->PortList[i].Pointer;
- if (pDat->PortList[i].Link == 1)
- linkBase += HTSLAVE_LINK01_OFFSET;
-
- AmdPCIReadBits(linkBase + HTSLAVE_LINK_CONTROL_0_REG, 22, 20, &temp);
- pDat->PortList[i].PrvWidthOutCap = convertBitsToWidth((u8)temp, pDat->nb);
-
- AmdPCIReadBits(linkBase + HTSLAVE_LINK_CONTROL_0_REG, 18, 16, &temp);
- pDat->PortList[i].PrvWidthInCap = convertBitsToWidth((u8)temp, pDat->nb);
-
- AmdPCIReadBits(linkBase + HTSLAVE_FREQ_REV_0_REG, 31, 16, &temp);
- pDat->PortList[i].PrvFrequencyCap = (u16)temp;
-
- AmdPCIReadBits(linkBase + HTSLAVE_FEATURE_CAP_REG, 7, 0, &temp);
- pDat->PortList[i].PrvFeatureCap = (u16)temp;
-
- if (pDat->HtBlock->AMD_CB_DeviceCapOverride)
- {
- linkBase &= 0xFFFFF000;
- AmdPCIRead(linkBase, &temp);
-
- pDat->HtBlock->AMD_CB_DeviceCapOverride(
- pDat->PortList[i].NodeID,
- pDat->PortList[i].HostLink,
- pDat->PortList[i].HostDepth,
- (u8)SBDFO_SEG(pDat->PortList[i].Pointer),
- (u8)SBDFO_BUS(pDat->PortList[i].Pointer),
- (u8)SBDFO_DEV(pDat->PortList[i].Pointer),
- temp,
- pDat->PortList[i].Link,
- &(pDat->PortList[i].PrvWidthInCap),
- &(pDat->PortList[i].PrvWidthOutCap),
- &(pDat->PortList[i].PrvFrequencyCap),
- &(pDat->PortList[i].PrvFeatureCap));
- }
- }
- }
-}
-
-/***************************************************************************//**
- *
- * static void
- * setLinkData(sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Change the hardware state for all links according to the now optimized data in the
- * port list data structure.
- *
- * Parameters:
- * @param[in] pDat = our global state, port list
- * @param[in] *nb = this northbridge
- *
- ******************************************************************************/
-static void setLinkData(sMainData *pDat, cNorthBridge *nb)
-{
- u8 i;
- SBDFO linkBase;
- u32 temp, temp2, frequency_index, widthin, widthout, bits;
-
- for (i = 0; i < pDat->TotalLinks*2; i++)
- {
-
- ASSERT(pDat->PortList[i&0xFE].SelWidthOut == pDat->PortList[(i&0xFE)+1].SelWidthIn);
- ASSERT(pDat->PortList[i&0xFE].SelWidthIn == pDat->PortList[(i&0xFE)+1].SelWidthOut);
- ASSERT(pDat->PortList[i&0xFE].SelFrequency == pDat->PortList[(i&0xFE)+1].SelFrequency);
-
- if (pDat->PortList[i].SelRegang)
- {
- ASSERT(pDat->PortList[i].Type == PORTLIST_TYPE_CPU);
- ASSERT(pDat->PortList[i].Link < 4);
- temp = 1;
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID),
- makePCIBusFromNode(pDat->PortList[i].NodeID),
- makePCIDeviceFromNode(pDat->PortList[i].NodeID),
- CPU_HTNB_FUNC_00,
- REG_HT_LINK_EXT_CONTROL0_0X170 + 4*pDat->PortList[i].Link),
- 0, 0, &temp);
- }
-
- if (pDat->PortList[i].Type == PORTLIST_TYPE_CPU)
- {
- if (pDat->HtBlock->AMD_CB_OverrideCpuPort)
- pDat->HtBlock->AMD_CB_OverrideCpuPort(pDat->PortList[i].NodeID,
- pDat->PortList[i].Link,
- &(pDat->PortList[i].SelWidthIn),
- &(pDat->PortList[i].SelWidthOut),
- &(pDat->PortList[i].SelFrequency));
- }
- else
- {
- if (pDat->HtBlock->AMD_CB_OverrideDevicePort)
- pDat->HtBlock->AMD_CB_OverrideDevicePort(pDat->PortList[i].NodeID,
- pDat->PortList[i].HostLink,
- pDat->PortList[i].HostDepth,
- pDat->PortList[i].Link,
- &(pDat->PortList[i].SelWidthIn),
- &(pDat->PortList[i].SelWidthOut),
- &(pDat->PortList[i].SelFrequency));
- }
-
- linkBase = pDat->PortList[i].Pointer;
- if ((pDat->PortList[i].Type == PORTLIST_TYPE_IO) && (pDat->PortList[i].Link == 1))
- linkBase += HTSLAVE_LINK01_OFFSET;
-
- /* Some IO devices don't work properly when setting widths, so write them in a single operation,
- * rather than individually.
- */
- widthout = convertWidthToBits(pDat->PortList[i].SelWidthOut, pDat->nb);
- ASSERT(widthout == 1 || widthout == 0 || widthout == 5 || widthout == 4);
- widthin = convertWidthToBits(pDat->PortList[i].SelWidthIn, pDat->nb);
- ASSERT(widthin == 1 || widthin == 0 || widthin == 5 || widthin == 4);
-
- temp = (widthin & 7) | ((widthout & 7) << 4);
- setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 31, 24, &temp);
-
- temp = pDat->PortList[i].SelFrequency;
- if (pDat->PortList[i].Type == PORTLIST_TYPE_CPU)
- {
- ASSERT((temp >= HT_FREQUENCY_600M && temp <= HT_FREQUENCY_3200M)
- || (temp == HT_FREQUENCY_200M) || (temp == HT_FREQUENCY_400M));
- frequency_index = temp;
- if (temp > 0xf) {
- temp2 = (temp >> 4) & 0x1;
- temp &= 0xf;
- } else {
- temp2 = 0x0;
- }
- /* NOTE
- * The Family 15h BKDG Rev. 3.14 is wrong
- * Freq[4] must be set before Freq[3:0], otherwise the register writes will be ignored!
- */
- if (is_gt_rev_d())
- AmdPCIWriteBits(linkBase + HTHOST_FREQ_REV_REG_2, 0, 0, &temp2);
- AmdPCIWriteBits(linkBase + HTHOST_FREQ_REV_REG, 11, 8, &temp);
-
- /* Enable isochronous flow control mode if supported by chipset */
- if (is_fam15h()) {
- if (pDat->PortList[i].enable_isochronous_mode)
- temp = 1;
- else
- temp = 0;
- setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 12, 12, &temp);
- }
-
- if (frequency_index > HT_FREQUENCY_1000M) /* Gen1 = 200MHz -> 1000MHz, Gen3 = 1200MHz -> 3200MHz */
- {
- /* Enable for Gen3 frequencies */
- temp = 1;
- }
- else
- {
- /* Disable for Gen1 frequencies */
- temp = 0;
- }
- /* HT3 retry mode enable / disable */
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID),
- makePCIBusFromNode(pDat->PortList[i].NodeID),
- makePCIDeviceFromNode(pDat->PortList[i].NodeID),
- CPU_HTNB_FUNC_00,
- REG_HT_LINK_RETRY0_0X130 + 4*pDat->PortList[i].Link),
- 0, 0, &temp);
-
- /* and Scrambling enable / disable */
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID),
- makePCIBusFromNode(pDat->PortList[i].NodeID),
- makePCIDeviceFromNode(pDat->PortList[i].NodeID),
- CPU_HTNB_FUNC_00,
- REG_HT_LINK_EXT_CONTROL0_0X170 + 4*pDat->PortList[i].Link),
- 3, 3, &temp);
- }
- else
- {
- SBDFO currentPtr;
- BOOL isFound;
-
- ASSERT(temp <= HT_FREQUENCY_3200M);
- /* Write the frequency setting */
- AmdPCIWriteBits(linkBase + HTSLAVE_FREQ_REV_0_REG, 11, 8, &temp);
-
- /* Handle additional HT3 frequency requirements, if needed,
- * or clear them if switching down to ht1 on a warm reset.
- * Gen1 = 200MHz -> 1000MHz, Gen3 = 1200MHz -> 2600MHz
- *
- * Even though we assert if debugging, we need to check that the capability was found
- * always, since this is an unknown hardware device, also we are taking
- * unqualified frequency from the call backs
- * (could be trying to do ht3 on an ht1 IO device).
- */
-
- if (temp > HT_FREQUENCY_1000M)
- {
- /* Enabling features if gen 3 */
- bits = 1;
- }
- else
- {
- /* Disabling features if gen 1 */
- bits = 0;
- }
-
- /* Enable isochronous flow control mode if supported by chipset */
- if (is_fam15h()) {
- if (pDat->PortList[i].enable_isochronous_mode)
- temp = 1;
- else
- temp = 0;
- }
-
- /* Retry Enable */
- isFound = FALSE;
- currentPtr = linkBase & (u32)0xFFFFF000; /* Set PCI Offset to 0 */
- do
- {
- AmdPCIFindNextCap(&currentPtr);
- if (currentPtr != ILLEGAL_SBDFO)
- {
- AmdPCIRead(currentPtr, &temp);
- /* HyperTransport Retry Capability? */
- if (IS_HT_RETRY_CAPABILITY(temp))
- {
- ASSERT(pDat->PortList[i].Link < 2);
- AmdPCIWriteBits(currentPtr + HTRETRY_CONTROL_REG,
- pDat->PortList[i].Link*16,
- pDat->PortList[i].Link*16,
- &bits);
- isFound = TRUE;
- }
- /* Some other capability, keep looking */
- }
- else
- {
- /* If we are turning it off, that may mean the device was only ht1 capable,
- * so don't complain that we can't do it.
- */
- if (bits != 0)
- {
- if (pDat->HtBlock->AMD_CB_EventNotify)
- {
- sHtEventOptRequiredCap evt;
- evt.eSize = sizeof(sHtEventOptRequiredCap);
- evt.node = pDat->PortList[i].NodeID;
- evt.link = pDat->PortList[i].HostLink;
- evt.depth = pDat->PortList[i].HostDepth;
-
- pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_WARNING,
- HT_EVENT_OPT_REQUIRED_CAP_RETRY,
- (u8 *)&evt);
- }
- STOP_HERE;
- }
- isFound = TRUE;
- }
- } while (!isFound);
-
- /* Scrambling enable */
- isFound = FALSE;
- currentPtr = linkBase & (u32)0xFFFFF000; /* Set PCI Offset to 0 */
- do
- {
- AmdPCIFindNextCap(&currentPtr);
- if (currentPtr != ILLEGAL_SBDFO)
- {
- AmdPCIRead(currentPtr, &temp);
- /* HyperTransport Gen3 Capability? */
- if (IS_HT_GEN3_CAPABILITY(temp))
- {
- ASSERT(pDat->PortList[i].Link < 2);
- AmdPCIWriteBits((currentPtr +
- HTGEN3_LINK_TRAINING_0_REG +
- pDat->PortList[i].Link*HTGEN3_LINK01_OFFSET),
- 3, 3, &bits);
- isFound = TRUE;
- }
- /* Some other capability, keep looking */
- }
- else
- {
- /* If we are turning it off, that may mean the device was only ht1 capable,
- * so don't complain that we can't do it.
- */
- if (bits != 0)
- {
- if (pDat->HtBlock->AMD_CB_EventNotify)
- {
- sHtEventOptRequiredCap evt;
- evt.eSize = sizeof(sHtEventOptRequiredCap);
- evt.node = pDat->PortList[i].NodeID;
- evt.link = pDat->PortList[i].HostLink;
- evt.depth = pDat->PortList[i].HostDepth;
-
- pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_WARNING,
- HT_EVENT_OPT_REQUIRED_CAP_GEN3,
- (u8 *)&evt);
- }
- STOP_HERE;
- }
- isFound = TRUE;
- }
- } while (!isFound);
- }
- }
-}
-
-/***************************************************************************//**
- *
- * void
- * fam0fWriteHTLinkCmdBufferAlloc(u8 node, u8 link, u8 req, u8 preq, u8 rsp, u8 prb)
- *
- * Description:
- * Set the command buffer allocations in the buffer count register for the node and link.
- * The command buffer settings in the low 16 bits are the same on both
- * family 10h and family 0fh northbridges.
- *
- * Parameters:
- * @param[in] node = The node to set allocations on
- * @param[in] link = the link to set allocations on
- * @param[in] req = non-posted Request Command Buffers
- * @param[in] preq = Posted Request Command Buffers
- * @param[in] rsp = Response Command Buffers
- * @param[in] prb = Probe Command Buffers
- *
- ******************************************************************************/
-#ifndef HT_BUILD_NC_ONLY
-
-static void fam0fWriteHTLinkCmdBufferAlloc(u8 node, u8 link, u8 req, u8 preq, u8 rsp, u8 prb)
-{
- u32 temp;
- SBDFO currentPtr;
-
- currentPtr = makeLinkBase(node, link);
- currentPtr += HTHOST_BUFFER_COUNT_REG;
-
- /* non-posted Request Command Buffers */
- temp = req;
- AmdPCIWriteBits(currentPtr, 3, 0, &temp);
- /* Posted Request Command Buffers */
- temp = preq;
- AmdPCIWriteBits(currentPtr, 7, 4, &temp);
- /* Response Command Buffers */
- temp = rsp;
- AmdPCIWriteBits(currentPtr, 11, 8, &temp);
- /* Probe Command Buffers */
- temp = prb;
- AmdPCIWriteBits(currentPtr, 15, 12, &temp);
- /* LockBc */
- temp = 1;
- AmdPCIWriteBits(currentPtr, 31, 31, &temp);
-}
-#endif /* HT_BUILD_NC_ONLY */
-
-/***************************************************************************//**
- *
- * void
- * fam0fWriteHTLinkDatBufferAlloc(u8 node, u8 link, u8 reqD, u8 preqD, u8 rspD)
- *
- * Description:
- * Set the data buffer allocations in the buffer count register for the node and link.
- * The command buffer settings in the high 16 bits are not the same on both
- * family 10h and family 0fh northbridges.
- *
- * Parameters:
- * @param[in] node = The node to set allocations on
- * @param[in] link = the link to set allocations on
- * @param[in] reqD = non-posted Request Data Buffers
- * @param[in] preqD = Posted Request Data Buffers
- * @param[in] rspD = Response Data Buffers
- *
- ******************************************************************************/
-#ifndef HT_BUILD_NC_ONLY
-
-static void fam0fWriteHTLinkDatBufferAlloc(u8 node, u8 link, u8 reqD, u8 preqD, u8 rspD)
-{
- u32 temp;
- SBDFO currentPtr;
-
- currentPtr = makeLinkBase(node, link);
- currentPtr += HTHOST_BUFFER_COUNT_REG;
-
- /* Request Data Buffers */
- temp = reqD;
- AmdPCIWriteBits(currentPtr, 18, 16, &temp);
- /* Posted Request Data Buffers */
- temp = preqD;
- AmdPCIWriteBits(currentPtr, 22, 20, &temp);
- /* Response Data Buffers */
- temp = rspD;
- AmdPCIWriteBits(currentPtr, 26, 24, &temp);
-}
-#endif /* HT_BUILD_NC_ONLY */
-
-/***************************************************************************//**
- *
- * static void
- * ht3WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb)
- *
- * Description:
- * Set the traffic distribution register for the links provided.
- *
- * Parameters:
- * @param[in] links01 = coherent links from node 0 to 1
- * @param[in] links10 = coherent links from node 1 to 0
- * @param[in] nb = this northbridge
- *
- ******************************************************************************/
-static void ht3WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 temp;
-
- /* Node 0 */
- /* DstLnk */
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(0),
- makePCIBusFromNode(0),
- makePCIDeviceFromNode(0),
- CPU_HTNB_FUNC_00,
- REG_HT_TRAFFIC_DIST_0X164),
- 23, 16, &links01);
- /* DstNode = 1, cHTPrbDistEn = 1, cHTRspDistEn = 1, cHTReqDistEn = 1 */
- temp = 0x0107;
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(0),
- makePCIBusFromNode(0),
- makePCIDeviceFromNode(0),
- CPU_HTNB_FUNC_00,
- REG_HT_TRAFFIC_DIST_0X164),
- 15, 0, &temp);
-
- /* Node 1 */
- /* DstLnk */
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(1),
- makePCIBusFromNode(1),
- makePCIDeviceFromNode(1),
- CPU_HTNB_FUNC_00,
- REG_HT_TRAFFIC_DIST_0X164),
- 23, 16, &links10);
- /* DstNode = 0, cHTPrbDistEn = 1, cHTRspDistEn = 1, cHTReqDistEn = 1 */
- temp = 0x0007;
- AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(1),
- makePCIBusFromNode(1),
- makePCIDeviceFromNode(1),
- CPU_HTNB_FUNC_00,
- REG_HT_TRAFFIC_DIST_0X164),
- 15, 0, &temp);
-#endif /* HT_BUILD_NC_ONLY */
-}
-
-/***************************************************************************//**
- *
- * static void
- * ht1WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb)
- *
- * Description:
- * Traffic distribution is more complex in this case as the routing table must be
- * adjusted to use one link for requests and the other for responses. Also,
- * perform the buffer tunings on the links required for this config.
- *
- * Parameters:
- * @param[in] links01 = coherent links from node 0 to 1
- * @param[in] links10 = coherent links from node 1 to 0
- * @param[in] nb = this northbridge
- *
- ******************************************************************************/
-static void ht1WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u32 route01, route10;
- u8 req0, req1, rsp0, rsp1, nclink;
-
- /*
- * Get the current request route for 0->1 and 1->0. This will indicate which of the links
- * in links01 are connected to which links in links10. Since we have to route to distribute
- * traffic, we need to know that. The link used by htinit will become the request, probe link.
- * the other link will be used for responses.
- */
-
- /* Get the routes, and hang on to them, we will write them back updated. */
- AmdPCIRead(MAKE_SBDFO(makePCISegmentFromNode(0),
- makePCIBusFromNode(0),
- makePCIDeviceFromNode(0),
- CPU_HTNB_FUNC_00,
- REG_ROUTE1_0X44),
- &route01);
- AmdPCIRead(MAKE_SBDFO(makePCISegmentFromNode(1),
- makePCIBusFromNode(1),
- makePCIDeviceFromNode(1),
- CPU_HTNB_FUNC_00,
- REG_ROUTE0_0X40),
- &route10);
-
- /* Convert the request routes to a link number. Note "0xE" is ht1 nb specific.
- * Find the response link numbers.
- */
- ASSERT((route01 & 0xE) && (route10 & 0xE)); /* no route! error! */
- req0 = (u8)AmdBitScanReverse((route01 & 0xE)) - 1;
- req1 = (u8)AmdBitScanReverse((route10 & 0xE)) - 1;
- /* Now, find the other link for the responses */
- rsp0 = (u8)AmdBitScanReverse((links01 & ~((u32)1 << req0)));
- rsp1 = (u8)AmdBitScanReverse((links10 & ~((u32)1 << req1)));
-
- /* ht1 nb restriction, must have exactly two links */
- ASSERT(((((links01 & ~((u32)1 << req0)) & ~((u32)1 << rsp0))) == 0)
- && ((((links10 & ~((u32)1 << req1)) & ~((u32)1 << rsp1))) == 0));
-
- route01 = (route01 & ~0x0E00) | ((u32)0x0100<<(rsp0 + 1));
- route10 = (route10 & ~0x0E00) | ((u32)0x0100<<(rsp1 + 1));
-
- AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(0),
- makePCIBusFromNode(0),
- makePCIDeviceFromNode(0),
- CPU_HTNB_FUNC_00,
- REG_ROUTE1_0X44),
- &route01);
-
- AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(1),
- makePCIBusFromNode(1),
- makePCIDeviceFromNode(1),
- CPU_HTNB_FUNC_00,
- REG_ROUTE0_0X40),
- &route10);
-
- /* While we otherwise do buffer tunings elsewhere, for the dual cHT DP case with
- * ht1 northbridges like family 0Fh, do the tunings here where we have all the
- * link and route info at hand and don't need to recalculate it.
- */
-
- /* Node 0, Request / Probe Link (note family F only has links < 4) */
- fam0fWriteHTLinkCmdBufferAlloc(0, req0, 6, 3, 1, 6);
- fam0fWriteHTLinkDatBufferAlloc(0, req0, 4, 3, 1);
- /* Node 0, Response Link (note family F only has links < 4) */
- fam0fWriteHTLinkCmdBufferAlloc(0, rsp0, 1, 0, 15, 0);
- fam0fWriteHTLinkDatBufferAlloc(0, rsp0, 1, 1, 6);
- /* Node 1, Request / Probe Link (note family F only has links < 4) */
- fam0fWriteHTLinkCmdBufferAlloc(1, req1, 6, 3, 1, 6);
- fam0fWriteHTLinkDatBufferAlloc(1, req1, 4, 3, 1);
- /* Node 1, Response Link (note family F only has links < 4) */
- fam0fWriteHTLinkCmdBufferAlloc(1, rsp1, 1, 0, 15, 0);
- fam0fWriteHTLinkDatBufferAlloc(1, rsp1, 1, 1, 6);
-
- /* Node 0, is the third link non-coherent? */
- nclink = (u8)AmdBitScanReverse(((u8)0x07 & ~((u32)1 << req0) & ~((u32)1 << rsp0)));
- if (nb->verifyLinkIsNonCoherent(0, nclink, nb))
- {
- fam0fWriteHTLinkCmdBufferAlloc(0, nclink, 6, 5, 2, 0);
- }
-
- /* Node 1, is the third link non-coherent? */
- nclink = (u8)AmdBitScanReverse(((u8)0x07 & ~((u32)1 << req1) & ~((u32)1 << rsp1)));
- if (nb->verifyLinkIsNonCoherent(1, nclink, nb))
- {
- fam0fWriteHTLinkCmdBufferAlloc(1, nclink, 6, 5, 2, 0);
- }
-#endif /* HT_BUILD_NC_ONLY */
-}
-
-/***************************************************************************//**
- *
- * static void
- * fam0fBufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Buffer tunings are inherently northbridge specific. Check for specific configs
- * which require adjustments and apply any standard workarounds to this node.
- *
- * Parameters:
- * @param[in] node = the node to
- * @param[in] *pDat = coherent links from node 0 to 1
- * @param[in] nb = this northbridge
- *
- ******************************************************************************/
-static void fam0fBufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb)
-{
-#ifndef HT_BUILD_NC_ONLY
- u8 i;
- u32 temp;
- SBDFO currentPtr;
-
- ASSERT(node < nb->maxNodes);
-
- /* Fix the FIFO pointer register before changing speeds */
- currentPtr = MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_FIFOPTR_3XDC);
- for (i = 0; i < nb->maxLinks; i++)
- {
- temp = 0;
- if (nb->verifyLinkIsCoherent(node, i, nb))
- {
- temp = 0x26;
- ASSERT(i < 3);
- AmdPCIWriteBits(currentPtr, 8*i + 5, 8*i, &temp);
- }
- else
- {
- if (nb->verifyLinkIsNonCoherent(node, i, nb))
- {
- temp = 0x25;
- ASSERT(i < 3);
- AmdPCIWriteBits(currentPtr, 8*i + 5, 8*i, &temp);
- }
- }
- }
- /*
- * 8P Buffer tuning.
- * Either apply the BKDG tunings or, if applicable, apply the more restrictive errata 153
- * workaround.
- * If 8 nodes, Check this node for 'inner' or 'outer'.
- * Tune each link based on coherent or non-coherent
- */
- if (pDat->NodesDiscovered >= 6)
- {
- u8 j;
- BOOL isOuter;
- BOOL isErrata153;
-
- /* This is for family 0Fh, so assuming dual core max then 7 or 8 nodes are required
- * to be in the situation of 14 or more cores. We checked nodes above, cross check
- * that the number of cores is 14 or more. We want both 14 cores with at least 7 or 8 nodes
- * not one condition alone, to apply the errata 153 workaround. Otherwise, 7 or 8 rev F
- * nodes use the BKDG tuning.
- */
-
- isErrata153 = 0;
-
- AmdPCIReadBits (MAKE_SBDFO(makePCISegmentFromNode(0),
- makePCIBusFromNode(0),
- makePCIDeviceFromNode(0),
- CPU_HTNB_FUNC_00,
- REG_NODE_ID_0X60),
- 19, 16, &temp);
-
- if (temp >= 14)
- {
- /* Check whether we need to do errata 153 tuning or BKDG tuning.
- * Errata 153 applies to JH-1, JH-2 and older. It is fixed in JH-3
- * (and, one assumes, from there on).
- */
- for (i = 0; i < (pDat->NodesDiscovered +1); i++)
- {
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(i),
- makePCIBusFromNode(i),
- makePCIDeviceFromNode(i),
- CPU_NB_FUNC_03,
- REG_NB_CPUID_3XFC),
- 7, 0, &temp);
- if (((u8)temp & ~0x40) < 0x13)
- {
- isErrata153 = 1;
- break;
- }
- }
- }
-
- for (i = 0; i < CPU_ADDR_NUM_CONFIG_MAPS; i++)
- {
- isOuter = FALSE;
- /* Check for outer node by scanning the config maps on node 0 for one
- * which is assigned to this node.
- */
- currentPtr = MAKE_SBDFO(makePCISegmentFromNode(0),
- makePCIBusFromNode(0),
- makePCIDeviceFromNode(0),
- CPU_ADDR_FUNC_01,
- REG_ADDR_CONFIG_MAP0_1XE0 + (4 * i));
- AmdPCIReadBits (currentPtr, 1, 0, &temp);
- /* Make sure this config map is valid, if it is it will be enabled for read/write */
- if (temp == 3)
- {
- /* It's valid, get the node (that node is an outer node) */
- AmdPCIReadBits (currentPtr, 6, 4, &temp);
- /* Is the node we're working on now? */
- if (node == (u8)temp)
- {
- /* This is an outer node. Tune it appropriately. */
- for (j = 0; j < nb->maxLinks; j++)
- {
- if (isErrata153)
- {
- if (nb->verifyLinkIsCoherent(node, j, nb))
- {
- fam0fWriteHTLinkCmdBufferAlloc(node, j, 1, 1, 6, 4);
- }
- else
- {
- if (nb->verifyLinkIsNonCoherent(node, j, nb))
- {
- fam0fWriteHTLinkCmdBufferAlloc(node, j, 5, 4, 1, 0);
- }
- }
- }
- else
- {
- if (nb->verifyLinkIsCoherent(node, j, nb))
- {
- fam0fWriteHTLinkCmdBufferAlloc(node, j, 1, 1, 8, 5);
- }
- }
- }
- /*
- * SRI to XBAR Buffer Counts are correct for outer node at power on defaults.
- */
- isOuter = TRUE;
- break;
- }
- }
- /* We fill config maps in ascending order, so if we didn't use this one, we're done. */
- else break;
- }
- if (!isOuter)
- {
- if (isErrata153)
- {
- /* Tuning for inner node coherent links */
- for (j = 0; j < nb->maxLinks; j++)
- {
- if (nb->verifyLinkIsCoherent(node, j, nb))
- {
- fam0fWriteHTLinkCmdBufferAlloc(node, j, 2, 1, 5, 4);
- }
-
- }
- /* SRI to XBAR Buffer Count for inner nodes, zero DReq and DPReq */
- temp = 0;
- AmdPCIWriteBits (MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_SRI_XBAR_BUF_3X70),
- 31, 28, &temp);
- }
- }
-
- /*
- * Tune MCT to XBAR Buffer Count the same an all nodes, 2 Probes, 5 Response
- */
- if (isErrata153)
- {
- temp = 0x25;
- AmdPCIWriteBits (MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_MCT_XBAR_BUF_3X78),
- 14, 8, &temp);
- }
- }
-#endif /* HT_BUILD_NC_ONLY */
-}
-
-/***************************************************************************//**
- *
- * static void
- * fam10BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Buffer tunings are inherently northbridge specific. Check for specific configs
- * which require adjustments and apply any standard workarounds to this node.
- *
- * Parameters:
- * @param[in] node = the node to tune
- * @param[in] *pDat = global state
- * @param[in] nb = this northbridge
- *
- ******************************************************************************/
-static void fam10BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb)
-{
- u32 temp;
- SBDFO currentPtr;
- u8 i;
-
- ASSERT(node < nb->maxNodes);
-
- /*
- * Link to XCS Token Count Tuning
- *
- * For each active link that we reganged (so this unfortunately can't go into the PCI reg
- * table), we have to switch the Link to XCS Token Counts to the ganged state.
- * We do this here for the non-uma case, which is to write the values that would have
- * been power on defaults if the link was ganged at cold reset.
- */
- for (i = 0; i < pDat->TotalLinks*2; i++)
- {
- if ((pDat->PortList[i].NodeID == node) && (pDat->PortList[i].Type == PORTLIST_TYPE_CPU))
- {
- /* If the link is greater than 4, this is a sublink 1, so it is not reganged. */
- if (pDat->PortList[i].Link < 4)
- {
- currentPtr = MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_LINK_XCS_TOKEN0_3X148 + 4*pDat->PortList[i].Link);
- if (pDat->PortList[i].SelRegang)
- {
- /* Handle all the regang Token count adjustments */
-
- /* Sublink 0: [Probe0tok] = 2 [Rsp0tok] = 2 [PReq0tok] = 2 [Req0tok] = 2 */
- temp = 0xAA;
- AmdPCIWriteBits(currentPtr, 7, 0, &temp);
- /* Sublink 1: [Probe1tok] = 0 [Rsp1tok] = 0 [PReq1tok] = 0 [Req1tok] = 0 */
- temp = 0;
- AmdPCIWriteBits(currentPtr, 23, 16, &temp);
- /* [FreeTok] = 3 */
- temp = 3;
- AmdPCIWriteBits(currentPtr, 15, 14, &temp);
- }
- else
- {
- /* Read the regang bit in hardware */
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID),
- makePCIBusFromNode(pDat->PortList[i].NodeID),
- makePCIDeviceFromNode(pDat->PortList[i].NodeID),
- CPU_HTNB_FUNC_00,
- REG_HT_LINK_EXT_CONTROL0_0X170 + 4*pDat->PortList[i].Link),
- 0, 0, &temp);
- if (temp == 1)
- {
- /* handle a minor adjustment for stapped ganged links. If SelRegang is false we
- * didn't do the regang, so if the bit is on then it's hardware strapped.
- */
-
- /* [FreeTok] = 3 */
- temp = 3;
- AmdPCIWriteBits(currentPtr, 15, 14, &temp);
- }
- }
- }
- }
- }
-}
-
-/***************************************************************************//**
- *
- * static void
- * fam15BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb)
- *
- * Description:
- * Buffer tunings are inherently northbridge specific. Check for specific configs
- * which require adjustments and apply any standard workarounds to this node.
- *
- * Parameters:
- * @param[in] node = the node to tune
- * @param[in] *pDat = global state
- * @param[in] nb = this northbridge
- *
- ******************************************************************************/
-static void fam15BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb)
-{
- /* Buffer count setup on Family 15h is currently handled in cpuSetAMDPCI */
-}
-
-/*
- * North Bridge 'constructor'.
- *
- */
-
-/***************************************************************************//**
- *
- * void
- * newNorthBridge(u8 node, cNorthBridge *nb)
- *
- * Description:
- * Construct a new northbridge. This routine encapsulates knowledge of how to tell
- * significant differences between families of supported northbridges and what routines
- * can be used in common and which are unique. A fully populated northbridge interface
- * is provided by nb.
- *
- * Parameters:
- * @param node
- * @param[out] nb = the caller's northbridge structure to initialize.
- *
- ******************************************************************************/
-void newNorthBridge(u8 node, cNorthBridge *nb)
-{
- u32 match;
- u32 extFam, baseFam, model;
-
- cNorthBridge fam15 =
- {
-#ifdef HT_BUILD_NC_ONLY
- 8,
- 1,
- 12,
-#else
- 8,
- 8,
- 64,
-#endif /* HT_BUILD_NC_ONLY*/
- writeRoutingTable,
- writeNodeID,
- readDefLnk,
- enableRoutingTables,
- verifyLinkIsCoherent,
- readTrueLinkFailStatus,
- readToken,
- writeToken,
- fam15GetNumCoresOnNode,
- setTotalNodesAndCores,
- limitNodes,
- writeFullRoutingTable,
- isCompatible,
- fam15IsCapable,
- (void (*)(u8, u8, cNorthBridge*))commonVoid,
- (BOOL (*)(u8, u8, sMainData*, cNorthBridge*))commonReturnFalse,
- readSbLink,
- verifyLinkIsNonCoherent,
- ht3SetCFGAddrMap,
- convertBitsToWidth,
- convertWidthToBits,
- fam15NorthBridgeFreqMask,
- gatherLinkData,
- setLinkData,
- ht3WriteTrafficDistribution,
- fam15BufferOptimizations,
- 0x00000001,
- 0x00000200,
- 18,
- 0x00000f06
- };
-
- cNorthBridge fam10 =
- {
-#ifdef HT_BUILD_NC_ONLY
- 8,
- 1,
- 12,
-#else
- 8,
- 8,
- 64,
-#endif /* HT_BUILD_NC_ONLY*/
- writeRoutingTable,
- writeNodeID,
- readDefLnk,
- enableRoutingTables,
- verifyLinkIsCoherent,
- readTrueLinkFailStatus,
- readToken,
- writeToken,
- fam10GetNumCoresOnNode,
- setTotalNodesAndCores,
- limitNodes,
- writeFullRoutingTable,
- isCompatible,
- fam10IsCapable,
- (void (*)(u8, u8, cNorthBridge*))commonVoid,
- (BOOL (*)(u8, u8, sMainData*, cNorthBridge*))commonReturnFalse,
- readSbLink,
- verifyLinkIsNonCoherent,
- ht3SetCFGAddrMap,
- convertBitsToWidth,
- convertWidthToBits,
- fam10NorthBridgeFreqMask,
- gatherLinkData,
- setLinkData,
- ht3WriteTrafficDistribution,
- fam10BufferOptimizations,
- 0x00000001,
- 0x00000200,
- 18,
- 0x00000f01
- };
-
- cNorthBridge fam0f =
- {
-#ifdef HT_BUILD_NC_ONLY
- 3,
- 1,
- 12,
-#else
- 3,
- 8,
- 32,
-#endif /* HT_BUILD_NC_ONLY*/
- writeRoutingTable,
- writeNodeID,
- readDefLnk,
- enableRoutingTables,
- verifyLinkIsCoherent,
- readTrueLinkFailStatus,
- readToken,
- writeToken,
- fam0FGetNumCoresOnNode,
- setTotalNodesAndCores,
- limitNodes,
- writeFullRoutingTable,
- isCompatible,
- fam0fIsCapable,
- fam0fStopLink,
- (BOOL (*)(u8, u8, sMainData*, cNorthBridge*))commonReturnFalse,
- readSbLink,
- verifyLinkIsNonCoherent,
- ht1SetCFGAddrMap,
- convertBitsToWidth,
- convertWidthToBits,
- ht1NorthBridgeFreqMask,
- gatherLinkData,
- setLinkData,
- ht1WriteTrafficDistribution,
- fam0fBufferOptimizations,
- 0x00000001,
- 0x00000100,
- 16,
- 0x00000f00
- };
-
- /* Start with enough of the key to identify the northbridge interface */
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CPUID_3XFC),
- 27, 20, &extFam);
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CPUID_3XFC),
- 11, 8, &baseFam);
- AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node),
- makePCIBusFromNode(node),
- makePCIDeviceFromNode(node),
- CPU_NB_FUNC_03,
- REG_NB_CPUID_3XFC),
- 7, 4, &model);
- match = (u32)((baseFam << 8) | extFam);
-
- /* Test each in turn looking for a match.
- * Initialize the struct if found.
- */
- if (match == fam15.compatibleKey)
- {
- Amdmemcpy((void *)nb, (const void *)&fam15, (u32) sizeof(cNorthBridge));
- }
- else if (match == fam10.compatibleKey)
- {
- Amdmemcpy((void *)nb, (const void *)&fam10, (u32) sizeof(cNorthBridge));
- }
- else
- {
- if (match == fam0f.compatibleKey)
- {
- Amdmemcpy((void *)nb, (const void *)&fam0f, (u32) sizeof(cNorthBridge));
- }
- else
- {
- STOP_HERE;
- }
- }
-
- /* Update the initial limited key to the real one, which may include other matching info */
- nb->compatibleKey = makeKey(node);
-}