2 * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
31 * Thermometer and thermal zones driver for Tegra SoCs.
32 * Calibration data and algo are taken from Linux, because this part of SoC
33 * is undocumented in TRM.
36 #include <sys/param.h>
37 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <sys/malloc.h>
44 #include <sys/sysctl.h>
46 #include <machine/bus.h>
48 #include <dev/extres/clk/clk.h>
49 #include <dev/extres/hwreset/hwreset.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
53 #include <arm/nvidia/tegra_efuse.h>
54 #include <gnu/dts/include/dt-bindings/thermal/tegra124-soctherm.h>
55 #include "tegra_soctherm_if.h"
57 /* Per sensors registers - base is 0x0c0*/
58 #define TSENSOR_CONFIG0 0x000
59 #define TSENSOR_CONFIG0_TALL(x) (((x) & 0xFFFFF) << 8)
60 #define TSENSOR_CONFIG0_STATUS_CLR (1 << 5)
61 #define TSENSOR_CONFIG0_TCALC_OVERFLOW (1 << 4)
62 #define TSENSOR_CONFIG0_OVERFLOW (1 << 3)
63 #define TSENSOR_CONFIG0_CPTR_OVERFLOW (1 << 2)
64 #define TSENSOR_CONFIG0_RO_SEL (1 << 1)
65 #define TSENSOR_CONFIG0_STOP (1 << 0)
67 #define TSENSOR_CONFIG1 0x004
68 #define TSENSOR_CONFIG1_TEMP_ENABLE (1U << 31)
69 #define TSENSOR_CONFIG1_TEN_COUNT(x) (((x) & 0x3F) << 24)
70 #define TSENSOR_CONFIG1_TIDDQ_EN(x) (((x) & 0x3F) << 15)
71 #define TSENSOR_CONFIG1_TSAMPLE(x) (((x) & 0x3FF) << 0)
73 #define TSENSOR_CONFIG2 0x008
74 #define TSENSOR_CONFIG2_THERMA(x) (((x) & 0xFFFF) << 16)
75 #define TSENSOR_CONFIG2_THERMB(x) (((x) & 0xFFFF) << 0)
77 #define TSENSOR_STATUS0 0x00c
78 #define TSENSOR_STATUS0_CAPTURE_VALID (1U << 31)
79 #define TSENSOR_STATUS0_CAPTURE(x) (((x) >> 0) & 0xffff)
81 #define TSENSOR_STATUS1 0x010
82 #define TSENSOR_STATUS1_TEMP_VALID (1U << 31)
83 #define TSENSOR_STATUS1_TEMP(x) (((x) >> 0) & 0xffff)
85 #define TSENSOR_STATUS2 0x014
86 #define TSENSOR_STATUS2_TEMP_MAX(x) (((x) >> 16) & 0xffff)
87 #define TSENSOR_STATUS2_TEMP_MIN(x) (((x) >> 0) & 0xffff)
89 /* Global registers */
90 #define TSENSOR_PDIV 0x1c0
91 #define TSENSOR_PDIV_T124 0x8888
92 #define TSENSOR_HOTSPOT_OFF 0x1c4
93 #define TSENSOR_HOTSPOT_OFF_T124 0x00060600
94 #define TSENSOR_TEMP1 0x1c8
95 #define TSENSOR_TEMP2 0x1cc
98 #define READBACK_VALUE_MASK 0xff00
99 #define READBACK_VALUE_SHIFT 8
100 #define READBACK_ADD_HALF (1 << 7)
101 #define READBACK_NEGATE (1 << 0)
105 #define FUSE_TSENSOR_CALIB_CP_TS_BASE_SHIFT 0
106 #define FUSE_TSENSOR_CALIB_CP_TS_BASE_BITS 13
107 #define FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT 13
108 #define FUSE_TSENSOR_CALIB_FT_TS_BASE_BITS 13
110 #define FUSE_TSENSOR8_CALIB 0x180
111 #define FUSE_TSENSOR8_CALIB_CP_TS_BASE(x) (((x) >> 0) & 0x3ff)
112 #define FUSE_TSENSOR8_CALIB_FT_TS_BASE(x) (((x) >> 10) & 0x7ff)
114 #define FUSE_SPARE_REALIGNMENT_REG 0x1fc
115 #define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_SHIFT 0
116 #define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_BITS 6
117 #define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT 21
118 #define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_BITS 5
119 #define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP(x) (((x) >> 0) & 0x3f)
120 #define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT(x) (((x) >> 21) & 0x1f)
123 #define NOMINAL_CALIB_FT_T124 105
124 #define NOMINAL_CALIB_CP_T124 25
126 #define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, (_r), (_v))
127 #define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_r))
129 static struct sysctl_ctx_list soctherm_sysctl_ctx;
131 struct soctherm_shared_cal {
134 int32_t actual_temp_cp;
135 int32_t actual_temp_ft;
143 uint32_t tsample_ate;
150 struct tsensor_cfg *cfg;
151 bus_addr_t sensor_base;
152 bus_addr_t calib_fuse;
160 struct soctherm_softc {
162 struct resource *mem_res;
163 struct resource *irq_res;
171 struct tsensor *tsensors;
174 static struct ofw_compat_data compat_data[] = {
175 {"nvidia,tegra124-soctherm", 1},
179 static struct tsensor_cfg t124_tsensor_config = {
190 static struct tsensor t124_tsensors[] = {
193 .id = TEGRA124_SOCTHERM_SENSOR_CPU,
194 .cfg = &t124_tsensor_config,
195 .sensor_base = 0x0c0,
197 .fuse_corr_alpha = 1135400,
198 .fuse_corr_beta = -6266900,
203 .cfg = &t124_tsensor_config,
204 .sensor_base = 0x0e0,
206 .fuse_corr_alpha = 1122220,
207 .fuse_corr_beta = -5700700,
212 .cfg = &t124_tsensor_config,
213 .sensor_base = 0x100,
215 .fuse_corr_alpha = 1127000,
216 .fuse_corr_beta = -6768200,
221 .cfg = &t124_tsensor_config,
222 .sensor_base = 0x120,
224 .fuse_corr_alpha = 1110900,
225 .fuse_corr_beta = -6232000,
229 .id = TEGRA124_SOCTHERM_SENSOR_MEM,
230 .cfg = &t124_tsensor_config,
231 .sensor_base = 0x140,
233 .fuse_corr_alpha = 1122300,
234 .fuse_corr_beta = -5936400,
239 .cfg = &t124_tsensor_config,
240 .sensor_base = 0x160,
242 .fuse_corr_alpha = 1145700,
243 .fuse_corr_beta = -7124600,
247 .id = TEGRA124_SOCTHERM_SENSOR_GPU,
248 .cfg = &t124_tsensor_config,
249 .sensor_base = 0x180,
251 .fuse_corr_alpha = 1120100,
252 .fuse_corr_beta = -6000500,
256 .id = TEGRA124_SOCTHERM_SENSOR_PLLX,
257 .cfg = &t124_tsensor_config,
258 .sensor_base = 0x1a0,
260 .fuse_corr_alpha = 1106500,
261 .fuse_corr_beta = -6729300,
265 /* Extract signed integer bitfield from register */
267 extract_signed(uint32_t reg, int shift, int bits)
272 mask = (1 << bits) - 1;
273 val = ((reg >> shift) & mask) << (32 - bits);
275 return ((int32_t)val);
278 static inline int64_t div64_s64_precise(int64_t a, int64_t b)
283 r = (al * 2 + 1) / (2 * b);
288 get_shared_cal(struct soctherm_softc *sc, struct soctherm_shared_cal *cal)
291 int calib_cp, calib_ft;
293 val = tegra_fuse_read_4(FUSE_TSENSOR8_CALIB);
294 cal->base_cp = FUSE_TSENSOR8_CALIB_CP_TS_BASE(val);
295 cal->base_ft = FUSE_TSENSOR8_CALIB_FT_TS_BASE(val);
297 val = tegra_fuse_read_4(FUSE_SPARE_REALIGNMENT_REG);
298 calib_ft = extract_signed(val,
299 FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT,
300 FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_BITS);
301 calib_cp = extract_signed(val,
302 FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_SHIFT,
303 FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_BITS);
305 cal->actual_temp_cp = 2 * NOMINAL_CALIB_CP_T124 + calib_cp;
306 cal->actual_temp_ft = 2 * NOMINAL_CALIB_FT_T124 + calib_ft;
308 printf("%s: base_cp: %u, base_ft: %d,"
309 " actual_temp_cp: %d, actual_temp_ft: %d\n",
310 __func__, cal->base_cp, cal->base_ft,
311 cal->actual_temp_cp, cal->actual_temp_ft);
317 tsensor_calibration(struct tsensor *sensor, struct soctherm_shared_cal *shared)
320 int mult, div, calib_cp, calib_ft;
321 int actual_tsensor_ft, actual_tsensor_cp, delta_sens, delta_temp;
325 val = tegra_fuse_read_4(sensor->calib_fuse);
326 calib_cp = extract_signed(val,
327 FUSE_TSENSOR_CALIB_CP_TS_BASE_SHIFT,
328 FUSE_TSENSOR_CALIB_CP_TS_BASE_BITS);
329 actual_tsensor_cp = shared->base_cp * 64 + calib_cp;
331 calib_ft = extract_signed(val,
332 FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT,
333 FUSE_TSENSOR_CALIB_FT_TS_BASE_BITS);
334 actual_tsensor_ft = shared->base_ft * 32 + calib_ft;
336 delta_sens = actual_tsensor_ft - actual_tsensor_cp;
337 delta_temp = shared->actual_temp_ft - shared->actual_temp_cp;
338 mult = sensor->cfg->pdiv * sensor->cfg->tsample_ate;
339 div = sensor->cfg->tsample * sensor->cfg->pdiv_ate;
342 temp_a = div64_s64_precise((int64_t) delta_temp * (1LL << 13) * mult,
343 (int64_t) delta_sens * div);
345 tmp = (int64_t)actual_tsensor_ft * shared->actual_temp_cp -
346 (int64_t)actual_tsensor_cp * shared->actual_temp_ft;
347 temp_b = div64_s64_precise(tmp, (int64_t)delta_sens);
349 temp_a = div64_s64_precise((int64_t)temp_a * sensor->fuse_corr_alpha,
351 temp_b = div64_s64_precise((int64_t)temp_b * sensor->fuse_corr_alpha +
352 sensor->fuse_corr_beta, 1000000);
353 sensor->therm_a = (int16_t)temp_a;
354 sensor->therm_b = (int16_t)temp_b;
356 printf("%s: sensor %s fuse: 0x%08X (0x%04X, 0x%04X)"
357 " calib_cp: %d(0x%04X), calib_ft: %d(0x%04X)\n",
358 __func__, sensor->name, val, val & 0x1FFF, (val >> 13) & 0x1FFF,
359 calib_cp, calib_cp, calib_ft, calib_ft);
360 printf("therma: 0x%04X(%d), thermb: 0x%04X(%d)\n",
361 (uint16_t)sensor->therm_a, temp_a,
362 (uint16_t)sensor->therm_b, sensor->therm_b);
367 soctherm_init_tsensor(struct soctherm_softc *sc, struct tsensor *sensor,
368 struct soctherm_shared_cal *shared_cal)
372 tsensor_calibration(sensor, shared_cal);
374 val = RD4(sc, sensor->sensor_base + TSENSOR_CONFIG0);
375 val |= TSENSOR_CONFIG0_STOP;
376 val |= TSENSOR_CONFIG0_STATUS_CLR;
377 WR4(sc, sensor->sensor_base + TSENSOR_CONFIG0, val);
379 val = TSENSOR_CONFIG0_TALL(sensor->cfg->tall);
380 val |= TSENSOR_CONFIG0_STOP;
381 WR4(sc, sensor->sensor_base + TSENSOR_CONFIG0, val);
383 val = TSENSOR_CONFIG1_TSAMPLE(sensor->cfg->tsample - 1);
384 val |= TSENSOR_CONFIG1_TIDDQ_EN(sensor->cfg->tiddq_en);
385 val |= TSENSOR_CONFIG1_TEN_COUNT(sensor->cfg->ten_count);
386 val |= TSENSOR_CONFIG1_TEMP_ENABLE;
387 WR4(sc, sensor->sensor_base + TSENSOR_CONFIG1, val);
389 val = TSENSOR_CONFIG2_THERMA((uint16_t)sensor->therm_a) |
390 TSENSOR_CONFIG2_THERMB((uint16_t)sensor->therm_b);
391 WR4(sc, sensor->sensor_base + TSENSOR_CONFIG2, val);
393 val = RD4(sc, sensor->sensor_base + TSENSOR_CONFIG0);
394 val &= ~TSENSOR_CONFIG0_STOP;
395 WR4(sc, sensor->sensor_base + TSENSOR_CONFIG0, val);
397 printf(" Sensor: %s cfg:0x%08X, 0x%08X, 0x%08X,"
398 " sts:0x%08X, 0x%08X, 0x%08X\n", sensor->name,
399 RD4(sc, sensor->sensor_base + TSENSOR_CONFIG0),
400 RD4(sc, sensor->sensor_base + TSENSOR_CONFIG1),
401 RD4(sc, sensor->sensor_base + TSENSOR_CONFIG2),
402 RD4(sc, sensor->sensor_base + TSENSOR_STATUS0),
403 RD4(sc, sensor->sensor_base + TSENSOR_STATUS1),
404 RD4(sc, sensor->sensor_base + TSENSOR_STATUS2)
410 soctherm_convert_raw(uint32_t val)
414 t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000;
415 if (val & READBACK_ADD_HALF)
417 if (val & READBACK_NEGATE)
424 soctherm_read_temp(struct soctherm_softc *sc, struct tsensor *sensor, int *temp)
430 /* wait for valid sample */
431 for (timeout = 1000; timeout > 0; timeout--) {
432 val = RD4(sc, sensor->sensor_base + TSENSOR_STATUS1);
433 if ((val & TSENSOR_STATUS1_TEMP_VALID) != 0)
438 device_printf(sc->dev, "Sensor %s timeouted\n", sensor->name);
439 *temp = soctherm_convert_raw(val);
441 printf("%s: Raw: 0x%08X, temp: %d\n", __func__, val, *temp);
442 printf(" Sensor: %s cfg:0x%08X, 0x%08X, 0x%08X,"
443 " sts:0x%08X, 0x%08X, 0x%08X\n", sensor->name,
444 RD4(sc, sensor->sensor_base + TSENSOR_CONFIG0),
445 RD4(sc, sensor->sensor_base + TSENSOR_CONFIG1),
446 RD4(sc, sensor->sensor_base + TSENSOR_CONFIG2),
447 RD4(sc, sensor->sensor_base + TSENSOR_STATUS0),
448 RD4(sc, sensor->sensor_base + TSENSOR_STATUS1),
449 RD4(sc, sensor->sensor_base + TSENSOR_STATUS2)
456 soctherm_get_temp(device_t dev, device_t cdev, uintptr_t id, int *val)
458 struct soctherm_softc *sc;
461 sc = device_get_softc(dev);
462 /* The direct sensor map starts at 0x100 */
465 if (id >= sc->ntsensors)
467 return(soctherm_read_temp(sc, sc->tsensors + id, val));
469 /* Linux (DT) compatible thermal zones */
470 for (i = 0; i < sc->ntsensors; i++) {
471 if (sc->tsensors->id == id)
472 return(soctherm_read_temp(sc, sc->tsensors + id, val));
478 soctherm_sysctl_temperature(SYSCTL_HANDLER_ARGS)
480 struct soctherm_softc *sc;
486 if (req->newptr != NULL)
492 if (id >= sc->ntsensors)
494 rv = soctherm_read_temp(sc, sc->tsensors + id, &val);
500 rv = sysctl_handle_int(oidp, &val, 0, req);
505 soctherm_init_sysctl(struct soctherm_softc *sc)
508 struct sysctl_oid *oid, *tmp;
510 sysctl_ctx_init(&soctherm_sysctl_ctx);
511 /* create node for hw.temp */
512 oid = SYSCTL_ADD_NODE(&soctherm_sysctl_ctx,
513 SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "temperature",
514 CTLFLAG_RD, NULL, "");
519 for (i = sc->ntsensors - 1; i >= 0; i--) {
520 tmp = SYSCTL_ADD_PROC(&soctherm_sysctl_ctx,
521 SYSCTL_CHILDREN(oid), OID_AUTO, sc->tsensors[i].name,
522 CTLTYPE_INT | CTLFLAG_RD, sc, i,
523 soctherm_sysctl_temperature, "IK", "SoC Temperature");
532 soctherm_probe(device_t dev)
535 if (!ofw_bus_status_okay(dev))
538 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
541 device_set_desc(dev, "Tegra temperature sensors");
542 return (BUS_PROBE_DEFAULT);
546 soctherm_attach(device_t dev)
548 struct soctherm_softc *sc;
551 struct soctherm_shared_cal shared_calib;
553 sc = device_get_softc(dev);
555 node = ofw_bus_get_node(sc->dev);
558 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
560 if (sc->mem_res == NULL) {
561 device_printf(dev, "Cannot allocate memory resources\n");
566 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
567 if (sc->irq_res == NULL) {
568 device_printf(dev, "Cannot allocate IRQ resources\n");
573 if ((bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
574 soctherm_intr, NULL, sc, &sc->irq_ih))) {
576 "WARNING: unable to register interrupt handler\n");
582 rv = hwreset_get_by_ofw_name(dev, 0, "soctherm", &sc->reset);
584 device_printf(dev, "Cannot get fuse reset\n");
587 rv = clk_get_by_ofw_name(dev, 0, "tsensor", &sc->tsensor_clk);
589 device_printf(dev, "Cannot get 'tsensor' clock: %d\n", rv);
592 rv = clk_get_by_ofw_name(dev, 0, "soctherm", &sc->soctherm_clk);
594 device_printf(dev, "Cannot get 'soctherm' clock: %d\n", rv);
598 rv = hwreset_assert(sc->reset);
600 device_printf(dev, "Cannot assert reset\n");
603 rv = clk_enable(sc->tsensor_clk);
605 device_printf(dev, "Cannot enable 'tsensor' clock: %d\n", rv);
608 rv = clk_enable(sc->soctherm_clk);
610 device_printf(dev, "Cannot enable 'soctherm' clock: %d\n", rv);
613 rv = hwreset_deassert(sc->reset);
615 device_printf(dev, "Cannot clear reset\n");
620 sc->tsensors = t124_tsensors;
621 sc->ntsensors = nitems(t124_tsensors);
622 get_shared_cal(sc, &shared_calib);
624 WR4(sc, TSENSOR_PDIV, TSENSOR_PDIV_T124);
625 WR4(sc, TSENSOR_HOTSPOT_OFF, TSENSOR_HOTSPOT_OFF_T124);
627 for (i = 0; i < sc->ntsensors; i++)
628 soctherm_init_tsensor(sc, sc->tsensors + i, &shared_calib);
630 rv = soctherm_init_sysctl(sc);
632 device_printf(sc->dev, "Cannot initialize sysctls\n");
636 OF_device_register_xref(OF_xref_from_node(node), dev);
637 return (bus_generic_attach(dev));
640 if (sc->irq_ih != NULL)
641 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
642 sysctl_ctx_free(&soctherm_sysctl_ctx);
643 if (sc->tsensor_clk != NULL)
644 clk_release(sc->tsensor_clk);
645 if (sc->soctherm_clk != NULL)
646 clk_release(sc->soctherm_clk);
647 if (sc->reset != NULL)
648 hwreset_release(sc->reset);
649 if (sc->irq_res != NULL)
650 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
651 if (sc->mem_res != NULL)
652 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
658 soctherm_detach(device_t dev)
660 struct soctherm_softc *sc;
661 sc = device_get_softc(dev);
663 if (sc->irq_ih != NULL)
664 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
665 sysctl_ctx_free(&soctherm_sysctl_ctx);
666 if (sc->tsensor_clk != NULL)
667 clk_release(sc->tsensor_clk);
668 if (sc->soctherm_clk != NULL)
669 clk_release(sc->soctherm_clk);
670 if (sc->reset != NULL)
671 hwreset_release(sc->reset);
672 if (sc->irq_res != NULL)
673 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
674 if (sc->mem_res != NULL)
675 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
680 static device_method_t tegra_soctherm_methods[] = {
681 /* Device interface */
682 DEVMETHOD(device_probe, soctherm_probe),
683 DEVMETHOD(device_attach, soctherm_attach),
684 DEVMETHOD(device_detach, soctherm_detach),
686 /* SOCTHERM interface */
687 DEVMETHOD(tegra_soctherm_get_temperature, soctherm_get_temp),
692 static devclass_t tegra_soctherm_devclass;
693 static DEFINE_CLASS_0(soctherm, tegra_soctherm_driver, tegra_soctherm_methods,
694 sizeof(struct soctherm_softc));
695 EARLY_DRIVER_MODULE(tegra_soctherm, simplebus, tegra_soctherm_driver,
696 tegra_soctherm_devclass, NULL, NULL, 79);