Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  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");