From fbd5d782096a2ab5a9b212ca7fdcf70050f89f56 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Wed, 14 Nov 2018 04:50:29 +0000 Subject: [PATCH] amdtemp(4): Fix temperature reporting on AMD 2990WX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the AMD family 17h temperature reporting based on AMD Tech Doc 56255 OSRR, section 4.2.1. For CPUS w/CUR_TEMP_RANGE_SEL set, scale the reported temperature into the range -49..206; i.e., subtract 49°C. Submitted by: gallatin@ Reported by: bcran@ Reviewed by: me (long ago) MFC after: 22.57 seconds Relnotes: yea Differential Revision: https://reviews.freebsd.org/D16855 --- sys/dev/amdtemp/amdtemp.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/sys/dev/amdtemp/amdtemp.c b/sys/dev/amdtemp/amdtemp.c index 6bbe3a1d27e..2c7afcd0c10 100644 --- a/sys/dev/amdtemp/amdtemp.c +++ b/sys/dev/amdtemp/amdtemp.c @@ -115,8 +115,15 @@ static struct amdtemp_product { /* * Reported Temperature, Family 17h + * + * According to AMD OSRR for 17H, section 4.2.1, bits 31-21 of this register + * provide the current temp. bit 19, when clear, means the temp is reported in + * a range 0.."225C" (probable typo for 255C), and when set changes the range + * to -49..206C. */ -#define AMDTEMP_17H_CUR_TMP 0x59800 +#define AMDTEMP_17H_CUR_TMP 0x59800 +#define AMDTEMP_17H_CUR_TMP_RANGE_SEL (1 << 19) +#define AMDTEMP_17H_CUR_TMP_RANGE_OFF 490 /* * Thermaltrip Status Register (Family 0Fh only) @@ -595,13 +602,15 @@ static int32_t amdtemp_gettemp17h(device_t dev, amdsensor_t sensor) { struct amdtemp_softc *sc = device_get_softc(dev); - uint32_t temp; + uint32_t temp, val; int error; - error = amdsmn_read(sc->sc_smn, AMDTEMP_17H_CUR_TMP, &temp); + error = amdsmn_read(sc->sc_smn, AMDTEMP_17H_CUR_TMP, &val); KASSERT(error == 0, ("amdsmn_read")); - temp = ((temp >> 21) & 0x7ff) * 5 / 4; + temp = ((val >> 21) & 0x7ff) * 5 / 4; + if ((val & AMDTEMP_17H_CUR_TMP_RANGE_SEL) != 0) + temp -= AMDTEMP_17H_CUR_TMP_RANGE_OFF; temp += AMDTEMP_ZERO_C_TO_K + sc->sc_offset * 10; return (temp);