cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

stm_thermal.c (14597B)


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