593 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved4 * Author: David Hernandez Sanchez <david.hernandezsanchez@st.com> for5 * 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 0x024#define DTS_T0VALR1_OFFSET 0x825#define DTS_RAMPVALR_OFFSET 0X1026#define DTS_ITR1_OFFSET 0x1427#define DTS_DR_OFFSET 0x1C28#define DTS_SR_OFFSET 0x2029#define DTS_ITENR_OFFSET 0x2430#define DTS_ICIFR_OFFSET 0x2831 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 1659#define TS1_HITTHD_POS 1660#define TS1_LITTHD_POS 061#define HSREF_CLK_DIV_POS 2462 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_SEL68#define Q_MEAS_OPT BIT(21)69#define CALIBRATION_CONTROL Q_MEAS_OPT70 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 10079#define ONE_MHZ 100000080#define POLL_TIMEOUT 500081#define STARTUP_TIME 4082#define TS1_T0_VAL0 30000 /* 30 celsius */83#define TS1_T0_VAL1 130000 /* 130 celsius */84#define NO_HW_TRIG 085#define SAMPLING_TIME 1586 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 in151 * DTS_CFGRx register. It requires a startup time of152 * 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 else249 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 framework316 * 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 here556 */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_new = 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");593