linux/drivers/thermal/tegra/soctherm.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
   3 *
   4 * Author:
   5 *      Mikko Perttunen <mperttunen@nvidia.com>
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License version 2, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 */
  17
  18#include <linux/debugfs.h>
  19#include <linux/bitops.h>
  20#include <linux/clk.h>
  21#include <linux/delay.h>
  22#include <linux/err.h>
  23#include <linux/interrupt.h>
  24#include <linux/io.h>
  25#include <linux/module.h>
  26#include <linux/of.h>
  27#include <linux/platform_device.h>
  28#include <linux/reset.h>
  29#include <linux/thermal.h>
  30
  31#include <dt-bindings/thermal/tegra124-soctherm.h>
  32
  33#include "../thermal_core.h"
  34#include "soctherm.h"
  35
  36#define SENSOR_CONFIG0                          0
  37#define SENSOR_CONFIG0_STOP                     BIT(0)
  38#define SENSOR_CONFIG0_CPTR_OVER                BIT(2)
  39#define SENSOR_CONFIG0_OVER                     BIT(3)
  40#define SENSOR_CONFIG0_TCALC_OVER               BIT(4)
  41#define SENSOR_CONFIG0_TALL_MASK                (0xfffff << 8)
  42#define SENSOR_CONFIG0_TALL_SHIFT               8
  43
  44#define SENSOR_CONFIG1                          4
  45#define SENSOR_CONFIG1_TSAMPLE_MASK             0x3ff
  46#define SENSOR_CONFIG1_TSAMPLE_SHIFT            0
  47#define SENSOR_CONFIG1_TIDDQ_EN_MASK            (0x3f << 15)
  48#define SENSOR_CONFIG1_TIDDQ_EN_SHIFT           15
  49#define SENSOR_CONFIG1_TEN_COUNT_MASK           (0x3f << 24)
  50#define SENSOR_CONFIG1_TEN_COUNT_SHIFT          24
  51#define SENSOR_CONFIG1_TEMP_ENABLE              BIT(31)
  52
  53/*
  54 * SENSOR_CONFIG2 is defined in soctherm.h
  55 * because, it will be used by tegra_soctherm_fuse.c
  56 */
  57
  58#define SENSOR_STATUS0                          0xc
  59#define SENSOR_STATUS0_VALID_MASK               BIT(31)
  60#define SENSOR_STATUS0_CAPTURE_MASK             0xffff
  61
  62#define SENSOR_STATUS1                          0x10
  63#define SENSOR_STATUS1_TEMP_VALID_MASK          BIT(31)
  64#define SENSOR_STATUS1_TEMP_MASK                0xffff
  65
  66#define READBACK_VALUE_MASK                     0xff00
  67#define READBACK_VALUE_SHIFT                    8
  68#define READBACK_ADD_HALF                       BIT(7)
  69#define READBACK_NEGATE                         BIT(0)
  70
  71/*
  72 * THERMCTL_LEVEL0_GROUP_CPU is defined in soctherm.h
  73 * because it will be used by tegraxxx_soctherm.c
  74 */
  75#define THERMCTL_LVL0_CPU0_EN_MASK              BIT(8)
  76#define THERMCTL_LVL0_CPU0_CPU_THROT_MASK       (0x3 << 5)
  77#define THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT      0x1
  78#define THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY      0x2
  79#define THERMCTL_LVL0_CPU0_GPU_THROT_MASK       (0x3 << 3)
  80#define THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT      0x1
  81#define THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY      0x2
  82#define THERMCTL_LVL0_CPU0_MEM_THROT_MASK       BIT(2)
  83#define THERMCTL_LVL0_CPU0_STATUS_MASK          0x3
  84
  85#define THERMCTL_LVL0_UP_STATS                  0x10
  86#define THERMCTL_LVL0_DN_STATS                  0x14
  87
  88#define THERMCTL_STATS_CTL                      0x94
  89#define STATS_CTL_CLR_DN                        0x8
  90#define STATS_CTL_EN_DN                         0x4
  91#define STATS_CTL_CLR_UP                        0x2
  92#define STATS_CTL_EN_UP                         0x1
  93
  94#define THROT_GLOBAL_CFG                        0x400
  95#define THROT_GLOBAL_ENB_MASK                   BIT(0)
  96
  97#define CPU_PSKIP_STATUS                        0x418
  98#define XPU_PSKIP_STATUS_M_MASK                 (0xff << 12)
  99#define XPU_PSKIP_STATUS_N_MASK                 (0xff << 4)
 100#define XPU_PSKIP_STATUS_SW_OVERRIDE_MASK       BIT(1)
 101#define XPU_PSKIP_STATUS_ENABLED_MASK           BIT(0)
 102
 103#define THROT_PRIORITY_LOCK                     0x424
 104#define THROT_PRIORITY_LOCK_PRIORITY_MASK       0xff
 105
 106#define THROT_STATUS                            0x428
 107#define THROT_STATUS_BREACH_MASK                BIT(12)
 108#define THROT_STATUS_STATE_MASK                 (0xff << 4)
 109#define THROT_STATUS_ENABLED_MASK               BIT(0)
 110
 111#define THROT_PSKIP_CTRL_LITE_CPU               0x430
 112#define THROT_PSKIP_CTRL_ENABLE_MASK            BIT(31)
 113#define THROT_PSKIP_CTRL_DIVIDEND_MASK          (0xff << 8)
 114#define THROT_PSKIP_CTRL_DIVISOR_MASK           0xff
 115#define THROT_PSKIP_CTRL_VECT_GPU_MASK          (0x7 << 16)
 116#define THROT_PSKIP_CTRL_VECT_CPU_MASK          (0x7 << 8)
 117#define THROT_PSKIP_CTRL_VECT2_CPU_MASK         0x7
 118
 119#define THROT_VECT_NONE                         0x0 /* 3'b000 */
 120#define THROT_VECT_LOW                          0x1 /* 3'b001 */
 121#define THROT_VECT_MED                          0x3 /* 3'b011 */
 122#define THROT_VECT_HIGH                         0x7 /* 3'b111 */
 123
 124#define THROT_PSKIP_RAMP_LITE_CPU               0x434
 125#define THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK   BIT(31)
 126#define THROT_PSKIP_RAMP_DURATION_MASK          (0xffff << 8)
 127#define THROT_PSKIP_RAMP_STEP_MASK              0xff
 128
 129#define THROT_PRIORITY_LITE                     0x444
 130#define THROT_PRIORITY_LITE_PRIO_MASK           0xff
 131
 132#define THROT_DELAY_LITE                        0x448
 133#define THROT_DELAY_LITE_DELAY_MASK             0xff
 134
 135/* car register offsets needed for enabling HW throttling */
 136#define CAR_SUPER_CCLKG_DIVIDER                 0x36c
 137#define CDIVG_USE_THERM_CONTROLS_MASK           BIT(30)
 138
 139/* ccroc register offsets needed for enabling HW throttling for Tegra132 */
 140#define CCROC_SUPER_CCLKG_DIVIDER               0x024
 141
 142#define CCROC_GLOBAL_CFG                        0x148
 143
 144#define CCROC_THROT_PSKIP_RAMP_CPU              0x150
 145#define CCROC_THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK     BIT(31)
 146#define CCROC_THROT_PSKIP_RAMP_DURATION_MASK    (0xffff << 8)
 147#define CCROC_THROT_PSKIP_RAMP_STEP_MASK        0xff
 148
 149#define CCROC_THROT_PSKIP_CTRL_CPU              0x154
 150#define CCROC_THROT_PSKIP_CTRL_ENB_MASK         BIT(31)
 151#define CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK    (0xff << 8)
 152#define CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK     0xff
 153
 154/* get val from register(r) mask bits(m) */
 155#define REG_GET_MASK(r, m)      (((r) & (m)) >> (ffs(m) - 1))
 156/* set val(v) to mask bits(m) of register(r) */
 157#define REG_SET_MASK(r, m, v)   (((r) & ~(m)) | \
 158                                 (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
 159
 160/* get dividend from the depth */
 161#define THROT_DEPTH_DIVIDEND(depth)     ((256 * (100 - (depth)) / 100) - 1)
 162
 163/* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */
 164#define THROT_OFFSET                    0x30
 165#define THROT_PSKIP_CTRL(throt, dev)    (THROT_PSKIP_CTRL_LITE_CPU + \
 166                                        (THROT_OFFSET * throt) + (8 * dev))
 167#define THROT_PSKIP_RAMP(throt, dev)    (THROT_PSKIP_RAMP_LITE_CPU + \
 168                                        (THROT_OFFSET * throt) + (8 * dev))
 169
 170/* get THROT_xxx_CTRL offset per LIGHT/HEAVY throt */
 171#define THROT_PRIORITY_CTRL(throt)      (THROT_PRIORITY_LITE + \
 172                                        (THROT_OFFSET * throt))
 173#define THROT_DELAY_CTRL(throt)         (THROT_DELAY_LITE + \
 174                                        (THROT_OFFSET * throt))
 175
 176/* get CCROC_THROT_PSKIP_xxx offset per HIGH/MED/LOW vect*/
 177#define CCROC_THROT_OFFSET                      0x0c
 178#define CCROC_THROT_PSKIP_CTRL_CPU_REG(vect)    (CCROC_THROT_PSKIP_CTRL_CPU + \
 179                                                (CCROC_THROT_OFFSET * vect))
 180#define CCROC_THROT_PSKIP_RAMP_CPU_REG(vect)    (CCROC_THROT_PSKIP_RAMP_CPU + \
 181                                                (CCROC_THROT_OFFSET * vect))
 182
 183/* get THERMCTL_LEVELx offset per CPU/GPU/MEM/TSENSE rg and LEVEL0~3 lv */
 184#define THERMCTL_LVL_REGS_SIZE          0x20
 185#define THERMCTL_LVL_REG(rg, lv)        ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE))
 186
 187static const int min_low_temp = -127000;
 188static const int max_high_temp = 127000;
 189
 190enum soctherm_throttle_id {
 191        THROTTLE_LIGHT = 0,
 192        THROTTLE_HEAVY,
 193        THROTTLE_SIZE,
 194};
 195
 196enum soctherm_throttle_dev_id {
 197        THROTTLE_DEV_CPU = 0,
 198        THROTTLE_DEV_GPU,
 199        THROTTLE_DEV_SIZE,
 200};
 201
 202static const char *const throt_names[] = {
 203        [THROTTLE_LIGHT] = "light",
 204        [THROTTLE_HEAVY] = "heavy",
 205};
 206
 207struct tegra_soctherm;
 208struct tegra_thermctl_zone {
 209        void __iomem *reg;
 210        struct device *dev;
 211        struct tegra_soctherm *ts;
 212        struct thermal_zone_device *tz;
 213        const struct tegra_tsensor_group *sg;
 214};
 215
 216struct soctherm_throt_cfg {
 217        const char *name;
 218        unsigned int id;
 219        u8 priority;
 220        u8 cpu_throt_level;
 221        u32 cpu_throt_depth;
 222        struct thermal_cooling_device *cdev;
 223        bool init;
 224};
 225
 226struct tegra_soctherm {
 227        struct reset_control *reset;
 228        struct clk *clock_tsensor;
 229        struct clk *clock_soctherm;
 230        void __iomem *regs;
 231        void __iomem *clk_regs;
 232        void __iomem *ccroc_regs;
 233
 234        u32 *calib;
 235        struct thermal_zone_device **thermctl_tzs;
 236        struct tegra_soctherm_soc *soc;
 237
 238        struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
 239
 240        struct dentry *debugfs_dir;
 241};
 242
 243/**
 244 * clk_writel() - writes a value to a CAR register
 245 * @ts: pointer to a struct tegra_soctherm
 246 * @v: the value to write
 247 * @reg: the register offset
 248 *
 249 * Writes @v to @reg.  No return value.
 250 */
 251static inline void clk_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
 252{
 253        writel(value, (ts->clk_regs + reg));
 254}
 255
 256/**
 257 * clk_readl() - reads specified register from CAR IP block
 258 * @ts: pointer to a struct tegra_soctherm
 259 * @reg: register address to be read
 260 *
 261 * Return: the value of the register
 262 */
 263static inline u32 clk_readl(struct tegra_soctherm *ts, u32 reg)
 264{
 265        return readl(ts->clk_regs + reg);
 266}
 267
 268/**
 269 * ccroc_writel() - writes a value to a CCROC register
 270 * @ts: pointer to a struct tegra_soctherm
 271 * @v: the value to write
 272 * @reg: the register offset
 273 *
 274 * Writes @v to @reg.  No return value.
 275 */
 276static inline void ccroc_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
 277{
 278        writel(value, (ts->ccroc_regs + reg));
 279}
 280
 281/**
 282 * ccroc_readl() - reads specified register from CCROC IP block
 283 * @ts: pointer to a struct tegra_soctherm
 284 * @reg: register address to be read
 285 *
 286 * Return: the value of the register
 287 */
 288static inline u32 ccroc_readl(struct tegra_soctherm *ts, u32 reg)
 289{
 290        return readl(ts->ccroc_regs + reg);
 291}
 292
 293static void enable_tsensor(struct tegra_soctherm *tegra, unsigned int i)
 294{
 295        const struct tegra_tsensor *sensor = &tegra->soc->tsensors[i];
 296        void __iomem *base = tegra->regs + sensor->base;
 297        unsigned int val;
 298
 299        val = sensor->config->tall << SENSOR_CONFIG0_TALL_SHIFT;
 300        writel(val, base + SENSOR_CONFIG0);
 301
 302        val  = (sensor->config->tsample - 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT;
 303        val |= sensor->config->tiddq_en << SENSOR_CONFIG1_TIDDQ_EN_SHIFT;
 304        val |= sensor->config->ten_count << SENSOR_CONFIG1_TEN_COUNT_SHIFT;
 305        val |= SENSOR_CONFIG1_TEMP_ENABLE;
 306        writel(val, base + SENSOR_CONFIG1);
 307
 308        writel(tegra->calib[i], base + SENSOR_CONFIG2);
 309}
 310
 311/*
 312 * Translate from soctherm readback format to millicelsius.
 313 * The soctherm readback format in bits is as follows:
 314 *   TTTTTTTT H______N
 315 * where T's contain the temperature in Celsius,
 316 * H denotes an addition of 0.5 Celsius and N denotes negation
 317 * of the final value.
 318 */
 319static int translate_temp(u16 val)
 320{
 321        int t;
 322
 323        t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000;
 324        if (val & READBACK_ADD_HALF)
 325                t += 500;
 326        if (val & READBACK_NEGATE)
 327                t *= -1;
 328
 329        return t;
 330}
 331
 332static int tegra_thermctl_get_temp(void *data, int *out_temp)
 333{
 334        struct tegra_thermctl_zone *zone = data;
 335        u32 val;
 336
 337        val = readl(zone->reg);
 338        val = REG_GET_MASK(val, zone->sg->sensor_temp_mask);
 339        *out_temp = translate_temp(val);
 340
 341        return 0;
 342}
 343
 344static int
 345thermtrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
 346                  int trip_temp);
 347static int
 348throttrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
 349                  struct soctherm_throt_cfg *stc, int trip_temp);
 350static struct soctherm_throt_cfg *
 351find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name);
 352
 353static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
 354{
 355        struct tegra_thermctl_zone *zone = data;
 356        struct thermal_zone_device *tz = zone->tz;
 357        struct tegra_soctherm *ts = zone->ts;
 358        const struct tegra_tsensor_group *sg = zone->sg;
 359        struct device *dev = zone->dev;
 360        enum thermal_trip_type type;
 361        int ret;
 362
 363        if (!tz)
 364                return -EINVAL;
 365
 366        ret = tz->ops->get_trip_type(tz, trip, &type);
 367        if (ret)
 368                return ret;
 369
 370        if (type == THERMAL_TRIP_CRITICAL) {
 371                return thermtrip_program(dev, sg, temp);
 372        } else if (type == THERMAL_TRIP_HOT) {
 373                int i;
 374
 375                for (i = 0; i < THROTTLE_SIZE; i++) {
 376                        struct thermal_cooling_device *cdev;
 377                        struct soctherm_throt_cfg *stc;
 378
 379                        if (!ts->throt_cfgs[i].init)
 380                                continue;
 381
 382                        cdev = ts->throt_cfgs[i].cdev;
 383                        if (get_thermal_instance(tz, cdev, trip))
 384                                stc = find_throttle_cfg_by_name(ts, cdev->type);
 385                        else
 386                                continue;
 387
 388                        return throttrip_program(dev, sg, stc, temp);
 389                }
 390        }
 391
 392        return 0;
 393}
 394
 395static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
 396        .get_temp = tegra_thermctl_get_temp,
 397        .set_trip_temp = tegra_thermctl_set_trip_temp,
 398};
 399
 400/**
 401 * enforce_temp_range() - check and enforce temperature range [min, max]
 402 * @trip_temp: the trip temperature to check
 403 *
 404 * Checks and enforces the permitted temperature range that SOC_THERM
 405 * HW can support This is
 406 * done while taking care of precision.
 407 *
 408 * Return: The precision adjusted capped temperature in millicelsius.
 409 */
 410static int enforce_temp_range(struct device *dev, int trip_temp)
 411{
 412        int temp;
 413
 414        temp = clamp_val(trip_temp, min_low_temp, max_high_temp);
 415        if (temp != trip_temp)
 416                dev_info(dev, "soctherm: trip temperature %d forced to %d\n",
 417                         trip_temp, temp);
 418        return temp;
 419}
 420
 421/**
 422 * thermtrip_program() - Configures the hardware to shut down the
 423 * system if a given sensor group reaches a given temperature
 424 * @dev: ptr to the struct device for the SOC_THERM IP block
 425 * @sg: pointer to the sensor group to set the thermtrip temperature for
 426 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
 427 *
 428 * Sets the thermal trip threshold of the given sensor group to be the
 429 * @trip_temp.  If this threshold is crossed, the hardware will shut
 430 * down.
 431 *
 432 * Note that, although @trip_temp is specified in millicelsius, the
 433 * hardware is programmed in degrees Celsius.
 434 *
 435 * Return: 0 upon success, or %-EINVAL upon failure.
 436 */
 437static int thermtrip_program(struct device *dev,
 438                             const struct tegra_tsensor_group *sg,
 439                             int trip_temp)
 440{
 441        struct tegra_soctherm *ts = dev_get_drvdata(dev);
 442        int temp;
 443        u32 r;
 444
 445        if (!sg || !sg->thermtrip_threshold_mask)
 446                return -EINVAL;
 447
 448        temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
 449
 450        r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
 451        r = REG_SET_MASK(r, sg->thermtrip_threshold_mask, temp);
 452        r = REG_SET_MASK(r, sg->thermtrip_enable_mask, 1);
 453        r = REG_SET_MASK(r, sg->thermtrip_any_en_mask, 0);
 454        writel(r, ts->regs + THERMCTL_THERMTRIP_CTL);
 455
 456        return 0;
 457}
 458
 459/**
 460 * throttrip_program() - Configures the hardware to throttle the
 461 * pulse if a given sensor group reaches a given temperature
 462 * @dev: ptr to the struct device for the SOC_THERM IP block
 463 * @sg: pointer to the sensor group to set the thermtrip temperature for
 464 * @stc: pointer to the throttle need to be triggered
 465 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
 466 *
 467 * Sets the thermal trip threshold and throttle event of the given sensor
 468 * group. If this threshold is crossed, the hardware will trigger the
 469 * throttle.
 470 *
 471 * Note that, although @trip_temp is specified in millicelsius, the
 472 * hardware is programmed in degrees Celsius.
 473 *
 474 * Return: 0 upon success, or %-EINVAL upon failure.
 475 */
 476static int throttrip_program(struct device *dev,
 477                             const struct tegra_tsensor_group *sg,
 478                             struct soctherm_throt_cfg *stc,
 479                             int trip_temp)
 480{
 481        struct tegra_soctherm *ts = dev_get_drvdata(dev);
 482        int temp, cpu_throt, gpu_throt;
 483        unsigned int throt;
 484        u32 r, reg_off;
 485
 486        if (!dev || !sg || !stc || !stc->init)
 487                return -EINVAL;
 488
 489        temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
 490
 491        /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
 492        throt = stc->id;
 493        reg_off = THERMCTL_LVL_REG(sg->thermctl_lvl0_offset, throt + 1);
 494
 495        if (throt == THROTTLE_LIGHT) {
 496                cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT;
 497                gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT;
 498        } else {
 499                cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY;
 500                gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY;
 501                if (throt != THROTTLE_HEAVY)
 502                        dev_warn(dev,
 503                                 "invalid throt id %d - assuming HEAVY",
 504                                 throt);
 505        }
 506
 507        r = readl(ts->regs + reg_off);
 508        r = REG_SET_MASK(r, sg->thermctl_lvl0_up_thresh_mask, temp);
 509        r = REG_SET_MASK(r, sg->thermctl_lvl0_dn_thresh_mask, temp);
 510        r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_CPU_THROT_MASK, cpu_throt);
 511        r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_GPU_THROT_MASK, gpu_throt);
 512        r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
 513        writel(r, ts->regs + reg_off);
 514
 515        return 0;
 516}
 517
 518static struct soctherm_throt_cfg *
 519find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
 520{
 521        unsigned int i;
 522
 523        for (i = 0; ts->throt_cfgs[i].name; i++)
 524                if (!strcmp(ts->throt_cfgs[i].name, name))
 525                        return &ts->throt_cfgs[i];
 526
 527        return NULL;
 528}
 529
 530static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
 531{
 532        int ntrips, i, ret;
 533        enum thermal_trip_type type;
 534
 535        ntrips = of_thermal_get_ntrips(tz);
 536        if (ntrips <= 0)
 537                return -EINVAL;
 538
 539        for (i = 0; i < ntrips; i++) {
 540                ret = tz->ops->get_trip_type(tz, i, &type);
 541                if (ret)
 542                        return -EINVAL;
 543                if (type == THERMAL_TRIP_HOT) {
 544                        ret = tz->ops->get_trip_temp(tz, i, temp);
 545                        if (!ret)
 546                                *trip = i;
 547
 548                        return ret;
 549                }
 550        }
 551
 552        return -EINVAL;
 553}
 554
 555/**
 556 * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
 557 * @dev: struct device * of the SOC_THERM instance
 558 *
 559 * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
 560 * "THROTTLE" trip points , using "critical" or "hot" type trip_temp
 561 * from thermal zone.
 562 * After they have been configured, THERMTRIP or THROTTLE will take
 563 * action when the configured SoC thermal sensor group reaches a
 564 * certain temperature.
 565 *
 566 * Return: 0 upon success, or a negative error code on failure.
 567 * "Success" does not mean that trips was enabled; it could also
 568 * mean that no node was found in DT.
 569 * THERMTRIP has been enabled successfully when a message similar to
 570 * this one appears on the serial console:
 571 * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
 572 * THROTTLE has been enabled successfully when a message similar to
 573 * this one appears on the serial console:
 574 * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
 575 */
 576static int tegra_soctherm_set_hwtrips(struct device *dev,
 577                                      const struct tegra_tsensor_group *sg,
 578                                      struct thermal_zone_device *tz)
 579{
 580        struct tegra_soctherm *ts = dev_get_drvdata(dev);
 581        struct soctherm_throt_cfg *stc;
 582        int i, trip, temperature;
 583        int ret;
 584
 585        ret = tz->ops->get_crit_temp(tz, &temperature);
 586        if (ret) {
 587                dev_warn(dev, "thermtrip: %s: missing critical temperature\n",
 588                         sg->name);
 589                goto set_throttle;
 590        }
 591
 592        ret = thermtrip_program(dev, sg, temperature);
 593        if (ret) {
 594                dev_err(dev, "thermtrip: %s: error during enable\n",
 595                        sg->name);
 596                return ret;
 597        }
 598
 599        dev_info(dev,
 600                 "thermtrip: will shut down when %s reaches %d mC\n",
 601                 sg->name, temperature);
 602
 603set_throttle:
 604        ret = get_hot_temp(tz, &trip, &temperature);
 605        if (ret) {
 606                dev_warn(dev, "throttrip: %s: missing hot temperature\n",
 607                         sg->name);
 608                return 0;
 609        }
 610
 611        for (i = 0; i < THROTTLE_SIZE; i++) {
 612                struct thermal_cooling_device *cdev;
 613
 614                if (!ts->throt_cfgs[i].init)
 615                        continue;
 616
 617                cdev = ts->throt_cfgs[i].cdev;
 618                if (get_thermal_instance(tz, cdev, trip))
 619                        stc = find_throttle_cfg_by_name(ts, cdev->type);
 620                else
 621                        continue;
 622
 623                ret = throttrip_program(dev, sg, stc, temperature);
 624                if (ret) {
 625                        dev_err(dev, "throttrip: %s: error during enable\n",
 626                                sg->name);
 627                        return ret;
 628                }
 629
 630                dev_info(dev,
 631                         "throttrip: will throttle when %s reaches %d mC\n",
 632                         sg->name, temperature);
 633                break;
 634        }
 635
 636        if (i == THROTTLE_SIZE)
 637                dev_warn(dev, "throttrip: %s: missing throttle cdev\n",
 638                         sg->name);
 639
 640        return 0;
 641}
 642
 643#ifdef CONFIG_DEBUG_FS
 644static int regs_show(struct seq_file *s, void *data)
 645{
 646        struct platform_device *pdev = s->private;
 647        struct tegra_soctherm *ts = platform_get_drvdata(pdev);
 648        const struct tegra_tsensor *tsensors = ts->soc->tsensors;
 649        const struct tegra_tsensor_group **ttgs = ts->soc->ttgs;
 650        u32 r, state;
 651        int i, level;
 652
 653        seq_puts(s, "-----TSENSE (convert HW)-----\n");
 654
 655        for (i = 0; i < ts->soc->num_tsensors; i++) {
 656                r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG1);
 657                state = REG_GET_MASK(r, SENSOR_CONFIG1_TEMP_ENABLE);
 658
 659                seq_printf(s, "%s: ", tsensors[i].name);
 660                seq_printf(s, "En(%d) ", state);
 661
 662                if (!state) {
 663                        seq_puts(s, "\n");
 664                        continue;
 665                }
 666
 667                state = REG_GET_MASK(r, SENSOR_CONFIG1_TIDDQ_EN_MASK);
 668                seq_printf(s, "tiddq(%d) ", state);
 669                state = REG_GET_MASK(r, SENSOR_CONFIG1_TEN_COUNT_MASK);
 670                seq_printf(s, "ten_count(%d) ", state);
 671                state = REG_GET_MASK(r, SENSOR_CONFIG1_TSAMPLE_MASK);
 672                seq_printf(s, "tsample(%d) ", state + 1);
 673
 674                r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS1);
 675                state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_VALID_MASK);
 676                seq_printf(s, "Temp(%d/", state);
 677                state = REG_GET_MASK(r, SENSOR_STATUS1_TEMP_MASK);
 678                seq_printf(s, "%d) ", translate_temp(state));
 679
 680                r = readl(ts->regs + tsensors[i].base + SENSOR_STATUS0);
 681                state = REG_GET_MASK(r, SENSOR_STATUS0_VALID_MASK);
 682                seq_printf(s, "Capture(%d/", state);
 683                state = REG_GET_MASK(r, SENSOR_STATUS0_CAPTURE_MASK);
 684                seq_printf(s, "%d) ", state);
 685
 686                r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG0);
 687                state = REG_GET_MASK(r, SENSOR_CONFIG0_STOP);
 688                seq_printf(s, "Stop(%d) ", state);
 689                state = REG_GET_MASK(r, SENSOR_CONFIG0_TALL_MASK);
 690                seq_printf(s, "Tall(%d) ", state);
 691                state = REG_GET_MASK(r, SENSOR_CONFIG0_TCALC_OVER);
 692                seq_printf(s, "Over(%d/", state);
 693                state = REG_GET_MASK(r, SENSOR_CONFIG0_OVER);
 694                seq_printf(s, "%d/", state);
 695                state = REG_GET_MASK(r, SENSOR_CONFIG0_CPTR_OVER);
 696                seq_printf(s, "%d) ", state);
 697
 698                r = readl(ts->regs + tsensors[i].base + SENSOR_CONFIG2);
 699                state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMA_MASK);
 700                seq_printf(s, "Therm_A/B(%d/", state);
 701                state = REG_GET_MASK(r, SENSOR_CONFIG2_THERMB_MASK);
 702                seq_printf(s, "%d)\n", (s16)state);
 703        }
 704
 705        r = readl(ts->regs + SENSOR_PDIV);
 706        seq_printf(s, "PDIV: 0x%x\n", r);
 707
 708        r = readl(ts->regs + SENSOR_HOTSPOT_OFF);
 709        seq_printf(s, "HOTSPOT: 0x%x\n", r);
 710
 711        seq_puts(s, "\n");
 712        seq_puts(s, "-----SOC_THERM-----\n");
 713
 714        r = readl(ts->regs + SENSOR_TEMP1);
 715        state = REG_GET_MASK(r, SENSOR_TEMP1_CPU_TEMP_MASK);
 716        seq_printf(s, "Temperatures: CPU(%d) ", translate_temp(state));
 717        state = REG_GET_MASK(r, SENSOR_TEMP1_GPU_TEMP_MASK);
 718        seq_printf(s, " GPU(%d) ", translate_temp(state));
 719        r = readl(ts->regs + SENSOR_TEMP2);
 720        state = REG_GET_MASK(r, SENSOR_TEMP2_PLLX_TEMP_MASK);
 721        seq_printf(s, " PLLX(%d) ", translate_temp(state));
 722        state = REG_GET_MASK(r, SENSOR_TEMP2_MEM_TEMP_MASK);
 723        seq_printf(s, " MEM(%d)\n", translate_temp(state));
 724
 725        for (i = 0; i < ts->soc->num_ttgs; i++) {
 726                seq_printf(s, "%s:\n", ttgs[i]->name);
 727                for (level = 0; level < 4; level++) {
 728                        s32 v;
 729                        u32 mask;
 730                        u16 off = ttgs[i]->thermctl_lvl0_offset;
 731
 732                        r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
 733
 734                        mask = ttgs[i]->thermctl_lvl0_up_thresh_mask;
 735                        state = REG_GET_MASK(r, mask);
 736                        v = sign_extend32(state, ts->soc->bptt - 1);
 737                        v *= ts->soc->thresh_grain;
 738                        seq_printf(s, "   %d: Up/Dn(%d /", level, v);
 739
 740                        mask = ttgs[i]->thermctl_lvl0_dn_thresh_mask;
 741                        state = REG_GET_MASK(r, mask);
 742                        v = sign_extend32(state, ts->soc->bptt - 1);
 743                        v *= ts->soc->thresh_grain;
 744                        seq_printf(s, "%d ) ", v);
 745
 746                        mask = THERMCTL_LVL0_CPU0_EN_MASK;
 747                        state = REG_GET_MASK(r, mask);
 748                        seq_printf(s, "En(%d) ", state);
 749
 750                        mask = THERMCTL_LVL0_CPU0_CPU_THROT_MASK;
 751                        state = REG_GET_MASK(r, mask);
 752                        seq_puts(s, "CPU Throt");
 753                        if (!state)
 754                                seq_printf(s, "(%s) ", "none");
 755                        else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT)
 756                                seq_printf(s, "(%s) ", "L");
 757                        else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY)
 758                                seq_printf(s, "(%s) ", "H");
 759                        else
 760                                seq_printf(s, "(%s) ", "H+L");
 761
 762                        mask = THERMCTL_LVL0_CPU0_GPU_THROT_MASK;
 763                        state = REG_GET_MASK(r, mask);
 764                        seq_puts(s, "GPU Throt");
 765                        if (!state)
 766                                seq_printf(s, "(%s) ", "none");
 767                        else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT)
 768                                seq_printf(s, "(%s) ", "L");
 769                        else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY)
 770                                seq_printf(s, "(%s) ", "H");
 771                        else
 772                                seq_printf(s, "(%s) ", "H+L");
 773
 774                        mask = THERMCTL_LVL0_CPU0_STATUS_MASK;
 775                        state = REG_GET_MASK(r, mask);
 776                        seq_printf(s, "Status(%s)\n",
 777                                   state == 0 ? "LO" :
 778                                   state == 1 ? "In" :
 779                                   state == 2 ? "Res" : "HI");
 780                }
 781        }
 782
 783        r = readl(ts->regs + THERMCTL_STATS_CTL);
 784        seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
 785                   r & STATS_CTL_EN_UP ? "En" : "--",
 786                   r & STATS_CTL_EN_DN ? "En" : "--");
 787
 788        for (level = 0; level < 4; level++) {
 789                u16 off;
 790
 791                off = THERMCTL_LVL0_UP_STATS;
 792                r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
 793                seq_printf(s, "  Level_%d Up(%d) ", level, r);
 794
 795                off = THERMCTL_LVL0_DN_STATS;
 796                r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
 797                seq_printf(s, "Dn(%d)\n", r);
 798        }
 799
 800        r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
 801        state = REG_GET_MASK(r, ttgs[0]->thermtrip_any_en_mask);
 802        seq_printf(s, "Thermtrip Any En(%d)\n", state);
 803        for (i = 0; i < ts->soc->num_ttgs; i++) {
 804                state = REG_GET_MASK(r, ttgs[i]->thermtrip_enable_mask);
 805                seq_printf(s, "     %s En(%d) ", ttgs[i]->name, state);
 806                state = REG_GET_MASK(r, ttgs[i]->thermtrip_threshold_mask);
 807                state *= ts->soc->thresh_grain;
 808                seq_printf(s, "Thresh(%d)\n", state);
 809        }
 810
 811        r = readl(ts->regs + THROT_GLOBAL_CFG);
 812        seq_puts(s, "\n");
 813        seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
 814
 815        seq_puts(s, "---------------------------------------------------\n");
 816        r = readl(ts->regs + THROT_STATUS);
 817        state = REG_GET_MASK(r, THROT_STATUS_BREACH_MASK);
 818        seq_printf(s, "THROT STATUS: breach(%d) ", state);
 819        state = REG_GET_MASK(r, THROT_STATUS_STATE_MASK);
 820        seq_printf(s, "state(%d) ", state);
 821        state = REG_GET_MASK(r, THROT_STATUS_ENABLED_MASK);
 822        seq_printf(s, "enabled(%d)\n", state);
 823
 824        r = readl(ts->regs + CPU_PSKIP_STATUS);
 825        if (ts->soc->use_ccroc) {
 826                state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
 827                seq_printf(s, "CPU PSKIP STATUS: enabled(%d)\n", state);
 828        } else {
 829                state = REG_GET_MASK(r, XPU_PSKIP_STATUS_M_MASK);
 830                seq_printf(s, "CPU PSKIP STATUS: M(%d) ", state);
 831                state = REG_GET_MASK(r, XPU_PSKIP_STATUS_N_MASK);
 832                seq_printf(s, "N(%d) ", state);
 833                state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
 834                seq_printf(s, "enabled(%d)\n", state);
 835        }
 836
 837        return 0;
 838}
 839
 840static int regs_open(struct inode *inode, struct file *file)
 841{
 842        return single_open(file, regs_show, inode->i_private);
 843}
 844
 845static const struct file_operations regs_fops = {
 846        .open           = regs_open,
 847        .read           = seq_read,
 848        .llseek         = seq_lseek,
 849        .release        = single_release,
 850};
 851
 852static void soctherm_debug_init(struct platform_device *pdev)
 853{
 854        struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
 855        struct dentry *root, *file;
 856
 857        root = debugfs_create_dir("soctherm", NULL);
 858        if (!root) {
 859                dev_err(&pdev->dev, "failed to create debugfs directory\n");
 860                return;
 861        }
 862
 863        tegra->debugfs_dir = root;
 864
 865        file = debugfs_create_file("reg_contents", 0644, root,
 866                                   pdev, &regs_fops);
 867        if (!file) {
 868                dev_err(&pdev->dev, "failed to create debugfs file\n");
 869                debugfs_remove_recursive(tegra->debugfs_dir);
 870                tegra->debugfs_dir = NULL;
 871        }
 872}
 873#else
 874static inline void soctherm_debug_init(struct platform_device *pdev) {}
 875#endif
 876
 877static int soctherm_clk_enable(struct platform_device *pdev, bool enable)
 878{
 879        struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
 880        int err;
 881
 882        if (!tegra->clock_soctherm || !tegra->clock_tsensor)
 883                return -EINVAL;
 884
 885        reset_control_assert(tegra->reset);
 886
 887        if (enable) {
 888                err = clk_prepare_enable(tegra->clock_soctherm);
 889                if (err) {
 890                        reset_control_deassert(tegra->reset);
 891                        return err;
 892                }
 893
 894                err = clk_prepare_enable(tegra->clock_tsensor);
 895                if (err) {
 896                        clk_disable_unprepare(tegra->clock_soctherm);
 897                        reset_control_deassert(tegra->reset);
 898                        return err;
 899                }
 900        } else {
 901                clk_disable_unprepare(tegra->clock_tsensor);
 902                clk_disable_unprepare(tegra->clock_soctherm);
 903        }
 904
 905        reset_control_deassert(tegra->reset);
 906
 907        return 0;
 908}
 909
 910static int throt_get_cdev_max_state(struct thermal_cooling_device *cdev,
 911                                    unsigned long *max_state)
 912{
 913        *max_state = 1;
 914        return 0;
 915}
 916
 917static int throt_get_cdev_cur_state(struct thermal_cooling_device *cdev,
 918                                    unsigned long *cur_state)
 919{
 920        struct tegra_soctherm *ts = cdev->devdata;
 921        u32 r;
 922
 923        r = readl(ts->regs + THROT_STATUS);
 924        if (REG_GET_MASK(r, THROT_STATUS_STATE_MASK))
 925                *cur_state = 1;
 926        else
 927                *cur_state = 0;
 928
 929        return 0;
 930}
 931
 932static int throt_set_cdev_state(struct thermal_cooling_device *cdev,
 933                                unsigned long cur_state)
 934{
 935        return 0;
 936}
 937
 938static struct thermal_cooling_device_ops throt_cooling_ops = {
 939        .get_max_state = throt_get_cdev_max_state,
 940        .get_cur_state = throt_get_cdev_cur_state,
 941        .set_cur_state = throt_set_cdev_state,
 942};
 943
 944/**
 945 * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
 946 * and register them as cooling devices.
 947 */
 948static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
 949{
 950        struct device *dev = &pdev->dev;
 951        struct tegra_soctherm *ts = dev_get_drvdata(dev);
 952        struct device_node *np_stc, *np_stcc;
 953        const char *name;
 954        u32 val;
 955        int i, r;
 956
 957        for (i = 0; i < THROTTLE_SIZE; i++) {
 958                ts->throt_cfgs[i].name = throt_names[i];
 959                ts->throt_cfgs[i].id = i;
 960                ts->throt_cfgs[i].init = false;
 961        }
 962
 963        np_stc = of_get_child_by_name(dev->of_node, "throttle-cfgs");
 964        if (!np_stc) {
 965                dev_info(dev,
 966                         "throttle-cfg: no throttle-cfgs - not enabling\n");
 967                return;
 968        }
 969
 970        for_each_child_of_node(np_stc, np_stcc) {
 971                struct soctherm_throt_cfg *stc;
 972                struct thermal_cooling_device *tcd;
 973
 974                name = np_stcc->name;
 975                stc = find_throttle_cfg_by_name(ts, name);
 976                if (!stc) {
 977                        dev_err(dev,
 978                                "throttle-cfg: could not find %s\n", name);
 979                        continue;
 980                }
 981
 982                r = of_property_read_u32(np_stcc, "nvidia,priority", &val);
 983                if (r) {
 984                        dev_info(dev,
 985                                 "throttle-cfg: %s: missing priority\n", name);
 986                        continue;
 987                }
 988                stc->priority = val;
 989
 990                if (ts->soc->use_ccroc) {
 991                        r = of_property_read_u32(np_stcc,
 992                                                 "nvidia,cpu-throt-level",
 993                                                 &val);
 994                        if (r) {
 995                                dev_info(dev,
 996                                         "throttle-cfg: %s: missing cpu-throt-level\n",
 997                                         name);
 998                                continue;
 999                        }
1000                        stc->cpu_throt_level = val;
1001                } else {
1002                        r = of_property_read_u32(np_stcc,
1003                                                 "nvidia,cpu-throt-percent",
1004                                                 &val);
1005                        if (r) {
1006                                dev_info(dev,
1007                                         "throttle-cfg: %s: missing cpu-throt-percent\n",
1008                                         name);
1009                                continue;
1010                        }
1011                        stc->cpu_throt_depth = val;
1012                }
1013
1014                tcd = thermal_of_cooling_device_register(np_stcc,
1015                                                         (char *)name, ts,
1016                                                         &throt_cooling_ops);
1017                of_node_put(np_stcc);
1018                if (IS_ERR_OR_NULL(tcd)) {
1019                        dev_err(dev,
1020                                "throttle-cfg: %s: failed to register cooling device\n",
1021                                name);
1022                        continue;
1023                }
1024
1025                stc->cdev = tcd;
1026                stc->init = true;
1027        }
1028
1029        of_node_put(np_stc);
1030}
1031
1032/**
1033 * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
1034 * @level: describing the level LOW/MED/HIGH of throttling
1035 *
1036 * It's necessary to set up the CPU-local CCROC NV_THERM instance with
1037 * the M/N values desired for each level. This function does this.
1038 *
1039 * This function pre-programs the CCROC NV_THERM levels in terms of
1040 * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
1041 * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
1042 */
1043static void throttlectl_cpu_level_cfg(struct tegra_soctherm *ts, int level)
1044{
1045        u8 depth, dividend;
1046        u32 r;
1047
1048        switch (level) {
1049        case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
1050                depth = 50;
1051                break;
1052        case TEGRA_SOCTHERM_THROT_LEVEL_MED:
1053                depth = 75;
1054                break;
1055        case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
1056                depth = 80;
1057                break;
1058        case TEGRA_SOCTHERM_THROT_LEVEL_NONE:
1059                return;
1060        default:
1061                return;
1062        }
1063
1064        dividend = THROT_DEPTH_DIVIDEND(depth);
1065
1066        /* setup PSKIP in ccroc nv_therm registers */
1067        r = ccroc_readl(ts, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
1068        r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
1069        r = REG_SET_MASK(r, CCROC_THROT_PSKIP_RAMP_STEP_MASK, 0xf);
1070        ccroc_writel(ts, r, CCROC_THROT_PSKIP_RAMP_CPU_REG(level));
1071
1072        r = ccroc_readl(ts, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
1073        r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_ENB_MASK, 1);
1074        r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
1075        r = REG_SET_MASK(r, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
1076        ccroc_writel(ts, r, CCROC_THROT_PSKIP_CTRL_CPU_REG(level));
1077}
1078
1079/**
1080 * throttlectl_cpu_level_select() - program CPU pulse skipper config
1081 * @throt: the LIGHT/HEAVY of throttle event id
1082 *
1083 * Pulse skippers are used to throttle clock frequencies.  This
1084 * function programs the pulse skippers based on @throt and platform
1085 * data.  This function is used on SoCs which have CPU-local pulse
1086 * skipper control, such as T13x. It programs soctherm's interface to
1087 * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
1088 * vectors. PSKIP_BYPASS mode is set as required per HW spec.
1089 */
1090static void throttlectl_cpu_level_select(struct tegra_soctherm *ts,
1091                                         enum soctherm_throttle_id throt)
1092{
1093        u32 r, throt_vect;
1094
1095        /* Denver:CCROC NV_THERM interface N:3 Mapping */
1096        switch (ts->throt_cfgs[throt].cpu_throt_level) {
1097        case TEGRA_SOCTHERM_THROT_LEVEL_LOW:
1098                throt_vect = THROT_VECT_LOW;
1099                break;
1100        case TEGRA_SOCTHERM_THROT_LEVEL_MED:
1101                throt_vect = THROT_VECT_MED;
1102                break;
1103        case TEGRA_SOCTHERM_THROT_LEVEL_HIGH:
1104                throt_vect = THROT_VECT_HIGH;
1105                break;
1106        default:
1107                throt_vect = THROT_VECT_NONE;
1108                break;
1109        }
1110
1111        r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1112        r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
1113        r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT_CPU_MASK, throt_vect);
1114        r = REG_SET_MASK(r, THROT_PSKIP_CTRL_VECT2_CPU_MASK, throt_vect);
1115        writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1116
1117        /* bypass sequencer in soc_therm as it is programmed in ccroc */
1118        r = REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK, 1);
1119        writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
1120}
1121
1122/**
1123 * throttlectl_cpu_mn() - program CPU pulse skipper configuration
1124 * @throt: the LIGHT/HEAVY of throttle event id
1125 *
1126 * Pulse skippers are used to throttle clock frequencies.  This
1127 * function programs the pulse skippers based on @throt and platform
1128 * data.  This function is used for CPUs that have "remote" pulse
1129 * skipper control, e.g., the CPU pulse skipper is controlled by the
1130 * SOC_THERM IP block.  (SOC_THERM is located outside the CPU
1131 * complex.)
1132 */
1133static void throttlectl_cpu_mn(struct tegra_soctherm *ts,
1134                               enum soctherm_throttle_id throt)
1135{
1136        u32 r;
1137        int depth;
1138        u8 dividend;
1139
1140        depth = ts->throt_cfgs[throt].cpu_throt_depth;
1141        dividend = THROT_DEPTH_DIVIDEND(depth);
1142
1143        r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1144        r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
1145        r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
1146        r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
1147        writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
1148
1149        r = readl(ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
1150        r = REG_SET_MASK(r, THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
1151        r = REG_SET_MASK(r, THROT_PSKIP_RAMP_STEP_MASK, 0xf);
1152        writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
1153}
1154
1155/**
1156 * soctherm_throttle_program() - programs pulse skippers' configuration
1157 * @throt: the LIGHT/HEAVY of the throttle event id.
1158 *
1159 * Pulse skippers are used to throttle clock frequencies.
1160 * This function programs the pulse skippers.
1161 */
1162static void soctherm_throttle_program(struct tegra_soctherm *ts,
1163                                      enum soctherm_throttle_id throt)
1164{
1165        u32 r;
1166        struct soctherm_throt_cfg stc = ts->throt_cfgs[throt];
1167
1168        if (!stc.init)
1169                return;
1170
1171        /* Setup PSKIP parameters */
1172        if (ts->soc->use_ccroc)
1173                throttlectl_cpu_level_select(ts, throt);
1174        else
1175                throttlectl_cpu_mn(ts, throt);
1176
1177        r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority);
1178        writel(r, ts->regs + THROT_PRIORITY_CTRL(throt));
1179
1180        r = REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK, 0);
1181        writel(r, ts->regs + THROT_DELAY_CTRL(throt));
1182
1183        r = readl(ts->regs + THROT_PRIORITY_LOCK);
1184        r = REG_GET_MASK(r, THROT_PRIORITY_LOCK_PRIORITY_MASK);
1185        if (r >= stc.priority)
1186                return;
1187        r = REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK,
1188                         stc.priority);
1189        writel(r, ts->regs + THROT_PRIORITY_LOCK);
1190}
1191
1192static void tegra_soctherm_throttle(struct device *dev)
1193{
1194        struct tegra_soctherm *ts = dev_get_drvdata(dev);
1195        u32 v;
1196        int i;
1197
1198        /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
1199        if (ts->soc->use_ccroc) {
1200                throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_LOW);
1201                throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_MED);
1202                throttlectl_cpu_level_cfg(ts, TEGRA_SOCTHERM_THROT_LEVEL_HIGH);
1203        }
1204
1205        /* Thermal HW throttle programming */
1206        for (i = 0; i < THROTTLE_SIZE; i++)
1207                soctherm_throttle_program(ts, i);
1208
1209        v = REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK, 1);
1210        if (ts->soc->use_ccroc) {
1211                ccroc_writel(ts, v, CCROC_GLOBAL_CFG);
1212
1213                v = ccroc_readl(ts, CCROC_SUPER_CCLKG_DIVIDER);
1214                v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
1215                ccroc_writel(ts, v, CCROC_SUPER_CCLKG_DIVIDER);
1216        } else {
1217                writel(v, ts->regs + THROT_GLOBAL_CFG);
1218
1219                v = clk_readl(ts, CAR_SUPER_CCLKG_DIVIDER);
1220                v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
1221                clk_writel(ts, v, CAR_SUPER_CCLKG_DIVIDER);
1222        }
1223
1224        /* initialize stats collection */
1225        v = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
1226            STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
1227        writel(v, ts->regs + THERMCTL_STATS_CTL);
1228}
1229
1230static void soctherm_init(struct platform_device *pdev)
1231{
1232        struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
1233        const struct tegra_tsensor_group **ttgs = tegra->soc->ttgs;
1234        int i;
1235        u32 pdiv, hotspot;
1236
1237        /* Initialize raw sensors */
1238        for (i = 0; i < tegra->soc->num_tsensors; ++i)
1239                enable_tsensor(tegra, i);
1240
1241        /* program pdiv and hotspot offsets per THERM */
1242        pdiv = readl(tegra->regs + SENSOR_PDIV);
1243        hotspot = readl(tegra->regs + SENSOR_HOTSPOT_OFF);
1244        for (i = 0; i < tegra->soc->num_ttgs; ++i) {
1245                pdiv = REG_SET_MASK(pdiv, ttgs[i]->pdiv_mask,
1246                                    ttgs[i]->pdiv);
1247                /* hotspot offset from PLLX, doesn't need to configure PLLX */
1248                if (ttgs[i]->id == TEGRA124_SOCTHERM_SENSOR_PLLX)
1249                        continue;
1250                hotspot =  REG_SET_MASK(hotspot,
1251                                        ttgs[i]->pllx_hotspot_mask,
1252                                        ttgs[i]->pllx_hotspot_diff);
1253        }
1254        writel(pdiv, tegra->regs + SENSOR_PDIV);
1255        writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF);
1256
1257        /* Configure hw throttle */
1258        tegra_soctherm_throttle(&pdev->dev);
1259}
1260
1261static const struct of_device_id tegra_soctherm_of_match[] = {
1262#ifdef CONFIG_ARCH_TEGRA_124_SOC
1263        {
1264                .compatible = "nvidia,tegra124-soctherm",
1265                .data = &tegra124_soctherm,
1266        },
1267#endif
1268#ifdef CONFIG_ARCH_TEGRA_132_SOC
1269        {
1270                .compatible = "nvidia,tegra132-soctherm",
1271                .data = &tegra132_soctherm,
1272        },
1273#endif
1274#ifdef CONFIG_ARCH_TEGRA_210_SOC
1275        {
1276                .compatible = "nvidia,tegra210-soctherm",
1277                .data = &tegra210_soctherm,
1278        },
1279#endif
1280        { },
1281};
1282MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
1283
1284static int tegra_soctherm_probe(struct platform_device *pdev)
1285{
1286        const struct of_device_id *match;
1287        struct tegra_soctherm *tegra;
1288        struct thermal_zone_device *z;
1289        struct tsensor_shared_calib shared_calib;
1290        struct resource *res;
1291        struct tegra_soctherm_soc *soc;
1292        unsigned int i;
1293        int err;
1294
1295        match = of_match_node(tegra_soctherm_of_match, pdev->dev.of_node);
1296        if (!match)
1297                return -ENODEV;
1298
1299        soc = (struct tegra_soctherm_soc *)match->data;
1300        if (soc->num_ttgs > TEGRA124_SOCTHERM_SENSOR_NUM)
1301                return -EINVAL;
1302
1303        tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
1304        if (!tegra)
1305                return -ENOMEM;
1306
1307        dev_set_drvdata(&pdev->dev, tegra);
1308
1309        tegra->soc = soc;
1310
1311        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1312                                           "soctherm-reg");
1313        tegra->regs = devm_ioremap_resource(&pdev->dev, res);
1314        if (IS_ERR(tegra->regs)) {
1315                dev_err(&pdev->dev, "can't get soctherm registers");
1316                return PTR_ERR(tegra->regs);
1317        }
1318
1319        if (!tegra->soc->use_ccroc) {
1320                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1321                                                   "car-reg");
1322                tegra->clk_regs = devm_ioremap_resource(&pdev->dev, res);
1323                if (IS_ERR(tegra->clk_regs)) {
1324                        dev_err(&pdev->dev, "can't get car clk registers");
1325                        return PTR_ERR(tegra->clk_regs);
1326                }
1327        } else {
1328                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1329                                                   "ccroc-reg");
1330                tegra->ccroc_regs = devm_ioremap_resource(&pdev->dev, res);
1331                if (IS_ERR(tegra->ccroc_regs)) {
1332                        dev_err(&pdev->dev, "can't get ccroc registers");
1333                        return PTR_ERR(tegra->ccroc_regs);
1334                }
1335        }
1336
1337        tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm");
1338        if (IS_ERR(tegra->reset)) {
1339                dev_err(&pdev->dev, "can't get soctherm reset\n");
1340                return PTR_ERR(tegra->reset);
1341        }
1342
1343        tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor");
1344        if (IS_ERR(tegra->clock_tsensor)) {
1345                dev_err(&pdev->dev, "can't get tsensor clock\n");
1346                return PTR_ERR(tegra->clock_tsensor);
1347        }
1348
1349        tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm");
1350        if (IS_ERR(tegra->clock_soctherm)) {
1351                dev_err(&pdev->dev, "can't get soctherm clock\n");
1352                return PTR_ERR(tegra->clock_soctherm);
1353        }
1354
1355        tegra->calib = devm_kzalloc(&pdev->dev,
1356                                    sizeof(u32) * soc->num_tsensors,
1357                                    GFP_KERNEL);
1358        if (!tegra->calib)
1359                return -ENOMEM;
1360
1361        /* calculate shared calibration data */
1362        err = tegra_calc_shared_calib(soc->tfuse, &shared_calib);
1363        if (err)
1364                return err;
1365
1366        /* calculate tsensor calibaration data */
1367        for (i = 0; i < soc->num_tsensors; ++i) {
1368                err = tegra_calc_tsensor_calib(&soc->tsensors[i],
1369                                               &shared_calib,
1370                                               &tegra->calib[i]);
1371                if (err)
1372                        return err;
1373        }
1374
1375        tegra->thermctl_tzs = devm_kzalloc(&pdev->dev,
1376                                           sizeof(*z) * soc->num_ttgs,
1377                                           GFP_KERNEL);
1378        if (!tegra->thermctl_tzs)
1379                return -ENOMEM;
1380
1381        err = soctherm_clk_enable(pdev, true);
1382        if (err)
1383                return err;
1384
1385        soctherm_init_hw_throt_cdev(pdev);
1386
1387        soctherm_init(pdev);
1388
1389        for (i = 0; i < soc->num_ttgs; ++i) {
1390                struct tegra_thermctl_zone *zone =
1391                        devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL);
1392                if (!zone) {
1393                        err = -ENOMEM;
1394                        goto disable_clocks;
1395                }
1396
1397                zone->reg = tegra->regs + soc->ttgs[i]->sensor_temp_offset;
1398                zone->dev = &pdev->dev;
1399                zone->sg = soc->ttgs[i];
1400                zone->ts = tegra;
1401
1402                z = devm_thermal_zone_of_sensor_register(&pdev->dev,
1403                                                         soc->ttgs[i]->id, zone,
1404                                                         &tegra_of_thermal_ops);
1405                if (IS_ERR(z)) {
1406                        err = PTR_ERR(z);
1407                        dev_err(&pdev->dev, "failed to register sensor: %d\n",
1408                                err);
1409                        goto disable_clocks;
1410                }
1411
1412                zone->tz = z;
1413                tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
1414
1415                /* Configure hw trip points */
1416                err = tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z);
1417                if (err)
1418                        goto disable_clocks;
1419        }
1420
1421        soctherm_debug_init(pdev);
1422
1423        return 0;
1424
1425disable_clocks:
1426        soctherm_clk_enable(pdev, false);
1427
1428        return err;
1429}
1430
1431static int tegra_soctherm_remove(struct platform_device *pdev)
1432{
1433        struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
1434
1435        debugfs_remove_recursive(tegra->debugfs_dir);
1436
1437        soctherm_clk_enable(pdev, false);
1438
1439        return 0;
1440}
1441
1442static int __maybe_unused soctherm_suspend(struct device *dev)
1443{
1444        struct platform_device *pdev = to_platform_device(dev);
1445
1446        soctherm_clk_enable(pdev, false);
1447
1448        return 0;
1449}
1450
1451static int __maybe_unused soctherm_resume(struct device *dev)
1452{
1453        struct platform_device *pdev = to_platform_device(dev);
1454        struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
1455        struct tegra_soctherm_soc *soc = tegra->soc;
1456        int err, i;
1457
1458        err = soctherm_clk_enable(pdev, true);
1459        if (err) {
1460                dev_err(&pdev->dev,
1461                        "Resume failed: enable clocks failed\n");
1462                return err;
1463        }
1464
1465        soctherm_init(pdev);
1466
1467        for (i = 0; i < soc->num_ttgs; ++i) {
1468                struct thermal_zone_device *tz;
1469
1470                tz = tegra->thermctl_tzs[soc->ttgs[i]->id];
1471                err = tegra_soctherm_set_hwtrips(dev, soc->ttgs[i], tz);
1472                if (err) {
1473                        dev_err(&pdev->dev,
1474                                "Resume failed: set hwtrips failed\n");
1475                        return err;
1476                }
1477        }
1478
1479        return 0;
1480}
1481
1482static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm, soctherm_suspend, soctherm_resume);
1483
1484static struct platform_driver tegra_soctherm_driver = {
1485        .probe = tegra_soctherm_probe,
1486        .remove = tegra_soctherm_remove,
1487        .driver = {
1488                .name = "tegra_soctherm",
1489                .pm = &tegra_soctherm_pm,
1490                .of_match_table = tegra_soctherm_of_match,
1491        },
1492};
1493module_platform_driver(tegra_soctherm_driver);
1494
1495MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
1496MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
1497MODULE_LICENSE("GPL v2");
1498