1 /*- 2 * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 21 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * 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 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 /* 30 * Allwinner thermal sensor controller 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/bus.h> 39 #include <sys/rman.h> 40 #include <sys/kernel.h> 41 #include <sys/sysctl.h> 42 #include <sys/reboot.h> 43 #include <sys/module.h> 44 #include <sys/cpu.h> 45 #include <sys/taskqueue.h> 46 #include <machine/bus.h> 47 48 #include <dev/ofw/ofw_bus.h> 49 #include <dev/ofw/ofw_bus_subr.h> 50 51 #include <dev/extres/clk/clk.h> 52 #include <dev/extres/hwreset/hwreset.h> 53 54 #include <arm/allwinner/aw_sid.h> 55 56 #include "cpufreq_if.h" 57 58 #define THS_CTRL0 0x00 59 #define THS_CTRL1 0x04 60 #define ADC_CALI_EN (1 << 17) 61 #define THS_CTRL2 0x40 62 #define SENSOR_ACQ1_SHIFT 16 63 #define SENSOR2_EN (1 << 2) 64 #define SENSOR1_EN (1 << 1) 65 #define SENSOR0_EN (1 << 0) 66 #define THS_INTC 0x44 67 #define THS_INTS 0x48 68 #define THS2_DATA_IRQ_STS (1 << 10) 69 #define THS1_DATA_IRQ_STS (1 << 9) 70 #define THS0_DATA_IRQ_STS (1 << 8) 71 #define SHUT_INT2_STS (1 << 6) 72 #define SHUT_INT1_STS (1 << 5) 73 #define SHUT_INT0_STS (1 << 4) 74 #define ALARM_INT2_STS (1 << 2) 75 #define ALARM_INT1_STS (1 << 1) 76 #define ALARM_INT0_STS (1 << 0) 77 #define THS_ALARM0_CTRL 0x50 78 #define ALARM_T_HOT_MASK 0xfff 79 #define ALARM_T_HOT_SHIFT 16 80 #define ALARM_T_HYST_MASK 0xfff 81 #define ALARM_T_HYST_SHIFT 0 82 #define THS_SHUTDOWN0_CTRL 0x60 83 #define SHUT_T_HOT_MASK 0xfff 84 #define SHUT_T_HOT_SHIFT 16 85 #define THS_FILTER 0x70 86 #define THS_CALIB0 0x74 87 #define THS_CALIB1 0x78 88 #define THS_DATA0 0x80 89 #define THS_DATA1 0x84 90 #define THS_DATA2 0x88 91 #define DATA_MASK 0xfff 92 93 #define A83T_ADC_ACQUIRE_TIME 0x17 94 #define A83T_FILTER 0x4 95 #define A83T_INTC 0x1000 96 #define A83T_TEMP_BASE 2719000 97 #define A83T_TEMP_MUL 1000 98 #define A83T_TEMP_DIV 14186 99 #define A83T_CLK_RATE 24000000 100 101 #define A64_ADC_ACQUIRE_TIME 0x190 102 #define A64_FILTER 0x6 103 #define A64_INTC 0x18000 104 #define A64_TEMP_BASE 2170000 105 #define A64_TEMP_MUL 1000 106 #define A64_TEMP_DIV 8560 107 #define A64_CLK_RATE 4000000 108 109 #define H3_ADC_ACQUIRE_TIME 0x3f 110 #define H3_FILTER 0x6 111 #define H3_INTC 0x191000 112 #define H3_TEMP_BASE 1794000 113 #define H3_TEMP_MUL 1000 114 #define H3_TEMP_DIV -8253 115 #define H3_CLK_RATE 4000000 116 117 #define TEMP_C_TO_K 273 118 #define SENSOR_ENABLE_ALL (SENSOR0_EN|SENSOR1_EN|SENSOR2_EN) 119 #define SHUT_INT_ALL (SHUT_INT0_STS|SHUT_INT1_STS|SHUT_INT2_STS) 120 #define ALARM_INT_ALL (ALARM_INT0_STS) 121 122 #define MAX_SENSORS 3 123 #define MAX_CF_LEVELS 64 124 125 #define THROTTLE_ENABLE_DEFAULT 1 126 127 /* Enable thermal throttling */ 128 static int aw_thermal_throttle_enable = THROTTLE_ENABLE_DEFAULT; 129 TUNABLE_INT("hw.aw_thermal.throttle_enable", &aw_thermal_throttle_enable); 130 131 struct aw_thermal_sensor { 132 const char *name; 133 const char *desc; 134 }; 135 136 struct aw_thermal_config { 137 struct aw_thermal_sensor sensors[MAX_SENSORS]; 138 int nsensors; 139 uint64_t clk_rate; 140 uint32_t adc_acquire_time; 141 int adc_cali_en; 142 uint32_t filter; 143 uint32_t intc; 144 int (*to_temp)(uint32_t); 145 int temp_base; 146 int temp_mul; 147 int temp_div; 148 int calib0, calib1; 149 uint32_t calib0_mask, calib1_mask; 150 }; 151 152 static int 153 a83t_to_temp(uint32_t val) 154 { 155 return ((A83T_TEMP_BASE - (val * A83T_TEMP_MUL)) / A83T_TEMP_DIV); 156 } 157 158 static const struct aw_thermal_config a83t_config = { 159 .nsensors = 3, 160 .sensors = { 161 [0] = { 162 .name = "cluster0", 163 .desc = "CPU cluster 0 temperature", 164 }, 165 [1] = { 166 .name = "cluster1", 167 .desc = "CPU cluster 1 temperature", 168 }, 169 [2] = { 170 .name = "gpu", 171 .desc = "GPU temperature", 172 }, 173 }, 174 .clk_rate = A83T_CLK_RATE, 175 .adc_acquire_time = A83T_ADC_ACQUIRE_TIME, 176 .adc_cali_en = 1, 177 .filter = A83T_FILTER, 178 .intc = A83T_INTC, 179 .to_temp = a83t_to_temp, 180 .calib0 = 1, 181 .calib0_mask = 0xffffffff, 182 .calib1 = 1, 183 .calib1_mask = 0xffffffff, 184 }; 185 186 static int 187 a64_to_temp(uint32_t val) 188 { 189 return ((A64_TEMP_BASE - (val * A64_TEMP_MUL)) / A64_TEMP_DIV); 190 } 191 192 static const struct aw_thermal_config a64_config = { 193 .nsensors = 3, 194 .sensors = { 195 [0] = { 196 .name = "cpu", 197 .desc = "CPU temperature", 198 }, 199 [1] = { 200 .name = "gpu1", 201 .desc = "GPU temperature 1", 202 }, 203 [2] = { 204 .name = "gpu2", 205 .desc = "GPU temperature 2", 206 }, 207 }, 208 .clk_rate = A64_CLK_RATE, 209 .adc_acquire_time = A64_ADC_ACQUIRE_TIME, 210 .filter = A64_FILTER, 211 .intc = A64_INTC, 212 .to_temp = a64_to_temp, 213 }; 214 215 static int 216 h3_to_temp(uint32_t val) 217 { 218 return (((int)(val * H3_TEMP_MUL) - H3_TEMP_BASE) / H3_TEMP_DIV); 219 } 220 221 static const struct aw_thermal_config h3_config = { 222 .nsensors = 1, 223 .sensors = { 224 [0] = { 225 .name = "cpu", 226 .desc = "CPU temperature", 227 }, 228 }, 229 .clk_rate = H3_CLK_RATE, 230 .adc_acquire_time = H3_ADC_ACQUIRE_TIME, 231 .filter = H3_FILTER, 232 .intc = H3_INTC, 233 .to_temp = h3_to_temp, 234 .calib0 = 1, 235 .calib0_mask = 0xfff, 236 }; 237 238 static struct ofw_compat_data compat_data[] = { 239 { "allwinner,sun8i-a83t-ts", (uintptr_t)&a83t_config }, 240 { "allwinner,sun8i-h3-ts", (uintptr_t)&h3_config }, 241 { "allwinner,sun50i-a64-ts", (uintptr_t)&a64_config }, 242 { NULL, (uintptr_t)NULL } 243 }; 244 245 #define THS_CONF(d) \ 246 (void *)ofw_bus_search_compatible((d), compat_data)->ocd_data 247 248 struct aw_thermal_softc { 249 device_t dev; 250 struct resource *res[2]; 251 struct aw_thermal_config *conf; 252 253 struct task cf_task; 254 int throttle; 255 int min_freq; 256 struct cf_level levels[MAX_CF_LEVELS]; 257 eventhandler_tag cf_pre_tag; 258 }; 259 260 static struct resource_spec aw_thermal_spec[] = { 261 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 262 { SYS_RES_IRQ, 0, RF_ACTIVE }, 263 { -1, 0 } 264 }; 265 266 #define RD4(sc, reg) bus_read_4((sc)->res[0], (reg)) 267 #define WR4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) 268 269 static int 270 aw_thermal_init(struct aw_thermal_softc *sc) 271 { 272 uint32_t calib0, calib1; 273 int error; 274 275 if (sc->conf->calib0 != 0 || sc->conf->calib1 != 0) { 276 /* Read calibration settings from SRAM */ 277 error = aw_sid_read_tscalib(&calib0, &calib1); 278 if (error != 0) 279 return (error); 280 281 calib0 &= sc->conf->calib0_mask; 282 calib1 &= sc->conf->calib1_mask; 283 284 /* Write calibration settings to thermal controller */ 285 if (sc->conf->calib0 != 0 && calib0 != 0) 286 WR4(sc, THS_CALIB0, calib0); 287 if (sc->conf->calib1 != 0 && calib1 != 0) 288 WR4(sc, THS_CALIB1, calib1); 289 } 290 291 /* Configure ADC acquire time (CLK_IN/(N+1)) and enable sensors */ 292 WR4(sc, THS_CTRL1, ADC_CALI_EN); 293 WR4(sc, THS_CTRL0, sc->conf->adc_acquire_time); 294 WR4(sc, THS_CTRL2, sc->conf->adc_acquire_time << SENSOR_ACQ1_SHIFT); 295 296 /* Enable average filter */ 297 WR4(sc, THS_FILTER, sc->conf->filter); 298 299 /* Enable interrupts */ 300 WR4(sc, THS_INTS, RD4(sc, THS_INTS)); 301 WR4(sc, THS_INTC, sc->conf->intc | SHUT_INT_ALL | ALARM_INT_ALL); 302 303 /* Enable sensors */ 304 WR4(sc, THS_CTRL2, RD4(sc, THS_CTRL2) | SENSOR_ENABLE_ALL); 305 306 return (0); 307 } 308 309 static int 310 aw_thermal_gettemp(struct aw_thermal_softc *sc, int sensor) 311 { 312 uint32_t val; 313 314 val = RD4(sc, THS_DATA0 + (sensor * 4)); 315 316 return (sc->conf->to_temp(val) + TEMP_C_TO_K); 317 } 318 319 static int 320 aw_thermal_getshut(struct aw_thermal_softc *sc, int sensor) 321 { 322 uint32_t val; 323 324 val = RD4(sc, THS_SHUTDOWN0_CTRL + (sensor * 4)); 325 val = (val >> SHUT_T_HOT_SHIFT) & SHUT_T_HOT_MASK; 326 327 return (sc->conf->to_temp(val) + TEMP_C_TO_K); 328 } 329 330 static int 331 aw_thermal_gethyst(struct aw_thermal_softc *sc, int sensor) 332 { 333 uint32_t val; 334 335 val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4)); 336 val = (val >> ALARM_T_HYST_SHIFT) & ALARM_T_HYST_MASK; 337 338 return (sc->conf->to_temp(val) + TEMP_C_TO_K); 339 } 340 341 static int 342 aw_thermal_getalarm(struct aw_thermal_softc *sc, int sensor) 343 { 344 uint32_t val; 345 346 val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4)); 347 val = (val >> ALARM_T_HOT_SHIFT) & ALARM_T_HOT_MASK; 348 349 return (sc->conf->to_temp(val) + TEMP_C_TO_K); 350 } 351 352 static int 353 aw_thermal_sysctl(SYSCTL_HANDLER_ARGS) 354 { 355 struct aw_thermal_softc *sc; 356 int sensor, val; 357 358 sc = arg1; 359 sensor = arg2; 360 361 val = aw_thermal_gettemp(sc, sensor); 362 363 return sysctl_handle_opaque(oidp, &val, sizeof(val), req); 364 } 365 366 static void 367 aw_thermal_throttle(struct aw_thermal_softc *sc, int enable) 368 { 369 device_t cf_dev; 370 int count, error; 371 372 if (enable == sc->throttle) 373 return; 374 375 if (enable != 0) { 376 /* Set the lowest available frequency */ 377 cf_dev = devclass_get_device(devclass_find("cpufreq"), 0); 378 if (cf_dev == NULL) 379 return; 380 count = MAX_CF_LEVELS; 381 error = CPUFREQ_LEVELS(cf_dev, sc->levels, &count); 382 if (error != 0 || count == 0) 383 return; 384 sc->min_freq = sc->levels[count - 1].total_set.freq; 385 error = CPUFREQ_SET(cf_dev, &sc->levels[count - 1], 386 CPUFREQ_PRIO_USER); 387 if (error != 0) 388 return; 389 } 390 391 sc->throttle = enable; 392 } 393 394 static void 395 aw_thermal_cf_task(void *arg, int pending) 396 { 397 struct aw_thermal_softc *sc; 398 399 sc = arg; 400 401 aw_thermal_throttle(sc, 1); 402 } 403 404 static void 405 aw_thermal_cf_pre_change(void *arg, const struct cf_level *level, int *status) 406 { 407 struct aw_thermal_softc *sc; 408 int temp_cur, temp_alarm; 409 410 sc = arg; 411 412 if (aw_thermal_throttle_enable == 0 || sc->throttle == 0 || 413 level->total_set.freq == sc->min_freq) 414 return; 415 416 temp_cur = aw_thermal_gettemp(sc, 0); 417 temp_alarm = aw_thermal_getalarm(sc, 0); 418 419 if (temp_cur < temp_alarm) 420 aw_thermal_throttle(sc, 0); 421 else 422 *status = ENXIO; 423 } 424 425 static void 426 aw_thermal_intr(void *arg) 427 { 428 struct aw_thermal_softc *sc; 429 device_t dev; 430 uint32_t ints; 431 432 dev = arg; 433 sc = device_get_softc(dev); 434 435 ints = RD4(sc, THS_INTS); 436 WR4(sc, THS_INTS, ints); 437 438 if ((ints & SHUT_INT_ALL) != 0) { 439 device_printf(dev, 440 "WARNING - current temperature exceeds safe limits\n"); 441 shutdown_nice(RB_POWEROFF); 442 } 443 444 if ((ints & ALARM_INT_ALL) != 0) 445 taskqueue_enqueue(taskqueue_thread, &sc->cf_task); 446 } 447 448 static int 449 aw_thermal_probe(device_t dev) 450 { 451 if (!ofw_bus_status_okay(dev)) 452 return (ENXIO); 453 454 if (THS_CONF(dev) == NULL) 455 return (ENXIO); 456 457 device_set_desc(dev, "Allwinner Thermal Sensor Controller"); 458 return (BUS_PROBE_DEFAULT); 459 } 460 461 static int 462 aw_thermal_attach(device_t dev) 463 { 464 struct aw_thermal_softc *sc; 465 clk_t clk_ahb, clk_ths; 466 hwreset_t rst; 467 int i, error; 468 void *ih; 469 470 sc = device_get_softc(dev); 471 clk_ahb = clk_ths = NULL; 472 rst = NULL; 473 ih = NULL; 474 475 sc->conf = THS_CONF(dev); 476 TASK_INIT(&sc->cf_task, 0, aw_thermal_cf_task, sc); 477 478 if (bus_alloc_resources(dev, aw_thermal_spec, sc->res) != 0) { 479 device_printf(dev, "cannot allocate resources for device\n"); 480 return (ENXIO); 481 } 482 483 if (clk_get_by_ofw_name(dev, 0, "ahb", &clk_ahb) == 0) { 484 error = clk_enable(clk_ahb); 485 if (error != 0) { 486 device_printf(dev, "cannot enable ahb clock\n"); 487 goto fail; 488 } 489 } 490 if (clk_get_by_ofw_name(dev, 0, "ths", &clk_ths) == 0) { 491 error = clk_set_freq(clk_ths, sc->conf->clk_rate, 0); 492 if (error != 0) { 493 device_printf(dev, "cannot set ths clock rate\n"); 494 goto fail; 495 } 496 error = clk_enable(clk_ths); 497 if (error != 0) { 498 device_printf(dev, "cannot enable ths clock\n"); 499 goto fail; 500 } 501 } 502 if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) { 503 error = hwreset_deassert(rst); 504 if (error != 0) { 505 device_printf(dev, "cannot de-assert reset\n"); 506 goto fail; 507 } 508 } 509 510 error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, 511 NULL, aw_thermal_intr, dev, &ih); 512 if (error != 0) { 513 device_printf(dev, "cannot setup interrupt handler\n"); 514 goto fail; 515 } 516 517 if (aw_thermal_init(sc) != 0) 518 goto fail; 519 520 for (i = 0; i < sc->conf->nsensors; i++) 521 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 522 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 523 OID_AUTO, sc->conf->sensors[i].name, 524 CTLTYPE_INT | CTLFLAG_RD, 525 sc, i, aw_thermal_sysctl, "IK0", 526 sc->conf->sensors[i].desc); 527 528 if (bootverbose) 529 for (i = 0; i < sc->conf->nsensors; i++) { 530 device_printf(dev, 531 "#%d: alarm %dC hyst %dC shut %dC\n", i, 532 aw_thermal_getalarm(sc, i) - TEMP_C_TO_K, 533 aw_thermal_gethyst(sc, i) - TEMP_C_TO_K, 534 aw_thermal_getshut(sc, i) - TEMP_C_TO_K); 535 } 536 537 sc->cf_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change, 538 aw_thermal_cf_pre_change, sc, EVENTHANDLER_PRI_FIRST); 539 540 return (0); 541 542 fail: 543 if (ih != NULL) 544 bus_teardown_intr(dev, sc->res[1], ih); 545 if (rst != NULL) 546 hwreset_release(rst); 547 if (clk_ahb != NULL) 548 clk_release(clk_ahb); 549 if (clk_ths != NULL) 550 clk_release(clk_ths); 551 bus_release_resources(dev, aw_thermal_spec, sc->res); 552 553 return (ENXIO); 554 } 555 556 static device_method_t aw_thermal_methods[] = { 557 /* Device interface */ 558 DEVMETHOD(device_probe, aw_thermal_probe), 559 DEVMETHOD(device_attach, aw_thermal_attach), 560 561 DEVMETHOD_END 562 }; 563 564 static driver_t aw_thermal_driver = { 565 "aw_thermal", 566 aw_thermal_methods, 567 sizeof(struct aw_thermal_softc), 568 }; 569 570 static devclass_t aw_thermal_devclass; 571 572 DRIVER_MODULE(aw_thermal, simplebus, aw_thermal_driver, aw_thermal_devclass, 573 0, 0); 574 MODULE_VERSION(aw_thermal, 1); 575