aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-08-02 21:36:24 -0500
committerMartin Roth <martinroth@google.com>2015-11-20 23:49:38 +0100
commit7c55f374d1bc9e87005cea288fa1a00c48c69b54 (patch)
tree7c9f22452cd878062a1c72df9d75e9d499b0395a /src/northbridge
parent5173bb7d9d0d16255941b56d5cc722141d661baa (diff)
northbridge/amd/amdht: Add support for HT3 2.8GHz and up link frequencies
Change-Id: Ifa1592d26ba7deb034046fd3f2a15149117d9a76 Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/12027 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/amd/amdht/h3ffeat.h6
-rw-r--r--src/northbridge/amd/amdht/h3finit.c93
-rw-r--r--src/northbridge/amd/amdht/h3finit.h18
-rw-r--r--src/northbridge/amd/amdht/h3ncmn.c82
-rw-r--r--src/northbridge/amd/amdht/h3ncmn.h3
5 files changed, 133 insertions, 69 deletions
diff --git a/src/northbridge/amd/amdht/h3ffeat.h b/src/northbridge/amd/amdht/h3ffeat.h
index 52c4def8a4..628b86e660 100644
--- a/src/northbridge/amd/amdht/h3ffeat.h
+++ b/src/northbridge/amd/amdht/h3ffeat.h
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 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
@@ -58,6 +59,7 @@
#define HTHOST_LINK_CAPABILITY_REG 0x00
#define HTHOST_LINK_CONTROL_REG 0x04
#define HTHOST_FREQ_REV_REG 0x08
+#define HTHOST_FREQ_REV_REG_2 0x1c
#define HT_HOST_REV_REV3 0x60
#define HTHOST_FEATURE_CAP_REG 0x0C
#define HTHOST_BUFFER_COUNT_REG 0x10
@@ -123,10 +125,10 @@ typedef struct
/* This section is for keeping track of capabilities and possible configurations */
BOOL RegangCap;
- u16 PrvFrequencyCap;
+ uint32_t PrvFrequencyCap;
u8 PrvWidthInCap;
u8 PrvWidthOutCap;
- u16 CompositeFrequencyCap;
+ uint32_t CompositeFrequencyCap;
} sPortDescriptor;
diff --git a/src/northbridge/amd/amdht/h3finit.c b/src/northbridge/amd/amdht/h3finit.c
index bcdcfa2ae6..e4ce76803a 100644
--- a/src/northbridge/amd/amdht/h3finit.c
+++ b/src/northbridge/amd/amdht/h3finit.c
@@ -48,28 +48,32 @@
#define APIC_Base_BSP 8
#define APIC_Base 0x1b
-#define NVRAM_LIMIT_HT_SPEED_200 0xf
-#define NVRAM_LIMIT_HT_SPEED_300 0xe
-#define NVRAM_LIMIT_HT_SPEED_400 0xd
-#define NVRAM_LIMIT_HT_SPEED_500 0xc
-#define NVRAM_LIMIT_HT_SPEED_600 0xb
-#define NVRAM_LIMIT_HT_SPEED_800 0xa
-#define NVRAM_LIMIT_HT_SPEED_1000 0x9
-#define NVRAM_LIMIT_HT_SPEED_1200 0x8
-#define NVRAM_LIMIT_HT_SPEED_1400 0x7
-#define NVRAM_LIMIT_HT_SPEED_1600 0x6
-#define NVRAM_LIMIT_HT_SPEED_1800 0x5
-#define NVRAM_LIMIT_HT_SPEED_2000 0x4
-#define NVRAM_LIMIT_HT_SPEED_2200 0x3
-#define NVRAM_LIMIT_HT_SPEED_2400 0x2
-#define NVRAM_LIMIT_HT_SPEED_2600 0x1
+#define NVRAM_LIMIT_HT_SPEED_200 0x12
+#define NVRAM_LIMIT_HT_SPEED_300 0x11
+#define NVRAM_LIMIT_HT_SPEED_400 0x10
+#define NVRAM_LIMIT_HT_SPEED_500 0xf
+#define NVRAM_LIMIT_HT_SPEED_600 0xe
+#define NVRAM_LIMIT_HT_SPEED_800 0xd
+#define NVRAM_LIMIT_HT_SPEED_1000 0xc
+#define NVRAM_LIMIT_HT_SPEED_1200 0xb
+#define NVRAM_LIMIT_HT_SPEED_1400 0xa
+#define NVRAM_LIMIT_HT_SPEED_1600 0x9
+#define NVRAM_LIMIT_HT_SPEED_1800 0x8
+#define NVRAM_LIMIT_HT_SPEED_2000 0x7
+#define NVRAM_LIMIT_HT_SPEED_2200 0x6
+#define NVRAM_LIMIT_HT_SPEED_2400 0x5
+#define NVRAM_LIMIT_HT_SPEED_2600 0x4
+#define NVRAM_LIMIT_HT_SPEED_2800 0x3
+#define NVRAM_LIMIT_HT_SPEED_3000 0x2
+#define NVRAM_LIMIT_HT_SPEED_3200 0x1
#define NVRAM_LIMIT_HT_SPEED_AUTO 0x0
-static const uint16_t ht_speed_limit[16] =
- {0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF,
- 0x0FFF, 0x07FF, 0x03FF, 0x01FF,
- 0x00FF, 0x007F, 0x003F, 0x001F,
- 0x000F, 0x0007, 0x0003, 0x0001};
+static const uint32_t ht_speed_limit[20] =
+ {0xFFFFF, 0xFFFFF, 0x7FFFF, 0x3FFFF,
+ 0x0FFFF, 0x07FFF, 0x03FFF, 0x01FFF,
+ 0x00FFF, 0x007FF, 0x003FF, 0x001FF,
+ 0x000FF, 0x0007F, 0x0003F, 0x0001F,
+ 0x0000F, 0x00007, 0x00003, 0x00001};
static const struct ht_speed_limit_map_t {
uint16_t mhz;
@@ -91,9 +95,12 @@ static const struct ht_speed_limit_map_t {
{2200, NVRAM_LIMIT_HT_SPEED_2200},
{2400, NVRAM_LIMIT_HT_SPEED_2400},
{2600, NVRAM_LIMIT_HT_SPEED_2600},
+ {2800, NVRAM_LIMIT_HT_SPEED_2800},
+ {3000, NVRAM_LIMIT_HT_SPEED_3000},
+ {3200, NVRAM_LIMIT_HT_SPEED_3200},
};
-static const uint16_t ht_speed_mhz_to_hw(uint16_t mhz)
+static const uint32_t ht_speed_mhz_to_hw(uint16_t mhz)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(ht_speed_limit_map); i++)
@@ -452,7 +459,7 @@ static void htDiscoveryFloodFill(sMainData *pDat)
/* Set currentNode's NodeID field to currentNode */
pDat->nb->writeNodeID(currentNode, currentNode, pDat->nb);
- /* Enable routing tables on currentNode*/
+ /* Enable routing tables on currentNode */
pDat->nb->enableRoutingTables(currentNode, pDat->nb);
for (currentLinkID = 0; currentLinkID < pDat->nb->maxLinks; currentLinkID++)
@@ -1427,19 +1434,30 @@ static void regangLinks(sMainData *pDat)
static void selectOptimalWidthAndFrequency(sMainData *pDat)
{
u8 i, j;
- u32 temp;
- u16 cbPCBFreqLimit;
- u16 cbPCBFreqLimit_NVRAM;
+ uint32_t temp;
+ uint32_t cbPCBFreqLimit;
+ uint32_t cbPCBFreqLimit_NVRAM;
u8 cbPCBABDownstreamWidth;
u8 cbPCBBAUpstreamWidth;
- cbPCBFreqLimit_NVRAM = 0xFFFF;
+ cbPCBFreqLimit_NVRAM = 0xfffff;
if (get_option(&temp, "hypertransport_speed_limit") == CB_SUCCESS)
cbPCBFreqLimit_NVRAM = ht_speed_limit[temp & 0xf];
+ if (!is_fam15h()) {
+ /* FIXME
+ * By default limit frequency to 2.6 GHz as there are residual
+ * problems with HT v3.1 implementation on at least some Socket G34
+ * mainboards / Fam10h CPUs.
+ * Debug the issues and reenable this...
+ */
+ if (cbPCBFreqLimit_NVRAM > 0xffff)
+ cbPCBFreqLimit_NVRAM = 0xffff;
+ }
+
for (i = 0; i < pDat->TotalLinks*2; i += 2)
{
- cbPCBFreqLimit = 0xFFFF; // Maximum allowed by autoconfiguration
+ cbPCBFreqLimit = 0xfffff; // Maximum allowed by autoconfiguration
if (pDat->HtBlock->ht_link_configuration)
cbPCBFreqLimit = ht_speed_mhz_to_hw(pDat->HtBlock->ht_link_configuration->ht_speed_limit);
cbPCBFreqLimit = min(cbPCBFreqLimit, cbPCBFreqLimit_NVRAM);
@@ -1484,17 +1502,18 @@ static void selectOptimalWidthAndFrequency(sMainData *pDat)
}
}
-
temp = pDat->PortList[i].PrvFrequencyCap;
temp &= pDat->PortList[i+1].PrvFrequencyCap;
temp &= cbPCBFreqLimit;
- pDat->PortList[i].CompositeFrequencyCap = (u16)temp;
- pDat->PortList[i+1].CompositeFrequencyCap = (u16)temp;
+ pDat->PortList[i].CompositeFrequencyCap = temp;
+ pDat->PortList[i+1].CompositeFrequencyCap = temp;
ASSERT (temp != 0);
- for (j = 15; ; j--)
+ for (j = 19; ; j--)
{
- if (temp & ((u32)1 << j))
+ if ((j == 16) || (j == 15))
+ continue;
+ if (temp & ((uint32_t)1 << j))
break;
}
@@ -1638,12 +1657,14 @@ static void hammerSublinkFixup(sMainData *pDat)
/* Remove hiFreq from the list of valid frequencies */
temp = temp & ~((uint32)1 << hiFreq);
ASSERT (temp != 0);
- pDat->PortList[hiIndex].CompositeFrequencyCap = (uint16)temp;
- pDat->PortList[hiIndex+1].CompositeFrequencyCap = (uint16)temp;
+ pDat->PortList[hiIndex].CompositeFrequencyCap = temp;
+ pDat->PortList[hiIndex+1].CompositeFrequencyCap = temp;
- for (k = 15; ; k--)
+ for (k = 19; ; k--)
{
- if (temp & ((u32)1 << k))
+ if ((j == 16) || (j == 15))
+ continue;
+ if (temp & ((uint32_t)1 << k))
break;
}
diff --git a/src/northbridge/amd/amdht/h3finit.h b/src/northbridge/amd/amdht/h3finit.h
index f6ab010b60..1bd8616ef2 100644
--- a/src/northbridge/amd/amdht/h3finit.h
+++ b/src/northbridge/amd/amdht/h3finit.h
@@ -49,6 +49,9 @@
#define HT_FREQUENCY_2200M 12
#define HT_FREQUENCY_2400M 13
#define HT_FREQUENCY_2600M 14
+#define HT_FREQUENCY_2800M 17
+#define HT_FREQUENCY_3000M 18
+#define HT_FREQUENCY_3200M 19
/* Frequency Limit equates for call backs which take a frequency supported mask. */
#define HT_FREQUENCY_LIMIT_200M 1
@@ -65,6 +68,9 @@
#define HT_FREQUENCY_LIMIT_2200M 0x1FFF
#define HT_FREQUENCY_LIMIT_2400M 0x3FFF
#define HT_FREQUENCY_LIMIT_2600M 0x7FFF
+#define HT_FREQUENCY_LIMIT_2800M 0x3FFFF
+#define HT_FREQUENCY_LIMIT_3000M 0x7FFFF
+#define HT_FREQUENCY_LIMIT_3200M 0xFFFFF
/*
* Event Notify definitions
@@ -220,7 +226,7 @@ typedef struct {
* @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
+ * @param[in,out] u32* FreqCap = modify to change the link's frequency capability
*
* ---------------------------------------------------------------------------------------
*/
@@ -235,7 +241,7 @@ typedef struct {
u8 Link,
u8 *LinkWidthIn,
u8 *LinkWidthOut,
- u16 *FreqCap
+ u32 *FreqCap
);
/**----------------------------------------------------------------------------------------
@@ -258,7 +264,7 @@ typedef struct {
* @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
+ * @param[in,out] u32* PCBFreqCap = modify to change the link's frequency capability
*
* ---------------------------------------------------------------------------------------
*/
@@ -269,7 +275,7 @@ typedef struct {
u8 LinkB,
u8 *ABLinkWidthLimit,
u8 *BALinkWidthLimit,
- u16 *PCBFreqCap
+ u32 *PCBFreqCap
);
/**----------------------------------------------------------------------------------------
@@ -291,7 +297,7 @@ typedef struct {
* @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
+ * @param[in,out] u32* PCBFreqCap = modify to change the link's frequency capability
*
* ---------------------------------------------------------------------------------------
*/
@@ -301,7 +307,7 @@ typedef struct {
u8 Depth,
u8 *DownstreamLinkWidthLimit,
u8 *UpstreamLinkWidthLimit,
- u16 *PCBFreqCap
+ u32 *PCBFreqCap
);
/**----------------------------------------------------------------------------------------
diff --git a/src/northbridge/amd/amdht/h3ncmn.c b/src/northbridge/amd/amdht/h3ncmn.c
index 8ee929d12e..29524afee0 100644
--- a/src/northbridge/amd/amdht/h3ncmn.c
+++ b/src/northbridge/amd/amdht/h3ncmn.c
@@ -1310,7 +1310,7 @@ static u8 convertWidthToBits(u8 value, cNorthBridge *nb)
* @return Frequency mask
*
******************************************************************************/
-static u16 ht1NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
+static uint32_t ht1NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
{
/* only up to HT1 speeds */
return (HT_FREQUENCY_LIMIT_HT1_ONLY);
@@ -1331,26 +1331,43 @@ static u16 ht1NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
* @return = Frequency mask
*
******************************************************************************/
-static u16 fam10NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
+static uint32_t fam10NorthBridgeFreqMask(u8 node, cNorthBridge *nb)
{
u8 nbCOF;
- u16 supported;
+ 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 <= 26))
+ 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 = ((u16)1 << ((nbCOF >> 1) + 2)) - 1;
+ supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1;
}
- else if (nbCOF > 26)
+ else if ((nbCOF >= 10) && (nbCOF <= 32))
{
- supported = HT_FREQUENCY_LIMIT_2600M;
+ /* 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)
@@ -1405,8 +1422,13 @@ static void gatherLinkData(sMainData *pDat, cNorthBridge *nb)
pDat->PortList[i].PrvWidthInCap = convertBitsToWidth((u8)temp, pDat->nb);
AmdPCIReadBits(linkBase + HTHOST_FREQ_REV_REG, 31, 16, &temp);
- pDat->PortList[i].PrvFrequencyCap = (u16)temp & 0x7FFF
- & nb->northBridgeFreqMask(pDat->PortList[i].NodeID, pDat->nb); /* Mask off bit 15, reserved value */
+ 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);
+ }
}
else
{
@@ -1463,7 +1485,7 @@ static void setLinkData(sMainData *pDat, cNorthBridge *nb)
{
u8 i;
SBDFO linkBase;
- u32 temp, widthin, widthout, bits;
+ u32 temp, temp2, frequency_index, widthin, widthout, bits;
for (i = 0; i < pDat->TotalLinks*2; i++)
{
@@ -1524,10 +1546,19 @@ static void setLinkData(sMainData *pDat, cNorthBridge *nb)
temp = pDat->PortList[i].SelFrequency;
if (pDat->PortList[i].Type == PORTLIST_TYPE_CPU)
{
- ASSERT((temp >= HT_FREQUENCY_600M && temp <= HT_FREQUENCY_2600M)
+ 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;
+ }
+ if (is_gt_rev_d())
+ AmdPCIWriteBits(linkBase + HTHOST_FREQ_REV_REG_2, 0, 0, &temp2);
AmdPCIWriteBits(linkBase + HTHOST_FREQ_REV_REG, 11, 8, &temp);
- if (temp > HT_FREQUENCY_1000M) /* Gen1 = 200MHz -> 1000MHz, Gen3 = 1200MHz -> 2600MHz */
+ if (frequency_index > HT_FREQUENCY_1000M) /* Gen1 = 200MHz -> 1000MHz, Gen3 = 1200MHz -> 3200MHz */
{
/* Enable for Gen3 frequencies */
temp = 1;
@@ -1537,27 +1568,27 @@ static void setLinkData(sMainData *pDat, cNorthBridge *nb)
/* 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),
+ /* 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_EXT_CONTROL0_0X170 + 4*pDat->PortList[i].Link),
- 3, 3, &temp);
+ 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_2600M);
+ ASSERT(temp <= HT_FREQUENCY_3200M);
/* Write the frequency setting */
AmdPCIWriteBits(linkBase + HTSLAVE_FREQ_REV_0_REG, 11, 8, &temp);
@@ -1718,6 +1749,9 @@ static void fam0fWriteHTLinkCmdBufferAlloc(u8 node, u8 link, u8 req, u8 preq, u8
/* Probe Command Buffers */
temp = prb;
AmdPCIWriteBits(currentPtr, 15, 12, &temp);
+ /* LockBc */
+ temp = 1;
+ AmdPCIWriteBits(currentPtr, 31, 31, &temp);
}
#endif /* HT_BUILD_NC_ONLY */
diff --git a/src/northbridge/amd/amdht/h3ncmn.h b/src/northbridge/amd/amdht/h3ncmn.h
index 328d909b8b..3c8a34612f 100644
--- a/src/northbridge/amd/amdht/h3ncmn.h
+++ b/src/northbridge/amd/amdht/h3ncmn.h
@@ -2,6 +2,7 @@
* 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
@@ -103,7 +104,7 @@ struct cNorthBridge
/* Public Interfaces for northbridge clients, Optimization */
u8 (*convertBitsToWidth)(u8 value, cNorthBridge *nb);
u8 (*convertWidthToBits)(u8 value, cNorthBridge *nb);
- u16 (*northBridgeFreqMask)(u8 node, cNorthBridge *nb);
+ uint32_t (*northBridgeFreqMask)(u8 node, cNorthBridge *nb);
void (*gatherLinkData)(sMainData *pDat, cNorthBridge *nb);
void (*setLinkData)(sMainData *pDat, cNorthBridge *nb);