xref: /openbsd/sys/dev/fdt/rktemp.c (revision 74b3eef0)
1 /*	$OpenBSD: rktemp.c,v 1.14 2024/06/27 09:40:15 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/ofw_thermal.h>
32 #include <dev/ofw/fdt.h>
33 
34 /* Registers */
35 #define TSADC_USER_CON			0x0000
36 #define  TSADC_USER_CON_INTER_PD_SOC_SHIFT	6
37 #define TSADC_AUTO_CON			0x0004
38 #define  TSADC_AUTO_CON_TSHUT_POLARITY	(1 << 8)
39 #define  TSADC_AUTO_CON_SRC_EN(ch)	(1 << ((ch) + 4))
40 #define  TSADC_AUTO_CON_TSADC_Q_SEL	(1 << 1)
41 #define  TSADC_AUTO_CON_AUTO_EN		(1 << 0)
42 #define TSADC_INT_EN			0x0008
43 #define  TSADC_INT_EN_TSHUT_2CRU_EN_SRC(ch)	(1 << ((ch) + 8))
44 #define  TSADC_INT_EN_TSHUT_2GPIO_EN_SRC(ch)	(1 << ((ch) + 4))
45 #define TSADC_INT_PD			0x000c
46 #define  TSADC_INT_PD_TSHUT_O_SRC(ch)		(1 << ((ch) + 4))
47 #define TSADC_DATA(ch)			(0x0020 + (ch) * 4)
48 #define TSADC_COMP_INT(ch)		(0x0030 + (ch) * 4)
49 #define TSADC_COMP_SHUT(ch)		(0x0040 + (ch) * 4)
50 #define TSADC_HIGHT_INT_DEBOUNCE	0x0060
51 #define TSADC_HIGHT_TSHUT_DEBOUNCE	0x0064
52 #define TSADC_AUTO_PERIOD		0x0068
53 #define TSADC_AUTO_PERIOD_HT		0x006c
54 
55 /* RK3588 */
56 #define TSADC_V3_AUTO_SRC		0x000c
57 #define  TSADC_V3_AUTO_SRC_CH(ch)	(1 << (ch))
58 #define TSADC_V3_HT_INT_EN		0x0014
59 #define  TSADC_V3_HT_INT_EN_CH(ch)	(1 << (ch))
60 #define TSADC_V3_GPIO_EN		0x0018
61 #define  TSADC_V3_GPIO_EN_CH(ch)	(1 << (ch))
62 #define TSADC_V3_CRU_EN			0x001c
63 #define  TSADC_V3_CRU_EN_CH(ch)		(1 << (ch))
64 #define TSADC_V3_HLT_INT_PD		0x0024
65 #define  TSADC_V3_HT_INT_STATUS(ch)	(1 << (ch))
66 #define TSADC_V3_DATA(ch)		(0x002c + (ch) * 4)
67 #define TSADC_V3_COMP_INT(ch)		(0x006c + (ch) * 4)
68 #define TSADC_V3_COMP_SHUT(ch)		(0x010c + (ch) * 4)
69 #define TSADC_V3_HIGHT_INT_DEBOUNCE	0x014c
70 #define TSADC_V3_HIGHT_TSHUT_DEBOUNCE	0x0150
71 #define TSADC_V3_AUTO_PERIOD		0x0154
72 #define TSADC_V3_AUTO_PERIOD_HT		0x0158
73 
74 /* RK3568 */
75 #define RK3568_GRF_TSADC_CON		0x0600
76 #define  RK3568_GRF_TSADC_EN		(1 << 8)
77 #define  RK3568_GRF_TSADC_ANA_REG(idx)	(1 << (idx))
78 
79 #define HREAD4(sc, reg)							\
80 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
81 #define HWRITE4(sc, reg, val)						\
82 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
83 
84 struct rktemp_entry {
85 	int32_t temp;
86 	int32_t code;
87 };
88 
89 /* RK3288 conversion table. */
90 const struct rktemp_entry rk3288_temps[] = {
91 	{ -40000, 3800 },
92 	{ -35000, 3792 },
93 	{ -30000, 3783 },
94 	{ -25000, 3774 },
95 	{ -20000, 3765 },
96 	{ -15000, 3756 },
97 	{ -10000, 3747 },
98 	{  -5000, 3737 },
99 	{      0, 3728 },
100 	{   5000, 3718 },
101 	{  10000, 3708 },
102 	{  15000, 3698 },
103 	{  20000, 3688 },
104 	{  25000, 3678 },
105 	{  30000, 3667 },
106 	{  35000, 3656 },
107 	{  40000, 3645 },
108 	{  45000, 3634 },
109 	{  50000, 3623 },
110 	{  55000, 3611 },
111 	{  60000, 3600 },
112 	{  65000, 3588 },
113 	{  70000, 3575 },
114 	{  75000, 3563 },
115 	{  80000, 3550 },
116 	{  85000, 3537 },
117 	{  90000, 3524 },
118 	{  95000, 3510 },
119 	{ 100000, 3496 },
120 	{ 105000, 3482 },
121 	{ 110000, 3467 },
122 	{ 115000, 3452 },
123 	{ 120000, 3437 },
124 	{ 125000, 3421 },
125 };
126 
127 const char *const rk3288_names[] = { "", "CPU", "GPU" };
128 
129 /* RK3328 conversion table. */
130 const struct rktemp_entry rk3328_temps[] = {
131 	{ -40000, 296 },
132 	{ -35000, 304 },
133 	{ -30000, 313 },
134 	{ -20000, 331 },
135 	{ -15000, 340 },
136 	{ -10000, 349 },
137 	{  -5000, 359 },
138 	{      0, 368 },
139 	{   5000, 378 },
140 	{  10000, 388 },
141 	{  15000, 398 },
142 	{  20000, 408 },
143 	{  25000, 418 },
144 	{  30000, 429 },
145 	{  35000, 440 },
146 	{  40000, 451 },
147 	{  45000, 462 },
148 	{  50000, 473 },
149 	{  55000, 485 },
150 	{  60000, 496 },
151 	{  65000, 508 },
152 	{  70000, 521 },
153 	{  75000, 533 },
154 	{  80000, 546 },
155 	{  85000, 559 },
156 	{  90000, 572 },
157 	{  95000, 586 },
158 	{ 100000, 600 },
159 	{ 105000, 614 },
160 	{ 110000, 629 },
161 	{ 115000, 644 },
162 	{ 120000, 659 },
163 	{ 125000, 675 },
164 };
165 
166 const char *const rk3308_names[] = { "CPU", "GPU" };
167 const char *const rk3328_names[] = { "CPU" };
168 
169 /* RK3399 conversion table. */
170 const struct rktemp_entry rk3399_temps[] = {
171 	{ -40000, 402 },
172 	{ -35000, 410 },
173 	{ -30000, 419 },
174 	{ -25000, 427 },
175 	{ -20000, 436 },
176 	{ -15000, 444 },
177 	{ -10000, 453 },
178 	{  -5000, 461 },
179 	{      0, 470 },
180 	{   5000, 478 },
181 	{  10000, 487 },
182 	{  15000, 496 },
183 	{  20000, 504 },
184 	{  25000, 513 },
185 	{  30000, 521 },
186 	{  35000, 530 },
187 	{  40000, 538 },
188 	{  45000, 547 },
189 	{  50000, 555 },
190 	{  55000, 564 },
191 	{  60000, 573 },
192 	{  65000, 581 },
193 	{  70000, 590 },
194 	{  75000, 599 },
195 	{  80000, 607 },
196 	{  85000, 616 },
197 	{  90000, 624 },
198 	{  95000, 633 },
199 	{ 100000, 642 },
200 	{ 105000, 650 },
201 	{ 110000, 659 },
202 	{ 115000, 668 },
203 	{ 120000, 677 },
204 	{ 125000, 685 },
205 };
206 
207 const char *const rk3399_names[] = { "CPU", "GPU" };
208 
209 /* RK3568 conversion table. */
210 const struct rktemp_entry rk3568_temps[] = {
211 	{ -40000, 1584 },
212 	{ -35000, 1620 },
213 	{ -30000, 1652 },
214 	{ -25000, 1688 },
215 	{ -20000, 1720 },
216 	{ -15000, 1756 },
217 	{ -10000, 1788 },
218 	{  -5000, 1824 },
219 	{      0, 1856 },
220 	{   5000, 1892 },
221 	{  10000, 1924 },
222 	{  15000, 1956 },
223 	{  20000, 1992 },
224 	{  25000, 2024 },
225 	{  30000, 2060 },
226 	{  35000, 2092 },
227 	{  40000, 2128 },
228 	{  45000, 2160 },
229 	{  50000, 2196 },
230 	{  55000, 2228 },
231 	{  60000, 2264 },
232 	{  65000, 2300 },
233 	{  70000, 2332 },
234 	{  75000, 2368 },
235 	{  80000, 2400 },
236 	{  85000, 2436 },
237 	{  90000, 2468 },
238 	{  95000, 2500 },
239 	{ 100000, 2536 },
240 	{ 105000, 2572 },
241 	{ 110000, 2604 },
242 	{ 115000, 2636 },
243 	{ 120000, 2672 },
244 	{ 125000, 2704 },
245 };
246 
247 const char *const rk3568_names[] = { "CPU", "GPU" };
248 
249 /* RK3588 conversion table. */
250 const struct rktemp_entry rk3588_temps[] = {
251 	{ -40000, 215 },
252 	{  25000, 285 },
253 	{  85000, 350 },
254 	{ 125000, 395 },
255 };
256 
257 const char *const rk3588_names[] = {
258 	"Top",
259 	"CPU (big0)",
260 	"CPU (big1)",
261 	"CPU (little)",
262 	"Center",
263 	"GPU",
264 	"NPU"
265 };
266 
267 struct rktemp_softc {
268 	struct device		sc_dev;
269 	bus_space_tag_t		sc_iot;
270 	bus_space_handle_t	sc_ioh;
271 	int			sc_node;
272 	void			*sc_ih;
273 
274 	bus_size_t		sc_data0;
275 
276 	const struct rktemp_entry *sc_temps;
277 	int			sc_ntemps;
278 
279 	struct ksensor		sc_sensors[7];
280 	int			sc_nsensors;
281 	struct ksensordev	sc_sensordev;
282 
283 	struct thermal_sensor	sc_ts;
284 };
285 
286 int	rktemp_match(struct device *, void *, void *);
287 void	rktemp_attach(struct device *, struct device *, void *);
288 
289 const struct cfattach rktemp_ca = {
290 	sizeof (struct rktemp_softc), rktemp_match, rktemp_attach
291 };
292 
293 struct cfdriver rktemp_cd = {
294 	NULL, "rktemp", DV_DULL
295 };
296 
297 int	rktemp_intr(void *);
298 void	rktemp_rk3568_init(struct rktemp_softc *);
299 int32_t rktemp_calc_code(struct rktemp_softc *, int32_t);
300 int32_t rktemp_calc_temp(struct rktemp_softc *, int32_t);
301 int	rktemp_valid(struct rktemp_softc *, int32_t);
302 void	rktemp_refresh_sensors(void *);
303 int32_t	rktemp_get_temperature(void *, uint32_t *);
304 int	rktemp_set_limit(void *, uint32_t *, uint32_t);
305 
306 int
rktemp_match(struct device * parent,void * match,void * aux)307 rktemp_match(struct device *parent, void *match, void *aux)
308 {
309 	struct fdt_attach_args *faa = aux;
310 
311 	return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-tsadc") ||
312 	    OF_is_compatible(faa->fa_node, "rockchip,rk3308-tsadc") ||
313 	    OF_is_compatible(faa->fa_node, "rockchip,rk3328-tsadc") ||
314 	    OF_is_compatible(faa->fa_node, "rockchip,rk3399-tsadc") ||
315 	    OF_is_compatible(faa->fa_node, "rockchip,rk3568-tsadc") ||
316 	    OF_is_compatible(faa->fa_node, "rockchip,rk3588-tsadc"));
317 }
318 
319 void
rktemp_attach(struct device * parent,struct device * self,void * aux)320 rktemp_attach(struct device *parent, struct device *self, void *aux)
321 {
322 	struct rktemp_softc *sc = (struct rktemp_softc *)self;
323 	struct fdt_attach_args *faa = aux;
324 	const char *const *names;
325 	uint32_t mode, polarity, temp;
326 	uint32_t auto_con, inter_pd_soc;
327 	int auto_period, auto_period_ht;
328 	int i;
329 
330 	if (faa->fa_nreg < 1) {
331 		printf(": no registers\n");
332 		return;
333 	}
334 
335 	sc->sc_iot = faa->fa_iot;
336 	sc->sc_node = faa->fa_node;
337 
338 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
339 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
340 		printf(": can't map registers\n");
341 		return;
342 	}
343 
344 	if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc")) {
345 		sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_SOFTCLOCK,
346 		    rktemp_intr, sc, sc->sc_dev.dv_xname);
347 		if (sc->sc_ih == NULL) {
348 			printf(": can't establish interrupt\n");
349 			return;
350 		}
351 	}
352 
353 	printf("\n");
354 
355 	if (OF_is_compatible(sc->sc_node, "rockchip,rk3288-tsadc")) {
356 		sc->sc_temps = rk3288_temps;
357 		sc->sc_ntemps = nitems(rk3288_temps);
358 		sc->sc_nsensors = 3;
359 		names = rk3288_names;
360 		inter_pd_soc = 13;
361 		auto_period = 250;	/* 250 ms */
362 		auto_period_ht = 50;	/* 50 ms */
363 	} else if (OF_is_compatible(sc->sc_node, "rockchip,rk3308-tsadc")) {
364 		sc->sc_temps = rk3328_temps;
365 		sc->sc_ntemps = nitems(rk3328_temps);
366 		sc->sc_nsensors = 2;
367 		names = rk3308_names;
368 		inter_pd_soc = 13;
369 		auto_period = 1875;	/* 2.5 ms */
370 		auto_period_ht = 1875;	/* 2.5 ms */
371 	} else if (OF_is_compatible(sc->sc_node, "rockchip,rk3328-tsadc")) {
372 		sc->sc_temps = rk3328_temps;
373 		sc->sc_ntemps = nitems(rk3328_temps);
374 		sc->sc_nsensors = 1;
375 		names = rk3328_names;
376 		inter_pd_soc = 13;
377 		auto_period = 1875;	/* 2.5 ms */
378 		auto_period_ht = 1875;	/* 2.5 ms */
379 	} else if (OF_is_compatible(sc->sc_node, "rockchip,rk3399-tsadc")) {
380 		sc->sc_temps = rk3399_temps;
381 		sc->sc_ntemps = nitems(rk3399_temps);
382 		sc->sc_nsensors = 2;
383 		names = rk3399_names;
384 		inter_pd_soc = 13;
385 		auto_period = 1875;	/* 2.5 ms */
386 		auto_period_ht = 1875;	/* 2.5 ms */
387 	} else if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc")) {
388 		sc->sc_temps = rk3568_temps;
389 		sc->sc_ntemps = nitems(rk3568_temps);
390 		sc->sc_nsensors = 2;
391 		names = rk3568_names;
392 		inter_pd_soc = 63;	/* 97 us */
393 		auto_period = 1622;	/* 2.5 ms */
394 		auto_period_ht = 1622;	/* 2.5 ms */
395 	} else {
396 		sc->sc_temps = rk3588_temps;
397 		sc->sc_ntemps = nitems(rk3588_temps);
398 		sc->sc_nsensors = 7;
399 		names = rk3588_names;
400 		inter_pd_soc = 0;
401 		auto_period = 5000;	/* 2.5 ms */
402 		auto_period_ht = 5000;	/* 2.5 ms */
403 	}
404 
405 	pinctrl_byname(sc->sc_node, "init");
406 
407 	clock_set_assigned(sc->sc_node);
408 	clock_enable(sc->sc_node, "tsadc");
409 	clock_enable(sc->sc_node, "apb_pclk");
410 
411 	/* Reset the TS-ADC controller block. */
412 	reset_assert_all(sc->sc_node);
413 	delay(10);
414 	reset_deassert_all(sc->sc_node);
415 
416 	mode = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-mode", 1);
417 	polarity = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-polarity", 0);
418 	temp = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-temp", 95000);
419 
420 	if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc")) {
421 		uint32_t gpio_en, cru_en;
422 
423 		sc->sc_data0 = TSADC_V3_DATA(0);
424 
425 		HWRITE4(sc, TSADC_V3_AUTO_PERIOD, auto_period);
426 		HWRITE4(sc, TSADC_V3_AUTO_PERIOD_HT, auto_period_ht);
427 		HWRITE4(sc, TSADC_V3_HIGHT_INT_DEBOUNCE, 4);
428 		HWRITE4(sc, TSADC_V3_HIGHT_TSHUT_DEBOUNCE, 4);
429 
430 		auto_con = TSADC_AUTO_CON_TSHUT_POLARITY << 16;
431 		if (polarity)
432 			auto_con = TSADC_AUTO_CON_TSHUT_POLARITY;
433 		HWRITE4(sc, TSADC_AUTO_CON, auto_con);
434 
435 		/* Set shutdown limit. */
436 		for (i = 0; i < sc->sc_nsensors; i++) {
437 			HWRITE4(sc, TSADC_V3_COMP_SHUT(i),
438 			    rktemp_calc_code(sc, temp));
439 			HWRITE4(sc, TSADC_V3_AUTO_SRC,
440 			    TSADC_V3_AUTO_SRC_CH(i) << 16 |
441 			    TSADC_V3_AUTO_SRC_CH(i));
442 		}
443 
444 		/* Clear shutdown output status. */
445 		for (i = 0; i < sc->sc_nsensors; i++) {
446 			HWRITE4(sc, TSADC_V3_HLT_INT_PD,
447 			    TSADC_V3_HT_INT_STATUS(i));
448 		}
449 
450 		/* Configure mode. */
451 		gpio_en = cru_en = 0;
452 		for (i = 0; i < sc->sc_nsensors; i++) {
453 			gpio_en |= TSADC_V3_GPIO_EN_CH(i) << 16;
454 			cru_en |= TSADC_V3_CRU_EN_CH(i) << 16;
455 			if (mode)
456 				gpio_en |= TSADC_V3_GPIO_EN_CH(i);
457 			else
458 				cru_en |= TSADC_V3_CRU_EN_CH(i);
459 		}
460 		HWRITE4(sc, TSADC_V3_GPIO_EN, gpio_en);
461 		HWRITE4(sc, TSADC_V3_CRU_EN, cru_en);
462 	} else {
463 		uint32_t int_en;
464 
465 		sc->sc_data0 = TSADC_DATA(0);
466 
467 		HWRITE4(sc, TSADC_USER_CON,
468 		    inter_pd_soc << TSADC_USER_CON_INTER_PD_SOC_SHIFT);
469 		HWRITE4(sc, TSADC_AUTO_PERIOD, auto_period);
470 		HWRITE4(sc, TSADC_AUTO_PERIOD_HT, auto_period_ht);
471 		HWRITE4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
472 		HWRITE4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
473 
474 		if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc"))
475 			rktemp_rk3568_init(sc);
476 
477 		auto_con = HREAD4(sc, TSADC_AUTO_CON);
478 		auto_con |= TSADC_AUTO_CON_TSADC_Q_SEL;
479 		if (polarity)
480 			auto_con |= TSADC_AUTO_CON_TSHUT_POLARITY;
481 		HWRITE4(sc, TSADC_AUTO_CON, auto_con);
482 
483 		/* Set shutdown limit. */
484 		for (i = 0; i < sc->sc_nsensors; i++) {
485 			HWRITE4(sc, TSADC_COMP_SHUT(i),
486 			    rktemp_calc_code(sc, temp));
487 			auto_con |= (TSADC_AUTO_CON_SRC_EN(i));
488 		}
489 		HWRITE4(sc, TSADC_AUTO_CON, auto_con);
490 
491 		/* Clear shutdown output status. */
492 		for (i = 0; i < sc->sc_nsensors; i++)
493 			HWRITE4(sc, TSADC_INT_PD, TSADC_INT_PD_TSHUT_O_SRC(i));
494 
495 		/* Configure mode. */
496 		int_en = HREAD4(sc, TSADC_INT_EN);
497 		for (i = 0; i < sc->sc_nsensors; i++) {
498 			if (mode)
499 				int_en |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC(i);
500 			else
501 				int_en |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC(i);
502 		}
503 		HWRITE4(sc, TSADC_INT_EN, int_en);
504 	}
505 
506 	pinctrl_byname(sc->sc_node, "default");
507 
508 	/* Finally turn on the ADC. */
509 	if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc")) {
510 		HWRITE4(sc, TSADC_AUTO_CON,
511 		    TSADC_AUTO_CON_AUTO_EN << 16 | TSADC_AUTO_CON_AUTO_EN);
512 	} else {
513 		auto_con |= TSADC_AUTO_CON_AUTO_EN;
514 		HWRITE4(sc, TSADC_AUTO_CON, auto_con);
515 	}
516 
517 	/* Register sensors. */
518 	strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
519 	    sizeof(sc->sc_sensordev.xname));
520 	for (i = 0; i < sc->sc_nsensors; i++) {
521 		strlcpy(sc->sc_sensors[i].desc, names[i],
522 		    sizeof(sc->sc_sensors[i].desc));
523 		sc->sc_sensors[i].type = SENSOR_TEMP;
524 		sc->sc_sensors[i].flags = SENSOR_FINVALID;
525 		sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
526 	}
527 	sensordev_install(&sc->sc_sensordev);
528 	sensor_task_register(sc, rktemp_refresh_sensors, 5);
529 
530 	sc->sc_ts.ts_node = sc->sc_node;
531 	sc->sc_ts.ts_cookie = sc;
532 	sc->sc_ts.ts_get_temperature = rktemp_get_temperature;
533 	if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc"))
534 		sc->sc_ts.ts_set_limit = rktemp_set_limit;
535 	thermal_sensor_register(&sc->sc_ts);
536 }
537 
538 int
rktemp_intr(void * arg)539 rktemp_intr(void *arg)
540 {
541 	struct rktemp_softc *sc = arg;
542 	uint32_t stat, ch;
543 
544 	stat = HREAD4(sc, TSADC_V3_HLT_INT_PD);
545 	stat &= HREAD4(sc, TSADC_V3_HT_INT_EN);
546 	for (ch = 0; ch < sc->sc_nsensors; ch++) {
547 		if (stat & TSADC_V3_HT_INT_STATUS(ch))
548 			thermal_sensor_update(&sc->sc_ts, &ch);
549 	}
550 
551 	/*
552 	 * Disable and clear the active interrupts.  The thermal zone
553 	 * code will set a new limit when necessary.
554 	 */
555 	HWRITE4(sc, TSADC_V3_HT_INT_EN, stat << 16);
556 	HWRITE4(sc, TSADC_V3_HLT_INT_PD, stat);
557 
558 	return 1;
559 }
560 
561 void
rktemp_rk3568_init(struct rktemp_softc * sc)562 rktemp_rk3568_init(struct rktemp_softc *sc)
563 {
564 	struct regmap *rm;
565 	uint32_t grf;
566 	int i;
567 
568 	grf = OF_getpropint(sc->sc_node, "rockchip,grf", 0);
569 	rm = regmap_byphandle(grf);
570 	if (rm == 0)
571 		return;
572 
573 	regmap_write_4(rm, RK3568_GRF_TSADC_CON,
574 	    RK3568_GRF_TSADC_EN << 16 | RK3568_GRF_TSADC_EN);
575 	delay(15);
576 	for (i = 0; i <= 2; i++) {
577 		regmap_write_4(rm, RK3568_GRF_TSADC_CON,
578 		    RK3568_GRF_TSADC_ANA_REG(i) << 16 |
579 		    RK3568_GRF_TSADC_ANA_REG(i));
580 	}
581 	delay(100);
582 }
583 
584 int32_t
rktemp_calc_code(struct rktemp_softc * sc,int32_t temp)585 rktemp_calc_code(struct rktemp_softc *sc, int32_t temp)
586 {
587 	const int n = sc->sc_ntemps;
588 	int32_t code0, delta_code;
589 	int32_t temp0, delta_temp;
590 	int i;
591 
592 	if (temp <= sc->sc_temps[0].temp)
593 		return sc->sc_temps[0].code;
594 	if (temp >= sc->sc_temps[n - 1].temp)
595 		return sc->sc_temps[n - 1].code;
596 
597 	for (i = 1; i < n; i++) {
598 		if (temp < sc->sc_temps[i].temp)
599 			break;
600 	}
601 
602 	code0 = sc->sc_temps[i - 1].code;
603 	temp0 = sc->sc_temps[i - 1].temp;
604 	delta_code = sc->sc_temps[i].code - code0;
605 	delta_temp = sc->sc_temps[i].temp - temp0;
606 
607 	return code0 + (temp - temp0) * delta_code / delta_temp;
608 }
609 
610 int32_t
rktemp_calc_temp(struct rktemp_softc * sc,int32_t code)611 rktemp_calc_temp(struct rktemp_softc *sc, int32_t code)
612 {
613 	const int n = sc->sc_ntemps;
614 	int32_t code0, delta_code;
615 	int32_t temp0, delta_temp;
616 	int i;
617 
618 	/* Handle both negative and positive temperature coefficients. */
619 	if (sc->sc_temps[0].code > sc->sc_temps[1].code) {
620 		if (code >= sc->sc_temps[0].code)
621 			return sc->sc_temps[0].code;
622 		if (code <= sc->sc_temps[n - 1].code)
623 			return sc->sc_temps[n - 1].temp;
624 
625 		for (i = 1; i < n; i++) {
626 			if (code > sc->sc_temps[i].code)
627 				break;
628 		}
629 	} else {
630 		if (code <= sc->sc_temps[0].code)
631 			return sc->sc_temps[0].temp;
632 		if (code >= sc->sc_temps[n - 1].code)
633 			return sc->sc_temps[n - 1].temp;
634 
635 		for (i = 1; i < n; i++) {
636 			if (code < sc->sc_temps[i].code)
637 				break;
638 		}
639 	}
640 
641 	code0 = sc->sc_temps[i - 1].code;
642 	temp0 = sc->sc_temps[i - 1].temp;
643 	delta_code = sc->sc_temps[i].code - code0;
644 	delta_temp = sc->sc_temps[i].temp - temp0;
645 
646 	return temp0 + (code - code0) * delta_temp / delta_code;
647 }
648 
649 int
rktemp_valid(struct rktemp_softc * sc,int32_t code)650 rktemp_valid(struct rktemp_softc *sc, int32_t code)
651 {
652 	const int n = sc->sc_ntemps;
653 
654 	if (sc->sc_temps[0].code > sc->sc_temps[1].code) {
655 		if (code > sc->sc_temps[0].code)
656 			return 0;
657 		if (code < sc->sc_temps[n - 1].code)
658 			return 0;
659 	} else {
660 		if (code < sc->sc_temps[0].code)
661 			return 0;
662 		if (code > sc->sc_temps[n - 1].code)
663 			return 0;
664 	}
665 	return 1;
666 }
667 
668 void
rktemp_refresh_sensors(void * arg)669 rktemp_refresh_sensors(void *arg)
670 {
671 	struct rktemp_softc *sc = arg;
672 	int32_t code, temp;
673 	int i;
674 
675 	for (i = 0; i < sc->sc_nsensors; i++) {
676 		code = HREAD4(sc, sc->sc_data0 + (i * 4));
677 		temp = rktemp_calc_temp(sc, code);
678 		sc->sc_sensors[i].value = 273150000 + 1000 * temp;
679 		if (rktemp_valid(sc, code))
680 			sc->sc_sensors[i].flags &= ~SENSOR_FINVALID;
681 		else
682 			sc->sc_sensors[i].flags |= SENSOR_FINVALID;
683 	}
684 }
685 
686 int32_t
rktemp_get_temperature(void * cookie,uint32_t * cells)687 rktemp_get_temperature(void *cookie, uint32_t *cells)
688 {
689 	struct rktemp_softc *sc = cookie;
690 	uint32_t ch = cells[0];
691 	int32_t code;
692 
693 	if (ch >= sc->sc_nsensors)
694 		return THERMAL_SENSOR_MAX;
695 
696 	code = HREAD4(sc, sc->sc_data0 + (ch * 4));
697 	if (rktemp_valid(sc, code))
698 		return rktemp_calc_temp(sc, code);
699 	else
700 		return THERMAL_SENSOR_MAX;
701 }
702 
703 int
rktemp_set_limit(void * cookie,uint32_t * cells,uint32_t temp)704 rktemp_set_limit(void *cookie, uint32_t *cells, uint32_t temp)
705 {
706 	struct rktemp_softc *sc = cookie;
707 	uint32_t ch = cells[0];
708 
709 	if (ch >= sc->sc_nsensors)
710 		return ENXIO;
711 
712 	/* Set limit for this sensor. */
713 	HWRITE4(sc, TSADC_V3_COMP_INT(ch), rktemp_calc_code(sc, temp));
714 
715 	/* Clear and enable the corresponding interrupt. */
716 	HWRITE4(sc, TSADC_V3_HLT_INT_PD, TSADC_V3_HT_INT_STATUS(ch));
717 	HWRITE4(sc, TSADC_V3_HT_INT_EN, TSADC_V3_HT_INT_EN_CH(ch) << 16 |
718 	    TSADC_V3_HT_INT_EN_CH(ch));
719 
720 	return 0;
721 }
722