17698c759SSepherosa Ziehau /*
27698c759SSepherosa Ziehau * Copyright (c) 2015 The DragonFly Project. All rights reserved.
37698c759SSepherosa Ziehau *
47698c759SSepherosa Ziehau * This code is derived from software contributed to The DragonFly Project
57698c759SSepherosa Ziehau * by Sepherosa Ziehau <sepherosa@gmail.com>
67698c759SSepherosa Ziehau *
77698c759SSepherosa Ziehau * Redistribution and use in source and binary forms, with or without
87698c759SSepherosa Ziehau * modification, are permitted provided that the following conditions
97698c759SSepherosa Ziehau * are met:
107698c759SSepherosa Ziehau *
117698c759SSepherosa Ziehau * 1. Redistributions of source code must retain the above copyright
127698c759SSepherosa Ziehau * notice, this list of conditions and the following disclaimer.
137698c759SSepherosa Ziehau * 2. Redistributions in binary form must reproduce the above copyright
147698c759SSepherosa Ziehau * notice, this list of conditions and the following disclaimer in
157698c759SSepherosa Ziehau * the documentation and/or other materials provided with the
167698c759SSepherosa Ziehau * distribution.
177698c759SSepherosa Ziehau * 3. Neither the name of The DragonFly Project nor the names of its
187698c759SSepherosa Ziehau * contributors may be used to endorse or promote products derived
197698c759SSepherosa Ziehau * from this software without specific, prior written permission.
207698c759SSepherosa Ziehau *
217698c759SSepherosa Ziehau * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
227698c759SSepherosa Ziehau * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
237698c759SSepherosa Ziehau * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
247698c759SSepherosa Ziehau * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
257698c759SSepherosa Ziehau * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
267698c759SSepherosa Ziehau * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
277698c759SSepherosa Ziehau * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
287698c759SSepherosa Ziehau * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
297698c759SSepherosa Ziehau * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
307698c759SSepherosa Ziehau * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
317698c759SSepherosa Ziehau * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
327698c759SSepherosa Ziehau * SUCH DAMAGE.
337698c759SSepherosa Ziehau */
347698c759SSepherosa Ziehau
357698c759SSepherosa Ziehau #include <sys/param.h>
367698c759SSepherosa Ziehau #include <sys/systm.h>
377698c759SSepherosa Ziehau #include <sys/bitops.h>
387698c759SSepherosa Ziehau #include <sys/bus.h>
39*7769f1bbSSepherosa Ziehau #include <sys/cpu_topology.h>
407698c759SSepherosa Ziehau #include <sys/kernel.h>
417698c759SSepherosa Ziehau #include <sys/malloc.h>
427698c759SSepherosa Ziehau #include <sys/sensors.h>
437698c759SSepherosa Ziehau #include <sys/sysctl.h>
447698c759SSepherosa Ziehau
457698c759SSepherosa Ziehau #include <bus/pci/pcivar.h>
467698c759SSepherosa Ziehau #include <bus/pci/pcireg.h>
477698c759SSepherosa Ziehau #include <bus/pci/pci_cfgreg.h>
487698c759SSepherosa Ziehau #include <bus/pci/pcib_private.h>
497698c759SSepherosa Ziehau
507698c759SSepherosa Ziehau #include "pcib_if.h"
517698c759SSepherosa Ziehau
52881f7bffSSepherosa Ziehau #include <dev/misc/dimm/dimm.h>
530c543cddSSepherosa Ziehau #include <dev/misc/ecc/e5_imc_reg.h>
540c543cddSSepherosa Ziehau #include <dev/misc/ecc/e5_imc_var.h>
557698c759SSepherosa Ziehau
56254817bdSSepherosa Ziehau #define MEMTEMP_E5_DIMM_TEMP_HIWAT 85 /* spec default TEMPLO */
57254817bdSSepherosa Ziehau #define MEMTEMP_E5_DIMM_TEMP_STEP 5 /* spec TEMPLO/MID/HI step */
58254817bdSSepherosa Ziehau
597698c759SSepherosa Ziehau struct memtemp_e5_softc;
607698c759SSepherosa Ziehau
617698c759SSepherosa Ziehau struct memtemp_e5_dimm {
627698c759SSepherosa Ziehau TAILQ_ENTRY(memtemp_e5_dimm) dimm_link;
637698c759SSepherosa Ziehau struct ksensor dimm_sensor;
647698c759SSepherosa Ziehau struct memtemp_e5_softc *dimm_parent;
657698c759SSepherosa Ziehau int dimm_id;
66254817bdSSepherosa Ziehau int dimm_flags;
67881f7bffSSepherosa Ziehau
68881f7bffSSepherosa Ziehau struct dimm_softc *dimm_softc;
69*7769f1bbSSepherosa Ziehau struct sensor_task *dimm_senstask;
707698c759SSepherosa Ziehau };
717698c759SSepherosa Ziehau
72254817bdSSepherosa Ziehau #define MEMTEMP_E5_DIMM_FLAG_CRIT 0x1
73254817bdSSepherosa Ziehau
747698c759SSepherosa Ziehau struct memtemp_e5_softc {
757698c759SSepherosa Ziehau device_t temp_dev;
760c543cddSSepherosa Ziehau const struct e5_imc_chan *temp_chan;
777698c759SSepherosa Ziehau int temp_node;
787698c759SSepherosa Ziehau TAILQ_HEAD(, memtemp_e5_dimm) temp_dimm;
797698c759SSepherosa Ziehau };
807698c759SSepherosa Ziehau
817698c759SSepherosa Ziehau static int memtemp_e5_probe(device_t);
827698c759SSepherosa Ziehau static int memtemp_e5_attach(device_t);
837698c759SSepherosa Ziehau static int memtemp_e5_detach(device_t);
847698c759SSepherosa Ziehau
85254817bdSSepherosa Ziehau static int memtemp_e5_tempth_adjust(int);
86254817bdSSepherosa Ziehau static void memtemp_e5_tempth_str(int, char *, int);
877698c759SSepherosa Ziehau static void memtemp_e5_sensor_task(void *);
887698c759SSepherosa Ziehau
890c543cddSSepherosa Ziehau #define MEMTEMP_E5_CHAN(v, imc, c, c_ext) \
907698c759SSepherosa Ziehau { \
910c543cddSSepherosa Ziehau .did = PCI_E5V##v##_IMC##imc##_THERMAL_CHN##c##_DID_ID, \
920c543cddSSepherosa Ziehau .slot = PCISLOT_E5V##v##_IMC##imc##_THERMAL_CHN##c, \
930c543cddSSepherosa Ziehau .func = PCIFUNC_E5V##v##_IMC##imc##_THERMAL_CHN##c, \
940c543cddSSepherosa Ziehau .desc = "Intel E5 v" #v " memory thermal sensor", \
950c543cddSSepherosa Ziehau \
960c543cddSSepherosa Ziehau E5_IMC_CHAN_FIELDS(v, imc, c, c_ext) \
977698c759SSepherosa Ziehau }
987698c759SSepherosa Ziehau
990c543cddSSepherosa Ziehau #define MEMTEMP_E5_CHAN_V2(c) MEMTEMP_E5_CHAN(2, 0, c, c)
100acbc630dSSepherosa Ziehau #define MEMTEMP_E5_CHAN_IMC0_V3(c) MEMTEMP_E5_CHAN(3, 0, c, c)
101acbc630dSSepherosa Ziehau #define MEMTEMP_E5_CHAN_IMC1_V3(c, c_ext) \
102acbc630dSSepherosa Ziehau MEMTEMP_E5_CHAN(3, 1, c, c_ext)
1030c543cddSSepherosa Ziehau #define MEMTEMP_E5_CHAN_END E5_IMC_CHAN_END
1047698c759SSepherosa Ziehau
1050c543cddSSepherosa Ziehau static const struct e5_imc_chan memtemp_e5_chans[] = {
1060c543cddSSepherosa Ziehau MEMTEMP_E5_CHAN_V2(0),
1070c543cddSSepherosa Ziehau MEMTEMP_E5_CHAN_V2(1),
1080c543cddSSepherosa Ziehau MEMTEMP_E5_CHAN_V2(2),
1090c543cddSSepherosa Ziehau MEMTEMP_E5_CHAN_V2(3),
1107698c759SSepherosa Ziehau
111acbc630dSSepherosa Ziehau MEMTEMP_E5_CHAN_IMC0_V3(0),
112acbc630dSSepherosa Ziehau MEMTEMP_E5_CHAN_IMC0_V3(1),
113acbc630dSSepherosa Ziehau MEMTEMP_E5_CHAN_IMC0_V3(2),
114acbc630dSSepherosa Ziehau MEMTEMP_E5_CHAN_IMC0_V3(3),
115acbc630dSSepherosa Ziehau MEMTEMP_E5_CHAN_IMC1_V3(0, 2), /* IMC1 chan0 -> channel2 */
116acbc630dSSepherosa Ziehau MEMTEMP_E5_CHAN_IMC1_V3(1, 3), /* IMC1 chan1 -> channel3 */
117acbc630dSSepherosa Ziehau
1180c543cddSSepherosa Ziehau MEMTEMP_E5_CHAN_END
1197698c759SSepherosa Ziehau };
1207698c759SSepherosa Ziehau
1210c543cddSSepherosa Ziehau #undef MEMTEMP_E5_CHAN_END
1220c543cddSSepherosa Ziehau #undef MEMTEMP_E5_CHAN_V2
1230c543cddSSepherosa Ziehau #undef MEMTEMP_E5_CHAN
1247698c759SSepherosa Ziehau
1257698c759SSepherosa Ziehau static device_method_t memtemp_e5_methods[] = {
1267698c759SSepherosa Ziehau /* Device interface */
1277698c759SSepherosa Ziehau DEVMETHOD(device_probe, memtemp_e5_probe),
1287698c759SSepherosa Ziehau DEVMETHOD(device_attach, memtemp_e5_attach),
1297698c759SSepherosa Ziehau DEVMETHOD(device_detach, memtemp_e5_detach),
1307698c759SSepherosa Ziehau DEVMETHOD(device_shutdown, bus_generic_shutdown),
1317698c759SSepherosa Ziehau DEVMETHOD(device_suspend, bus_generic_suspend),
1327698c759SSepherosa Ziehau DEVMETHOD(device_resume, bus_generic_resume),
1337698c759SSepherosa Ziehau DEVMETHOD_END
1347698c759SSepherosa Ziehau };
1357698c759SSepherosa Ziehau
1367698c759SSepherosa Ziehau static driver_t memtemp_e5_driver = {
1377698c759SSepherosa Ziehau "memtemp",
1387698c759SSepherosa Ziehau memtemp_e5_methods,
1397698c759SSepherosa Ziehau sizeof(struct memtemp_e5_softc)
1407698c759SSepherosa Ziehau };
1417698c759SSepherosa Ziehau static devclass_t memtemp_devclass;
1427698c759SSepherosa Ziehau DRIVER_MODULE(memtemp_e5, pci, memtemp_e5_driver, memtemp_devclass, NULL, NULL);
1437698c759SSepherosa Ziehau MODULE_DEPEND(memtemp_e5, pci, 1, 1, 1);
144881f7bffSSepherosa Ziehau MODULE_DEPEND(memtemp_e5, dimm, 1, 1, 1);
1457698c759SSepherosa Ziehau
1467698c759SSepherosa Ziehau static int
memtemp_e5_probe(device_t dev)1477698c759SSepherosa Ziehau memtemp_e5_probe(device_t dev)
1487698c759SSepherosa Ziehau {
1490c543cddSSepherosa Ziehau const struct e5_imc_chan *c;
1507698c759SSepherosa Ziehau uint16_t vid, did;
1517698c759SSepherosa Ziehau int slot, func;
1527698c759SSepherosa Ziehau
1537698c759SSepherosa Ziehau vid = pci_get_vendor(dev);
1540c543cddSSepherosa Ziehau if (vid != PCI_E5_IMC_VID_ID)
1557698c759SSepherosa Ziehau return ENXIO;
1567698c759SSepherosa Ziehau
1577698c759SSepherosa Ziehau did = pci_get_device(dev);
1587698c759SSepherosa Ziehau slot = pci_get_slot(dev);
1597698c759SSepherosa Ziehau func = pci_get_function(dev);
1607698c759SSepherosa Ziehau
1610c543cddSSepherosa Ziehau for (c = memtemp_e5_chans; c->desc != NULL; ++c) {
1620c543cddSSepherosa Ziehau if (c->did == did && c->slot == slot && c->func == func) {
1637698c759SSepherosa Ziehau struct memtemp_e5_softc *sc = device_get_softc(dev);
1646682d8f0SSepherosa Ziehau uint32_t cfg;
1650c543cddSSepherosa Ziehau int node;
1667698c759SSepherosa Ziehau
1670c543cddSSepherosa Ziehau node = e5_imc_node_probe(dev, c);
1680c543cddSSepherosa Ziehau if (node < 0)
1697698c759SSepherosa Ziehau break;
1707698c759SSepherosa Ziehau
1716682d8f0SSepherosa Ziehau /*
1726682d8f0SSepherosa Ziehau * XXX
1736682d8f0SSepherosa Ziehau * It seems that memory thermal sensor is available,
1746682d8f0SSepherosa Ziehau * only if CLTT is set (OLTT_EN does not seem matter).
1756682d8f0SSepherosa Ziehau */
1766682d8f0SSepherosa Ziehau cfg = pci_read_config(dev,
1776682d8f0SSepherosa Ziehau PCI_E5_IMC_THERMAL_CHN_TEMP_CFG, 4);
1786682d8f0SSepherosa Ziehau if ((cfg & PCI_E5_IMC_THERMAL_CHN_TEMP_CFG_CLTT) == 0)
1796682d8f0SSepherosa Ziehau break;
1806682d8f0SSepherosa Ziehau
181881f7bffSSepherosa Ziehau device_set_desc(dev, c->desc);
1827698c759SSepherosa Ziehau
1830c543cddSSepherosa Ziehau sc->temp_chan = c;
1847698c759SSepherosa Ziehau sc->temp_node = node;
1857698c759SSepherosa Ziehau
1867698c759SSepherosa Ziehau return 0;
1877698c759SSepherosa Ziehau }
1887698c759SSepherosa Ziehau }
1897698c759SSepherosa Ziehau return ENXIO;
1907698c759SSepherosa Ziehau }
1917698c759SSepherosa Ziehau
1927698c759SSepherosa Ziehau static int
memtemp_e5_tempth_adjust(int temp)193254817bdSSepherosa Ziehau memtemp_e5_tempth_adjust(int temp)
194254817bdSSepherosa Ziehau {
195254817bdSSepherosa Ziehau if (temp == PCI_E5_IMC_THERMAL_DIMM_TEMP_TH_DISABLE)
196254817bdSSepherosa Ziehau return 0;
197254817bdSSepherosa Ziehau else if (temp < PCI_E5_IMC_THERMAL_DIMM_TEMP_TH_TEMPMIN ||
198254817bdSSepherosa Ziehau temp >= PCI_E5_IMC_THERMAL_DIMM_TEMP_TH_TEMPMAX)
199254817bdSSepherosa Ziehau return -1;
200254817bdSSepherosa Ziehau return temp;
201254817bdSSepherosa Ziehau }
202254817bdSSepherosa Ziehau
203254817bdSSepherosa Ziehau static void
memtemp_e5_tempth_str(int temp,char * temp_str,int temp_strlen)204254817bdSSepherosa Ziehau memtemp_e5_tempth_str(int temp, char *temp_str, int temp_strlen)
205254817bdSSepherosa Ziehau {
206254817bdSSepherosa Ziehau if (temp < 0)
207254817bdSSepherosa Ziehau strlcpy(temp_str, "reserved", temp_strlen);
208254817bdSSepherosa Ziehau else if (temp == 0)
209254817bdSSepherosa Ziehau strlcpy(temp_str, "disabled", temp_strlen);
210254817bdSSepherosa Ziehau else
211254817bdSSepherosa Ziehau ksnprintf(temp_str, temp_strlen, "%dC", temp);
212254817bdSSepherosa Ziehau }
213254817bdSSepherosa Ziehau
214254817bdSSepherosa Ziehau static int
memtemp_e5_attach(device_t dev)2157698c759SSepherosa Ziehau memtemp_e5_attach(device_t dev)
2167698c759SSepherosa Ziehau {
2177698c759SSepherosa Ziehau struct memtemp_e5_softc *sc = device_get_softc(dev);
218*7769f1bbSSepherosa Ziehau const cpu_node_t *node;
219*7769f1bbSSepherosa Ziehau int dimm, cpuid = -1;
2207698c759SSepherosa Ziehau
2217698c759SSepherosa Ziehau sc->temp_dev = dev;
2227698c759SSepherosa Ziehau TAILQ_INIT(&sc->temp_dimm);
2237698c759SSepherosa Ziehau
224*7769f1bbSSepherosa Ziehau node = get_cpu_node_by_chipid(sc->temp_node);
225*7769f1bbSSepherosa Ziehau if (node != NULL && node->child_no > 0) {
226*7769f1bbSSepherosa Ziehau cpuid = BSRCPUMASK(node->members);
227*7769f1bbSSepherosa Ziehau if (bootverbose) {
228*7769f1bbSSepherosa Ziehau device_printf(dev, "node%d chan%d -> cpu%d\n",
229*7769f1bbSSepherosa Ziehau sc->temp_node, sc->temp_chan->chan_ext, cpuid);
230*7769f1bbSSepherosa Ziehau }
231*7769f1bbSSepherosa Ziehau }
232*7769f1bbSSepherosa Ziehau
2330c543cddSSepherosa Ziehau for (dimm = 0; dimm < PCI_E5_IMC_CHN_DIMM_MAX; ++dimm) {
234254817bdSSepherosa Ziehau char temp_lostr[16], temp_midstr[16], temp_histr[16];
2357698c759SSepherosa Ziehau struct memtemp_e5_dimm *dimm_sc;
236881f7bffSSepherosa Ziehau int temp_lo, temp_mid, temp_hi;
237881f7bffSSepherosa Ziehau int temp_hiwat, temp_lowat, has_temp_thresh = 1;
238254817bdSSepherosa Ziehau uint32_t dimmmtr, temp_th;
239881f7bffSSepherosa Ziehau struct ksensor *sens;
2407698c759SSepherosa Ziehau
241254817bdSSepherosa Ziehau dimmmtr = IMC_CTAD_READ_4(dev, sc->temp_chan,
2427698c759SSepherosa Ziehau PCI_E5_IMC_CTAD_DIMMMTR(dimm));
2437698c759SSepherosa Ziehau
2447698c759SSepherosa Ziehau if ((dimmmtr & PCI_E5_IMC_CTAD_DIMMMTR_DIMM_POP) == 0)
2457698c759SSepherosa Ziehau continue;
2467698c759SSepherosa Ziehau
2477698c759SSepherosa Ziehau dimm_sc = kmalloc(sizeof(*dimm_sc), M_DEVBUF,
2487698c759SSepherosa Ziehau M_WAITOK | M_ZERO);
2497698c759SSepherosa Ziehau dimm_sc->dimm_id = dimm;
2507698c759SSepherosa Ziehau dimm_sc->dimm_parent = sc;
251254817bdSSepherosa Ziehau
252254817bdSSepherosa Ziehau temp_th = pci_read_config(dev,
253254817bdSSepherosa Ziehau PCI_E5_IMC_THERMAL_DIMM_TEMP_TH(dimm), 4);
254254817bdSSepherosa Ziehau
255254817bdSSepherosa Ziehau temp_lo = __SHIFTOUT(temp_th,
256254817bdSSepherosa Ziehau PCI_E5_IMC_THERMAL_DIMM_TEMP_TH_TEMPLO);
257254817bdSSepherosa Ziehau temp_lo = memtemp_e5_tempth_adjust(temp_lo);
258254817bdSSepherosa Ziehau memtemp_e5_tempth_str(temp_lo, temp_lostr, sizeof(temp_lostr));
259254817bdSSepherosa Ziehau
260254817bdSSepherosa Ziehau temp_mid = __SHIFTOUT(temp_th,
261254817bdSSepherosa Ziehau PCI_E5_IMC_THERMAL_DIMM_TEMP_TH_TEMPMID);
262254817bdSSepherosa Ziehau temp_mid = memtemp_e5_tempth_adjust(temp_mid);
263254817bdSSepherosa Ziehau memtemp_e5_tempth_str(temp_mid, temp_midstr,
264254817bdSSepherosa Ziehau sizeof(temp_midstr));
265254817bdSSepherosa Ziehau
266254817bdSSepherosa Ziehau temp_hi = __SHIFTOUT(temp_th,
267254817bdSSepherosa Ziehau PCI_E5_IMC_THERMAL_DIMM_TEMP_TH_TEMPHI);
268254817bdSSepherosa Ziehau temp_hi = memtemp_e5_tempth_adjust(temp_hi);
269254817bdSSepherosa Ziehau memtemp_e5_tempth_str(temp_hi, temp_histr, sizeof(temp_histr));
270254817bdSSepherosa Ziehau
271254817bdSSepherosa Ziehau /*
272254817bdSSepherosa Ziehau * NOTE:
273254817bdSSepherosa Ziehau * - TEMPHI initiates THRTCRIT.
274254817bdSSepherosa Ziehau * - TEMPMID initiates THRTHI, so it is also taken into
275254817bdSSepherosa Ziehau * consideration.
276254817bdSSepherosa Ziehau * - Some BIOSes program temp_lo to a rediculous low value,
277254817bdSSepherosa Ziehau * so ignore TEMPLO here.
278254817bdSSepherosa Ziehau */
279254817bdSSepherosa Ziehau if (temp_mid <= 0) {
280881f7bffSSepherosa Ziehau if (temp_hi <= 0) {
281881f7bffSSepherosa Ziehau temp_hiwat = MEMTEMP_E5_DIMM_TEMP_HIWAT;
282881f7bffSSepherosa Ziehau has_temp_thresh = 0;
283254817bdSSepherosa Ziehau } else {
284881f7bffSSepherosa Ziehau temp_hiwat = temp_hi;
285254817bdSSepherosa Ziehau }
286881f7bffSSepherosa Ziehau } else {
287881f7bffSSepherosa Ziehau temp_hiwat = temp_mid;
288881f7bffSSepherosa Ziehau }
289881f7bffSSepherosa Ziehau if (temp_hiwat < MEMTEMP_E5_DIMM_TEMP_STEP) {
290881f7bffSSepherosa Ziehau temp_hiwat = MEMTEMP_E5_DIMM_TEMP_HIWAT;
291881f7bffSSepherosa Ziehau has_temp_thresh = 0;
292881f7bffSSepherosa Ziehau }
293881f7bffSSepherosa Ziehau temp_lowat = temp_hiwat - MEMTEMP_E5_DIMM_TEMP_STEP;
294254817bdSSepherosa Ziehau
295881f7bffSSepherosa Ziehau if (bootverbose) {
296254817bdSSepherosa Ziehau device_printf(dev, "DIMM%d "
297254817bdSSepherosa Ziehau "temp_hi %s, temp_mid %s, temp_lo %s\n", dimm,
298254817bdSSepherosa Ziehau temp_histr, temp_midstr, temp_lostr);
299881f7bffSSepherosa Ziehau }
30065c1e3ddSSepherosa Ziehau
301881f7bffSSepherosa Ziehau dimm_sc->dimm_softc = dimm_create(sc->temp_node,
302881f7bffSSepherosa Ziehau sc->temp_chan->chan_ext, dimm);
303881f7bffSSepherosa Ziehau
304881f7bffSSepherosa Ziehau if (has_temp_thresh) {
305881f7bffSSepherosa Ziehau if (bootverbose) {
306881f7bffSSepherosa Ziehau device_printf(dev, "DIMM%d "
307881f7bffSSepherosa Ziehau "hiwat %dC, lowat %dC\n",
308881f7bffSSepherosa Ziehau dimm, temp_hiwat, temp_lowat);
309881f7bffSSepherosa Ziehau }
310881f7bffSSepherosa Ziehau dimm_set_temp_thresh(dimm_sc->dimm_softc,
311881f7bffSSepherosa Ziehau temp_hiwat, temp_lowat);
312881f7bffSSepherosa Ziehau }
313881f7bffSSepherosa Ziehau
314881f7bffSSepherosa Ziehau sens = &dimm_sc->dimm_sensor;
315881f7bffSSepherosa Ziehau ksnprintf(sens->desc, sizeof(sens->desc),
31614387d56SSepherosa Ziehau "node%d chan%d DIMM%d temp",
317881f7bffSSepherosa Ziehau sc->temp_node, sc->temp_chan->chan_ext, dimm);
318881f7bffSSepherosa Ziehau sens->type = SENSOR_TEMP;
3197273d7b8SSepherosa Ziehau sensor_set_unknown(sens);
320881f7bffSSepherosa Ziehau dimm_sensor_attach(dimm_sc->dimm_softc, sens);
321*7769f1bbSSepherosa Ziehau dimm_sc->dimm_senstask = sensor_task_register2(dimm_sc,
322*7769f1bbSSepherosa Ziehau memtemp_e5_sensor_task, 5, cpuid);
32365c1e3ddSSepherosa Ziehau
32465c1e3ddSSepherosa Ziehau TAILQ_INSERT_TAIL(&sc->temp_dimm, dimm_sc, dimm_link);
3257698c759SSepherosa Ziehau }
3267698c759SSepherosa Ziehau return 0;
3277698c759SSepherosa Ziehau }
3287698c759SSepherosa Ziehau
3297698c759SSepherosa Ziehau static int
memtemp_e5_detach(device_t dev)3307698c759SSepherosa Ziehau memtemp_e5_detach(device_t dev)
3317698c759SSepherosa Ziehau {
3327698c759SSepherosa Ziehau struct memtemp_e5_softc *sc = device_get_softc(dev);
3337698c759SSepherosa Ziehau struct memtemp_e5_dimm *dimm_sc;
3347698c759SSepherosa Ziehau
3357698c759SSepherosa Ziehau while ((dimm_sc = TAILQ_FIRST(&sc->temp_dimm)) != NULL) {
3367698c759SSepherosa Ziehau TAILQ_REMOVE(&sc->temp_dimm, dimm_sc, dimm_link);
3377698c759SSepherosa Ziehau
338*7769f1bbSSepherosa Ziehau sensor_task_unregister2(dimm_sc->dimm_senstask);
339881f7bffSSepherosa Ziehau dimm_sensor_detach(dimm_sc->dimm_softc, &dimm_sc->dimm_sensor);
340881f7bffSSepherosa Ziehau dimm_destroy(dimm_sc->dimm_softc);
3417698c759SSepherosa Ziehau
3427698c759SSepherosa Ziehau kfree(dimm_sc, M_DEVBUF);
3437698c759SSepherosa Ziehau }
3447698c759SSepherosa Ziehau return 0;
3457698c759SSepherosa Ziehau }
3467698c759SSepherosa Ziehau
3477698c759SSepherosa Ziehau static void
memtemp_e5_sensor_task(void * xdimm_sc)3487698c759SSepherosa Ziehau memtemp_e5_sensor_task(void *xdimm_sc)
3497698c759SSepherosa Ziehau {
3507698c759SSepherosa Ziehau struct memtemp_e5_dimm *dimm_sc = xdimm_sc;
3517698c759SSepherosa Ziehau struct ksensor *sensor = &dimm_sc->dimm_sensor;
352254817bdSSepherosa Ziehau device_t dev = dimm_sc->dimm_parent->temp_dev;
3537698c759SSepherosa Ziehau uint32_t val;
354254817bdSSepherosa Ziehau int temp, reg;
3557698c759SSepherosa Ziehau
356881f7bffSSepherosa Ziehau reg = PCI_E5_IMC_THERMAL_DIMMTEMPSTAT(dimm_sc->dimm_id);
357254817bdSSepherosa Ziehau
358254817bdSSepherosa Ziehau val = pci_read_config(dev, reg, 4);
359254817bdSSepherosa Ziehau if (val & (PCI_E5_IMC_THERMAL_DIMMTEMPSTAT_TEMPHI |
360254817bdSSepherosa Ziehau PCI_E5_IMC_THERMAL_DIMMTEMPSTAT_TEMPMID |
361254817bdSSepherosa Ziehau PCI_E5_IMC_THERMAL_DIMMTEMPSTAT_TEMPLO))
362254817bdSSepherosa Ziehau pci_write_config(dev, reg, val, 4);
363254817bdSSepherosa Ziehau
3647698c759SSepherosa Ziehau temp = __SHIFTOUT(val, PCI_E5_IMC_THERMAL_DIMMTEMPSTAT_TEMP);
365254817bdSSepherosa Ziehau if (temp < PCI_E5_IMC_THERMAL_DIMMTEMPSTAT_TEMPMIN ||
366254817bdSSepherosa Ziehau temp >= PCI_E5_IMC_THERMAL_DIMMTEMPSTAT_TEMPMAX) {
367254817bdSSepherosa Ziehau sensor->status = SENSOR_S_UNSPEC;
368254817bdSSepherosa Ziehau sensor->flags |= SENSOR_FINVALID;
369254817bdSSepherosa Ziehau sensor->value = 0;
370254817bdSSepherosa Ziehau return;
371254817bdSSepherosa Ziehau }
372881f7bffSSepherosa Ziehau dimm_sensor_temp(dimm_sc->dimm_softc, sensor, temp);
3737698c759SSepherosa Ziehau }
374