xref: /netbsd/sys/arch/arm/rockchip/rk_tsadc.c (revision 43365e7e)
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