xref: /linux/drivers/thermal/st/stm_thermal.c (revision 50501936288d6a29d7ef78f25d00e33240fad45f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4  * Author: David Hernandez Sanchez <david.hernandezsanchez@st.com> for
5  * STMicroelectronics.
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/clk-provider.h>
10 #include <linux/delay.h>
11 #include <linux/err.h>
12 #include <linux/interrupt.h>
13 #include <linux/io.h>
14 #include <linux/iopoll.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/of_address.h>
18 #include <linux/of_device.h>
19 #include <linux/platform_device.h>
20 #include <linux/thermal.h>
21 
22 #include "../thermal_hwmon.h"
23 
24 /* DTS register offsets */
25 #define DTS_CFGR1_OFFSET	0x0
26 #define DTS_T0VALR1_OFFSET	0x8
27 #define DTS_RAMPVALR_OFFSET	0X10
28 #define DTS_ITR1_OFFSET		0x14
29 #define DTS_DR_OFFSET		0x1C
30 #define DTS_SR_OFFSET		0x20
31 #define DTS_ITENR_OFFSET	0x24
32 #define DTS_ICIFR_OFFSET	0x28
33 
34 /* DTS_CFGR1 register mask definitions */
35 #define HSREF_CLK_DIV_MASK	GENMASK(30, 24)
36 #define TS1_SMP_TIME_MASK	GENMASK(19, 16)
37 #define TS1_INTRIG_SEL_MASK	GENMASK(11, 8)
38 
39 /* DTS_T0VALR1 register mask definitions */
40 #define TS1_T0_MASK		GENMASK(17, 16)
41 #define TS1_FMT0_MASK		GENMASK(15, 0)
42 
43 /* DTS_RAMPVALR register mask definitions */
44 #define TS1_RAMP_COEFF_MASK	GENMASK(15, 0)
45 
46 /* DTS_ITR1 register mask definitions */
47 #define TS1_HITTHD_MASK		GENMASK(31, 16)
48 #define TS1_LITTHD_MASK		GENMASK(15, 0)
49 
50 /* DTS_DR register mask definitions */
51 #define TS1_MFREQ_MASK		GENMASK(15, 0)
52 
53 /* DTS_ITENR register mask definitions */
54 #define ITENR_MASK		(GENMASK(2, 0) | GENMASK(6, 4))
55 
56 /* DTS_ICIFR register mask definitions */
57 #define ICIFR_MASK		(GENMASK(2, 0) | GENMASK(6, 4))
58 
59 /* Less significant bit position definitions */
60 #define TS1_T0_POS		16
61 #define TS1_HITTHD_POS		16
62 #define TS1_LITTHD_POS		0
63 #define HSREF_CLK_DIV_POS	24
64 
65 /* DTS_CFGR1 bit definitions */
66 #define TS1_EN			BIT(0)
67 #define TS1_START		BIT(4)
68 #define REFCLK_SEL		BIT(20)
69 #define REFCLK_LSE		REFCLK_SEL
70 #define Q_MEAS_OPT		BIT(21)
71 #define CALIBRATION_CONTROL	Q_MEAS_OPT
72 
73 /* DTS_SR bit definitions */
74 #define TS_RDY			BIT(15)
75 /* Bit definitions below are common for DTS_SR, DTS_ITENR and DTS_CIFR */
76 #define HIGH_THRESHOLD		BIT(2)
77 #define LOW_THRESHOLD		BIT(1)
78 
79 /* Constants */
80 #define ADJUST			100
81 #define ONE_MHZ			1000000
82 #define POLL_TIMEOUT		5000
83 #define STARTUP_TIME		40
84 #define TS1_T0_VAL0		30000  /* 30 celsius */
85 #define TS1_T0_VAL1		130000 /* 130 celsius */
86 #define NO_HW_TRIG		0
87 #define SAMPLING_TIME		15
88 
89 struct stm_thermal_sensor {
90 	struct device *dev;
91 	struct thermal_zone_device *th_dev;
92 	enum thermal_device_mode mode;
93 	struct clk *clk;
94 	unsigned int low_temp_enabled;
95 	unsigned int high_temp_enabled;
96 	int irq;
97 	void __iomem *base;
98 	int t0, fmt0, ramp_coeff;
99 };
100 
101 static int stm_enable_irq(struct stm_thermal_sensor *sensor)
102 {
103 	u32 value;
104 
105 	dev_dbg(sensor->dev, "low:%d high:%d\n", sensor->low_temp_enabled,
106 		sensor->high_temp_enabled);
107 
108 	/* Disable IT generation for low and high thresholds */
109 	value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
110 	value &= ~(LOW_THRESHOLD | HIGH_THRESHOLD);
111 
112 	if (sensor->low_temp_enabled)
113 		value |= HIGH_THRESHOLD;
114 
115 	if (sensor->high_temp_enabled)
116 		value |= LOW_THRESHOLD;
117 
118 	/* Enable interrupts */
119 	writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
120 
121 	return 0;
122 }
123 
124 static irqreturn_t stm_thermal_irq_handler(int irq, void *sdata)
125 {
126 	struct stm_thermal_sensor *sensor = sdata;
127 
128 	dev_dbg(sensor->dev, "sr:%d\n",
129 		readl_relaxed(sensor->base + DTS_SR_OFFSET));
130 
131 	thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
132 
133 	stm_enable_irq(sensor);
134 
135 	/* Acknoledge all DTS irqs */
136 	writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
137 
138 	return IRQ_HANDLED;
139 }
140 
141 static int stm_sensor_power_on(struct stm_thermal_sensor *sensor)
142 {
143 	int ret;
144 	u32 value;
145 
146 	/* Enable sensor */
147 	value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
148 	value |= TS1_EN;
149 	writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
150 
151 	/*
152 	 * The DTS block can be enabled by setting TSx_EN bit in
153 	 * DTS_CFGRx register. It requires a startup time of
154 	 * 40μs. Use 5 ms as arbitrary timeout.
155 	 */
156 	ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET,
157 				 value, (value & TS_RDY),
158 				 STARTUP_TIME, POLL_TIMEOUT);
159 	if (ret)
160 		return ret;
161 
162 	/* Start continuous measuring */
163 	value = readl_relaxed(sensor->base +
164 			      DTS_CFGR1_OFFSET);
165 	value |= TS1_START;
166 	writel_relaxed(value, sensor->base +
167 		       DTS_CFGR1_OFFSET);
168 
169 	sensor->mode = THERMAL_DEVICE_ENABLED;
170 
171 	return 0;
172 }
173 
174 static int stm_sensor_power_off(struct stm_thermal_sensor *sensor)
175 {
176 	u32 value;
177 
178 	sensor->mode = THERMAL_DEVICE_DISABLED;
179 
180 	/* Stop measuring */
181 	value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
182 	value &= ~TS1_START;
183 	writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
184 
185 	/* Ensure stop is taken into account */
186 	usleep_range(STARTUP_TIME, POLL_TIMEOUT);
187 
188 	/* Disable sensor */
189 	value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
190 	value &= ~TS1_EN;
191 	writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
192 
193 	/* Ensure disable is taken into account */
194 	return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value,
195 				  !(value & TS_RDY),
196 				  STARTUP_TIME, POLL_TIMEOUT);
197 }
198 
199 static int stm_thermal_calibration(struct stm_thermal_sensor *sensor)
200 {
201 	u32 value, clk_freq;
202 	u32 prescaler;
203 
204 	/* Figure out prescaler value for PCLK during calibration */
205 	clk_freq = clk_get_rate(sensor->clk);
206 	if (!clk_freq)
207 		return -EINVAL;
208 
209 	prescaler = 0;
210 	clk_freq /= ONE_MHZ;
211 	if (clk_freq) {
212 		while (prescaler <= clk_freq)
213 			prescaler++;
214 	}
215 
216 	value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
217 
218 	/* Clear prescaler */
219 	value &= ~HSREF_CLK_DIV_MASK;
220 
221 	/* Set prescaler. pclk_freq/prescaler < 1MHz */
222 	value |= (prescaler << HSREF_CLK_DIV_POS);
223 
224 	/* Select PCLK as reference clock */
225 	value &= ~REFCLK_SEL;
226 
227 	/* Set maximal sampling time for better precision */
228 	value |= TS1_SMP_TIME_MASK;
229 
230 	/* Measure with calibration */
231 	value &= ~CALIBRATION_CONTROL;
232 
233 	/* select trigger */
234 	value &= ~TS1_INTRIG_SEL_MASK;
235 	value |= NO_HW_TRIG;
236 
237 	writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
238 
239 	return 0;
240 }
241 
242 /* Fill in DTS structure with factory sensor values */
243 static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor)
244 {
245 	/* Retrieve engineering calibration temperature */
246 	sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) &
247 					TS1_T0_MASK;
248 	if (!sensor->t0)
249 		sensor->t0 = TS1_T0_VAL0;
250 	else
251 		sensor->t0 = TS1_T0_VAL1;
252 
253 	/* Retrieve fmt0 and put it on Hz */
254 	sensor->fmt0 = ADJUST * (readl_relaxed(sensor->base +
255 				 DTS_T0VALR1_OFFSET) & TS1_FMT0_MASK);
256 
257 	/* Retrieve ramp coefficient */
258 	sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) &
259 					   TS1_RAMP_COEFF_MASK;
260 
261 	if (!sensor->fmt0 || !sensor->ramp_coeff) {
262 		dev_err(sensor->dev, "%s: wrong setting\n", __func__);
263 		return -EINVAL;
264 	}
265 
266 	dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC",
267 		__func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff);
268 
269 	return 0;
270 }
271 
272 static int stm_thermal_calculate_threshold(struct stm_thermal_sensor *sensor,
273 					   int temp, u32 *th)
274 {
275 	int freqM;
276 
277 	/* Figure out the CLK_PTAT frequency for a given temperature */
278 	freqM = ((temp - sensor->t0) * sensor->ramp_coeff) / 1000 +
279 		sensor->fmt0;
280 
281 	/* Figure out the threshold sample number */
282 	*th = clk_get_rate(sensor->clk) * SAMPLING_TIME / freqM;
283 	if (!*th)
284 		return -EINVAL;
285 
286 	dev_dbg(sensor->dev, "freqM=%d Hz, threshold=0x%x", freqM, *th);
287 
288 	return 0;
289 }
290 
291 /* Disable temperature interrupt */
292 static int stm_disable_irq(struct stm_thermal_sensor *sensor)
293 {
294 	u32 value;
295 
296 	/* Disable IT generation */
297 	value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
298 	value &= ~ITENR_MASK;
299 	writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
300 
301 	return 0;
302 }
303 
304 static int stm_thermal_set_trips(struct thermal_zone_device *tz, int low, int high)
305 {
306 	struct stm_thermal_sensor *sensor = thermal_zone_device_priv(tz);
307 	u32 itr1, th;
308 	int ret;
309 
310 	dev_dbg(sensor->dev, "set trips %d <--> %d\n", low, high);
311 
312 	/* Erase threshold content */
313 	itr1 = readl_relaxed(sensor->base + DTS_ITR1_OFFSET);
314 	itr1 &= ~(TS1_LITTHD_MASK | TS1_HITTHD_MASK);
315 
316 	/*
317 	 * Disable low-temp if "low" is too small. As per thermal framework
318 	 * API, we use -INT_MAX rather than INT_MIN.
319 	 */
320 
321 	if (low > -INT_MAX) {
322 		sensor->low_temp_enabled = 1;
323 		/* add 0.5 of hysteresis due to measurement error */
324 		ret = stm_thermal_calculate_threshold(sensor, low - 500, &th);
325 		if (ret)
326 			return ret;
327 
328 		itr1 |= (TS1_HITTHD_MASK  & (th << TS1_HITTHD_POS));
329 	} else {
330 		sensor->low_temp_enabled = 0;
331 	}
332 
333 	/* Disable high-temp if "high" is too big. */
334 	if (high < INT_MAX) {
335 		sensor->high_temp_enabled = 1;
336 		ret = stm_thermal_calculate_threshold(sensor, high, &th);
337 		if (ret)
338 			return ret;
339 
340 		itr1 |= (TS1_LITTHD_MASK  & (th << TS1_LITTHD_POS));
341 	} else {
342 		sensor->high_temp_enabled = 0;
343 	}
344 
345 	/* Write new threshod values*/
346 	writel_relaxed(itr1, sensor->base + DTS_ITR1_OFFSET);
347 
348 	return 0;
349 }
350 
351 /* Callback to get temperature from HW */
352 static int stm_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
353 {
354 	struct stm_thermal_sensor *sensor = thermal_zone_device_priv(tz);
355 	u32 periods;
356 	int freqM, ret;
357 
358 	if (sensor->mode != THERMAL_DEVICE_ENABLED)
359 		return -EAGAIN;
360 
361 	/* Retrieve the number of periods sampled */
362 	ret = readl_relaxed_poll_timeout(sensor->base + DTS_DR_OFFSET, periods,
363 					 (periods & TS1_MFREQ_MASK),
364 					 STARTUP_TIME, POLL_TIMEOUT);
365 	if (ret)
366 		return ret;
367 
368 	/* Figure out the CLK_PTAT frequency */
369 	freqM = (clk_get_rate(sensor->clk) * SAMPLING_TIME) / periods;
370 	if (!freqM)
371 		return -EINVAL;
372 
373 	/* Figure out the temperature in mili celsius */
374 	*temp = (freqM - sensor->fmt0) * 1000 / sensor->ramp_coeff + sensor->t0;
375 
376 	return 0;
377 }
378 
379 /* Registers DTS irq to be visible by GIC */
380 static int stm_register_irq(struct stm_thermal_sensor *sensor)
381 {
382 	struct device *dev = sensor->dev;
383 	struct platform_device *pdev = to_platform_device(dev);
384 	int ret;
385 
386 	sensor->irq = platform_get_irq(pdev, 0);
387 	if (sensor->irq < 0)
388 		return sensor->irq;
389 
390 	ret = devm_request_threaded_irq(dev, sensor->irq,
391 					NULL,
392 					stm_thermal_irq_handler,
393 					IRQF_ONESHOT,
394 					dev->driver->name, sensor);
395 	if (ret) {
396 		dev_err(dev, "%s: Failed to register IRQ %d\n", __func__,
397 			sensor->irq);
398 		return ret;
399 	}
400 
401 	dev_dbg(dev, "%s: thermal IRQ registered", __func__);
402 
403 	return 0;
404 }
405 
406 static int stm_thermal_sensor_off(struct stm_thermal_sensor *sensor)
407 {
408 	int ret;
409 
410 	stm_disable_irq(sensor);
411 
412 	ret = stm_sensor_power_off(sensor);
413 	if (ret)
414 		return ret;
415 
416 	clk_disable_unprepare(sensor->clk);
417 
418 	return 0;
419 }
420 
421 static int stm_thermal_prepare(struct stm_thermal_sensor *sensor)
422 {
423 	int ret;
424 
425 	ret = clk_prepare_enable(sensor->clk);
426 	if (ret)
427 		return ret;
428 
429 	ret = stm_thermal_read_factory_settings(sensor);
430 	if (ret)
431 		goto thermal_unprepare;
432 
433 	ret = stm_thermal_calibration(sensor);
434 	if (ret)
435 		goto thermal_unprepare;
436 
437 	return 0;
438 
439 thermal_unprepare:
440 	clk_disable_unprepare(sensor->clk);
441 
442 	return ret;
443 }
444 
445 #ifdef CONFIG_PM_SLEEP
446 static int stm_thermal_suspend(struct device *dev)
447 {
448 	struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
449 
450 	return stm_thermal_sensor_off(sensor);
451 }
452 
453 static int stm_thermal_resume(struct device *dev)
454 {
455 	int ret;
456 	struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
457 
458 	ret = stm_thermal_prepare(sensor);
459 	if (ret)
460 		return ret;
461 
462 	ret = stm_sensor_power_on(sensor);
463 	if (ret)
464 		return ret;
465 
466 	thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
467 	stm_enable_irq(sensor);
468 
469 	return 0;
470 }
471 #endif /* CONFIG_PM_SLEEP */
472 
473 static SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops,
474 			 stm_thermal_suspend, stm_thermal_resume);
475 
476 static const struct thermal_zone_device_ops stm_tz_ops = {
477 	.get_temp	= stm_thermal_get_temp,
478 	.set_trips	= stm_thermal_set_trips,
479 };
480 
481 static const struct of_device_id stm_thermal_of_match[] = {
482 		{ .compatible = "st,stm32-thermal"},
483 	{ /* sentinel */ }
484 };
485 MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
486 
487 static int stm_thermal_probe(struct platform_device *pdev)
488 {
489 	struct stm_thermal_sensor *sensor;
490 	void __iomem *base;
491 	int ret;
492 
493 	if (!pdev->dev.of_node) {
494 		dev_err(&pdev->dev, "%s: device tree node not found\n",
495 			__func__);
496 		return -EINVAL;
497 	}
498 
499 	sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
500 	if (!sensor)
501 		return -ENOMEM;
502 
503 	platform_set_drvdata(pdev, sensor);
504 
505 	sensor->dev = &pdev->dev;
506 
507 	base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
508 	if (IS_ERR(base))
509 		return PTR_ERR(base);
510 
511 	/* Populate sensor */
512 	sensor->base = base;
513 
514 	sensor->clk = devm_clk_get(&pdev->dev, "pclk");
515 	if (IS_ERR(sensor->clk)) {
516 		dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
517 			__func__);
518 		return PTR_ERR(sensor->clk);
519 	}
520 
521 	stm_disable_irq(sensor);
522 
523 	/* Clear irq flags */
524 	writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
525 
526 	/* Configure and enable HW sensor */
527 	ret = stm_thermal_prepare(sensor);
528 	if (ret) {
529 		dev_err(&pdev->dev, "Error prepare sensor: %d\n", ret);
530 		return ret;
531 	}
532 
533 	ret = stm_sensor_power_on(sensor);
534 	if (ret) {
535 		dev_err(&pdev->dev, "Error power on sensor: %d\n", ret);
536 		return ret;
537 	}
538 
539 	sensor->th_dev = devm_thermal_of_zone_register(&pdev->dev, 0,
540 						       sensor,
541 						       &stm_tz_ops);
542 
543 	if (IS_ERR(sensor->th_dev)) {
544 		dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
545 			__func__);
546 		ret = PTR_ERR(sensor->th_dev);
547 		return ret;
548 	}
549 
550 	/* Register IRQ into GIC */
551 	ret = stm_register_irq(sensor);
552 	if (ret)
553 		goto err_tz;
554 
555 	stm_enable_irq(sensor);
556 
557 	/*
558 	 * Thermal_zone doesn't enable hwmon as default,
559 	 * enable it here
560 	 */
561 	ret = thermal_add_hwmon_sysfs(sensor->th_dev);
562 	if (ret)
563 		goto err_tz;
564 
565 	dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
566 		 __func__);
567 
568 	return 0;
569 
570 err_tz:
571 	return ret;
572 }
573 
574 static int stm_thermal_remove(struct platform_device *pdev)
575 {
576 	struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
577 
578 	stm_thermal_sensor_off(sensor);
579 	thermal_remove_hwmon_sysfs(sensor->th_dev);
580 
581 	return 0;
582 }
583 
584 static struct platform_driver stm_thermal_driver = {
585 	.driver = {
586 		.name	= "stm_thermal",
587 		.pm     = &stm_thermal_pm_ops,
588 		.of_match_table = stm_thermal_of_match,
589 	},
590 	.probe		= stm_thermal_probe,
591 	.remove		= stm_thermal_remove,
592 };
593 module_platform_driver(stm_thermal_driver);
594 
595 MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
596 MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
597 MODULE_LICENSE("GPL v2");
598 MODULE_ALIAS("platform:stm_thermal");
599