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 * ccroc_writel() - writes a value to a CCROC 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 ccroc_writel(struct tegra_soctherm
*ts
, u32 value
, u32 reg
)
253 writel(value
, (ts
->ccroc_regs
+ reg
));
257 * ccroc_readl() - reads specified register from CCROC 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
ccroc_readl(struct tegra_soctherm
*ts
, u32 reg
)
265 return readl(ts
->ccroc_regs
+ reg
);
268 static void enable_tsensor(struct tegra_soctherm
*tegra
, unsigned int i
)
270 const struct tegra_tsensor
*sensor
= &tegra
->soc
->tsensors
[i
];
271 void __iomem
*base
= tegra
->regs
+ sensor
->base
;
274 val
= sensor
->config
->tall
<< SENSOR_CONFIG0_TALL_SHIFT
;
275 writel(val
, base
+ SENSOR_CONFIG0
);
277 val
= (sensor
->config
->tsample
- 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT
;
278 val
|= sensor
->config
->tiddq_en
<< SENSOR_CONFIG1_TIDDQ_EN_SHIFT
;
279 val
|= sensor
->config
->ten_count
<< SENSOR_CONFIG1_TEN_COUNT_SHIFT
;
280 val
|= SENSOR_CONFIG1_TEMP_ENABLE
;
281 writel(val
, base
+ SENSOR_CONFIG1
);
283 writel(tegra
->calib
[i
], base
+ SENSOR_CONFIG2
);
287 * Translate from soctherm readback format to millicelsius.
288 * The soctherm readback format in bits is as follows:
290 * where T's contain the temperature in Celsius,
291 * H denotes an addition of 0.5 Celsius and N denotes negation
292 * of the final value.
294 static int translate_temp(u16 val
)
298 t
= ((val
& READBACK_VALUE_MASK
) >> READBACK_VALUE_SHIFT
) * 1000;
299 if (val
& READBACK_ADD_HALF
)
301 if (val
& READBACK_NEGATE
)
307 static int tegra_thermctl_get_temp(void *data
, int *out_temp
)
309 struct tegra_thermctl_zone
*zone
= data
;
312 val
= readl(zone
->reg
);
313 val
= REG_GET_MASK(val
, zone
->sg
->sensor_temp_mask
);
314 *out_temp
= translate_temp(val
);
320 * enforce_temp_range() - check and enforce temperature range [min, max]
321 * @trip_temp: the trip temperature to check
323 * Checks and enforces the permitted temperature range that SOC_THERM
324 * HW can support This is
325 * done while taking care of precision.
327 * Return: The precision adjusted capped temperature in millicelsius.
329 static int enforce_temp_range(struct device
*dev
, int trip_temp
)
333 temp
= clamp_val(trip_temp
, min_low_temp
, max_high_temp
);
334 if (temp
!= trip_temp
)
335 dev_info(dev
, "soctherm: trip temperature %d forced to %d\n",
341 * thermtrip_program() - Configures the hardware to shut down the
342 * system if a given sensor group reaches a given temperature
343 * @dev: ptr to the struct device for the SOC_THERM IP block
344 * @sg: pointer to the sensor group to set the thermtrip temperature for
345 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
347 * Sets the thermal trip threshold of the given sensor group to be the
348 * @trip_temp. If this threshold is crossed, the hardware will shut
351 * Note that, although @trip_temp is specified in millicelsius, the
352 * hardware is programmed in degrees Celsius.
354 * Return: 0 upon success, or %-EINVAL upon failure.
356 static int thermtrip_program(struct device
*dev
,
357 const struct tegra_tsensor_group
*sg
,
360 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
364 if (!sg
|| !sg
->thermtrip_threshold_mask
)
367 temp
= enforce_temp_range(dev
, trip_temp
) / ts
->soc
->thresh_grain
;
369 r
= readl(ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
370 r
= REG_SET_MASK(r
, sg
->thermtrip_threshold_mask
, temp
);
371 r
= REG_SET_MASK(r
, sg
->thermtrip_enable_mask
, 1);
372 r
= REG_SET_MASK(r
, sg
->thermtrip_any_en_mask
, 0);
373 writel(r
, ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
379 * throttrip_program() - Configures the hardware to throttle the
380 * pulse if a given sensor group reaches a given temperature
381 * @dev: ptr to the struct device for the SOC_THERM IP block
382 * @sg: pointer to the sensor group to set the thermtrip temperature for
383 * @stc: pointer to the throttle need to be triggered
384 * @trip_temp: the temperature in millicelsius to trigger the thermal trip at
386 * Sets the thermal trip threshold and throttle event of the given sensor
387 * group. If this threshold is crossed, the hardware will trigger the
390 * Note that, although @trip_temp is specified in millicelsius, the
391 * hardware is programmed in degrees Celsius.
393 * Return: 0 upon success, or %-EINVAL upon failure.
395 static int throttrip_program(struct device
*dev
,
396 const struct tegra_tsensor_group
*sg
,
397 struct soctherm_throt_cfg
*stc
,
400 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
401 int temp
, cpu_throt
, gpu_throt
;
405 if (!sg
|| !stc
|| !stc
->init
)
408 temp
= enforce_temp_range(dev
, trip_temp
) / ts
->soc
->thresh_grain
;
410 /* Hardcode LIGHT on LEVEL1 and HEAVY on LEVEL2 */
412 reg_off
= THERMCTL_LVL_REG(sg
->thermctl_lvl0_offset
, throt
+ 1);
414 if (throt
== THROTTLE_LIGHT
) {
415 cpu_throt
= THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT
;
416 gpu_throt
= THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT
;
418 cpu_throt
= THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY
;
419 gpu_throt
= THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY
;
420 if (throt
!= THROTTLE_HEAVY
)
422 "invalid throt id %d - assuming HEAVY",
426 r
= readl(ts
->regs
+ reg_off
);
427 r
= REG_SET_MASK(r
, sg
->thermctl_lvl0_up_thresh_mask
, temp
);
428 r
= REG_SET_MASK(r
, sg
->thermctl_lvl0_dn_thresh_mask
, temp
);
429 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_CPU_THROT_MASK
, cpu_throt
);
430 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_GPU_THROT_MASK
, gpu_throt
);
431 r
= REG_SET_MASK(r
, THERMCTL_LVL0_CPU0_EN_MASK
, 1);
432 writel(r
, ts
->regs
+ reg_off
);
437 static struct soctherm_throt_cfg
*
438 find_throttle_cfg_by_name(struct tegra_soctherm
*ts
, const char *name
)
442 for (i
= 0; ts
->throt_cfgs
[i
].name
; i
++)
443 if (!strcmp(ts
->throt_cfgs
[i
].name
, name
))
444 return &ts
->throt_cfgs
[i
];
449 static int tegra_thermctl_set_trip_temp(void *data
, int trip
, int temp
)
451 struct tegra_thermctl_zone
*zone
= data
;
452 struct thermal_zone_device
*tz
= zone
->tz
;
453 struct tegra_soctherm
*ts
= zone
->ts
;
454 const struct tegra_tsensor_group
*sg
= zone
->sg
;
455 struct device
*dev
= zone
->dev
;
456 enum thermal_trip_type type
;
462 ret
= tz
->ops
->get_trip_type(tz
, trip
, &type
);
466 if (type
== THERMAL_TRIP_CRITICAL
) {
467 return thermtrip_program(dev
, sg
, temp
);
468 } else if (type
== THERMAL_TRIP_HOT
) {
471 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
472 struct thermal_cooling_device
*cdev
;
473 struct soctherm_throt_cfg
*stc
;
475 if (!ts
->throt_cfgs
[i
].init
)
478 cdev
= ts
->throt_cfgs
[i
].cdev
;
479 if (get_thermal_instance(tz
, cdev
, trip
))
480 stc
= find_throttle_cfg_by_name(ts
, cdev
->type
);
484 return throttrip_program(dev
, sg
, stc
, temp
);
491 static const struct thermal_zone_of_device_ops tegra_of_thermal_ops
= {
492 .get_temp
= tegra_thermctl_get_temp
,
493 .set_trip_temp
= tegra_thermctl_set_trip_temp
,
496 static int get_hot_temp(struct thermal_zone_device
*tz
, int *trip
, int *temp
)
499 enum thermal_trip_type type
;
501 ntrips
= of_thermal_get_ntrips(tz
);
505 for (i
= 0; i
< ntrips
; i
++) {
506 ret
= tz
->ops
->get_trip_type(tz
, i
, &type
);
509 if (type
== THERMAL_TRIP_HOT
) {
510 ret
= tz
->ops
->get_trip_temp(tz
, i
, temp
);
522 * tegra_soctherm_set_hwtrips() - set HW trip point from DT data
523 * @dev: struct device * of the SOC_THERM instance
525 * Configure the SOC_THERM HW trip points, setting "THERMTRIP"
526 * "THROTTLE" trip points , using "critical" or "hot" type trip_temp
528 * After they have been configured, THERMTRIP or THROTTLE will take
529 * action when the configured SoC thermal sensor group reaches a
530 * certain temperature.
532 * Return: 0 upon success, or a negative error code on failure.
533 * "Success" does not mean that trips was enabled; it could also
534 * mean that no node was found in DT.
535 * THERMTRIP has been enabled successfully when a message similar to
536 * this one appears on the serial console:
537 * "thermtrip: will shut down when sensor group XXX reaches YYYYYY mC"
538 * THROTTLE has been enabled successfully when a message similar to
539 * this one appears on the serial console:
540 * ""throttrip: will throttle when sensor group XXX reaches YYYYYY mC"
542 static int tegra_soctherm_set_hwtrips(struct device
*dev
,
543 const struct tegra_tsensor_group
*sg
,
544 struct thermal_zone_device
*tz
)
546 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
547 struct soctherm_throt_cfg
*stc
;
548 int i
, trip
, temperature
;
551 ret
= tz
->ops
->get_crit_temp(tz
, &temperature
);
553 dev_warn(dev
, "thermtrip: %s: missing critical temperature\n",
558 ret
= thermtrip_program(dev
, sg
, temperature
);
560 dev_err(dev
, "thermtrip: %s: error during enable\n",
566 "thermtrip: will shut down when %s reaches %d mC\n",
567 sg
->name
, temperature
);
570 ret
= get_hot_temp(tz
, &trip
, &temperature
);
572 dev_warn(dev
, "throttrip: %s: missing hot temperature\n",
577 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
578 struct thermal_cooling_device
*cdev
;
580 if (!ts
->throt_cfgs
[i
].init
)
583 cdev
= ts
->throt_cfgs
[i
].cdev
;
584 if (get_thermal_instance(tz
, cdev
, trip
))
585 stc
= find_throttle_cfg_by_name(ts
, cdev
->type
);
589 ret
= throttrip_program(dev
, sg
, stc
, temperature
);
591 dev_err(dev
, "throttrip: %s: error during enable\n",
597 "throttrip: will throttle when %s reaches %d mC\n",
598 sg
->name
, temperature
);
602 if (i
== THROTTLE_SIZE
)
603 dev_warn(dev
, "throttrip: %s: missing throttle cdev\n",
609 #ifdef CONFIG_DEBUG_FS
610 static int regs_show(struct seq_file
*s
, void *data
)
612 struct platform_device
*pdev
= s
->private;
613 struct tegra_soctherm
*ts
= platform_get_drvdata(pdev
);
614 const struct tegra_tsensor
*tsensors
= ts
->soc
->tsensors
;
615 const struct tegra_tsensor_group
**ttgs
= ts
->soc
->ttgs
;
619 seq_puts(s
, "-----TSENSE (convert HW)-----\n");
621 for (i
= 0; i
< ts
->soc
->num_tsensors
; i
++) {
622 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG1
);
623 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TEMP_ENABLE
);
625 seq_printf(s
, "%s: ", tsensors
[i
].name
);
626 seq_printf(s
, "En(%d) ", state
);
633 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TIDDQ_EN_MASK
);
634 seq_printf(s
, "tiddq(%d) ", state
);
635 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TEN_COUNT_MASK
);
636 seq_printf(s
, "ten_count(%d) ", state
);
637 state
= REG_GET_MASK(r
, SENSOR_CONFIG1_TSAMPLE_MASK
);
638 seq_printf(s
, "tsample(%d) ", state
+ 1);
640 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_STATUS1
);
641 state
= REG_GET_MASK(r
, SENSOR_STATUS1_TEMP_VALID_MASK
);
642 seq_printf(s
, "Temp(%d/", state
);
643 state
= REG_GET_MASK(r
, SENSOR_STATUS1_TEMP_MASK
);
644 seq_printf(s
, "%d) ", translate_temp(state
));
646 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_STATUS0
);
647 state
= REG_GET_MASK(r
, SENSOR_STATUS0_VALID_MASK
);
648 seq_printf(s
, "Capture(%d/", state
);
649 state
= REG_GET_MASK(r
, SENSOR_STATUS0_CAPTURE_MASK
);
650 seq_printf(s
, "%d) ", state
);
652 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG0
);
653 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_STOP
);
654 seq_printf(s
, "Stop(%d) ", state
);
655 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_TALL_MASK
);
656 seq_printf(s
, "Tall(%d) ", state
);
657 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_TCALC_OVER
);
658 seq_printf(s
, "Over(%d/", state
);
659 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_OVER
);
660 seq_printf(s
, "%d/", state
);
661 state
= REG_GET_MASK(r
, SENSOR_CONFIG0_CPTR_OVER
);
662 seq_printf(s
, "%d) ", state
);
664 r
= readl(ts
->regs
+ tsensors
[i
].base
+ SENSOR_CONFIG2
);
665 state
= REG_GET_MASK(r
, SENSOR_CONFIG2_THERMA_MASK
);
666 seq_printf(s
, "Therm_A/B(%d/", state
);
667 state
= REG_GET_MASK(r
, SENSOR_CONFIG2_THERMB_MASK
);
668 seq_printf(s
, "%d)\n", (s16
)state
);
671 r
= readl(ts
->regs
+ SENSOR_PDIV
);
672 seq_printf(s
, "PDIV: 0x%x\n", r
);
674 r
= readl(ts
->regs
+ SENSOR_HOTSPOT_OFF
);
675 seq_printf(s
, "HOTSPOT: 0x%x\n", r
);
678 seq_puts(s
, "-----SOC_THERM-----\n");
680 r
= readl(ts
->regs
+ SENSOR_TEMP1
);
681 state
= REG_GET_MASK(r
, SENSOR_TEMP1_CPU_TEMP_MASK
);
682 seq_printf(s
, "Temperatures: CPU(%d) ", translate_temp(state
));
683 state
= REG_GET_MASK(r
, SENSOR_TEMP1_GPU_TEMP_MASK
);
684 seq_printf(s
, " GPU(%d) ", translate_temp(state
));
685 r
= readl(ts
->regs
+ SENSOR_TEMP2
);
686 state
= REG_GET_MASK(r
, SENSOR_TEMP2_PLLX_TEMP_MASK
);
687 seq_printf(s
, " PLLX(%d) ", translate_temp(state
));
688 state
= REG_GET_MASK(r
, SENSOR_TEMP2_MEM_TEMP_MASK
);
689 seq_printf(s
, " MEM(%d)\n", translate_temp(state
));
691 for (i
= 0; i
< ts
->soc
->num_ttgs
; i
++) {
692 seq_printf(s
, "%s:\n", ttgs
[i
]->name
);
693 for (level
= 0; level
< 4; level
++) {
696 u16 off
= ttgs
[i
]->thermctl_lvl0_offset
;
698 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
700 mask
= ttgs
[i
]->thermctl_lvl0_up_thresh_mask
;
701 state
= REG_GET_MASK(r
, mask
);
702 v
= sign_extend32(state
, ts
->soc
->bptt
- 1);
703 v
*= ts
->soc
->thresh_grain
;
704 seq_printf(s
, " %d: Up/Dn(%d /", level
, v
);
706 mask
= ttgs
[i
]->thermctl_lvl0_dn_thresh_mask
;
707 state
= REG_GET_MASK(r
, mask
);
708 v
= sign_extend32(state
, ts
->soc
->bptt
- 1);
709 v
*= ts
->soc
->thresh_grain
;
710 seq_printf(s
, "%d ) ", v
);
712 mask
= THERMCTL_LVL0_CPU0_EN_MASK
;
713 state
= REG_GET_MASK(r
, mask
);
714 seq_printf(s
, "En(%d) ", state
);
716 mask
= THERMCTL_LVL0_CPU0_CPU_THROT_MASK
;
717 state
= REG_GET_MASK(r
, mask
);
718 seq_puts(s
, "CPU Throt");
720 seq_printf(s
, "(%s) ", "none");
721 else if (state
== THERMCTL_LVL0_CPU0_CPU_THROT_LIGHT
)
722 seq_printf(s
, "(%s) ", "L");
723 else if (state
== THERMCTL_LVL0_CPU0_CPU_THROT_HEAVY
)
724 seq_printf(s
, "(%s) ", "H");
726 seq_printf(s
, "(%s) ", "H+L");
728 mask
= THERMCTL_LVL0_CPU0_GPU_THROT_MASK
;
729 state
= REG_GET_MASK(r
, mask
);
730 seq_puts(s
, "GPU Throt");
732 seq_printf(s
, "(%s) ", "none");
733 else if (state
== THERMCTL_LVL0_CPU0_GPU_THROT_LIGHT
)
734 seq_printf(s
, "(%s) ", "L");
735 else if (state
== THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY
)
736 seq_printf(s
, "(%s) ", "H");
738 seq_printf(s
, "(%s) ", "H+L");
740 mask
= THERMCTL_LVL0_CPU0_STATUS_MASK
;
741 state
= REG_GET_MASK(r
, mask
);
742 seq_printf(s
, "Status(%s)\n",
745 state
== 2 ? "Res" : "HI");
749 r
= readl(ts
->regs
+ THERMCTL_STATS_CTL
);
750 seq_printf(s
, "STATS: Up(%s) Dn(%s)\n",
751 r
& STATS_CTL_EN_UP
? "En" : "--",
752 r
& STATS_CTL_EN_DN
? "En" : "--");
754 for (level
= 0; level
< 4; level
++) {
757 off
= THERMCTL_LVL0_UP_STATS
;
758 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
759 seq_printf(s
, " Level_%d Up(%d) ", level
, r
);
761 off
= THERMCTL_LVL0_DN_STATS
;
762 r
= readl(ts
->regs
+ THERMCTL_LVL_REG(off
, level
));
763 seq_printf(s
, "Dn(%d)\n", r
);
766 r
= readl(ts
->regs
+ THERMCTL_THERMTRIP_CTL
);
767 state
= REG_GET_MASK(r
, ttgs
[0]->thermtrip_any_en_mask
);
768 seq_printf(s
, "Thermtrip Any En(%d)\n", state
);
769 for (i
= 0; i
< ts
->soc
->num_ttgs
; i
++) {
770 state
= REG_GET_MASK(r
, ttgs
[i
]->thermtrip_enable_mask
);
771 seq_printf(s
, " %s En(%d) ", ttgs
[i
]->name
, state
);
772 state
= REG_GET_MASK(r
, ttgs
[i
]->thermtrip_threshold_mask
);
773 state
*= ts
->soc
->thresh_grain
;
774 seq_printf(s
, "Thresh(%d)\n", state
);
777 r
= readl(ts
->regs
+ THROT_GLOBAL_CFG
);
779 seq_printf(s
, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r
);
781 seq_puts(s
, "---------------------------------------------------\n");
782 r
= readl(ts
->regs
+ THROT_STATUS
);
783 state
= REG_GET_MASK(r
, THROT_STATUS_BREACH_MASK
);
784 seq_printf(s
, "THROT STATUS: breach(%d) ", state
);
785 state
= REG_GET_MASK(r
, THROT_STATUS_STATE_MASK
);
786 seq_printf(s
, "state(%d) ", state
);
787 state
= REG_GET_MASK(r
, THROT_STATUS_ENABLED_MASK
);
788 seq_printf(s
, "enabled(%d)\n", state
);
790 r
= readl(ts
->regs
+ CPU_PSKIP_STATUS
);
791 if (ts
->soc
->use_ccroc
) {
792 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_ENABLED_MASK
);
793 seq_printf(s
, "CPU PSKIP STATUS: enabled(%d)\n", state
);
795 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_M_MASK
);
796 seq_printf(s
, "CPU PSKIP STATUS: M(%d) ", state
);
797 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_N_MASK
);
798 seq_printf(s
, "N(%d) ", state
);
799 state
= REG_GET_MASK(r
, XPU_PSKIP_STATUS_ENABLED_MASK
);
800 seq_printf(s
, "enabled(%d)\n", state
);
806 static int regs_open(struct inode
*inode
, struct file
*file
)
808 return single_open(file
, regs_show
, inode
->i_private
);
811 static const struct file_operations regs_fops
= {
815 .release
= single_release
,
818 static void soctherm_debug_init(struct platform_device
*pdev
)
820 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
821 struct dentry
*root
, *file
;
823 root
= debugfs_create_dir("soctherm", NULL
);
825 dev_err(&pdev
->dev
, "failed to create debugfs directory\n");
829 tegra
->debugfs_dir
= root
;
831 file
= debugfs_create_file("reg_contents", 0644, root
,
834 dev_err(&pdev
->dev
, "failed to create debugfs file\n");
835 debugfs_remove_recursive(tegra
->debugfs_dir
);
836 tegra
->debugfs_dir
= NULL
;
840 static inline void soctherm_debug_init(struct platform_device
*pdev
) {}
843 static int soctherm_clk_enable(struct platform_device
*pdev
, bool enable
)
845 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
848 if (!tegra
->clock_soctherm
|| !tegra
->clock_tsensor
)
851 reset_control_assert(tegra
->reset
);
854 err
= clk_prepare_enable(tegra
->clock_soctherm
);
856 reset_control_deassert(tegra
->reset
);
860 err
= clk_prepare_enable(tegra
->clock_tsensor
);
862 clk_disable_unprepare(tegra
->clock_soctherm
);
863 reset_control_deassert(tegra
->reset
);
867 clk_disable_unprepare(tegra
->clock_tsensor
);
868 clk_disable_unprepare(tegra
->clock_soctherm
);
871 reset_control_deassert(tegra
->reset
);
876 static int throt_get_cdev_max_state(struct thermal_cooling_device
*cdev
,
877 unsigned long *max_state
)
883 static int throt_get_cdev_cur_state(struct thermal_cooling_device
*cdev
,
884 unsigned long *cur_state
)
886 struct tegra_soctherm
*ts
= cdev
->devdata
;
889 r
= readl(ts
->regs
+ THROT_STATUS
);
890 if (REG_GET_MASK(r
, THROT_STATUS_STATE_MASK
))
898 static int throt_set_cdev_state(struct thermal_cooling_device
*cdev
,
899 unsigned long cur_state
)
904 static const struct thermal_cooling_device_ops throt_cooling_ops
= {
905 .get_max_state
= throt_get_cdev_max_state
,
906 .get_cur_state
= throt_get_cdev_cur_state
,
907 .set_cur_state
= throt_set_cdev_state
,
911 * soctherm_init_hw_throt_cdev() - Parse the HW throttle configurations
912 * and register them as cooling devices.
914 static void soctherm_init_hw_throt_cdev(struct platform_device
*pdev
)
916 struct device
*dev
= &pdev
->dev
;
917 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
918 struct device_node
*np_stc
, *np_stcc
;
923 for (i
= 0; i
< THROTTLE_SIZE
; i
++) {
924 ts
->throt_cfgs
[i
].name
= throt_names
[i
];
925 ts
->throt_cfgs
[i
].id
= i
;
926 ts
->throt_cfgs
[i
].init
= false;
929 np_stc
= of_get_child_by_name(dev
->of_node
, "throttle-cfgs");
932 "throttle-cfg: no throttle-cfgs - not enabling\n");
936 for_each_child_of_node(np_stc
, np_stcc
) {
937 struct soctherm_throt_cfg
*stc
;
938 struct thermal_cooling_device
*tcd
;
940 name
= np_stcc
->name
;
941 stc
= find_throttle_cfg_by_name(ts
, name
);
944 "throttle-cfg: could not find %s\n", name
);
948 r
= of_property_read_u32(np_stcc
, "nvidia,priority", &val
);
951 "throttle-cfg: %s: missing priority\n", name
);
956 if (ts
->soc
->use_ccroc
) {
957 r
= of_property_read_u32(np_stcc
,
958 "nvidia,cpu-throt-level",
962 "throttle-cfg: %s: missing cpu-throt-level\n",
966 stc
->cpu_throt_level
= val
;
968 r
= of_property_read_u32(np_stcc
,
969 "nvidia,cpu-throt-percent",
973 "throttle-cfg: %s: missing cpu-throt-percent\n",
977 stc
->cpu_throt_depth
= val
;
980 tcd
= thermal_of_cooling_device_register(np_stcc
,
983 of_node_put(np_stcc
);
984 if (IS_ERR_OR_NULL(tcd
)) {
986 "throttle-cfg: %s: failed to register cooling device\n",
999 * throttlectl_cpu_level_cfg() - programs CCROC NV_THERM level config
1000 * @level: describing the level LOW/MED/HIGH of throttling
1002 * It's necessary to set up the CPU-local CCROC NV_THERM instance with
1003 * the M/N values desired for each level. This function does this.
1005 * This function pre-programs the CCROC NV_THERM levels in terms of
1006 * pre-configured "Low", "Medium" or "Heavy" throttle levels which are
1007 * mapped to THROT_LEVEL_LOW, THROT_LEVEL_MED and THROT_LEVEL_HVY.
1009 static void throttlectl_cpu_level_cfg(struct tegra_soctherm
*ts
, int level
)
1015 case TEGRA_SOCTHERM_THROT_LEVEL_LOW
:
1018 case TEGRA_SOCTHERM_THROT_LEVEL_MED
:
1021 case TEGRA_SOCTHERM_THROT_LEVEL_HIGH
:
1024 case TEGRA_SOCTHERM_THROT_LEVEL_NONE
:
1030 dividend
= THROT_DEPTH_DIVIDEND(depth
);
1032 /* setup PSKIP in ccroc nv_therm registers */
1033 r
= ccroc_readl(ts
, CCROC_THROT_PSKIP_RAMP_CPU_REG(level
));
1034 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_RAMP_DURATION_MASK
, 0xff);
1035 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_RAMP_STEP_MASK
, 0xf);
1036 ccroc_writel(ts
, r
, CCROC_THROT_PSKIP_RAMP_CPU_REG(level
));
1038 r
= ccroc_readl(ts
, CCROC_THROT_PSKIP_CTRL_CPU_REG(level
));
1039 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_ENB_MASK
, 1);
1040 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_DIVIDEND_MASK
, dividend
);
1041 r
= REG_SET_MASK(r
, CCROC_THROT_PSKIP_CTRL_DIVISOR_MASK
, 0xff);
1042 ccroc_writel(ts
, r
, CCROC_THROT_PSKIP_CTRL_CPU_REG(level
));
1046 * throttlectl_cpu_level_select() - program CPU pulse skipper config
1047 * @throt: the LIGHT/HEAVY of throttle event id
1049 * Pulse skippers are used to throttle clock frequencies. This
1050 * function programs the pulse skippers based on @throt and platform
1051 * data. This function is used on SoCs which have CPU-local pulse
1052 * skipper control, such as T13x. It programs soctherm's interface to
1053 * Denver:CCROC NV_THERM in terms of Low, Medium and HIGH throttling
1054 * vectors. PSKIP_BYPASS mode is set as required per HW spec.
1056 static void throttlectl_cpu_level_select(struct tegra_soctherm
*ts
,
1057 enum soctherm_throttle_id throt
)
1061 /* Denver:CCROC NV_THERM interface N:3 Mapping */
1062 switch (ts
->throt_cfgs
[throt
].cpu_throt_level
) {
1063 case TEGRA_SOCTHERM_THROT_LEVEL_LOW
:
1064 throt_vect
= THROT_VECT_LOW
;
1066 case TEGRA_SOCTHERM_THROT_LEVEL_MED
:
1067 throt_vect
= THROT_VECT_MED
;
1069 case TEGRA_SOCTHERM_THROT_LEVEL_HIGH
:
1070 throt_vect
= THROT_VECT_HIGH
;
1073 throt_vect
= THROT_VECT_NONE
;
1077 r
= readl(ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1078 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_ENABLE_MASK
, 1);
1079 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_VECT_CPU_MASK
, throt_vect
);
1080 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_VECT2_CPU_MASK
, throt_vect
);
1081 writel(r
, ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1083 /* bypass sequencer in soc_therm as it is programmed in ccroc */
1084 r
= REG_SET_MASK(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK
, 1);
1085 writel(r
, ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1089 * throttlectl_cpu_mn() - program CPU pulse skipper configuration
1090 * @throt: the LIGHT/HEAVY of throttle event id
1092 * Pulse skippers are used to throttle clock frequencies. This
1093 * function programs the pulse skippers based on @throt and platform
1094 * data. This function is used for CPUs that have "remote" pulse
1095 * skipper control, e.g., the CPU pulse skipper is controlled by the
1096 * SOC_THERM IP block. (SOC_THERM is located outside the CPU
1099 static void throttlectl_cpu_mn(struct tegra_soctherm
*ts
,
1100 enum soctherm_throttle_id throt
)
1106 depth
= ts
->throt_cfgs
[throt
].cpu_throt_depth
;
1107 dividend
= THROT_DEPTH_DIVIDEND(depth
);
1109 r
= readl(ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1110 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_ENABLE_MASK
, 1);
1111 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_DIVIDEND_MASK
, dividend
);
1112 r
= REG_SET_MASK(r
, THROT_PSKIP_CTRL_DIVISOR_MASK
, 0xff);
1113 writel(r
, ts
->regs
+ THROT_PSKIP_CTRL(throt
, THROTTLE_DEV_CPU
));
1115 r
= readl(ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1116 r
= REG_SET_MASK(r
, THROT_PSKIP_RAMP_DURATION_MASK
, 0xff);
1117 r
= REG_SET_MASK(r
, THROT_PSKIP_RAMP_STEP_MASK
, 0xf);
1118 writel(r
, ts
->regs
+ THROT_PSKIP_RAMP(throt
, THROTTLE_DEV_CPU
));
1122 * soctherm_throttle_program() - programs pulse skippers' configuration
1123 * @throt: the LIGHT/HEAVY of the throttle event id.
1125 * Pulse skippers are used to throttle clock frequencies.
1126 * This function programs the pulse skippers.
1128 static void soctherm_throttle_program(struct tegra_soctherm
*ts
,
1129 enum soctherm_throttle_id throt
)
1132 struct soctherm_throt_cfg stc
= ts
->throt_cfgs
[throt
];
1137 /* Setup PSKIP parameters */
1138 if (ts
->soc
->use_ccroc
)
1139 throttlectl_cpu_level_select(ts
, throt
);
1141 throttlectl_cpu_mn(ts
, throt
);
1143 r
= REG_SET_MASK(0, THROT_PRIORITY_LITE_PRIO_MASK
, stc
.priority
);
1144 writel(r
, ts
->regs
+ THROT_PRIORITY_CTRL(throt
));
1146 r
= REG_SET_MASK(0, THROT_DELAY_LITE_DELAY_MASK
, 0);
1147 writel(r
, ts
->regs
+ THROT_DELAY_CTRL(throt
));
1149 r
= readl(ts
->regs
+ THROT_PRIORITY_LOCK
);
1150 r
= REG_GET_MASK(r
, THROT_PRIORITY_LOCK_PRIORITY_MASK
);
1151 if (r
>= stc
.priority
)
1153 r
= REG_SET_MASK(0, THROT_PRIORITY_LOCK_PRIORITY_MASK
,
1155 writel(r
, ts
->regs
+ THROT_PRIORITY_LOCK
);
1158 static void tegra_soctherm_throttle(struct device
*dev
)
1160 struct tegra_soctherm
*ts
= dev_get_drvdata(dev
);
1164 /* configure LOW, MED and HIGH levels for CCROC NV_THERM */
1165 if (ts
->soc
->use_ccroc
) {
1166 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_LOW
);
1167 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_MED
);
1168 throttlectl_cpu_level_cfg(ts
, TEGRA_SOCTHERM_THROT_LEVEL_HIGH
);
1171 /* Thermal HW throttle programming */
1172 for (i
= 0; i
< THROTTLE_SIZE
; i
++)
1173 soctherm_throttle_program(ts
, i
);
1175 v
= REG_SET_MASK(0, THROT_GLOBAL_ENB_MASK
, 1);
1176 if (ts
->soc
->use_ccroc
) {
1177 ccroc_writel(ts
, v
, CCROC_GLOBAL_CFG
);
1179 v
= ccroc_readl(ts
, CCROC_SUPER_CCLKG_DIVIDER
);
1180 v
= REG_SET_MASK(v
, CDIVG_USE_THERM_CONTROLS_MASK
, 1);
1181 ccroc_writel(ts
, v
, CCROC_SUPER_CCLKG_DIVIDER
);
1183 writel(v
, ts
->regs
+ THROT_GLOBAL_CFG
);
1185 v
= readl(ts
->clk_regs
+ CAR_SUPER_CCLKG_DIVIDER
);
1186 v
= REG_SET_MASK(v
, CDIVG_USE_THERM_CONTROLS_MASK
, 1);
1187 writel(v
, ts
->clk_regs
+ CAR_SUPER_CCLKG_DIVIDER
);
1190 /* initialize stats collection */
1191 v
= STATS_CTL_CLR_DN
| STATS_CTL_EN_DN
|
1192 STATS_CTL_CLR_UP
| STATS_CTL_EN_UP
;
1193 writel(v
, ts
->regs
+ THERMCTL_STATS_CTL
);
1196 static void soctherm_init(struct platform_device
*pdev
)
1198 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1199 const struct tegra_tsensor_group
**ttgs
= tegra
->soc
->ttgs
;
1203 /* Initialize raw sensors */
1204 for (i
= 0; i
< tegra
->soc
->num_tsensors
; ++i
)
1205 enable_tsensor(tegra
, i
);
1207 /* program pdiv and hotspot offsets per THERM */
1208 pdiv
= readl(tegra
->regs
+ SENSOR_PDIV
);
1209 hotspot
= readl(tegra
->regs
+ SENSOR_HOTSPOT_OFF
);
1210 for (i
= 0; i
< tegra
->soc
->num_ttgs
; ++i
) {
1211 pdiv
= REG_SET_MASK(pdiv
, ttgs
[i
]->pdiv_mask
,
1213 /* hotspot offset from PLLX, doesn't need to configure PLLX */
1214 if (ttgs
[i
]->id
== TEGRA124_SOCTHERM_SENSOR_PLLX
)
1216 hotspot
= REG_SET_MASK(hotspot
,
1217 ttgs
[i
]->pllx_hotspot_mask
,
1218 ttgs
[i
]->pllx_hotspot_diff
);
1220 writel(pdiv
, tegra
->regs
+ SENSOR_PDIV
);
1221 writel(hotspot
, tegra
->regs
+ SENSOR_HOTSPOT_OFF
);
1223 /* Configure hw throttle */
1224 tegra_soctherm_throttle(&pdev
->dev
);
1227 static const struct of_device_id tegra_soctherm_of_match
[] = {
1228 #ifdef CONFIG_ARCH_TEGRA_124_SOC
1230 .compatible
= "nvidia,tegra124-soctherm",
1231 .data
= &tegra124_soctherm
,
1234 #ifdef CONFIG_ARCH_TEGRA_132_SOC
1236 .compatible
= "nvidia,tegra132-soctherm",
1237 .data
= &tegra132_soctherm
,
1240 #ifdef CONFIG_ARCH_TEGRA_210_SOC
1242 .compatible
= "nvidia,tegra210-soctherm",
1243 .data
= &tegra210_soctherm
,
1248 MODULE_DEVICE_TABLE(of
, tegra_soctherm_of_match
);
1250 static int tegra_soctherm_probe(struct platform_device
*pdev
)
1252 const struct of_device_id
*match
;
1253 struct tegra_soctherm
*tegra
;
1254 struct thermal_zone_device
*z
;
1255 struct tsensor_shared_calib shared_calib
;
1256 struct resource
*res
;
1257 struct tegra_soctherm_soc
*soc
;
1261 match
= of_match_node(tegra_soctherm_of_match
, pdev
->dev
.of_node
);
1265 soc
= (struct tegra_soctherm_soc
*)match
->data
;
1266 if (soc
->num_ttgs
> TEGRA124_SOCTHERM_SENSOR_NUM
)
1269 tegra
= devm_kzalloc(&pdev
->dev
, sizeof(*tegra
), GFP_KERNEL
);
1273 dev_set_drvdata(&pdev
->dev
, tegra
);
1277 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1279 tegra
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1280 if (IS_ERR(tegra
->regs
)) {
1281 dev_err(&pdev
->dev
, "can't get soctherm registers");
1282 return PTR_ERR(tegra
->regs
);
1285 if (!tegra
->soc
->use_ccroc
) {
1286 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1288 tegra
->clk_regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1289 if (IS_ERR(tegra
->clk_regs
)) {
1290 dev_err(&pdev
->dev
, "can't get car clk registers");
1291 return PTR_ERR(tegra
->clk_regs
);
1294 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1296 tegra
->ccroc_regs
= devm_ioremap_resource(&pdev
->dev
, res
);
1297 if (IS_ERR(tegra
->ccroc_regs
)) {
1298 dev_err(&pdev
->dev
, "can't get ccroc registers");
1299 return PTR_ERR(tegra
->ccroc_regs
);
1303 tegra
->reset
= devm_reset_control_get(&pdev
->dev
, "soctherm");
1304 if (IS_ERR(tegra
->reset
)) {
1305 dev_err(&pdev
->dev
, "can't get soctherm reset\n");
1306 return PTR_ERR(tegra
->reset
);
1309 tegra
->clock_tsensor
= devm_clk_get(&pdev
->dev
, "tsensor");
1310 if (IS_ERR(tegra
->clock_tsensor
)) {
1311 dev_err(&pdev
->dev
, "can't get tsensor clock\n");
1312 return PTR_ERR(tegra
->clock_tsensor
);
1315 tegra
->clock_soctherm
= devm_clk_get(&pdev
->dev
, "soctherm");
1316 if (IS_ERR(tegra
->clock_soctherm
)) {
1317 dev_err(&pdev
->dev
, "can't get soctherm clock\n");
1318 return PTR_ERR(tegra
->clock_soctherm
);
1321 tegra
->calib
= devm_kcalloc(&pdev
->dev
,
1322 soc
->num_tsensors
, sizeof(u32
),
1327 /* calculate shared calibration data */
1328 err
= tegra_calc_shared_calib(soc
->tfuse
, &shared_calib
);
1332 /* calculate tsensor calibaration data */
1333 for (i
= 0; i
< soc
->num_tsensors
; ++i
) {
1334 err
= tegra_calc_tsensor_calib(&soc
->tsensors
[i
],
1341 tegra
->thermctl_tzs
= devm_kcalloc(&pdev
->dev
,
1342 soc
->num_ttgs
, sizeof(*z
),
1344 if (!tegra
->thermctl_tzs
)
1347 err
= soctherm_clk_enable(pdev
, true);
1351 soctherm_init_hw_throt_cdev(pdev
);
1353 soctherm_init(pdev
);
1355 for (i
= 0; i
< soc
->num_ttgs
; ++i
) {
1356 struct tegra_thermctl_zone
*zone
=
1357 devm_kzalloc(&pdev
->dev
, sizeof(*zone
), GFP_KERNEL
);
1360 goto disable_clocks
;
1363 zone
->reg
= tegra
->regs
+ soc
->ttgs
[i
]->sensor_temp_offset
;
1364 zone
->dev
= &pdev
->dev
;
1365 zone
->sg
= soc
->ttgs
[i
];
1368 z
= devm_thermal_zone_of_sensor_register(&pdev
->dev
,
1369 soc
->ttgs
[i
]->id
, zone
,
1370 &tegra_of_thermal_ops
);
1373 dev_err(&pdev
->dev
, "failed to register sensor: %d\n",
1375 goto disable_clocks
;
1379 tegra
->thermctl_tzs
[soc
->ttgs
[i
]->id
] = z
;
1381 /* Configure hw trip points */
1382 err
= tegra_soctherm_set_hwtrips(&pdev
->dev
, soc
->ttgs
[i
], z
);
1384 goto disable_clocks
;
1387 soctherm_debug_init(pdev
);
1392 soctherm_clk_enable(pdev
, false);
1397 static int tegra_soctherm_remove(struct platform_device
*pdev
)
1399 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1401 debugfs_remove_recursive(tegra
->debugfs_dir
);
1403 soctherm_clk_enable(pdev
, false);
1408 static int __maybe_unused
soctherm_suspend(struct device
*dev
)
1410 struct platform_device
*pdev
= to_platform_device(dev
);
1412 soctherm_clk_enable(pdev
, false);
1417 static int __maybe_unused
soctherm_resume(struct device
*dev
)
1419 struct platform_device
*pdev
= to_platform_device(dev
);
1420 struct tegra_soctherm
*tegra
= platform_get_drvdata(pdev
);
1421 struct tegra_soctherm_soc
*soc
= tegra
->soc
;
1424 err
= soctherm_clk_enable(pdev
, true);
1427 "Resume failed: enable clocks failed\n");
1431 soctherm_init(pdev
);
1433 for (i
= 0; i
< soc
->num_ttgs
; ++i
) {
1434 struct thermal_zone_device
*tz
;
1436 tz
= tegra
->thermctl_tzs
[soc
->ttgs
[i
]->id
];
1437 err
= tegra_soctherm_set_hwtrips(dev
, soc
->ttgs
[i
], tz
);
1440 "Resume failed: set hwtrips failed\n");
1448 static SIMPLE_DEV_PM_OPS(tegra_soctherm_pm
, soctherm_suspend
, soctherm_resume
);
1450 static struct platform_driver tegra_soctherm_driver
= {
1451 .probe
= tegra_soctherm_probe
,
1452 .remove
= tegra_soctherm_remove
,
1454 .name
= "tegra_soctherm",
1455 .pm
= &tegra_soctherm_pm
,
1456 .of_match_table
= tegra_soctherm_of_match
,
1459 module_platform_driver(tegra_soctherm_driver
);
1461 MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
1462 MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
1463 MODULE_LICENSE("GPL v2");