Linux Audio

Check our new training course

Loading...
v6.13.7
  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");
v5.4
  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");