2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
5 * Mikko Perttunen <mperttunen@nvidia.com>
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
18 #include <linux/debugfs.h>
19 #include <linux/bitops.h>
20 #include <linux/clk.h>
21 #include <linux/delay.h>
22 #include <linux/err.h>
23 #include <linux/interrupt.h>
25 #include <linux/module.h>
27 #include <linux/platform_device.h>
28 #include <linux/reset.h>
29 #include <linux/thermal.h>
31 #include <dt-bindings/thermal/tegra124-soctherm.h>
33 #include "../thermal_core.h"
36 #define SENSOR_CONFIG0 0
37 #define SENSOR_CONFIG0_STOP BIT(0)
38 #define SENSOR_CONFIG0_CPTR_OVER BIT(2)
39 #define SENSOR_CONFIG0_OVER BIT(3)
40 #define SENSOR_CONFIG0_TCALC_OVER BIT(4)
41 #define SENSOR_CONFIG0_TALL_MASK (0xfffff << 8)
42 #define SENSOR_CONFIG0_TALL_SHIFT 8
44 #define SENSOR_CONFIG1 4
45 #define SENSOR_CONFIG1_TSAMPLE_MASK 0x3ff
46 #define SENSOR_CONFIG1_TSAMPLE_SHIFT 0
47 #define SENSOR_CONFIG1_TIDDQ_EN_MASK (0x3f << 15)
48 #define SENSOR_CONFIG1_TIDDQ_EN_SHIFT 15
49 #define SENSOR_CONFIG1_TEN_COUNT_MASK (0x3f << 24)
50 #define SENSOR_CONFIG1_TEN_COUNT_SHIFT 24
51 #define SENSOR_CONFIG1_TEMP_ENABLE BIT(31)
54 * SENSOR_CONFIG2 is defined in soctherm.h
55 * because, it will be used by tegra_soctherm_fuse.c
58 #define SENSOR_STATUS0 0xc
59 #define SENSOR_STATUS0_VALID_MASK BIT(31)
60 #define SENSOR_STATUS0_CAPTURE_MASK 0xffff
62 #define SENSOR_STATUS1 0x10
63 #define SENSOR_STATUS1_TEMP_VALID_MASK BIT(31)
64 #define SENSOR_STATUS1_TEMP_MASK 0xffff
66 #define READBACK_VALUE_MASK 0xff00
67 #define READBACK_VALUE_SHIFT 8
68 #define READBACK_ADD_HALF BIT(7)
69 #define READBACK_NEGATE BIT(0)
72 * THERMCTL_LEVEL0_GROUP_CPU is defined in soctherm.h
73 * because it will be used by tegraxxx_soctherm.c
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
85 #define THERMCTL_LVL0_UP_STATS 0x10
86 #define THERMCTL_LVL0_DN_STATS 0x14
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
94 #define THROT_GLOBAL_CFG 0x400
95 #define THROT_GLOBAL_ENB_MASK BIT(0)
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)
103 #define THROT_PRIORITY_LOCK 0x424
104 #define THROT_PRIORITY_LOCK_PRIORITY_MASK 0xff
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)
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
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 */
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
129 #define THROT_PRIORITY_LITE 0x444
130 #define THROT_PRIORITY_LITE_PRIO_MASK 0xff
132 #define THROT_DELAY_LITE 0x448
133 #define THROT_DELAY_LITE_DELAY_MASK 0xff
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)
139 /* ccroc register offsets needed for enabling HW throttling for Tegra132 */
140 #define CCROC_SUPER_CCLKG_DIVIDER 0x024
142 #define CCROC_GLOBAL_CFG 0x148
144 #define CCROC_THROT_PSKIP_RAMP_CPU 0x150
145 #define CCROC_THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK BIT(31)
146 #define CCROC_THROT_PSKIP_RAMP_DURATION_MASK (0xffff << 8)
147 #define CCROC_THROT_PSKIP_RAMP_STEP_MASK 0xff
149 #define CCROC_THROT_PSKIP_CTRL_CPU 0x154
150 #define CCROC_THROT_PSKIP_CTRL_ENB_MASK BIT(31)
151 #define CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK (0xff << 8)
152 #define CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
154 /* get val from register(r) mask bits(m) */
155 #define REG_GET_MASK(r, m) (((r) & (m)) >> (ffs(m) - 1))
156 /* set val(v) to mask bits(m) of register(r) */
157 #define REG_SET_MASK(r, m, v) (((r) & ~(m)) | \
158 (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
160 /* get dividend from the depth */
161 #define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
163 /* get THROT_PSKIP_xxx offset per LIGHT/HEAVY throt and CPU/GPU dev */
164 #define THROT_OFFSET 0x30
165 #define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \
166 (THROT_OFFSET * throt) + (8 * dev))
167 #define THROT_PSKIP_RAMP(throt, dev) (THROT_PSKIP_RAMP_LITE_CPU + \
168 (THROT_OFFSET * throt) + (8 * dev))
170 /* get THROT_xxx_CTRL offset per LIGHT/HEAVY throt */
171 #define THROT_PRIORITY_CTRL(throt) (THROT_PRIORITY_LITE + \
172 (THROT_OFFSET * throt))
173 #define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \
174 (THROT_OFFSET * throt))
176 /* get CCROC_THROT_PSKIP_xxx offset per HIGH/MED/LOW vect*/
177 #define CCROC_THROT_OFFSET 0x0c
178 #define CCROC_THROT_PSKIP_CTRL_CPU_REG(vect) (CCROC_THROT_PSKIP_CTRL_CPU + \
179 (CCROC_THROT_OFFSET * vect))
180 #define CCROC_THROT_PSKIP_RAMP_CPU_REG(vect) (CCROC_THROT_PSKIP_RAMP_CPU + \
181 (CCROC_THROT_OFFSET * vect))
183 /* get THERMCTL_LEVELx offset per CPU/GPU/MEM/TSENSE rg and LEVEL0~3 lv */
184 #define THERMCTL_LVL_REGS_SIZE 0x20
185 #define THERMCTL_LVL_REG(rg, lv) ((rg) + ((lv) * THERMCTL_LVL_REGS_SIZE))
187 static const int min_low_temp
= -127000;
188 static const int max_high_temp
= 127000;
190 enum soctherm_throttle_id
{
196 enum soctherm_throttle_dev_id
{
197 THROTTLE_DEV_CPU
= 0,
202 static const char *const throt_names
[] = {
203 [THROTTLE_LIGHT
] = "light",
204 [THROTTLE_HEAVY
] = "heavy",
207 struct tegra_soctherm
;
208 struct tegra_thermctl_zone
{
211 struct tegra_soctherm
*ts
;
212 struct thermal_zone_device
*tz
;
213 const struct tegra_tsensor_group
*sg
;
216 struct soctherm_throt_cfg
{
222 struct thermal_cooling_device
*cdev
;
226 struct tegra_soctherm
{
227 struct reset_control
*reset
;
228 struct clk
*clock_tsensor
;
229 struct clk
*clock_soctherm
;
231 void __iomem
*clk_regs
;
232 void __iomem
*ccroc_regs
;
235 struct thermal_zone_device
**thermctl_tzs
;
236 struct tegra_soctherm_soc
*soc
;
238 struct soctherm_throt_cfg throt_cfgs
[THROTTLE_SIZE
];
240 struct dentry
*debugfs_dir
;
244 * clk_writel() - writes a value to a CAR register
245 * @ts: pointer to a struct tegra_soctherm
246 * @v: the value to write
247 * @reg: the register offset
249 * Writes @v to @reg. No return value.
251 static inline void clk_writel(struct tegra_soctherm
*ts
, u32 value
, u32 reg
)
253 writel(value
, (ts
->clk_regs
+ reg
));
257 * clk_readl() - reads specified register from CAR IP block
258 * @ts: pointer to a struct tegra_soctherm
259 * @reg: register address to be read
261 * Return: the value of the register
263 static inline u32
clk_readl(struct tegra_soctherm
*ts
, u32 reg
)
265 return readl(ts
->clk_regs
+ reg
);
269 * ccroc_writel() - writes a value to a CCROC register
270 * @ts: pointer to a struct tegra_soctherm
271 * @v: the value to write
272 * @reg: the register offset
274 * Writes @v to @reg. No return value.
276 static inline void ccroc_writel(struct tegra_soctherm
*ts
, u32 value
, u32 reg
)
278 writel(value
, (ts
->ccroc_regs
+ reg
));
282 * ccroc_readl() - reads specified register from CCROC IP block
283 * @ts: pointer to a struct tegra_soctherm
284 * @reg: register address to be read
286 * Return: the value of the register
288 static inline u32
ccroc_readl(struct tegra_soctherm
*ts
, u32 reg
)
290 return readl(ts
->ccroc_regs
+ reg
);
293 static void enable_tsensor(struct tegra_soctherm
*tegra
, unsigned int i
)
295 const struct tegra_tsensor
*sensor
= &tegra
->soc
->tsensors
[i
];
296 void __iomem
*base
= tegra
->regs
+ sensor
->base
;
299 val
= sensor
->config
->tall
<< SENSOR_CONFIG0_TALL_SHIFT
;
300 writel(val
, base
+ SENSOR_CONFIG0
);
302 val
= (sensor
->config
->tsample
- 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT
;
303 val
|= sensor
->config
->tiddq_en
<< SENSOR_CONFIG1_TIDDQ_EN_SHIFT
;
304 val
|= sensor
->config
->ten_count
<< SENSOR_CONFIG1_TEN_COUNT_SHIFT
;
305 val
|= SENSOR_CONFIG1_TEMP_ENABLE
;
306 writel(val
, base
+ SENSOR_CONFIG1
);
308 writel(tegra
->calib
[i
], base
+ SENSOR_CONFIG2
);
312 * Translate from soctherm readback format to millicelsius.
313 * The soctherm readback format in bits is as follows:
315 * where T's contain the temperature in Celsius,
316 * H denotes an addition of 0.5 Celsius and N denotes negation
317 * of the final value.
319 static int translate_temp(u16 val
)
323 t
= ((val
& READBACK_VALUE_MASK
) >> READBACK_VALUE_SHIFT
) * 1000;
324 if (val
& READBACK_ADD_HALF
)
326 if (val
& READBACK_NEGATE
)
332 static int tegra_thermctl_get_temp(void *data
, int *out_temp
)
334 struct tegra_thermctl_zone
*zone
= data
;
337 val
= readl(zone
->reg
);
338 val
= REG_GET_MASK(val
, zone
->sg
->sensor_temp_mask
);
339 *out_temp
= translate_temp(val
);
345 * enforce_temp_range() - check and enforce temperature range [min, max]
346 * @trip_temp: the trip temperature to check
348 * Checks and enforces the permitted temperature range that SOC_THERM
349 * HW can support This is
350 * done while taking care of precision.
352 * Return: The precision adjusted capped temperature in millicelsius.
354 static int enforce_temp_range(struct device
*dev
, int trip_temp
)
358 temp
= clamp_val(trip_temp
, min_low_temp
, max_high_temp
);
359 if (temp
!= trip_temp
)
360 dev_info(dev
, "soctherm: trip temperature %d forced to %d\n",
366 * thermtrip_program() - Configures the hardware to shut down the
367 * system if a given sensor group reaches a given temperature
368 * @dev: ptr to the struct device for the SOC_THERM IP block
369 * @sg: pointer to the sensor group to set the thermtrip temperature for
370 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
372 * Sets the thermal trip threshold of the given sensor group to be the
373 * @trip_temp. If this threshold is crossed, the hardware will shut
376 * Note that, although @trip_temp is specified in millicelsius, the
377 * hardware is programmed in degrees Celsius.
379 * Return: 0 upon success, or %-EINVAL upon failure.
381 static int thermtrip_program(struct device
*dev
,
382 const struct tegra_tsensor_group
*sg
,
385 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
389 if (!sg
|| !sg
->thermtrip_threshold_mask
)
392 temp
= enforce_temp_range(dev
, trip_temp
) / ts
->soc
->thresh_grain
;
394 r
= readl(ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
395 r
= REG_SET_MASK(r
, sg
->thermtrip_threshold_mask
, temp
);
396 r
= REG_SET_MASK(r
, sg
->thermtrip_enable_mask
, 1);
397 r
= REG_SET_MASK(r
, sg
->thermtrip_any_en_mask
, 0);
398 writel(r
, ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
404 * throttrip_program() - Configures the hardware to throttle the
405 * pulse if a given sensor group reaches a given temperature
406 * @dev: ptr to the struct device for the SOC_THERM IP block
407 * @sg: pointer to the sensor group to set the thermtrip temperature for
408 * @stc: pointer to the throttle need to be triggered
409 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
411 * Sets the thermal trip threshold and throttle event of the given sensor
412 * group. If this threshold is crossed, the hardware will trigger the
415 * Note that, although @trip_temp is specified in millicelsius, the
416 * hardware is programmed in degrees Celsius.
418 * Return: 0 upon success, or %-EINVAL upon failure.
420 static int throttrip_program(struct device
*dev
,
421 const struct tegra_tsensor_group
*sg
,
422 struct soctherm_throt_cfg
*stc
,
425 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
426 int temp
, cpu_throt
, gpu_throt
;
430 if (!sg
|| !stc
|| !stc
->init
)
433 temp
= enforce_temp_range(dev
, trip_temp
) / ts
->soc
->thresh_grain
;
435 /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
437 reg_off
= THERMCTL_LVL_REG(sg
->thermctl_lvl0_offset
, throt
+ 1);
439 if (throt
== THROTTLE_LIGHT
) {
440 cpu_throt
= THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT
;
441 gpu_throt
= THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT
;
443 cpu_throt
= THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY
;
444 gpu_throt
= THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY
;
445 if (throt
!= THROTTLE_HEAVY
)
447 "invalid throt id %d - assuming HEAVY",
451 r
= readl(ts
->regs
+ reg_off
);
452 r
= REG_SET_MASK(r
, sg
->thermctl_lvl0_up_thresh_mask
, temp
);
453 r
= REG_SET_MASK(r
, sg
->thermctl_lvl0_dn_thresh_mask
, temp
);
454 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_CPU_THROT_MASK
, cpu_throt
);
455 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_GPU_THROT_MASK
, gpu_throt
);
456 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_EN_MASK
, 1);
457 writel(r
, ts
->regs
+ reg_off
);
462 static struct soctherm_throt_cfg
*
463 find_throttle_cfg_by_name(struct tegra_soctherm
*ts
, const char *name
)
467 for (i
= 0; ts
->throt_cfgs
[i
].name
; i
++)
468 if (!strcmp(ts
->throt_cfgs
[i
].name
, name
))
469 return &ts
->throt_cfgs
[i
];
474 static int tegra_thermctl_set_trip_temp(void *data
, int trip
, int temp
)
476 struct tegra_thermctl_zone
*zone
= data
;
477 struct thermal_zone_device
*tz
= zone
->tz
;
478 struct tegra_soctherm
*ts
= zone
->ts
;
479 const struct tegra_tsensor_group
*sg
= zone
->sg
;
480 struct device
*dev
= zone
->dev
;
481 enum thermal_trip_type type
;
487 ret
= tz
->ops
->get_trip_type(tz
, trip
, &type
);
491 if (type
== THERMAL_TRIP_CRITICAL
) {
492 return thermtrip_program(dev
, sg
, temp
);
493 } else if (type
== THERMAL_TRIP_HOT
) {
496 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
497 struct thermal_cooling_device
*cdev
;
498 struct soctherm_throt_cfg
*stc
;
500 if (!ts
->throt_cfgs
[i
].init
)
503 cdev
= ts
->throt_cfgs
[i
].cdev
;
504 if (get_thermal_instance(tz
, cdev
, trip
))
505 stc
= find_throttle_cfg_by_name(ts
, cdev
->type
);
509 return throttrip_program(dev
, sg
, stc
, temp
);
516 static const struct thermal_zone_of_device_ops tegra_of_thermal_ops
= {
517 .get_temp
= tegra_thermctl_get_temp
,
518 .set_trip_temp
= tegra_thermctl_set_trip_temp
,
521 static int get_hot_temp(struct thermal_zone_device
*tz
, int *trip
, int *temp
)
524 enum thermal_trip_type type
;
526 ntrips
= of_thermal_get_ntrips(tz
);
530 for (i
= 0; i
< ntrips
; i
++) {
531 ret
= tz
->ops
->get_trip_type(tz
, i
, &type
);
534 if (type
== THERMAL_TRIP_HOT
) {
535 ret
= tz
->ops
->get_trip_temp(tz
, i
, temp
);
547 * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
548 * @dev: struct device * of the SOC_THERM instance
550 * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
551 * "THROTTLE" trip points , using "critical" or "hot" type trip_temp
553 * After they have been configured, THERMTRIP or THROTTLE will take
554 * action when the configured SoC thermal sensor group reaches a
555 * certain temperature.
557 * Return: 0 upon success, or a negative error code on failure.
558 * "Success" does not mean that trips was enabled; it could also
559 * mean that no node was found in DT.
560 * THERMTRIP has been enabled successfully when a message similar to
561 * this one appears on the serial console:
562 * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
563 * THROTTLE has been enabled successfully when a message similar to
564 * this one appears on the serial console:
565 * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
567 static int tegra_soctherm_set_hwtrips(struct device
*dev
,
568 const struct tegra_tsensor_group
*sg
,
569 struct thermal_zone_device
*tz
)
571 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
572 struct soctherm_throt_cfg
*stc
;
573 int i
, trip
, temperature
;
576 ret
= tz
->ops
->get_crit_temp(tz
, &temperature
);
578 dev_warn(dev
, "thermtrip: %s: missing critical temperature\n",
583 ret
= thermtrip_program(dev
, sg
, temperature
);
585 dev_err(dev
, "thermtrip: %s: error during enable\n",
591 "thermtrip: will shut down when %s reaches %d mC\n",
592 sg
->name
, temperature
);
595 ret
= get_hot_temp(tz
, &trip
, &temperature
);
597 dev_warn(dev
, "throttrip: %s: missing hot temperature\n",
602 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
603 struct thermal_cooling_device
*cdev
;
605 if (!ts
->throt_cfgs
[i
].init
)
608 cdev
= ts
->throt_cfgs
[i
].cdev
;
609 if (get_thermal_instance(tz
, cdev
, trip
))
610 stc
= find_throttle_cfg_by_name(ts
, cdev
->type
);
614 ret
= throttrip_program(dev
, sg
, stc
, temperature
);
616 dev_err(dev
, "throttrip: %s: error during enable\n",
622 "throttrip: will throttle when %s reaches %d mC\n",
623 sg
->name
, temperature
);
627 if (i
== THROTTLE_SIZE
)
628 dev_warn(dev
, "throttrip: %s: missing throttle cdev\n",
634 #ifdef CONFIG_DEBUG_FS
635 static int regs_show(struct seq_file
*s
, void *data
)
637 struct platform_device
*pdev
= s
->private;
638 struct tegra_soctherm
*ts
= platform_get_drvdata(pdev
);
639 const struct tegra_tsensor
*tsensors
= ts
->soc
->tsensors
;
640 const struct tegra_tsensor_group
**ttgs
= ts
->soc
->ttgs
;
644 seq_puts(s
, "-----TSENSE (convert HW)-----\n");
646 for (i
= 0; i
< ts
->soc
->num_tsensors
; i
++) {
647 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG1
);
648 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TEMP_ENABLE
);
650 seq_printf(s
, "%s: ", tsensors
[i
].name
);
651 seq_printf(s
, "En(%d) ", state
);
658 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TIDDQ_EN_MASK
);
659 seq_printf(s
, "tiddq(%d) ", state
);
660 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TEN_COUNT_MASK
);
661 seq_printf(s
, "ten_count(%d) ", state
);
662 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TSAMPLE_MASK
);
663 seq_printf(s
, "tsample(%d) ", state
+ 1);
665 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_STATUS1
);
666 state
= REG_GET_MASK(r
, SENSOR_STATUS1_TEMP_VALID_MASK
);
667 seq_printf(s
, "Temp(%d/", state
);
668 state
= REG_GET_MASK(r
, SENSOR_STATUS1_TEMP_MASK
);
669 seq_printf(s
, "%d) ", translate_temp(state
));
671 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_STATUS0
);
672 state
= REG_GET_MASK(r
, SENSOR_STATUS0_VALID_MASK
);
673 seq_printf(s
, "Capture(%d/", state
);
674 state
= REG_GET_MASK(r
, SENSOR_STATUS0_CAPTURE_MASK
);
675 seq_printf(s
, "%d) ", state
);
677 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG0
);
678 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_STOP
);
679 seq_printf(s
, "Stop(%d) ", state
);
680 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_TALL_MASK
);
681 seq_printf(s
, "Tall(%d) ", state
);
682 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_TCALC_OVER
);
683 seq_printf(s
, "Over(%d/", state
);
684 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_OVER
);
685 seq_printf(s
, "%d/", state
);
686 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_CPTR_OVER
);
687 seq_printf(s
, "%d) ", state
);
689 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG2
);
690 state
= REG_GET_MASK(r
, SENSOR_CONFIG2_THERMA_MASK
);
691 seq_printf(s
, "Therm_A/B(%d/", state
);
692 state
= REG_GET_MASK(r
, SENSOR_CONFIG2_THERMB_MASK
);
693 seq_printf(s
, "%d)\n", (s16
)state
);
696 r
= readl(ts
->regs
+ SENSOR_PDIV
);
697 seq_printf(s
, "PDIV: 0x%x\n", r
);
699 r
= readl(ts
->regs
+ SENSOR_HOTSPOT_OFF
);
700 seq_printf(s
, "HOTSPOT: 0x%x\n", r
);
703 seq_puts(s
, "-----SOC_THERM-----\n");
705 r
= readl(ts
->regs
+ SENSOR_TEMP1
);
706 state
= REG_GET_MASK(r
, SENSOR_TEMP1_CPU_TEMP_MASK
);
707 seq_printf(s
, "Temperatures: CPU(%d) ", translate_temp(state
));
708 state
= REG_GET_MASK(r
, SENSOR_TEMP1_GPU_TEMP_MASK
);
709 seq_printf(s
, " GPU(%d) ", translate_temp(state
));
710 r
= readl(ts
->regs
+ SENSOR_TEMP2
);
711 state
= REG_GET_MASK(r
, SENSOR_TEMP2_PLLX_TEMP_MASK
);
712 seq_printf(s
, " PLLX(%d) ", translate_temp(state
));
713 state
= REG_GET_MASK(r
, SENSOR_TEMP2_MEM_TEMP_MASK
);
714 seq_printf(s
, " MEM(%d)\n", translate_temp(state
));
716 for (i
= 0; i
< ts
->soc
->num_ttgs
; i
++) {
717 seq_printf(s
, "%s:\n", ttgs
[i
]->name
);
718 for (level
= 0; level
< 4; level
++) {
721 u16 off
= ttgs
[i
]->thermctl_lvl0_offset
;
723 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
725 mask
= ttgs
[i
]->thermctl_lvl0_up_thresh_mask
;
726 state
= REG_GET_MASK(r
, mask
);
727 v
= sign_extend32(state
, ts
->soc
->bptt
- 1);
728 v
*= ts
->soc
->thresh_grain
;
729 seq_printf(s
, " %d: Up/Dn(%d /", level
, v
);
731 mask
= ttgs
[i
]->thermctl_lvl0_dn_thresh_mask
;
732 state
= REG_GET_MASK(r
, mask
);
733 v
= sign_extend32(state
, ts
->soc
->bptt
- 1);
734 v
*= ts
->soc
->thresh_grain
;
735 seq_printf(s
, "%d ) ", v
);
737 mask
= THERMCTL_LVL0_CPU0_EN_MASK
;
738 state
= REG_GET_MASK(r
, mask
);
739 seq_printf(s
, "En(%d) ", state
);
741 mask
= THERMCTL_LVL0_CPU0_CPU_THROT_MASK
;
742 state
= REG_GET_MASK(r
, mask
);
743 seq_puts(s
, "CPU Throt");
745 seq_printf(s
, "(%s) ", "none");
746 else if (state
== THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT
)
747 seq_printf(s
, "(%s) ", "L");
748 else if (state
== THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY
)
749 seq_printf(s
, "(%s) ", "H");
751 seq_printf(s
, "(%s) ", "H+L");
753 mask
= THERMCTL_LVL0_CPU0_GPU_THROT_MASK
;
754 state
= REG_GET_MASK(r
, mask
);
755 seq_puts(s
, "GPU Throt");
757 seq_printf(s
, "(%s) ", "none");
758 else if (state
== THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT
)
759 seq_printf(s
, "(%s) ", "L");
760 else if (state
== THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY
)
761 seq_printf(s
, "(%s) ", "H");
763 seq_printf(s
, "(%s) ", "H+L");
765 mask
= THERMCTL_LVL0_CPU0_STATUS_MASK
;
766 state
= REG_GET_MASK(r
, mask
);
767 seq_printf(s
, "Status(%s)\n",
770 state
== 2 ? "Res" : "HI");
774 r
= readl(ts
->regs
+ THERMCTL_STATS_CTL
);
775 seq_printf(s
, "STATS: Up(%s) Dn(%s)\n",
776 r
& STATS_CTL_EN_UP
? "En" : "--",
777 r
& STATS_CTL_EN_DN
? "En" : "--");
779 for (level
= 0; level
< 4; level
++) {
782 off
= THERMCTL_LVL0_UP_STATS
;
783 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
784 seq_printf(s
, " Level_%d Up(%d) ", level
, r
);
786 off
= THERMCTL_LVL0_DN_STATS
;
787 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
788 seq_printf(s
, "Dn(%d)\n", r
);
791 r
= readl(ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
792 state
= REG_GET_MASK(r
, ttgs
[0]->thermtrip_any_en_mask
);
793 seq_printf(s
, "Thermtrip Any En(%d)\n", state
);
794 for (i
= 0; i
< ts
->soc
->num_ttgs
; i
++) {
795 state
= REG_GET_MASK(r
, ttgs
[i
]->thermtrip_enable_mask
);
796 seq_printf(s
, " %s En(%d) ", ttgs
[i
]->name
, state
);
797 state
= REG_GET_MASK(r
, ttgs
[i
]->thermtrip_threshold_mask
);
798 state
*= ts
->soc
->thresh_grain
;
799 seq_printf(s
, "Thresh(%d)\n", state
);
802 r
= readl(ts
->regs
+ THROT_GLOBAL_CFG
);
804 seq_printf(s
, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r
);
806 seq_puts(s
, "---------------------------------------------------\n");
807 r
= readl(ts
->regs
+ THROT_STATUS
);
808 state
= REG_GET_MASK(r
, THROT_STATUS_BREACH_MASK
);
809 seq_printf(s
, "THROT STATUS: breach(%d) ", state
);
810 state
= REG_GET_MASK(r
, THROT_STATUS_STATE_MASK
);
811 seq_printf(s
, "state(%d) ", state
);
812 state
= REG_GET_MASK(r
, THROT_STATUS_ENABLED_MASK
);
813 seq_printf(s
, "enabled(%d)\n", state
);
815 r
= readl(ts
->regs
+ CPU_PSKIP_STATUS
);
816 if (ts
->soc
->use_ccroc
) {
817 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_ENABLED_MASK
);
818 seq_printf(s
, "CPU PSKIP STATUS: enabled(%d)\n", state
);
820 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_M_MASK
);
821 seq_printf(s
, "CPU PSKIP STATUS: M(%d) ", state
);
822 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_N_MASK
);
823 seq_printf(s
, "N(%d) ", state
);
824 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_ENABLED_MASK
);
825 seq_printf(s
, "enabled(%d)\n", state
);
831 static int regs_open(struct inode
*inode
, struct file
*file
)
833 return single_open(file
, regs_show
, inode
->i_private
);
836 static const struct file_operations regs_fops
= {
840 .release
= single_release
,
843 static void soctherm_debug_init(struct platform_device
*pdev
)
845 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
846 struct dentry
*root
, *file
;
848 root
= debugfs_create_dir("soctherm", NULL
);
850 dev_err(&pdev
->dev
, "failed to create debugfs directory\n");
854 tegra
->debugfs_dir
= root
;
856 file
= debugfs_create_file("reg_contents", 0644, root
,
859 dev_err(&pdev
->dev
, "failed to create debugfs file\n");
860 debugfs_remove_recursive(tegra
->debugfs_dir
);
861 tegra
->debugfs_dir
= NULL
;
865 static inline void soctherm_debug_init(struct platform_device
*pdev
) {}
868 static int soctherm_clk_enable(struct platform_device
*pdev
, bool enable
)
870 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
873 if (!tegra
->clock_soctherm
|| !tegra
->clock_tsensor
)
876 reset_control_assert(tegra
->reset
);
879 err
= clk_prepare_enable(tegra
->clock_soctherm
);
881 reset_control_deassert(tegra
->reset
);
885 err
= clk_prepare_enable(tegra
->clock_tsensor
);
887 clk_disable_unprepare(tegra
->clock_soctherm
);
888 reset_control_deassert(tegra
->reset
);
892 clk_disable_unprepare(tegra
->clock_tsensor
);
893 clk_disable_unprepare(tegra
->clock_soctherm
);
896 reset_control_deassert(tegra
->reset
);
901 static int throt_get_cdev_max_state(struct thermal_cooling_device
*cdev
,
902 unsigned long *max_state
)
908 static int throt_get_cdev_cur_state(struct thermal_cooling_device
*cdev
,
909 unsigned long *cur_state
)
911 struct tegra_soctherm
*ts
= cdev
->devdata
;
914 r
= readl(ts
->regs
+ THROT_STATUS
);
915 if (REG_GET_MASK(r
, THROT_STATUS_STATE_MASK
))
923 static int throt_set_cdev_state(struct thermal_cooling_device
*cdev
,
924 unsigned long cur_state
)
929 static struct thermal_cooling_device_ops throt_cooling_ops
= {
930 .get_max_state
= throt_get_cdev_max_state
,
931 .get_cur_state
= throt_get_cdev_cur_state
,
932 .set_cur_state
= throt_set_cdev_state
,
936 * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
937 * and register them as cooling devices.
939 static void soctherm_init_hw_throt_cdev(struct platform_device
*pdev
)
941 struct device
*dev
= &pdev
->dev
;
942 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
943 struct device_node
*np_stc
, *np_stcc
;
948 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
949 ts
->throt_cfgs
[i
].name
= throt_names
[i
];
950 ts
->throt_cfgs
[i
].id
= i
;
951 ts
->throt_cfgs
[i
].init
= false;
954 np_stc
= of_get_child_by_name(dev
->of_node
, "throttle-cfgs");
957 "throttle-cfg: no throttle-cfgs - not enabling\n");
961 for_each_child_of_node(np_stc
, np_stcc
) {
962 struct soctherm_throt_cfg
*stc
;
963 struct thermal_cooling_device
*tcd
;
965 name
= np_stcc
->name
;
966 stc
= find_throttle_cfg_by_name(ts
, name
);
969 "throttle-cfg: could not find %s\n", name
);
973 r
= of_property_read_u32(np_stcc
, "nvidia,priority", &val
);
976 "throttle-cfg: %s: missing priority\n", name
);
981 if (ts
->soc
->use_ccroc
) {
982 r
= of_property_read_u32(np_stcc
,
983 "nvidia,cpu-throt-level",
987 "throttle-cfg: %s: missing cpu-throt-level\n",
991 stc
->cpu_throt_level
= val
;
993 r
= of_property_read_u32(np_stcc
,
994 "nvidia,cpu-throt-percent",
998 "throttle-cfg: %s: missing cpu-throt-percent\n",
1002 stc
->cpu_throt_depth
= val
;
1005 tcd
= thermal_of_cooling_device_register(np_stcc
,
1007 &throt_cooling_ops
);
1008 of_node_put(np_stcc
);
1009 if (IS_ERR_OR_NULL(tcd
)) {
1011 "throttle-cfg: %s: failed to register cooling device\n",
1020 of_node_put(np_stc
);
1024 * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
1025 * @level: describing the level LOW/MED/HIGH of throttling
1027 * It's necessary to set up the CPU-local CCROC NV_THERM instance with
1028 * the M/N values desired for each level. This function does this.
1030 * This function pre-programs the CCROC NV_THERM levels in terms of
1031 * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
1032 * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
1034 static void throttlectl_cpu_level_cfg(struct tegra_soctherm
*ts
, int level
)
1040 case TEGRA_SOCTHERM_THROT_LEVEL_LOW
:
1043 case TEGRA_SOCTHERM_THROT_LEVEL_MED
:
1046 case TEGRA_SOCTHERM_THROT_LEVEL_HIGH
:
1049 case TEGRA_SOCTHERM_THROT_LEVEL_NONE
:
1055 dividend
= THROT_DEPTH_DIVIDEND(depth
);
1057 /* setup PSKIP in ccroc nv_therm registers */
1058 r
= ccroc_readl(ts
, CCROC_THROT_PSKIP_RAMP_CPU_REG(level
));
1059 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_RAMP_DURATION_MASK
, 0xff);
1060 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_RAMP_STEP_MASK
, 0xf);
1061 ccroc_writel(ts
, r
, CCROC_THROT_PSKIP_RAMP_CPU_REG(level
));
1063 r
= ccroc_readl(ts
, CCROC_THROT_PSKIP_CTRL_CPU_REG(level
));
1064 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_ENB_MASK
, 1);
1065 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK
, dividend
);
1066 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK
, 0xff);
1067 ccroc_writel(ts
, r
, CCROC_THROT_PSKIP_CTRL_CPU_REG(level
));
1071 * throttlectl_cpu_level_select() - program CPU pulse skipper config
1072 * @throt: the LIGHT/HEAVY of throttle event id
1074 * Pulse skippers are used to throttle clock frequencies. This
1075 * function programs the pulse skippers based on @throt and platform
1076 * data. This function is used on SoCs which have CPU-local pulse
1077 * skipper control, such as T13x. It programs soctherm's interface to
1078 * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
1079 * vectors. PSKIP_BYPASS mode is set as required per HW spec.
1081 static void throttlectl_cpu_level_select(struct tegra_soctherm
*ts
,
1082 enum soctherm_throttle_id throt
)
1086 /* Denver:CCROC NV_THERM interface N:3 Mapping */
1087 switch (ts
->throt_cfgs
[throt
].cpu_throt_level
) {
1088 case TEGRA_SOCTHERM_THROT_LEVEL_LOW
:
1089 throt_vect
= THROT_VECT_LOW
;
1091 case TEGRA_SOCTHERM_THROT_LEVEL_MED
:
1092 throt_vect
= THROT_VECT_MED
;
1094 case TEGRA_SOCTHERM_THROT_LEVEL_HIGH
:
1095 throt_vect
= THROT_VECT_HIGH
;
1098 throt_vect
= THROT_VECT_NONE
;
1102 r
= readl(ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1103 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_ENABLE_MASK
, 1);
1104 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_VECT_CPU_MASK
, throt_vect
);
1105 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_VECT2_CPU_MASK
, throt_vect
);
1106 writel(r
, ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1108 /* bypass sequencer in soc_therm as it is programmed in ccroc */
1109 r
= REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK
, 1);
1110 writel(r
, ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1114 * throttlectl_cpu_mn() - program CPU pulse skipper configuration
1115 * @throt: the LIGHT/HEAVY of throttle event id
1117 * Pulse skippers are used to throttle clock frequencies. This
1118 * function programs the pulse skippers based on @throt and platform
1119 * data. This function is used for CPUs that have "remote" pulse
1120 * skipper control, e.g., the CPU pulse skipper is controlled by the
1121 * SOC_THERM IP block. (SOC_THERM is located outside the CPU
1124 static void throttlectl_cpu_mn(struct tegra_soctherm
*ts
,
1125 enum soctherm_throttle_id throt
)
1131 depth
= ts
->throt_cfgs
[throt
].cpu_throt_depth
;
1132 dividend
= THROT_DEPTH_DIVIDEND(depth
);
1134 r
= readl(ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1135 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_ENABLE_MASK
, 1);
1136 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_DIVIDEND_MASK
, dividend
);
1137 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_DIVISOR_MASK
, 0xff);
1138 writel(r
, ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1140 r
= readl(ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1141 r
= REG_SET_MASK(r
, THROT_PSKIP_RAMP_DURATION_MASK
, 0xff);
1142 r
= REG_SET_MASK(r
, THROT_PSKIP_RAMP_STEP_MASK
, 0xf);
1143 writel(r
, ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1147 * soctherm_throttle_program() - programs pulse skippers' configuration
1148 * @throt: the LIGHT/HEAVY of the throttle event id.
1150 * Pulse skippers are used to throttle clock frequencies.
1151 * This function programs the pulse skippers.
1153 static void soctherm_throttle_program(struct tegra_soctherm
*ts
,
1154 enum soctherm_throttle_id throt
)
1157 struct soctherm_throt_cfg stc
= ts
->throt_cfgs
[throt
];
1162 /* Setup PSKIP parameters */
1163 if (ts
->soc
->use_ccroc
)
1164 throttlectl_cpu_level_select(ts
, throt
);
1166 throttlectl_cpu_mn(ts
, throt
);
1168 r
= REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK
, stc
.priority
);
1169 writel(r
, ts
->regs
+ THROT_PRIORITY_CTRL(throt
));
1171 r
= REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK
, 0);
1172 writel(r
, ts
->regs
+ THROT_DELAY_CTRL(throt
));
1174 r
= readl(ts
->regs
+ THROT_PRIORITY_LOCK
);
1175 r
= REG_GET_MASK(r
, THROT_PRIORITY_LOCK_PRIORITY_MASK
);
1176 if (r
>= stc
.priority
)
1178 r
= REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK
,
1180 writel(r
, ts
->regs
+ THROT_PRIORITY_LOCK
);
1183 static void tegra_soctherm_throttle(struct device
*dev
)
1185 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
1189 /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
1190 if (ts
->soc
->use_ccroc
) {
1191 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_LOW
);
1192 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_MED
);
1193 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_HIGH
);
1196 /* Thermal HW throttle programming */
1197 for (i
= 0; i
< THROTTLE_SIZE
; i
++)
1198 soctherm_throttle_program(ts
, i
);
1200 v
= REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK
, 1);
1201 if (ts
->soc
->use_ccroc
) {
1202 ccroc_writel(ts
, v
, CCROC_GLOBAL_CFG
);
1204 v
= ccroc_readl(ts
, CCROC_SUPER_CCLKG_DIVIDER
);
1205 v
= REG_SET_MASK(v
, CDIVG_USE_THERM_CONTROLS_MASK
, 1);
1206 ccroc_writel(ts
, v
, CCROC_SUPER_CCLKG_DIVIDER
);
1208 writel(v
, ts
->regs
+ THROT_GLOBAL_CFG
);
1210 v
= clk_readl(ts
, CAR_SUPER_CCLKG_DIVIDER
);
1211 v
= REG_SET_MASK(v
, CDIVG_USE_THERM_CONTROLS_MASK
, 1);
1212 clk_writel(ts
, v
, CAR_SUPER_CCLKG_DIVIDER
);
1215 /* initialize stats collection */
1216 v
= STATS_CTL_CLR_DN
| STATS_CTL_EN_DN
|
1217 STATS_CTL_CLR_UP
| STATS_CTL_EN_UP
;
1218 writel(v
, ts
->regs
+ THERMCTL_STATS_CTL
);
1221 static void soctherm_init(struct platform_device
*pdev
)
1223 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1224 const struct tegra_tsensor_group
**ttgs
= tegra
->soc
->ttgs
;
1228 /* Initialize raw sensors */
1229 for (i
= 0; i
< tegra
->soc
->num_tsensors
; ++i
)
1230 enable_tsensor(tegra
, i
);
1232 /* program pdiv and hotspot offsets per THERM */
1233 pdiv
= readl(tegra
->regs
+ SENSOR_PDIV
);
1234 hotspot
= readl(tegra
->regs
+ SENSOR_HOTSPOT_OFF
);
1235 for (i
= 0; i
< tegra
->soc
->num_ttgs
; ++i
) {
1236 pdiv
= REG_SET_MASK(pdiv
, ttgs
[i
]->pdiv_mask
,
1238 /* hotspot offset from PLLX, doesn't need to configure PLLX */
1239 if (ttgs
[i
]->id
== TEGRA124_SOCTHERM_SENSOR_PLLX
)
1241 hotspot
= REG_SET_MASK(hotspot
,
1242 ttgs
[i
]->pllx_hotspot_mask
,
1243 ttgs
[i
]->pllx_hotspot_diff
);
1245 writel(pdiv
, tegra
->regs
+ SENSOR_PDIV
);
1246 writel(hotspot
, tegra
->regs
+ SENSOR_HOTSPOT_OFF
);
1248 /* Configure hw throttle */
1249 tegra_soctherm_throttle(&pdev
->dev
);
1252 static const struct of_device_id tegra_soctherm_of_match
[] = {
1253 #ifdef CONFIG_ARCH_TEGRA_124_SOC
1255 .compatible
= "nvidia,tegra124-soctherm",
1256 .data
= &tegra124_soctherm
,
1259 #ifdef CONFIG_ARCH_TEGRA_132_SOC
1261 .compatible
= "nvidia,tegra132-soctherm",
1262 .data
= &tegra132_soctherm
,
1265 #ifdef CONFIG_ARCH_TEGRA_210_SOC
1267 .compatible
= "nvidia,tegra210-soctherm",
1268 .data
= &tegra210_soctherm
,
1273 MODULE_DEVICE_TABLE(of
, tegra_soctherm_of_match
);
1275 static int tegra_soctherm_probe(struct platform_device
*pdev
)
1277 const struct of_device_id
*match
;
1278 struct tegra_soctherm
*tegra
;
1279 struct thermal_zone_device
*z
;
1280 struct tsensor_shared_calib shared_calib
;
1281 struct resource
*res
;
1282 struct tegra_soctherm_soc
*soc
;
1286 match
= of_match_node(tegra_soctherm_of_match
, pdev
->dev
.of_node
);
1290 soc
= (struct tegra_soctherm_soc
*)match
->data
;
1291 if (soc
->num_ttgs
> TEGRA124_SOCTHERM_SENSOR_NUM
)
1294 tegra
= devm_kzalloc(&pdev
->dev
, sizeof(*tegra
), GFP_KERNEL
);
1298 dev_set_drvdata(&pdev
->dev
, tegra
);
1302 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1304 tegra
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1305 if (IS_ERR(tegra
->regs
)) {
1306 dev_err(&pdev
->dev
, "can't get soctherm registers");
1307 return PTR_ERR(tegra
->regs
);
1310 if (!tegra
->soc
->use_ccroc
) {
1311 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1313 tegra
->clk_regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1314 if (IS_ERR(tegra
->clk_regs
)) {
1315 dev_err(&pdev
->dev
, "can't get car clk registers");
1316 return PTR_ERR(tegra
->clk_regs
);
1319 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1321 tegra
->ccroc_regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1322 if (IS_ERR(tegra
->ccroc_regs
)) {
1323 dev_err(&pdev
->dev
, "can't get ccroc registers");
1324 return PTR_ERR(tegra
->ccroc_regs
);
1328 tegra
->reset
= devm_reset_control_get(&pdev
->dev
, "soctherm");
1329 if (IS_ERR(tegra
->reset
)) {
1330 dev_err(&pdev
->dev
, "can't get soctherm reset\n");
1331 return PTR_ERR(tegra
->reset
);
1334 tegra
->clock_tsensor
= devm_clk_get(&pdev
->dev
, "tsensor");
1335 if (IS_ERR(tegra
->clock_tsensor
)) {
1336 dev_err(&pdev
->dev
, "can't get tsensor clock\n");
1337 return PTR_ERR(tegra
->clock_tsensor
);
1340 tegra
->clock_soctherm
= devm_clk_get(&pdev
->dev
, "soctherm");
1341 if (IS_ERR(tegra
->clock_soctherm
)) {
1342 dev_err(&pdev
->dev
, "can't get soctherm clock\n");
1343 return PTR_ERR(tegra
->clock_soctherm
);
1346 tegra
->calib
= devm_kzalloc(&pdev
->dev
,
1347 sizeof(u32
) * soc
->num_tsensors
,
1352 /* calculate shared calibration data */
1353 err
= tegra_calc_shared_calib(soc
->tfuse
, &shared_calib
);
1357 /* calculate tsensor calibaration data */
1358 for (i
= 0; i
< soc
->num_tsensors
; ++i
) {
1359 err
= tegra_calc_tsensor_calib(&soc
->tsensors
[i
],
1366 tegra
->thermctl_tzs
= devm_kzalloc(&pdev
->dev
,
1367 sizeof(*z
) * soc
->num_ttgs
,
1369 if (!tegra
->thermctl_tzs
)
1372 err
= soctherm_clk_enable(pdev
, true);
1376 soctherm_init_hw_throt_cdev(pdev
);
1378 soctherm_init(pdev
);
1380 for (i
= 0; i
< soc
->num_ttgs
; ++i
) {
1381 struct tegra_thermctl_zone
*zone
=
1382 devm_kzalloc(&pdev
->dev
, sizeof(*zone
), GFP_KERNEL
);
1385 goto disable_clocks
;
1388 zone
->reg
= tegra
->regs
+ soc
->ttgs
[i
]->sensor_temp_offset
;
1389 zone
->dev
= &pdev
->dev
;
1390 zone
->sg
= soc
->ttgs
[i
];
1393 z
= devm_thermal_zone_of_sensor_register(&pdev
->dev
,
1394 soc
->ttgs
[i
]->id
, zone
,
1395 &tegra_of_thermal_ops
);
1398 dev_err(&pdev
->dev
, "failed to register sensor: %d\n",
1400 goto disable_clocks
;
1404 tegra
->thermctl_tzs
[soc
->ttgs
[i
]->id
] = z
;
1406 /* Configure hw trip points */
1407 err
= tegra_soctherm_set_hwtrips(&pdev
->dev
, soc
->ttgs
[i
], z
);
1409 goto disable_clocks
;
1412 soctherm_debug_init(pdev
);
1417 soctherm_clk_enable(pdev
, false);
1422 static int tegra_soctherm_remove(struct platform_device
*pdev
)
1424 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1426 debugfs_remove_recursive(tegra
->debugfs_dir
);
1428 soctherm_clk_enable(pdev
, false);
1433 static int __maybe_unused
soctherm_suspend(struct device
*dev
)
1435 struct platform_device
*pdev
= to_platform_device(dev
);
1437 soctherm_clk_enable(pdev
, false);
1442 static int __maybe_unused
soctherm_resume(struct device
*dev
)
1444 struct platform_device
*pdev
= to_platform_device(dev
);
1445 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1446 struct tegra_soctherm_soc
*soc
= tegra
->soc
;
1449 err
= soctherm_clk_enable(pdev
, true);
1452 "Resume failed: enable clocks failed\n");
1456 soctherm_init(pdev
);
1458 for (i
= 0; i
< soc
->num_ttgs
; ++i
) {
1459 struct thermal_zone_device
*tz
;
1461 tz
= tegra
->thermctl_tzs
[soc
->ttgs
[i
]->id
];
1462 err
= tegra_soctherm_set_hwtrips(dev
, soc
->ttgs
[i
], tz
);
1465 "Resume failed: set hwtrips failed\n");
1473 static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm
, soctherm_suspend
, soctherm_resume
);
1475 static struct platform_driver tegra_soctherm_driver
= {
1476 .probe
= tegra_soctherm_probe
,
1477 .remove
= tegra_soctherm_remove
,
1479 .name
= "tegra_soctherm",
1480 .pm
= &tegra_soctherm_pm
,
1481 .of_match_table
= tegra_soctherm_of_match
,
1484 module_platform_driver(tegra_soctherm_driver
);
1486 MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
1487 MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
1488 MODULE_LICENSE("GPL v2");