Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86/pci Update to support Family 15h Model 60 tempe...



details:   https://anonhg.NetBSD.org/src/rev/229f4dfddfe9
branches:  trunk
changeset: 971284:229f4dfddfe9
user:      simonb <simonb%NetBSD.org@localhost>
date:      Mon Apr 20 11:03:02 2020 +0000

description:
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.

diffstat:

 sys/arch/x86/pci/amdsmn.c     |   61 +++++++++++++++++-----
 sys/arch/x86/pci/amdzentemp.c |  110 +++++++++++++++++++++++++++++++++--------
 2 files changed, 135 insertions(+), 36 deletions(-)

diffs (truncated from 330 to 300 lines):

diff -r 56411113bd84 -r 229f4dfddfe9 sys/arch/x86/pci/amdsmn.c
--- a/sys/arch/x86/pci/amdsmn.c Mon Apr 20 05:22:28 2020 +0000
+++ b/sys/arch/x86/pci/amdsmn.c Mon Apr 20 11:03:02 2020 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: amdsmn.c,v 1.6 2019/08/06 05:32:44 msaitoh Exp $       */
+/*     $NetBSD: amdsmn.c,v 1.7 2020/04/20 11:03:02 simonb Exp $        */
 
 /*-
- * Copyright (c) 2017 Conrad Meyer <cem%FreeBSD.org@localhost>
+ * Copyright (c) 2017, 2019 Conrad Meyer <cem%FreeBSD.org@localhost>
  * All rights reserved.
  *
  * NetBSD port by Ian Clark <mrrooster%gmail.com@localhost>
@@ -29,10 +29,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.6 2019/08/06 05:32:44 msaitoh Exp $ ");
+__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.7 2020/04/20 11:03:02 simonb 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 @@
 #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,29 @@
 
 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_60_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_7X_RC,
+               .amdsmn_addr_reg = F17H_SMN_ADDR_REG,
+               .amdsmn_data_reg = F17H_SMN_DATA_REG,
+       },
 };
 
 static int amdsmn_match(device_t, cfdata_t, void *);
@@ -110,12 +134,21 @@
        struct amdsmn_softc *sc = device_private(self);
        struct pci_attach_args *pa = aux;
        int flags = 0;
+       int 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 +179,8 @@
        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 +192,8 @@
        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;
diff -r 56411113bd84 -r 229f4dfddfe9 sys/arch/x86/pci/amdzentemp.c
--- a/sys/arch/x86/pci/amdzentemp.c     Mon Apr 20 05:22:28 2020 +0000
+++ b/sys/arch/x86/pci/amdzentemp.c     Mon Apr 20 11:03:02 2020 +0000
@@ -1,8 +1,11 @@
-/*      $NetBSD: amdzentemp.c,v 1.9 2019/06/16 09:12:51 mlelstv Exp $ */
+/*      $NetBSD: amdzentemp.c,v 1.10 2020/04/20 11:03:02 simonb 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@localhost>
  * 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.9 2019/06/16 09:12:51 mlelstv Exp $ ");
+__KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.10 2020/04/20 11:03:02 simonb Exp $ ");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -70,17 +73,35 @@
 
 #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        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
 
 struct amdzentemp_softc {
-        pci_chipset_tag_t sc_pc;
-        pcitag_t sc_pcitag;
        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;
 };
 
@@ -89,8 +110,9 @@
 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 *);
+static void amdzentemp_setup_sensors(struct amdzentemp_softc *, int);
+static void amdzentemp_family15_refresh(struct sysmon_envsys *, envsys_data_t *);
 static void amdzentemp_family17_refresh(struct sysmon_envsys *, envsys_data_t *);
 
 CFATTACH_DECL_NEW(amdzentemp, sizeof(struct amdzentemp_softc),
@@ -114,18 +136,19 @@
 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;
        int error;
        size_t i;
 
+       family = CPUID_TO_FAMILY(ci->ci_signature);
        aprint_naive("\n");
-       aprint_normal(": AMD CPU Temperature Sensors (Family17h)");
+       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);
 
        aprint_normal("\n");
 
@@ -133,7 +156,7 @@
        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, device_unit(self));
 
        /*
         * Set properties in sensors.
@@ -149,7 +172,17 @@
        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:
+               sc->sc_sme->sme_refresh = amdzentemp_family17_refresh;
+               break;
+       default:
+               /* XXX panic */
+               break;
+       }
 
        error = sysmon_envsys_register(sc->sc_sme);
        if (error) {
@@ -189,7 +222,7 @@
 
 
 static void
-amdzentemp_family17_init(struct amdzentemp_softc *sc) 
+amdzentemp_init(struct amdzentemp_softc *sc) 
 {
 
        sc->sc_numsensors = 1;
@@ -207,7 +240,7 @@
 }
 
 static void
-amdzentemp_family17_setup_sensors(struct amdzentemp_softc *sc, int dv_unit) 
+amdzentemp_setup_sensors(struct amdzentemp_softc *sc, int dv_unit) 
 {
        sc->sc_sensor[0].units = ENVSYS_STEMP;
        sc->sc_sensor[0].state = ENVSYS_SVALID;
@@ -218,6 +251,40 @@
 }
 
 static void
+amdzentemp_family15_refresh(struct sysmon_envsys *sme,
+    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;
+               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.)



Home | Main Index | Thread Index | Old Index