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 thermtrip_program(struct device
*dev
, const struct tegra_tsensor_group
*sg
,
348 throttrip_program(struct device
*dev
, const struct tegra_tsensor_group
*sg
,
349 struct soctherm_throt_cfg
*stc
, int trip_temp
);
350 static struct soctherm_throt_cfg
*
351 find_throttle_cfg_by_name(struct tegra_soctherm
*ts
, const char *name
);
353 static int tegra_thermctl_set_trip_temp(void *data
, int trip
, int temp
)
355 struct tegra_thermctl_zone
*zone
= data
;
356 struct thermal_zone_device
*tz
= zone
->tz
;
357 struct tegra_soctherm
*ts
= zone
->ts
;
358 const struct tegra_tsensor_group
*sg
= zone
->sg
;
359 struct device
*dev
= zone
->dev
;
360 enum thermal_trip_type type
;
366 ret
= tz
->ops
->get_trip_type(tz
, trip
, &type
);
370 if (type
== THERMAL_TRIP_CRITICAL
) {
371 return thermtrip_program(dev
, sg
, temp
);
372 } else if (type
== THERMAL_TRIP_HOT
) {
375 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
376 struct thermal_cooling_device
*cdev
;
377 struct soctherm_throt_cfg
*stc
;
379 if (!ts
->throt_cfgs
[i
].init
)
382 cdev
= ts
->throt_cfgs
[i
].cdev
;
383 if (get_thermal_instance(tz
, cdev
, trip
))
384 stc
= find_throttle_cfg_by_name(ts
, cdev
->type
);
388 return throttrip_program(dev
, sg
, stc
, temp
);
395 static const struct thermal_zone_of_device_ops tegra_of_thermal_ops
= {
396 .get_temp
= tegra_thermctl_get_temp
,
397 .set_trip_temp
= tegra_thermctl_set_trip_temp
,
401 * enforce_temp_range() - check and enforce temperature range [min, max]
402 * @trip_temp: the trip temperature to check
404 * Checks and enforces the permitted temperature range that SOC_THERM
405 * HW can support This is
406 * done while taking care of precision.
408 * Return: The precision adjusted capped temperature in millicelsius.
410 static int enforce_temp_range(struct device
*dev
, int trip_temp
)
414 temp
= clamp_val(trip_temp
, min_low_temp
, max_high_temp
);
415 if (temp
!= trip_temp
)
416 dev_info(dev
, "soctherm: trip temperature %d forced to %d\n",
422 * thermtrip_program() - Configures the hardware to shut down the
423 * system if a given sensor group reaches a given temperature
424 * @dev: ptr to the struct device for the SOC_THERM IP block
425 * @sg: pointer to the sensor group to set the thermtrip temperature for
426 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
428 * Sets the thermal trip threshold of the given sensor group to be the
429 * @trip_temp. If this threshold is crossed, the hardware will shut
432 * Note that, although @trip_temp is specified in millicelsius, the
433 * hardware is programmed in degrees Celsius.
435 * Return: 0 upon success, or %-EINVAL upon failure.
437 static int thermtrip_program(struct device
*dev
,
438 const struct tegra_tsensor_group
*sg
,
441 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
445 if (!sg
|| !sg
->thermtrip_threshold_mask
)
448 temp
= enforce_temp_range(dev
, trip_temp
) / ts
->soc
->thresh_grain
;
450 r
= readl(ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
451 r
= REG_SET_MASK(r
, sg
->thermtrip_threshold_mask
, temp
);
452 r
= REG_SET_MASK(r
, sg
->thermtrip_enable_mask
, 1);
453 r
= REG_SET_MASK(r
, sg
->thermtrip_any_en_mask
, 0);
454 writel(r
, ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
460 * throttrip_program() - Configures the hardware to throttle the
461 * pulse if a given sensor group reaches a given temperature
462 * @dev: ptr to the struct device for the SOC_THERM IP block
463 * @sg: pointer to the sensor group to set the thermtrip temperature for
464 * @stc: pointer to the throttle need to be triggered
465 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
467 * Sets the thermal trip threshold and throttle event of the given sensor
468 * group. If this threshold is crossed, the hardware will trigger the
471 * Note that, although @trip_temp is specified in millicelsius, the
472 * hardware is programmed in degrees Celsius.
474 * Return: 0 upon success, or %-EINVAL upon failure.
476 static int throttrip_program(struct device
*dev
,
477 const struct tegra_tsensor_group
*sg
,
478 struct soctherm_throt_cfg
*stc
,
481 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
482 int temp
, cpu_throt
, gpu_throt
;
486 if (!sg
|| !stc
|| !stc
->init
)
489 temp
= enforce_temp_range(dev
, trip_temp
) / ts
->soc
->thresh_grain
;
491 /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
493 reg_off
= THERMCTL_LVL_REG(sg
->thermctl_lvl0_offset
, throt
+ 1);
495 if (throt
== THROTTLE_LIGHT
) {
496 cpu_throt
= THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT
;
497 gpu_throt
= THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT
;
499 cpu_throt
= THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY
;
500 gpu_throt
= THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY
;
501 if (throt
!= THROTTLE_HEAVY
)
503 "invalid throt id %d - assuming HEAVY",
507 r
= readl(ts
->regs
+ reg_off
);
508 r
= REG_SET_MASK(r
, sg
->thermctl_lvl0_up_thresh_mask
, temp
);
509 r
= REG_SET_MASK(r
, sg
->thermctl_lvl0_dn_thresh_mask
, temp
);
510 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_CPU_THROT_MASK
, cpu_throt
);
511 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_GPU_THROT_MASK
, gpu_throt
);
512 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_EN_MASK
, 1);
513 writel(r
, ts
->regs
+ reg_off
);
518 static struct soctherm_throt_cfg
*
519 find_throttle_cfg_by_name(struct tegra_soctherm
*ts
, const char *name
)
523 for (i
= 0; ts
->throt_cfgs
[i
].name
; i
++)
524 if (!strcmp(ts
->throt_cfgs
[i
].name
, name
))
525 return &ts
->throt_cfgs
[i
];
530 static int get_hot_temp(struct thermal_zone_device
*tz
, int *trip
, int *temp
)
533 enum thermal_trip_type type
;
535 ntrips
= of_thermal_get_ntrips(tz
);
539 for (i
= 0; i
< ntrips
; i
++) {
540 ret
= tz
->ops
->get_trip_type(tz
, i
, &type
);
543 if (type
== THERMAL_TRIP_HOT
) {
544 ret
= tz
->ops
->get_trip_temp(tz
, i
, temp
);
556 * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
557 * @dev: struct device * of the SOC_THERM instance
559 * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
560 * "THROTTLE" trip points , using "critical" or "hot" type trip_temp
562 * After they have been configured, THERMTRIP or THROTTLE will take
563 * action when the configured SoC thermal sensor group reaches a
564 * certain temperature.
566 * Return: 0 upon success, or a negative error code on failure.
567 * "Success" does not mean that trips was enabled; it could also
568 * mean that no node was found in DT.
569 * THERMTRIP has been enabled successfully when a message similar to
570 * this one appears on the serial console:
571 * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
572 * THROTTLE has been enabled successfully when a message similar to
573 * this one appears on the serial console:
574 * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
576 static int tegra_soctherm_set_hwtrips(struct device
*dev
,
577 const struct tegra_tsensor_group
*sg
,
578 struct thermal_zone_device
*tz
)
580 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
581 struct soctherm_throt_cfg
*stc
;
582 int i
, trip
, temperature
;
585 ret
= tz
->ops
->get_crit_temp(tz
, &temperature
);
587 dev_warn(dev
, "thermtrip: %s: missing critical temperature\n",
592 ret
= thermtrip_program(dev
, sg
, temperature
);
594 dev_err(dev
, "thermtrip: %s: error during enable\n",
600 "thermtrip: will shut down when %s reaches %d mC\n",
601 sg
->name
, temperature
);
604 ret
= get_hot_temp(tz
, &trip
, &temperature
);
606 dev_warn(dev
, "throttrip: %s: missing hot temperature\n",
611 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
612 struct thermal_cooling_device
*cdev
;
614 if (!ts
->throt_cfgs
[i
].init
)
617 cdev
= ts
->throt_cfgs
[i
].cdev
;
618 if (get_thermal_instance(tz
, cdev
, trip
))
619 stc
= find_throttle_cfg_by_name(ts
, cdev
->type
);
623 ret
= throttrip_program(dev
, sg
, stc
, temperature
);
625 dev_err(dev
, "throttrip: %s: error during enable\n",
631 "throttrip: will throttle when %s reaches %d mC\n",
632 sg
->name
, temperature
);
636 if (i
== THROTTLE_SIZE
)
637 dev_warn(dev
, "throttrip: %s: missing throttle cdev\n",
643 #ifdef CONFIG_DEBUG_FS
644 static int regs_show(struct seq_file
*s
, void *data
)
646 struct platform_device
*pdev
= s
->private;
647 struct tegra_soctherm
*ts
= platform_get_drvdata(pdev
);
648 const struct tegra_tsensor
*tsensors
= ts
->soc
->tsensors
;
649 const struct tegra_tsensor_group
**ttgs
= ts
->soc
->ttgs
;
653 seq_puts(s
, "-----TSENSE (convert HW)-----\n");
655 for (i
= 0; i
< ts
->soc
->num_tsensors
; i
++) {
656 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG1
);
657 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TEMP_ENABLE
);
659 seq_printf(s
, "%s: ", tsensors
[i
].name
);
660 seq_printf(s
, "En(%d) ", state
);
667 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TIDDQ_EN_MASK
);
668 seq_printf(s
, "tiddq(%d) ", state
);
669 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TEN_COUNT_MASK
);
670 seq_printf(s
, "ten_count(%d) ", state
);
671 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TSAMPLE_MASK
);
672 seq_printf(s
, "tsample(%d) ", state
+ 1);
674 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_STATUS1
);
675 state
= REG_GET_MASK(r
, SENSOR_STATUS1_TEMP_VALID_MASK
);
676 seq_printf(s
, "Temp(%d/", state
);
677 state
= REG_GET_MASK(r
, SENSOR_STATUS1_TEMP_MASK
);
678 seq_printf(s
, "%d) ", translate_temp(state
));
680 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_STATUS0
);
681 state
= REG_GET_MASK(r
, SENSOR_STATUS0_VALID_MASK
);
682 seq_printf(s
, "Capture(%d/", state
);
683 state
= REG_GET_MASK(r
, SENSOR_STATUS0_CAPTURE_MASK
);
684 seq_printf(s
, "%d) ", state
);
686 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG0
);
687 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_STOP
);
688 seq_printf(s
, "Stop(%d) ", state
);
689 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_TALL_MASK
);
690 seq_printf(s
, "Tall(%d) ", state
);
691 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_TCALC_OVER
);
692 seq_printf(s
, "Over(%d/", state
);
693 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_OVER
);
694 seq_printf(s
, "%d/", state
);
695 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_CPTR_OVER
);
696 seq_printf(s
, "%d) ", state
);
698 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG2
);
699 state
= REG_GET_MASK(r
, SENSOR_CONFIG2_THERMA_MASK
);
700 seq_printf(s
, "Therm_A/B(%d/", state
);
701 state
= REG_GET_MASK(r
, SENSOR_CONFIG2_THERMB_MASK
);
702 seq_printf(s
, "%d)\n", (s16
)state
);
705 r
= readl(ts
->regs
+ SENSOR_PDIV
);
706 seq_printf(s
, "PDIV: 0x%x\n", r
);
708 r
= readl(ts
->regs
+ SENSOR_HOTSPOT_OFF
);
709 seq_printf(s
, "HOTSPOT: 0x%x\n", r
);
712 seq_puts(s
, "-----SOC_THERM-----\n");
714 r
= readl(ts
->regs
+ SENSOR_TEMP1
);
715 state
= REG_GET_MASK(r
, SENSOR_TEMP1_CPU_TEMP_MASK
);
716 seq_printf(s
, "Temperatures: CPU(%d) ", translate_temp(state
));
717 state
= REG_GET_MASK(r
, SENSOR_TEMP1_GPU_TEMP_MASK
);
718 seq_printf(s
, " GPU(%d) ", translate_temp(state
));
719 r
= readl(ts
->regs
+ SENSOR_TEMP2
);
720 state
= REG_GET_MASK(r
, SENSOR_TEMP2_PLLX_TEMP_MASK
);
721 seq_printf(s
, " PLLX(%d) ", translate_temp(state
));
722 state
= REG_GET_MASK(r
, SENSOR_TEMP2_MEM_TEMP_MASK
);
723 seq_printf(s
, " MEM(%d)\n", translate_temp(state
));
725 for (i
= 0; i
< ts
->soc
->num_ttgs
; i
++) {
726 seq_printf(s
, "%s:\n", ttgs
[i
]->name
);
727 for (level
= 0; level
< 4; level
++) {
730 u16 off
= ttgs
[i
]->thermctl_lvl0_offset
;
732 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
734 mask
= ttgs
[i
]->thermctl_lvl0_up_thresh_mask
;
735 state
= REG_GET_MASK(r
, mask
);
736 v
= sign_extend32(state
, ts
->soc
->bptt
- 1);
737 v
*= ts
->soc
->thresh_grain
;
738 seq_printf(s
, " %d: Up/Dn(%d /", level
, v
);
740 mask
= ttgs
[i
]->thermctl_lvl0_dn_thresh_mask
;
741 state
= REG_GET_MASK(r
, mask
);
742 v
= sign_extend32(state
, ts
->soc
->bptt
- 1);
743 v
*= ts
->soc
->thresh_grain
;
744 seq_printf(s
, "%d ) ", v
);
746 mask
= THERMCTL_LVL0_CPU0_EN_MASK
;
747 state
= REG_GET_MASK(r
, mask
);
748 seq_printf(s
, "En(%d) ", state
);
750 mask
= THERMCTL_LVL0_CPU0_CPU_THROT_MASK
;
751 state
= REG_GET_MASK(r
, mask
);
752 seq_puts(s
, "CPU Throt");
754 seq_printf(s
, "(%s) ", "none");
755 else if (state
== THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT
)
756 seq_printf(s
, "(%s) ", "L");
757 else if (state
== THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY
)
758 seq_printf(s
, "(%s) ", "H");
760 seq_printf(s
, "(%s) ", "H+L");
762 mask
= THERMCTL_LVL0_CPU0_GPU_THROT_MASK
;
763 state
= REG_GET_MASK(r
, mask
);
764 seq_puts(s
, "GPU Throt");
766 seq_printf(s
, "(%s) ", "none");
767 else if (state
== THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT
)
768 seq_printf(s
, "(%s) ", "L");
769 else if (state
== THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY
)
770 seq_printf(s
, "(%s) ", "H");
772 seq_printf(s
, "(%s) ", "H+L");
774 mask
= THERMCTL_LVL0_CPU0_STATUS_MASK
;
775 state
= REG_GET_MASK(r
, mask
);
776 seq_printf(s
, "Status(%s)\n",
779 state
== 2 ? "Res" : "HI");
783 r
= readl(ts
->regs
+ THERMCTL_STATS_CTL
);
784 seq_printf(s
, "STATS: Up(%s) Dn(%s)\n",
785 r
& STATS_CTL_EN_UP
? "En" : "--",
786 r
& STATS_CTL_EN_DN
? "En" : "--");
788 for (level
= 0; level
< 4; level
++) {
791 off
= THERMCTL_LVL0_UP_STATS
;
792 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
793 seq_printf(s
, " Level_%d Up(%d) ", level
, r
);
795 off
= THERMCTL_LVL0_DN_STATS
;
796 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
797 seq_printf(s
, "Dn(%d)\n", r
);
800 r
= readl(ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
801 state
= REG_GET_MASK(r
, ttgs
[0]->thermtrip_any_en_mask
);
802 seq_printf(s
, "Thermtrip Any En(%d)\n", state
);
803 for (i
= 0; i
< ts
->soc
->num_ttgs
; i
++) {
804 state
= REG_GET_MASK(r
, ttgs
[i
]->thermtrip_enable_mask
);
805 seq_printf(s
, " %s En(%d) ", ttgs
[i
]->name
, state
);
806 state
= REG_GET_MASK(r
, ttgs
[i
]->thermtrip_threshold_mask
);
807 state
*= ts
->soc
->thresh_grain
;
808 seq_printf(s
, "Thresh(%d)\n", state
);
811 r
= readl(ts
->regs
+ THROT_GLOBAL_CFG
);
813 seq_printf(s
, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r
);
815 seq_puts(s
, "---------------------------------------------------\n");
816 r
= readl(ts
->regs
+ THROT_STATUS
);
817 state
= REG_GET_MASK(r
, THROT_STATUS_BREACH_MASK
);
818 seq_printf(s
, "THROT STATUS: breach(%d) ", state
);
819 state
= REG_GET_MASK(r
, THROT_STATUS_STATE_MASK
);
820 seq_printf(s
, "state(%d) ", state
);
821 state
= REG_GET_MASK(r
, THROT_STATUS_ENABLED_MASK
);
822 seq_printf(s
, "enabled(%d)\n", state
);
824 r
= readl(ts
->regs
+ CPU_PSKIP_STATUS
);
825 if (ts
->soc
->use_ccroc
) {
826 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_ENABLED_MASK
);
827 seq_printf(s
, "CPU PSKIP STATUS: enabled(%d)\n", state
);
829 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_M_MASK
);
830 seq_printf(s
, "CPU PSKIP STATUS: M(%d) ", state
);
831 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_N_MASK
);
832 seq_printf(s
, "N(%d) ", state
);
833 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_ENABLED_MASK
);
834 seq_printf(s
, "enabled(%d)\n", state
);
840 static int regs_open(struct inode
*inode
, struct file
*file
)
842 return single_open(file
, regs_show
, inode
->i_private
);
845 static const struct file_operations regs_fops
= {
849 .release
= single_release
,
852 static void soctherm_debug_init(struct platform_device
*pdev
)
854 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
855 struct dentry
*root
, *file
;
857 root
= debugfs_create_dir("soctherm", NULL
);
859 dev_err(&pdev
->dev
, "failed to create debugfs directory\n");
863 tegra
->debugfs_dir
= root
;
865 file
= debugfs_create_file("reg_contents", 0644, root
,
868 dev_err(&pdev
->dev
, "failed to create debugfs file\n");
869 debugfs_remove_recursive(tegra
->debugfs_dir
);
870 tegra
->debugfs_dir
= NULL
;
874 static inline void soctherm_debug_init(struct platform_device
*pdev
) {}
877 static int soctherm_clk_enable(struct platform_device
*pdev
, bool enable
)
879 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
882 if (!tegra
->clock_soctherm
|| !tegra
->clock_tsensor
)
885 reset_control_assert(tegra
->reset
);
888 err
= clk_prepare_enable(tegra
->clock_soctherm
);
890 reset_control_deassert(tegra
->reset
);
894 err
= clk_prepare_enable(tegra
->clock_tsensor
);
896 clk_disable_unprepare(tegra
->clock_soctherm
);
897 reset_control_deassert(tegra
->reset
);
901 clk_disable_unprepare(tegra
->clock_tsensor
);
902 clk_disable_unprepare(tegra
->clock_soctherm
);
905 reset_control_deassert(tegra
->reset
);
910 static int throt_get_cdev_max_state(struct thermal_cooling_device
*cdev
,
911 unsigned long *max_state
)
917 static int throt_get_cdev_cur_state(struct thermal_cooling_device
*cdev
,
918 unsigned long *cur_state
)
920 struct tegra_soctherm
*ts
= cdev
->devdata
;
923 r
= readl(ts
->regs
+ THROT_STATUS
);
924 if (REG_GET_MASK(r
, THROT_STATUS_STATE_MASK
))
932 static int throt_set_cdev_state(struct thermal_cooling_device
*cdev
,
933 unsigned long cur_state
)
938 static struct thermal_cooling_device_ops throt_cooling_ops
= {
939 .get_max_state
= throt_get_cdev_max_state
,
940 .get_cur_state
= throt_get_cdev_cur_state
,
941 .set_cur_state
= throt_set_cdev_state
,
945 * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
946 * and register them as cooling devices.
948 static void soctherm_init_hw_throt_cdev(struct platform_device
*pdev
)
950 struct device
*dev
= &pdev
->dev
;
951 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
952 struct device_node
*np_stc
, *np_stcc
;
957 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
958 ts
->throt_cfgs
[i
].name
= throt_names
[i
];
959 ts
->throt_cfgs
[i
].id
= i
;
960 ts
->throt_cfgs
[i
].init
= false;
963 np_stc
= of_get_child_by_name(dev
->of_node
, "throttle-cfgs");
966 "throttle-cfg: no throttle-cfgs - not enabling\n");
970 for_each_child_of_node(np_stc
, np_stcc
) {
971 struct soctherm_throt_cfg
*stc
;
972 struct thermal_cooling_device
*tcd
;
974 name
= np_stcc
->name
;
975 stc
= find_throttle_cfg_by_name(ts
, name
);
978 "throttle-cfg: could not find %s\n", name
);
982 r
= of_property_read_u32(np_stcc
, "nvidia,priority", &val
);
985 "throttle-cfg: %s: missing priority\n", name
);
990 if (ts
->soc
->use_ccroc
) {
991 r
= of_property_read_u32(np_stcc
,
992 "nvidia,cpu-throt-level",
996 "throttle-cfg: %s: missing cpu-throt-level\n",
1000 stc
->cpu_throt_level
= val
;
1002 r
= of_property_read_u32(np_stcc
,
1003 "nvidia,cpu-throt-percent",
1007 "throttle-cfg: %s: missing cpu-throt-percent\n",
1011 stc
->cpu_throt_depth
= val
;
1014 tcd
= thermal_of_cooling_device_register(np_stcc
,
1016 &throt_cooling_ops
);
1017 of_node_put(np_stcc
);
1018 if (IS_ERR_OR_NULL(tcd
)) {
1020 "throttle-cfg: %s: failed to register cooling device\n",
1029 of_node_put(np_stc
);
1033 * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
1034 * @level: describing the level LOW/MED/HIGH of throttling
1036 * It's necessary to set up the CPU-local CCROC NV_THERM instance with
1037 * the M/N values desired for each level. This function does this.
1039 * This function pre-programs the CCROC NV_THERM levels in terms of
1040 * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
1041 * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
1043 static void throttlectl_cpu_level_cfg(struct tegra_soctherm
*ts
, int level
)
1049 case TEGRA_SOCTHERM_THROT_LEVEL_LOW
:
1052 case TEGRA_SOCTHERM_THROT_LEVEL_MED
:
1055 case TEGRA_SOCTHERM_THROT_LEVEL_HIGH
:
1058 case TEGRA_SOCTHERM_THROT_LEVEL_NONE
:
1064 dividend
= THROT_DEPTH_DIVIDEND(depth
);
1066 /* setup PSKIP in ccroc nv_therm registers */
1067 r
= ccroc_readl(ts
, CCROC_THROT_PSKIP_RAMP_CPU_REG(level
));
1068 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_RAMP_DURATION_MASK
, 0xff);
1069 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_RAMP_STEP_MASK
, 0xf);
1070 ccroc_writel(ts
, r
, CCROC_THROT_PSKIP_RAMP_CPU_REG(level
));
1072 r
= ccroc_readl(ts
, CCROC_THROT_PSKIP_CTRL_CPU_REG(level
));
1073 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_ENB_MASK
, 1);
1074 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK
, dividend
);
1075 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK
, 0xff);
1076 ccroc_writel(ts
, r
, CCROC_THROT_PSKIP_CTRL_CPU_REG(level
));
1080 * throttlectl_cpu_level_select() - program CPU pulse skipper config
1081 * @throt: the LIGHT/HEAVY of throttle event id
1083 * Pulse skippers are used to throttle clock frequencies. This
1084 * function programs the pulse skippers based on @throt and platform
1085 * data. This function is used on SoCs which have CPU-local pulse
1086 * skipper control, such as T13x. It programs soctherm's interface to
1087 * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
1088 * vectors. PSKIP_BYPASS mode is set as required per HW spec.
1090 static void throttlectl_cpu_level_select(struct tegra_soctherm
*ts
,
1091 enum soctherm_throttle_id throt
)
1095 /* Denver:CCROC NV_THERM interface N:3 Mapping */
1096 switch (ts
->throt_cfgs
[throt
].cpu_throt_level
) {
1097 case TEGRA_SOCTHERM_THROT_LEVEL_LOW
:
1098 throt_vect
= THROT_VECT_LOW
;
1100 case TEGRA_SOCTHERM_THROT_LEVEL_MED
:
1101 throt_vect
= THROT_VECT_MED
;
1103 case TEGRA_SOCTHERM_THROT_LEVEL_HIGH
:
1104 throt_vect
= THROT_VECT_HIGH
;
1107 throt_vect
= THROT_VECT_NONE
;
1111 r
= readl(ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1112 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_ENABLE_MASK
, 1);
1113 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_VECT_CPU_MASK
, throt_vect
);
1114 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_VECT2_CPU_MASK
, throt_vect
);
1115 writel(r
, ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1117 /* bypass sequencer in soc_therm as it is programmed in ccroc */
1118 r
= REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK
, 1);
1119 writel(r
, ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1123 * throttlectl_cpu_mn() - program CPU pulse skipper configuration
1124 * @throt: the LIGHT/HEAVY of throttle event id
1126 * Pulse skippers are used to throttle clock frequencies. This
1127 * function programs the pulse skippers based on @throt and platform
1128 * data. This function is used for CPUs that have "remote" pulse
1129 * skipper control, e.g., the CPU pulse skipper is controlled by the
1130 * SOC_THERM IP block. (SOC_THERM is located outside the CPU
1133 static void throttlectl_cpu_mn(struct tegra_soctherm
*ts
,
1134 enum soctherm_throttle_id throt
)
1140 depth
= ts
->throt_cfgs
[throt
].cpu_throt_depth
;
1141 dividend
= THROT_DEPTH_DIVIDEND(depth
);
1143 r
= readl(ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1144 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_ENABLE_MASK
, 1);
1145 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_DIVIDEND_MASK
, dividend
);
1146 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_DIVISOR_MASK
, 0xff);
1147 writel(r
, ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1149 r
= readl(ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1150 r
= REG_SET_MASK(r
, THROT_PSKIP_RAMP_DURATION_MASK
, 0xff);
1151 r
= REG_SET_MASK(r
, THROT_PSKIP_RAMP_STEP_MASK
, 0xf);
1152 writel(r
, ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1156 * soctherm_throttle_program() - programs pulse skippers' configuration
1157 * @throt: the LIGHT/HEAVY of the throttle event id.
1159 * Pulse skippers are used to throttle clock frequencies.
1160 * This function programs the pulse skippers.
1162 static void soctherm_throttle_program(struct tegra_soctherm
*ts
,
1163 enum soctherm_throttle_id throt
)
1166 struct soctherm_throt_cfg stc
= ts
->throt_cfgs
[throt
];
1171 /* Setup PSKIP parameters */
1172 if (ts
->soc
->use_ccroc
)
1173 throttlectl_cpu_level_select(ts
, throt
);
1175 throttlectl_cpu_mn(ts
, throt
);
1177 r
= REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK
, stc
.priority
);
1178 writel(r
, ts
->regs
+ THROT_PRIORITY_CTRL(throt
));
1180 r
= REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK
, 0);
1181 writel(r
, ts
->regs
+ THROT_DELAY_CTRL(throt
));
1183 r
= readl(ts
->regs
+ THROT_PRIORITY_LOCK
);
1184 r
= REG_GET_MASK(r
, THROT_PRIORITY_LOCK_PRIORITY_MASK
);
1185 if (r
>= stc
.priority
)
1187 r
= REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK
,
1189 writel(r
, ts
->regs
+ THROT_PRIORITY_LOCK
);
1192 static void tegra_soctherm_throttle(struct device
*dev
)
1194 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
1198 /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
1199 if (ts
->soc
->use_ccroc
) {
1200 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_LOW
);
1201 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_MED
);
1202 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_HIGH
);
1205 /* Thermal HW throttle programming */
1206 for (i
= 0; i
< THROTTLE_SIZE
; i
++)
1207 soctherm_throttle_program(ts
, i
);
1209 v
= REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK
, 1);
1210 if (ts
->soc
->use_ccroc
) {
1211 ccroc_writel(ts
, v
, CCROC_GLOBAL_CFG
);
1213 v
= ccroc_readl(ts
, CCROC_SUPER_CCLKG_DIVIDER
);
1214 v
= REG_SET_MASK(v
, CDIVG_USE_THERM_CONTROLS_MASK
, 1);
1215 ccroc_writel(ts
, v
, CCROC_SUPER_CCLKG_DIVIDER
);
1217 writel(v
, ts
->regs
+ THROT_GLOBAL_CFG
);
1219 v
= clk_readl(ts
, CAR_SUPER_CCLKG_DIVIDER
);
1220 v
= REG_SET_MASK(v
, CDIVG_USE_THERM_CONTROLS_MASK
, 1);
1221 clk_writel(ts
, v
, CAR_SUPER_CCLKG_DIVIDER
);
1224 /* initialize stats collection */
1225 v
= STATS_CTL_CLR_DN
| STATS_CTL_EN_DN
|
1226 STATS_CTL_CLR_UP
| STATS_CTL_EN_UP
;
1227 writel(v
, ts
->regs
+ THERMCTL_STATS_CTL
);
1230 static void soctherm_init(struct platform_device
*pdev
)
1232 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1233 const struct tegra_tsensor_group
**ttgs
= tegra
->soc
->ttgs
;
1237 /* Initialize raw sensors */
1238 for (i
= 0; i
< tegra
->soc
->num_tsensors
; ++i
)
1239 enable_tsensor(tegra
, i
);
1241 /* program pdiv and hotspot offsets per THERM */
1242 pdiv
= readl(tegra
->regs
+ SENSOR_PDIV
);
1243 hotspot
= readl(tegra
->regs
+ SENSOR_HOTSPOT_OFF
);
1244 for (i
= 0; i
< tegra
->soc
->num_ttgs
; ++i
) {
1245 pdiv
= REG_SET_MASK(pdiv
, ttgs
[i
]->pdiv_mask
,
1247 /* hotspot offset from PLLX, doesn't need to configure PLLX */
1248 if (ttgs
[i
]->id
== TEGRA124_SOCTHERM_SENSOR_PLLX
)
1250 hotspot
= REG_SET_MASK(hotspot
,
1251 ttgs
[i
]->pllx_hotspot_mask
,
1252 ttgs
[i
]->pllx_hotspot_diff
);
1254 writel(pdiv
, tegra
->regs
+ SENSOR_PDIV
);
1255 writel(hotspot
, tegra
->regs
+ SENSOR_HOTSPOT_OFF
);
1257 /* Configure hw throttle */
1258 tegra_soctherm_throttle(&pdev
->dev
);
1261 static const struct of_device_id tegra_soctherm_of_match
[] = {
1262 #ifdef CONFIG_ARCH_TEGRA_124_SOC
1264 .compatible
= "nvidia,tegra124-soctherm",
1265 .data
= &tegra124_soctherm
,
1268 #ifdef CONFIG_ARCH_TEGRA_132_SOC
1270 .compatible
= "nvidia,tegra132-soctherm",
1271 .data
= &tegra132_soctherm
,
1274 #ifdef CONFIG_ARCH_TEGRA_210_SOC
1276 .compatible
= "nvidia,tegra210-soctherm",
1277 .data
= &tegra210_soctherm
,
1282 MODULE_DEVICE_TABLE(of
, tegra_soctherm_of_match
);
1284 static int tegra_soctherm_probe(struct platform_device
*pdev
)
1286 const struct of_device_id
*match
;
1287 struct tegra_soctherm
*tegra
;
1288 struct thermal_zone_device
*z
;
1289 struct tsensor_shared_calib shared_calib
;
1290 struct resource
*res
;
1291 struct tegra_soctherm_soc
*soc
;
1295 match
= of_match_node(tegra_soctherm_of_match
, pdev
->dev
.of_node
);
1299 soc
= (struct tegra_soctherm_soc
*)match
->data
;
1300 if (soc
->num_ttgs
> TEGRA124_SOCTHERM_SENSOR_NUM
)
1303 tegra
= devm_kzalloc(&pdev
->dev
, sizeof(*tegra
), GFP_KERNEL
);
1307 dev_set_drvdata(&pdev
->dev
, tegra
);
1311 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1313 tegra
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1314 if (IS_ERR(tegra
->regs
)) {
1315 dev_err(&pdev
->dev
, "can't get soctherm registers");
1316 return PTR_ERR(tegra
->regs
);
1319 if (!tegra
->soc
->use_ccroc
) {
1320 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1322 tegra
->clk_regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1323 if (IS_ERR(tegra
->clk_regs
)) {
1324 dev_err(&pdev
->dev
, "can't get car clk registers");
1325 return PTR_ERR(tegra
->clk_regs
);
1328 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1330 tegra
->ccroc_regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1331 if (IS_ERR(tegra
->ccroc_regs
)) {
1332 dev_err(&pdev
->dev
, "can't get ccroc registers");
1333 return PTR_ERR(tegra
->ccroc_regs
);
1337 tegra
->reset
= devm_reset_control_get(&pdev
->dev
, "soctherm");
1338 if (IS_ERR(tegra
->reset
)) {
1339 dev_err(&pdev
->dev
, "can't get soctherm reset\n");
1340 return PTR_ERR(tegra
->reset
);
1343 tegra
->clock_tsensor
= devm_clk_get(&pdev
->dev
, "tsensor");
1344 if (IS_ERR(tegra
->clock_tsensor
)) {
1345 dev_err(&pdev
->dev
, "can't get tsensor clock\n");
1346 return PTR_ERR(tegra
->clock_tsensor
);
1349 tegra
->clock_soctherm
= devm_clk_get(&pdev
->dev
, "soctherm");
1350 if (IS_ERR(tegra
->clock_soctherm
)) {
1351 dev_err(&pdev
->dev
, "can't get soctherm clock\n");
1352 return PTR_ERR(tegra
->clock_soctherm
);
1355 tegra
->calib
= devm_kzalloc(&pdev
->dev
,
1356 sizeof(u32
) * soc
->num_tsensors
,
1361 /* calculate shared calibration data */
1362 err
= tegra_calc_shared_calib(soc
->tfuse
, &shared_calib
);
1366 /* calculate tsensor calibaration data */
1367 for (i
= 0; i
< soc
->num_tsensors
; ++i
) {
1368 err
= tegra_calc_tsensor_calib(&soc
->tsensors
[i
],
1375 tegra
->thermctl_tzs
= devm_kzalloc(&pdev
->dev
,
1376 sizeof(*z
) * soc
->num_ttgs
,
1378 if (!tegra
->thermctl_tzs
)
1381 err
= soctherm_clk_enable(pdev
, true);
1385 soctherm_init_hw_throt_cdev(pdev
);
1387 soctherm_init(pdev
);
1389 for (i
= 0; i
< soc
->num_ttgs
; ++i
) {
1390 struct tegra_thermctl_zone
*zone
=
1391 devm_kzalloc(&pdev
->dev
, sizeof(*zone
), GFP_KERNEL
);
1394 goto disable_clocks
;
1397 zone
->reg
= tegra
->regs
+ soc
->ttgs
[i
]->sensor_temp_offset
;
1398 zone
->dev
= &pdev
->dev
;
1399 zone
->sg
= soc
->ttgs
[i
];
1402 z
= devm_thermal_zone_of_sensor_register(&pdev
->dev
,
1403 soc
->ttgs
[i
]->id
, zone
,
1404 &tegra_of_thermal_ops
);
1407 dev_err(&pdev
->dev
, "failed to register sensor: %d\n",
1409 goto disable_clocks
;
1413 tegra
->thermctl_tzs
[soc
->ttgs
[i
]->id
] = z
;
1415 /* Configure hw trip points */
1416 err
= tegra_soctherm_set_hwtrips(&pdev
->dev
, soc
->ttgs
[i
], z
);
1418 goto disable_clocks
;
1421 soctherm_debug_init(pdev
);
1426 soctherm_clk_enable(pdev
, false);
1431 static int tegra_soctherm_remove(struct platform_device
*pdev
)
1433 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1435 debugfs_remove_recursive(tegra
->debugfs_dir
);
1437 soctherm_clk_enable(pdev
, false);
1442 static int __maybe_unused
soctherm_suspend(struct device
*dev
)
1444 struct platform_device
*pdev
= to_platform_device(dev
);
1446 soctherm_clk_enable(pdev
, false);
1451 static int __maybe_unused
soctherm_resume(struct device
*dev
)
1453 struct platform_device
*pdev
= to_platform_device(dev
);
1454 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1455 struct tegra_soctherm_soc
*soc
= tegra
->soc
;
1458 err
= soctherm_clk_enable(pdev
, true);
1461 "Resume failed: enable clocks failed\n");
1465 soctherm_init(pdev
);
1467 for (i
= 0; i
< soc
->num_ttgs
; ++i
) {
1468 struct thermal_zone_device
*tz
;
1470 tz
= tegra
->thermctl_tzs
[soc
->ttgs
[i
]->id
];
1471 err
= tegra_soctherm_set_hwtrips(dev
, soc
->ttgs
[i
], tz
);
1474 "Resume failed: set hwtrips failed\n");
1482 static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm
, soctherm_suspend
, soctherm_resume
);
1484 static struct platform_driver tegra_soctherm_driver
= {
1485 .probe
= tegra_soctherm_probe
,
1486 .remove
= tegra_soctherm_remove
,
1488 .name
= "tegra_soctherm",
1489 .pm
= &tegra_soctherm_pm
,
1490 .of_match_table
= tegra_soctherm_of_match
,
1493 module_platform_driver(tegra_soctherm_driver
);
1495 MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
1496 MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
1497 MODULE_LICENSE("GPL v2");