1 /* $OpenBSD: rktemp.c,v 1.4 2019/01/01 15:56:19 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/device.h> 21 #include <sys/sensors.h> 22 23 #include <machine/intr.h> 24 #include <machine/bus.h> 25 #include <machine/fdt.h> 26 27 #include <dev/ofw/openfirm.h> 28 #include <dev/ofw/ofw_clock.h> 29 #include <dev/ofw/ofw_misc.h> 30 #include <dev/ofw/ofw_pinctrl.h> 31 #include <dev/ofw/fdt.h> 32 33 /* Registers */ 34 #define TSADC_USER_CON 0x0000 35 #define TSADC_AUTO_CON 0x0004 36 #define TSADC_AUTO_CON_TSHUT_POLARITY (1 << 8) 37 #define TSADC_AUTO_CON_SRC3_EN (1 << 7) 38 #define TSADC_AUTO_CON_SRC2_EN (1 << 6) 39 #define TSADC_AUTO_CON_SRC1_EN (1 << 5) 40 #define TSADC_AUTO_CON_SRC0_EN (1 << 4) 41 #define TSADC_AUTO_CON_TSADC_Q_SEL (1 << 1) 42 #define TSADC_AUTO_CON_AUTO_EN (1 << 0) 43 #define TSADC_INT_EN 0x0008 44 #define TSADC_INT_EN_TSHUT_2CRU_EN_SRC3 (1 << 11) 45 #define TSADC_INT_EN_TSHUT_2CRU_EN_SRC2 (1 << 10) 46 #define TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 (1 << 9) 47 #define TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 (1 << 8) 48 #define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC3 (1 << 7) 49 #define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC2 (1 << 6) 50 #define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 (1 << 5) 51 #define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 (1 << 4) 52 #define TSADC_INT_PD 0x000c 53 #define TSADC_DATA0 0x0020 54 #define TSADC_DATA1 0x0024 55 #define TSADC_DATA2 0x0028 56 #define TSADC_DATA3 0x002c 57 #define TSADC_COMP0_INT 0x0030 58 #define TSADC_COMP1_INT 0x0034 59 #define TSADC_COMP2_INT 0x0038 60 #define TSADC_COMP3_INT 0x003c 61 #define TSADC_COMP0_SHUT 0x0040 62 #define TSADC_COMP1_SHUT 0x0044 63 #define TSADC_COMP2_SHUT 0x0048 64 #define TSADC_COMP3_SHUT 0x004c 65 #define TSADC_AUTO_PERIOD 0x0068 66 #define TSADC_AUTO_PERIOD_HT 0x006c 67 68 #define HREAD4(sc, reg) \ 69 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 70 #define HWRITE4(sc, reg, val) \ 71 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 72 73 struct rktemp_entry { 74 int32_t temp; 75 int32_t code; 76 }; 77 78 /* RK3288 conversion table. */ 79 struct rktemp_entry rk3288_temps[] = { 80 { -40000, 3800 }, 81 { -35000, 3792 }, 82 { -30000, 3783 }, 83 { -25000, 3774 }, 84 { -20000, 3765 }, 85 { -15000, 3756 }, 86 { -10000, 3747 }, 87 { -5000, 3737 }, 88 { 0, 3728 }, 89 { 5000, 3718 }, 90 { 10000, 3708 }, 91 { 15000, 3698 }, 92 { 20000, 3688 }, 93 { 25000, 3678 }, 94 { 30000, 3667 }, 95 { 35000, 3656 }, 96 { 40000, 3645 }, 97 { 45000, 3634 }, 98 { 50000, 3623 }, 99 { 55000, 3611 }, 100 { 60000, 3600 }, 101 { 65000, 3588 }, 102 { 70000, 3575 }, 103 { 75000, 3563 }, 104 { 80000, 3550 }, 105 { 85000, 3537 }, 106 { 90000, 3524 }, 107 { 95000, 3510 }, 108 { 100000, 3496 }, 109 { 105000, 3482 }, 110 { 110000, 3467 }, 111 { 115000, 3452 }, 112 { 120000, 3437 }, 113 { 125000, 3421 }, 114 }; 115 116 const char *rk3288_names[] = { "", "CPU", "GPU" }; 117 118 /* RK3328 conversion table. */ 119 struct rktemp_entry rk3328_temps[] = { 120 { -40000, 296 }, 121 { -35000, 304 }, 122 { -30000, 313 }, 123 { -20000, 331 }, 124 { -15000, 340 }, 125 { -10000, 349 }, 126 { -5000, 359 }, 127 { 0, 368 }, 128 { 5000, 378 }, 129 { 10000, 388 }, 130 { 15000, 398 }, 131 { 20000, 408 }, 132 { 25000, 418 }, 133 { 30000, 429 }, 134 { 35000, 440 }, 135 { 40000, 451 }, 136 { 45000, 462 }, 137 { 50000, 473 }, 138 { 55000, 485 }, 139 { 60000, 496 }, 140 { 65000, 508 }, 141 { 70000, 521 }, 142 { 75000, 533 }, 143 { 80000, 546 }, 144 { 85000, 559 }, 145 { 90000, 572 }, 146 { 95000, 586 }, 147 { 100000, 600 }, 148 { 105000, 614 }, 149 { 110000, 629 }, 150 { 115000, 644 }, 151 { 120000, 659 }, 152 { 125000, 675 }, 153 }; 154 155 const char *rk3328_names[] = { "CPU" }; 156 157 /* RK3399 conversion table. */ 158 struct rktemp_entry rk3399_temps[] = { 159 { -40000, 402 }, 160 { -35000, 410 }, 161 { -30000, 419 }, 162 { -25000, 427 }, 163 { -20000, 436 }, 164 { -15000, 444 }, 165 { -10000, 453 }, 166 { -5000, 461 }, 167 { 0, 470 }, 168 { 5000, 478 }, 169 { 10000, 487 }, 170 { 15000, 496 }, 171 { 20000, 504 }, 172 { 25000, 513 }, 173 { 30000, 521 }, 174 { 35000, 530 }, 175 { 40000, 538 }, 176 { 45000, 547 }, 177 { 50000, 555 }, 178 { 55000, 564 }, 179 { 60000, 573 }, 180 { 65000, 581 }, 181 { 70000, 590 }, 182 { 75000, 599 }, 183 { 80000, 607 }, 184 { 85000, 616 }, 185 { 90000, 624 }, 186 { 95000, 633 }, 187 { 100000, 642 }, 188 { 105000, 650 }, 189 { 110000, 659 }, 190 { 115000, 668 }, 191 { 120000, 677 }, 192 { 125000, 685 }, 193 }; 194 195 const char *rk3399_names[] = { "CPU", "GPU" }; 196 197 struct rktemp_softc { 198 struct device sc_dev; 199 bus_space_tag_t sc_iot; 200 bus_space_handle_t sc_ioh; 201 202 struct rktemp_entry *sc_temps; 203 int sc_ntemps; 204 205 struct ksensor sc_sensors[3]; 206 int sc_nsensors; 207 struct ksensordev sc_sensordev; 208 }; 209 210 int rktemp_match(struct device *, void *, void *); 211 void rktemp_attach(struct device *, struct device *, void *); 212 213 struct cfattach rktemp_ca = { 214 sizeof (struct rktemp_softc), rktemp_match, rktemp_attach 215 }; 216 217 struct cfdriver rktemp_cd = { 218 NULL, "rktemp", DV_DULL 219 }; 220 221 int32_t rktemp_calc_code(struct rktemp_softc *, int32_t); 222 int32_t rktemp_calc_temp(struct rktemp_softc *, int32_t); 223 int rktemp_valid(struct rktemp_softc *, int32_t); 224 void rktemp_refresh_sensors(void *); 225 226 int 227 rktemp_match(struct device *parent, void *match, void *aux) 228 { 229 struct fdt_attach_args *faa = aux; 230 231 return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-tsadc") || 232 OF_is_compatible(faa->fa_node, "rockchip,rk3328-tsadc") || 233 OF_is_compatible(faa->fa_node, "rockchip,rk3399-tsadc")); 234 } 235 236 void 237 rktemp_attach(struct device *parent, struct device *self, void *aux) 238 { 239 struct rktemp_softc *sc = (struct rktemp_softc *)self; 240 struct fdt_attach_args *faa = aux; 241 const char **names; 242 uint32_t mode, polarity, temp; 243 uint32_t auto_con, int_en; 244 int node = faa->fa_node; 245 int i; 246 247 if (faa->fa_nreg < 1) { 248 printf(": no registers\n"); 249 return; 250 } 251 252 sc->sc_iot = faa->fa_iot; 253 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 254 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 255 printf(": can't map registers\n"); 256 return; 257 } 258 259 printf("\n"); 260 261 if (OF_is_compatible(node, "rockchip,rk3288-tsadc")) { 262 sc->sc_temps = rk3288_temps; 263 sc->sc_ntemps = nitems(rk3288_temps); 264 sc->sc_nsensors = 3; 265 names = rk3288_names; 266 } else if (OF_is_compatible(node, "rockchip,rk3328-tsadc")) { 267 sc->sc_temps = rk3328_temps; 268 sc->sc_ntemps = nitems(rk3328_temps); 269 sc->sc_nsensors = 1; 270 names = rk3328_names; 271 } else { 272 sc->sc_temps = rk3399_temps; 273 sc->sc_ntemps = nitems(rk3399_temps); 274 sc->sc_nsensors = 2; 275 names = rk3399_names; 276 } 277 278 pinctrl_byname(node, "init"); 279 280 clock_set_assigned(node); 281 clock_enable(node, "tsadc"); 282 clock_enable(node, "apb_pclk"); 283 284 /* Reset the TS-ADC controller block. */ 285 reset_assert(node, "tsadc-apb"); 286 delay(10); 287 reset_deassert(node, "tsadc-apb"); 288 289 mode = OF_getpropint(node, "rockchip,hw-tshut-mode", 1); 290 polarity = OF_getpropint(node, "rockchip,hw-tshut-polarity", 0); 291 temp = OF_getpropint(node, "rockchip,hw-tshut-temp", 95000); 292 293 auto_con = HREAD4(sc, TSADC_AUTO_CON); 294 auto_con |= TSADC_AUTO_CON_TSADC_Q_SEL; 295 if (polarity) 296 auto_con |= TSADC_AUTO_CON_TSHUT_POLARITY; 297 HWRITE4(sc, TSADC_AUTO_CON, auto_con); 298 299 /* Configure mode. */ 300 int_en = HREAD4(sc, TSADC_INT_EN); 301 for (i = 0; i < sc->sc_nsensors; i++) { 302 if (mode) 303 int_en |= (TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 << i); 304 else 305 int_en |= (TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 << i); 306 } 307 HWRITE4(sc, TSADC_INT_EN, int_en); 308 309 /* Set shutdown limit. */ 310 for (i = 0; i < sc->sc_nsensors; i++) { 311 HWRITE4(sc, TSADC_COMP0_SHUT + i * 4, 312 rktemp_calc_code(sc, temp)); 313 auto_con |= (TSADC_AUTO_CON_SRC0_EN << i); 314 } 315 HWRITE4(sc, TSADC_AUTO_CON, auto_con); 316 317 pinctrl_byname(faa->fa_node, "default"); 318 319 /* Finally turn on the ADC. */ 320 auto_con |= TSADC_AUTO_CON_AUTO_EN; 321 HWRITE4(sc, TSADC_AUTO_CON, auto_con); 322 323 /* Register sensors. */ 324 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 325 sizeof(sc->sc_sensordev.xname)); 326 for (i = 0; i < sc->sc_nsensors; i++) { 327 strlcpy(sc->sc_sensors[i].desc, names[i], 328 sizeof(sc->sc_sensors[i].desc)); 329 sc->sc_sensors[i].type = SENSOR_TEMP; 330 sc->sc_sensors[i].flags = SENSOR_FINVALID; 331 sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]); 332 } 333 sensordev_install(&sc->sc_sensordev); 334 sensor_task_register(sc, rktemp_refresh_sensors, 5); 335 } 336 337 int32_t 338 rktemp_calc_code(struct rktemp_softc *sc, int32_t temp) 339 { 340 const int n = sc->sc_ntemps; 341 int32_t code0, delta_code; 342 int32_t temp0, delta_temp; 343 int i; 344 345 if (temp <= sc->sc_temps[0].temp) 346 return sc->sc_temps[0].code; 347 if (temp >= sc->sc_temps[n - 1].temp) 348 return sc->sc_temps[n - 1].code; 349 350 for (i = 1; i < n; i++) { 351 if (temp < sc->sc_temps[i].temp) 352 break; 353 } 354 355 code0 = sc->sc_temps[i - 1].code; 356 temp0 = sc->sc_temps[i - 1].temp; 357 delta_code = sc->sc_temps[i].code - code0; 358 delta_temp = sc->sc_temps[i].temp - temp0; 359 360 return code0 + (temp - temp0) * delta_code / delta_temp; 361 } 362 363 int32_t 364 rktemp_calc_temp(struct rktemp_softc *sc, int32_t code) 365 { 366 const int n = sc->sc_ntemps; 367 int32_t code0, delta_code; 368 int32_t temp0, delta_temp; 369 int i; 370 371 /* Handle both negative and postive temperature coefficients. */ 372 if (sc->sc_temps[0].code > sc->sc_temps[1].code) { 373 if (code >= sc->sc_temps[0].code) 374 return sc->sc_temps[0].code; 375 if (code <= sc->sc_temps[n - 1].code) 376 return sc->sc_temps[n - 1].temp; 377 378 for (i = 1; i < n; i++) { 379 if (code > sc->sc_temps[i].code) 380 break; 381 } 382 } else { 383 if (code <= sc->sc_temps[0].code) 384 return sc->sc_temps[0].temp; 385 if (code >= sc->sc_temps[n - 1].code) 386 return sc->sc_temps[n - 1].temp; 387 388 for (i = 1; i < n; i++) { 389 if (code < sc->sc_temps[i].code) 390 break; 391 } 392 } 393 394 code0 = sc->sc_temps[i - 1].code; 395 temp0 = sc->sc_temps[i - 1].temp; 396 delta_code = sc->sc_temps[i].code - code0; 397 delta_temp = sc->sc_temps[i].temp - temp0; 398 399 return temp0 + (code - code0) * delta_temp / delta_code; 400 } 401 402 int 403 rktemp_valid(struct rktemp_softc *sc, int32_t code) 404 { 405 const int n = sc->sc_ntemps; 406 407 if (sc->sc_temps[0].code > sc->sc_temps[1].code) { 408 if (code > sc->sc_temps[0].code) 409 return 0; 410 if (code < sc->sc_temps[n - 1].code) 411 return 0; 412 } else { 413 if (code < sc->sc_temps[0].code) 414 return 0; 415 if (code > sc->sc_temps[n - 1].code) 416 return 0; 417 } 418 return 1; 419 } 420 421 void 422 rktemp_refresh_sensors(void *arg) 423 { 424 struct rktemp_softc *sc = arg; 425 int32_t code, temp; 426 int i; 427 428 for (i = 0; i < sc->sc_nsensors; i++) { 429 code = HREAD4(sc, TSADC_DATA0 + i * 4); 430 temp = rktemp_calc_temp(sc, code); 431 sc->sc_sensors[i].value = 273150000 + 1000 * temp; 432 if (rktemp_valid(sc, code)) 433 sc->sc_sensors[i].flags &= ~SENSOR_FINVALID; 434 else 435 sc->sc_sensors[i].flags |= SENSOR_FINVALID; 436 } 437 } 438