Pull up following revision(s) (requested by msaitoh in ticket #1773):
share/man/man4/man4.x86/amdsmn.4 1.4,1.5 share/man/man4/man4.x86/amdzentemp.4 1.7 sys/arch/x86/pci/amdsmn.c 1.7-1.9,1.13,1.14 sys/arch/x86/pci/amdzentemp.c 1.8-1.10,1.12-1.15 adjust for possible 49K offset presence of this offset is indicated by a set 19th bit which is shifted away this brings the temperature to "normal" levels on my ryzen 2700 (I assumed the same 49K offset as the k10temp project) correct for known temperature bias values. Update to support Family 15h Model 60 temperature sensors. Changes based on FreeBSD amdtemp driver changes by Conrad Meyer. XXX: Some code duplication between this driver and amdtemp as parts of the 15h refresh code share more in common with older CPUs while accessing the device more like 17h. Don't mix sign and unsigned operands. Just use size_t for the loop. Apply previous change ("Don't mix sign and unsigned operands. Just use size_t for the loop.") to another loop variable. amdzentemp(4): Add Zen 3 support. amdzentemp(4): Add support for per CCD temperature sensor from FreeBSD. Fix build failure on i386. Rename for AMD F15/6X device. No functional change. amdsmn(4),amdzentemp(4): Add support for 17h/6xh and 19h/6xh. Note that these drivers are present on some newer AMD Family 15h processors. amdsmn.4: Now support AMD Family 19h processors.
This commit is contained in:
parent
e236846411
commit
1c848b0cd3
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: amdsmn.4,v 1.3.2.2 2018/02/05 13:06:55 martin Exp $
|
||||
.\" $NetBSD: amdsmn.4,v 1.3.2.3 2022/10/11 18:22:44 martin Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2018 Ian Clark <mrrooster@gmail.com>
|
||||
.\" All rights reserved.
|
||||
|
@ -54,7 +54,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD: head/share/man/man4/amdsmn.4 323184 2017-09-05 15:13:41Z cem $
|
||||
.\"
|
||||
.Dd January 22, 2018
|
||||
.Dd October 2, 2022
|
||||
.Dt AMDSMN 4 x86
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -66,7 +66,8 @@
|
|||
The
|
||||
.Nm
|
||||
driver provides support for resources on the System Management Network bus
|
||||
in AMD Family 17h processors.
|
||||
in AMD Family 19h processors, 17h processors and some later
|
||||
AMD Family 15h processors.
|
||||
.Sh SEE ALSO
|
||||
.Xr amdzentemp 4
|
||||
.Sh HISTORY
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: amdzentemp.4,v 1.6.2.2 2018/02/05 13:06:55 martin Exp $
|
||||
.\" $NetBSD: amdzentemp.4,v 1.6.2.3 2022/10/11 18:22:44 martin Exp $
|
||||
.\"-
|
||||
.\" Copyright (c) 2008 Christoph Egger
|
||||
.\" All rights reserved.
|
||||
|
@ -26,7 +26,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD: src/share/man/man4/coretemp.4,v 1.4 2007/10/15 20:00:19 netchild Exp $
|
||||
.\"
|
||||
.Dd January 28, 2018
|
||||
.Dd April 20, 2020
|
||||
.Dt AMDZENTEMP 4 x86
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -38,7 +38,7 @@
|
|||
The
|
||||
.Nm
|
||||
driver provides support for the on-die digital thermal sensor present
|
||||
on AMD Ryzen CPUs
|
||||
on AMD Ryzen CPUs and some later AMD Opteron CPUs.
|
||||
.Pp
|
||||
These sensors provide 0.125\(deC accuracy.
|
||||
There is one sensor for each CPU socket.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: amdsmn.c,v 1.3.2.4 2019/08/06 16:05:11 martin Exp $ */
|
||||
/* $NetBSD: amdsmn.c,v 1.3.2.5 2022/10/11 18:22:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org>
|
||||
* Copyright (c) 2017, 2019 Conrad Meyer <cem@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* NetBSD port by Ian Clark <mrrooster@gmail.com>
|
||||
|
@ -29,10 +29,11 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.3.2.4 2019/08/06 16:05:11 martin Exp $ ");
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.3.2.5 2022/10/11 18:22:44 martin Exp $ ");
|
||||
|
||||
/*
|
||||
* Driver for the AMD Family 17h CPU System Management Network.
|
||||
* Driver for the AMD Family 15h (model 60+) and 17h CPU
|
||||
* System Management Network.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -52,11 +53,15 @@ __KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.3.2.4 2019/08/06 16:05:11 martin Exp $
|
|||
#include "amdsmn.h"
|
||||
#include "ioconf.h"
|
||||
|
||||
#define SMN_ADDR_REG 0x60
|
||||
#define SMN_DATA_REG 0x64
|
||||
#define F15H_SMN_ADDR_REG 0xb8
|
||||
#define F15H_SMN_DATA_REG 0xbc
|
||||
#define F17H_SMN_ADDR_REG 0x60
|
||||
#define F17H_SMN_DATA_REG 0x64
|
||||
|
||||
struct amdsmn_softc {
|
||||
kmutex_t smn_lock;
|
||||
uint8_t smn_addr_reg;
|
||||
uint8_t smn_data_reg;
|
||||
struct pci_attach_args pa;
|
||||
pci_chipset_tag_t pc;
|
||||
pcitag_t pcitag;
|
||||
|
@ -64,10 +69,39 @@ struct amdsmn_softc {
|
|||
|
||||
static const struct pciid {
|
||||
uint16_t amdsmn_deviceid;
|
||||
uint8_t amdsmn_addr_reg;
|
||||
uint8_t amdsmn_data_reg;
|
||||
} amdsmn_ids[] = {
|
||||
{ PCI_PRODUCT_AMD_F17_RC },
|
||||
{ PCI_PRODUCT_AMD_F17_1X_RC },
|
||||
{ PCI_PRODUCT_AMD_F17_7X_RC },
|
||||
{
|
||||
.amdsmn_deviceid = PCI_PRODUCT_AMD_F15_6X_RC,
|
||||
.amdsmn_addr_reg = F15H_SMN_ADDR_REG,
|
||||
.amdsmn_data_reg = F15H_SMN_DATA_REG,
|
||||
},
|
||||
{
|
||||
.amdsmn_deviceid = PCI_PRODUCT_AMD_F17_RC,
|
||||
.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
|
||||
.amdsmn_data_reg = F17H_SMN_DATA_REG,
|
||||
},
|
||||
{
|
||||
.amdsmn_deviceid = PCI_PRODUCT_AMD_F17_1X_RC,
|
||||
.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
|
||||
.amdsmn_data_reg = F17H_SMN_DATA_REG,
|
||||
},
|
||||
{
|
||||
.amdsmn_deviceid = PCI_PRODUCT_AMD_F17_6X_RC,
|
||||
.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
|
||||
.amdsmn_data_reg = F17H_SMN_DATA_REG,
|
||||
},
|
||||
{
|
||||
.amdsmn_deviceid = PCI_PRODUCT_AMD_F17_7X_RC,
|
||||
.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
|
||||
.amdsmn_data_reg = F17H_SMN_DATA_REG,
|
||||
},
|
||||
{
|
||||
.amdsmn_deviceid = PCI_PRODUCT_AMD_F19_6X_RC,
|
||||
.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
|
||||
.amdsmn_data_reg = F17H_SMN_DATA_REG,
|
||||
},
|
||||
};
|
||||
|
||||
static int amdsmn_match(device_t, cfdata_t, void *);
|
||||
|
@ -83,7 +117,7 @@ static int
|
|||
amdsmn_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct pci_attach_args *pa = aux;
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
|
||||
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_AMD)
|
||||
return 0;
|
||||
|
@ -110,12 +144,21 @@ amdsmn_attach(device_t parent, device_t self, void *aux)
|
|||
struct amdsmn_softc *sc = device_private(self);
|
||||
struct pci_attach_args *pa = aux;
|
||||
int flags = 0;
|
||||
size_t i;
|
||||
|
||||
mutex_init(&sc->smn_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
sc->pa = *pa;
|
||||
sc->pc = pa->pa_pc;
|
||||
sc->pcitag = pa->pa_tag;
|
||||
aprint_normal(": AMD Family 17h System Management Network\n");
|
||||
|
||||
for (i = 0; i < __arraycount(amdsmn_ids); i++)
|
||||
if (PCI_PRODUCT(pa->pa_id) == amdsmn_ids[i].amdsmn_deviceid) {
|
||||
sc->smn_addr_reg = amdsmn_ids[i].amdsmn_addr_reg;
|
||||
sc->smn_data_reg = amdsmn_ids[i].amdsmn_data_reg;
|
||||
}
|
||||
|
||||
// aprint_normal(": AMD Family 17h System Management Network\n");
|
||||
aprint_normal(": AMD System Management Network\n");
|
||||
amdsmn_rescan(self, "amdsmnbus", &flags);
|
||||
}
|
||||
|
||||
|
@ -146,8 +189,8 @@ amdsmn_read(device_t dev, uint32_t addr, uint32_t *value)
|
|||
struct amdsmn_softc *sc = device_private(dev);
|
||||
|
||||
mutex_enter(&sc->smn_lock);
|
||||
pci_conf_write(sc->pc, sc->pcitag, SMN_ADDR_REG, addr);
|
||||
*value = pci_conf_read(sc->pc, sc->pcitag, SMN_DATA_REG);
|
||||
pci_conf_write(sc->pc, sc->pcitag, sc->smn_addr_reg, addr);
|
||||
*value = pci_conf_read(sc->pc, sc->pcitag, sc->smn_data_reg);
|
||||
mutex_exit(&sc->smn_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -159,8 +202,8 @@ amdsmn_write(device_t dev, uint32_t addr, uint32_t value)
|
|||
struct amdsmn_softc *sc = device_private(dev);
|
||||
|
||||
mutex_enter(&sc->smn_lock);
|
||||
pci_conf_write(sc->pc, sc->pcitag, SMN_ADDR_REG, addr);
|
||||
pci_conf_write(sc->pc, sc->pcitag, SMN_DATA_REG, value);
|
||||
pci_conf_write(sc->pc, sc->pcitag, sc->smn_addr_reg, addr);
|
||||
pci_conf_write(sc->pc, sc->pcitag, sc->smn_data_reg, value);
|
||||
mutex_exit(&sc->smn_lock);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/* $NetBSD: amdzentemp.c,v 1.7.2.2 2018/02/05 13:06:55 martin Exp $ */
|
||||
/* $NetBSD: amdzentemp.c,v 1.7.2.3 2022/10/11 18:22:44 martin Exp $ */
|
||||
/* $OpenBSD: kate.c,v 1.2 2008/03/27 04:52:03 cnst Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2008, 2020 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2019 Conrad Meyer <cem@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -50,7 +53,7 @@
|
|||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.7.2.2 2018/02/05 13:06:55 martin Exp $ ");
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.7.2.3 2022/10/11 18:22:44 martin Exp $ ");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -70,17 +73,64 @@ __KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.7.2.2 2018/02/05 13:06:55 martin Ex
|
|||
|
||||
#include "amdsmn.h"
|
||||
|
||||
/* Address to query for temp on family 17h */
|
||||
#define AMD_17H_CUR_TMP 0x59800
|
||||
#define AMD_CURTMP_RANGE_ADJUST 49000000 /* in microKelvins (ie, 49C) */
|
||||
#define AMD_CURTMP_RANGE_CHECK __BIT(19)
|
||||
#define F10_TEMP_CURTMP __BITS(31,21) /* XXX same as amdtemp.c */
|
||||
#define F10_TEMP_CURTMP_MASK 0x7ff
|
||||
#define F15M60_CURTMP_TJSEL __BITS(17,16)
|
||||
|
||||
/*
|
||||
* Reported Temperature, Family 15h, M60+
|
||||
*
|
||||
* Same register bit definitions as other Family 15h CPUs, but access is
|
||||
* indirect via SMN, like Family 17h.
|
||||
*/
|
||||
#define AMD_15H_M60H_REPTMP_CTRL 0xd8200ca4
|
||||
|
||||
/*
|
||||
* 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 AMD_17H_CUR_TMP 0x59800
|
||||
|
||||
/*
|
||||
* The following register set was discovered experimentally by Ondrej Čerman
|
||||
* and collaborators, but is not (yet) documented in a PPR/OSRR (other than
|
||||
* the M70H PPR SMN memory map showing [0x59800, +0x314] as allocated to
|
||||
* SMU::THM). It seems plausible and the Linux sensor folks have adopted it.
|
||||
*/
|
||||
#define AMD_17H_CCD_TMP_BASE 0x59954
|
||||
#define AMD_17H_CCD_TMP_VALID __BIT(11)
|
||||
|
||||
struct amdzentemp_softc {
|
||||
pci_chipset_tag_t sc_pc;
|
||||
pcitag_t sc_pcitag;
|
||||
device_t sc_dev;
|
||||
struct sysmon_envsys *sc_sme;
|
||||
device_t sc_smn;
|
||||
envsys_data_t *sc_sensor;
|
||||
size_t sc_sensor_len;
|
||||
size_t sc_numsensors;
|
||||
size_t sc_numsensors;
|
||||
int32_t sc_offset;
|
||||
uint32_t sc_ccd_tmp_base;
|
||||
};
|
||||
|
||||
enum {
|
||||
NOSENSOR = 0,
|
||||
CORE0_SENSOR0,
|
||||
CCD_BASE,
|
||||
CCD0 = CCD_BASE,
|
||||
CCD1,
|
||||
CCD2,
|
||||
CCD3,
|
||||
CCD4,
|
||||
CCD5,
|
||||
CCD6,
|
||||
CCD7,
|
||||
CCD_MAX,
|
||||
NUM_CCDS = CCD_MAX - CCD_BASE
|
||||
};
|
||||
|
||||
|
||||
|
@ -88,9 +138,12 @@ static int amdzentemp_match(device_t, cfdata_t, void *);
|
|||
static void amdzentemp_attach(device_t, device_t, void *);
|
||||
static int amdzentemp_detach(device_t, int);
|
||||
|
||||
static void amdzentemp_family17_init(struct amdzentemp_softc *);
|
||||
static void amdzentemp_family17_setup_sensors(struct amdzentemp_softc *, int);
|
||||
static void amdzentemp_init(struct amdzentemp_softc *, int, int);
|
||||
static void amdzentemp_setup_sensors(struct amdzentemp_softc *);
|
||||
static void amdzentemp_family15_refresh(struct sysmon_envsys *, envsys_data_t *);
|
||||
static void amdzentemp_family17_refresh(struct sysmon_envsys *, envsys_data_t *);
|
||||
static int amdzentemp_probe_ccd_sensors(struct amdzentemp_softc *, int, int);
|
||||
static void amdzentemp_setup_ccd_sensors(struct amdzentemp_softc *);
|
||||
|
||||
CFATTACH_DECL_NEW(amdzentemp, sizeof(struct amdzentemp_softc),
|
||||
amdzentemp_match, amdzentemp_attach, amdzentemp_detach, NULL);
|
||||
|
@ -101,9 +154,9 @@ amdzentemp_match(device_t parent, cfdata_t match, void *aux)
|
|||
struct pci_attach_args *pa __diagused = aux;
|
||||
|
||||
KASSERT(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD);
|
||||
|
||||
|
||||
cfdata_t parent_cfdata = device_cfdata(parent);
|
||||
|
||||
|
||||
/* Got AMD family 17h system management network */
|
||||
return parent_cfdata->cf_name &&
|
||||
memcmp(parent_cfdata->cf_name, "amdsmn", 6) == 0;
|
||||
|
@ -113,18 +166,21 @@ static void
|
|||
amdzentemp_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct amdzentemp_softc *sc = device_private(self);
|
||||
struct pci_attach_args *pa = aux;
|
||||
struct cpu_info *ci = curcpu();
|
||||
int family, model;
|
||||
int error;
|
||||
size_t i;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": AMD CPU Temperature Sensors (Family17h)");
|
||||
sc->sc_dev = self;
|
||||
|
||||
family = CPUID_TO_FAMILY(ci->ci_signature);
|
||||
model = CPUID_TO_MODEL(ci->ci_signature);
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": AMD CPU Temperature Sensors (Family%xh)", family);
|
||||
|
||||
sc->sc_pc = pa->pa_pc;
|
||||
sc->sc_pcitag = pa->pa_tag;
|
||||
sc->sc_smn = parent;
|
||||
|
||||
amdzentemp_family17_init(sc);
|
||||
|
||||
amdzentemp_init(sc, family, model);
|
||||
|
||||
aprint_normal("\n");
|
||||
|
||||
|
@ -132,12 +188,14 @@ amdzentemp_attach(device_t parent, device_t self, void *aux)
|
|||
sc->sc_sensor_len = sizeof(envsys_data_t) * sc->sc_numsensors;
|
||||
sc->sc_sensor = kmem_zalloc(sc->sc_sensor_len, KM_SLEEP);
|
||||
|
||||
amdzentemp_family17_setup_sensors(sc, device_unit(self));
|
||||
amdzentemp_setup_sensors(sc);
|
||||
|
||||
/*
|
||||
* Set properties in sensors.
|
||||
*/
|
||||
for (i = 0; i < sc->sc_numsensors; i++) {
|
||||
if (sc->sc_sensor[i].private == NOSENSOR)
|
||||
continue;
|
||||
if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i]))
|
||||
goto bad;
|
||||
}
|
||||
|
@ -148,7 +206,18 @@ amdzentemp_attach(device_t parent, device_t self, void *aux)
|
|||
sc->sc_sme->sme_name = device_xname(self);
|
||||
sc->sc_sme->sme_cookie = sc;
|
||||
|
||||
sc->sc_sme->sme_refresh = amdzentemp_family17_refresh;
|
||||
switch (family) {
|
||||
case 0x15:
|
||||
sc->sc_sme->sme_refresh = amdzentemp_family15_refresh;
|
||||
break;
|
||||
case 0x17:
|
||||
case 0x19:
|
||||
sc->sc_sme->sme_refresh = amdzentemp_family17_refresh;
|
||||
break;
|
||||
default:
|
||||
/* XXX panic */
|
||||
break;
|
||||
}
|
||||
|
||||
error = sysmon_envsys_register(sc->sc_sme);
|
||||
if (error) {
|
||||
|
@ -188,37 +257,206 @@ amdzentemp_detach(device_t self, int flags)
|
|||
|
||||
|
||||
static void
|
||||
amdzentemp_family17_init(struct amdzentemp_softc *sc)
|
||||
amdzentemp_init(struct amdzentemp_softc *sc, int family, int model)
|
||||
{
|
||||
sc->sc_numsensors = 1;
|
||||
|
||||
sc->sc_numsensors = 1 + amdzentemp_probe_ccd_sensors(sc, family, model);
|
||||
sc->sc_offset = 0;
|
||||
|
||||
if (strstr(cpu_brand_string, "AMD Ryzen 5 1600X")
|
||||
|| strstr(cpu_brand_string, "AMD Ryzen 7 1700X")
|
||||
|| strstr(cpu_brand_string, "AMD Ryzen 7 1800X"))
|
||||
sc->sc_offset = -20000000;
|
||||
else if (strstr(cpu_brand_string, "AMD Ryzen 7 2700X"))
|
||||
sc->sc_offset = -10000000;
|
||||
else if (strstr(cpu_brand_string, "AMD Ryzen Threadripper 19")
|
||||
|| strstr(cpu_brand_string, "AMD Ryzen Threadripper 29"))
|
||||
sc->sc_offset = -27000000;
|
||||
}
|
||||
|
||||
static void
|
||||
amdzentemp_family17_setup_sensors(struct amdzentemp_softc *sc, int dv_unit)
|
||||
amdzentemp_setup_sensors(struct amdzentemp_softc *sc)
|
||||
{
|
||||
sc->sc_sensor[0].units = ENVSYS_STEMP;
|
||||
sc->sc_sensor[0].state = ENVSYS_SVALID;
|
||||
sc->sc_sensor[0].flags = ENVSYS_FHAS_ENTROPY;
|
||||
sc->sc_sensor[0].private = CORE0_SENSOR0;
|
||||
|
||||
snprintf(sc->sc_sensor[0].desc, sizeof(sc->sc_sensor[0].desc),
|
||||
"cpu%u temperature", dv_unit);
|
||||
"cpu%u temperature", device_unit(sc->sc_dev));
|
||||
|
||||
if (sc->sc_numsensors > 1)
|
||||
amdzentemp_setup_ccd_sensors(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
amdzentemp_family17_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
amdzentemp_family15_refresh(struct sysmon_envsys *sme,
|
||||
envsys_data_t *edata)
|
||||
{
|
||||
struct amdzentemp_softc *sc = sme->sme_cookie;
|
||||
uint32_t temp;
|
||||
uint32_t val, temp;
|
||||
int error;
|
||||
|
||||
error = amdsmn_read(sc->sc_smn, AMD_17H_CUR_TMP, &temp);
|
||||
|
||||
error = amdsmn_read(sc->sc_smn, AMD_15H_M60H_REPTMP_CTRL, &val);
|
||||
if (error) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
/* from amdtemp.c:amdtemp_family10_refresh() */
|
||||
temp = __SHIFTOUT(val, F10_TEMP_CURTMP);
|
||||
|
||||
/* From Celsius to micro-Kelvin. */
|
||||
edata->value_cur = (temp * 125000) + 273150000;
|
||||
|
||||
/*
|
||||
* On Family 15h and higher, if CurTmpTjSel is 11b, the range is
|
||||
* adjusted down by 49.0 degrees Celsius. (This adjustment is not
|
||||
* documented in BKDGs prior to family 15h model 00h.)
|
||||
*
|
||||
* XXX should be in amdtemp.c:amdtemp_family10_refresh() for f15
|
||||
* as well??
|
||||
*/
|
||||
if (__SHIFTOUT(val, F15M60_CURTMP_TJSEL) == 0x3)
|
||||
edata->value_cur -= AMD_CURTMP_RANGE_ADJUST;
|
||||
|
||||
edata->state = ENVSYS_SVALID;
|
||||
/* From C to uK. */
|
||||
edata->value_cur = ((temp >> 21) * 125000) + 273150000;
|
||||
}
|
||||
|
||||
static void
|
||||
amdzentemp_family17_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
struct amdzentemp_softc *sc = sme->sme_cookie;
|
||||
uint32_t temp;
|
||||
bool minus49;
|
||||
int i, error;
|
||||
|
||||
switch (edata->private) {
|
||||
case CORE0_SENSOR0:
|
||||
/* Tctl */
|
||||
error = amdsmn_read(sc->sc_smn, AMD_17H_CUR_TMP, &temp);
|
||||
if (error) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
minus49 = (temp & AMD_CURTMP_RANGE_CHECK) ? true : false;
|
||||
temp = __SHIFTOUT(temp, F10_TEMP_CURTMP);
|
||||
break;
|
||||
case CCD_BASE ... (CCD_MAX - 1):
|
||||
/* Tccd */
|
||||
i = edata->private - CCD_BASE;
|
||||
error = amdsmn_read(sc->sc_smn,
|
||||
sc->sc_ccd_tmp_base + (i * sizeof(temp)), &temp);
|
||||
if (error || !ISSET(temp, AMD_17H_CCD_TMP_VALID)) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
minus49 = true;
|
||||
temp &= F10_TEMP_CURTMP_MASK;
|
||||
break;
|
||||
default:
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
return;
|
||||
}
|
||||
edata->state = ENVSYS_SVALID;
|
||||
/* From C to uK. */
|
||||
edata->value_cur = (temp * 125000) + 273150000;
|
||||
/* adjust for possible offset of 49K */
|
||||
if (minus49)
|
||||
edata->value_cur -= AMD_CURTMP_RANGE_ADJUST;
|
||||
edata->value_cur += sc->sc_offset;
|
||||
}
|
||||
|
||||
static int
|
||||
amdzentemp_probe_ccd_sensors17h(struct amdzentemp_softc *sc, int model)
|
||||
{
|
||||
int maxreg;
|
||||
|
||||
switch (model) {
|
||||
case 0x00 ... 0x2f: /* Zen1, Zen+ */
|
||||
maxreg = 4;
|
||||
break;
|
||||
case 0x30 ... 0x3f: /* Zen2 TR (Castle Peak)/EPYC (Rome) */
|
||||
case 0x60 ... 0x7f: /* Zen2 Ryzen (Renoir APU, Matisse) */
|
||||
case 0x90 ... 0x9f: /* Zen2 Ryzen (Van Gogh APU) */
|
||||
maxreg = 8;
|
||||
break;
|
||||
default:
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"Unrecognized Family 17h Model: %02xh\n", model);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return maxreg;
|
||||
}
|
||||
|
||||
static int
|
||||
amdzentemp_probe_ccd_sensors19h(struct amdzentemp_softc *sc, int model)
|
||||
{
|
||||
int maxreg;
|
||||
|
||||
switch (model) {
|
||||
case 0x00 ... 0x0f: /* Zen3 EPYC "Milan" */
|
||||
case 0x20 ... 0x2f: /* Zen3 Ryzen "Vermeer" */
|
||||
maxreg = 8;
|
||||
break;
|
||||
case 0x60 ... 0x6f: /* Zen4 Ryzen "Raphael" */
|
||||
sc->sc_ccd_tmp_base = 0x59b08;
|
||||
maxreg = 8;
|
||||
break;
|
||||
default:
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"Unrecognized Family 19h Model: %02xh\n", model);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return maxreg;
|
||||
}
|
||||
|
||||
static int
|
||||
amdzentemp_probe_ccd_sensors(struct amdzentemp_softc *sc, int family, int model)
|
||||
{
|
||||
int nccd;
|
||||
|
||||
/* Set default CCD temp sensor base address. */
|
||||
sc->sc_ccd_tmp_base = 0x59954;
|
||||
|
||||
switch (family) {
|
||||
case 0x17:
|
||||
nccd = amdzentemp_probe_ccd_sensors17h(sc, model);
|
||||
break;
|
||||
case 0x19:
|
||||
nccd = amdzentemp_probe_ccd_sensors19h(sc, model);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nccd;
|
||||
}
|
||||
|
||||
static void
|
||||
amdzentemp_setup_ccd_sensors(struct amdzentemp_softc *sc)
|
||||
{
|
||||
envsys_data_t *edata;
|
||||
size_t i;
|
||||
uint32_t temp;
|
||||
int error;
|
||||
|
||||
for (i = 0; i < sc->sc_numsensors - 1; i++) {
|
||||
error = amdsmn_read(sc->sc_smn,
|
||||
sc->sc_ccd_tmp_base + (i * sizeof(temp)), &temp);
|
||||
if (error || !ISSET(temp, AMD_17H_CCD_TMP_VALID))
|
||||
continue;
|
||||
|
||||
edata = &sc->sc_sensor[1 + i];
|
||||
edata->units = ENVSYS_STEMP;
|
||||
edata->state = ENVSYS_SVALID;
|
||||
edata->flags = ENVSYS_FHAS_ENTROPY;
|
||||
edata->private = CCD_BASE + i;
|
||||
snprintf(edata->desc, sizeof(edata->desc),
|
||||
"cpu%u ccd%zu temperature", device_unit(sc->sc_dev), i);
|
||||
}
|
||||
}
|
||||
|
||||
MODULE(MODULE_CLASS_DRIVER, amdzentemp, "sysmon_envsys,amdsmn");
|
||||
|
@ -249,4 +487,3 @@ amdzentemp_modcmd(modcmd_t cmd, void *aux)
|
|||
return ENOTTY;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue