linux/drivers/thermal/imx_thermal.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Copyright 2013 Freescale Semiconductor, Inc.
   4
   5#include <linux/clk.h>
   6#include <linux/cpufreq.h>
   7#include <linux/cpu_cooling.h>
   8#include <linux/delay.h>
   9#include <linux/interrupt.h>
  10#include <linux/io.h>
  11#include <linux/mfd/syscon.h>
  12#include <linux/module.h>
  13#include <linux/of.h>
  14#include <linux/of_device.h>
  15#include <linux/regmap.h>
  16#include <linux/thermal.h>
  17#include <linux/nvmem-consumer.h>
  18
  19#define REG_SET         0x4
  20#define REG_CLR         0x8
  21#define REG_TOG         0xc
  22
  23/* i.MX6 specific */
  24#define IMX6_MISC0                              0x0150
  25#define IMX6_MISC0_REFTOP_SELBIASOFF            (1 << 3)
  26#define IMX6_MISC1                              0x0160
  27#define IMX6_MISC1_IRQ_TEMPHIGH                 (1 << 29)
  28/* Below LOW and PANIC bits are only for TEMPMON_IMX6SX */
  29#define IMX6_MISC1_IRQ_TEMPLOW                  (1 << 28)
  30#define IMX6_MISC1_IRQ_TEMPPANIC                (1 << 27)
  31
  32#define IMX6_TEMPSENSE0                         0x0180
  33#define IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT       20
  34#define IMX6_TEMPSENSE0_ALARM_VALUE_MASK        (0xfff << 20)
  35#define IMX6_TEMPSENSE0_TEMP_CNT_SHIFT          8
  36#define IMX6_TEMPSENSE0_TEMP_CNT_MASK           (0xfff << 8)
  37#define IMX6_TEMPSENSE0_FINISHED                (1 << 2)
  38#define IMX6_TEMPSENSE0_MEASURE_TEMP            (1 << 1)
  39#define IMX6_TEMPSENSE0_POWER_DOWN              (1 << 0)
  40
  41#define IMX6_TEMPSENSE1                         0x0190
  42#define IMX6_TEMPSENSE1_MEASURE_FREQ            0xffff
  43#define IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT      0
  44
  45#define OCOTP_MEM0                      0x0480
  46#define OCOTP_ANA1                      0x04e0
  47
  48/* Below TEMPSENSE2 is only for TEMPMON_IMX6SX */
  49#define IMX6_TEMPSENSE2                         0x0290
  50#define IMX6_TEMPSENSE2_LOW_VALUE_SHIFT         0
  51#define IMX6_TEMPSENSE2_LOW_VALUE_MASK          0xfff
  52#define IMX6_TEMPSENSE2_PANIC_VALUE_SHIFT       16
  53#define IMX6_TEMPSENSE2_PANIC_VALUE_MASK        0xfff0000
  54
  55/* i.MX7 specific */
  56#define IMX7_ANADIG_DIGPROG                     0x800
  57#define IMX7_TEMPSENSE0                         0x300
  58#define IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT       18
  59#define IMX7_TEMPSENSE0_PANIC_ALARM_MASK        (0x1ff << 18)
  60#define IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT        9
  61#define IMX7_TEMPSENSE0_HIGH_ALARM_MASK         (0x1ff << 9)
  62#define IMX7_TEMPSENSE0_LOW_ALARM_SHIFT         0
  63#define IMX7_TEMPSENSE0_LOW_ALARM_MASK          0x1ff
  64
  65#define IMX7_TEMPSENSE1                         0x310
  66#define IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT      16
  67#define IMX7_TEMPSENSE1_MEASURE_FREQ_MASK       (0xffff << 16)
  68#define IMX7_TEMPSENSE1_FINISHED                (1 << 11)
  69#define IMX7_TEMPSENSE1_MEASURE_TEMP            (1 << 10)
  70#define IMX7_TEMPSENSE1_POWER_DOWN              (1 << 9)
  71#define IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT        0
  72#define IMX7_TEMPSENSE1_TEMP_VALUE_MASK         0x1ff
  73
  74/* The driver supports 1 passive trip point and 1 critical trip point */
  75enum imx_thermal_trip {
  76        IMX_TRIP_PASSIVE,
  77        IMX_TRIP_CRITICAL,
  78        IMX_TRIP_NUM,
  79};
  80
  81#define IMX_POLLING_DELAY               2000 /* millisecond */
  82#define IMX_PASSIVE_DELAY               1000
  83
  84#define TEMPMON_IMX6Q                   1
  85#define TEMPMON_IMX6SX                  2
  86#define TEMPMON_IMX7D                   3
  87
  88struct thermal_soc_data {
  89        u32 version;
  90
  91        u32 sensor_ctrl;
  92        u32 power_down_mask;
  93        u32 measure_temp_mask;
  94
  95        u32 measure_freq_ctrl;
  96        u32 measure_freq_mask;
  97        u32 measure_freq_shift;
  98
  99        u32 temp_data;
 100        u32 temp_value_mask;
 101        u32 temp_value_shift;
 102        u32 temp_valid_mask;
 103
 104        u32 panic_alarm_ctrl;
 105        u32 panic_alarm_mask;
 106        u32 panic_alarm_shift;
 107
 108        u32 high_alarm_ctrl;
 109        u32 high_alarm_mask;
 110        u32 high_alarm_shift;
 111
 112        u32 low_alarm_ctrl;
 113        u32 low_alarm_mask;
 114        u32 low_alarm_shift;
 115};
 116
 117static struct thermal_soc_data thermal_imx6q_data = {
 118        .version = TEMPMON_IMX6Q,
 119
 120        .sensor_ctrl = IMX6_TEMPSENSE0,
 121        .power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
 122        .measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
 123
 124        .measure_freq_ctrl = IMX6_TEMPSENSE1,
 125        .measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
 126        .measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
 127
 128        .temp_data = IMX6_TEMPSENSE0,
 129        .temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
 130        .temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
 131        .temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
 132
 133        .high_alarm_ctrl = IMX6_TEMPSENSE0,
 134        .high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
 135        .high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
 136};
 137
 138static struct thermal_soc_data thermal_imx6sx_data = {
 139        .version = TEMPMON_IMX6SX,
 140
 141        .sensor_ctrl = IMX6_TEMPSENSE0,
 142        .power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
 143        .measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
 144
 145        .measure_freq_ctrl = IMX6_TEMPSENSE1,
 146        .measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
 147        .measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
 148
 149        .temp_data = IMX6_TEMPSENSE0,
 150        .temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
 151        .temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
 152        .temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
 153
 154        .high_alarm_ctrl = IMX6_TEMPSENSE0,
 155        .high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
 156        .high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
 157
 158        .panic_alarm_ctrl = IMX6_TEMPSENSE2,
 159        .panic_alarm_mask = IMX6_TEMPSENSE2_PANIC_VALUE_MASK,
 160        .panic_alarm_shift = IMX6_TEMPSENSE2_PANIC_VALUE_SHIFT,
 161
 162        .low_alarm_ctrl = IMX6_TEMPSENSE2,
 163        .low_alarm_mask = IMX6_TEMPSENSE2_LOW_VALUE_MASK,
 164        .low_alarm_shift = IMX6_TEMPSENSE2_LOW_VALUE_SHIFT,
 165};
 166
 167static struct thermal_soc_data thermal_imx7d_data = {
 168        .version = TEMPMON_IMX7D,
 169
 170        .sensor_ctrl = IMX7_TEMPSENSE1,
 171        .power_down_mask = IMX7_TEMPSENSE1_POWER_DOWN,
 172        .measure_temp_mask = IMX7_TEMPSENSE1_MEASURE_TEMP,
 173
 174        .measure_freq_ctrl = IMX7_TEMPSENSE1,
 175        .measure_freq_shift = IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT,
 176        .measure_freq_mask = IMX7_TEMPSENSE1_MEASURE_FREQ_MASK,
 177
 178        .temp_data = IMX7_TEMPSENSE1,
 179        .temp_value_mask = IMX7_TEMPSENSE1_TEMP_VALUE_MASK,
 180        .temp_value_shift = IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT,
 181        .temp_valid_mask = IMX7_TEMPSENSE1_FINISHED,
 182
 183        .panic_alarm_ctrl = IMX7_TEMPSENSE1,
 184        .panic_alarm_mask = IMX7_TEMPSENSE0_PANIC_ALARM_MASK,
 185        .panic_alarm_shift = IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT,
 186
 187        .high_alarm_ctrl = IMX7_TEMPSENSE0,
 188        .high_alarm_mask = IMX7_TEMPSENSE0_HIGH_ALARM_MASK,
 189        .high_alarm_shift = IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT,
 190
 191        .low_alarm_ctrl = IMX7_TEMPSENSE0,
 192        .low_alarm_mask = IMX7_TEMPSENSE0_LOW_ALARM_MASK,
 193        .low_alarm_shift = IMX7_TEMPSENSE0_LOW_ALARM_SHIFT,
 194};
 195
 196struct imx_thermal_data {
 197        struct cpufreq_policy *policy;
 198        struct thermal_zone_device *tz;
 199        struct thermal_cooling_device *cdev;
 200        enum thermal_device_mode mode;
 201        struct regmap *tempmon;
 202        u32 c1, c2; /* See formula in imx_init_calib() */
 203        int temp_passive;
 204        int temp_critical;
 205        int temp_max;
 206        int alarm_temp;
 207        int last_temp;
 208        bool irq_enabled;
 209        int irq;
 210        struct clk *thermal_clk;
 211        const struct thermal_soc_data *socdata;
 212        const char *temp_grade;
 213};
 214
 215static void imx_set_panic_temp(struct imx_thermal_data *data,
 216                               int panic_temp)
 217{
 218        const struct thermal_soc_data *soc_data = data->socdata;
 219        struct regmap *map = data->tempmon;
 220        int critical_value;
 221
 222        critical_value = (data->c2 - panic_temp) / data->c1;
 223
 224        regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
 225                     soc_data->panic_alarm_mask);
 226        regmap_write(map, soc_data->panic_alarm_ctrl + REG_SET,
 227                     critical_value << soc_data->panic_alarm_shift);
 228}
 229
 230static void imx_set_alarm_temp(struct imx_thermal_data *data,
 231                               int alarm_temp)
 232{
 233        struct regmap *map = data->tempmon;
 234        const struct thermal_soc_data *soc_data = data->socdata;
 235        int alarm_value;
 236
 237        data->alarm_temp = alarm_temp;
 238
 239        if (data->socdata->version == TEMPMON_IMX7D)
 240                alarm_value = alarm_temp / 1000 + data->c1 - 25;
 241        else
 242                alarm_value = (data->c2 - alarm_temp) / data->c1;
 243
 244        regmap_write(map, soc_data->high_alarm_ctrl + REG_CLR,
 245                     soc_data->high_alarm_mask);
 246        regmap_write(map, soc_data->high_alarm_ctrl + REG_SET,
 247                     alarm_value << soc_data->high_alarm_shift);
 248}
 249
 250static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
 251{
 252        struct imx_thermal_data *data = tz->devdata;
 253        const struct thermal_soc_data *soc_data = data->socdata;
 254        struct regmap *map = data->tempmon;
 255        unsigned int n_meas;
 256        bool wait;
 257        u32 val;
 258
 259        if (data->mode == THERMAL_DEVICE_ENABLED) {
 260                /* Check if a measurement is currently in progress */
 261                regmap_read(map, soc_data->temp_data, &val);
 262                wait = !(val & soc_data->temp_valid_mask);
 263        } else {
 264                /*
 265                 * Every time we measure the temperature, we will power on the
 266                 * temperature sensor, enable measurements, take a reading,
 267                 * disable measurements, power off the temperature sensor.
 268                 */
 269                regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
 270                            soc_data->power_down_mask);
 271                regmap_write(map, soc_data->sensor_ctrl + REG_SET,
 272                            soc_data->measure_temp_mask);
 273
 274                wait = true;
 275        }
 276
 277        /*
 278         * According to the temp sensor designers, it may require up to ~17us
 279         * to complete a measurement.
 280         */
 281        if (wait)
 282                usleep_range(20, 50);
 283
 284        regmap_read(map, soc_data->temp_data, &val);
 285
 286        if (data->mode != THERMAL_DEVICE_ENABLED) {
 287                regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
 288                             soc_data->measure_temp_mask);
 289                regmap_write(map, soc_data->sensor_ctrl + REG_SET,
 290                             soc_data->power_down_mask);
 291        }
 292
 293        if ((val & soc_data->temp_valid_mask) == 0) {
 294                dev_dbg(&tz->device, "temp measurement never finished\n");
 295                return -EAGAIN;
 296        }
 297
 298        n_meas = (val & soc_data->temp_value_mask)
 299                >> soc_data->temp_value_shift;
 300
 301        /* See imx_init_calib() for formula derivation */
 302        if (data->socdata->version == TEMPMON_IMX7D)
 303                *temp = (n_meas - data->c1 + 25) * 1000;
 304        else
 305                *temp = data->c2 - n_meas * data->c1;
 306
 307        /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
 308        if (data->socdata->version == TEMPMON_IMX6Q) {
 309                if (data->alarm_temp == data->temp_passive &&
 310                        *temp >= data->temp_passive)
 311                        imx_set_alarm_temp(data, data->temp_critical);
 312                if (data->alarm_temp == data->temp_critical &&
 313                        *temp < data->temp_passive) {
 314                        imx_set_alarm_temp(data, data->temp_passive);
 315                        dev_dbg(&tz->device, "thermal alarm off: T < %d\n",
 316                                data->alarm_temp / 1000);
 317                }
 318        }
 319
 320        if (*temp != data->last_temp) {
 321                dev_dbg(&tz->device, "millicelsius: %d\n", *temp);
 322                data->last_temp = *temp;
 323        }
 324
 325        /* Reenable alarm IRQ if temperature below alarm temperature */
 326        if (!data->irq_enabled && *temp < data->alarm_temp) {
 327                data->irq_enabled = true;
 328                enable_irq(data->irq);
 329        }
 330
 331        return 0;
 332}
 333
 334static int imx_get_mode(struct thermal_zone_device *tz,
 335                        enum thermal_device_mode *mode)
 336{
 337        struct imx_thermal_data *data = tz->devdata;
 338
 339        *mode = data->mode;
 340
 341        return 0;
 342}
 343
 344static int imx_set_mode(struct thermal_zone_device *tz,
 345                        enum thermal_device_mode mode)
 346{
 347        struct imx_thermal_data *data = tz->devdata;
 348        struct regmap *map = data->tempmon;
 349        const struct thermal_soc_data *soc_data = data->socdata;
 350
 351        if (mode == THERMAL_DEVICE_ENABLED) {
 352                tz->polling_delay = IMX_POLLING_DELAY;
 353                tz->passive_delay = IMX_PASSIVE_DELAY;
 354
 355                regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
 356                             soc_data->power_down_mask);
 357                regmap_write(map, soc_data->sensor_ctrl + REG_SET,
 358                             soc_data->measure_temp_mask);
 359
 360                if (!data->irq_enabled) {
 361                        data->irq_enabled = true;
 362                        enable_irq(data->irq);
 363                }
 364        } else {
 365                regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
 366                             soc_data->measure_temp_mask);
 367                regmap_write(map, soc_data->sensor_ctrl + REG_SET,
 368                             soc_data->power_down_mask);
 369
 370                tz->polling_delay = 0;
 371                tz->passive_delay = 0;
 372
 373                if (data->irq_enabled) {
 374                        disable_irq(data->irq);
 375                        data->irq_enabled = false;
 376                }
 377        }
 378
 379        data->mode = mode;
 380        thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
 381
 382        return 0;
 383}
 384
 385static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
 386                             enum thermal_trip_type *type)
 387{
 388        *type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE :
 389                                             THERMAL_TRIP_CRITICAL;
 390        return 0;
 391}
 392
 393static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp)
 394{
 395        struct imx_thermal_data *data = tz->devdata;
 396
 397        *temp = data->temp_critical;
 398        return 0;
 399}
 400
 401static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
 402                             int *temp)
 403{
 404        struct imx_thermal_data *data = tz->devdata;
 405
 406        *temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
 407                                             data->temp_critical;
 408        return 0;
 409}
 410
 411static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
 412                             int temp)
 413{
 414        struct imx_thermal_data *data = tz->devdata;
 415
 416        /* do not allow changing critical threshold */
 417        if (trip == IMX_TRIP_CRITICAL)
 418                return -EPERM;
 419
 420        /* do not allow passive to be set higher than critical */
 421        if (temp < 0 || temp > data->temp_critical)
 422                return -EINVAL;
 423
 424        data->temp_passive = temp;
 425
 426        imx_set_alarm_temp(data, temp);
 427
 428        return 0;
 429}
 430
 431static int imx_bind(struct thermal_zone_device *tz,
 432                    struct thermal_cooling_device *cdev)
 433{
 434        int ret;
 435
 436        ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev,
 437                                               THERMAL_NO_LIMIT,
 438                                               THERMAL_NO_LIMIT,
 439                                               THERMAL_WEIGHT_DEFAULT);
 440        if (ret) {
 441                dev_err(&tz->device,
 442                        "binding zone %s with cdev %s failed:%d\n",
 443                        tz->type, cdev->type, ret);
 444                return ret;
 445        }
 446
 447        return 0;
 448}
 449
 450static int imx_unbind(struct thermal_zone_device *tz,
 451                      struct thermal_cooling_device *cdev)
 452{
 453        int ret;
 454
 455        ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev);
 456        if (ret) {
 457                dev_err(&tz->device,
 458                        "unbinding zone %s with cdev %s failed:%d\n",
 459                        tz->type, cdev->type, ret);
 460                return ret;
 461        }
 462
 463        return 0;
 464}
 465
 466static struct thermal_zone_device_ops imx_tz_ops = {
 467        .bind = imx_bind,
 468        .unbind = imx_unbind,
 469        .get_temp = imx_get_temp,
 470        .get_mode = imx_get_mode,
 471        .set_mode = imx_set_mode,
 472        .get_trip_type = imx_get_trip_type,
 473        .get_trip_temp = imx_get_trip_temp,
 474        .get_crit_temp = imx_get_crit_temp,
 475        .set_trip_temp = imx_set_trip_temp,
 476};
 477
 478static int imx_init_calib(struct platform_device *pdev, u32 ocotp_ana1)
 479{
 480        struct imx_thermal_data *data = platform_get_drvdata(pdev);
 481        int n1;
 482        u64 temp64;
 483
 484        if (ocotp_ana1 == 0 || ocotp_ana1 == ~0) {
 485                dev_err(&pdev->dev, "invalid sensor calibration data\n");
 486                return -EINVAL;
 487        }
 488
 489        /*
 490         * On i.MX7D, we only use the calibration data at 25C to get the temp,
 491         * Tmeas = ( Nmeas - n1) + 25; n1 is the fuse value for 25C.
 492         */
 493        if (data->socdata->version == TEMPMON_IMX7D) {
 494                data->c1 = (ocotp_ana1 >> 9) & 0x1ff;
 495                return 0;
 496        }
 497
 498        /*
 499         * The sensor is calibrated at 25 °C (aka T1) and the value measured
 500         * (aka N1) at this temperature is provided in bits [31:20] in the
 501         * i.MX's OCOTP value ANA1.
 502         * To find the actual temperature T, the following formula has to be used
 503         * when reading value n from the sensor:
 504         *
 505         * T = T1 + (N - N1) / (0.4148468 - 0.0015423 * N1) °C + 3.580661 °C
 506         *   = [T1' - N1 / (0.4148468 - 0.0015423 * N1) °C] + N / (0.4148468 - 0.0015423 * N1) °C
 507         *   = [T1' + N1 / (0.0015423 * N1 - 0.4148468) °C] - N / (0.0015423 * N1 - 0.4148468) °C
 508         *   = c2 - c1 * N
 509         *
 510         * with
 511         *
 512         *  T1' = 28.580661 °C
 513         *   c1 = 1 / (0.0015423 * N1 - 0.4297157) °C
 514         *   c2 = T1' + N1 / (0.0015423 * N1 - 0.4148468) °C
 515         *      = T1' + N1 * c1
 516         */
 517        n1 = ocotp_ana1 >> 20;
 518
 519        temp64 = 10000000; /* use 10^7 as fixed point constant for values in formula */
 520        temp64 *= 1000; /* to get result in °mC */
 521        do_div(temp64, 15423 * n1 - 4148468);
 522        data->c1 = temp64;
 523        data->c2 = n1 * data->c1 + 28581;
 524
 525        return 0;
 526}
 527
 528static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
 529{
 530        struct imx_thermal_data *data = platform_get_drvdata(pdev);
 531
 532        /* The maximum die temp is specified by the Temperature Grade */
 533        switch ((ocotp_mem0 >> 6) & 0x3) {
 534        case 0: /* Commercial (0 to 95 °C) */
 535                data->temp_grade = "Commercial";
 536                data->temp_max = 95000;
 537                break;
 538        case 1: /* Extended Commercial (-20 °C to 105 °C) */
 539                data->temp_grade = "Extended Commercial";
 540                data->temp_max = 105000;
 541                break;
 542        case 2: /* Industrial (-40 °C to 105 °C) */
 543                data->temp_grade = "Industrial";
 544                data->temp_max = 105000;
 545                break;
 546        case 3: /* Automotive (-40 °C to 125 °C) */
 547                data->temp_grade = "Automotive";
 548                data->temp_max = 125000;
 549                break;
 550        }
 551
 552        /*
 553         * Set the critical trip point at 5 °C under max
 554         * Set the passive trip point at 10 °C under max (changeable via sysfs)
 555         */
 556        data->temp_critical = data->temp_max - (1000 * 5);
 557        data->temp_passive = data->temp_max - (1000 * 10);
 558}
 559
 560static int imx_init_from_tempmon_data(struct platform_device *pdev)
 561{
 562        struct regmap *map;
 563        int ret;
 564        u32 val;
 565
 566        map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 567                                              "fsl,tempmon-data");
 568        if (IS_ERR(map)) {
 569                ret = PTR_ERR(map);
 570                dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
 571                return ret;
 572        }
 573
 574        ret = regmap_read(map, OCOTP_ANA1, &val);
 575        if (ret) {
 576                dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
 577                return ret;
 578        }
 579        ret = imx_init_calib(pdev, val);
 580        if (ret)
 581                return ret;
 582
 583        ret = regmap_read(map, OCOTP_MEM0, &val);
 584        if (ret) {
 585                dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
 586                return ret;
 587        }
 588        imx_init_temp_grade(pdev, val);
 589
 590        return 0;
 591}
 592
 593static int imx_init_from_nvmem_cells(struct platform_device *pdev)
 594{
 595        int ret;
 596        u32 val;
 597
 598        ret = nvmem_cell_read_u32(&pdev->dev, "calib", &val);
 599        if (ret)
 600                return ret;
 601
 602        ret = imx_init_calib(pdev, val);
 603        if (ret)
 604                return ret;
 605
 606        ret = nvmem_cell_read_u32(&pdev->dev, "temp_grade", &val);
 607        if (ret)
 608                return ret;
 609        imx_init_temp_grade(pdev, val);
 610
 611        return 0;
 612}
 613
 614static irqreturn_t imx_thermal_alarm_irq(int irq, void *dev)
 615{
 616        struct imx_thermal_data *data = dev;
 617
 618        disable_irq_nosync(irq);
 619        data->irq_enabled = false;
 620
 621        return IRQ_WAKE_THREAD;
 622}
 623
 624static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
 625{
 626        struct imx_thermal_data *data = dev;
 627
 628        dev_dbg(&data->tz->device, "THERMAL ALARM: T > %d\n",
 629                data->alarm_temp / 1000);
 630
 631        thermal_zone_device_update(data->tz, THERMAL_EVENT_UNSPECIFIED);
 632
 633        return IRQ_HANDLED;
 634}
 635
 636static const struct of_device_id of_imx_thermal_match[] = {
 637        { .compatible = "fsl,imx6q-tempmon", .data = &thermal_imx6q_data, },
 638        { .compatible = "fsl,imx6sx-tempmon", .data = &thermal_imx6sx_data, },
 639        { .compatible = "fsl,imx7d-tempmon", .data = &thermal_imx7d_data, },
 640        { /* end */ }
 641};
 642MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
 643
 644#ifdef CONFIG_CPU_FREQ
 645/*
 646 * Create cooling device in case no #cooling-cells property is available in
 647 * CPU node
 648 */
 649static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
 650{
 651        struct device_node *np;
 652        int ret = 0;
 653
 654        data->policy = cpufreq_cpu_get(0);
 655        if (!data->policy) {
 656                pr_debug("%s: CPUFreq policy not found\n", __func__);
 657                return -EPROBE_DEFER;
 658        }
 659
 660        np = of_get_cpu_node(data->policy->cpu, NULL);
 661
 662        if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
 663                data->cdev = cpufreq_cooling_register(data->policy);
 664                if (IS_ERR(data->cdev)) {
 665                        ret = PTR_ERR(data->cdev);
 666                        cpufreq_cpu_put(data->policy);
 667                }
 668        }
 669
 670        of_node_put(np);
 671
 672        return ret;
 673}
 674
 675static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
 676{
 677        cpufreq_cooling_unregister(data->cdev);
 678        cpufreq_cpu_put(data->policy);
 679}
 680
 681#else
 682
 683static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
 684{
 685        return 0;
 686}
 687
 688static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
 689{
 690}
 691#endif
 692
 693static int imx_thermal_probe(struct platform_device *pdev)
 694{
 695        struct imx_thermal_data *data;
 696        struct regmap *map;
 697        int measure_freq;
 698        int ret;
 699
 700        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 701        if (!data)
 702                return -ENOMEM;
 703
 704        map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
 705        if (IS_ERR(map)) {
 706                ret = PTR_ERR(map);
 707                dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
 708                return ret;
 709        }
 710        data->tempmon = map;
 711
 712        data->socdata = of_device_get_match_data(&pdev->dev);
 713        if (!data->socdata) {
 714                dev_err(&pdev->dev, "no device match found\n");
 715                return -ENODEV;
 716        }
 717
 718        /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */
 719        if (data->socdata->version == TEMPMON_IMX6SX) {
 720                regmap_write(map, IMX6_MISC1 + REG_CLR,
 721                        IMX6_MISC1_IRQ_TEMPHIGH | IMX6_MISC1_IRQ_TEMPLOW
 722                        | IMX6_MISC1_IRQ_TEMPPANIC);
 723                /*
 724                 * reset value of LOW ALARM is incorrect, set it to lowest
 725                 * value to avoid false trigger of low alarm.
 726                 */
 727                regmap_write(map, data->socdata->low_alarm_ctrl + REG_SET,
 728                             data->socdata->low_alarm_mask);
 729        }
 730
 731        data->irq = platform_get_irq(pdev, 0);
 732        if (data->irq < 0)
 733                return data->irq;
 734
 735        platform_set_drvdata(pdev, data);
 736
 737        if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
 738                ret = imx_init_from_nvmem_cells(pdev);
 739                if (ret) {
 740                        if (ret == -EPROBE_DEFER)
 741                                return ret;
 742
 743                        dev_err(&pdev->dev, "failed to init from nvmem: %d\n",
 744                                ret);
 745                        return ret;
 746                }
 747        } else {
 748                ret = imx_init_from_tempmon_data(pdev);
 749                if (ret) {
 750                        dev_err(&pdev->dev, "failed to init from fsl,tempmon-data\n");
 751                        return ret;
 752                }
 753        }
 754
 755        /* Make sure sensor is in known good state for measurements */
 756        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 757                     data->socdata->power_down_mask);
 758        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 759                     data->socdata->measure_temp_mask);
 760        regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
 761                     data->socdata->measure_freq_mask);
 762        if (data->socdata->version != TEMPMON_IMX7D)
 763                regmap_write(map, IMX6_MISC0 + REG_SET,
 764                        IMX6_MISC0_REFTOP_SELBIASOFF);
 765        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 766                     data->socdata->power_down_mask);
 767
 768        ret = imx_thermal_register_legacy_cooling(data);
 769        if (ret) {
 770                if (ret == -EPROBE_DEFER)
 771                        return ret;
 772
 773                dev_err(&pdev->dev,
 774                        "failed to register cpufreq cooling device: %d\n", ret);
 775                return ret;
 776        }
 777
 778        data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
 779        if (IS_ERR(data->thermal_clk)) {
 780                ret = PTR_ERR(data->thermal_clk);
 781                if (ret != -EPROBE_DEFER)
 782                        dev_err(&pdev->dev,
 783                                "failed to get thermal clk: %d\n", ret);
 784                goto legacy_cleanup;
 785        }
 786
 787        /*
 788         * Thermal sensor needs clk on to get correct value, normally
 789         * we should enable its clk before taking measurement and disable
 790         * clk after measurement is done, but if alarm function is enabled,
 791         * hardware will auto measure the temperature periodically, so we
 792         * need to keep the clk always on for alarm function.
 793         */
 794        ret = clk_prepare_enable(data->thermal_clk);
 795        if (ret) {
 796                dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
 797                goto legacy_cleanup;
 798        }
 799
 800        data->tz = thermal_zone_device_register("imx_thermal_zone",
 801                                                IMX_TRIP_NUM,
 802                                                BIT(IMX_TRIP_PASSIVE), data,
 803                                                &imx_tz_ops, NULL,
 804                                                IMX_PASSIVE_DELAY,
 805                                                IMX_POLLING_DELAY);
 806        if (IS_ERR(data->tz)) {
 807                ret = PTR_ERR(data->tz);
 808                dev_err(&pdev->dev,
 809                        "failed to register thermal zone device %d\n", ret);
 810                goto clk_disable;
 811        }
 812
 813        dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
 814                 " critical:%dC passive:%dC\n", data->temp_grade,
 815                 data->temp_max / 1000, data->temp_critical / 1000,
 816                 data->temp_passive / 1000);
 817
 818        /* Enable measurements at ~ 10 Hz */
 819        regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
 820                     data->socdata->measure_freq_mask);
 821        measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
 822        regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET,
 823                     measure_freq << data->socdata->measure_freq_shift);
 824        imx_set_alarm_temp(data, data->temp_passive);
 825
 826        if (data->socdata->version == TEMPMON_IMX6SX)
 827                imx_set_panic_temp(data, data->temp_critical);
 828
 829        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 830                     data->socdata->power_down_mask);
 831        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 832                     data->socdata->measure_temp_mask);
 833
 834        data->irq_enabled = true;
 835        data->mode = THERMAL_DEVICE_ENABLED;
 836
 837        ret = devm_request_threaded_irq(&pdev->dev, data->irq,
 838                        imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
 839                        0, "imx_thermal", data);
 840        if (ret < 0) {
 841                dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
 842                goto thermal_zone_unregister;
 843        }
 844
 845        return 0;
 846
 847thermal_zone_unregister:
 848        thermal_zone_device_unregister(data->tz);
 849clk_disable:
 850        clk_disable_unprepare(data->thermal_clk);
 851legacy_cleanup:
 852        imx_thermal_unregister_legacy_cooling(data);
 853
 854        return ret;
 855}
 856
 857static int imx_thermal_remove(struct platform_device *pdev)
 858{
 859        struct imx_thermal_data *data = platform_get_drvdata(pdev);
 860        struct regmap *map = data->tempmon;
 861
 862        /* Disable measurements */
 863        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 864                     data->socdata->power_down_mask);
 865        if (!IS_ERR(data->thermal_clk))
 866                clk_disable_unprepare(data->thermal_clk);
 867
 868        thermal_zone_device_unregister(data->tz);
 869        imx_thermal_unregister_legacy_cooling(data);
 870
 871        return 0;
 872}
 873
 874static int __maybe_unused imx_thermal_suspend(struct device *dev)
 875{
 876        struct imx_thermal_data *data = dev_get_drvdata(dev);
 877        struct regmap *map = data->tempmon;
 878
 879        /*
 880         * Need to disable thermal sensor, otherwise, when thermal core
 881         * try to get temperature before thermal sensor resume, a wrong
 882         * temperature will be read as the thermal sensor is powered
 883         * down.
 884         */
 885        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 886                     data->socdata->measure_temp_mask);
 887        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 888                     data->socdata->power_down_mask);
 889        data->mode = THERMAL_DEVICE_DISABLED;
 890        clk_disable_unprepare(data->thermal_clk);
 891
 892        return 0;
 893}
 894
 895static int __maybe_unused imx_thermal_resume(struct device *dev)
 896{
 897        struct imx_thermal_data *data = dev_get_drvdata(dev);
 898        struct regmap *map = data->tempmon;
 899        int ret;
 900
 901        ret = clk_prepare_enable(data->thermal_clk);
 902        if (ret)
 903                return ret;
 904        /* Enabled thermal sensor after resume */
 905        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 906                     data->socdata->power_down_mask);
 907        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 908                     data->socdata->measure_temp_mask);
 909        data->mode = THERMAL_DEVICE_ENABLED;
 910
 911        return 0;
 912}
 913
 914static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops,
 915                         imx_thermal_suspend, imx_thermal_resume);
 916
 917static struct platform_driver imx_thermal = {
 918        .driver = {
 919                .name   = "imx_thermal",
 920                .pm     = &imx_thermal_pm_ops,
 921                .of_match_table = of_imx_thermal_match,
 922        },
 923        .probe          = imx_thermal_probe,
 924        .remove         = imx_thermal_remove,
 925};
 926module_platform_driver(imx_thermal);
 927
 928MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 929MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs");
 930MODULE_LICENSE("GPL v2");
 931MODULE_ALIAS("platform:imx-thermal");
 932