aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Ni <wni@nvidia.com>2016-05-11 06:20:17 -0400
committerZhang Rui <rui.zhang@intel.com>2016-09-27 02:02:32 -0400
commitce0dbf04f685d48ffdec64a17ebb4965f828c3ff (patch)
tree29347f927f7a7036b29cac82a6ddbdcd969ad875
parent44f3d4170e00debf154e778e7068e5d78c41dd82 (diff)
thermal: tegra: add hw-throttle function
Tegra soctherm support HW throttle, when the soctherm snesors' temperature is above the throttle trip point, it will trigger pulse skiper to tune clocks accroding to the throttle depth. Add this function for Tegra124 and Tegra210. Since Tegra132 use different registers to configure pulse skiper, will support it in next patch. Signed-off-by: Wei Ni <wni@nvidia.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
-rw-r--r--drivers/thermal/tegra/soctherm.c668
-rw-r--r--drivers/thermal/tegra/soctherm.h10
-rw-r--r--drivers/thermal/tegra/tegra124-soctherm.c18
-rw-r--r--drivers/thermal/tegra/tegra132-soctherm.c1
-rw-r--r--drivers/thermal/tegra/tegra210-soctherm.c18
5 files changed, 700 insertions, 15 deletions
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index b8651726201e..dc75f92e1d8e 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -30,6 +30,7 @@
30 30
31#include <dt-bindings/thermal/tegra124-soctherm.h> 31#include <dt-bindings/thermal/tegra124-soctherm.h>
32 32
33#include "../thermal_core.h"
33#include "soctherm.h" 34#include "soctherm.h"
34 35
35#define SENSOR_CONFIG0 0 36#define SENSOR_CONFIG0 0
@@ -67,35 +68,179 @@
67#define READBACK_ADD_HALF BIT(7) 68#define READBACK_ADD_HALF BIT(7)
68#define READBACK_NEGATE BIT(0) 69#define READBACK_NEGATE BIT(0)
69 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
70/* get val from register(r) mask bits(m) */ 139/* get val from register(r) mask bits(m) */
71#define REG_GET_MASK(r, m) (((r) & (m)) >> (ffs(m) - 1)) 140#define REG_GET_MASK(r, m) (((r) & (m)) >> (ffs(m) - 1))
72/* set val(v) to mask bits(m) of register(r) */ 141/* set val(v) to mask bits(m) of register(r) */
73#define REG_SET_MASK(r, m, v) (((r) & ~(m)) | \ 142#define REG_SET_MASK(r, m, v) (((r) & ~(m)) | \
74 (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1))) 143 (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
75 144
145/* get dividend from the depth */
146#define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
147
148/* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */
149#define THROT_OFFSET 0x30
150#define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \
151 (THROT_OFFSET * throt) + (8 * dev))
152#define THROT_PSKIP_RAMP(throt, dev) (THROT_PSKIP_RAMP_LITE_CPU + \
153 (THROT_OFFSET * throt) + (8 * dev))
154
155/* get THROT_xxx_CTRL offset per LIGHT/HEAVY throt */
156#define THROT_PRIORITY_CTRL(throt) (THROT_PRIORITY_LITE + \
157 (THROT_OFFSET * throt))
158#define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \
159 (THROT_OFFSET * throt))
160
161/* get THERMCTL_LEVELx offset per CPU/GPU/MEM/TSENSE rg and LEVEL0~3 lv */
162#define THERMCTL_LVL_REGS_SIZE 0x20
163#define THERMCTL_LVL_REG(rg, lv) ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE))
164
76static const int min_low_temp = -127000; 165static const int min_low_temp = -127000;
77static const int max_high_temp = 127000; 166static const int max_high_temp = 127000;
78 167
168enum soctherm_throttle_id {
169 THROTTLE_LIGHT = 0,
170 THROTTLE_HEAVY,
171 THROTTLE_SIZE,
172};
173
174enum soctherm_throttle_dev_id {
175 THROTTLE_DEV_CPU = 0,
176 THROTTLE_DEV_GPU,
177 THROTTLE_DEV_SIZE,
178};
179
180static const char *const throt_names[] = {
181 [THROTTLE_LIGHT] = "light",
182 [THROTTLE_HEAVY] = "heavy",
183};
184
185struct tegra_soctherm;
79struct tegra_thermctl_zone { 186struct tegra_thermctl_zone {
80 void __iomem *reg; 187 void __iomem *reg;
81 struct device *dev; 188 struct device *dev;
189 struct tegra_soctherm *ts;
82 struct thermal_zone_device *tz; 190 struct thermal_zone_device *tz;
83 const struct tegra_tsensor_group *sg; 191 const struct tegra_tsensor_group *sg;
84}; 192};
85 193
194struct soctherm_throt_cfg {
195 const char *name;
196 unsigned int id;
197 u8 priority;
198 u32 cpu_throt_depth;
199 struct thermal_cooling_device *cdev;
200 bool init;
201};
202
86struct tegra_soctherm { 203struct tegra_soctherm {
87 struct reset_control *reset; 204 struct reset_control *reset;
88 struct clk *clock_tsensor; 205 struct clk *clock_tsensor;
89 struct clk *clock_soctherm; 206 struct clk *clock_soctherm;
90 void __iomem *regs; 207 void __iomem *regs;
91 struct thermal_zone_device **thermctl_tzs; 208 void __iomem *clk_regs;
92 209
93 u32 *calib; 210 u32 *calib;
211 struct thermal_zone_device **thermctl_tzs;
94 struct tegra_soctherm_soc *soc; 212 struct tegra_soctherm_soc *soc;
95 213
214 struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
215
96 struct dentry *debugfs_dir; 216 struct dentry *debugfs_dir;
97}; 217};
98 218
219/**
220 * clk_writel() - writes a value to a CAR register
221 * @ts: pointer to a struct tegra_soctherm
222 * @v: the value to write
223 * @reg: the register offset
224 *
225 * Writes @v to @reg. No return value.
226 */
227static inline void clk_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
228{
229 writel(value, (ts->clk_regs + reg));
230}
231
232/**
233 * clk_readl() - reads specified register from CAR IP block
234 * @ts: pointer to a struct tegra_soctherm
235 * @reg: register address to be read
236 *
237 * Return: the value of the register
238 */
239static inline u32 clk_readl(struct tegra_soctherm *ts, u32 reg)
240{
241 return readl(ts->clk_regs + reg);
242}
243
99static void enable_tsensor(struct tegra_soctherm *tegra, unsigned int i) 244static void enable_tsensor(struct tegra_soctherm *tegra, unsigned int i)
100{ 245{
101 const struct tegra_tsensor *sensor = &tegra->soc->tsensors[i]; 246 const struct tegra_tsensor *sensor = &tegra->soc->tsensors[i];
@@ -150,11 +295,17 @@ static int tegra_thermctl_get_temp(void *data, int *out_temp)
150static int 295static int
151thermtrip_program(struct device *dev, const struct tegra_tsensor_group *sg, 296thermtrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
152 int trip_temp); 297 int trip_temp);
298static int
299throttrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
300 struct soctherm_throt_cfg *stc, int trip_temp);
301static struct soctherm_throt_cfg *
302find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name);
153 303
154static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp) 304static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
155{ 305{
156 struct tegra_thermctl_zone *zone = data; 306 struct tegra_thermctl_zone *zone = data;
157 struct thermal_zone_device *tz = zone->tz; 307 struct thermal_zone_device *tz = zone->tz;
308 struct tegra_soctherm *ts = zone->ts;
158 const struct tegra_tsensor_group *sg = zone->sg; 309 const struct tegra_tsensor_group *sg = zone->sg;
159 struct device *dev = zone->dev; 310 struct device *dev = zone->dev;
160 enum thermal_trip_type type; 311 enum thermal_trip_type type;
@@ -167,10 +318,29 @@ static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
167 if (ret) 318 if (ret)
168 return ret; 319 return ret;
169 320
170 if (type != THERMAL_TRIP_CRITICAL) 321 if (type == THERMAL_TRIP_CRITICAL) {
171 return 0; 322 return thermtrip_program(dev, sg, temp);
323 } else if (type == THERMAL_TRIP_HOT) {
324 int i;
325
326 for (i = 0; i < THROTTLE_SIZE; i++) {
327 struct thermal_cooling_device *cdev;
328 struct soctherm_throt_cfg *stc;
172 329
173 return thermtrip_program(dev, sg, temp); 330 if (!ts->throt_cfgs[i].init)
331 continue;
332
333 cdev = ts->throt_cfgs[i].cdev;
334 if (get_thermal_instance(tz, cdev, trip))
335 stc = find_throttle_cfg_by_name(ts, cdev->type);
336 else
337 continue;
338
339 return throttrip_program(dev, sg, stc, temp);
340 }
341 }
342
343 return 0;
174} 344}
175 345
176static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { 346static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
@@ -238,14 +408,110 @@ static int thermtrip_program(struct device *dev,
238} 408}
239 409
240/** 410/**
411 * throttrip_program() - Configures the hardware to throttle the
412 * pulse if a given sensor group reaches a given temperature
413 * @dev: ptr to the struct device for the SOC_THERM IP block
414 * @sg: pointer to the sensor group to set the thermtrip temperature for
415 * @stc: pointer to the throttle need to be triggered
416 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
417 *
418 * Sets the thermal trip threshold and throttle event of the given sensor
419 * group. If this threshold is crossed, the hardware will trigger the
420 * throttle.
421 *
422 * Note that, although @trip_temp is specified in millicelsius, the
423 * hardware is programmed in degrees Celsius.
424 *
425 * Return: 0 upon success, or %-EINVAL upon failure.
426 */
427static int throttrip_program(struct device *dev,
428 const struct tegra_tsensor_group *sg,
429 struct soctherm_throt_cfg *stc,
430 int trip_temp)
431{
432 struct tegra_soctherm *ts = dev_get_drvdata(dev);
433 int temp, cpu_throt, gpu_throt;
434 unsigned int throt;
435 u32 r, reg_off;
436
437 if (!dev || !sg || !stc || !stc->init)
438 return -EINVAL;
439
440 temp = enforce_temp_range(dev, trip_temp) / ts->soc->thresh_grain;
441
442 /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
443 throt = stc->id;
444 reg_off = THERMCTL_LVL_REG(sg->thermctl_lvl0_offset, throt + 1);
445
446 if (throt == THROTTLE_LIGHT) {
447 cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT;
448 gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT;
449 } else {
450 cpu_throt = THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY;
451 gpu_throt = THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY;
452 if (throt != THROTTLE_HEAVY)
453 dev_warn(dev,
454 "invalid throt id %d - assuming HEAVY",
455 throt);
456 }
457
458 r = readl(ts->regs + reg_off);
459 r = REG_SET_MASK(r, sg->thermctl_lvl0_up_thresh_mask, temp);
460 r = REG_SET_MASK(r, sg->thermctl_lvl0_dn_thresh_mask, temp);
461 r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_CPU_THROT_MASK, cpu_throt);
462 r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_GPU_THROT_MASK, gpu_throt);
463 r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
464 writel(r, ts->regs + reg_off);
465
466 return 0;
467}
468
469static struct soctherm_throt_cfg *
470find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
471{
472 unsigned int i;
473
474 for (i = 0; ts->throt_cfgs[i].name; i++)
475 if (!strcmp(ts->throt_cfgs[i].name, name))
476 return &ts->throt_cfgs[i];
477
478 return NULL;
479}
480
481static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
482{
483 int ntrips, i, ret;
484 enum thermal_trip_type type;
485
486 ntrips = of_thermal_get_ntrips(tz);
487 if (ntrips <= 0)
488 return -EINVAL;
489
490 for (i = 0; i < ntrips; i++) {
491 ret = tz->ops->get_trip_type(tz, i, &type);
492 if (ret)
493 return -EINVAL;
494 if (type == THERMAL_TRIP_HOT) {
495 ret = tz->ops->get_trip_temp(tz, i, temp);
496 if (!ret)
497 *trip = i;
498
499 return ret;
500 }
501 }
502
503 return -EINVAL;
504}
505
506/**
241 * tegra_soctherm_set_hwtrips() - set HW trip point from DT data 507 * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
242 * @dev: struct device * of the SOC_THERM instance 508 * @dev: struct device * of the SOC_THERM instance
243 * 509 *
244 * Configure the SOC_THERM HW trip points, setting "THERMTRIP" 510 * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
245 * trip points , using "critical" type trip_temp from thermal 511 * "THROTTLE" trip points , using "critical" or "hot" type trip_temp
246 * zone. 512 * from thermal zone.
247 * After they have been configured, THERMTRIP will take action 513 * After they have been configured, THERMTRIP or THROTTLE will take
248 * when the configured SoC thermal sensor group reaches a 514 * action when the configured SoC thermal sensor group reaches a
249 * certain temperature. 515 * certain temperature.
250 * 516 *
251 * Return: 0 upon success, or a negative error code on failure. 517 * Return: 0 upon success, or a negative error code on failure.
@@ -254,19 +520,24 @@ static int thermtrip_program(struct device *dev,
254 * THERMTRIP has been enabled successfully when a message similar to 520 * THERMTRIP has been enabled successfully when a message similar to
255 * this one appears on the serial console: 521 * this one appears on the serial console:
256 * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC" 522 * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
523 * THROTTLE has been enabled successfully when a message similar to
524 * this one appears on the serial console:
525 * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
257 */ 526 */
258static int tegra_soctherm_set_hwtrips(struct device *dev, 527static int tegra_soctherm_set_hwtrips(struct device *dev,
259 const struct tegra_tsensor_group *sg, 528 const struct tegra_tsensor_group *sg,
260 struct thermal_zone_device *tz) 529 struct thermal_zone_device *tz)
261{ 530{
262 int temperature; 531 struct tegra_soctherm *ts = dev_get_drvdata(dev);
532 struct soctherm_throt_cfg *stc;
533 int i, trip, temperature;
263 int ret; 534 int ret;
264 535
265 ret = tz->ops->get_crit_temp(tz, &temperature); 536 ret = tz->ops->get_crit_temp(tz, &temperature);
266 if (ret) { 537 if (ret) {
267 dev_warn(dev, "thermtrip: %s: missing critical temperature\n", 538 dev_warn(dev, "thermtrip: %s: missing critical temperature\n",
268 sg->name); 539 sg->name);
269 return ret; 540 goto set_throttle;
270 } 541 }
271 542
272 ret = thermtrip_program(dev, sg, temperature); 543 ret = thermtrip_program(dev, sg, temperature);
@@ -280,6 +551,46 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
280 "thermtrip: will shut down when %s reaches %d mC\n", 551 "thermtrip: will shut down when %s reaches %d mC\n",
281 sg->name, temperature); 552 sg->name, temperature);
282 553
554set_throttle:
555 if (ts->soc->use_ccroc)
556 return 0;
557
558 ret = get_hot_temp(tz, &trip, &temperature);
559 if (ret) {
560 dev_warn(dev, "throttrip: %s: missing hot temperature\n",
561 sg->name);
562 return 0;
563 }
564
565 for (i = 0; i < THROTTLE_SIZE; i++) {
566 struct thermal_cooling_device *cdev;
567
568 if (!ts->throt_cfgs[i].init)
569 continue;
570
571 cdev = ts->throt_cfgs[i].cdev;
572 if (get_thermal_instance(tz, cdev, trip))
573 stc = find_throttle_cfg_by_name(ts, cdev->type);
574 else
575 continue;
576
577 ret = throttrip_program(dev, sg, stc, temperature);
578 if (ret) {
579 dev_err(dev, "throttrip: %s: error during enable\n",
580 sg->name);
581 return ret;
582 }
583
584 dev_info(dev,
585 "throttrip: will throttle when %s reaches %d mC\n",
586 sg->name, temperature);
587 break;
588 }
589
590 if (i == THROTTLE_SIZE)
591 dev_warn(dev, "throttrip: %s: missing throttle cdev\n",
592 sg->name);
593
283 return 0; 594 return 0;
284} 595}
285 596
@@ -291,7 +602,7 @@ static int regs_show(struct seq_file *s, void *data)
291 const struct tegra_tsensor *tsensors = ts->soc->tsensors; 602 const struct tegra_tsensor *tsensors = ts->soc->tsensors;
292 const struct tegra_tsensor_group **ttgs = ts->soc->ttgs; 603 const struct tegra_tsensor_group **ttgs = ts->soc->ttgs;
293 u32 r, state; 604 u32 r, state;
294 int i; 605 int i, level;
295 606
296 seq_puts(s, "-----TSENSE (convert HW)-----\n"); 607 seq_puts(s, "-----TSENSE (convert HW)-----\n");
297 608
@@ -365,6 +676,84 @@ static int regs_show(struct seq_file *s, void *data)
365 state = REG_GET_MASK(r, SENSOR_TEMP2_MEM_TEMP_MASK); 676 state = REG_GET_MASK(r, SENSOR_TEMP2_MEM_TEMP_MASK);
366 seq_printf(s, " MEM(%d)\n", translate_temp(state)); 677 seq_printf(s, " MEM(%d)\n", translate_temp(state));
367 678
679 if (ts->soc->use_ccroc)
680 return 0;
681
682 for (i = 0; i < ts->soc->num_ttgs; i++) {
683 seq_printf(s, "%s:\n", ttgs[i]->name);
684 for (level = 0; level < 4; level++) {
685 s32 v;
686 u32 mask;
687 u16 off = ttgs[i]->thermctl_lvl0_offset;
688
689 r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
690
691 mask = ttgs[i]->thermctl_lvl0_up_thresh_mask;
692 state = REG_GET_MASK(r, mask);
693 v = sign_extend32(state, ts->soc->bptt - 1);
694 v *= ts->soc->thresh_grain;
695 seq_printf(s, " %d: Up/Dn(%d /", level, v);
696
697 mask = ttgs[i]->thermctl_lvl0_dn_thresh_mask;
698 state = REG_GET_MASK(r, mask);
699 v = sign_extend32(state, ts->soc->bptt - 1);
700 v *= ts->soc->thresh_grain;
701 seq_printf(s, "%d ) ", v);
702
703 mask = THERMCTL_LVL0_CPU0_EN_MASK;
704 state = REG_GET_MASK(r, mask);
705 seq_printf(s, "En(%d) ", state);
706
707 mask = THERMCTL_LVL0_CPU0_CPU_THROT_MASK;
708 state = REG_GET_MASK(r, mask);
709 seq_puts(s, "CPU Throt");
710 if (!state)
711 seq_printf(s, "(%s) ", "none");
712 else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT)
713 seq_printf(s, "(%s) ", "L");
714 else if (state == THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY)
715 seq_printf(s, "(%s) ", "H");
716 else
717 seq_printf(s, "(%s) ", "H+L");
718
719 mask = THERMCTL_LVL0_CPU0_GPU_THROT_MASK;
720 state = REG_GET_MASK(r, mask);
721 seq_puts(s, "GPU Throt");
722 if (!state)
723 seq_printf(s, "(%s) ", "none");
724 else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT)
725 seq_printf(s, "(%s) ", "L");
726 else if (state == THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY)
727 seq_printf(s, "(%s) ", "H");
728 else
729 seq_printf(s, "(%s) ", "H+L");
730
731 mask = THERMCTL_LVL0_CPU0_STATUS_MASK;
732 state = REG_GET_MASK(r, mask);
733 seq_printf(s, "Status(%s)\n",
734 state == 0 ? "LO" :
735 state == 1 ? "In" :
736 state == 2 ? "Res" : "HI");
737 }
738 }
739
740 r = readl(ts->regs + THERMCTL_STATS_CTL);
741 seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
742 r & STATS_CTL_EN_UP ? "En" : "--",
743 r & STATS_CTL_EN_DN ? "En" : "--");
744
745 for (level = 0; level < 4; level++) {
746 u16 off;
747
748 off = THERMCTL_LVL0_UP_STATS;
749 r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
750 seq_printf(s, " Level_%d Up(%d) ", level, r);
751
752 off = THERMCTL_LVL0_DN_STATS;
753 r = readl(ts->regs + THERMCTL_LVL_REG(off, level));
754 seq_printf(s, "Dn(%d)\n", r);
755 }
756
368 r = readl(ts->regs + THERMCTL_THERMTRIP_CTL); 757 r = readl(ts->regs + THERMCTL_THERMTRIP_CTL);
369 state = REG_GET_MASK(r, ttgs[0]->thermtrip_any_en_mask); 758 state = REG_GET_MASK(r, ttgs[0]->thermtrip_any_en_mask);
370 seq_printf(s, "Thermtrip Any En(%d)\n", state); 759 seq_printf(s, "Thermtrip Any En(%d)\n", state);
@@ -376,6 +765,27 @@ static int regs_show(struct seq_file *s, void *data)
376 seq_printf(s, "Thresh(%d)\n", state); 765 seq_printf(s, "Thresh(%d)\n", state);
377 } 766 }
378 767
768 r = readl(ts->regs + THROT_GLOBAL_CFG);
769 seq_puts(s, "\n");
770 seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
771
772 seq_puts(s, "---------------------------------------------------\n");
773 r = readl(ts->regs + THROT_STATUS);
774 state = REG_GET_MASK(r, THROT_STATUS_BREACH_MASK);
775 seq_printf(s, "THROT STATUS: breach(%d) ", state);
776 state = REG_GET_MASK(r, THROT_STATUS_STATE_MASK);
777 seq_printf(s, "state(%d) ", state);
778 state = REG_GET_MASK(r, THROT_STATUS_ENABLED_MASK);
779 seq_printf(s, "enabled(%d)\n", state);
780
781 r = readl(ts->regs + CPU_PSKIP_STATUS);
782 state = REG_GET_MASK(r, XPU_PSKIP_STATUS_M_MASK);
783 seq_printf(s, "CPU PSKIP STATUS: M(%d) ", state);
784 state = REG_GET_MASK(r, XPU_PSKIP_STATUS_N_MASK);
785 seq_printf(s, "N(%d) ", state);
786 state = REG_GET_MASK(r, XPU_PSKIP_STATUS_ENABLED_MASK);
787 seq_printf(s, "enabled(%d)\n", state);
788
379 return 0; 789 return 0;
380} 790}
381 791
@@ -449,6 +859,204 @@ static int soctherm_clk_enable(struct platform_device *pdev, bool enable)
449 return 0; 859 return 0;
450} 860}
451 861
862static int throt_get_cdev_max_state(struct thermal_cooling_device *cdev,
863 unsigned long *max_state)
864{
865 *max_state = 1;
866 return 0;
867}
868
869static int throt_get_cdev_cur_state(struct thermal_cooling_device *cdev,
870 unsigned long *cur_state)
871{
872 struct tegra_soctherm *ts = cdev->devdata;
873 u32 r;
874
875 r = readl(ts->regs + THROT_STATUS);
876 if (REG_GET_MASK(r, THROT_STATUS_STATE_MASK))
877 *cur_state = 1;
878 else
879 *cur_state = 0;
880
881 return 0;
882}
883
884static int throt_set_cdev_state(struct thermal_cooling_device *cdev,
885 unsigned long cur_state)
886{
887 return 0;
888}
889
890static struct thermal_cooling_device_ops throt_cooling_ops = {
891 .get_max_state = throt_get_cdev_max_state,
892 .get_cur_state = throt_get_cdev_cur_state,
893 .set_cur_state = throt_set_cdev_state,
894};
895
896/**
897 * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
898 * and register them as cooling devices.
899 */
900static void soctherm_init_hw_throt_cdev(struct platform_device *pdev)
901{
902 struct device *dev = &pdev->dev;
903 struct tegra_soctherm *ts = dev_get_drvdata(dev);
904 struct device_node *np_stc, *np_stcc;
905 const char *name;
906 u32 val;
907 int i, r;
908
909 for (i = 0; i < THROTTLE_SIZE; i++) {
910 ts->throt_cfgs[i].name = throt_names[i];
911 ts->throt_cfgs[i].id = i;
912 ts->throt_cfgs[i].init = false;
913 }
914
915 np_stc = of_get_child_by_name(dev->of_node, "throttle-cfgs");
916 if (!np_stc) {
917 dev_info(dev,
918 "throttle-cfg: no throttle-cfgs - not enabling\n");
919 return;
920 }
921
922 for_each_child_of_node(np_stc, np_stcc) {
923 struct soctherm_throt_cfg *stc;
924 struct thermal_cooling_device *tcd;
925
926 name = np_stcc->name;
927 stc = find_throttle_cfg_by_name(ts, name);
928 if (!stc) {
929 dev_err(dev,
930 "throttle-cfg: could not find %s\n", name);
931 continue;
932 }
933
934 r = of_property_read_u32(np_stcc, "nvidia,priority", &val);
935 if (r) {
936 dev_info(dev,
937 "throttle-cfg: %s: missing priority\n", name);
938 continue;
939 }
940 stc->priority = val;
941
942 r = of_property_read_u32(np_stcc, "nvidia,cpu-throt-percent",
943 &val);
944 if (r) {
945 dev_info(dev,
946 "throttle-cfg: %s: missing cpu-throt-percent\n",
947 name);
948 continue;
949 }
950 stc->cpu_throt_depth = val;
951
952 tcd = thermal_of_cooling_device_register(np_stcc,
953 (char *)name, ts,
954 &throt_cooling_ops);
955 of_node_put(np_stcc);
956 if (IS_ERR_OR_NULL(tcd)) {
957 dev_err(dev,
958 "throttle-cfg: %s: failed to register cooling device\n",
959 name);
960 continue;
961 }
962
963 stc->cdev = tcd;
964 stc->init = true;
965 }
966
967 of_node_put(np_stc);
968}
969
970/**
971 * throttlectl_cpu_mn() - program CPU pulse skipper configuration
972 * @throt: the LIGHT/HEAVY of throttle event id
973 *
974 * Pulse skippers are used to throttle clock frequencies. This
975 * function programs the pulse skippers based on @throt and platform
976 * data. This function is used for CPUs that have "remote" pulse
977 * skipper control, e.g., the CPU pulse skipper is controlled by the
978 * SOC_THERM IP block. (SOC_THERM is located outside the CPU
979 * complex.)
980 */
981static void throttlectl_cpu_mn(struct tegra_soctherm *ts,
982 enum soctherm_throttle_id throt)
983{
984 u32 r;
985 int depth;
986 u8 dividend;
987
988 depth = ts->throt_cfgs[throt].cpu_throt_depth;
989 dividend = THROT_DEPTH_DIVIDEND(depth);
990
991 r = readl(ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
992 r = REG_SET_MASK(r, THROT_PSKIP_CTRL_ENABLE_MASK, 1);
993 r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVIDEND_MASK, dividend);
994 r = REG_SET_MASK(r, THROT_PSKIP_CTRL_DIVISOR_MASK, 0xff);
995 writel(r, ts->regs + THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
996
997 r = readl(ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
998 r = REG_SET_MASK(r, THROT_PSKIP_RAMP_DURATION_MASK, 0xff);
999 r = REG_SET_MASK(r, THROT_PSKIP_RAMP_STEP_MASK, 0xf);
1000 writel(r, ts->regs + THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
1001}
1002
1003/**
1004 * soctherm_throttle_program() - programs pulse skippers' configuration
1005 * @throt: the LIGHT/HEAVY of the throttle event id.
1006 *
1007 * Pulse skippers are used to throttle clock frequencies.
1008 * This function programs the pulse skippers.
1009 */
1010static void soctherm_throttle_program(struct tegra_soctherm *ts,
1011 enum soctherm_throttle_id throt)
1012{
1013 u32 r;
1014 struct soctherm_throt_cfg stc = ts->throt_cfgs[throt];
1015
1016 if (!stc.init)
1017 return;
1018
1019 /* Setup PSKIP parameters */
1020 throttlectl_cpu_mn(ts, throt);
1021
1022 r = REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK, stc.priority);
1023 writel(r, ts->regs + THROT_PRIORITY_CTRL(throt));
1024
1025 r = REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK, 0);
1026 writel(r, ts->regs + THROT_DELAY_CTRL(throt));
1027
1028 r = readl(ts->regs + THROT_PRIORITY_LOCK);
1029 r = REG_GET_MASK(r, THROT_PRIORITY_LOCK_PRIORITY_MASK);
1030 if (r >= stc.priority)
1031 return;
1032 r = REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK,
1033 stc.priority);
1034 writel(r, ts->regs + THROT_PRIORITY_LOCK);
1035}
1036
1037static void tegra_soctherm_throttle(struct device *dev)
1038{
1039 struct tegra_soctherm *ts = dev_get_drvdata(dev);
1040 u32 v;
1041 int i;
1042
1043 /* Thermal HW throttle programming */
1044 for (i = 0; i < THROTTLE_SIZE; i++)
1045 soctherm_throttle_program(ts, i);
1046
1047 v = REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK, 1);
1048 writel(v, ts->regs + THROT_GLOBAL_CFG);
1049
1050 v = clk_readl(ts, CAR_SUPER_CCLKG_DIVIDER);
1051 v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
1052 clk_writel(ts, v, CAR_SUPER_CCLKG_DIVIDER);
1053
1054 /* initialize stats collection */
1055 v = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
1056 STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
1057 writel(v, ts->regs + THERMCTL_STATS_CTL);
1058}
1059
452static void soctherm_init(struct platform_device *pdev) 1060static void soctherm_init(struct platform_device *pdev)
453{ 1061{
454 struct tegra_soctherm *tegra = platform_get_drvdata(pdev); 1062 struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
@@ -475,6 +1083,12 @@ static void soctherm_init(struct platform_device *pdev)
475 } 1083 }
476 writel(pdiv, tegra->regs + SENSOR_PDIV); 1084 writel(pdiv, tegra->regs + SENSOR_PDIV);
477 writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF); 1085 writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF);
1086
1087 if (tegra->soc->use_ccroc)
1088 return;
1089
1090 /* Configure hw throttle */
1091 tegra_soctherm_throttle(&pdev->dev);
478} 1092}
479 1093
480static const struct of_device_id tegra_soctherm_of_match[] = { 1094static const struct of_device_id tegra_soctherm_of_match[] = {
@@ -527,10 +1141,23 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
527 1141
528 tegra->soc = soc; 1142 tegra->soc = soc;
529 1143
530 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1144 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1145 "soctherm-reg");
531 tegra->regs = devm_ioremap_resource(&pdev->dev, res); 1146 tegra->regs = devm_ioremap_resource(&pdev->dev, res);
532 if (IS_ERR(tegra->regs)) 1147 if (IS_ERR(tegra->regs)) {
1148 dev_err(&pdev->dev, "can't get soctherm registers");
533 return PTR_ERR(tegra->regs); 1149 return PTR_ERR(tegra->regs);
1150 }
1151
1152 if (!tegra->soc->use_ccroc) {
1153 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1154 "car-reg");
1155 tegra->clk_regs = devm_ioremap_resource(&pdev->dev, res);
1156 if (IS_ERR(tegra->clk_regs)) {
1157 dev_err(&pdev->dev, "can't get car clk registers");
1158 return PTR_ERR(tegra->clk_regs);
1159 }
1160 }
534 1161
535 tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm"); 1162 tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm");
536 if (IS_ERR(tegra->reset)) { 1163 if (IS_ERR(tegra->reset)) {
@@ -580,6 +1207,9 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
580 if (err) 1207 if (err)
581 return err; 1208 return err;
582 1209
1210 if (!tegra->soc->use_ccroc)
1211 soctherm_init_hw_throt_cdev(pdev);
1212
583 soctherm_init(pdev); 1213 soctherm_init(pdev);
584 1214
585 for (i = 0; i < soc->num_ttgs; ++i) { 1215 for (i = 0; i < soc->num_ttgs; ++i) {
@@ -593,6 +1223,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
593 zone->reg = tegra->regs + soc->ttgs[i]->sensor_temp_offset; 1223 zone->reg = tegra->regs + soc->ttgs[i]->sensor_temp_offset;
594 zone->dev = &pdev->dev; 1224 zone->dev = &pdev->dev;
595 zone->sg = soc->ttgs[i]; 1225 zone->sg = soc->ttgs[i];
1226 zone->ts = tegra;
596 1227
597 z = devm_thermal_zone_of_sensor_register(&pdev->dev, 1228 z = devm_thermal_zone_of_sensor_register(&pdev->dev,
598 soc->ttgs[i]->id, zone, 1229 soc->ttgs[i]->id, zone,
@@ -608,7 +1239,9 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
608 tegra->thermctl_tzs[soc->ttgs[i]->id] = z; 1239 tegra->thermctl_tzs[soc->ttgs[i]->id] = z;
609 1240
610 /* Configure hw trip points */ 1241 /* Configure hw trip points */
611 tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z); 1242 err = tegra_soctherm_set_hwtrips(&pdev->dev, soc->ttgs[i], z);
1243 if (err)
1244 goto disable_clocks;
612 } 1245 }
613 1246
614 soctherm_debug_init(pdev); 1247 soctherm_debug_init(pdev);
@@ -661,7 +1294,12 @@ static int __maybe_unused soctherm_resume(struct device *dev)
661 struct thermal_zone_device *tz; 1294 struct thermal_zone_device *tz;
662 1295
663 tz = tegra->thermctl_tzs[soc->ttgs[i]->id]; 1296 tz = tegra->thermctl_tzs[soc->ttgs[i]->id];
664 tegra_soctherm_set_hwtrips(dev, soc->ttgs[i], tz); 1297 err = tegra_soctherm_set_hwtrips(dev, soc->ttgs[i], tz);
1298 if (err) {
1299 dev_err(&pdev->dev,
1300 "Resume failed: set hwtrips failed\n");
1301 return err;
1302 }
665 } 1303 }
666 1304
667 return 0; 1305 return 0;
diff --git a/drivers/thermal/tegra/soctherm.h b/drivers/thermal/tegra/soctherm.h
index 28e18ec4b4c3..e96ca73fd780 100644
--- a/drivers/thermal/tegra/soctherm.h
+++ b/drivers/thermal/tegra/soctherm.h
@@ -15,6 +15,11 @@
15#ifndef __DRIVERS_THERMAL_TEGRA_SOCTHERM_H 15#ifndef __DRIVERS_THERMAL_TEGRA_SOCTHERM_H
16#define __DRIVERS_THERMAL_TEGRA_SOCTHERM_H 16#define __DRIVERS_THERMAL_TEGRA_SOCTHERM_H
17 17
18#define THERMCTL_LEVEL0_GROUP_CPU 0x0
19#define THERMCTL_LEVEL0_GROUP_GPU 0x4
20#define THERMCTL_LEVEL0_GROUP_MEM 0x8
21#define THERMCTL_LEVEL0_GROUP_TSENSE 0xc
22
18#define SENSOR_CONFIG2 8 23#define SENSOR_CONFIG2 8
19#define SENSOR_CONFIG2_THERMA_MASK (0xffff << 16) 24#define SENSOR_CONFIG2_THERMA_MASK (0xffff << 16)
20#define SENSOR_CONFIG2_THERMA_SHIFT 16 25#define SENSOR_CONFIG2_THERMA_SHIFT 16
@@ -65,6 +70,9 @@ struct tegra_tsensor_group {
65 u32 thermtrip_enable_mask; 70 u32 thermtrip_enable_mask;
66 u32 thermtrip_any_en_mask; 71 u32 thermtrip_any_en_mask;
67 u32 thermtrip_threshold_mask; 72 u32 thermtrip_threshold_mask;
73 u16 thermctl_lvl0_offset;
74 u32 thermctl_lvl0_up_thresh_mask;
75 u32 thermctl_lvl0_dn_thresh_mask;
68}; 76};
69 77
70struct tegra_tsensor_configuration { 78struct tegra_tsensor_configuration {
@@ -103,6 +111,8 @@ struct tegra_soctherm_soc {
103 const unsigned int num_ttgs; 111 const unsigned int num_ttgs;
104 const struct tegra_soctherm_fuse *tfuse; 112 const struct tegra_soctherm_fuse *tfuse;
105 const int thresh_grain; 113 const int thresh_grain;
114 const unsigned int bptt;
115 const bool use_ccroc;
106}; 116};
107 117
108int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse, 118int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse,
diff --git a/drivers/thermal/tegra/tegra124-soctherm.c b/drivers/thermal/tegra/tegra124-soctherm.c
index beb9d36b9c8a..36768630f78c 100644
--- a/drivers/thermal/tegra/tegra124-soctherm.c
+++ b/drivers/thermal/tegra/tegra124-soctherm.c
@@ -28,7 +28,11 @@
28#define TEGRA124_THERMTRIP_CPU_THRESH_MASK (0xff << 8) 28#define TEGRA124_THERMTRIP_CPU_THRESH_MASK (0xff << 8)
29#define TEGRA124_THERMTRIP_TSENSE_THRESH_MASK 0xff 29#define TEGRA124_THERMTRIP_TSENSE_THRESH_MASK 0xff
30 30
31#define TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK (0xff << 17)
32#define TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK (0xff << 9)
33
31#define TEGRA124_THRESH_GRAIN 1000 34#define TEGRA124_THRESH_GRAIN 1000
35#define TEGRA124_BPTT 8
32 36
33static const struct tegra_tsensor_configuration tegra124_tsensor_config = { 37static const struct tegra_tsensor_configuration tegra124_tsensor_config = {
34 .tall = 16300, 38 .tall = 16300,
@@ -51,6 +55,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
51 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 55 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
52 .thermtrip_enable_mask = TEGRA124_THERMTRIP_CPU_EN_MASK, 56 .thermtrip_enable_mask = TEGRA124_THERMTRIP_CPU_EN_MASK,
53 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_CPU_THRESH_MASK, 57 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_CPU_THRESH_MASK,
58 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
59 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
60 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
54}; 61};
55 62
56static const struct tegra_tsensor_group tegra124_tsensor_group_gpu = { 63static const struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
@@ -66,6 +73,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
66 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 73 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
67 .thermtrip_enable_mask = TEGRA124_THERMTRIP_GPU_EN_MASK, 74 .thermtrip_enable_mask = TEGRA124_THERMTRIP_GPU_EN_MASK,
68 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK, 75 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK,
76 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
77 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
78 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
69}; 79};
70 80
71static const struct tegra_tsensor_group tegra124_tsensor_group_pll = { 81static const struct tegra_tsensor_group tegra124_tsensor_group_pll = {
@@ -79,6 +89,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_pll = {
79 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 89 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
80 .thermtrip_enable_mask = TEGRA124_THERMTRIP_TSENSE_EN_MASK, 90 .thermtrip_enable_mask = TEGRA124_THERMTRIP_TSENSE_EN_MASK,
81 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_TSENSE_THRESH_MASK, 91 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_TSENSE_THRESH_MASK,
92 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
93 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
94 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
82}; 95};
83 96
84static const struct tegra_tsensor_group tegra124_tsensor_group_mem = { 97static const struct tegra_tsensor_group tegra124_tsensor_group_mem = {
@@ -94,6 +107,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_mem = {
94 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK, 107 .thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
95 .thermtrip_enable_mask = TEGRA124_THERMTRIP_MEM_EN_MASK, 108 .thermtrip_enable_mask = TEGRA124_THERMTRIP_MEM_EN_MASK,
96 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK, 109 .thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK,
110 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
111 .thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
112 .thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
97}; 113};
98 114
99static const struct tegra_tsensor_group *tegra124_tsensor_groups[] = { 115static const struct tegra_tsensor_group *tegra124_tsensor_groups[] = {
@@ -193,4 +209,6 @@ const struct tegra_soctherm_soc tegra124_soctherm = {
193 .num_ttgs = ARRAY_SIZE(tegra124_tsensor_groups), 209 .num_ttgs = ARRAY_SIZE(tegra124_tsensor_groups),
194 .tfuse = &tegra124_soctherm_fuse, 210 .tfuse = &tegra124_soctherm_fuse,
195 .thresh_grain = TEGRA124_THRESH_GRAIN, 211 .thresh_grain = TEGRA124_THRESH_GRAIN,
212 .bptt = TEGRA124_BPTT,
213 .use_ccroc = false,
196}; 214};
diff --git a/drivers/thermal/tegra/tegra132-soctherm.c b/drivers/thermal/tegra/tegra132-soctherm.c
index e2aa84e1b307..ae5d61af2df3 100644
--- a/drivers/thermal/tegra/tegra132-soctherm.c
+++ b/drivers/thermal/tegra/tegra132-soctherm.c
@@ -193,4 +193,5 @@ const struct tegra_soctherm_soc tegra132_soctherm = {
193 .num_ttgs = ARRAY_SIZE(tegra132_tsensor_groups), 193 .num_ttgs = ARRAY_SIZE(tegra132_tsensor_groups),
194 .tfuse = &tegra132_soctherm_fuse, 194 .tfuse = &tegra132_soctherm_fuse,
195 .thresh_grain = TEGRA132_THRESH_GRAIN, 195 .thresh_grain = TEGRA132_THRESH_GRAIN,
196 .use_ccroc = true,
196}; 197};
diff --git a/drivers/thermal/tegra/tegra210-soctherm.c b/drivers/thermal/tegra/tegra210-soctherm.c
index 19cc0ab66f0e..ad53169a8e95 100644
--- a/drivers/thermal/tegra/tegra210-soctherm.c
+++ b/drivers/thermal/tegra/tegra210-soctherm.c
@@ -29,7 +29,11 @@
29#define TEGRA210_THERMTRIP_CPU_THRESH_MASK (0x1ff << 9) 29#define TEGRA210_THERMTRIP_CPU_THRESH_MASK (0x1ff << 9)
30#define TEGRA210_THERMTRIP_TSENSE_THRESH_MASK 0x1ff 30#define TEGRA210_THERMTRIP_TSENSE_THRESH_MASK 0x1ff
31 31
32#define TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK (0x1ff << 18)
33#define TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK (0x1ff << 9)
34
32#define TEGRA210_THRESH_GRAIN 500 35#define TEGRA210_THRESH_GRAIN 500
36#define TEGRA210_BPTT 9
33 37
34static const struct tegra_tsensor_configuration tegra210_tsensor_config = { 38static const struct tegra_tsensor_configuration tegra210_tsensor_config = {
35 .tall = 16300, 39 .tall = 16300,
@@ -52,6 +56,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_cpu = {
52 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 56 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
53 .thermtrip_enable_mask = TEGRA210_THERMTRIP_CPU_EN_MASK, 57 .thermtrip_enable_mask = TEGRA210_THERMTRIP_CPU_EN_MASK,
54 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_CPU_THRESH_MASK, 58 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_CPU_THRESH_MASK,
59 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
60 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
61 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
55}; 62};
56 63
57static const struct tegra_tsensor_group tegra210_tsensor_group_gpu = { 64static const struct tegra_tsensor_group tegra210_tsensor_group_gpu = {
@@ -67,6 +74,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_gpu = {
67 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 74 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
68 .thermtrip_enable_mask = TEGRA210_THERMTRIP_GPU_EN_MASK, 75 .thermtrip_enable_mask = TEGRA210_THERMTRIP_GPU_EN_MASK,
69 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK, 76 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK,
77 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
78 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
79 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
70}; 80};
71 81
72static const struct tegra_tsensor_group tegra210_tsensor_group_pll = { 82static const struct tegra_tsensor_group tegra210_tsensor_group_pll = {
@@ -80,6 +90,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_pll = {
80 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 90 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
81 .thermtrip_enable_mask = TEGRA210_THERMTRIP_TSENSE_EN_MASK, 91 .thermtrip_enable_mask = TEGRA210_THERMTRIP_TSENSE_EN_MASK,
82 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_TSENSE_THRESH_MASK, 92 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_TSENSE_THRESH_MASK,
93 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
94 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
95 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
83}; 96};
84 97
85static const struct tegra_tsensor_group tegra210_tsensor_group_mem = { 98static const struct tegra_tsensor_group tegra210_tsensor_group_mem = {
@@ -95,6 +108,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_mem = {
95 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK, 108 .thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
96 .thermtrip_enable_mask = TEGRA210_THERMTRIP_MEM_EN_MASK, 109 .thermtrip_enable_mask = TEGRA210_THERMTRIP_MEM_EN_MASK,
97 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK, 110 .thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK,
111 .thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
112 .thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
113 .thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
98}; 114};
99 115
100static const struct tegra_tsensor_group *tegra210_tsensor_groups[] = { 116static const struct tegra_tsensor_group *tegra210_tsensor_groups[] = {
@@ -194,4 +210,6 @@ const struct tegra_soctherm_soc tegra210_soctherm = {
194 .num_ttgs = ARRAY_SIZE(tegra210_tsensor_groups), 210 .num_ttgs = ARRAY_SIZE(tegra210_tsensor_groups),
195 .tfuse = &tegra210_soctherm_fuse, 211 .tfuse = &tegra210_soctherm_fuse,
196 .thresh_grain = TEGRA210_THRESH_GRAIN, 212 .thresh_grain = TEGRA210_THRESH_GRAIN,
213 .bptt = TEGRA210_BPTT,
214 .use_ccroc = false,
197}; 215};