1/* $NetBSD: rk_tsadc.c,v 1.16 2021/12/11 19:24:21 mrg Exp $ */ 2 3/* 4 * Copyright (c) 2019 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30 31__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.16 2021/12/11 19:24:21 mrg Exp $"); 32 33/* 34 * Driver for the TSADC temperature sensor monitor in RK3328 and RK3399. 35 * 36 * TODO: 37 * - handle setting various temp values 38 * - handle DT trips/temp value defaults 39 * - interrupts aren't triggered (test by lowering warn/crit values), and 40 * once they work, make the interrupt do something 41 */ 42 43#include <sys/param.h> 44#include <sys/bus.h> 45#include <sys/device.h> 46#include <sys/intr.h> 47#include <sys/systm.h> 48#include <sys/time.h> 49#include <sys/kmem.h> 50 51#include <dev/fdt/fdtvar.h> 52#include <dev/fdt/syscon.h> 53 54#include <dev/sysmon/sysmonvar.h> 55 56#ifdef RKTSADC_DEBUG 57#define DPRINTF(fmt, ...) \ 58 printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__) 59#else 60#define DPRINTF(fmt, ...) 61#endif 62 63/* Register definitions */ 64#define TSADC_USER_CON 0x00 65#define TSADC_USER_CON_ADC_STATUS __BIT(12) 66#define TSADC_USER_CON_INTER_PD_SOC __BITS(11,6) 67#define TSADC_USER_CON_START __BIT(5) 68#define TSADC_USER_CON_START_MODE __BIT(4) 69#define TSADC_USER_CON_ADC_POWER_CTRL __BIT(3) 70#define TSADC_USER_CON_ADC_INPUT_SRC_SEL __BITS(2,0) 71#define TSADC_AUTO_CON 0x04 72#define TSADC_AUTO_CON_LAST_TSHUT_2CRU __BIT(25) 73#define TSADC_AUTO_CON_LAST_TSHUT_2GPIO __BIT(24) 74#define TSADC_AUTO_CON_SAMPLE_DLY_SEL __BIT(17) 75#define TSADC_AUTO_CON_AUTO_STATUS __BIT(16) 76#define TSADC_AUTO_CON_SRC1_LT_EN __BIT(13) 77#define TSADC_AUTO_CON_SRC0_LT_EN __BIT(12) 78#define TSADC_AUTO_CON_TSHUT_POLARITY __BIT(8) 79#define TSADC_AUTO_CON_SRC1_EN __BIT(5) 80#define TSADC_AUTO_CON_SRC0_EN __BIT(4) 81#define TSADC_AUTO_CON_Q_SEL __BIT(1) 82#define TSADC_AUTO_CON_AUTO_EN __BIT(0) 83#define TSADC_INT_EN 0x08 84#define TSADC_INT_EN_EOC_INT_EN __BIT(16) 85#define TSADC_INT_EN_LT_INTEN_SRC1 __BIT(13) 86#define TSADC_INT_EN_LT_INTEN_SRC0 __BIT(12) 87#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 __BIT(9) 88#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 __BIT(8) 89#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 __BIT(5) 90#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 __BIT(4) 91#define TSADC_INT_EN_HT_INTEN_SRC1 __BIT(1) 92#define TSADC_INT_EN_HT_INTEN_SRC0 __BIT(0) 93#define TSADC_INT_PD 0x0c 94#define TSADC_INT_PD_EOC_INT_PD_V3 __BIT(16) 95#define TSADC_INT_PD_LT_IRQ_SRC1 __BIT(13) 96#define TSADC_INT_PD_LT_IRQ_SRC0 __BIT(12) 97#define TSADC_INT_PD_EOC_INT_PD_V2 __BIT(8) 98#define TSADC_INT_PD_TSHUT_O_SRC1 __BIT(5) 99#define TSADC_INT_PD_TSHUT_O_SRC0 __BIT(4) 100#define TSADC_INT_PD_HT_IRQ_SRC1 __BIT(1) 101#define TSADC_INT_PD_HT_IRQ_SRC0 __BIT(0) 102#define TSADC_DATA0 0x20 103#define TSADC_DATA0_ADC_DATA __BITS(11,0) 104#define TSADC_DATA1 0x24 105#define TSADC_DATA1_ADC_DATA __BITS(11,0) 106#define TSADC_COMP0_INT 0x30 107#define TSADC_COMP0_INT_COMP_SRC0 __BITS(11,0) 108#define TSADC_COMP1_INT 0x34 109#define TSADC_COMP1_INT_COMP_SRC1 __BITS(11,0) 110#define TSADC_COMP0_SHUT 0x40 111#define TSADC_COMP0_SHUT_COMP_SRC0 __BITS(11,0) 112#define TSADC_COMP1_SHUT 0x44 113#define TSADC_COMP1_SHUT_COMP_SRC1 __BITS(11,0) 114#define TSADC_HIGH_INT_DEBOUNCE 0x60 115#define TSADC_HIGH_INT_DEBOUNCE_TEMP __BITS(7,0) 116#define TSADC_HIGH_TSHUT_DEBOUNCE 0x64 117#define TSADC_HIGH_TSHUT_DEBOUNCE_TEMP __BITS(7,0) 118#define TSADC_AUTO_PERIOD 0x68 119#define TSADC_AUTO_PERIOD_TEMP __BITS(31,0) 120#define TSADC_AUTO_PERIOD_HT 0x6c 121#define TSADC_AUTO_PERIOD_HT_TEMP __BITS(31,0) 122#define TSADC_COMP0_LOW_INT 0x80 123#define TSADC_COMP0_LOW_INT_COMP_SRC0 __BITS(11,0) 124#define TSADC_COMP1_LOW_INT 0x84 125#define TSADC_COMP1_LOW_INT_COMP_SRC1 __BITS(11,0) 126 127#define RK3288_TSADC_AUTO_PERIOD_TIME 250 /* 250ms */ 128#define RK3288_TSADC_AUTO_PERIOD_HT_TIME 50 /* 50ms */ 129#define RK3328_TSADC_AUTO_PERIOD_TIME 250 /* 250ms */ 130#define RK3399_TSADC_AUTO_PERIOD_TIME 1875 /* 2.5ms */ 131#define TSADC_HT_DEBOUNCE_COUNT 4 132 133/* 134 * All this magic is taking from the Linux rockchip_thermal driver. 135 * 136 * VCM means "voltage common mode", but the documentation for RK3399 137 * does not mention this and I don't know what any of this really 138 * is for. 139 */ 140#define RK3399_GRF_SARADC_TESTBIT 0xe644 141#define RK3399_GRF_SARADC_TESTBIT_ON (0x10001 << 2) 142#define RK3399_GRF_TSADC_TESTBIT_L 0xe648 143#define RK3399_GRF_TSADC_TESTBIT_VCM_EN_L (0x10001 << 7) 144#define RK3399_GRF_TSADC_TESTBIT_H 0xe64c 145#define RK3399_GRF_TSADC_TESTBIT_VCM_EN_H (0x10001 << 7) 146#define RK3399_GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) 147 148#define TEMP_uC_TO_uK 273150000 149 150#define TSHUT_MODE_CPU 0 151#define TSHUT_MODE_GPIO 1 152 153#define TSHUT_LOW_ACTIVE 0 154#define TSHUT_HIGH_ACTIVE 1 155 156#define TSHUT_DEF_TEMP 95000 157 158#define TSADC_DATA_MAX 0xfff 159 160#define MAX_SENSORS 2 161 162typedef struct rk_data_array { 163 uint32_t data; /* register value */ 164 int temp; /* micro-degC */ 165} rk_data_array; 166 167struct rk_tsadc_softc; 168typedef struct rk_data { 169 const char *rd_name; 170 const rk_data_array *rd_array; 171 size_t rd_size; 172 void (*rd_init)(struct rk_tsadc_softc *, int, int); 173 bool rd_decr; /* lower values -> higher temp */ 174 unsigned rd_min, rd_max; 175 unsigned rd_auto_period; 176 unsigned rd_auto_period_ht; 177 unsigned rd_num_sensors; 178 unsigned rd_version; 179} rk_data; 180 181/* Per-sensor data */ 182struct rk_tsadc_sensor { 183 envsys_data_t s_data; 184 bool s_attached; 185 /* TSADC register offsets for this sensor */ 186 unsigned s_data_reg; 187 unsigned s_comp_tshut; 188 unsigned s_comp_int; 189 /* enable bit in AUTO_CON register */ 190 unsigned s_comp_int_en; 191 /* warn/crit values in micro Kelvin */ 192 int s_warn; 193 int s_tshut; 194}; 195 196struct rk_tsadc_softc { 197 device_t sc_dev; 198 int sc_phandle; 199 bus_space_tag_t sc_bst; 200 bus_space_handle_t sc_bsh; 201 size_t sc_size; 202 uint32_t sc_data_mask; 203 void *sc_ih; 204 205 struct sysmon_envsys *sc_sme; 206 struct rk_tsadc_sensor sc_sensors[MAX_SENSORS]; 207 208 struct clk *sc_clock; 209 struct clk *sc_clockapb; 210 struct fdtbus_reset *sc_reset; 211 struct syscon *sc_syscon; 212 213 const rk_data *sc_rd; 214}; 215 216static int rk_tsadc_match(device_t, cfdata_t, void *); 217static void rk_tsadc_attach(device_t, device_t, void *); 218static int rk_tsadc_detach(device_t, int); 219static int rk_tsadc_init_clocks(struct rk_tsadc_softc *); 220static void rk_tsadc_init_counts(struct rk_tsadc_softc *); 221static void rk_tsadc_tshut_set(struct rk_tsadc_softc *s); 222static void rk_tsadc_init_tshut(struct rk_tsadc_softc *, int, int); 223static void rk_tsadc_init_common(struct rk_tsadc_softc *, int, int); 224static void rk_tsadc_init_rk3399(struct rk_tsadc_softc *, int, int); 225static void rk_tsadc_init_enable(struct rk_tsadc_softc *); 226static void rk_tsadc_init(struct rk_tsadc_softc *, int, int); 227static void rk_tsadc_refresh(struct sysmon_envsys *, envsys_data_t *); 228static void rk_tsadc_get_limits(struct sysmon_envsys *, envsys_data_t *, 229 sysmon_envsys_lim_t *, uint32_t *); 230 231static int rk_tsadc_intr(void *); 232static int rk_tsadc_data_to_temp(struct rk_tsadc_softc *, uint32_t); 233static uint32_t rk_tsadc_temp_to_data(struct rk_tsadc_softc *, int); 234 235/* RK3328/RK3399 compatible sensors */ 236static const struct rk_tsadc_sensor rk_tsadc_sensors[] = { 237 { 238 .s_data = { .desc = "CPU" }, 239 .s_data_reg = TSADC_DATA0, 240 .s_comp_tshut = TSADC_COMP0_SHUT, 241 .s_comp_int = TSADC_COMP0_INT, 242 .s_comp_int_en = TSADC_AUTO_CON_SRC0_EN, 243 /* 244 * XXX DT has: 245 * cpu_alert1: cpu_alert1 { 246 * temperature = <75000>; 247 * hysteresis = <2000>; 248 * cpu_crit: cpu_crit { 249 * temperature = <95000>; 250 * hysteresis = <2000>; 251 * pull out of here? 252 * do something with hysteresis? put in debounce? 253 * 254 * Note that tshut may be overridden by the board specific DT. 255 */ 256 .s_warn = 75000000, 257 .s_tshut = 95000000, 258 }, { 259 .s_data = { .desc = "GPU" }, 260 .s_data_reg = TSADC_DATA1, 261 .s_comp_tshut = TSADC_COMP1_SHUT, 262 .s_comp_int = TSADC_COMP1_INT, 263 .s_comp_int_en = TSADC_AUTO_CON_SRC1_EN, 264 .s_warn = 75000000, 265 .s_tshut = 95000000, 266 }, 267}; 268 269/* 270 * Table from RK3288 manual. 271 */ 272static const rk_data_array rk3288_data_array[] = { 273#define ENTRY(d,C) { .data = (d), .temp = (C) * 1000 * 1000, } 274 ENTRY(TSADC_DATA_MAX, -40), 275 ENTRY(3800, -40), 276 ENTRY(3792, -35), 277 ENTRY(3783, -30), 278 ENTRY(3774, -25), 279 ENTRY(3765, -20), 280 ENTRY(3756, -15), 281 ENTRY(3747, -10), 282 ENTRY(3737, -5), 283 ENTRY(3728, 0), 284 ENTRY(3718, 5), 285 ENTRY(3708, 10), 286 ENTRY(3698, 15), 287 ENTRY(3688, 20), 288 ENTRY(3678, 25), 289 ENTRY(3667, 30), 290 ENTRY(3656, 35), 291 ENTRY(3645, 40), 292 ENTRY(3634, 45), 293 ENTRY(3623, 50), 294 ENTRY(3611, 55), 295 ENTRY(3600, 60), 296 ENTRY(3588, 65), 297 ENTRY(3575, 70), 298 ENTRY(3563, 75), 299 ENTRY(3550, 80), 300 ENTRY(3537, 85), 301 ENTRY(3524, 90), 302 ENTRY(3510, 95), 303 ENTRY(3496, 100), 304 ENTRY(3482, 105), 305 ENTRY(3467, 110), 306 ENTRY(3452, 115), 307 ENTRY(3437, 120), 308 ENTRY(3421, 125), 309 ENTRY(0, 15), 310#undef ENTRY 311}; 312 313/* 314 * Table from RK3328 manual. Note that the manual lists valid numbers as 315 * 4096 - number. This also means it is increasing not decreasing for 316 * higher temps, and the min and max are also offset from 4096. 317 */ 318#define RK3328_DATA_OFFSET (4096) 319static const rk_data_array rk3328_data_array[] = { 320#define ENTRY(d,C) \ 321 { .data = RK3328_DATA_OFFSET - (d), .temp = (C) * 1000 * 1000, } 322 ENTRY(TSADC_DATA_MAX, -40), 323 ENTRY(3800, -40), 324 ENTRY(3792, -35), 325 ENTRY(3783, -30), 326 ENTRY(3774, -25), 327 ENTRY(3765, -20), 328 ENTRY(3756, -15), 329 ENTRY(3747, -10), 330 ENTRY(3737, -5), 331 ENTRY(3728, 0), 332 ENTRY(3718, 5), 333 ENTRY(3708, 10), 334 ENTRY(3698, 15), 335 ENTRY(3688, 20), 336 ENTRY(3678, 25), 337 ENTRY(3667, 30), 338 ENTRY(3656, 35), 339 ENTRY(3645, 40), 340 ENTRY(3634, 45), 341 ENTRY(3623, 50), 342 ENTRY(3611, 55), 343 ENTRY(3600, 60), 344 ENTRY(3588, 65), 345 ENTRY(3575, 70), 346 ENTRY(3563, 75), 347 ENTRY(3550, 80), 348 ENTRY(3537, 85), 349 ENTRY(3524, 90), 350 ENTRY(3510, 95), 351 ENTRY(3496, 100), 352 ENTRY(3482, 105), 353 ENTRY(3467, 110), 354 ENTRY(3452, 115), 355 ENTRY(3437, 120), 356 ENTRY(3421, 125), 357 ENTRY(0, 125), 358#undef ENTRY 359}; 360 361/* Table from RK3399 manual */ 362static const rk_data_array rk3399_data_array[] = { 363#define ENTRY(d,C) { .data = (d), .temp = (C) * 1000 * 1000, } 364 ENTRY(0, -40), 365 ENTRY(402, -40), 366 ENTRY(410, -35), 367 ENTRY(419, -30), 368 ENTRY(427, -25), 369 ENTRY(436, -20), 370 ENTRY(444, -15), 371 ENTRY(453, -10), 372 ENTRY(461, -5), 373 ENTRY(470, 0), 374 ENTRY(478, 5), 375 ENTRY(487, 10), 376 ENTRY(496, 15), 377 ENTRY(504, 20), 378 ENTRY(513, 25), 379 ENTRY(521, 30), 380 ENTRY(530, 35), 381 ENTRY(538, 40), 382 ENTRY(547, 45), 383 ENTRY(555, 50), 384 ENTRY(564, 55), 385 ENTRY(573, 60), 386 ENTRY(581, 65), 387 ENTRY(590, 70), 388 ENTRY(599, 75), 389 ENTRY(607, 80), 390 ENTRY(616, 85), 391 ENTRY(624, 90), 392 ENTRY(633, 95), 393 ENTRY(642, 100), 394 ENTRY(650, 105), 395 ENTRY(659, 110), 396 ENTRY(668, 115), 397 ENTRY(677, 120), 398 ENTRY(685, 125), 399 ENTRY(TSADC_DATA_MAX, 125), 400#undef ENTRY 401}; 402 403static const rk_data rk3288_data_table = { 404 .rd_name = "RK3288", 405 .rd_array = rk3288_data_array, 406 .rd_size = __arraycount(rk3288_data_array), 407 .rd_init = rk_tsadc_init_common, 408 .rd_decr = true, 409 .rd_max = 3800, 410 .rd_min = 3421, 411 .rd_auto_period = RK3288_TSADC_AUTO_PERIOD_TIME, 412 .rd_auto_period_ht = RK3288_TSADC_AUTO_PERIOD_HT_TIME, 413 .rd_num_sensors = 2, 414 .rd_version = 2, 415}; 416 417static const rk_data rk3328_data_table = { 418 .rd_name = "RK3328", 419 .rd_array = rk3328_data_array, 420 .rd_size = __arraycount(rk3328_data_array), 421 .rd_init = rk_tsadc_init_common, 422 .rd_decr = false, 423 .rd_max = RK3328_DATA_OFFSET - 3420, 424 .rd_min = RK3328_DATA_OFFSET - 3801, 425 .rd_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME, 426 .rd_auto_period_ht = RK3328_TSADC_AUTO_PERIOD_TIME, 427 .rd_num_sensors = 1, 428 .rd_version = 3, 429}; 430 431static const rk_data rk3399_data_table = { 432 .rd_name = "RK3399", 433 .rd_array = rk3399_data_array, 434 .rd_size = __arraycount(rk3399_data_array), 435 .rd_init = rk_tsadc_init_rk3399, 436 .rd_decr = false, 437 .rd_max = 686, 438 .rd_min = 401, 439 .rd_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME, 440 .rd_auto_period_ht = RK3399_TSADC_AUTO_PERIOD_TIME, 441 .rd_num_sensors = 2, 442 .rd_version = 3, 443}; 444 445static const struct device_compatible_entry compat_data[] = { 446 { .compat = "rockchip,rk3288-tsadc", .data = &rk3288_data_table }, 447 { .compat = "rockchip,rk3328-tsadc", .data = &rk3328_data_table }, 448 { .compat = "rockchip,rk3399-tsadc", .data = &rk3399_data_table }, 449 DEVICE_COMPAT_EOL 450}; 451 452#define TSADC_READ(sc, reg) \ 453 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 454#define TSADC_WRITE(sc, reg, val) \ 455 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 456 457CFATTACH_DECL3_NEW(rk_tsadc, sizeof(struct rk_tsadc_softc), 458 rk_tsadc_match, rk_tsadc_attach, rk_tsadc_detach, NULL, NULL, NULL, 459 DVF_DETACH_SHUTDOWN); 460 461/* init/teardown support */ 462static int 463rk_tsadc_match(device_t parent, cfdata_t cf, void *aux) 464{ 465 struct fdt_attach_args * const faa = aux; 466 467 return of_compatible_match(faa->faa_phandle, compat_data); 468} 469 470static void 471rk_tsadc_attach(device_t parent, device_t self, void *aux) 472{ 473 struct rk_tsadc_softc * const sc = device_private(self); 474 struct fdt_attach_args * const faa = aux; 475 char intrstr[128]; 476 const int phandle = faa->faa_phandle; 477 bus_addr_t addr; 478 int mode, polarity, tshut_temp; 479 480 sc->sc_dev = self; 481 sc->sc_phandle = phandle; 482 sc->sc_bst = faa->faa_bst; 483 484 sc->sc_sme = sysmon_envsys_create(); 485 486 sc->sc_sme->sme_name = device_xname(self); 487 sc->sc_sme->sme_cookie = sc; 488 sc->sc_sme->sme_refresh = rk_tsadc_refresh; 489 sc->sc_sme->sme_get_limits = rk_tsadc_get_limits; 490 sc->sc_data_mask = TSADC_DATA_MAX; 491 492 pmf_device_register(self, NULL, NULL); 493 494 sc->sc_rd = of_compatible_lookup(faa->faa_phandle, compat_data)->data; 495 496 aprint_naive("\n"); 497 aprint_normal(": %s Temperature Sensor ADC\n", sc->sc_rd->rd_name); 498 499 /* Default to tshut via gpio and tshut low is active */ 500 if (of_getprop_uint32(phandle, "rockchip,hw-tshut-mode", 501 &mode) != 0) { 502 aprint_error(": could not get TSHUT mode, default to GPIO"); 503 mode = TSHUT_MODE_GPIO; 504 } 505 if (mode != TSHUT_MODE_CPU && mode != TSHUT_MODE_GPIO) { 506 aprint_error(": TSHUT mode should be 0 or 1\n"); 507 goto fail; 508 } 509 510 if (of_getprop_uint32(phandle, "rockchip,hw-tshut-polarity", 511 &polarity) != 0) { 512 aprint_error(": could not get TSHUT polarity, default to low"); 513 polarity = TSHUT_LOW_ACTIVE; 514 } 515 if (of_getprop_uint32(phandle, 516 "rockchip,hw-tshut-temp", &tshut_temp) != 0) { 517 aprint_error(": could not get TSHUT temperature, default to %u", 518 TSHUT_DEF_TEMP); 519 tshut_temp = TSHUT_DEF_TEMP; 520 } 521 tshut_temp *= 1000; /* convert fdt mK -> uK */ 522 523 memcpy(sc->sc_sensors, rk_tsadc_sensors, sizeof(sc->sc_sensors)); 524 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 525 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 526 527 rks->s_data.flags = ENVSYS_FMONLIMITS; 528 rks->s_data.units = ENVSYS_STEMP; 529 rks->s_data.state = ENVSYS_SINVALID; 530 531 if (sysmon_envsys_sensor_attach(sc->sc_sme, &rks->s_data)) 532 goto fail; 533 rks->s_attached = true; 534 rks->s_tshut = tshut_temp; 535#if 0 536 // testing 537 rks->s_tshut = 68000000; 538 rks->s_warn = 61000000; 539#endif 540 } 541 542 sc->sc_syscon = fdtbus_syscon_acquire(phandle, "rockchip,grf"); 543 if (sc->sc_syscon == NULL) { 544 aprint_error(": couldn't get grf syscon\n"); 545 goto fail; 546 } 547 if (fdtbus_get_reg(phandle, 0, &addr, &sc->sc_size) != 0) { 548 aprint_error(": couldn't get registers\n"); 549 sc->sc_size = 0; 550 goto fail; 551 } 552 if (bus_space_map(sc->sc_bst, addr, sc->sc_size, 0, &sc->sc_bsh) != 0) { 553 aprint_error(": couldn't map registers\n"); 554 sc->sc_size = 0; 555 goto fail; 556 } 557 558 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 559 aprint_error(": failed to decode interrupt\n"); 560 goto fail; 561 } 562 563 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, FDT_INTR_MPSAFE, 564 rk_tsadc_intr, sc, device_xname(self)); 565 if (sc->sc_ih == NULL) { 566 aprint_error_dev(self, "couldn't establish interrupt on %s\n", 567 intrstr); 568 goto fail; 569 } 570 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 571 572 if (rk_tsadc_init_clocks(sc)) { 573 aprint_error(": couldn't enable clocks\n"); 574 return; 575 } 576 577 /* 578 * Manual says to setup auto period (both), high temp (interrupt), 579 * high temp (shutdown), enable high temp resets (TSHUT to GPIO 580 * or reset chip), set the debounce times, and, finally, enable the 581 * controller iself. 582 */ 583 rk_tsadc_init(sc, mode, polarity); 584 585 return; 586 587fail: 588 rk_tsadc_detach(self, 0); 589} 590 591static int 592rk_tsadc_detach(device_t self, int flags) 593{ 594 struct rk_tsadc_softc *sc = device_private(self); 595 596 pmf_device_deregister(self); 597 598 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 599 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 600 601 if (rks->s_attached) { 602 sysmon_envsys_sensor_detach(sc->sc_sme, &rks->s_data); 603 rks->s_attached = false; 604 } 605 } 606 607 sysmon_envsys_unregister(sc->sc_sme); 608 609 if (sc->sc_clockapb) 610 clk_disable(sc->sc_clockapb); 611 if (sc->sc_clock) 612 clk_disable(sc->sc_clock); 613 614 if (sc->sc_ih) 615 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); 616 617 if (sc->sc_size) 618 bus_space_unmap(sc->sc_bst, sc->sc_bsh, sc->sc_size); 619 620 sysmon_envsys_destroy(sc->sc_sme); 621 622 return 0; 623} 624 625static int 626rk_tsadc_init_clocks(struct rk_tsadc_softc *sc) 627{ 628 int error; 629 630 fdtbus_clock_assign(sc->sc_phandle); 631 632 sc->sc_reset = fdtbus_reset_get(sc->sc_phandle, "tsadc-apb"); 633 sc->sc_clock = fdtbus_clock_get(sc->sc_phandle, "tsadc"); 634 sc->sc_clockapb = fdtbus_clock_get(sc->sc_phandle, "apb_pclk"); 635 if (sc->sc_reset == NULL || 636 sc->sc_clock == NULL || 637 sc->sc_clockapb == NULL) 638 return EINVAL; 639 640 fdtbus_reset_assert(sc->sc_reset); 641 642 error = clk_enable(sc->sc_clock); 643 if (error) { 644 fdtbus_reset_deassert(sc->sc_reset); 645 return error; 646 } 647 648 error = clk_enable(sc->sc_clockapb); 649 650 DELAY(20); 651 fdtbus_reset_deassert(sc->sc_reset); 652 653 return error; 654} 655 656static void 657rk_tsadc_init_counts(struct rk_tsadc_softc *sc) 658{ 659 660 TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rd->rd_auto_period); 661 TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rd->rd_auto_period_ht); 662 TSADC_WRITE(sc, TSADC_HIGH_INT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT); 663 TSADC_WRITE(sc, TSADC_HIGH_TSHUT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT); 664} 665 666/* Configure the hardware with the tshut setup. */ 667static void 668rk_tsadc_tshut_set(struct rk_tsadc_softc *sc) 669{ 670 uint32_t val = TSADC_READ(sc, TSADC_AUTO_CON); 671 672 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 673 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 674 uint32_t data, warndata; 675 676 if (!rks->s_attached) 677 continue; 678 679 data = rk_tsadc_temp_to_data(sc, rks->s_tshut); 680 warndata = rk_tsadc_temp_to_data(sc, rks->s_warn); 681 682 DPRINTF("(%s:%s): tshut/data %d/%u warn/data %d/%u", 683 sc->sc_sme->sme_name, rks->s_data.desc, 684 rks->s_tshut, data, 685 rks->s_warn, warndata); 686 687 if (data == sc->sc_data_mask) { 688 aprint_error_dev(sc->sc_dev, 689 "Failed converting critical temp %u.%06u to code", 690 rks->s_tshut / 1000000, rks->s_tshut % 1000000); 691 continue; 692 } 693 if (warndata == sc->sc_data_mask) { 694 aprint_error_dev(sc->sc_dev, 695 "Failed converting warn temp %u.%06u to code", 696 rks->s_warn / 1000000, rks->s_warn % 1000000); 697 continue; 698 } 699 700 TSADC_WRITE(sc, rks->s_comp_tshut, data); 701 TSADC_WRITE(sc, rks->s_comp_int, warndata); 702 703 val |= rks->s_comp_int_en; 704 } 705 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 706} 707 708static void 709rk_tsadc_init_tshut(struct rk_tsadc_softc *sc, int mode, int polarity) 710{ 711 uint32_t val; 712 713 /* Handle TSHUT temp setting. */ 714 rk_tsadc_tshut_set(sc); 715 716 /* Handle TSHUT mode setting. */ 717 val = TSADC_READ(sc, TSADC_INT_EN); 718 if (mode == TSHUT_MODE_CPU) { 719 val |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 | 720 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0; 721 val &= ~(TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 | 722 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0); 723 } else { 724 KASSERT(mode == TSHUT_MODE_GPIO); 725 val &= ~(TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 | 726 TSADC_INT_EN_TSHUT_2CRU_EN_SRC0); 727 val |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 | 728 TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0; 729 } 730 TSADC_WRITE(sc, TSADC_INT_EN, val); 731 732 /* Handle TSHUT polarity setting. */ 733 val = TSADC_READ(sc, TSADC_AUTO_CON); 734 if (polarity == TSHUT_HIGH_ACTIVE) 735 val |= TSADC_AUTO_CON_TSHUT_POLARITY; 736 else 737 val &= ~TSADC_AUTO_CON_TSHUT_POLARITY; 738 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 739} 740 741static void 742rk_tsadc_init_common(struct rk_tsadc_softc *sc, int mode, int polarity) 743{ 744 745 rk_tsadc_init_tshut(sc, mode, polarity); 746 rk_tsadc_init_counts(sc); 747} 748 749static void 750rk_tsadc_init_rk3399(struct rk_tsadc_softc *sc, int mode, int polarity) 751{ 752 753 syscon_lock(sc->sc_syscon); 754 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_L, 755 RK3399_GRF_TSADC_TESTBIT_VCM_EN_L); 756 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H, 757 RK3399_GRF_TSADC_TESTBIT_VCM_EN_H); 758 759 DELAY(20); 760 syscon_write_4(sc->sc_syscon, RK3399_GRF_SARADC_TESTBIT, 761 RK3399_GRF_SARADC_TESTBIT_ON); 762 syscon_write_4(sc->sc_syscon, RK3399_GRF_TSADC_TESTBIT_H, 763 RK3399_GRF_TSADC_TESTBIT_H_ON); 764 DELAY(100); 765 syscon_unlock(sc->sc_syscon); 766 767 rk_tsadc_init_common(sc, mode, polarity); 768} 769 770static void 771rk_tsadc_init_enable(struct rk_tsadc_softc *sc) 772{ 773 uint32_t val; 774 775 val = TSADC_READ(sc, TSADC_AUTO_CON); 776 val |= TSADC_AUTO_CON_AUTO_STATUS | 777 TSADC_AUTO_CON_SRC1_LT_EN | TSADC_AUTO_CON_SRC0_LT_EN; 778 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 779 780 /* Finally, register & enable the controller */ 781 sysmon_envsys_register(sc->sc_sme); 782 783 val = TSADC_READ(sc, TSADC_AUTO_CON); 784 val |= TSADC_AUTO_CON_AUTO_EN; 785 if (sc->sc_rd->rd_version >= 3) { 786 val |= TSADC_AUTO_CON_Q_SEL; 787 } 788 TSADC_WRITE(sc, TSADC_AUTO_CON, val); 789} 790 791static void 792rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity) 793{ 794 795 (*sc->sc_rd->rd_init)(sc, mode, polarity); 796 rk_tsadc_init_enable(sc); 797} 798 799/* run time support */ 800 801/* given edata, find the matching rk sensor structure */ 802static struct rk_tsadc_sensor * 803rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata) 804{ 805 806 for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) { 807 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 808 809 if (&rks->s_data == edata) 810 return rks; 811 } 812 return NULL; 813} 814 815static void 816rk_tsadc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 817{ 818 struct rk_tsadc_softc * const sc = sme->sme_cookie; 819 struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata); 820 unsigned data; 821 int temp; 822 823 if (rks == NULL) 824 return; 825 826 data = TSADC_READ(sc, rks->s_data_reg) & sc->sc_data_mask; 827 temp = rk_tsadc_data_to_temp(sc, data); 828 829 DPRINTF("(%s:%s): temp/data %d/%u", 830 sc->sc_sme->sme_name, rks->s_data.desc, 831 temp, data); 832 833 if (temp == sc->sc_data_mask) { 834 edata->state = ENVSYS_SINVALID; 835 } else { 836 edata->value_cur = temp + TEMP_uC_TO_uK; 837 edata->state = ENVSYS_SVALID; 838 } 839} 840 841static void 842rk_tsadc_get_limits(struct sysmon_envsys *sme, 843 envsys_data_t *edata, 844 sysmon_envsys_lim_t *lim, 845 uint32_t *props) 846{ 847 struct rk_tsadc_softc *sc = sme->sme_cookie; 848 struct rk_tsadc_sensor *rks = rk_tsadc_edata_to_sensor(sc, edata); 849 850 if (rks == NULL) 851 return; 852 853 lim->sel_critmax = rks->s_tshut + TEMP_uC_TO_uK; 854 lim->sel_warnmax = rks->s_warn + TEMP_uC_TO_uK; 855 856 *props = PROP_CRITMAX | PROP_WARNMAX; 857} 858 859/* XXX do something with interrupts that don't happen yet. */ 860static int 861rk_tsadc_intr(void *arg) 862{ 863 struct rk_tsadc_softc * const sc = arg; 864 uint32_t val; 865 866 /* XXX */ 867 DPRINTF("(%s): interrupted", sc->sc_sme->sme_name); 868 for (unsigned n = 0; n < __arraycount(rk_tsadc_sensors); n++) { 869 struct rk_tsadc_sensor *rks = &sc->sc_sensors[n]; 870 871 rk_tsadc_refresh(sc->sc_sme, (envsys_data_t *)rks); 872 } 873 874 /* ack interrupt */ 875 val = TSADC_READ(sc, TSADC_INT_PD); 876 if (sc->sc_rd->rd_version >= 3) { 877 TSADC_WRITE(sc, TSADC_INT_PD, 878 val & ~TSADC_INT_PD_EOC_INT_PD_V3); 879 } else { 880 TSADC_WRITE(sc, TSADC_INT_PD, 881 val & ~TSADC_INT_PD_EOC_INT_PD_V2); 882 } 883 884 return 1; 885} 886 887/* 888 * Convert TDASC data codes to temp and reverse. The manual only has codes 889 * and temperature values in 5 degC intervals, but says that interpolation 890 * can be done to achieve better resolution between these values, and that 891 * the spacing is linear. 892 */ 893static int 894rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data) 895{ 896 unsigned i; 897 const rk_data *rd = sc->sc_rd; 898 899 if (data > rd->rd_max || data < rd->rd_min) { 900 DPRINTF("data out of range (%u > %u || %u < %u)", 901 data, rd->rd_max, data, rd->rd_min); 902 return sc->sc_data_mask; 903 } 904 for (i = 1; i < rd->rd_size; i++) { 905 if (rd->rd_array[i].data >= data) { 906 int temprange, offset; 907 uint32_t datarange, datadiff; 908 unsigned first, secnd; 909 910 if (rd->rd_array[i].data == data) 911 return rd->rd_array[i].temp; 912 913 /* must interpolate */ 914 if (rd->rd_decr) { 915 first = i; 916 secnd = i+1; 917 } else { 918 first = i; 919 secnd = i-1; 920 } 921 922 temprange = rd->rd_array[first].temp - 923 rd->rd_array[secnd].temp; 924 datarange = rd->rd_array[first].data - 925 rd->rd_array[secnd].data; 926 datadiff = data - rd->rd_array[secnd].data; 927 928 offset = (temprange * datadiff) / datarange; 929 return rd->rd_array[secnd].temp + offset; 930 } 931 } 932 panic("didn't find range"); 933} 934 935static uint32_t 936rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp) 937{ 938 unsigned i; 939 const rk_data *rd = sc->sc_rd; 940 941 for (i = 1; i < rd->rd_size; i++) { 942 if (rd->rd_array[i].temp >= temp) { 943 int temprange, tempdiff; 944 uint32_t datarange, offset; 945 unsigned first, secnd; 946 947 if (rd->rd_array[i].temp == temp) 948 return rd->rd_array[i].data; 949 950 /* must interpolate */ 951 if (rd->rd_decr) { 952 first = i; 953 secnd = i+1; 954 } else { 955 first = i; 956 secnd = i-1; 957 } 958 959 datarange = rd->rd_array[first].data - 960 rd->rd_array[secnd].data; 961 temprange = rd->rd_array[first].temp - 962 rd->rd_array[secnd].temp; 963 tempdiff = temp - rd->rd_array[secnd].temp; 964 965 offset = (datarange * tempdiff) / temprange; 966 return rd->rd_array[secnd].data + offset; 967 } 968 } 969 970 return sc->sc_data_mask; 971} 972