linux/drivers/thermal/st/stm_thermal.c
<<
>>
Prefs
   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        int ret;
 450        struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
 451
 452        ret = stm_thermal_sensor_off(sensor);
 453        if (ret)
 454                return ret;
 455
 456        return 0;
 457}
 458
 459static int stm_thermal_resume(struct device *dev)
 460{
 461        int ret;
 462        struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
 463
 464        ret = stm_thermal_prepare(sensor);
 465        if (ret)
 466                return ret;
 467
 468        ret = stm_sensor_power_on(sensor);
 469        if (ret)
 470                return ret;
 471
 472        thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
 473        stm_enable_irq(sensor);
 474
 475        return 0;
 476}
 477#endif /* CONFIG_PM_SLEEP */
 478
 479static SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops,
 480                         stm_thermal_suspend, stm_thermal_resume);
 481
 482static const struct thermal_zone_of_device_ops stm_tz_ops = {
 483        .get_temp       = stm_thermal_get_temp,
 484        .set_trips      = stm_thermal_set_trips,
 485};
 486
 487static const struct of_device_id stm_thermal_of_match[] = {
 488                { .compatible = "st,stm32-thermal"},
 489        { /* sentinel */ }
 490};
 491MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
 492
 493static int stm_thermal_probe(struct platform_device *pdev)
 494{
 495        struct stm_thermal_sensor *sensor;
 496        struct resource *res;
 497        void __iomem *base;
 498        int ret;
 499
 500        if (!pdev->dev.of_node) {
 501                dev_err(&pdev->dev, "%s: device tree node not found\n",
 502                        __func__);
 503                return -EINVAL;
 504        }
 505
 506        sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
 507        if (!sensor)
 508                return -ENOMEM;
 509
 510        platform_set_drvdata(pdev, sensor);
 511
 512        sensor->dev = &pdev->dev;
 513
 514        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 515        base = devm_ioremap_resource(&pdev->dev, res);
 516        if (IS_ERR(base))
 517                return PTR_ERR(base);
 518
 519        /* Populate sensor */
 520        sensor->base = base;
 521
 522        sensor->clk = devm_clk_get(&pdev->dev, "pclk");
 523        if (IS_ERR(sensor->clk)) {
 524                dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
 525                        __func__);
 526                return PTR_ERR(sensor->clk);
 527        }
 528
 529        stm_disable_irq(sensor);
 530
 531        /* Clear irq flags */
 532        writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
 533
 534        /* Configure and enable HW sensor */
 535        ret = stm_thermal_prepare(sensor);
 536        if (ret) {
 537                dev_err(&pdev->dev, "Error prepare sensor: %d\n", ret);
 538                return ret;
 539        }
 540
 541        ret = stm_sensor_power_on(sensor);
 542        if (ret) {
 543                dev_err(&pdev->dev, "Error power on sensor: %d\n", ret);
 544                return ret;
 545        }
 546
 547        sensor->th_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
 548                                                              sensor,
 549                                                              &stm_tz_ops);
 550
 551        if (IS_ERR(sensor->th_dev)) {
 552                dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
 553                        __func__);
 554                ret = PTR_ERR(sensor->th_dev);
 555                return ret;
 556        }
 557
 558        /* Register IRQ into GIC */
 559        ret = stm_register_irq(sensor);
 560        if (ret)
 561                goto err_tz;
 562
 563        stm_enable_irq(sensor);
 564
 565        /*
 566         * Thermal_zone doesn't enable hwmon as default,
 567         * enable it here
 568         */
 569        sensor->th_dev->tzp->no_hwmon = false;
 570        ret = thermal_add_hwmon_sysfs(sensor->th_dev);
 571        if (ret)
 572                goto err_tz;
 573
 574        dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
 575                 __func__);
 576
 577        return 0;
 578
 579err_tz:
 580        thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
 581        return ret;
 582}
 583
 584static int stm_thermal_remove(struct platform_device *pdev)
 585{
 586        struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
 587
 588        stm_thermal_sensor_off(sensor);
 589        thermal_remove_hwmon_sysfs(sensor->th_dev);
 590        thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
 591
 592        return 0;
 593}
 594
 595static struct platform_driver stm_thermal_driver = {
 596        .driver = {
 597                .name   = "stm_thermal",
 598                .pm     = &stm_thermal_pm_ops,
 599                .of_match_table = stm_thermal_of_match,
 600        },
 601        .probe          = stm_thermal_probe,
 602        .remove         = stm_thermal_remove,
 603};
 604module_platform_driver(stm_thermal_driver);
 605
 606MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
 607MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
 608MODULE_LICENSE("GPL v2");
 609MODULE_ALIAS("platform:stm_thermal");
 610