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
162 typedef struct rk_data_array {
163 uint32_t data; /* register value */
164 int temp; /* micro-degC */
165 } rk_data_array;
166
167 struct rk_tsadc_softc;
168 typedef 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 */
182 struct 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
196 struct 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
216 static int rk_tsadc_match(device_t, cfdata_t, void *);
217 static void rk_tsadc_attach(device_t, device_t, void *);
218 static int rk_tsadc_detach(device_t, int);
219 static int rk_tsadc_init_clocks(struct rk_tsadc_softc *);
220 static void rk_tsadc_init_counts(struct rk_tsadc_softc *);
221 static void rk_tsadc_tshut_set(struct rk_tsadc_softc *s);
222 static void rk_tsadc_init_tshut(struct rk_tsadc_softc *, int, int);
223 static void rk_tsadc_init_common(struct rk_tsadc_softc *, int, int);
224 static void rk_tsadc_init_rk3399(struct rk_tsadc_softc *, int, int);
225 static void rk_tsadc_init_enable(struct rk_tsadc_softc *);
226 static void rk_tsadc_init(struct rk_tsadc_softc *, int, int);
227 static void rk_tsadc_refresh(struct sysmon_envsys *, envsys_data_t *);
228 static void rk_tsadc_get_limits(struct sysmon_envsys *, envsys_data_t *,
229 sysmon_envsys_lim_t *, uint32_t *);
230
231 static int rk_tsadc_intr(void *);
232 static int rk_tsadc_data_to_temp(struct rk_tsadc_softc *, uint32_t);
233 static uint32_t rk_tsadc_temp_to_data(struct rk_tsadc_softc *, int);
234
235 /* RK3328/RK3399 compatible sensors */
236 static 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 */
272 static 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)
319 static 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 */
362 static 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
403 static 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
417 static 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
431 static 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
445 static 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
457 CFATTACH_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 */
462 static int
rk_tsadc_match(device_t parent,cfdata_t cf,void * aux)463 rk_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
470 static void
rk_tsadc_attach(device_t parent,device_t self,void * aux)471 rk_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
587 fail:
588 rk_tsadc_detach(self, 0);
589 }
590
591 static int
rk_tsadc_detach(device_t self,int flags)592 rk_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
625 static int
rk_tsadc_init_clocks(struct rk_tsadc_softc * sc)626 rk_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
656 static void
rk_tsadc_init_counts(struct rk_tsadc_softc * sc)657 rk_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. */
667 static void
rk_tsadc_tshut_set(struct rk_tsadc_softc * sc)668 rk_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
708 static void
rk_tsadc_init_tshut(struct rk_tsadc_softc * sc,int mode,int polarity)709 rk_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
741 static void
rk_tsadc_init_common(struct rk_tsadc_softc * sc,int mode,int polarity)742 rk_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
749 static void
rk_tsadc_init_rk3399(struct rk_tsadc_softc * sc,int mode,int polarity)750 rk_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
770 static void
rk_tsadc_init_enable(struct rk_tsadc_softc * sc)771 rk_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
791 static void
rk_tsadc_init(struct rk_tsadc_softc * sc,int mode,int polarity)792 rk_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 */
802 static struct rk_tsadc_sensor *
rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc,envsys_data_t * edata)803 rk_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
815 static void
rk_tsadc_refresh(struct sysmon_envsys * sme,envsys_data_t * edata)816 rk_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
841 static void
rk_tsadc_get_limits(struct sysmon_envsys * sme,envsys_data_t * edata,sysmon_envsys_lim_t * lim,uint32_t * props)842 rk_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. */
860 static int
rk_tsadc_intr(void * arg)861 rk_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 */
893 static int
rk_tsadc_data_to_temp(struct rk_tsadc_softc * sc,uint32_t data)894 rk_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
935 static uint32_t
rk_tsadc_temp_to_data(struct rk_tsadc_softc * sc,int temp)936 rk_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