Add temperature quirks for AMD EPYCs (#616)

Closes #411
This commit is contained in:
Sam Demeulemeester authored and GitHub committed 2026-05-25 20:57:38 +02:00
1 parent 997d4d2da2
commit badcf8a57c
5 files changed
+75 -7

No files matched your search

+3 -1
View File
@@ -83,7 +83,9 @@
#define IMC_K1A_GRG 0x8210 // Zen5 (Granite Ridge)
#define IMC_K1A_KRN 0x8220 // Zen5 (Krackan)
#define IMC_K1A_STH 0x8230 // Zen5 (Strix Halo)
#define IMC_K1A_MDS 0x8240 // Zen6 (Medusa)
#define IMC_K1A_TUR 0x8240 // Zen5 (Turin)
#define IMC_K1A_MDS 0x8300 // Zen6 (Medusa)
#define IMC_LSLA 0xC000 // Loongson LoongArch family
#define IMC_LA464 0xC010 // LA464 (Loongson 3th Gen)
+55 -1
View File
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2004-2025 Sam Demeulemeester
// Copyright (C) 2004-2026 Sam Demeulemeester
//
// ------------------------
// This file is used to detect quirks on specific hardware
@@ -11,6 +11,7 @@
#include "hwquirks.h"
#include "io.h"
#include "pci.h"
#include "string.h"
#include "unistd.h"
#include "cpuinfo.h"
#include "cpuid.h"
@@ -158,6 +159,48 @@ static void amd_k8_revfg_temp(void)
cpu_temp_offset = 21.0f;
}
// AMD Zen Tctl -> Tdie offset table.
typedef struct {
uint8_t ext_family;
uint8_t ext_model;
float tctl_offset;
char brand_prefix[CPUID_BRAND_STR_LENGTH];
} amd_tctl_offset_t;
static const amd_tctl_offset_t amd_tctl_offset_table[] = {
{ 0x8, 0x0, -20.0f, "AMD Ryzen 5 1600X" }, // Summit Ridge
{ 0x8, 0x0, -20.0f, "AMD Ryzen 7 1700X" }, // Summit Ridge
{ 0x8, 0x0, -20.0f, "AMD Ryzen 7 1800X" }, // Summit Ridge
{ 0x8, 0x0, -10.0f, "AMD Ryzen 7 2700X" }, // Pinnacle Ridge
{ 0x8, 0x0, -27.0f, "AMD Ryzen Threadripper 19" }, // Whitehaven (1900X/1920X/1950X)
{ 0x8, 0x0, -27.0f, "AMD Ryzen Threadripper 29" }, // Colfax (29x0X/29x0WX)
{ 0x8, 0x0, -27.0f, "AMD EPYC 7" }, // Naples (Family 17h, Model 01h)
//{ 0xA, 0xA, -49.0f, "AMD EPYC 8" }, // Siena (Maybe needed)
//{ 0xA, 0x1, -49.0f, "AMD EPYC 9" }, // Genoa (Maybe needed)
{ 0xB, 0x0, -49.0f, "AMD EPYC 9" }, // Turin (Family 19h, Model 11h)
// Other EPYC parts report Tdie directly using the bit-19 (T_OFFSET_PRESENT) path.
};
static void amd_zen_apply_tctl_offset(void)
{
const char *brand = cpuid_info.brand_id.str;
uint8_t ext_family = cpuid_info.version.extendedFamily;
uint8_t ext_model = cpuid_info.version.extendedModel;
for (size_t i = 0; i < sizeof(amd_tctl_offset_table) / sizeof(amd_tctl_offset_table[0]); i++) {
const amd_tctl_offset_t *e = &amd_tctl_offset_table[i];
if (e->ext_family != ext_family || e->ext_model != ext_model) {
continue;
}
if (strncmp(brand, e->brand_prefix, strlen(e->brand_prefix)) == 0) {
cpu_temp_offset += e->tctl_offset;
return;
}
}
}
static void loongson_7a00_ehci_workaround(void)
{
uintptr_t reg_addr = 0x10010000;
@@ -327,6 +370,17 @@ void quirks_init(void)
}
}
// -----------------------------------------------------------
// -- AMD Zen-class Tctl -> Tdie offset for affected SKUs --
// -----------------------------------------------------------
if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF
&& cpuid_info.version.extendedFamily >= 8) {
quirk.id = QUIRK_AMD_ZEN_TCTL_OFFSET;
quirk.type |= QUIRK_TYPE_TEMP;
quirk.process = amd_zen_apply_tctl_offset;
}
// -----------------------------------------------------------
// -- Loongson 7A1000 and 7A2000 chipset USB 2.0 workaround --
// -----------------------------------------------------------
+2 -1
View File
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2004-2025 Sam Demeulemeester
// Copyright (C) 2004-2026 Sam Demeulemeester
#ifndef _QUIRK_H_
#define _QUIRK_H_
/**
@@ -29,6 +29,7 @@ typedef enum {
QUIRK_K8_BSTEP_NOTEMP,
QUIRK_K8_REVFG_TEMP,
QUIRK_AMD_ERRATA_319,
QUIRK_AMD_ZEN_TCTL_OFFSET,
QUIRK_VIA_VP,
QUIRK_SIS_530,
QUIRK_LOONGSON7A00_EHCI_WORKARD,
+3
View File
@@ -356,6 +356,9 @@ static void determine_imc(void)
break;
case 0xB:
switch(cpuid_info.version.extendedModel) {
case 0:
imc.family = IMC_K1A_TUR; // Zen5 EPYC (Family 1Ah - Turin Classic, SP5)
break;
case 2:
imc.family = IMC_K1A_STP; // Zen5 APU (Family 1Ah - Strix Point)
break;
+12 -4
View File
@@ -78,6 +78,18 @@ void cpu_temp_init(void)
}
}
}
// On Zen and newer, check once whether firmware reports the generic
// -49 °C Tctl bias via T_OFFSET_PRESENT (bit 19). The result is folded
// into cpu_temp_offset so per-SKU quirks set above can still apply.
if (cpuid_info.vendor_id.str[0] == 'A' && cpuid_info.version.family == 0xF
&& cpuid_info.version.extendedFamily >= 8) {
regl = amd_smn_read(SMN_THM_TCON_CUR_TMP);
if ((regl >> 19) & 0x01) {
cpu_temp_offset += -49.0f;
}
}
}
int get_cpu_temp(void)
@@ -100,10 +112,6 @@ int get_cpu_temp(void)
regl = amd_smn_read(SMN_THM_TCON_CUR_TMP);
if ((regl >> 19) & 0x01) {
cpu_temp_offset = -49.0f;
}
return cpu_temp_offset + 0.125f * (float)((regl >> 21) & 0x7FF);
} else if (cpuid_info.version.extendedFamily == 6 && (cpuid_info.version.extendedModel == 6 || cpuid_info.version.extendedModel == 7)) { // Target family 15h (Excavator)