Pull up following revision(s) (requested by msaitoh in ticket #1539):
share/man/man4/man4.x86/amdsmn.4: revision 1.5 sys/arch/x86/pci/amdsmn.c: revision 1.14 sys/arch/x86/pci/amdzentemp.c: revision 1.12-1.15 amdzentemp(4): Add Zen 3 support. amdzentemp(4): Add support for per CCD temperature sensor from FreeBSD. Fix build failure on i386. amdsmn(4),amdzentemp(4): Add support for 17h/6xh and 19h/6xh. amdsmn.4: Now support AMD Family 19h processors.
This commit is contained in:
parent
9a522ca6be
commit
d5badbfc7a
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: amdsmn.4,v 1.3.8.1 2020/04/24 17:46:44 martin Exp $
|
||||
.\" $NetBSD: amdsmn.4,v 1.3.8.2 2022/10/11 18:16:20 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 April 20, 2020
|
||||
.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 and some later AMD Family 15h 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: amdsmn.c,v 1.5.2.2 2022/07/27 14:40:08 martin Exp $ */
|
||||
/* $NetBSD: amdsmn.c,v 1.5.2.3 2022/10/11 18:16:20 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017, 2019 Conrad Meyer <cem@FreeBSD.org>
|
||||
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.5.2.2 2022/07/27 14:40:08 martin Exp $ ");
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.5.2.3 2022/10/11 18:16:20 martin Exp $ ");
|
||||
|
||||
/*
|
||||
* Driver for the AMD Family 15h (model 60+) and 17h CPU
|
||||
|
@ -87,11 +87,21 @@ static const struct pciid {
|
|||
.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 *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: amdzentemp.c,v 1.9.2.1 2020/04/24 17:46:44 martin Exp $ */
|
||||
/* $NetBSD: amdzentemp.c,v 1.9.2.2 2022/10/11 18:16:20 martin Exp $ */
|
||||
/* $OpenBSD: kate.c,v 1.2 2008/03/27 04:52:03 cnst Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -53,7 +53,7 @@
|
|||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.9.2.1 2020/04/24 17:46:44 martin Exp $ ");
|
||||
__KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.9.2.2 2022/10/11 18:16:20 martin Exp $ ");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -76,6 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.9.2.1 2020/04/24 17:46:44 martin Ex
|
|||
#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)
|
||||
|
||||
/*
|
||||
|
@ -96,13 +97,40 @@ __KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.9.2.1 2020/04/24 17:46:44 martin Ex
|
|||
*/
|
||||
#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 {
|
||||
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;
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
|
@ -110,10 +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_init(struct amdzentemp_softc *);
|
||||
static void amdzentemp_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);
|
||||
|
@ -124,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;
|
||||
|
@ -137,18 +167,20 @@ amdzentemp_attach(device_t parent, device_t self, void *aux)
|
|||
{
|
||||
struct amdzentemp_softc *sc = device_private(self);
|
||||
struct cpu_info *ci = curcpu();
|
||||
int family;
|
||||
int family, model;
|
||||
int error;
|
||||
size_t i;
|
||||
|
||||
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);
|
||||
aprint_normal(": AMD CPU Temperature Sensors (Family%xh)", family);
|
||||
|
||||
sc->sc_smn = parent;
|
||||
|
||||
amdzentemp_init(sc);
|
||||
amdzentemp_init(sc, family, model);
|
||||
|
||||
aprint_normal("\n");
|
||||
|
||||
|
@ -156,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_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;
|
||||
}
|
||||
|
@ -177,6 +211,7 @@ amdzentemp_attach(device_t parent, device_t self, void *aux)
|
|||
sc->sc_sme->sme_refresh = amdzentemp_family15_refresh;
|
||||
break;
|
||||
case 0x17:
|
||||
case 0x19:
|
||||
sc->sc_sme->sme_refresh = amdzentemp_family17_refresh;
|
||||
break;
|
||||
default:
|
||||
|
@ -222,10 +257,10 @@ amdzentemp_detach(device_t self, int flags)
|
|||
|
||||
|
||||
static void
|
||||
amdzentemp_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")
|
||||
|
@ -240,24 +275,28 @@ amdzentemp_init(struct amdzentemp_softc *sc)
|
|||
}
|
||||
|
||||
static void
|
||||
amdzentemp_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_family15_refresh(struct sysmon_envsys *sme,
|
||||
envsys_data_t *edata)
|
||||
envsys_data_t *edata)
|
||||
{
|
||||
struct amdzentemp_softc *sc = sme->sme_cookie;
|
||||
uint32_t val, temp;
|
||||
int error;
|
||||
|
||||
|
||||
error = amdsmn_read(sc->sc_smn, AMD_15H_M60H_REPTMP_CTRL, &val);
|
||||
if (error) {
|
||||
edata->state = ENVSYS_SINVALID;
|
||||
|
@ -285,26 +324,141 @@ amdzentemp_family15_refresh(struct sysmon_envsys *sme,
|
|||
}
|
||||
|
||||
static void
|
||||
amdzentemp_family17_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
amdzentemp_family17_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
struct amdzentemp_softc *sc = sme->sme_cookie;
|
||||
uint32_t temp;
|
||||
int error;
|
||||
|
||||
error = amdsmn_read(sc->sc_smn, AMD_17H_CUR_TMP, &temp);
|
||||
if (error) {
|
||||
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 >> 21) * 125000) + 273150000;
|
||||
/* From C to uK. */
|
||||
edata->value_cur = (temp * 125000) + 273150000;
|
||||
/* adjust for possible offset of 49K */
|
||||
if (temp & AMD_CURTMP_RANGE_CHECK)
|
||||
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");
|
||||
|
||||
#ifdef _MODULE
|
||||
|
|
Loading…
Reference in New Issue