On Tue, Sep 17, 2019 at 12:41:11PM -0400, Bryan Steele wrote:
> Unlike with previous generations of AMD processors, the on-die
> temperature sensor is only available from reading from the SMU
> co-processor over an internal network (SMN), this includes all
> Ryzen CPUs and some later Family 15h models (not supported here).
>
> This adds a new driver based on km(4) and info gleamed from Linux
> FreeBSD.
>
> High-TDP Zen/Zen+ parts have undocumented offsets from the control temp
> and need to be adjusted, low-TDP (mobile) and Zen2 have no offsets.
>
> I've tested this on a Ryzen 2700X desktop and a Ryzen 5 2500U (mobile)
> laptop (no offset). I would appreciate feedback on other models, and
> confirmation about Zen2.
>
> Thanks to @[email protected] for the providing helpful information and
> much needed prodding.
>
> -Bryan.
>

This works on my Ryzen 2700U, thanks!

kmsmn0 at pci0 dev 0 function 0 "AMD AMD64 17h/1xh Root Complex" rev 0x00

kmsmn0.temp0                             60.88 degC

-ml

> Index: arch/amd64/conf/GENERIC
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
> retrieving revision 1.478
> diff -u -p -u -r1.478 GENERIC
> --- sys/arch/amd64/conf/GENERIC       7 Sep 2019 13:46:19 -0000       1.478
> +++ sys/arch/amd64/conf/GENERIC       17 Sep 2019 16:24:03 -0000
> @@ -103,6 +103,7 @@ amdpcib* at pci?          # AMD 8111 LPC bridge
>  tcpcib*      at pci?                 # Intel Atom E600 LPC bridge
>  kate*        at pci?                 # AMD K8 temperature sensor
>  km*  at pci?                 # AMD K10 temperature sensor
> +kmsmn*       at pci?                 # AMD F17 temperature sensor
>  amas*        at pci? disable         # AMD memory configuration
>  pchtemp* at pci?             # Intel C610 termperature sensor
>  ccp* at pci?                 # AMD Cryptographic Co-processor
> Index: dev/pci/files.pci
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/files.pci,v
> retrieving revision 1.338
> diff -u -p -u -r1.338 files.pci
> --- sys/dev/pci/files.pci     5 Aug 2019 08:33:38 -0000       1.338
> +++ sys/dev/pci/files.pci     17 Sep 2019 16:24:03 -0000
> @@ -774,6 +774,11 @@ device   km
>  attach       km at pci
>  file dev/pci/km.c                    km
>
> +# AMD Family 15h/17h Temperature sensor over SMN
> +device       kmsmn
> +attach       kmsmn at pci
> +file dev/pci/kmsmn.c                 kmsmn
> +
>  # Intel SOC GCU
>  device       gcu
>  attach       gcu at pci
> Index: dev/pci/kmsmn.c
> ===================================================================
> RCS file: dev/pci/kmsmn.c
> diff -N dev/pci/kmsmn.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ sys/dev/pci/kmsmn.c       17 Sep 2019 16:24:03 -0000
> @@ -0,0 +1,170 @@
> +/*   $OpenBSD$       */
> +
> +/*
> + * Copyright (c) 2019 Bryan Steele <[email protected]>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/device.h>
> +#include <sys/sensors.h>
> +
> +#include <machine/bus.h>
> +
> +#include <dev/pci/pcivar.h>
> +#include <dev/pci/pcidevs.h>
> +
> +/*
> + * AMD temperature sensors on Family 17h (and some 15h) must be
> + * read from the System Management Unit (SMU) co-processor over
> + * the System Management Network (SMN).
> + */
> +
> +#define SMN_17H_ADDR_R 0x60
> +#define SMN_17H_DATA_R 0x64
> +
> +/*
> +  * AMD Family 17h SMU Thermal Registers (THM)
> +  *
> +  * 4.2.1, OSRR (Open-Source Register Reference) Guide for Family 17h
> +  *     [31:21]  Current reported temperature.
> +  */
> +#define SMU_17H_THM          0x59800
> +#define KM_GET_CURTMP(r)     (((r) >> 21) & 0x7ff)
> +
> +/*
> + * Bit 19 set: "Report on -49C to 206C scale range."
> + *      clear: "Report on 0C to 225C (255C?) scale range."
> + */
> +#define CURTMP_17H_RANGE_SEL (1 << 19)
> +#define CURTMP_17H_RANGE_ADJUST      490
> +
> +/*
> + * Undocumented tCTL offsets gleamed from Linux k10temp driver.
> + */
> +struct curtmp_offset {
> +     const char *const cpu_model; /* partial match */
> +     int tctl_offset;
> +} cpu_model_offsets[] = {
> +     { "AMD Ryzen 5 1600X", 200 },
> +     { "AMD Ryzen 7 1700X", 200 },
> +     { "AMD Ryzen 7 1800X", 200 },
> +     { "AMD Ryzen 7 2700X", 100 },
> +     { "AMD Ryzen Threadripper 19", 270 }, /* many models */
> +     { "AMD Ryzen Threadripper 29", 270 }, /* many models */
> +     { NULL, 0 },
> +     /* ... */
> +};
> +
> +struct kmsmn_softc {
> +     struct device           sc_dev;
> +
> +     pci_chipset_tag_t       sc_pc;
> +     pcitag_t                sc_pcitag;
> +
> +     int                     sc_tctl_offset;
> +     struct mutex            sc_smnlock;
> +
> +     struct ksensor          sc_sensor;
> +     struct ksensordev       sc_sensordev;
> +};
> +
> +int  kmsmn_match(struct device *, void *, void *);
> +void kmsmn_attach(struct device *, struct device *, void *);
> +void kmsmn_refresh(void *);
> +
> +struct cfattach kmsmn_ca = {
> +     sizeof(struct kmsmn_softc), kmsmn_match, kmsmn_attach
> +};
> +
> +struct cfdriver kmsmn_cd = {
> +     NULL, "kmsmn", DV_DULL
> +};
> +
> +static const struct pci_matchid kmsmn_devices[] = {
> +     { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_17_RC },
> +     { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_17_1X_RC },
> +     { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_17_3X_RC }
> +};
> +
> +int
> +kmsmn_match(struct device *parent, void *match, void *aux)
> +{
> +     /* successful match supersedes pchb(4) */
> +     return pci_matchbyid((struct pci_attach_args *)aux, kmsmn_devices,
> +         sizeof(kmsmn_devices) / sizeof(kmsmn_devices[0])) * 2;
> +}
> +
> +void
> +kmsmn_attach(struct device *parent, struct device *self, void *aux)
> +{
> +     struct kmsmn_softc      *sc = (struct kmsmn_softc *)self;
> +     struct pci_attach_args  *pa = aux;
> +     struct curtmp_offset    *p;
> +     extern char             cpu_model[];
> +
> +     sc->sc_pc = pa->pa_pc;
> +     sc->sc_pcitag = pa->pa_tag;
> +
> +     strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
> +         sizeof(sc->sc_sensordev.xname));
> +
> +     sc->sc_sensor.type = SENSOR_TEMP;
> +     sensor_attach(&sc->sc_sensordev, &sc->sc_sensor);
> +
> +     /*
> +      * Zen/Zen+ CPUs are offset if TDP > 65, otherwise 0.
> +      * Zen 2 models appear to have no tCTL offset, so always 0.
> +      *
> +      * XXX: Does any public documentation exist for this?
> +      */
> +     for (p = cpu_model_offsets; p->cpu_model != NULL; p++) {
> +             if (!strncmp(cpu_model, p->cpu_model, strlen(p->cpu_model)))
> +                     sc->sc_tctl_offset = p->tctl_offset;
> +     }
> +
> +     /* For accessing the SMU */
> +     mtx_init(&sc->sc_smnlock, IPL_NONE);
> +     if (sensor_task_register(sc, kmsmn_refresh, 5) == NULL) {
> +             printf(": unable to register update task\n");
> +             return;
> +     }
> +
> +     sensordev_install(&sc->sc_sensordev);
> +
> +     printf("\n");
> +}
> +
> +void
> +kmsmn_refresh(void *arg)
> +{
> +     struct kmsmn_softc      *sc = arg;
> +     struct ksensor  *s = &sc->sc_sensor;
> +     pcireg_t        reg;
> +     int             c;
> +
> +     mtx_enter(&sc->sc_smnlock);
> +     pci_conf_write(sc->sc_pc, sc->sc_pcitag, SMN_17H_ADDR_R,
> +         SMU_17H_THM);
> +     reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, SMN_17H_DATA_R);
> +     mtx_leave(&sc->sc_smnlock);
> +
> +     c = KM_GET_CURTMP(reg) * 5 / 4; /* 1.25 */
> +     if ((reg & CURTMP_17H_RANGE_SEL) != 0)
> +             c -= CURTMP_17H_RANGE_ADJUST;
> +     if (c > sc->sc_tctl_offset)
> +             c -= sc->sc_tctl_offset;
> +     s->value = c * 125000 + 273150000;
> +}
> Index: dev/pci/pcidevs
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/pcidevs,v
> retrieving revision 1.1895
> diff -u -p -u -r1.1895 pcidevs
> --- sys/dev/pci/pcidevs       23 Aug 2019 01:18:08 -0000      1.1895
> +++ sys/dev/pci/pcidevs       17 Sep 2019 16:24:03 -0000
> @@ -753,6 +753,7 @@ product AMD AMD64_17_DF_8 0x1467  AMD64 1
>  product AMD AMD64_17_CCP_2   0x1468  AMD64 17h Crypto
>  product AMD AMD64_17_PCIE_4  0x1470  AMD64 17h PCIE
>  product AMD AMD64_17_PCIE_5  0x1471  AMD64 17h PCIE
> +product AMD AMD64_17_3X_RC   0x1480  AMD64 17h/3xh Root Complex
>  product AMD AMD64_14_HB              0x1510  AMD64 14h Host
>  product AMD AMD64_14_PCIE_1  0x1512  AMD64 14h PCIE
>  product AMD AMD64_14_PCIE_2  0x1513  AMD64 14h PCIE
> Index: dev/pci/pcidevs.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/pcidevs.h,v
> retrieving revision 1.1888
> diff -u -p -u -r1.1888 pcidevs.h
> --- sys/dev/pci/pcidevs.h     23 Aug 2019 01:19:24 -0000      1.1888
> +++ sys/dev/pci/pcidevs.h     17 Sep 2019 16:24:04 -0000
> @@ -758,6 +758,7 @@
>  #define      PCI_PRODUCT_AMD_AMD64_17_CCP_2  0x1468          /* AMD64 17h 
> Crypto */
>  #define      PCI_PRODUCT_AMD_AMD64_17_PCIE_4 0x1470          /* AMD64 17h 
> PCIE */
>  #define      PCI_PRODUCT_AMD_AMD64_17_PCIE_5 0x1471          /* AMD64 17h 
> PCIE */
> +#define      PCI_PRODUCT_AMD_AMD64_17_3X_RC  0x1480          /* AMD64 
> 17h/3xh Root Complex */
>  #define      PCI_PRODUCT_AMD_AMD64_14_HB     0x1510          /* AMD64 14h 
> Host */
>  #define      PCI_PRODUCT_AMD_AMD64_14_PCIE_1 0x1512          /* AMD64 14h 
> PCIE */
>  #define      PCI_PRODUCT_AMD_AMD64_14_PCIE_2 0x1513          /* AMD64 14h 
> PCIE */
> Index: dev/pci/pcidevs_data.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/pcidevs_data.h,v
> retrieving revision 1.1883
> diff -u -p -u -r1.1883 pcidevs_data.h
> --- sys/dev/pci/pcidevs_data.h        23 Aug 2019 01:19:24 -0000      1.1883
> +++ sys/dev/pci/pcidevs_data.h        17 Sep 2019 16:24:04 -0000
> @@ -1356,6 +1356,10 @@ static const struct pci_known_product pc
>           "AMD64 17h PCIE",
>       },
>       {
> +         PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_17_3X_RC,
> +         "AMD64 17h/3xh Root Complex",
> +     },
> +     {
>           PCI_VENDOR_AMD, PCI_PRODUCT_AMD_AMD64_14_HB,
>           "AMD64 14h Host",
>       },
>

Reply via email to