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