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