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        struct regmap *tempmon;
 201        u32 c1, c2; /* See formula in imx_init_calib() */
 202        int temp_passive;
 203        int temp_critical;
 204        int temp_max;
 205        int alarm_temp;
 206        int last_temp;
 207        bool irq_enabled;
 208        int irq;
 209        struct clk *thermal_clk;
 210        const struct thermal_soc_data *socdata;
 211        const char *temp_grade;
 212};
 213
 214static void imx_set_panic_temp(struct imx_thermal_data *data,
 215                               int panic_temp)
 216{
 217        const struct thermal_soc_data *soc_data = data->socdata;
 218        struct regmap *map = data->tempmon;
 219        int critical_value;
 220
 221        critical_value = (data->c2 - panic_temp) / data->c1;
 222
 223        regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
 224                     soc_data->panic_alarm_mask);
 225        regmap_write(map, soc_data->panic_alarm_ctrl + REG_SET,
 226                     critical_value << soc_data->panic_alarm_shift);
 227}
 228
 229static void imx_set_alarm_temp(struct imx_thermal_data *data,
 230                               int alarm_temp)
 231{
 232        struct regmap *map = data->tempmon;
 233        const struct thermal_soc_data *soc_data = data->socdata;
 234        int alarm_value;
 235
 236        data->alarm_temp = alarm_temp;
 237
 238        if (data->socdata->version == TEMPMON_IMX7D)
 239                alarm_value = alarm_temp / 1000 + data->c1 - 25;
 240        else
 241                alarm_value = (data->c2 - alarm_temp) / data->c1;
 242
 243        regmap_write(map, soc_data->high_alarm_ctrl + REG_CLR,
 244                     soc_data->high_alarm_mask);
 245        regmap_write(map, soc_data->high_alarm_ctrl + REG_SET,
 246                     alarm_value << soc_data->high_alarm_shift);
 247}
 248
 249static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
 250{
 251        struct imx_thermal_data *data = tz->devdata;
 252        const struct thermal_soc_data *soc_data = data->socdata;
 253        struct regmap *map = data->tempmon;
 254        unsigned int n_meas;
 255        bool wait, run_measurement;
 256        u32 val;
 257
 258        run_measurement = !data->irq_enabled;
 259        if (!run_measurement) {
 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 (run_measurement) {
 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_change_mode(struct thermal_zone_device *tz,
 335                           enum thermal_device_mode mode)
 336{
 337        struct imx_thermal_data *data = tz->devdata;
 338        struct regmap *map = data->tempmon;
 339        const struct thermal_soc_data *soc_data = data->socdata;
 340
 341        if (mode == THERMAL_DEVICE_ENABLED) {
 342                regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
 343                             soc_data->power_down_mask);
 344                regmap_write(map, soc_data->sensor_ctrl + REG_SET,
 345                             soc_data->measure_temp_mask);
 346
 347                if (!data->irq_enabled) {
 348                        data->irq_enabled = true;
 349                        enable_irq(data->irq);
 350                }
 351        } else {
 352                regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
 353                             soc_data->measure_temp_mask);
 354                regmap_write(map, soc_data->sensor_ctrl + REG_SET,
 355                             soc_data->power_down_mask);
 356
 357                if (data->irq_enabled) {
 358                        disable_irq(data->irq);
 359                        data->irq_enabled = false;
 360                }
 361        }
 362
 363        return 0;
 364}
 365
 366static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
 367                             enum thermal_trip_type *type)
 368{
 369        *type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE :
 370                                             THERMAL_TRIP_CRITICAL;
 371        return 0;
 372}
 373
 374static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp)
 375{
 376        struct imx_thermal_data *data = tz->devdata;
 377
 378        *temp = data->temp_critical;
 379        return 0;
 380}
 381
 382static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
 383                             int *temp)
 384{
 385        struct imx_thermal_data *data = tz->devdata;
 386
 387        *temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
 388                                             data->temp_critical;
 389        return 0;
 390}
 391
 392static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
 393                             int temp)
 394{
 395        struct imx_thermal_data *data = tz->devdata;
 396
 397        /* do not allow changing critical threshold */
 398        if (trip == IMX_TRIP_CRITICAL)
 399                return -EPERM;
 400
 401        /* do not allow passive to be set higher than critical */
 402        if (temp < 0 || temp > data->temp_critical)
 403                return -EINVAL;
 404
 405        data->temp_passive = temp;
 406
 407        imx_set_alarm_temp(data, temp);
 408
 409        return 0;
 410}
 411
 412static int imx_bind(struct thermal_zone_device *tz,
 413                    struct thermal_cooling_device *cdev)
 414{
 415        int ret;
 416
 417        ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev,
 418                                               THERMAL_NO_LIMIT,
 419                                               THERMAL_NO_LIMIT,
 420                                               THERMAL_WEIGHT_DEFAULT);
 421        if (ret) {
 422                dev_err(&tz->device,
 423                        "binding zone %s with cdev %s failed:%d\n",
 424                        tz->type, cdev->type, ret);
 425                return ret;
 426        }
 427
 428        return 0;
 429}
 430
 431static int imx_unbind(struct thermal_zone_device *tz,
 432                      struct thermal_cooling_device *cdev)
 433{
 434        int ret;
 435
 436        ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev);
 437        if (ret) {
 438                dev_err(&tz->device,
 439                        "unbinding zone %s with cdev %s failed:%d\n",
 440                        tz->type, cdev->type, ret);
 441                return ret;
 442        }
 443
 444        return 0;
 445}
 446
 447static struct thermal_zone_device_ops imx_tz_ops = {
 448        .bind = imx_bind,
 449        .unbind = imx_unbind,
 450        .get_temp = imx_get_temp,
 451        .change_mode = imx_change_mode,
 452        .get_trip_type = imx_get_trip_type,
 453        .get_trip_temp = imx_get_trip_temp,
 454        .get_crit_temp = imx_get_crit_temp,
 455        .set_trip_temp = imx_set_trip_temp,
 456};
 457
 458static int imx_init_calib(struct platform_device *pdev, u32 ocotp_ana1)
 459{
 460        struct imx_thermal_data *data = platform_get_drvdata(pdev);
 461        int n1;
 462        u64 temp64;
 463
 464        if (ocotp_ana1 == 0 || ocotp_ana1 == ~0) {
 465                dev_err(&pdev->dev, "invalid sensor calibration data\n");
 466                return -EINVAL;
 467        }
 468
 469        /*
 470         * On i.MX7D, we only use the calibration data at 25C to get the temp,
 471         * Tmeas = ( Nmeas - n1) + 25; n1 is the fuse value for 25C.
 472         */
 473        if (data->socdata->version == TEMPMON_IMX7D) {
 474                data->c1 = (ocotp_ana1 >> 9) & 0x1ff;
 475                return 0;
 476        }
 477
 478        /*
 479         * The sensor is calibrated at 25 °C (aka T1) and the value measured
 480         * (aka N1) at this temperature is provided in bits [31:20] in the
 481         * i.MX's OCOTP value ANA1.
 482         * To find the actual temperature T, the following formula has to be used
 483         * when reading value n from the sensor:
 484         *
 485         * T = T1 + (N - N1) / (0.4148468 - 0.0015423 * N1) °C + 3.580661 °C
 486         *   = [T1' - N1 / (0.4148468 - 0.0015423 * N1) °C] + N / (0.4148468 - 0.0015423 * N1) °C
 487         *   = [T1' + N1 / (0.0015423 * N1 - 0.4148468) °C] - N / (0.0015423 * N1 - 0.4148468) °C
 488         *   = c2 - c1 * N
 489         *
 490         * with
 491         *
 492         *  T1' = 28.580661 °C
 493         *   c1 = 1 / (0.0015423 * N1 - 0.4297157) °C
 494         *   c2 = T1' + N1 / (0.0015423 * N1 - 0.4148468) °C
 495         *      = T1' + N1 * c1
 496         */
 497        n1 = ocotp_ana1 >> 20;
 498
 499        temp64 = 10000000; /* use 10^7 as fixed point constant for values in formula */
 500        temp64 *= 1000; /* to get result in °mC */
 501        do_div(temp64, 15423 * n1 - 4148468);
 502        data->c1 = temp64;
 503        data->c2 = n1 * data->c1 + 28581;
 504
 505        return 0;
 506}
 507
 508static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
 509{
 510        struct imx_thermal_data *data = platform_get_drvdata(pdev);
 511
 512        /* The maximum die temp is specified by the Temperature Grade */
 513        switch ((ocotp_mem0 >> 6) & 0x3) {
 514        case 0: /* Commercial (0 to 95 °C) */
 515                data->temp_grade = "Commercial";
 516                data->temp_max = 95000;
 517                break;
 518        case 1: /* Extended Commercial (-20 °C to 105 °C) */
 519                data->temp_grade = "Extended Commercial";
 520                data->temp_max = 105000;
 521                break;
 522        case 2: /* Industrial (-40 °C to 105 °C) */
 523                data->temp_grade = "Industrial";
 524                data->temp_max = 105000;
 525                break;
 526        case 3: /* Automotive (-40 °C to 125 °C) */
 527                data->temp_grade = "Automotive";
 528                data->temp_max = 125000;
 529                break;
 530        }
 531
 532        /*
 533         * Set the critical trip point at 5 °C under max
 534         * Set the passive trip point at 10 °C under max (changeable via sysfs)
 535         */
 536        data->temp_critical = data->temp_max - (1000 * 5);
 537        data->temp_passive = data->temp_max - (1000 * 10);
 538}
 539
 540static int imx_init_from_tempmon_data(struct platform_device *pdev)
 541{
 542        struct regmap *map;
 543        int ret;
 544        u32 val;
 545
 546        map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 547                                              "fsl,tempmon-data");
 548        if (IS_ERR(map)) {
 549                ret = PTR_ERR(map);
 550                dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
 551                return ret;
 552        }
 553
 554        ret = regmap_read(map, OCOTP_ANA1, &val);
 555        if (ret) {
 556                dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
 557                return ret;
 558        }
 559        ret = imx_init_calib(pdev, val);
 560        if (ret)
 561                return ret;
 562
 563        ret = regmap_read(map, OCOTP_MEM0, &val);
 564        if (ret) {
 565                dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
 566                return ret;
 567        }
 568        imx_init_temp_grade(pdev, val);
 569
 570        return 0;
 571}
 572
 573static int imx_init_from_nvmem_cells(struct platform_device *pdev)
 574{
 575        int ret;
 576        u32 val;
 577
 578        ret = nvmem_cell_read_u32(&pdev->dev, "calib", &val);
 579        if (ret)
 580                return ret;
 581
 582        ret = imx_init_calib(pdev, val);
 583        if (ret)
 584                return ret;
 585
 586        ret = nvmem_cell_read_u32(&pdev->dev, "temp_grade", &val);
 587        if (ret)
 588                return ret;
 589        imx_init_temp_grade(pdev, val);
 590
 591        return 0;
 592}
 593
 594static irqreturn_t imx_thermal_alarm_irq(int irq, void *dev)
 595{
 596        struct imx_thermal_data *data = dev;
 597
 598        disable_irq_nosync(irq);
 599        data->irq_enabled = false;
 600
 601        return IRQ_WAKE_THREAD;
 602}
 603
 604static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
 605{
 606        struct imx_thermal_data *data = dev;
 607
 608        dev_dbg(&data->tz->device, "THERMAL ALARM: T > %d\n",
 609                data->alarm_temp / 1000);
 610
 611        thermal_zone_device_update(data->tz, THERMAL_EVENT_UNSPECIFIED);
 612
 613        return IRQ_HANDLED;
 614}
 615
 616static const struct of_device_id of_imx_thermal_match[] = {
 617        { .compatible = "fsl,imx6q-tempmon", .data = &thermal_imx6q_data, },
 618        { .compatible = "fsl,imx6sx-tempmon", .data = &thermal_imx6sx_data, },
 619        { .compatible = "fsl,imx7d-tempmon", .data = &thermal_imx7d_data, },
 620        { /* end */ }
 621};
 622MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
 623
 624#ifdef CONFIG_CPU_FREQ
 625/*
 626 * Create cooling device in case no #cooling-cells property is available in
 627 * CPU node
 628 */
 629static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
 630{
 631        struct device_node *np;
 632        int ret = 0;
 633
 634        data->policy = cpufreq_cpu_get(0);
 635        if (!data->policy) {
 636                pr_debug("%s: CPUFreq policy not found\n", __func__);
 637                return -EPROBE_DEFER;
 638        }
 639
 640        np = of_get_cpu_node(data->policy->cpu, NULL);
 641
 642        if (!np || !of_find_property(np, "#cooling-cells", NULL)) {
 643                data->cdev = cpufreq_cooling_register(data->policy);
 644                if (IS_ERR(data->cdev)) {
 645                        ret = PTR_ERR(data->cdev);
 646                        cpufreq_cpu_put(data->policy);
 647                }
 648        }
 649
 650        of_node_put(np);
 651
 652        return ret;
 653}
 654
 655static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
 656{
 657        cpufreq_cooling_unregister(data->cdev);
 658        cpufreq_cpu_put(data->policy);
 659}
 660
 661#else
 662
 663static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data)
 664{
 665        return 0;
 666}
 667
 668static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data)
 669{
 670}
 671#endif
 672
 673static int imx_thermal_probe(struct platform_device *pdev)
 674{
 675        struct imx_thermal_data *data;
 676        struct regmap *map;
 677        int measure_freq;
 678        int ret;
 679
 680        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 681        if (!data)
 682                return -ENOMEM;
 683
 684        map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
 685        if (IS_ERR(map)) {
 686                ret = PTR_ERR(map);
 687                dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
 688                return ret;
 689        }
 690        data->tempmon = map;
 691
 692        data->socdata = of_device_get_match_data(&pdev->dev);
 693        if (!data->socdata) {
 694                dev_err(&pdev->dev, "no device match found\n");
 695                return -ENODEV;
 696        }
 697
 698        /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */
 699        if (data->socdata->version == TEMPMON_IMX6SX) {
 700                regmap_write(map, IMX6_MISC1 + REG_CLR,
 701                        IMX6_MISC1_IRQ_TEMPHIGH | IMX6_MISC1_IRQ_TEMPLOW
 702                        | IMX6_MISC1_IRQ_TEMPPANIC);
 703                /*
 704                 * reset value of LOW ALARM is incorrect, set it to lowest
 705                 * value to avoid false trigger of low alarm.
 706                 */
 707                regmap_write(map, data->socdata->low_alarm_ctrl + REG_SET,
 708                             data->socdata->low_alarm_mask);
 709        }
 710
 711        data->irq = platform_get_irq(pdev, 0);
 712        if (data->irq < 0)
 713                return data->irq;
 714
 715        platform_set_drvdata(pdev, data);
 716
 717        if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
 718                ret = imx_init_from_nvmem_cells(pdev);
 719                if (ret)
 720                        return dev_err_probe(&pdev->dev, ret,
 721                                             "failed to init from nvmem\n");
 722        } else {
 723                ret = imx_init_from_tempmon_data(pdev);
 724                if (ret) {
 725                        dev_err(&pdev->dev, "failed to init from fsl,tempmon-data\n");
 726                        return ret;
 727                }
 728        }
 729
 730        /* Make sure sensor is in known good state for measurements */
 731        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 732                     data->socdata->power_down_mask);
 733        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 734                     data->socdata->measure_temp_mask);
 735        regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
 736                     data->socdata->measure_freq_mask);
 737        if (data->socdata->version != TEMPMON_IMX7D)
 738                regmap_write(map, IMX6_MISC0 + REG_SET,
 739                        IMX6_MISC0_REFTOP_SELBIASOFF);
 740        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 741                     data->socdata->power_down_mask);
 742
 743        ret = imx_thermal_register_legacy_cooling(data);
 744        if (ret)
 745                return dev_err_probe(&pdev->dev, ret,
 746                                     "failed to register cpufreq cooling device\n");
 747
 748        data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
 749        if (IS_ERR(data->thermal_clk)) {
 750                ret = PTR_ERR(data->thermal_clk);
 751                if (ret != -EPROBE_DEFER)
 752                        dev_err(&pdev->dev,
 753                                "failed to get thermal clk: %d\n", ret);
 754                goto legacy_cleanup;
 755        }
 756
 757        /*
 758         * Thermal sensor needs clk on to get correct value, normally
 759         * we should enable its clk before taking measurement and disable
 760         * clk after measurement is done, but if alarm function is enabled,
 761         * hardware will auto measure the temperature periodically, so we
 762         * need to keep the clk always on for alarm function.
 763         */
 764        ret = clk_prepare_enable(data->thermal_clk);
 765        if (ret) {
 766                dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
 767                goto legacy_cleanup;
 768        }
 769
 770        data->tz = thermal_zone_device_register("imx_thermal_zone",
 771                                                IMX_TRIP_NUM,
 772                                                BIT(IMX_TRIP_PASSIVE), data,
 773                                                &imx_tz_ops, NULL,
 774                                                IMX_PASSIVE_DELAY,
 775                                                IMX_POLLING_DELAY);
 776        if (IS_ERR(data->tz)) {
 777                ret = PTR_ERR(data->tz);
 778                dev_err(&pdev->dev,
 779                        "failed to register thermal zone device %d\n", ret);
 780                goto clk_disable;
 781        }
 782
 783        dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
 784                 " critical:%dC passive:%dC\n", data->temp_grade,
 785                 data->temp_max / 1000, data->temp_critical / 1000,
 786                 data->temp_passive / 1000);
 787
 788        /* Enable measurements at ~ 10 Hz */
 789        regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
 790                     data->socdata->measure_freq_mask);
 791        measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
 792        regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET,
 793                     measure_freq << data->socdata->measure_freq_shift);
 794        imx_set_alarm_temp(data, data->temp_passive);
 795
 796        if (data->socdata->version == TEMPMON_IMX6SX)
 797                imx_set_panic_temp(data, data->temp_critical);
 798
 799        regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
 800                     data->socdata->power_down_mask);
 801        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 802                     data->socdata->measure_temp_mask);
 803
 804        data->irq_enabled = true;
 805        ret = thermal_zone_device_enable(data->tz);
 806        if (ret)
 807                goto thermal_zone_unregister;
 808
 809        ret = devm_request_threaded_irq(&pdev->dev, data->irq,
 810                        imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
 811                        0, "imx_thermal", data);
 812        if (ret < 0) {
 813                dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
 814                goto thermal_zone_unregister;
 815        }
 816
 817        return 0;
 818
 819thermal_zone_unregister:
 820        thermal_zone_device_unregister(data->tz);
 821clk_disable:
 822        clk_disable_unprepare(data->thermal_clk);
 823legacy_cleanup:
 824        imx_thermal_unregister_legacy_cooling(data);
 825
 826        return ret;
 827}
 828
 829static int imx_thermal_remove(struct platform_device *pdev)
 830{
 831        struct imx_thermal_data *data = platform_get_drvdata(pdev);
 832        struct regmap *map = data->tempmon;
 833
 834        /* Disable measurements */
 835        regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
 836                     data->socdata->power_down_mask);
 837        if (!IS_ERR(data->thermal_clk))
 838                clk_disable_unprepare(data->thermal_clk);
 839
 840        thermal_zone_device_unregister(data->tz);
 841        imx_thermal_unregister_legacy_cooling(data);
 842
 843        return 0;
 844}
 845
 846static int __maybe_unused imx_thermal_suspend(struct device *dev)
 847{
 848        struct imx_thermal_data *data = dev_get_drvdata(dev);
 849        int ret;
 850
 851        /*
 852         * Need to disable thermal sensor, otherwise, when thermal core
 853         * try to get temperature before thermal sensor resume, a wrong
 854         * temperature will be read as the thermal sensor is powered
 855         * down. This is done in change_mode() operation called from
 856         * thermal_zone_device_disable()
 857         */
 858        ret = thermal_zone_device_disable(data->tz);
 859        if (ret)
 860                return ret;
 861        clk_disable_unprepare(data->thermal_clk);
 862
 863        return 0;
 864}
 865
 866static int __maybe_unused imx_thermal_resume(struct device *dev)
 867{
 868        struct imx_thermal_data *data = dev_get_drvdata(dev);
 869        int ret;
 870
 871        ret = clk_prepare_enable(data->thermal_clk);
 872        if (ret)
 873                return ret;
 874        /* Enabled thermal sensor after resume */
 875        ret = thermal_zone_device_enable(data->tz);
 876        if (ret)
 877                return ret;
 878
 879        return 0;
 880}
 881
 882static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops,
 883                         imx_thermal_suspend, imx_thermal_resume);
 884
 885static struct platform_driver imx_thermal = {
 886        .driver = {
 887                .name   = "imx_thermal",
 888                .pm     = &imx_thermal_pm_ops,
 889                .of_match_table = of_imx_thermal_match,
 890        },
 891        .probe          = imx_thermal_probe,
 892        .remove         = imx_thermal_remove,
 893};
 894module_platform_driver(imx_thermal);
 895
 896MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 897MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs");
 898MODULE_LICENSE("GPL v2");
 899MODULE_ALIAS("platform:imx-thermal");
 900