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