Lines Matching +full:temp +full:- +full:sensor

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2009-2012 Jung-uk Kim <jkim@FreeBSD.org>
8 * Copyright (c) 2017-2020 Conrad Meyer <cem@FreeBSD.org>. All rights reserved.
33 * Driver for the AMD CPU on-die thermal sensors.
77 NUM_CCDS = CCD_MAX - CCD_BASE + 1,
85 #define AMDTEMP_FLAG_CT_10BIT 0x02 /* CurTmp is 10-bit wide. */
86 #define AMDTEMP_FLAG_ALT_OFFSET 0x04 /* CurTmp starts at -28C. */
128 * 0xFC register is only valid on the D18F3 PCI device; SMN temp
157 * Reported Temperature Control Register, family 0Fh-15h (some models), 16h.
175 * Reported Temperature, Family 17h - 1Ah
177 * According to AMD OSRR for 17H, section 4.2.1, bits 31-21 of this register
178 * provide the current temp. bit 19, when clear, means the temp is reported in
180 * to -49..206C.
185 * Bits 16-17, when set, mean that CUR_TMP is read-write. When it is, the
194 * SMU::THM). It seems plausible and the Linux sensor folks have adopted it.
233 static int32_t amdtemp_gettemp0f(device_t dev, amdsensor_t sensor);
234 static int32_t amdtemp_gettemp(device_t dev, amdsensor_t sensor);
235 static int32_t amdtemp_gettemp15hm60h(device_t dev, amdsensor_t sensor);
236 static int32_t amdtemp_gettemp17h(device_t dev, amdsensor_t sensor);
344 device_set_descf(dev, "AMD Family %02Xh CPU On-Die Thermal Sensors", in amdtemp_probe()
377 * revision multi-socket system where the attach thread is potentially in amdtemp_attach()
387 if (product->amdtemp_has_cpuid && (family > 0x0f || in amdtemp_attach()
400 * - ThermSenseCoreSel in amdtemp_attach()
402 * Revision F & G: 0 - Core1, 1 - Core0 in amdtemp_attach()
403 * Other: 0 - Core0, 1 - Core1 in amdtemp_attach()
405 * - CurTmp in amdtemp_attach()
407 * Revision G: bits 23-14 in amdtemp_attach()
408 * Other: bits 23-16 in amdtemp_attach()
418 * XXX According to Linux, CurTmp starts at -28C on in amdtemp_attach()
423 sc->sc_flags |= AMDTEMP_FLAG_CS_SWAP; in amdtemp_attach()
434 sc->sc_flags |= in amdtemp_attach()
441 sc->sc_flags |= in amdtemp_attach()
445 sc->sc_flags |= AMDTEMP_FLAG_ALT_OFFSET; in amdtemp_attach()
447 sc->sc_flags |= AMDTEMP_FLAG_CT_10BIT; in amdtemp_attach()
453 sc->sc_ntemps = 2; in amdtemp_attach()
455 sc->sc_gettemp = amdtemp_gettemp0f; in amdtemp_attach()
475 /* XXX 00100F42h (RB-C2) exists in both formats. */ in amdtemp_attach()
485 sc->sc_ntemps = 1; in amdtemp_attach()
489 * from 17h and the decoding matches other 10h-15h models, in amdtemp_attach()
493 sc->sc_gettemp = amdtemp_gettemp15hm60h; in amdtemp_attach()
496 sc->sc_gettemp = amdtemp_gettemp; in amdtemp_attach()
501 sc->sc_ntemps = 1; in amdtemp_attach()
502 sc->sc_gettemp = amdtemp_gettemp17h; in amdtemp_attach()
511 sc->sc_smn = device_find_child( in amdtemp_attach()
512 device_get_parent(dev), "amdsmn", -1); in amdtemp_attach()
513 if (sc->sc_smn == NULL) { in amdtemp_attach()
521 sc->sc_ncores = (amd_feature2 & AMDID2_CMP) != 0 ? in amdtemp_attach()
523 if (sc->sc_ncores > MAXCPU) in amdtemp_attach()
526 mtx_init(&sc->sc_lock, "amdtemp", NULL, MTX_DEF); in amdtemp_attach()
532 sc->sc_ncores, in amdtemp_attach()
533 sc->sc_ntemps > 1 ? sc->sc_ntemps * sc->sc_ncores : 1); in amdtemp_attach()
540 TUNABLE_INT_FETCH(tn, &sc->sc_offset); in amdtemp_attach()
545 "sensor_offset", CTLFLAG_RW, &sc->sc_offset, 0, in amdtemp_attach()
546 "Temperature sensor offset"); in amdtemp_attach()
556 "Core 0 / Sensor 0 temperature"); in amdtemp_attach()
558 sc->sc_temp_base = AMDTEMP_17H_CCD_TMP_BASE; in amdtemp_attach()
566 else if (sc->sc_ntemps > 1) { in amdtemp_attach()
572 "Core 0 / Sensor 1 temperature"); in amdtemp_attach()
574 if (sc->sc_ncores > 1) { in amdtemp_attach()
585 "Core 1 / Sensor 0 temperature"); in amdtemp_attach()
592 "Core 1 / Sensor 1 temperature"); in amdtemp_attach()
602 sc->sc_ich.ich_func = amdtemp_intrhook; in amdtemp_attach()
603 sc->sc_ich.ich_arg = dev; in amdtemp_attach()
604 if (config_intrhook_establish(&sc->sc_ich) != 0) { in amdtemp_attach()
619 amdsensor_t sensor; in amdtemp_intrhook() local
630 for (i = 0; i < sc->sc_ncores; i++) { in amdtemp_intrhook()
631 if (sc->sc_sysctl_cpu[i] != NULL) in amdtemp_intrhook()
634 device_get_unit(dev) * sc->sc_ncores + i); in amdtemp_intrhook()
638 sensor = sc->sc_ntemps > 1 ? in amdtemp_intrhook()
640 sc->sc_sysctl_cpu[i] = SYSCTL_ADD_PROC(sysctlctx, in amdtemp_intrhook()
644 dev, sensor, amdtemp_sysctl, "IK", in amdtemp_intrhook()
648 if (sc->sc_ich.ich_arg != NULL) in amdtemp_intrhook()
649 config_intrhook_disestablish(&sc->sc_ich); in amdtemp_intrhook()
658 for (i = 0; i < sc->sc_ncores; i++) in amdtemp_detach()
659 if (sc->sc_sysctl_cpu[i] != NULL) in amdtemp_detach()
660 sysctl_remove_oid(sc->sc_sysctl_cpu[i], 1, 0); in amdtemp_detach()
664 mtx_destroy(&sc->sc_lock); in amdtemp_detach()
673 amdsensor_t sensor = (amdsensor_t)arg2; in amdtemp_sysctl() local
674 int32_t auxtemp[2], temp; in amdtemp_sysctl() local
677 switch (sensor) { in amdtemp_sysctl()
679 auxtemp[0] = sc->sc_gettemp(dev, CORE0_SENSOR0); in amdtemp_sysctl()
680 auxtemp[1] = sc->sc_gettemp(dev, CORE0_SENSOR1); in amdtemp_sysctl()
681 temp = imax(auxtemp[0], auxtemp[1]); in amdtemp_sysctl()
684 auxtemp[0] = sc->sc_gettemp(dev, CORE1_SENSOR0); in amdtemp_sysctl()
685 auxtemp[1] = sc->sc_gettemp(dev, CORE1_SENSOR1); in amdtemp_sysctl()
686 temp = imax(auxtemp[0], auxtemp[1]); in amdtemp_sysctl()
689 temp = sc->sc_gettemp(dev, sensor); in amdtemp_sysctl()
692 error = sysctl_handle_int(oidp, &temp, 0, req); in amdtemp_sysctl()
700 amdtemp_gettemp0f(device_t dev, amdsensor_t sensor) in amdtemp_gettemp0f() argument
703 uint32_t mask, offset, temp; in amdtemp_gettemp0f() local
705 mtx_lock(&sc->sc_lock); in amdtemp_gettemp0f()
707 /* Set Sensor/Core selector. */ in amdtemp_gettemp0f()
708 temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 1); in amdtemp_gettemp0f()
709 temp &= ~(AMDTEMP_TTSR_SELCORE | AMDTEMP_TTSR_SELSENSOR); in amdtemp_gettemp0f()
710 switch (sensor) { in amdtemp_gettemp0f()
712 temp |= AMDTEMP_TTSR_SELSENSOR; in amdtemp_gettemp0f()
716 if ((sc->sc_flags & AMDTEMP_FLAG_CS_SWAP) != 0) in amdtemp_gettemp0f()
717 temp |= AMDTEMP_TTSR_SELCORE; in amdtemp_gettemp0f()
720 temp |= AMDTEMP_TTSR_SELSENSOR; in amdtemp_gettemp0f()
724 if ((sc->sc_flags & AMDTEMP_FLAG_CS_SWAP) == 0) in amdtemp_gettemp0f()
725 temp |= AMDTEMP_TTSR_SELCORE; in amdtemp_gettemp0f()
730 pci_write_config(dev, AMDTEMP_THERMTP_STAT, temp, 1); in amdtemp_gettemp0f()
732 mask = (sc->sc_flags & AMDTEMP_FLAG_CT_10BIT) != 0 ? 0x3ff : 0x3fc; in amdtemp_gettemp0f()
733 offset = (sc->sc_flags & AMDTEMP_FLAG_ALT_OFFSET) != 0 ? 28 : 49; in amdtemp_gettemp0f()
734 temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 4); in amdtemp_gettemp0f()
735 temp = ((temp >> 14) & mask) * 5 / 2; in amdtemp_gettemp0f()
736 temp += AMDTEMP_ZERO_C_TO_K + (sc->sc_offset - offset) * 10; in amdtemp_gettemp0f()
738 mtx_unlock(&sc->sc_lock); in amdtemp_gettemp0f()
739 return (temp); in amdtemp_gettemp0f()
745 uint32_t temp; in amdtemp_decode_fam10h_to_17h() local
748 temp = (val & AMDTEMP_REPTMP10H_CURTMP_MASK) * 5 / 4; in amdtemp_decode_fam10h_to_17h()
751 temp -= AMDTEMP_CURTMP_RANGE_ADJUST; in amdtemp_decode_fam10h_to_17h()
753 temp += AMDTEMP_ZERO_C_TO_K + sc_offset * 10; in amdtemp_decode_fam10h_to_17h()
754 return (temp); in amdtemp_decode_fam10h_to_17h()
787 amdtemp_gettemp(device_t dev, amdsensor_t sensor) in amdtemp_gettemp() argument
790 uint32_t temp; in amdtemp_gettemp() local
792 temp = pci_read_config(dev, AMDTEMP_REPTMP_CTRL, 4); in amdtemp_gettemp()
793 return (amdtemp_decode_fam10h_to_16h(sc->sc_offset, temp)); in amdtemp_gettemp()
797 amdtemp_gettemp15hm60h(device_t dev, amdsensor_t sensor) in amdtemp_gettemp15hm60h() argument
803 error = amdsmn_read(sc->sc_smn, AMDTEMP_15H_M60H_REPTMP_CTRL, &val); in amdtemp_gettemp15hm60h()
805 return (amdtemp_decode_fam10h_to_16h(sc->sc_offset, val)); in amdtemp_gettemp15hm60h()
809 amdtemp_gettemp17h(device_t dev, amdsensor_t sensor) in amdtemp_gettemp17h() argument
815 switch (sensor) { in amdtemp_gettemp17h()
818 error = amdsmn_read(sc->sc_smn, AMDTEMP_17H_CUR_TMP, &val); in amdtemp_gettemp17h()
820 return (amdtemp_decode_fam17h_tctl(sc->sc_offset, val)); in amdtemp_gettemp17h()
823 error = amdsmn_read(sc->sc_smn, sc->sc_temp_base + in amdtemp_gettemp17h()
824 (((int)sensor - CCD_BASE) * sizeof(val)), &val); in amdtemp_gettemp17h()
827 ("sensor %d: not valid", (int)sensor)); in amdtemp_gettemp17h()
828 return (amdtemp_decode_fam10h_to_17h(sc->sc_offset, val, true)); in amdtemp_gettemp17h()
844 error = amdsmn_read(sc->sc_smn, sc->sc_temp_base + in amdtemp_probe_ccd_sensors()
900 sc->sc_temp_base = AMDTEMP_ZEN4_10H_CCD_TMP_BASE; in amdtemp_probe_ccd_sensors19h()
907 sc->sc_temp_base = AMDTEMP_ZEN4_CCD_TMP_BASE; in amdtemp_probe_ccd_sensors19h()
930 sc->sc_temp_base = AMDTEMP_ZEN4_CCD_TMP_BASE; in amdtemp_probe_ccd_sensors1ah()