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