Loading...
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
87struct 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
99static 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
122static 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
139static 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
172static 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
197static 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 */
241static 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
270static 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 */
290static 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
302static 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 */
350static 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 */
378static 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
404static 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
419static 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
437thermal_unprepare:
438 clk_disable_unprepare(sensor->clk);
439
440 return ret;
441}
442
443static int stm_thermal_suspend(struct device *dev)
444{
445 struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
446
447 return stm_thermal_sensor_off(sensor);
448}
449
450static int stm_thermal_resume(struct device *dev)
451{
452 int ret;
453 struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
454
455 ret = stm_thermal_prepare(sensor);
456 if (ret)
457 return ret;
458
459 ret = stm_sensor_power_on(sensor);
460 if (ret)
461 return ret;
462
463 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
464 stm_enable_irq(sensor);
465
466 return 0;
467}
468
469static DEFINE_SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops,
470 stm_thermal_suspend, stm_thermal_resume);
471
472static const struct thermal_zone_device_ops stm_tz_ops = {
473 .get_temp = stm_thermal_get_temp,
474 .set_trips = stm_thermal_set_trips,
475};
476
477static const struct of_device_id stm_thermal_of_match[] = {
478 { .compatible = "st,stm32-thermal"},
479 { /* sentinel */ }
480};
481MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
482
483static int stm_thermal_probe(struct platform_device *pdev)
484{
485 struct stm_thermal_sensor *sensor;
486 void __iomem *base;
487 int ret;
488
489 if (!pdev->dev.of_node) {
490 dev_err(&pdev->dev, "%s: device tree node not found\n",
491 __func__);
492 return -EINVAL;
493 }
494
495 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
496 if (!sensor)
497 return -ENOMEM;
498
499 platform_set_drvdata(pdev, sensor);
500
501 sensor->dev = &pdev->dev;
502
503 base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
504 if (IS_ERR(base))
505 return PTR_ERR(base);
506
507 /* Populate sensor */
508 sensor->base = base;
509
510 sensor->clk = devm_clk_get(&pdev->dev, "pclk");
511 if (IS_ERR(sensor->clk)) {
512 dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
513 __func__);
514 return PTR_ERR(sensor->clk);
515 }
516
517 stm_disable_irq(sensor);
518
519 /* Clear irq flags */
520 writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
521
522 /* Configure and enable HW sensor */
523 ret = stm_thermal_prepare(sensor);
524 if (ret) {
525 dev_err(&pdev->dev, "Error prepare sensor: %d\n", ret);
526 return ret;
527 }
528
529 ret = stm_sensor_power_on(sensor);
530 if (ret) {
531 dev_err(&pdev->dev, "Error power on sensor: %d\n", ret);
532 return ret;
533 }
534
535 sensor->th_dev = devm_thermal_of_zone_register(&pdev->dev, 0,
536 sensor,
537 &stm_tz_ops);
538
539 if (IS_ERR(sensor->th_dev)) {
540 dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
541 __func__);
542 ret = PTR_ERR(sensor->th_dev);
543 return ret;
544 }
545
546 /* Register IRQ into GIC */
547 ret = stm_register_irq(sensor);
548 if (ret)
549 goto err_tz;
550
551 stm_enable_irq(sensor);
552
553 /*
554 * Thermal_zone doesn't enable hwmon as default,
555 * enable it here
556 */
557 ret = thermal_add_hwmon_sysfs(sensor->th_dev);
558 if (ret)
559 goto err_tz;
560
561 dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
562 __func__);
563
564 return 0;
565
566err_tz:
567 return ret;
568}
569
570static void stm_thermal_remove(struct platform_device *pdev)
571{
572 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
573
574 stm_thermal_sensor_off(sensor);
575 thermal_remove_hwmon_sysfs(sensor->th_dev);
576}
577
578static struct platform_driver stm_thermal_driver = {
579 .driver = {
580 .name = "stm_thermal",
581 .pm = pm_sleep_ptr(&stm_thermal_pm_ops),
582 .of_match_table = stm_thermal_of_match,
583 },
584 .probe = stm_thermal_probe,
585 .remove = stm_thermal_remove,
586};
587module_platform_driver(stm_thermal_driver);
588
589MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
590MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
591MODULE_LICENSE("GPL v2");
592MODULE_ALIAS("platform:stm_thermal");
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_core.h"
23#include "../thermal_hwmon.h"
24
25/* DTS register offsets */
26#define DTS_CFGR1_OFFSET 0x0
27#define DTS_T0VALR1_OFFSET 0x8
28#define DTS_RAMPVALR_OFFSET 0X10
29#define DTS_ITR1_OFFSET 0x14
30#define DTS_DR_OFFSET 0x1C
31#define DTS_SR_OFFSET 0x20
32#define DTS_ITENR_OFFSET 0x24
33#define DTS_CIFR_OFFSET 0x28
34
35/* DTS_CFGR1 register mask definitions */
36#define HSREF_CLK_DIV_MASK GENMASK(30, 24)
37#define TS1_SMP_TIME_MASK GENMASK(19, 16)
38#define TS1_INTRIG_SEL_MASK GENMASK(11, 8)
39
40/* DTS_T0VALR1 register mask definitions */
41#define TS1_T0_MASK GENMASK(17, 16)
42#define TS1_FMT0_MASK GENMASK(15, 0)
43
44/* DTS_RAMPVALR register mask definitions */
45#define TS1_RAMP_COEFF_MASK GENMASK(15, 0)
46
47/* DTS_ITR1 register mask definitions */
48#define TS1_HITTHD_MASK GENMASK(31, 16)
49#define TS1_LITTHD_MASK GENMASK(15, 0)
50
51/* DTS_DR register mask definitions */
52#define TS1_MFREQ_MASK GENMASK(15, 0)
53
54/* Less significant bit position definitions */
55#define TS1_T0_POS 16
56#define TS1_SMP_TIME_POS 16
57#define TS1_HITTHD_POS 16
58#define HSREF_CLK_DIV_POS 24
59
60/* DTS_CFGR1 bit definitions */
61#define TS1_EN BIT(0)
62#define TS1_START BIT(4)
63#define REFCLK_SEL BIT(20)
64#define REFCLK_LSE REFCLK_SEL
65#define Q_MEAS_OPT BIT(21)
66#define CALIBRATION_CONTROL Q_MEAS_OPT
67
68/* DTS_SR bit definitions */
69#define TS_RDY BIT(15)
70/* Bit definitions below are common for DTS_SR, DTS_ITENR and DTS_CIFR */
71#define HIGH_THRESHOLD BIT(2)
72#define LOW_THRESHOLD BIT(1)
73
74/* Constants */
75#define ADJUST 100
76#define ONE_MHZ 1000000
77#define POLL_TIMEOUT 5000
78#define STARTUP_TIME 40
79#define TS1_T0_VAL0 30
80#define TS1_T0_VAL1 130
81#define NO_HW_TRIG 0
82
83/* The Thermal Framework expects millidegrees */
84#define mcelsius(temp) ((temp) * 1000)
85
86/* The Sensor expects oC degrees */
87#define celsius(temp) ((temp) / 1000)
88
89struct 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 int high_temp;
95 int low_temp;
96 int temp_critical;
97 int temp_passive;
98 unsigned int low_temp_enabled;
99 int num_trips;
100 int irq;
101 unsigned int irq_enabled;
102 void __iomem *base;
103 int t0, fmt0, ramp_coeff;
104};
105
106static irqreturn_t stm_thermal_alarm_irq(int irq, void *sdata)
107{
108 struct stm_thermal_sensor *sensor = sdata;
109
110 disable_irq_nosync(irq);
111 sensor->irq_enabled = false;
112
113 return IRQ_WAKE_THREAD;
114}
115
116static irqreturn_t stm_thermal_alarm_irq_thread(int irq, void *sdata)
117{
118 u32 value;
119 struct stm_thermal_sensor *sensor = sdata;
120
121 /* read IT reason in SR and clear flags */
122 value = readl_relaxed(sensor->base + DTS_SR_OFFSET);
123
124 if ((value & LOW_THRESHOLD) == LOW_THRESHOLD)
125 writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
126
127 if ((value & HIGH_THRESHOLD) == HIGH_THRESHOLD)
128 writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
129
130 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
131
132 return IRQ_HANDLED;
133}
134
135static int stm_sensor_power_on(struct stm_thermal_sensor *sensor)
136{
137 int ret;
138 u32 value;
139
140 /* Enable sensor */
141 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
142 value |= TS1_EN;
143 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
144
145 /*
146 * The DTS block can be enabled by setting TSx_EN bit in
147 * DTS_CFGRx register. It requires a startup time of
148 * 40μs. Use 5 ms as arbitrary timeout.
149 */
150 ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET,
151 value, (value & TS_RDY),
152 STARTUP_TIME, POLL_TIMEOUT);
153 if (ret)
154 return ret;
155
156 /* Start continuous measuring */
157 value = readl_relaxed(sensor->base +
158 DTS_CFGR1_OFFSET);
159 value |= TS1_START;
160 writel_relaxed(value, sensor->base +
161 DTS_CFGR1_OFFSET);
162
163 return 0;
164}
165
166static int stm_sensor_power_off(struct stm_thermal_sensor *sensor)
167{
168 u32 value;
169
170 /* Stop measuring */
171 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
172 value &= ~TS1_START;
173 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
174
175 /* Ensure stop is taken into account */
176 usleep_range(STARTUP_TIME, POLL_TIMEOUT);
177
178 /* Disable sensor */
179 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
180 value &= ~TS1_EN;
181 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
182
183 /* Ensure disable is taken into account */
184 return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value,
185 !(value & TS_RDY),
186 STARTUP_TIME, POLL_TIMEOUT);
187}
188
189static int stm_thermal_calibration(struct stm_thermal_sensor *sensor)
190{
191 u32 value, clk_freq;
192 u32 prescaler;
193
194 /* Figure out prescaler value for PCLK during calibration */
195 clk_freq = clk_get_rate(sensor->clk);
196 if (!clk_freq)
197 return -EINVAL;
198
199 prescaler = 0;
200 clk_freq /= ONE_MHZ;
201 if (clk_freq) {
202 while (prescaler <= clk_freq)
203 prescaler++;
204 }
205
206 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
207
208 /* Clear prescaler */
209 value &= ~HSREF_CLK_DIV_MASK;
210
211 /* Set prescaler. pclk_freq/prescaler < 1MHz */
212 value |= (prescaler << HSREF_CLK_DIV_POS);
213
214 /* Select PCLK as reference clock */
215 value &= ~REFCLK_SEL;
216
217 /* Set maximal sampling time for better precision */
218 value |= TS1_SMP_TIME_MASK;
219
220 /* Measure with calibration */
221 value &= ~CALIBRATION_CONTROL;
222
223 /* select trigger */
224 value &= ~TS1_INTRIG_SEL_MASK;
225 value |= NO_HW_TRIG;
226
227 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
228
229 return 0;
230}
231
232/* Fill in DTS structure with factory sensor values */
233static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor)
234{
235 /* Retrieve engineering calibration temperature */
236 sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) &
237 TS1_T0_MASK;
238 if (!sensor->t0)
239 sensor->t0 = TS1_T0_VAL0;
240 else
241 sensor->t0 = TS1_T0_VAL1;
242
243 /* Retrieve fmt0 and put it on Hz */
244 sensor->fmt0 = ADJUST * (readl_relaxed(sensor->base +
245 DTS_T0VALR1_OFFSET) & TS1_FMT0_MASK);
246
247 /* Retrieve ramp coefficient */
248 sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) &
249 TS1_RAMP_COEFF_MASK;
250
251 if (!sensor->fmt0 || !sensor->ramp_coeff) {
252 dev_err(sensor->dev, "%s: wrong setting\n", __func__);
253 return -EINVAL;
254 }
255
256 dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC",
257 __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff);
258
259 return 0;
260}
261
262static int stm_thermal_calculate_threshold(struct stm_thermal_sensor *sensor,
263 int temp, u32 *th)
264{
265 int freqM;
266 u32 sampling_time;
267
268 /* Retrieve the number of periods to sample */
269 sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) &
270 TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS;
271
272 /* Figure out the CLK_PTAT frequency for a given temperature */
273 freqM = ((temp - sensor->t0) * sensor->ramp_coeff)
274 + sensor->fmt0;
275
276 dev_dbg(sensor->dev, "%s: freqM for threshold = %d Hz",
277 __func__, freqM);
278
279 /* Figure out the threshold sample number */
280 *th = clk_get_rate(sensor->clk);
281 if (!*th)
282 return -EINVAL;
283
284 *th = *th / freqM;
285
286 *th *= sampling_time;
287
288 return 0;
289}
290
291static int stm_thermal_set_threshold(struct stm_thermal_sensor *sensor)
292{
293 u32 value, th;
294 int ret;
295
296 value = readl_relaxed(sensor->base + DTS_ITR1_OFFSET);
297
298 /* Erase threshold content */
299 value &= ~(TS1_LITTHD_MASK | TS1_HITTHD_MASK);
300
301 /* Retrieve the sample threshold number th for a given temperature */
302 ret = stm_thermal_calculate_threshold(sensor, sensor->high_temp, &th);
303 if (ret)
304 return ret;
305
306 value |= th & TS1_LITTHD_MASK;
307
308 if (sensor->low_temp_enabled) {
309 /* Retrieve the sample threshold */
310 ret = stm_thermal_calculate_threshold(sensor, sensor->low_temp,
311 &th);
312 if (ret)
313 return ret;
314
315 value |= (TS1_HITTHD_MASK & (th << TS1_HITTHD_POS));
316 }
317
318 /* Write value on the Low interrupt threshold */
319 writel_relaxed(value, sensor->base + DTS_ITR1_OFFSET);
320
321 return 0;
322}
323
324/* Disable temperature interrupt */
325static int stm_disable_irq(struct stm_thermal_sensor *sensor)
326{
327 u32 value;
328
329 /* Disable IT generation for low and high thresholds */
330 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
331 writel_relaxed(value & ~(LOW_THRESHOLD | HIGH_THRESHOLD),
332 sensor->base + DTS_ITENR_OFFSET);
333
334 dev_dbg(sensor->dev, "%s: IT disabled on sensor side", __func__);
335
336 return 0;
337}
338
339/* Enable temperature interrupt */
340static int stm_enable_irq(struct stm_thermal_sensor *sensor)
341{
342 u32 value;
343
344 /*
345 * Code below enables High temperature threshold using a low threshold
346 * sampling value
347 */
348
349 /* Make sure LOW_THRESHOLD IT is clear before enabling */
350 writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
351
352 /* Enable IT generation for low threshold */
353 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
354 value |= LOW_THRESHOLD;
355
356 /* Enable the low temperature threshold if needed */
357 if (sensor->low_temp_enabled) {
358 /* Make sure HIGH_THRESHOLD IT is clear before enabling */
359 writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
360
361 /* Enable IT generation for high threshold */
362 value |= HIGH_THRESHOLD;
363 }
364
365 /* Enable thresholds */
366 writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
367
368 dev_dbg(sensor->dev, "%s: IT enabled on sensor side", __func__);
369
370 return 0;
371}
372
373static int stm_thermal_update_threshold(struct stm_thermal_sensor *sensor)
374{
375 int ret;
376
377 sensor->mode = THERMAL_DEVICE_DISABLED;
378
379 ret = stm_sensor_power_off(sensor);
380 if (ret)
381 return ret;
382
383 ret = stm_disable_irq(sensor);
384 if (ret)
385 return ret;
386
387 ret = stm_thermal_set_threshold(sensor);
388 if (ret)
389 return ret;
390
391 ret = stm_enable_irq(sensor);
392 if (ret)
393 return ret;
394
395 ret = stm_sensor_power_on(sensor);
396 if (ret)
397 return ret;
398
399 sensor->mode = THERMAL_DEVICE_ENABLED;
400
401 return 0;
402}
403
404/* Callback to get temperature from HW */
405static int stm_thermal_get_temp(void *data, int *temp)
406{
407 struct stm_thermal_sensor *sensor = data;
408 u32 sampling_time;
409 int freqM, ret;
410
411 if (sensor->mode != THERMAL_DEVICE_ENABLED)
412 return -EAGAIN;
413
414 /* Retrieve the number of samples */
415 ret = readl_poll_timeout(sensor->base + DTS_DR_OFFSET, freqM,
416 (freqM & TS1_MFREQ_MASK), STARTUP_TIME,
417 POLL_TIMEOUT);
418
419 if (ret)
420 return ret;
421
422 if (!freqM)
423 return -ENODATA;
424
425 /* Retrieve the number of periods sampled */
426 sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) &
427 TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS;
428
429 /* Figure out the number of samples per period */
430 freqM /= sampling_time;
431
432 /* Figure out the CLK_PTAT frequency */
433 freqM = clk_get_rate(sensor->clk) / freqM;
434 if (!freqM)
435 return -EINVAL;
436
437 dev_dbg(sensor->dev, "%s: freqM=%d\n", __func__, freqM);
438
439 /* Figure out the temperature in mili celsius */
440 *temp = mcelsius(sensor->t0 + ((freqM - sensor->fmt0) /
441 sensor->ramp_coeff));
442
443 dev_dbg(sensor->dev, "%s: temperature = %d millicelsius",
444 __func__, *temp);
445
446 /* Update thresholds */
447 if (sensor->num_trips > 1) {
448 /* Update alarm threshold value to next higher trip point */
449 if (sensor->high_temp == sensor->temp_passive &&
450 celsius(*temp) >= sensor->temp_passive) {
451 sensor->high_temp = sensor->temp_critical;
452 sensor->low_temp = sensor->temp_passive;
453 sensor->low_temp_enabled = true;
454 ret = stm_thermal_update_threshold(sensor);
455 if (ret)
456 return ret;
457 }
458
459 if (sensor->high_temp == sensor->temp_critical &&
460 celsius(*temp) < sensor->temp_passive) {
461 sensor->high_temp = sensor->temp_passive;
462 sensor->low_temp_enabled = false;
463 ret = stm_thermal_update_threshold(sensor);
464 if (ret)
465 return ret;
466 }
467
468 /*
469 * Re-enable alarm IRQ if temperature below critical
470 * temperature
471 */
472 if (!sensor->irq_enabled &&
473 (celsius(*temp) < sensor->temp_critical)) {
474 sensor->irq_enabled = true;
475 enable_irq(sensor->irq);
476 }
477 }
478
479 return 0;
480}
481
482/* Registers DTS irq to be visible by GIC */
483static int stm_register_irq(struct stm_thermal_sensor *sensor)
484{
485 struct device *dev = sensor->dev;
486 struct platform_device *pdev = to_platform_device(dev);
487 int ret;
488
489 sensor->irq = platform_get_irq(pdev, 0);
490 if (sensor->irq < 0) {
491 dev_err(dev, "%s: Unable to find IRQ\n", __func__);
492 return sensor->irq;
493 }
494
495 ret = devm_request_threaded_irq(dev, sensor->irq,
496 stm_thermal_alarm_irq,
497 stm_thermal_alarm_irq_thread,
498 IRQF_ONESHOT,
499 dev->driver->name, sensor);
500 if (ret) {
501 dev_err(dev, "%s: Failed to register IRQ %d\n", __func__,
502 sensor->irq);
503 return ret;
504 }
505
506 sensor->irq_enabled = true;
507
508 dev_dbg(dev, "%s: thermal IRQ registered", __func__);
509
510 return 0;
511}
512
513static int stm_thermal_sensor_off(struct stm_thermal_sensor *sensor)
514{
515 int ret;
516
517 ret = stm_sensor_power_off(sensor);
518 if (ret)
519 return ret;
520
521 clk_disable_unprepare(sensor->clk);
522
523 return 0;
524}
525
526static int stm_thermal_prepare(struct stm_thermal_sensor *sensor)
527{
528 int ret;
529 struct device *dev = sensor->dev;
530
531 ret = clk_prepare_enable(sensor->clk);
532 if (ret)
533 return ret;
534
535 ret = stm_thermal_read_factory_settings(sensor);
536 if (ret)
537 goto thermal_unprepare;
538
539 ret = stm_thermal_calibration(sensor);
540 if (ret)
541 goto thermal_unprepare;
542
543 /* Set threshold(s) for IRQ */
544 ret = stm_thermal_set_threshold(sensor);
545 if (ret)
546 goto thermal_unprepare;
547
548 ret = stm_enable_irq(sensor);
549 if (ret)
550 goto thermal_unprepare;
551
552 ret = stm_sensor_power_on(sensor);
553 if (ret) {
554 dev_err(dev, "%s: failed to power on sensor\n", __func__);
555 goto irq_disable;
556 }
557
558 return 0;
559
560irq_disable:
561 stm_disable_irq(sensor);
562
563thermal_unprepare:
564 clk_disable_unprepare(sensor->clk);
565
566 return ret;
567}
568
569#ifdef CONFIG_PM_SLEEP
570static int stm_thermal_suspend(struct device *dev)
571{
572 int ret;
573 struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
574
575 ret = stm_thermal_sensor_off(sensor);
576 if (ret)
577 return ret;
578
579 sensor->mode = THERMAL_DEVICE_DISABLED;
580
581 return 0;
582}
583
584static int stm_thermal_resume(struct device *dev)
585{
586 int ret;
587 struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
588
589 ret = stm_thermal_prepare(sensor);
590 if (ret)
591 return ret;
592
593 sensor->mode = THERMAL_DEVICE_ENABLED;
594
595 return 0;
596}
597#endif /* CONFIG_PM_SLEEP */
598
599SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops, stm_thermal_suspend, stm_thermal_resume);
600
601static const struct thermal_zone_of_device_ops stm_tz_ops = {
602 .get_temp = stm_thermal_get_temp,
603};
604
605static const struct of_device_id stm_thermal_of_match[] = {
606 { .compatible = "st,stm32-thermal"},
607 { /* sentinel */ }
608};
609MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
610
611static int stm_thermal_probe(struct platform_device *pdev)
612{
613 struct stm_thermal_sensor *sensor;
614 struct resource *res;
615 const struct thermal_trip *trip;
616 void __iomem *base;
617 int ret, i;
618
619 if (!pdev->dev.of_node) {
620 dev_err(&pdev->dev, "%s: device tree node not found\n",
621 __func__);
622 return -EINVAL;
623 }
624
625 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
626 if (!sensor)
627 return -ENOMEM;
628
629 platform_set_drvdata(pdev, sensor);
630
631 sensor->dev = &pdev->dev;
632
633 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
634 base = devm_ioremap_resource(&pdev->dev, res);
635 if (IS_ERR(base))
636 return PTR_ERR(base);
637
638 /* Populate sensor */
639 sensor->base = base;
640
641 sensor->clk = devm_clk_get(&pdev->dev, "pclk");
642 if (IS_ERR(sensor->clk)) {
643 dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
644 __func__);
645 return PTR_ERR(sensor->clk);
646 }
647
648 /* Register IRQ into GIC */
649 ret = stm_register_irq(sensor);
650 if (ret)
651 return ret;
652
653 sensor->th_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
654 sensor,
655 &stm_tz_ops);
656
657 if (IS_ERR(sensor->th_dev)) {
658 dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
659 __func__);
660 ret = PTR_ERR(sensor->th_dev);
661 return ret;
662 }
663
664 if (!sensor->th_dev->ops->get_crit_temp) {
665 /* Critical point must be provided */
666 ret = -EINVAL;
667 goto err_tz;
668 }
669
670 ret = sensor->th_dev->ops->get_crit_temp(sensor->th_dev,
671 &sensor->temp_critical);
672 if (ret) {
673 dev_err(&pdev->dev,
674 "Not able to read critical_temp: %d\n", ret);
675 goto err_tz;
676 }
677
678 sensor->temp_critical = celsius(sensor->temp_critical);
679
680 /* Set thresholds for IRQ */
681 sensor->high_temp = sensor->temp_critical;
682
683 trip = of_thermal_get_trip_points(sensor->th_dev);
684 sensor->num_trips = of_thermal_get_ntrips(sensor->th_dev);
685
686 /* Find out passive temperature if it exists */
687 for (i = (sensor->num_trips - 1); i >= 0; i--) {
688 if (trip[i].type == THERMAL_TRIP_PASSIVE) {
689 sensor->temp_passive = celsius(trip[i].temperature);
690 /* Update high temperature threshold */
691 sensor->high_temp = sensor->temp_passive;
692 }
693 }
694
695 /*
696 * Ensure low_temp_enabled flag is disabled.
697 * By disabling low_temp_enabled, low threshold IT will not be
698 * configured neither enabled because it is not needed as high
699 * threshold is set on the lowest temperature trip point after
700 * probe.
701 */
702 sensor->low_temp_enabled = false;
703
704 /* Configure and enable HW sensor */
705 ret = stm_thermal_prepare(sensor);
706 if (ret) {
707 dev_err(&pdev->dev,
708 "Not able to enable sensor: %d\n", ret);
709 goto err_tz;
710 }
711
712 /*
713 * Thermal_zone doesn't enable hwmon as default,
714 * enable it here
715 */
716 sensor->th_dev->tzp->no_hwmon = false;
717 ret = thermal_add_hwmon_sysfs(sensor->th_dev);
718 if (ret)
719 goto err_tz;
720
721 sensor->mode = THERMAL_DEVICE_ENABLED;
722
723 dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
724 __func__);
725
726 return 0;
727
728err_tz:
729 thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
730 return ret;
731}
732
733static int stm_thermal_remove(struct platform_device *pdev)
734{
735 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
736
737 stm_thermal_sensor_off(sensor);
738 thermal_remove_hwmon_sysfs(sensor->th_dev);
739 thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
740
741 return 0;
742}
743
744static struct platform_driver stm_thermal_driver = {
745 .driver = {
746 .name = "stm_thermal",
747 .pm = &stm_thermal_pm_ops,
748 .of_match_table = stm_thermal_of_match,
749 },
750 .probe = stm_thermal_probe,
751 .remove = stm_thermal_remove,
752};
753module_platform_driver(stm_thermal_driver);
754
755MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
756MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
757MODULE_LICENSE("GPL v2");
758MODULE_ALIAS("platform:stm_thermal");