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