1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  R-Car Gen3 THS thermal sensor driver
4  *  Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen.
5  *
6  * Copyright (C) 2016 Renesas Electronics Corporation.
7  * Copyright (C) 2016 Sang Engineering
8  */
9 #include <linux/delay.h>
10 #include <linux/err.h>
11 #include <linux/interrupt.h>
12 #include <linux/io.h>
13 #include <linux/module.h>
14 #include <linux/of_device.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/sys_soc.h>
18 #include <linux/thermal.h>
19 
20 #include "thermal_core.h"
21 #include "thermal_hwmon.h"
22 
23 /* Register offsets */
24 #define REG_GEN3_IRQSTR		0x04
25 #define REG_GEN3_IRQMSK		0x08
26 #define REG_GEN3_IRQCTL		0x0C
27 #define REG_GEN3_IRQEN		0x10
28 #define REG_GEN3_IRQTEMP1	0x14
29 #define REG_GEN3_IRQTEMP2	0x18
30 #define REG_GEN3_IRQTEMP3	0x1C
31 #define REG_GEN3_CTSR		0x20
32 #define REG_GEN3_THCTR		0x20
33 #define REG_GEN3_TEMP		0x28
34 #define REG_GEN3_THCODE1	0x50
35 #define REG_GEN3_THCODE2	0x54
36 #define REG_GEN3_THCODE3	0x58
37 #define REG_GEN3_PTAT1		0x5c
38 #define REG_GEN3_PTAT2		0x60
39 #define REG_GEN3_PTAT3		0x64
40 #define REG_GEN3_THSCP		0x68
41 
42 /* IRQ{STR,MSK,EN} bits */
43 #define IRQ_TEMP1		BIT(0)
44 #define IRQ_TEMP2		BIT(1)
45 #define IRQ_TEMP3		BIT(2)
46 #define IRQ_TEMPD1		BIT(3)
47 #define IRQ_TEMPD2		BIT(4)
48 #define IRQ_TEMPD3		BIT(5)
49 
50 /* CTSR bits */
51 #define CTSR_PONM	BIT(8)
52 #define CTSR_AOUT	BIT(7)
53 #define CTSR_THBGR	BIT(5)
54 #define CTSR_VMEN	BIT(4)
55 #define CTSR_VMST	BIT(1)
56 #define CTSR_THSST	BIT(0)
57 
58 /* THCTR bits */
59 #define THCTR_PONM	BIT(6)
60 #define THCTR_THSST	BIT(0)
61 
62 /* THSCP bits */
63 #define THSCP_COR_PARA_VLD	(BIT(15) | BIT(14))
64 
65 #define CTEMP_MASK	0xFFF
66 
67 #define MCELSIUS(temp)	((temp) * 1000)
68 #define GEN3_FUSE_MASK	0xFFF
69 
70 #define TSC_MAX_NUM	5
71 
72 /* Structure for thermal temperature calculation */
73 struct equation_coefs {
74 	int a1;
75 	int b1;
76 	int a2;
77 	int b2;
78 };
79 
80 struct rcar_gen3_thermal_tsc {
81 	void __iomem *base;
82 	struct thermal_zone_device *zone;
83 	struct equation_coefs coef;
84 	int tj_t;
85 	int thcode[3];
86 };
87 
88 struct rcar_gen3_thermal_priv {
89 	struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
90 	unsigned int num_tscs;
91 	void (*thermal_init)(struct rcar_gen3_thermal_tsc *tsc);
92 	int ptat[3];
93 };
94 
95 static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc,
96 					 u32 reg)
97 {
98 	return ioread32(tsc->base + reg);
99 }
100 
101 static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
102 					   u32 reg, u32 data)
103 {
104 	iowrite32(data, tsc->base + reg);
105 }
106 
107 /*
108  * Linear approximation for temperature
109  *
110  * [reg] = [temp] * a + b => [temp] = ([reg] - b) / a
111  *
112  * The constants a and b are calculated using two triplets of int values PTAT
113  * and THCODE. PTAT and THCODE can either be read from hardware or use hard
114  * coded values from driver. The formula to calculate a and b are taken from
115  * BSP and sparsely documented and understood.
116  *
117  * Examining the linear formula and the formula used to calculate constants a
118  * and b while knowing that the span for PTAT and THCODE values are between
119  * 0x000 and 0xfff the largest integer possible is 0xfff * 0xfff == 0xffe001.
120  * Integer also needs to be signed so that leaves 7 bits for binary
121  * fixed point scaling.
122  */
123 
124 #define FIXPT_SHIFT 7
125 #define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT)
126 #define INT_FIXPT(_x) ((_x) >> FIXPT_SHIFT)
127 #define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b))
128 #define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT)
129 
130 #define RCAR3_THERMAL_GRAN 500 /* mili Celsius */
131 
132 /* no idea where these constants come from */
133 #define TJ_3 -41
134 
135 static void rcar_gen3_thermal_calc_coefs(struct rcar_gen3_thermal_priv *priv,
136 					 struct rcar_gen3_thermal_tsc *tsc,
137 					 int ths_tj_1)
138 {
139 	/* TODO: Find documentation and document constant calculation formula */
140 
141 	/*
142 	 * Division is not scaled in BSP and if scaled it might overflow
143 	 * the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled
144 	 */
145 	tsc->tj_t = (FIXPT_INT((priv->ptat[1] - priv->ptat[2]) * (ths_tj_1 - TJ_3))
146 		     / (priv->ptat[0] - priv->ptat[2])) + FIXPT_INT(TJ_3);
147 
148 	tsc->coef.a1 = FIXPT_DIV(FIXPT_INT(tsc->thcode[1] - tsc->thcode[2]),
149 				 tsc->tj_t - FIXPT_INT(TJ_3));
150 	tsc->coef.b1 = FIXPT_INT(tsc->thcode[2]) - tsc->coef.a1 * TJ_3;
151 
152 	tsc->coef.a2 = FIXPT_DIV(FIXPT_INT(tsc->thcode[1] - tsc->thcode[0]),
153 				 tsc->tj_t - FIXPT_INT(ths_tj_1));
154 	tsc->coef.b2 = FIXPT_INT(tsc->thcode[0]) - tsc->coef.a2 * ths_tj_1;
155 }
156 
157 static int rcar_gen3_thermal_round(int temp)
158 {
159 	int result, round_offs;
160 
161 	round_offs = temp >= 0 ? RCAR3_THERMAL_GRAN / 2 :
162 		-RCAR3_THERMAL_GRAN / 2;
163 	result = (temp + round_offs) / RCAR3_THERMAL_GRAN;
164 	return result * RCAR3_THERMAL_GRAN;
165 }
166 
167 static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
168 {
169 	struct rcar_gen3_thermal_tsc *tsc = devdata;
170 	int mcelsius, val;
171 	int reg;
172 
173 	/* Read register and convert to mili Celsius */
174 	reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK;
175 
176 	if (reg <= tsc->thcode[1])
177 		val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1,
178 				tsc->coef.a1);
179 	else
180 		val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2,
181 				tsc->coef.a2);
182 	mcelsius = FIXPT_TO_MCELSIUS(val);
183 
184 	/* Guaranteed operating range is -40C to 125C. */
185 
186 	/* Round value to device granularity setting */
187 	*temp = rcar_gen3_thermal_round(mcelsius);
188 
189 	return 0;
190 }
191 
192 static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc,
193 					      int mcelsius)
194 {
195 	int celsius, val;
196 
197 	celsius = DIV_ROUND_CLOSEST(mcelsius, 1000);
198 	if (celsius <= INT_FIXPT(tsc->tj_t))
199 		val = celsius * tsc->coef.a1 + tsc->coef.b1;
200 	else
201 		val = celsius * tsc->coef.a2 + tsc->coef.b2;
202 
203 	return INT_FIXPT(val);
204 }
205 
206 static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high)
207 {
208 	struct rcar_gen3_thermal_tsc *tsc = devdata;
209 	u32 irqmsk = 0;
210 
211 	if (low != -INT_MAX) {
212 		irqmsk |= IRQ_TEMPD1;
213 		rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1,
214 					rcar_gen3_thermal_mcelsius_to_temp(tsc, low));
215 	}
216 
217 	if (high != INT_MAX) {
218 		irqmsk |= IRQ_TEMP2;
219 		rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2,
220 					rcar_gen3_thermal_mcelsius_to_temp(tsc, high));
221 	}
222 
223 	rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, irqmsk);
224 
225 	return 0;
226 }
227 
228 static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = {
229 	.get_temp	= rcar_gen3_thermal_get_temp,
230 	.set_trips	= rcar_gen3_thermal_set_trips,
231 };
232 
233 static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data)
234 {
235 	struct rcar_gen3_thermal_priv *priv = data;
236 	unsigned int i;
237 	u32 status;
238 
239 	for (i = 0; i < priv->num_tscs; i++) {
240 		status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR);
241 		rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0);
242 		if (status)
243 			thermal_zone_device_update(priv->tscs[i]->zone,
244 						   THERMAL_EVENT_UNSPECIFIED);
245 	}
246 
247 	return IRQ_HANDLED;
248 }
249 
250 static const struct soc_device_attribute r8a7795es1[] = {
251 	{ .soc_id = "r8a7795", .revision = "ES1.*" },
252 	{ /* sentinel */ }
253 };
254 
255 static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
256 {
257 	unsigned int i;
258 	u32 thscp;
259 
260 	/* If fuses are not set, fallback to pseudo values. */
261 	thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP);
262 	if ((thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) {
263 		/* Default THCODE values in case FUSEs are not set. */
264 		static const int thcodes[TSC_MAX_NUM][3] = {
265 			{ 3397, 2800, 2221 },
266 			{ 3393, 2795, 2216 },
267 			{ 3389, 2805, 2237 },
268 			{ 3415, 2694, 2195 },
269 			{ 3356, 2724, 2244 },
270 		};
271 
272 		priv->ptat[0] = 2631;
273 		priv->ptat[1] = 1509;
274 		priv->ptat[2] = 435;
275 
276 		for (i = 0; i < priv->num_tscs; i++) {
277 			struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
278 
279 			tsc->thcode[0] = thcodes[i][0];
280 			tsc->thcode[1] = thcodes[i][1];
281 			tsc->thcode[2] = thcodes[i][2];
282 		}
283 
284 		return false;
285 	}
286 
287 	/*
288 	 * Set the pseudo calibration points with fused values.
289 	 * PTAT is shared between all TSCs but only fused for the first
290 	 * TSC while THCODEs are fused for each TSC.
291 	 */
292 	priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) &
293 		GEN3_FUSE_MASK;
294 	priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) &
295 		GEN3_FUSE_MASK;
296 	priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) &
297 		GEN3_FUSE_MASK;
298 
299 	for (i = 0; i < priv->num_tscs; i++) {
300 		struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
301 
302 		tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) &
303 			GEN3_FUSE_MASK;
304 		tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) &
305 			GEN3_FUSE_MASK;
306 		tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) &
307 			GEN3_FUSE_MASK;
308 	}
309 
310 	return true;
311 }
312 
313 static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_tsc *tsc)
314 {
315 	rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR,  CTSR_THBGR);
316 	rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR,  0x0);
317 
318 	usleep_range(1000, 2000);
319 
320 	rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_PONM);
321 
322 	rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F);
323 	rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
324 	if (tsc->zone->ops->set_trips)
325 		rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN,
326 					IRQ_TEMPD1 | IRQ_TEMP2);
327 
328 	rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR,
329 				CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN);
330 
331 	usleep_range(100, 200);
332 
333 	rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR,
334 				CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN |
335 				CTSR_VMST | CTSR_THSST);
336 
337 	usleep_range(1000, 2000);
338 }
339 
340 static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
341 {
342 	u32 reg_val;
343 
344 	reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR);
345 	reg_val &= ~THCTR_PONM;
346 	rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val);
347 
348 	usleep_range(1000, 2000);
349 
350 	rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0);
351 	rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
352 	if (tsc->zone->ops->set_trips)
353 		rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN,
354 					IRQ_TEMPD1 | IRQ_TEMP2);
355 
356 	reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR);
357 	reg_val |= THCTR_THSST;
358 	rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val);
359 
360 	usleep_range(1000, 2000);
361 }
362 
363 static const int rcar_gen3_ths_tj_1 = 126;
364 static const int rcar_gen3_ths_tj_1_m3_w = 116;
365 static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
366 	{
367 		.compatible = "renesas,r8a774a1-thermal",
368 		.data = &rcar_gen3_ths_tj_1_m3_w,
369 	},
370 	{
371 		.compatible = "renesas,r8a774b1-thermal",
372 		.data = &rcar_gen3_ths_tj_1,
373 	},
374 	{
375 		.compatible = "renesas,r8a774e1-thermal",
376 		.data = &rcar_gen3_ths_tj_1,
377 	},
378 	{
379 		.compatible = "renesas,r8a7795-thermal",
380 		.data = &rcar_gen3_ths_tj_1,
381 	},
382 	{
383 		.compatible = "renesas,r8a7796-thermal",
384 		.data = &rcar_gen3_ths_tj_1_m3_w,
385 	},
386 	{
387 		.compatible = "renesas,r8a77961-thermal",
388 		.data = &rcar_gen3_ths_tj_1_m3_w,
389 	},
390 	{
391 		.compatible = "renesas,r8a77965-thermal",
392 		.data = &rcar_gen3_ths_tj_1,
393 	},
394 	{
395 		.compatible = "renesas,r8a77980-thermal",
396 		.data = &rcar_gen3_ths_tj_1,
397 	},
398 	{
399 		.compatible = "renesas,r8a779a0-thermal",
400 		.data = &rcar_gen3_ths_tj_1,
401 	},
402 	{
403 		.compatible = "renesas,r8a779f0-thermal",
404 		.data = &rcar_gen3_ths_tj_1,
405 	},
406 	{},
407 };
408 MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
409 
410 static int rcar_gen3_thermal_remove(struct platform_device *pdev)
411 {
412 	struct device *dev = &pdev->dev;
413 
414 	pm_runtime_put(dev);
415 	pm_runtime_disable(dev);
416 
417 	return 0;
418 }
419 
420 static void rcar_gen3_hwmon_action(void *data)
421 {
422 	struct thermal_zone_device *zone = data;
423 
424 	thermal_remove_hwmon_sysfs(zone);
425 }
426 
427 static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv,
428 					  struct platform_device *pdev)
429 {
430 	struct device *dev = &pdev->dev;
431 	unsigned int i;
432 	char *irqname;
433 	int ret, irq;
434 
435 	for (i = 0; i < 2; i++) {
436 		irq = platform_get_irq_optional(pdev, i);
437 		if (irq < 0)
438 			return irq;
439 
440 		irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d",
441 					 dev_name(dev), i);
442 		if (!irqname)
443 			return -ENOMEM;
444 
445 		ret = devm_request_threaded_irq(dev, irq, NULL,
446 						rcar_gen3_thermal_irq,
447 						IRQF_ONESHOT, irqname, priv);
448 		if (ret)
449 			return ret;
450 	}
451 
452 	return 0;
453 }
454 
455 static int rcar_gen3_thermal_probe(struct platform_device *pdev)
456 {
457 	struct rcar_gen3_thermal_priv *priv;
458 	struct device *dev = &pdev->dev;
459 	const int *ths_tj_1 = of_device_get_match_data(dev);
460 	struct resource *res;
461 	struct thermal_zone_device *zone;
462 	unsigned int i;
463 	int ret;
464 
465 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
466 	if (!priv)
467 		return -ENOMEM;
468 
469 	priv->thermal_init = rcar_gen3_thermal_init;
470 	if (soc_device_match(r8a7795es1))
471 		priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1;
472 
473 	platform_set_drvdata(pdev, priv);
474 
475 	if (rcar_gen3_thermal_request_irqs(priv, pdev))
476 		rcar_gen3_tz_of_ops.set_trips = NULL;
477 
478 	pm_runtime_enable(dev);
479 	pm_runtime_get_sync(dev);
480 
481 	for (i = 0; i < TSC_MAX_NUM; i++) {
482 		struct rcar_gen3_thermal_tsc *tsc;
483 
484 		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
485 		if (!res)
486 			break;
487 
488 		tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL);
489 		if (!tsc) {
490 			ret = -ENOMEM;
491 			goto error_unregister;
492 		}
493 
494 		tsc->base = devm_ioremap_resource(dev, res);
495 		if (IS_ERR(tsc->base)) {
496 			ret = PTR_ERR(tsc->base);
497 			goto error_unregister;
498 		}
499 
500 		priv->tscs[i] = tsc;
501 	}
502 
503 	priv->num_tscs = i;
504 
505 	if (!rcar_gen3_thermal_read_fuses(priv))
506 		dev_info(dev, "No calibration values fused, fallback to driver values\n");
507 
508 	for (i = 0; i < priv->num_tscs; i++) {
509 		struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
510 
511 		zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
512 							    &rcar_gen3_tz_of_ops);
513 		if (IS_ERR(zone)) {
514 			dev_err(dev, "Sensor %u: Can't register thermal zone\n", i);
515 			ret = PTR_ERR(zone);
516 			goto error_unregister;
517 		}
518 		tsc->zone = zone;
519 
520 		priv->thermal_init(tsc);
521 		rcar_gen3_thermal_calc_coefs(priv, tsc, *ths_tj_1);
522 
523 		tsc->zone->tzp->no_hwmon = false;
524 		ret = thermal_add_hwmon_sysfs(tsc->zone);
525 		if (ret)
526 			goto error_unregister;
527 
528 		ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone);
529 		if (ret)
530 			goto error_unregister;
531 
532 		ret = of_thermal_get_ntrips(tsc->zone);
533 		if (ret < 0)
534 			goto error_unregister;
535 
536 		dev_info(dev, "Sensor %u: Loaded %d trip points\n", i, ret);
537 	}
538 
539 	if (!priv->num_tscs) {
540 		ret = -ENODEV;
541 		goto error_unregister;
542 	}
543 
544 	return 0;
545 
546 error_unregister:
547 	rcar_gen3_thermal_remove(pdev);
548 
549 	return ret;
550 }
551 
552 static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev)
553 {
554 	struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev);
555 	unsigned int i;
556 
557 	for (i = 0; i < priv->num_tscs; i++) {
558 		struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
559 		struct thermal_zone_device *zone = tsc->zone;
560 
561 		priv->thermal_init(tsc);
562 		if (zone->ops->set_trips)
563 			rcar_gen3_thermal_set_trips(tsc, zone->prev_low_trip,
564 						    zone->prev_high_trip);
565 	}
566 
567 	return 0;
568 }
569 
570 static SIMPLE_DEV_PM_OPS(rcar_gen3_thermal_pm_ops, NULL,
571 			 rcar_gen3_thermal_resume);
572 
573 static struct platform_driver rcar_gen3_thermal_driver = {
574 	.driver	= {
575 		.name	= "rcar_gen3_thermal",
576 		.pm = &rcar_gen3_thermal_pm_ops,
577 		.of_match_table = rcar_gen3_thermal_dt_ids,
578 	},
579 	.probe		= rcar_gen3_thermal_probe,
580 	.remove		= rcar_gen3_thermal_remove,
581 };
582 module_platform_driver(rcar_gen3_thermal_driver);
583 
584 MODULE_LICENSE("GPL v2");
585 MODULE_DESCRIPTION("R-Car Gen3 THS thermal sensor driver");
586 MODULE_AUTHOR("Wolfram Sang <wsa+renesas@sang-engineering.com>");
587