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