2 * arch/arm/mach-tegra/tegra11_soctherm.c
4 * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <linux/debugfs.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/list.h>
23 #include <linux/mutex.h>
24 #include <linux/delay.h>
25 #include <linux/err.h>
26 #include <linux/gpio.h>
28 #include <linux/clk.h>
29 #include <linux/cpufreq.h>
30 #include <linux/seq_file.h>
31 #include <linux/irq.h>
32 #include <linux/interrupt.h>
33 #include <linux/irqdomain.h>
34 #include <linux/slab.h>
35 #include <linux/suspend.h>
36 #include <linux/uaccess.h>
37 #include <linux/thermal.h>
38 #include <linux/platform_data/thermal_sensors.h>
39 #include <linux/pid_thermal_gov.h>
40 #include <linux/bug.h>
41 #include <linux/tegra-fuse.h>
42 #include <linux/tegra-pmc.h>
43 #include <linux/regulator/consumer.h>
46 #include "tegra11_soctherm.h"
47 #include "gpio-names.h"
51 static const int MAX_HIGH_TEMP = 127000;
52 static const int MIN_LOW_TEMP = -127000;
54 /* Min temp granularity specified as X in 2^X.
55 * -1: Hi precision option: 2^-1 = 0.5C (T12x onwards)
56 * 0: Lo precision option: 2^0 = 1.0C
58 #ifdef CONFIG_ARCH_TEGRA_12x_SOC
59 static const int precision = -1; /* Use high precision on T12x */
61 static const int precision; /* default 0 -> low precision */
64 #define LOWER_PRECISION_FOR_CONV(val) ((!precision) ? ((val)*2) : (val))
65 #define LOWER_PRECISION_FOR_TEMP(val) ((!precision) ? ((val)/2) : (val))
66 #define PRECISION_IS_LOWER() ((!precision))
67 #define PRECISION_TO_STR() ((!precision) ? "Lo" : "Hi")
69 #define TS_TSENSE_REGS_SIZE 0x20
70 #define TS_TSENSE_REG_OFFSET(reg, ts) ((reg) + ((ts) * TS_TSENSE_REGS_SIZE))
72 #define TS_THERM_LVL_REGS_SIZE 0x20
73 #define TS_THERM_GRP_REGS_SIZE 0x04
74 #define TS_THERM_REG_OFFSET(rg, lv, gr) ((rg) + ((lv) * TS_THERM_LVL_REGS_SIZE)\
75 + ((gr) * TS_THERM_GRP_REGS_SIZE))
77 #define CTL_LVL0_CPU0 0x0
78 #define CTL_LVL0_CPU0_UP_THRESH_SHIFT 17
79 #define CTL_LVL0_CPU0_UP_THRESH_MASK 0xff
80 #define CTL_LVL0_CPU0_DN_THRESH_SHIFT 9
81 #define CTL_LVL0_CPU0_DN_THRESH_MASK 0xff
82 #define CTL_LVL0_CPU0_EN_SHIFT 8
83 #define CTL_LVL0_CPU0_EN_MASK 0x1
84 #define CTL_LVL0_CPU0_CPU_THROT_SHIFT 5
85 #define CTL_LVL0_CPU0_CPU_THROT_MASK 0x3
86 #define CTL_LVL0_CPU0_CPU_THROT_LIGHT 0x1
87 #define CTL_LVL0_CPU0_CPU_THROT_HEAVY 0x2
88 #define CTL_LVL0_CPU0_GPU_THROT_SHIFT 3
89 #define CTL_LVL0_CPU0_GPU_THROT_MASK 0x3
90 #define CTL_LVL0_CPU0_GPU_THROT_LIGHT 0x1
91 #define CTL_LVL0_CPU0_GPU_THROT_HEAVY 0x2
92 #define CTL_LVL0_CPU0_MEM_THROT_SHIFT 2
93 #define CTL_LVL0_CPU0_MEM_THROT_MASK 0x1
94 #define CTL_LVL0_CPU0_STATUS_SHIFT 0
95 #define CTL_LVL0_CPU0_STATUS_MASK 0x3
97 #define THERMTRIP 0x80
98 #define THERMTRIP_ANY_EN_SHIFT 28
99 #define THERMTRIP_ANY_EN_MASK 0x1
100 #define THERMTRIP_MEM_EN_SHIFT 27
101 #define THERMTRIP_MEM_EN_MASK 0x1
102 #define THERMTRIP_GPU_EN_SHIFT 26
103 #define THERMTRIP_GPU_EN_MASK 0x1
104 #define THERMTRIP_CPU_EN_SHIFT 25
105 #define THERMTRIP_CPU_EN_MASK 0x1
106 #define THERMTRIP_TSENSE_EN_SHIFT 24
107 #define THERMTRIP_TSENSE_EN_MASK 0x1
108 #define THERMTRIP_GPUMEM_THRESH_SHIFT 16
109 #define THERMTRIP_GPUMEM_THRESH_MASK 0xff
110 #define THERMTRIP_CPU_THRESH_SHIFT 8
111 #define THERMTRIP_CPU_THRESH_MASK 0xff
112 #define THERMTRIP_TSENSE_THRESH_SHIFT 0
113 #define THERMTRIP_TSENSE_THRESH_MASK 0xff
115 #define TS_CPU0_CONFIG0 0xc0
116 #define TS_CPU0_CONFIG0_TALL_SHIFT 8
117 #define TS_CPU0_CONFIG0_TALL_MASK 0xfffff
118 #define TS_CPU0_CONFIG0_TCALC_OVER_SHIFT 4
119 #define TS_CPU0_CONFIG0_TCALC_OVER_MASK 0x1
120 #define TS_CPU0_CONFIG0_OVER_SHIFT 3
121 #define TS_CPU0_CONFIG0_OVER_MASK 0x1
122 #define TS_CPU0_CONFIG0_CPTR_OVER_SHIFT 2
123 #define TS_CPU0_CONFIG0_CPTR_OVER_MASK 0x1
124 #define TS_CPU0_CONFIG0_STOP_SHIFT 0
125 #define TS_CPU0_CONFIG0_STOP_MASK 0x1
127 #define TS_CPU0_CONFIG1 0xc4
128 #define TS_CPU0_CONFIG1_EN_SHIFT 31
129 #define TS_CPU0_CONFIG1_EN_MASK 0x1
130 #define TS_CPU0_CONFIG1_TIDDQ_SHIFT 15
131 #define TS_CPU0_CONFIG1_TIDDQ_MASK 0x3f
132 #define TS_CPU0_CONFIG1_TEN_COUNT_SHIFT 24
133 #define TS_CPU0_CONFIG1_TEN_COUNT_MASK 0x3f
134 #define TS_CPU0_CONFIG1_TSAMPLE_SHIFT 0
135 #define TS_CPU0_CONFIG1_TSAMPLE_MASK 0x3ff
137 #define TS_CPU0_CONFIG2 0xc8
138 #define TS_CPU0_CONFIG2_THERM_A_SHIFT 16
139 #define TS_CPU0_CONFIG2_THERM_A_MASK 0xffff
140 #define TS_CPU0_CONFIG2_THERM_B_SHIFT 0
141 #define TS_CPU0_CONFIG2_THERM_B_MASK 0xffff
143 #define TS_CPU0_STATUS0 0xcc
144 #define TS_CPU0_STATUS0_VALID_SHIFT 31
145 #define TS_CPU0_STATUS0_VALID_MASK 0x1
146 #define TS_CPU0_STATUS0_CAPTURE_SHIFT 0
147 #define TS_CPU0_STATUS0_CAPTURE_MASK 0xffff
149 #define TS_CPU0_STATUS1 0xd0
150 #define TS_CPU0_STATUS1_TEMP_VALID_SHIFT 31
151 #define TS_CPU0_STATUS1_TEMP_VALID_MASK 0x1
152 #define TS_CPU0_STATUS1_TEMP_SHIFT 0
153 #define TS_CPU0_STATUS1_TEMP_MASK 0xffff
155 #define TS_CPU0_STATUS2 0xd4
157 #define TS_PDIV 0x1c0
158 #define TS_PDIV_CPU_SHIFT 12
159 #define TS_PDIV_CPU_MASK 0xf
160 #define TS_PDIV_GPU_SHIFT 8
161 #define TS_PDIV_GPU_MASK 0xf
162 #define TS_PDIV_MEM_SHIFT 4
163 #define TS_PDIV_MEM_MASK 0xf
164 #define TS_PDIV_PLLX_SHIFT 0
165 #define TS_PDIV_PLLX_MASK 0xf
167 #define TS_HOTSPOT_OFF 0x1c4
168 #define TS_HOTSPOT_OFF_CPU_SHIFT 16
169 #define TS_HOTSPOT_OFF_CPU_MASK 0xff
170 #define TS_HOTSPOT_OFF_GPU_SHIFT 8
171 #define TS_HOTSPOT_OFF_GPU_MASK 0xff
172 #define TS_HOTSPOT_OFF_MEM_SHIFT 0
173 #define TS_HOTSPOT_OFF_MEM_MASK 0xff
175 #define TS_TEMP1 0x1c8
176 #define TS_TEMP1_CPU_TEMP_SHIFT 16
177 #define TS_TEMP1_CPU_TEMP_MASK 0xffff
178 #define TS_TEMP1_GPU_TEMP_SHIFT 0
179 #define TS_TEMP1_GPU_TEMP_MASK 0xffff
181 #define TS_TEMP2 0x1cc
182 #define TS_TEMP2_MEM_TEMP_SHIFT 16
183 #define TS_TEMP2_MEM_TEMP_MASK 0xffff
184 #define TS_TEMP2_PLLX_TEMP_SHIFT 0
185 #define TS_TEMP2_PLLX_TEMP_MASK 0xffff
187 #define TS_TEMP_SW_OVERRIDE 0x1d8
189 #define TH_INTR_STATUS 0x84
190 #define TH_INTR_ENABLE 0x88
191 #define TH_INTR_DISABLE 0x8c
193 #define LOCK_CTL 0x90
195 #define TH_INTR_POS_MD3_SHIFT 31
196 #define TH_INTR_POS_MD3_MASK 0x1
197 #define TH_INTR_POS_MU3_SHIFT 30
198 #define TH_INTR_POS_MU3_MASK 0x1
199 #define TH_INTR_POS_MD2_SHIFT 29
200 #define TH_INTR_POS_MD2_MASK 0x1
201 #define TH_INTR_POS_MU2_SHIFT 28
202 #define TH_INTR_POS_MU2_MASK 0x1
203 #define TH_INTR_POS_MD1_SHIFT 27
204 #define TH_INTR_POS_MD1_MASK 0x1
205 #define TH_INTR_POS_MU1_SHIFT 26
206 #define TH_INTR_POS_MU1_MASK 0x1
207 #define TH_INTR_POS_MD0_SHIFT 25
208 #define TH_INTR_POS_MD0_MASK 0x1
209 #define TH_INTR_POS_MU0_SHIFT 24
210 #define TH_INTR_POS_MU0_MASK 0x1
211 #define TH_INTR_POS_GD3_SHIFT 23
212 #define TH_INTR_POS_GD3_MASK 0x1
213 #define TH_INTR_POS_GU3_SHIFT 22
214 #define TH_INTR_POS_GU3_MASK 0x1
215 #define TH_INTR_POS_GD2_SHIFT 21
216 #define TH_INTR_POS_GD2_MASK 0x1
217 #define TH_INTR_POS_GU2_SHIFT 20
218 #define TH_INTR_POS_GU2_MASK 0x1
219 #define TH_INTR_POS_GD1_SHIFT 19
220 #define TH_INTR_POS_GD1_MASK 0x1
221 #define TH_INTR_POS_GU1_SHIFT 18
222 #define TH_INTR_POS_GU1_MASK 0x1
223 #define TH_INTR_POS_GD0_SHIFT 17
224 #define TH_INTR_POS_GD0_MASK 0x1
225 #define TH_INTR_POS_GU0_SHIFT 16
226 #define TH_INTR_POS_GU0_MASK 0x1
227 #define TH_INTR_POS_CD3_SHIFT 15
228 #define TH_INTR_POS_CD3_MASK 0x1
229 #define TH_INTR_POS_CU3_SHIFT 14
230 #define TH_INTR_POS_CU3_MASK 0x1
231 #define TH_INTR_POS_CD2_SHIFT 13
232 #define TH_INTR_POS_CD2_MASK 0x1
233 #define TH_INTR_POS_CU2_SHIFT 12
234 #define TH_INTR_POS_CU2_MASK 0x1
235 #define TH_INTR_POS_CD1_SHIFT 11
236 #define TH_INTR_POS_CD1_MASK 0x1
237 #define TH_INTR_POS_CU1_SHIFT 10
238 #define TH_INTR_POS_CU1_MASK 0x1
239 #define TH_INTR_POS_CD0_SHIFT 9
240 #define TH_INTR_POS_CD0_MASK 0x1
241 #define TH_INTR_POS_CU0_SHIFT 8
242 #define TH_INTR_POS_CU0_MASK 0x1
243 #define TH_INTR_POS_PD3_SHIFT 7
244 #define TH_INTR_POS_PD3_MASK 0x1
245 #define TH_INTR_POS_PU3_SHIFT 6
246 #define TH_INTR_POS_PU3_MASK 0x1
247 #define TH_INTR_POS_PD2_SHIFT 5
248 #define TH_INTR_POS_PD2_MASK 0x1
249 #define TH_INTR_POS_PU2_SHIFT 4
250 #define TH_INTR_POS_PU2_MASK 0x1
251 #define TH_INTR_POS_PD1_SHIFT 3
252 #define TH_INTR_POS_PD1_MASK 0x1
253 #define TH_INTR_POS_PU1_SHIFT 2
254 #define TH_INTR_POS_PU1_MASK 0x1
255 #define TH_INTR_POS_PD0_SHIFT 1
256 #define TH_INTR_POS_PD0_MASK 0x1
257 #define TH_INTR_POS_PU0_SHIFT 0
258 #define TH_INTR_POS_PU0_MASK 0x1
261 #define UP_STATS_L0 0x10
262 #define DN_STATS_L0 0x14
264 #define STATS_CTL 0x94
265 #define STATS_CTL_CLR_DN 0x8
266 #define STATS_CTL_EN_DN 0x4
267 #define STATS_CTL_CLR_UP 0x2
268 #define STATS_CTL_EN_UP 0x1
270 #define THROT_GLOBAL_CFG 0x400
271 #define THROT13_GLOBAL_CFG 0x148
272 #define THROT_GLOBAL_ENB_SHIFT 0
273 #define THROT_GLOBAL_ENB_MASK 0x1
275 #define OC1_CFG 0x310
276 #define OC1_CFG_LONG_LATENCY_SHIFT 6
277 #define OC1_CFG_LONG_LATENCY_MASK 0x1
278 #define OC1_CFG_HW_RESTORE_SHIFT 5
279 #define OC1_CFG_HW_RESTORE_MASK 0x1
280 #define OC1_CFG_PWR_GOOD_MASK_SHIFT 4
281 #define OC1_CFG_PWR_GOOD_MASK_MASK 0x1
282 #define OC1_CFG_THROTTLE_MODE_SHIFT 2
283 #define OC1_CFG_THROTTLE_MODE_MASK 0x3
284 #define OC1_CFG_ALARM_POLARITY_SHIFT 1
285 #define OC1_CFG_ALARM_POLARITY_MASK 0x1
286 #define OC1_CFG_EN_THROTTLE_SHIFT 0
287 #define OC1_CFG_EN_THROTTLE_MASK 0x1
289 #define OC1_CNT_THRESHOLD 0x314
290 #define OC1_THROTTLE_PERIOD 0x318
291 #define OC1_ALARM_COUNT 0x31c
292 #define OC1_FILTER 0x320
294 #define OC1_STATS 0x3a8
296 #define OC_INTR_STATUS 0x39c
297 #define OC_INTR_ENABLE 0x3a0
298 #define OC_INTR_DISABLE 0x3a4
299 #define OC_INTR_POS_OC1_SHIFT 0
300 #define OC_INTR_POS_OC1_MASK 0x1
301 #define OC_INTR_POS_OC2_SHIFT 1
302 #define OC_INTR_POS_OC2_MASK 0x1
303 #define OC_INTR_POS_OC3_SHIFT 2
304 #define OC_INTR_POS_OC3_MASK 0x1
305 #define OC_INTR_POS_OC4_SHIFT 3
306 #define OC_INTR_POS_OC4_MASK 0x1
307 #define OC_INTR_POS_OC5_SHIFT 4
308 #define OC_INTR_POS_OC5_MASK 0x1
310 #define OC_STATS_CTL 0x3c4
311 #define OC_STATS_CTL_CLR_ALL 0x2
312 #define OC_STATS_CTL_EN_ALL 0x1
314 #define CPU_PSKIP_STATUS 0x418
315 #define GPU_PSKIP_STATUS 0x41c
316 #define XPU_PSKIP_STATUS_M_SHIFT 12
317 #define XPU_PSKIP_STATUS_M_MASK 0xff
318 #define XPU_PSKIP_STATUS_N_SHIFT 4
319 #define XPU_PSKIP_STATUS_N_MASK 0xff
320 #define XPU_PSKIP_STATUS_SW_OVERRIDE_SHIFT 1
321 #define XPU_PSKIP_STATUS_SW_OVERRIDE_MASK 0x1
322 #define XPU_PSKIP_STATUS_ENABLED_SHIFT 0
323 #define XPU_PSKIP_STATUS_ENABLED_MASK 0x1
325 #define THROT_PRIORITY_LOCK 0x424
326 #define THROT_PRIORITY_LOCK_PRIORITY_SHIFT 0
327 #define THROT_PRIORITY_LOCK_PRIORITY_MASK 0xff
329 #define THROT_STATUS 0x428
330 #define THROT_STATUS_BREACH_SHIFT 12
331 #define THROT_STATUS_BREACH_MASK 0x1
332 #define THROT_STATUS_STATE_SHIFT 4
333 #define THROT_STATUS_STATE_MASK 0xff
334 #define THROT_STATUS_ENABLED_SHIFT 0
335 #define THROT_STATUS_ENABLED_MASK 0x1
337 #define THROT_PSKIP_CTRL_LITE_CPU 0x430
338 #define THROT13_PSKIP_CTRL_LOW_CPU 0x154
339 #define THROT_PSKIP_CTRL_ENABLE_SHIFT 31
340 #define THROT_PSKIP_CTRL_ENABLE_MASK 0x1
341 #define THROT_PSKIP_CTRL_VECT_GPU_SHIFT 16
342 #define THROT_PSKIP_CTRL_VECT_GPU_MASK 0x7
343 #define THROT_PSKIP_CTRL_VECT_CPU_SHIFT 8
344 #define THROT_PSKIP_CTRL_VECT_CPU_MASK 0x7
345 #define THROT_PSKIP_CTRL_DIVIDEND_SHIFT 8
346 #define THROT_PSKIP_CTRL_DIVIDEND_MASK 0xff
347 #define THROT_PSKIP_CTRL_DIVISOR_SHIFT 0
348 #define THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
349 #define THROT_PSKIP_CTRL_VECT2_CPU_SHIFT 0
350 #define THROT_PSKIP_CTRL_VECT2_CPU_MASK 0x7
352 #define THROT_PSKIP_RAMP_LITE_CPU 0x434
353 #define THROT13_PSKIP_RAMP_LOW_CPU 0x150
354 #define THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_SHIFT 31
355 #define THROT_PSKIP_RAMP_SEQ_BYPASS_MODE_MASK 0x1
356 #define THROT_PSKIP_RAMP_DURATION_SHIFT 8
357 #define THROT_PSKIP_RAMP_DURATION_MASK 0xffff
358 #define THROT_PSKIP_RAMP_STEP_SHIFT 0
359 #define THROT_PSKIP_RAMP_STEP_MASK 0xff
361 #define THROT_VECT_NONE 0x0 /* 3'b000 */
362 #define THROT_VECT_LOW 0x1 /* 3'b001 */
363 #define THROT_VECT_MED 0x3 /* 3'b011 */
364 #define THROT_VECT_HVY 0x7 /* 3'b111 */
366 #define THROT_LEVEL_LOW 0
367 #define THROT_LEVEL_MED 1
368 #define THROT_LEVEL_HVY 2
369 #define THROT_LEVEL_NONE -1 /* invalid */
371 #define THROT_PRIORITY_LITE 0x444
372 #define THROT_PRIORITY_LITE_PRIO_SHIFT 0
373 #define THROT_PRIORITY_LITE_PRIO_MASK 0xff
375 #define THROT_DELAY_LITE 0x448
376 #define THROT_DELAY_LITE_DELAY_SHIFT 0
377 #define THROT_DELAY_LITE_DELAY_MASK 0xff
379 #define THROT_OFFSET 0x30
380 #define THROT13_OFFSET 0x0c
381 #define ALARM_OFFSET 0x14
383 #define FUSE_TSENSOR_CALIB_FT_SHIFT 13
384 #define FUSE_TSENSOR_CALIB_FT_MASK 0x1fff
385 #define FUSE_TSENSOR_CALIB_CP_SHIFT 0
386 #define FUSE_TSENSOR_CALIB_CP_MASK 0x1fff
387 #define FUSE_TSENSOR_CALIB_BITS 13
389 /* car register offsets needed for enabling HW throttling */
390 #define CAR_SUPER_CCLKG_DIVIDER 0x36c
391 #define CAR13_SUPER_CCLKG_DIVIDER 0x024
392 #define CDIVG_ENABLE_SHIFT 31
393 #define CDIVG_ENABLE_MASK 0x1
394 #define CDIVG_USE_THERM_CONTROLS_SHIFT 30
395 #define CDIVG_USE_THERM_CONTROLS_MASK 0x1
396 #define CDIVG_DIVIDEND_MASK 0xff
397 #define CDIVG_DIVIDEND_SHIFT 8
398 #define CDIVG_DIVISOR_MASK 0xff
399 #define CDIVG_DIVISOR_SHIFT 0
401 #define CAR_SUPER_CLK_DIVIDER_REGISTER() (IS_T13X ? \
402 CAR13_SUPER_CCLKG_DIVIDER : \
403 CAR_SUPER_CCLKG_DIVIDER)
404 #define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \
405 (THROT_OFFSET * throt) + \
407 #define THROT_PSKIP_RAMP(throt, dev) (THROT_PSKIP_RAMP_LITE_CPU + \
408 (THROT_OFFSET * throt) + \
410 #define THROT13_PSKIP_CTRL_CPU(vect) (THROT13_PSKIP_CTRL_LOW_CPU + \
411 (THROT13_OFFSET * vect))
412 #define THROT13_PSKIP_RAMP_CPU(vect) (THROT13_PSKIP_RAMP_LOW_CPU + \
413 (THROT13_OFFSET * vect))
414 #define THROT_PRIORITY_CTRL(throt) (THROT_PRIORITY_LITE + \
415 (THROT_OFFSET * throt))
416 #define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \
417 (THROT_OFFSET * throt))
418 #define ALARM_CFG(throt) (OC1_CFG + \
419 (ALARM_OFFSET * (throt - \
421 #define ALARM_CNT_THRESHOLD(throt) (OC1_CNT_THRESHOLD + \
422 (ALARM_OFFSET * (throt - \
424 #define ALARM_THROTTLE_PERIOD(throt) (OC1_THROTTLE_PERIOD + \
425 (ALARM_OFFSET * (throt - \
427 #define ALARM_ALARM_COUNT(throt) (OC1_ALARM_COUNT + \
428 (ALARM_OFFSET * (throt - \
430 #define ALARM_FILTER(throt) (OC1_FILTER + \
431 (ALARM_OFFSET * (throt - \
433 #define ALARM_STATS(throt) (OC1_STATS + \
434 (4 * (throt - THROTTLE_OC1)))
436 #define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
437 #define THROT_DEPTH(th, dp) { \
438 (th)->depth = (dp); \
439 (th)->dividend = THROT_DEPTH_DIVIDEND(dp); \
440 (th)->divisor = 255; \
441 (th)->duration = 0xff; \
445 #define REG_SET(r, _name, val) (((r) & ~(_name##_MASK << _name##_SHIFT)) | \
446 (((val) & _name##_MASK) << _name##_SHIFT))
447 #define REG_GET_BIT(r, _name) ((r) & (_name##_MASK << _name##_SHIFT))
448 #define REG_GET(r, _name) (REG_GET_BIT(r, _name) >> _name##_SHIFT)
449 #define MAKE_SIGNED32(val, nb) ((s32)(val) << (32 - (nb)) >> (32 - (nb)))
451 #define IS_T11X (tegra_chip_id == TEGRA_CHIPID_TEGRA11)
452 #define IS_T14X (tegra_chip_id == TEGRA_CHIPID_TEGRA14)
453 #define IS_T12X (tegra_chip_id == TEGRA_CHIPID_TEGRA12)
454 #define IS_T13X (tegra_chip_id == TEGRA_CHIPID_TEGRA13)
456 static void __iomem *reg_soctherm_base = IOMEM(IO_ADDRESS(TEGRA_SOCTHERM_BASE));
457 static void __iomem *clk_reset_base = IOMEM(IO_ADDRESS(TEGRA_CLK_RESET_BASE));
458 static void __iomem *clk13_rst_base = IOMEM(IO_ADDRESS(TEGRA_CLK13_RESET_BASE));
460 static DEFINE_MUTEX(soctherm_suspend_resume_lock);
462 static int soctherm_suspend(void);
463 static int soctherm_resume(void);
465 static struct soctherm_platform_data plat_data;
468 * Remove this flag once this "driver" is structured as a platform driver and
469 * the board files calls platform_device_register instead of directly calling
470 * tegra11_soctherm_init(). See nvbug 1206311.
472 static bool soctherm_init_platform_done;
473 static bool read_hw_temp = true;
474 static bool soctherm_suspended;
475 static bool vdd_cpu_low_voltage;
476 static bool vdd_core_low_voltage;
477 static u32 tegra_chip_id;
479 static struct clk *soctherm_clk;
480 static struct clk *tsensor_clk;
483 * soctherm_writel() - Writes a value to a SOC_THERM register
484 * @value: The value to write
485 * @reg: The register offset
487 * Writes the @value to @reg if the soctherm device is not suspended.
489 static inline void soctherm_writel(u32 value, u32 reg)
491 if (!soctherm_suspended)
492 __raw_writel(value, (void __iomem *)
493 (reg_soctherm_base + reg));
497 * soctherm_readl() - reads specified register from SOC_THERM IP block
498 * @reg: register address to be read
500 * Return: 0 if SOC_THERM is suspended, else the value of the register
502 static inline u32 soctherm_readl(u32 reg)
504 if (soctherm_suspended)
506 return __raw_readl(reg_soctherm_base + reg);
509 /* XXX Temporary until CCROC accesses are split out */
510 static void clk_reset13_writel(u32 value, u32 reg)
513 __raw_writel(value, clk13_rst_base + reg);
514 __raw_readl(clk13_rst_base + reg);
517 /* XXX Temporary until CCROC accesses are split out */
518 static u32 clk_reset13_readl(u32 reg)
521 return __raw_readl(clk13_rst_base + reg);
524 static inline void clk_reset_writel(u32 value, u32 reg)
527 __raw_writel(value, clk13_rst_base + reg);
528 __raw_readl(clk13_rst_base + reg);
530 __raw_writel(value, clk_reset_base + reg);
533 static inline u32 clk_reset_readl(u32 reg)
536 return __raw_readl(clk13_rst_base + reg);
538 return __raw_readl(clk_reset_base + reg);
542 * temp_convert() - convert raw sensor readings to temperature
543 * @cap: raw TSOSC count
544 * @a: slope of count/temperature linear regression
545 * @b: x-intercept of count/temperature linear regression
547 * This is a software version of what happens in the hardware when
548 * temp_translate() is called. However, when the hardware does the conversion,
549 * it cannot do it with the same precision that can be done with software.
551 * This function is not in use as long as @read_hw_temp is set to true, however
552 * software temperature conversion could be used to monitor temperatures with a
553 * higher degree of precision as they near a temperature threshold.
555 * Return: temperature in millicelsius.
557 static inline long temp_convert(int cap, int a, int b)
562 cap *= LOWER_PRECISION_FOR_CONV(500);
568 * temp_translate_rev() - Translates the given temperature from two's
569 * complement to the signed magnitude form used in SOC_THERM registers
570 * @temp: The temperature to be translated
572 * The register value returned will have the following bit assignment:
573 * 15:7 magnitude of temperature in (1/2 or 1 degree precision) centigrade
574 * 0 the sign bit of the temperature
576 * This function is the inverse of the temp_translate() function
578 * Return: The register value.
580 static inline u32 temp_translate_rev(long temp)
588 sign = (temp > 0 ? 1 : -1);
589 low_bit = (sign > 0 ? 0 : 1);
591 /* high precision only */
592 if (!PRECISION_IS_LOWER()) {
593 lsb = ((temp % 1000) > 0) ? 1 : 0;
594 abs = (temp - 500 * lsb) / 1000;
596 reg = ((abs << 8) | (lsb << 7) | low_bit);
601 #ifdef CONFIG_THERMAL
602 static struct thermal_zone_device *soctherm_th_zones[THERM_SIZE];
604 struct soctherm_oc_irq_chip_data {
606 struct mutex irq_lock; /* serialize OC IRQs */
607 struct irq_chip irq_chip;
608 struct irq_domain *domain;
611 static struct soctherm_oc_irq_chip_data soc_irq_cdata;
613 static u32 fuse_calib_base_cp;
614 static u32 fuse_calib_base_ft;
615 static s32 actual_temp_cp;
616 static s32 actual_temp_ft;
618 static const char *const therm_names[] = {
625 static const char *const throt_names[] = {
626 [THROTTLE_LIGHT] = "light",
627 [THROTTLE_HEAVY] = "heavy",
628 [THROTTLE_OC1] = "oc1",
629 [THROTTLE_OC2] = "oc2",
630 [THROTTLE_OC3] = "oc3",
631 [THROTTLE_OC4] = "oc4",
632 [THROTTLE_OC5] = "oc5", /* reserved */
635 static const char *const throt_dev_names[] = {
636 [THROTTLE_DEV_CPU] = "CPU",
637 [THROTTLE_DEV_GPU] = "GPU",
640 static const char *const sensor_names[] = {
641 [TSENSE_CPU0] = "cpu0",
642 [TSENSE_CPU1] = "cpu1",
643 [TSENSE_CPU2] = "cpu2",
644 [TSENSE_CPU3] = "cpu3",
645 [TSENSE_MEM0] = "mem0",
646 [TSENSE_MEM1] = "mem1",
647 [TSENSE_GPU] = "gpu0",
648 [TSENSE_PLLX] = "pllx",
651 static const int sensor2tsensorcalib[] = {
662 static const int tsensor2therm_map[] = {
663 [TSENSE_CPU0] = THERM_CPU,
664 [TSENSE_CPU1] = THERM_CPU,
665 [TSENSE_CPU2] = THERM_CPU,
666 [TSENSE_CPU3] = THERM_CPU,
667 [TSENSE_GPU] = THERM_GPU,
668 [TSENSE_MEM0] = THERM_MEM,
669 [TSENSE_MEM1] = THERM_MEM,
670 [TSENSE_PLLX] = THERM_PLL,
673 static const enum soctherm_throttle_dev_id therm2dev[] = {
674 [THERM_CPU] = THROTTLE_DEV_CPU,
675 [THERM_MEM] = THROTTLE_DEV_NONE,
676 [THERM_GPU] = THROTTLE_DEV_GPU,
677 [THERM_PLL] = THROTTLE_DEV_NONE,
680 static const struct soctherm_sensor default_t11x_sensor_params = {
689 static const struct soctherm_sensor default_t14x_sensor_params = {
699 /* Used for T124 and T132 */
700 static const struct soctherm_sensor default_t12x_sensor_params = {
710 static const unsigned long default_t11x_soctherm_clk_rate = 51000000;
711 static const unsigned long default_t11x_tsensor_clk_rate = 500000;
712 static const unsigned long default_t14x_soctherm_clk_rate = 51000000;
713 static const unsigned long default_t14x_tsensor_clk_rate = 400000;
714 /* TODO : finalize the default clk rate */
715 static const unsigned long default_t12x_soctherm_clk_rate = 51000000;
716 static const unsigned long default_t12x_tsensor_clk_rate = 400000;
718 /* SOC- OCx to theirt GPIO which is wakeup capable. This is T114 specific */
719 static int soctherm_ocx_to_wake_gpio[TEGRA_SOC_OC_IRQ_MAX] = {
720 TEGRA_GPIO_PEE3, /* TEGRA_SOC_OC_IRQ_1 */
721 TEGRA_GPIO_INVALID, /* TEGRA_SOC_OC_IRQ_2 */
722 TEGRA_GPIO_INVALID, /* TEGRA_SOC_OC_IRQ_3 */
723 TEGRA_GPIO_PJ2, /* TEGRA_SOC_OC_IRQ_4 */
724 TEGRA_GPIO_INVALID, /* TEGRA_SOC_OC_IRQ_5 */
727 static int sensor2therm_a[TSENSE_SIZE];
728 static int sensor2therm_b[TSENSE_SIZE];
731 * div64_s64_precise() - wrapper for div64_s64()
735 * Implements division with fairly accurate rounding instead of truncation by
736 * shifting the dividend to the left by 16 so that the quotient has a
737 * much higher precision.
739 * Return: the quotient of a / b.
742 static inline s64 div64_s64_precise(s64 a, s32 b)
746 /* scale up for increased precision in division */
749 r = div64_s64((al * 2) + 1, 2 * b);
754 * temp_translate() - Converts temperature
755 * @readback: The value from a SOC_THERM sensor temperature
758 * Converts temperature from the format used in registers to a (signed)
759 * long. This function is the inverse of temp_translate_rev().
761 * Return: the translated temperature in millicelsius
763 static inline long temp_translate(int readback)
765 int abs = readback >> 8;
766 int lsb = (readback & 0x80) >> 7;
767 int sign = readback & 0x01 ? -1 : 1;
769 return (abs * LOWER_PRECISION_FOR_CONV(1000) +
770 lsb * LOWER_PRECISION_FOR_CONV(500)) * sign;
773 #ifdef CONFIG_THERMAL
776 * soctherm_has_mn_cpu_pskip_status() - does CPU use M,N values for pskip status?
778 * If the currently-running SoC reports the CPU thermal throttling
779 * pulse skipper status with (M, N) values via SOC_THERM registers,
780 * then return true; otherwise, return false. XXX Temporary - should
781 * be replaced by autodetection or DT properties/compatible flags.
783 * Return: true if CPU thermal pulse-skipper M,N status values are available via
784 * SOC_THERM, or false if not.
786 static int soctherm_has_mn_cpu_pskip_status(void)
788 return IS_T11X || IS_T14X || IS_T12X;
792 * soctherm_get_mn_cpu_pskip_status() - read state of CPU thermal pulse skipper
793 * @enabled: pointer to a u8: return 0 if the skipper is disabled, 1 if enabled
794 * @sw_override: ptr to a u8: return 0 if sw override is disabled, 1 if enabled
795 * @m: pointer to a u16 to return the current pulse skipper ratio numerator into
796 * @n: pointer to a u16 to return the current pulse skipper ratio denominator to
798 * Read the current status of the thermal throttling pulse skipper
799 * attached to the CPU clock, and return the status into the variables
800 * pointed to by @enabled, @sw_override, @m, and @n. The M and N
801 * values are not what is stored in the register bitfields, but
802 * instead are the actual values used by the pulse skipper -- i.e.,
803 * they are the bitfield values _plus one_; they have valid ranges of
804 * 1-256. This function is only defined for chips that report M,N
805 * thermal throttling states
807 * Return: 0 upon success, -ENOTSUPP if called on a chip that uses
808 * CPU-local (i.e., non-SOC_THERM) pulse-skipper status, or -EINVAL if
809 * any of the arguments are NULL.
811 int soctherm_get_mn_cpu_pskip_status(u8 *enabled, u8 *sw_override, u16 *m,
816 if (!enabled || !m || !n || !sw_override)
820 * XXX should be replaced with an earlier DT property read to
821 * determine the GPU type (or GPU->SOC_THERM integration) in
824 if (!soctherm_has_mn_cpu_pskip_status())
827 v = soctherm_readl(CPU_PSKIP_STATUS);
828 if (REG_GET(v, XPU_PSKIP_STATUS_ENABLED)) {
830 *sw_override = REG_GET(v, XPU_PSKIP_STATUS_SW_OVERRIDE);
831 *m = REG_GET(v, XPU_PSKIP_STATUS_M) + 1;
832 *n = REG_GET(v, XPU_PSKIP_STATUS_N) + 1;
841 * soctherm_has_gpu_pskip_status() - is GPU pskip state readable via SOC_THERM?
843 * If the currently-running SoC reports the GPU thermal throttling
844 * pulse skipper status via SOC_THERM registers, then return true;
845 * otherwise, return false. XXX Temporary - should be replaced by
846 * autodetection or DT properties/compatible flags.
848 * Return: true if GPU thermal pulse-skipper status is readable via
849 * SOC_THERM, or false if not.
851 static int soctherm_has_gpu_pskip_status(void)
853 return IS_T11X || IS_T14X;
857 * soctherm_get_gpu_pskip_status() - read state of the GPU thermal pulse skipper
858 * @enabled: pointer to a u8: return 0 if the skipper is disabled, 1 if enabled
859 * @sw_override: ptr to a u8: return 0 if sw override is disabled, 1 if enabled
860 * @m: pointer to a u8 to return the current pulse skipper ratio numerator into
861 * @n: pointer to a u8 to return the current pulse skipper ratio denominator to
863 * Read the current status of the thermal throttling pulse skipper
864 * attached to the GPU clock, and return the status into the variables
865 * pointed to by @enabled, @sw_override, @m, and @n. Note that the M
866 * and N values are not what is stored in the register bitfields, but
867 * instead are the actual values used by the pulse skipper -- i.e., they
868 * are the bitfield values _plus one_; they have valid ranges of 1-256.
870 * Return: 0 upon success, -ENOTSUPP on chips with GPU-local
871 * throttling status (e.g., T124, T132) or -EINVAL if any of the
872 * arguments are NULL.
874 int soctherm_get_gpu_pskip_status(u8 *enabled, u8 *sw_override, u16 *m, u16 *n)
878 if (!enabled || !m || !n || !sw_override)
882 * XXX should be replaced with an earlier DT property read to
883 * determine the GPU type (or GPU->SOC_THERM integration) in
886 if (!soctherm_has_gpu_pskip_status())
889 v = soctherm_readl(GPU_PSKIP_STATUS);
890 if (REG_GET(v, XPU_PSKIP_STATUS_ENABLED)) {
892 *sw_override = REG_GET(v, XPU_PSKIP_STATUS_SW_OVERRIDE);
893 *m = REG_GET(v, XPU_PSKIP_STATUS_M) + 1;
894 *n = REG_GET(v, XPU_PSKIP_STATUS_N) + 1;
903 * enforce_temp_range() - check and enforce temperature range [min, max]
904 * @trip_temp: The trip temperature to check
906 * Checks and enforces the permitted temperature range that SOC_THERM
907 * HW can support with 8-bit registers to specify temperature. This is
908 * done while taking care of precision.
910 * Return: The precsion adjusted capped temperature in millicelsius.
912 static int enforce_temp_range(long trip_temp)
914 long temp = LOWER_PRECISION_FOR_TEMP(trip_temp);
916 if (temp < MIN_LOW_TEMP) {
917 pr_info("soctherm: trip_point temp %ld forced to %d\n",
918 trip_temp, LOWER_PRECISION_FOR_CONV(MIN_LOW_TEMP));
920 } else if (temp > MAX_HIGH_TEMP) {
921 pr_info("soctherm: trip_point temp %ld forced to %d\n",
922 trip_temp, LOWER_PRECISION_FOR_CONV(MAX_HIGH_TEMP));
923 temp = MAX_HIGH_TEMP;
930 * prog_hw_shutdown() - Configures the hardware to shut down the
931 * system if a given sensor group reaches a given temperature
932 * @trip_state: The trip information. Includes the temperature
933 * at which a trip occurs.
934 * @therm: Int specifying the sensor group.
935 * Should be one of the following:
936 * THERM_CPU, THERM_GPU,
937 * THERM_MEM, or THERM_PPL.
939 * Sets the thermal trip threshold of the given sensor group
940 * to be the trip temperature of @trip_state.
941 * If this threshold is crossed, the hardware will shut down.
943 * Return: No return value (void).
945 static inline void prog_hw_shutdown(struct thermal_trip_info *trip_state,
951 /* Add 1'C to HW shutdown threshold so SW can try to shutdown first */
952 temp = trip_state->trip_temp + LOWER_PRECISION_FOR_CONV(1000);
954 temp = enforce_temp_range(temp) / 1000;
956 r = soctherm_readl(THERMTRIP);
957 if (therm == THERM_CPU) {
958 r = REG_SET(r, THERMTRIP_CPU_EN, 1);
959 r = REG_SET(r, THERMTRIP_CPU_THRESH, temp);
960 } else if (therm == THERM_GPU) {
961 r = REG_SET(r, THERMTRIP_GPU_EN, 1);
962 r = REG_SET(r, THERMTRIP_GPUMEM_THRESH, temp);
963 } else if (therm == THERM_PLL) {
964 r = REG_SET(r, THERMTRIP_TSENSE_EN, 1);
965 r = REG_SET(r, THERMTRIP_TSENSE_THRESH, temp);
966 } else if (therm == THERM_MEM) {
967 r = REG_SET(r, THERMTRIP_MEM_EN, 1);
968 r = REG_SET(r, THERMTRIP_GPUMEM_THRESH, temp);
970 r = REG_SET(r, THERMTRIP_ANY_EN, 0);
971 soctherm_writel(r, THERMTRIP);
975 * prog_hw_threshold() - updates hardware temperature threshold
976 * of a particular trip point
977 * @trip_state: setting of a trip point to use to update hardware threshold
978 * @therm: soctherm_therm_id specifying the sensor group to update
979 * @throt: soctherm_throttle_id indicating throttling level to update
981 * Configure sensor group @therm to engage a hardware throttling response at
982 * the threshold indicated by @trip_state.
984 * Checks to see if HW config register needs reprogramming:
986 * There's an intentional side-effect of writing trip temperature thresholds
987 * in HW; It resets the up/down state machine that track hysteresis and can
988 * cause unnecessary thermal events (interrupts).
990 * Avoid unnecessary events by checking if the trip config register is
991 * being configured to the same settings and skipping the write.
993 static inline void prog_hw_threshold(struct thermal_trip_info *trip_state,
994 int therm, int throt)
999 int cpu_throt, gpu_throt;
1001 temp = enforce_temp_range(trip_state->trip_temp) / 1000;
1003 /* Hardcode LITE on level-1 and HEAVY on level-2 */
1004 reg_off = TS_THERM_REG_OFFSET(CTL_LVL0_CPU0, throt + 1, therm);
1006 if (throt == THROTTLE_LIGHT) {
1007 cpu_throt = CTL_LVL0_CPU0_CPU_THROT_LIGHT;
1008 gpu_throt = CTL_LVL0_CPU0_GPU_THROT_LIGHT;
1010 cpu_throt = CTL_LVL0_CPU0_CPU_THROT_HEAVY;
1011 gpu_throt = CTL_LVL0_CPU0_GPU_THROT_HEAVY;
1012 if (throt != THROTTLE_HEAVY)
1013 pr_warn("soctherm: invalid throt %d - assuming HEAVY",
1017 r = soctherm_readl(reg_off);
1018 reprogram = ((REG_GET(r, CTL_LVL0_CPU0_DN_THRESH) != temp) ||
1019 (REG_GET(r, CTL_LVL0_CPU0_UP_THRESH) != temp) ||
1020 (REG_GET(r, CTL_LVL0_CPU0_CPU_THROT) != cpu_throt) ||
1021 (REG_GET(r, CTL_LVL0_CPU0_GPU_THROT) != gpu_throt) ||
1022 (REG_GET(r, CTL_LVL0_CPU0_EN) != 1));
1025 r = REG_SET(r, CTL_LVL0_CPU0_UP_THRESH, temp);
1026 r = REG_SET(r, CTL_LVL0_CPU0_DN_THRESH, temp);
1027 r = REG_SET(r, CTL_LVL0_CPU0_CPU_THROT, cpu_throt);
1028 r = REG_SET(r, CTL_LVL0_CPU0_GPU_THROT, gpu_throt);
1029 r = REG_SET(r, CTL_LVL0_CPU0_EN, 1);
1030 soctherm_writel(r, reg_off);
1035 * soctherm_set_limits() - Configures a sensor group to raise interrupts outside
1036 * the given temperature range
1037 * @therm: ID of the sensor group
1038 * @lo_limit: The lowest temperature limit
1039 * @hi_limit: The highest temperature limit
1041 * Configures sensor group @therm to raise an interrupt when temperature goes
1042 * above @hi_limit or below @lo_limit.
1044 * Checks to see if HW config register needs reprogramming. See comment in
1045 * prog_hw_threshold().
1047 static void soctherm_set_limits(enum soctherm_therm_id therm,
1048 long lo_limit, long hi_limit)
1051 int rlo_limit, rhi_limit;
1054 rlo_limit = LOWER_PRECISION_FOR_TEMP(lo_limit) / 1000;
1055 rhi_limit = LOWER_PRECISION_FOR_TEMP(hi_limit) / 1000;
1057 reg_off = TS_THERM_REG_OFFSET(CTL_LVL0_CPU0, 0, therm);
1058 r = soctherm_readl(reg_off);
1060 reprogram = ((REG_GET(r, CTL_LVL0_CPU0_DN_THRESH) != rlo_limit) ||
1061 (REG_GET(r, CTL_LVL0_CPU0_UP_THRESH) != rhi_limit) ||
1062 (REG_GET(r, CTL_LVL0_CPU0_EN) != 1));
1065 r = REG_SET(r, CTL_LVL0_CPU0_DN_THRESH, rlo_limit);
1066 r = REG_SET(r, CTL_LVL0_CPU0_UP_THRESH, rhi_limit);
1067 r = REG_SET(r, CTL_LVL0_CPU0_EN, 1);
1068 soctherm_writel(r, reg_off);
1073 r = REG_SET(0, TH_INTR_POS_CD0, 1);
1074 r = REG_SET(r, TH_INTR_POS_CU0, 1);
1077 r = REG_SET(0, TH_INTR_POS_GD0, 1);
1078 r = REG_SET(r, TH_INTR_POS_GU0, 1);
1081 r = REG_SET(0, TH_INTR_POS_PD0, 1);
1082 r = REG_SET(r, TH_INTR_POS_PU0, 1);
1085 r = REG_SET(0, TH_INTR_POS_MD0, 1);
1086 r = REG_SET(r, TH_INTR_POS_MU0, 1);
1092 soctherm_writel(r, TH_INTR_ENABLE);
1096 * soctherm_update_zone() - Updates the given zone.
1097 * @zn: The number of the zone to be updated.
1098 * This number correlates to one of the following:
1099 * CPU, GPU, MEM, or PLL.
1101 * Based on current temperature and the trip points associated with
1102 * this zone, update the temperature thresholds at which hardware will
1103 * generate interrupts.
1105 * Return: Nothing is returned (void).
1107 static void soctherm_update_zone(int zn)
1109 long low_temp = 0, high_temp = MAX_HIGH_TEMP;
1110 long trip_temp, passive_low_temp = MAX_HIGH_TEMP, zone_temp;
1111 enum thermal_trip_type trip_type;
1112 struct thermal_trip_info *trip_state;
1113 struct thermal_zone_device *cur_thz = soctherm_th_zones[zn];
1116 thermal_zone_device_update(cur_thz);
1118 trips = cur_thz->trips;
1119 for (count = 0; count < trips; count++) {
1120 cur_thz->ops->get_trip_type(cur_thz, count, &trip_type);
1121 if (trip_type == THERMAL_TRIP_HOT)
1122 continue; /* handled in HW */
1124 cur_thz->ops->get_trip_temp(cur_thz, count, &trip_temp);
1126 trip_state = &plat_data.therm[zn].trips[count];
1127 zone_temp = cur_thz->temperature;
1129 if (!trip_state->tripped) { /* not tripped? update high */
1130 if (trip_temp < high_temp)
1131 high_temp = trip_temp;
1132 } else { /* tripped? update low */
1133 if (trip_type != THERMAL_TRIP_PASSIVE) {
1134 /* get highest ACTIVE and CRITICAL*/
1135 if (trip_temp > low_temp)
1136 low_temp = trip_temp;
1138 /* get lowest PASSIVE */
1139 if (trip_temp < passive_low_temp)
1140 passive_low_temp = trip_temp;
1145 if (passive_low_temp != MAX_HIGH_TEMP)
1146 low_temp = max(low_temp, passive_low_temp);
1148 soctherm_set_limits(zn, low_temp, high_temp);
1152 * soctherm_update() - updates all thermal zones
1154 * Will not run if the board-specific data has not been initialized. Loops
1155 * through all of the thermal zones and makes sure that their high and low
1156 * temperature limits are updated.
1158 static void soctherm_update(void)
1162 if (!soctherm_init_platform_done)
1165 for (i = 0; i < THERM_SIZE; i++) {
1166 if (soctherm_th_zones[i] && soctherm_th_zones[i]->trips)
1167 soctherm_update_zone(i);
1172 * soctherm_hw_action_get_max_state() - gets the max state for cooling
1173 * devices associated with hardware throttling
1174 * @cdev: cooling device to get the state
1175 * @max_state: pointer where the maximum state will be written to
1177 * Sets @max_state = 3. See soctherm_hw_action_get_cur_state.
1181 static int soctherm_hw_action_get_max_state(struct thermal_cooling_device *cdev,
1182 unsigned long *max_state)
1184 struct thermal_trip_info *trip_state = cdev->devdata;
1189 *max_state = 3; /* bit 1: CPU bit 2: GPU */
1194 * soctherm_get_cpu_throt_state - read the current state of the CPU pulse skipper
1195 * @dividend: pulse skipper numerator value to test against (1-256)
1196 * @divisor: pulse skipper denominator value to test against (1-256)
1197 * @cur_state: ptr to the variable that the current throttle state is stored in
1199 * Determine the current state of the CPU thermal throttling pulse
1200 * skipper, and if it's enabled and at its configured ending state,
1201 * set the appropriate 'enabled' bit in the variable pointed to by
1202 * @cur_state. This works on T114, T124, and T148 by comparing
1203 * @dividend and @divisor with the current state of the hardware -
1204 * though note that @dividend and @divisor must be the actual dividend
1205 * and divisor values. That is, they must be in 1-256 range, not the
1206 * 0-255 range used by the hardware bitfields.
1208 * FIXME: For T132 switch to Denver:CCROC NV_THERM style status. Does
1209 * not currently work on T132.
1211 * Return: 0 upon success, -ENOTSUPP on T12x and T13x, or -EINVAL if
1212 * the arguments are invalid or out of range.
1215 static int soctherm_get_cpu_throt_state(u16 dividend, u16 divisor,
1216 unsigned long *cur_state)
1219 u8 enabled, sw_override;
1221 if (!cur_state || dividend == 0 || divisor == 0 ||
1222 dividend > 256 || divisor > 256)
1225 if (soctherm_has_mn_cpu_pskip_status()) {
1226 soctherm_get_mn_cpu_pskip_status(&enabled, &sw_override, &m, &n);
1228 if (enabled && m == dividend && n == divisor)
1229 *cur_state |= (1 << THROTTLE_DEV_CPU);
1231 pr_warn_once("CPU throttling status not yet available on this SoC\n");
1239 * soctherm_get_gpu_throt_state - read the current state of the GPU pulse skipper
1240 * @dividend: pulse skipper numerator value to test against (1-256)
1241 * @divisor: pulse skipper denominator value to test against (1-256)
1242 * @cur_state: ptr to the variable that the current throttle state is stored in
1244 * Determine the current state of the GPU thermal throttling pulse
1245 * skipper, and if it's enabled and at its configured ending state,
1246 * set the appropriate 'enabled' bit in the variable pointed to by
1247 * @cur_state. This works on T114 and T148 by comparing @dividend and
1248 * @divisor with the current state of the hardware - though note that
1249 * @dividend and @divisor must be the actual dividend and divisor
1250 * values. That is, they must be in 1-256 range, not the 0-255 range used
1251 * by the hardware bitfields.
1253 * Unfortunately, on T12x and T13x, the GPU manages its own thermal
1254 * throttling, and does not report its state to the SOC_THERM IP
1255 * block. So on those chips, this function will return an error.
1257 * Return: 0 upon success, -ENOTSUPP on T12x and T13x, or -EINVAL if
1258 * the arguments are invalid or out of range.
1260 static int soctherm_get_gpu_throt_state(u16 dividend, u16 divisor,
1261 unsigned long *cur_state)
1264 u8 enabled, sw_override;
1267 if (!cur_state || dividend == 0 || divisor == 0 ||
1268 dividend > 256 || divisor > 256)
1272 * XXX should be replaced with an earlier DT property read to
1273 * determine the GPU type (or GPU->SOC_THERM integration) in
1276 if (!soctherm_has_gpu_pskip_status())
1279 r = soctherm_get_gpu_pskip_status(&enabled, &sw_override, &m, &n);
1288 *cur_state |= (m == dividend && n == divisor) ?
1289 (1 << THROTTLE_DEV_GPU) : 0;
1295 * soctherm_hw_action_get_cur_state() - get the current CPU/GPU throttling state
1296 * @cdev: ptr to the struct thermal_cooling_device associated with SOC_THERM
1297 * @cur_state: ptr to a variable to return the throttling state into
1299 * Query the current state of the SOC_THERM cooling device represented
1300 * by @cdev, and return its current state into the variable pointed to
1301 * by @cur_state. Intended to be used as a thermal framework callback
1306 static int soctherm_hw_action_get_cur_state(struct thermal_cooling_device *cdev,
1307 unsigned long *cur_state)
1309 struct thermal_trip_info *trip_state = cdev->devdata;
1310 struct soctherm_throttle_dev *devs;
1317 if (trip_state->trip_type != THERMAL_TRIP_HOT)
1320 for (i = THROTTLE_LIGHT; i <= THROTTLE_HEAVY; i++) {
1321 if (!strnstr(trip_state->cdev_type, throt_names[i],
1322 THERMAL_NAME_LENGTH))
1325 devs = &plat_data.throttle[i].devs[THROTTLE_DEV_CPU];
1327 soctherm_get_cpu_throt_state(devs->dividend + 1,
1331 devs = &plat_data.throttle[i].devs[THROTTLE_DEV_GPU];
1333 r = soctherm_get_gpu_throt_state(devs->dividend + 1,
1337 * On some chips, the GPU thermal throttling
1338 * status isn't reported back to the SOC_THERM
1339 * hardware. The ideal situation is for the
1340 * GPU driver to register its own cooling
1341 * device in that case; however, that code
1342 * isn't implemented AFAIK. On those chips,
1343 * Diwakar's preferred approach is for the GPU
1344 * throttling status bit to follow the CPU
1345 * throttling status bit, since that's the
1346 * vendor- recommended thermal configuration.
1347 * Diwakar notes: On Tegra12x OC5 is a
1348 * reserved alarm. Hence GPU 'PSKIP' state
1349 * always shows ON. The real status register
1350 * 'NV_THERM_CLK_STATUS' can't be read safely
1351 * [from this code - pjw]. So we mirror the
1355 if (*cur_state & (1 << THROTTLE_DEV_CPU))
1356 *cur_state |= (1 << THROTTLE_DEV_GPU);
1364 static int soctherm_hw_action_set_cur_state(struct thermal_cooling_device *cdev,
1365 unsigned long cur_state)
1367 return 0; /* hw sets this state */
1370 static struct thermal_cooling_device *soctherm_hw_critical_cdev;
1371 static struct thermal_cooling_device *soctherm_hw_heavy_cdev;
1372 static struct thermal_cooling_device *soctherm_hw_light_cdev;
1373 static struct thermal_cooling_device_ops soctherm_hw_action_ops = {
1374 .get_max_state = soctherm_hw_action_get_max_state,
1375 .get_cur_state = soctherm_hw_action_get_cur_state,
1376 .set_cur_state = soctherm_hw_action_set_cur_state,
1379 static int soctherm_suspend_get_max_state(struct thermal_cooling_device *cdev,
1380 unsigned long *max_state)
1386 static int soctherm_suspend_get_cur_state(struct thermal_cooling_device *cdev,
1387 unsigned long *cur_state)
1389 *cur_state = !soctherm_suspended;
1394 * soctherm_suspend_set_cur_state() - Resumes or suspends soctherm
1395 * @cdev: Thermal cooling device. Currently not being used.
1396 * @cur_state: The current state
1398 * Ensures that the SOC_THERM device is suspended or resumed to match
1399 * @cur_state. This function is passed to the thermal framework as part of a
1400 * cooling device. This is a workaround to suspend the SOC_THERM IP block, which
1401 * is only needed because this is not yet a device driver. Once this code is
1402 * converted to be a device driver, the soctherm_suspend implementation can
1404 * Return: 0 (success).
1406 static int soctherm_suspend_set_cur_state(struct thermal_cooling_device *cdev,
1407 unsigned long cur_state)
1409 if (!cur_state != soctherm_suspended) {
1418 static struct thermal_cooling_device_ops soctherm_suspend_ops = {
1419 .get_max_state = soctherm_suspend_get_max_state,
1420 .get_cur_state = soctherm_suspend_get_cur_state,
1421 .set_cur_state = soctherm_suspend_set_cur_state,
1425 * soctherm_bind() - Binds the given thermal zone's trip
1426 * points with the given cooling device.
1427 * @thz: The thermal zone device to be bound
1428 * @cdev: The cooling device to be bound
1430 * If thermal sensor calibration data is missing from fuses,
1431 * the cooling devices are not bound.
1433 * Based on platform-specific configuration associated with this
1434 * thermal zone, soctherm_bind() binds this cooling device to this
1435 * thermal zone at various trip points.
1437 * soctherm_bind is called as a thermal_zone_device_ops bind function.
1439 * Return: Returns 0 on successful binding. Returns 0 if passed an
1440 * invalid thermal zone argument, or improperly fused soctherm.
1441 * In the latter two cases, binding of the cooling device does not
1444 static int soctherm_bind(struct thermal_zone_device *thz,
1445 struct thermal_cooling_device *cdev)
1448 struct soctherm_therm *therm = thz->devdata;
1449 struct thermal_trip_info *trip_state;
1451 /* skip binding cooling devices on improperly fused soctherm */
1452 if (tegra_fuse_calib_base_get_cp(NULL, NULL) < 0 ||
1453 tegra_fuse_calib_base_get_ft(NULL, NULL) < 0)
1456 for (i = 0; i < therm->num_trips; i++) {
1457 trip_state = &therm->trips[i];
1458 if (trip_state->cdev_type &&
1459 !strncmp(trip_state->cdev_type, cdev->type,
1460 THERMAL_NAME_LENGTH)) {
1461 thermal_zone_bind_cooling_device(thz, i, cdev,
1464 trip_state->bound = true;
1472 * soctherm_unbind() - unbinds cooling device from a thermal zone.
1473 * @thz: thermal zone to be dissociated with a cooling device
1474 * @cdev: a cooling device to be dissociated with a thermal zone
1476 * Dissociates a given cooling device from a given thermal zone.
1477 * This function will go through every trip point and dissociate
1478 * cooling device from the thermal zone.
1482 static int soctherm_unbind(struct thermal_zone_device *thz,
1483 struct thermal_cooling_device *cdev)
1486 struct soctherm_therm *therm = thz->devdata;
1487 struct thermal_trip_info *trip_state;
1489 for (i = 0; i < therm->num_trips; i++) {
1490 trip_state = &therm->trips[i];
1491 if (!trip_state->bound)
1493 if (trip_state->cdev_type &&
1494 !strncmp(trip_state->cdev_type, cdev->type,
1495 THERMAL_NAME_LENGTH)) {
1496 thermal_zone_unbind_cooling_device(thz, 0, cdev);
1497 trip_state->bound = false;
1505 * soctherm_get_temp() - gets the temperature for the given thermal zone
1506 * @thz: the thermal zone from which to get the temperature
1507 * @temp: a pointer to where the temperature will be stored
1509 * Reads the sensor associated with the given thermal zone, converts the
1510 * reading to millicelcius, and places it into temp. This function is passed
1511 * to the thermal framework as a callback function when the zone is created and
1516 static int soctherm_get_temp(struct thermal_zone_device *thz, long *temp)
1518 struct soctherm_therm *therm = thz->devdata;
1519 ptrdiff_t index = therm - plat_data.therm;
1520 u32 r, regv, shft, mask;
1521 enum soctherm_sense i, j;
1527 shft = TS_TEMP1_CPU_TEMP_SHIFT;
1528 mask = TS_TEMP1_CPU_TEMP_MASK;
1535 shft = TS_TEMP1_GPU_TEMP_SHIFT;
1536 mask = TS_TEMP1_GPU_TEMP_MASK;
1543 shft = TS_TEMP2_MEM_TEMP_SHIFT;
1544 mask = TS_TEMP2_MEM_TEMP_MASK;
1550 default: /* if devdata has error, return PLL temp to be safe */
1552 shft = TS_TEMP2_PLLX_TEMP_SHIFT;
1553 mask = TS_TEMP2_PLLX_TEMP_MASK;
1560 r = soctherm_readl(regv);
1561 *temp = temp_translate((r & (mask << shft)) >> shft);
1563 for (tt = 0; i <= j; i++) {
1564 r = soctherm_readl(TS_TSENSE_REG_OFFSET(
1565 TS_CPU0_STATUS0, i));
1566 ti = temp_convert(REG_GET(r, TS_CPU0_STATUS0_CAPTURE),
1569 *temp = tt = max(tt, ti);
1576 * soctherm_get_trip_type() - Gets the type of a given trip point
1577 * for a given thermal zone device.
1578 * @thz: The thermal zone device
1579 * @trip: The trip point index.
1580 * @type: The trip type.
1582 * The trip type will be one of the following values:
1583 * THERMAL_TRIP_ACTIVE, THERMAL_TRIP_PASSIVE, THERMAL_TRIP_HOT,
1584 * THERMAL_TRIP_CRITICAL
1586 * This function is passed to the thermal framework as a callback
1587 * for each of the SOC_THERM-related thermal zones
1589 * Return: Returns 0 on success, -EINVAL when passed an invalid argument.
1591 static int soctherm_get_trip_type(struct thermal_zone_device *thz,
1592 int trip, enum thermal_trip_type *type)
1594 struct soctherm_therm *therm = thz->devdata;
1596 *type = therm->trips[trip].trip_type;
1601 * soctherm_get_trip_temp() - gets the threshold of a trip point from a zone
1602 * @thz: the thermal zone whose trip point temperature will be accessed
1603 * @trip: the index of the trip point
1604 * @temp: a pointer to where the temperature will be stored
1606 * Reads the temperature threshold value of the specified trip point from the
1607 * specified thermal zone (in millicelsius) and places it into temp. It also
1608 * update's the zone's tripped flag. This function is passed to the thermal
1609 * framework as a callback function for each thermal zone.
1611 * Return: 0 if success, otherwise %-EINVAL.
1614 static int soctherm_get_trip_temp(struct thermal_zone_device *thz,
1615 int trip, long *temp)
1617 struct soctherm_therm *therm = thz->devdata;
1618 struct thermal_trip_info *trip_state;
1619 long trip_temp, zone_temp;
1621 trip_state = &therm->trips[trip];
1622 trip_temp = trip_state->trip_temp;
1623 zone_temp = thz->temperature;
1625 if (zone_temp >= trip_temp) {
1626 trip_temp -= trip_state->hysteresis;
1627 trip_state->tripped = true;
1628 } else if (trip_state->tripped) {
1629 trip_temp -= trip_state->hysteresis;
1630 if (zone_temp < trip_temp)
1631 trip_state->tripped = false;
1639 * soctherm_set_trip_temp() - updates trip temperature
1640 * for a particular trip point
1641 * @thz: pointer to thermal_zone_device to update trip temperature
1642 * @trip: index value of thermal_trip_info in soctherm_therm->trips
1643 * @temp: value for new temperature
1645 * Updates both the software data structure and the hardware threshold
1646 * for a trip point. This function is passed to the thermal framework
1647 * as a callback function for each of the thermal zone.
1649 * Return: 0 if successful else %-EINVAL
1651 static int soctherm_set_trip_temp(struct thermal_zone_device *thz,
1652 int trip, long temp)
1654 struct soctherm_therm *therm = thz->devdata;
1655 struct thermal_trip_info *trip_state;
1656 ptrdiff_t index = therm - plat_data.therm;
1659 trip_state = &therm->trips[trip];
1660 trip_state->trip_temp = enforce_temp_range(temp);
1662 rem = trip_state->trip_temp % LOWER_PRECISION_FOR_CONV(1000);
1664 pr_warn("soctherm: zone%d/trip_point%d %ld mC rounded down\n",
1665 thz->id, trip, trip_state->trip_temp);
1666 trip_state->trip_temp -= rem;
1669 if (trip_state->trip_type == THERMAL_TRIP_HOT) {
1670 if (strnstr(trip_state->cdev_type,
1671 "heavy", THERMAL_NAME_LENGTH))
1672 prog_hw_threshold(trip_state, index, THROTTLE_HEAVY);
1673 else if (strnstr(trip_state->cdev_type,
1674 "light", THERMAL_NAME_LENGTH))
1675 prog_hw_threshold(trip_state, index, THROTTLE_LIGHT);
1678 /* Allow SW to shutdown at 'Critical temperature reached' */
1679 thermal_notify_framework(thz, trip);
1681 /* Reprogram HW thermtrip */
1682 if (trip_state->trip_type == THERMAL_TRIP_CRITICAL)
1683 prog_hw_shutdown(trip_state, index);
1689 * soctherm_get_crit_temp() - Gets critical temperature of a thermal zone
1690 * @tzd: The pointer to thermal zone device
1691 * @temp: The pointer to the temperature
1693 * Iterates through the list of thermal trips for a given @thz, and looks for
1694 * its critical temperature point @temp to cause a shutdown.
1696 * Return: 0 if it is able to find a critical temperature point and stores it
1697 * into the variable pointed by the address in @temp; Otherwise, return -EINVAL.
1699 static int soctherm_get_crit_temp(struct thermal_zone_device *thz, long *temp)
1702 struct soctherm_therm *therm = thz->devdata;
1703 struct thermal_trip_info *trip_state;
1705 for (i = 0; i < therm->num_trips; i++) {
1706 trip_state = &therm->trips[i];
1707 if (trip_state->trip_type != THERMAL_TRIP_CRITICAL)
1709 *temp = trip_state->trip_temp;
1717 * soctherm_get_trend() - Gets the thermal trend for a given
1718 * thermal zone device
1719 * @thz: The thermal zone device whose trend is being obtained
1720 * @trip: The trip point number
1721 * @trend: The thermal trend
1723 * This function is passed to the thermal framework as a callback
1724 * for SOC_THERM's thermal zone devices
1726 * The trend will be one of the following:
1727 * THERMAL_TREND_STABLE: the temperature is stable
1728 * THERMAL_TREND_RAISING: the temperature is increasing
1729 * THERMAL_TREND_DROPPING: the temperature is decreasing
1730 * THERMAL_TREND_RAISE_FULL: apply the highest cooling action
1731 * THERMAL_TREND_DROP_FULL: apply the lowest cooling action
1733 * If the trip type of the trip point of the thermal zone device is
1734 * THERMAL_TRIP_ACTIVE, then the thermal trend is THERMAL_TREND_RAISING.
1735 * Otherwise, if the device's temperature is higher than its trip
1736 * temperature, the trend is THERMAL_TREND_RAISING. If the device's
1737 * temperature is lower, the trend is THERMAL_TREND_DROPPING. Otherwise
1738 * the trend is stable.
1740 * Return: 0 on success. Returns -EINVAL if the function was
1741 * passed an invalid argument.
1743 static int soctherm_get_trend(struct thermal_zone_device *thz,
1745 enum thermal_trend *trend)
1747 struct soctherm_therm *therm = thz->devdata;
1748 struct thermal_trip_info *trip_state;
1751 trip_state = &therm->trips[trip];
1752 thz->ops->get_trip_temp(thz, trip, &trip_temp);
1754 switch (trip_state->trip_type) {
1755 case THERMAL_TRIP_ACTIVE:
1756 /* aggressive active cooling */
1757 *trend = THERMAL_TREND_RAISING;
1759 case THERMAL_TRIP_PASSIVE:
1760 if (thz->temperature > trip_state->trip_temp)
1761 *trend = THERMAL_TREND_RAISING;
1762 else if (thz->temperature < trip_temp)
1763 *trend = THERMAL_TREND_DROPPING;
1765 *trend = THERMAL_TREND_STABLE;
1773 static struct thermal_zone_device_ops soctherm_ops = {
1774 .bind = soctherm_bind,
1775 .unbind = soctherm_unbind,
1776 .get_temp = soctherm_get_temp,
1777 .get_trip_type = soctherm_get_trip_type,
1778 .get_trip_temp = soctherm_get_trip_temp,
1779 .set_trip_temp = soctherm_set_trip_temp,
1780 .get_crit_temp = soctherm_get_crit_temp,
1781 .get_trend = soctherm_get_trend,
1785 * soctherm_hot_cdev_register() - registers cooling devices
1786 * associated with hardware throttling.
1787 * @i: soctherm_therm_id index of the sensor group
1788 * @trip: index of thermal_trip_info in soctherm_therm->trips
1790 * As indicated by platform configuration data, registers with
1791 * the thermal framework two cooling devices representing
1792 * SOC_THERM's hardware throttling capability associated with
1795 * These cooling devices are special. To function properly, they must be
1796 * bound (with a single trip point) to the thermal zone associated with
1797 * the same sensor group.
1799 * Setting the trip point temperature leads to an adjustment of the
1800 * hardware throttling temperature threshold. Examining the cooling
1801 * device's cur_state indicates whether hardware throttling is active.
1803 static void __init soctherm_hot_cdev_register(int i, int trip)
1805 struct soctherm_therm *therm;
1808 therm = &plat_data.therm[i];
1810 for (k = 0; k < THROTTLE_SIZE; k++) {
1811 if ((therm2dev[i] == THROTTLE_DEV_NONE) ||
1812 (!plat_data.throttle[k].devs[therm2dev[i]].enable))
1815 if ((strnstr(therm->trips[trip].cdev_type, "oc1",
1816 THERMAL_NAME_LENGTH) && k == THROTTLE_OC1) ||
1817 (strnstr(therm->trips[trip].cdev_type, "oc2",
1818 THERMAL_NAME_LENGTH) && k == THROTTLE_OC2) ||
1819 (strnstr(therm->trips[trip].cdev_type, "oc3",
1820 THERMAL_NAME_LENGTH) && k == THROTTLE_OC3) ||
1821 (strnstr(therm->trips[trip].cdev_type, "oc4",
1822 THERMAL_NAME_LENGTH) && k == THROTTLE_OC4))
1825 if (strnstr(therm->trips[trip].cdev_type,
1827 THERMAL_NAME_LENGTH) &&
1828 k == THROTTLE_HEAVY &&
1829 !soctherm_hw_heavy_cdev) {
1830 soctherm_hw_heavy_cdev =
1831 thermal_cooling_device_register(
1832 therm->trips[trip].cdev_type,
1833 &therm->trips[trip],
1834 &soctherm_hw_action_ops);
1838 if (strnstr(therm->trips[trip].cdev_type,
1840 THERMAL_NAME_LENGTH) &&
1841 k == THROTTLE_LIGHT &&
1842 !soctherm_hw_light_cdev) {
1843 soctherm_hw_light_cdev =
1844 thermal_cooling_device_register(
1845 therm->trips[trip].cdev_type,
1846 &therm->trips[trip],
1847 &soctherm_hw_action_ops);
1854 * soctherm_thermal_sys_init() - initializes the SOC_THERM thermal system
1856 * After the board-specific data has been initalized, this creates a thermal
1857 * zone device for each enabled sensor and each enabled sensor group.
1858 * It also creates a cooling zone device for each enabled thermal zone that has
1859 * a critical trip point. It enables the suspend feature if no over-current
1860 * alarms are enabled.
1862 * Once all of the thermal zones have been registered, it runs
1863 * soctherm_update(), which sets high and low temperature thresholds.
1865 * Runs at kernel boot-time.
1869 static int __init soctherm_thermal_sys_init(void)
1871 char name[THERMAL_NAME_LENGTH];
1872 struct soctherm_therm *therm;
1876 if (!soctherm_init_platform_done)
1879 for (i = 0; i < THERM_SIZE; i++) {
1880 therm = &plat_data.therm[i];
1881 if (!therm->zone_enable)
1884 for (j = 0; j < therm->num_trips; j++) {
1885 switch (therm->trips[j].trip_type) {
1886 case THERMAL_TRIP_CRITICAL:
1887 if (soctherm_hw_critical_cdev)
1889 soctherm_hw_critical_cdev =
1890 thermal_cooling_device_register(
1891 therm->trips[j].cdev_type,
1893 &soctherm_hw_action_ops);
1896 case THERMAL_TRIP_HOT:
1897 soctherm_hot_cdev_register(i, j);
1900 case THERMAL_TRIP_PASSIVE:
1901 case THERMAL_TRIP_ACTIVE:
1902 break; /* done elsewhere */
1906 snprintf(name, THERMAL_NAME_LENGTH, "%s-therm", therm_names[i]);
1907 soctherm_th_zones[i] = thermal_zone_device_register(
1910 (1ULL << therm->num_trips) - 1,
1914 therm->passive_delay,
1917 for (j = THROTTLE_OC1; !oc_en && j < THROTTLE_SIZE; j++)
1918 if ((therm2dev[i] != THROTTLE_DEV_NONE) &&
1919 (plat_data.throttle[j].devs[therm2dev[i]].enable))
1923 /* do not enable suspend feature if any OC alarms are enabled */
1925 thermal_cooling_device_register("suspend_soctherm", NULL,
1926 &soctherm_suspend_ops);
1928 pr_warn("soctherm: Suspend feature CANNOT be enabled %s\n",
1929 "when any OC alarm is enabled");
1934 module_init(soctherm_thermal_sys_init);
1937 static void soctherm_update_zone(int zn)
1940 static void soctherm_update(void)
1946 * soctherm_thermal_thread_func() - Handles a thermal interrupt request
1947 * @irq: The interrupt number being requested; not used
1948 * @arg: Opaque pointer to an argument; not used
1950 * Clears the interrupt status register if there are expected
1951 * interrupt bits set.
1952 * The interrupt(s) are then handled by updating the corresponding
1955 * An error is logged if any unexpected interrupt bits are set.
1957 * Disabled interrupts are re-enabled.
1959 * Return: %IRQ_HANDLED. Interrupt was handled and no further processing
1962 static irqreturn_t soctherm_thermal_thread_func(int irq, void *arg)
1964 u32 st, ex = 0, cp = 0, gp = 0, pl = 0;
1966 st = soctherm_readl(TH_INTR_STATUS);
1968 /* deliberately clear expected interrupts handled in SW */
1969 cp |= REG_GET_BIT(st, TH_INTR_POS_CD0);
1970 cp |= REG_GET_BIT(st, TH_INTR_POS_CU0);
1973 gp |= REG_GET_BIT(st, TH_INTR_POS_GD0);
1974 gp |= REG_GET_BIT(st, TH_INTR_POS_GU0);
1977 pl |= REG_GET_BIT(st, TH_INTR_POS_PD0);
1978 pl |= REG_GET_BIT(st, TH_INTR_POS_PU0);
1982 soctherm_writel(ex, TH_INTR_STATUS);
1985 soctherm_update_zone(THERM_CPU);
1987 soctherm_update_zone(THERM_GPU);
1989 soctherm_update_zone(THERM_PLL);
1992 /* deliberately ignore expected interrupts NOT handled in SW */
1993 ex |= REG_GET_BIT(st, TH_INTR_POS_MD0);
1994 ex |= REG_GET_BIT(st, TH_INTR_POS_MU0);
1996 ex |= REG_GET_BIT(st, TH_INTR_POS_CD1);
1997 ex |= REG_GET_BIT(st, TH_INTR_POS_CU1);
1998 ex |= REG_GET_BIT(st, TH_INTR_POS_CD2);
1999 ex |= REG_GET_BIT(st, TH_INTR_POS_CU2);
2000 ex |= REG_GET_BIT(st, TH_INTR_POS_CD3);
2001 ex |= REG_GET_BIT(st, TH_INTR_POS_CU3);
2003 ex |= REG_GET_BIT(st, TH_INTR_POS_GD1);
2004 ex |= REG_GET_BIT(st, TH_INTR_POS_GU1);
2005 ex |= REG_GET_BIT(st, TH_INTR_POS_GD2);
2006 ex |= REG_GET_BIT(st, TH_INTR_POS_GU2);
2007 ex |= REG_GET_BIT(st, TH_INTR_POS_GD3);
2008 ex |= REG_GET_BIT(st, TH_INTR_POS_GU3);
2010 ex |= REG_GET_BIT(st, TH_INTR_POS_PD1);
2011 ex |= REG_GET_BIT(st, TH_INTR_POS_PU1);
2012 ex |= REG_GET_BIT(st, TH_INTR_POS_PD2);
2013 ex |= REG_GET_BIT(st, TH_INTR_POS_PU2);
2014 ex |= REG_GET_BIT(st, TH_INTR_POS_PD3);
2015 ex |= REG_GET_BIT(st, TH_INTR_POS_PU3);
2017 ex |= REG_GET_BIT(st, TH_INTR_POS_MD1);
2018 ex |= REG_GET_BIT(st, TH_INTR_POS_MU1);
2019 ex |= REG_GET_BIT(st, TH_INTR_POS_MD2);
2020 ex |= REG_GET_BIT(st, TH_INTR_POS_MU2);
2021 ex |= REG_GET_BIT(st, TH_INTR_POS_MD3);
2022 ex |= REG_GET_BIT(st, TH_INTR_POS_MU3);
2026 /* Whine about any other unexpected INTR bits still set */
2027 pr_err("soctherm: Ignored unexpected INTRs 0x%08x\n", st);
2028 soctherm_writel(st, TH_INTR_STATUS);
2035 * soctherm_oc_intr_enable() - Enables the soctherm over-current interrupt
2036 * @alarm: The soctherm throttle id
2037 * @enable: Flag indicating enable the soctherm over-current
2038 * interrupt or disable it
2040 * Enables a specific over-current pins @alarm to raise an interrupt if the flag
2041 * is set and the alarm corresponds to OC1, OC2, OC3, or OC4.
2043 static inline void soctherm_oc_intr_enable(enum soctherm_throttle_id alarm,
2051 r = soctherm_readl(OC_INTR_ENABLE);
2054 r = REG_SET(r, OC_INTR_POS_OC1, 1);
2057 r = REG_SET(r, OC_INTR_POS_OC2, 1);
2060 r = REG_SET(r, OC_INTR_POS_OC3, 1);
2063 r = REG_SET(r, OC_INTR_POS_OC4, 1);
2069 soctherm_writel(r, OC_INTR_ENABLE);
2073 * soctherm_handle_alarm() - Handles soctherm alarms
2074 * @alarm: The soctherm throttle id
2076 * "Handles" over-current alarms (OC1, OC2, OC3, and OC4) by printing
2077 * a warning or informative message.
2079 * Return: -EINVAL for @alarm = THROTTLE_OC3, otherwise 0 (success).
2081 static int soctherm_handle_alarm(enum soctherm_throttle_id alarm)
2087 pr_debug("soctherm: Successfully handled OC1 alarm\n");
2088 /* add OC1 alarm handling code here */
2093 pr_info("soctherm: Successfully handled OC2 alarm\n");
2094 /* TODO: add OC2 alarm handling code here */
2099 pr_warn("soctherm: Unexpected OC3 alarm\n");
2100 /* add OC3 alarm handling code here */
2104 pr_debug("soctherm: Successfully handled OC4 alarm\n");
2105 /* TODO: add OC4 alarm handling code here */
2114 pr_err("soctherm: ERROR in handling %s alarm\n",
2115 throt_names[alarm]);
2121 * soctherm_edp_thread_func() - log an over-current interrupt request
2122 * @irq: OC irq number. Currently not being used. See description
2123 * @arg: a void pointer for callback, currently not being used
2125 * Over-current events are handled in hardware. This function is called to log
2126 * and handle any OC events that happened. Additionally, it checks every
2127 * over-current interrupt registers for registers are set but
2128 * was not expected (i.e. any discrepancy in interrupt status) by the function,
2129 * the discrepancy will logged.
2131 * Return: %IRQ_HANDLED
2133 static irqreturn_t soctherm_edp_thread_func(int irq, void *arg)
2135 u32 st, ex, oc1, oc2, oc3, oc4;
2137 st = soctherm_readl(OC_INTR_STATUS);
2139 /* deliberately clear expected interrupts handled in SW */
2140 oc1 = REG_GET_BIT(st, OC_INTR_POS_OC1);
2141 oc2 = REG_GET_BIT(st, OC_INTR_POS_OC2);
2142 oc3 = REG_GET_BIT(st, OC_INTR_POS_OC3);
2143 oc4 = REG_GET_BIT(st, OC_INTR_POS_OC4);
2144 ex = oc1 | oc2 | oc3 | oc4;
2147 soctherm_writel(st, OC_INTR_STATUS);
2150 if (oc1 && !soctherm_handle_alarm(THROTTLE_OC1))
2151 soctherm_oc_intr_enable(THROTTLE_OC1, true);
2153 if (oc2 && !soctherm_handle_alarm(THROTTLE_OC2))
2154 soctherm_oc_intr_enable(THROTTLE_OC2, true);
2156 if (oc3 && !soctherm_handle_alarm(THROTTLE_OC3))
2157 soctherm_oc_intr_enable(THROTTLE_OC3, true);
2159 if (oc4 && !soctherm_handle_alarm(THROTTLE_OC4))
2160 soctherm_oc_intr_enable(THROTTLE_OC4, true);
2162 if (oc1 && soc_irq_cdata.irq_enable & BIT(0))
2164 irq_find_mapping(soc_irq_cdata.domain, 0));
2166 if (oc2 && soc_irq_cdata.irq_enable & BIT(1))
2168 irq_find_mapping(soc_irq_cdata.domain, 1));
2170 if (oc3 && soc_irq_cdata.irq_enable & BIT(2))
2172 irq_find_mapping(soc_irq_cdata.domain, 2));
2174 if (oc4 && soc_irq_cdata.irq_enable & BIT(3))
2176 irq_find_mapping(soc_irq_cdata.domain, 3));
2180 pr_err("soctherm: Ignored unexpected OC ALARM 0x%08x\n", st);
2181 soctherm_writel(st, OC_INTR_STATUS);
2188 * soctherm_thermal_isr() - thermal interrupt request handler
2189 * @irq: Interrupt request number
2192 * Reads the thermal interrupt status and then disables any asserted
2193 * interrupts. The thread woken by this isr services the asserted
2194 * interrupts and re-enables them.
2196 * Return: %IRQ_WAKE_THREAD
2198 static irqreturn_t soctherm_thermal_isr(int irq, void *arg)
2202 r = soctherm_readl(TH_INTR_STATUS);
2203 soctherm_writel(r, TH_INTR_DISABLE);
2205 return IRQ_WAKE_THREAD;
2209 * soctherm_edp_isr() - Disables any active interrupts
2210 * @irq: The interrupt request number
2211 * @arg: Opaque pointer to an argument
2213 * Writes to the OC_INTR_DISABLE register the over current interrupt status,
2214 * masking any asserted interrupts. Doing this prevents the same interrupts
2215 * from triggering this isr repeatedly. The thread woken by this isr will
2216 * handle asserted interrupts and subsequently unmask/re-enable them.
2218 * The OC_INTR_DISABLE register indicates which OC interrupts
2219 * have been disabled.
2221 * Return: %IRQ_WAKE_THREAD, handler requests to wake the handler thread
2223 static irqreturn_t soctherm_edp_isr(int irq, void *arg)
2227 r = soctherm_readl(OC_INTR_STATUS);
2228 soctherm_writel(r, OC_INTR_DISABLE);
2230 return IRQ_WAKE_THREAD;
2234 * throttlectl_cpu_mn() - program CPU pulse skipper configuration
2235 * @throt: soctherm_throttle_id describing the level of throttling
2237 * Pulse skippers are used to throttle clock frequencies. This
2238 * function programs the pulse skippers based on @throt and platform
2239 * data. This function is used for CPUs that have "remote" pulse
2240 * skipper control, e.g., the CPU pulse skipper is controlled by the
2241 * SOC_THERM IP block. (SOC_THERM is located outside the CPU
2244 * Return: boolean true if HW was programmed, or false if the desired
2245 * configuration is not supported.
2247 static bool throttlectl_cpu_mn(enum soctherm_throttle_id throt)
2250 struct soctherm_throttle *data = &plat_data.throttle[throt];
2251 struct soctherm_throttle_dev *dev = &data->devs[THROTTLE_DEV_CPU];
2256 r = soctherm_readl(THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
2257 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, dev->enable);
2258 r = REG_SET(r, THROT_PSKIP_CTRL_DIVIDEND, dev->dividend);
2259 r = REG_SET(r, THROT_PSKIP_CTRL_DIVISOR, dev->divisor);
2260 soctherm_writel(r, THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
2262 r = soctherm_readl(THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
2263 r = REG_SET(r, THROT_PSKIP_RAMP_DURATION, dev->duration);
2264 r = REG_SET(r, THROT_PSKIP_RAMP_STEP, dev->step);
2265 soctherm_writel(r, THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
2271 * throttlectl_cpu_level() - program CPU pulse skipper configuration
2272 * @throt: soctherm_throttle_id describing the level of throttling
2274 * Pulse skippers are used to throttle clock frequencies. This
2275 * function programs the pulse skippers based on @throt and platform
2276 * data. This function is used on SoCs which have CPU-local pulse
2277 * skipper control, such as T13x. It programs soctherm's interface to
2278 * Denver:CCROC NV_THERM in terms of Low, Medium and Heavy throttling
2279 * vectors. PSKIP_BYPASS mode is set as required per HW spec.
2281 * It's also necessary to set up the CPU-local NV_THERM instance with
2282 * the M/N values desired for each level. This function does this
2283 * also, although it should be handled by a separate driver.
2285 * Return: boolean true if HW was programmed, or false if the desired
2286 * configuration is not supported.
2288 static bool throttlectl_cpu_level(enum soctherm_throttle_id throt)
2292 struct soctherm_throttle *data = &plat_data.throttle[throt];
2293 struct soctherm_throttle_dev *dev = &data->devs[THROTTLE_DEV_CPU];
2298 /* Denver:CCROC NV_THERM interface N:3 Mapping */
2299 if (!strcmp(dev->throttling_depth, "heavy_throttling")) {
2300 throt_level = THROT_LEVEL_HVY;
2301 throt_vect = THROT_VECT_HVY;
2302 } else if (!strcmp(dev->throttling_depth, "medium_throttling")) {
2303 throt_level = THROT_LEVEL_MED;
2304 throt_vect = THROT_VECT_MED;
2305 } else if (!strcmp(dev->throttling_depth, "low_throttling")) {
2306 throt_level = THROT_LEVEL_LOW;
2307 throt_vect = THROT_VECT_LOW;
2309 throt_level = THROT_LEVEL_NONE;
2310 throt_vect = THROT_VECT_NONE;
2314 THROT_DEPTH(dev, dev->depth);
2316 r = soctherm_readl(THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
2317 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, dev->enable);
2318 /* setup throttle vector in soctherm register */
2319 r = REG_SET(r, THROT_PSKIP_CTRL_VECT_CPU, throt_vect);
2320 r = REG_SET(r, THROT_PSKIP_CTRL_VECT2_CPU, throt_vect);
2321 soctherm_writel(r, THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
2323 /* bypass sequencer in soc_therm as it is programmed in ccroc */
2324 r = REG_SET(0, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE, 1);
2325 soctherm_writel(r, THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
2327 if (throt_level == THROT_LEVEL_NONE)
2330 /* setup PSKIP in ccroc nv_therm registers */
2331 r = clk_reset13_readl(THROT13_PSKIP_RAMP_CPU(throt_level));
2332 r = REG_SET(r, THROT_PSKIP_RAMP_DURATION, dev->duration);
2333 r = REG_SET(r, THROT_PSKIP_RAMP_STEP, dev->step);
2334 clk_reset13_writel(r, THROT13_PSKIP_RAMP_CPU(throt_level));
2336 r = clk_reset13_readl(THROT13_PSKIP_CTRL_CPU(throt_level));
2337 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, dev->enable);
2338 r = REG_SET(r, THROT_PSKIP_CTRL_DIVIDEND, dev->dividend);
2339 r = REG_SET(r, THROT_PSKIP_CTRL_DIVISOR, dev->divisor);
2340 clk_reset13_writel(r, THROT13_PSKIP_CTRL_CPU(throt_level));
2346 * throttlectl_gpu_gk20a_nv_therm_style() - programs GK20a NV_THERM config
2347 * @dev device struct pointer to GPU device
2348 * @throt soctherm_throttle_id describing the level of throttling
2350 * This function programs soctherm's interface to GK20a NV_THERM in
2351 * terms of Low, Medium and Heavy throttling preset levels.
2353 * Return: boolean true if HW was programmed
2355 static bool throttlectl_gpu_gk20a_nv_therm_style(
2356 struct soctherm_throttle_dev *dev,
2357 enum soctherm_throttle_id throt)
2361 /* gk20a nv_therm interface N:3 Mapping */
2362 if (!strcmp(dev->throttling_depth, "heavy_throttling"))
2363 throt_vect = THROT_VECT_HVY;
2364 else if (!strcmp(dev->throttling_depth, "medium_throttling"))
2365 throt_vect = THROT_VECT_MED;
2367 throt_vect = THROT_VECT_LOW;
2369 r = soctherm_readl(THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
2370 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, dev->enable);
2371 r = REG_SET(r, THROT_PSKIP_CTRL_VECT_GPU, throt_vect);
2372 soctherm_writel(r, THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
2374 r = soctherm_readl(THROT_PSKIP_RAMP(throt, THROTTLE_DEV_GPU));
2375 r = REG_SET(r, THROT_PSKIP_RAMP_SEQ_BYPASS_MODE, 1);
2376 soctherm_writel(r, THROT_PSKIP_RAMP(throt, THROTTLE_DEV_GPU));
2382 * throttlectl_gpu() - programs GPU pulse skippers' configuration
2383 * @throt soctherm_throttle_id describing the level of throttling
2385 * Pulse skippers are used to throttle clock frequencies.
2386 * This function programs the pulse skippers based on @throt and platform data.
2388 * Return: boolean true if HW was programmed
2390 static bool throttlectl_gpu(enum soctherm_throttle_id throt)
2393 struct soctherm_throttle *data = &plat_data.throttle[throt];
2394 struct soctherm_throttle_dev *dev = &data->devs[THROTTLE_DEV_GPU];
2399 if (IS_T12X || IS_T13X)
2400 return throttlectl_gpu_gk20a_nv_therm_style(dev, throt);
2403 THROT_DEPTH(dev, dev->depth);
2405 r = soctherm_readl(THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
2406 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, dev->enable);
2407 r = REG_SET(r, THROT_PSKIP_CTRL_DIVIDEND, dev->dividend);
2408 r = REG_SET(r, THROT_PSKIP_CTRL_DIVISOR, dev->divisor);
2409 soctherm_writel(r, THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
2411 r = soctherm_readl(THROT_PSKIP_RAMP(throt, THROTTLE_DEV_GPU));
2412 r = REG_SET(r, THROT_PSKIP_RAMP_DURATION, dev->duration);
2413 r = REG_SET(r, THROT_PSKIP_RAMP_STEP, dev->step);
2414 soctherm_writel(r, THROT_PSKIP_RAMP(throt, THROTTLE_DEV_GPU));
2420 * soctherm_throttle_program() - programs pulse skippers' configuration
2421 * @throt soctherm_throttle_id describing the level of throttling
2423 * Pulse skippers are used to throttle clock frequencies.
2424 * This function programs the pulse skippers based on @throt and platform data.
2426 * Return: Nothing is returned (void).
2428 static void soctherm_throttle_program(enum soctherm_throttle_id throt)
2432 struct soctherm_throttle *data = &plat_data.throttle[throt];
2434 throt_enable = (IS_T13X) ? throttlectl_cpu_level(throt) :
2435 throttlectl_cpu_mn(throt);
2436 throt_enable |= throttlectl_gpu(throt);
2438 r = REG_SET(0, THROT_PRIORITY_LITE_PRIO, data->priority);
2439 soctherm_writel(r, THROT_PRIORITY_CTRL(throt));
2441 r = REG_SET(0, THROT_DELAY_LITE_DELAY, 0);
2442 soctherm_writel(r, THROT_DELAY_CTRL(throt));
2444 r = soctherm_readl(THROT_PRIORITY_LOCK);
2445 if (r < data->priority) {
2446 r = REG_SET(0, THROT_PRIORITY_LOCK_PRIORITY, data->priority);
2447 soctherm_writel(r, THROT_PRIORITY_LOCK);
2450 /* ----- configure reserved OC5 alarm ----- */
2451 if (throt == THROTTLE_OC5) {
2452 r = soctherm_readl(ALARM_CFG(throt));
2453 r = REG_SET(r, OC1_CFG_THROTTLE_MODE, BRIEF);
2454 r = REG_SET(r, OC1_CFG_ALARM_POLARITY, 0);
2455 r = REG_SET(r, OC1_CFG_EN_THROTTLE, 1);
2456 soctherm_writel(r, ALARM_CFG(throt));
2458 r = REG_SET(r, OC1_CFG_ALARM_POLARITY, 1);
2459 soctherm_writel(r, ALARM_CFG(throt));
2461 r = REG_SET(r, OC1_CFG_ALARM_POLARITY, 0);
2462 soctherm_writel(r, ALARM_CFG(throt));
2464 r = REG_SET(r, THROT_PSKIP_CTRL_DIVIDEND, 0);
2465 r = REG_SET(r, THROT_PSKIP_CTRL_DIVISOR, 0);
2466 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, 1);
2467 soctherm_writel(r, THROT_PSKIP_CTRL(throt, THROTTLE_DEV_CPU));
2469 r = soctherm_readl(THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
2470 r = REG_SET(r, THROT_PSKIP_RAMP_DURATION, 0xff);
2471 r = REG_SET(r, THROT_PSKIP_RAMP_STEP, 0xf);
2472 soctherm_writel(r, THROT_PSKIP_RAMP(throt, THROTTLE_DEV_CPU));
2474 r = soctherm_readl(THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
2475 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, 1);
2476 soctherm_writel(r, THROT_PSKIP_CTRL(throt, THROTTLE_DEV_GPU));
2478 r = REG_SET(0, THROT_PRIORITY_LITE_PRIO, 1);
2479 soctherm_writel(r, THROT_PRIORITY_CTRL(throt));
2483 if (!throt_enable || (throt < THROTTLE_OC1))
2486 /* ----- configure other OC alarms ----- */
2487 if (!(data->throt_mode == BRIEF || data->throt_mode == STICKY))
2488 pr_warn("soctherm: Invalid throt_mode in %s\n",
2489 throt_names[throt]);
2491 r = soctherm_readl(ALARM_CFG(throt));
2492 r = REG_SET(r, OC1_CFG_HW_RESTORE, 1);
2493 r = REG_SET(r, OC1_CFG_PWR_GOOD_MASK, data->pgmask);
2494 r = REG_SET(r, OC1_CFG_THROTTLE_MODE, data->throt_mode);
2495 r = REG_SET(r, OC1_CFG_ALARM_POLARITY, data->polarity);
2496 r = REG_SET(r, OC1_CFG_EN_THROTTLE, 1);
2497 soctherm_writel(r, ALARM_CFG(throt));
2499 soctherm_oc_intr_enable(throt, data->intr);
2501 soctherm_writel(data->period, ALARM_THROTTLE_PERIOD(throt)); /* usec */
2502 soctherm_writel(data->alarm_cnt_threshold, ALARM_CNT_THRESHOLD(throt));
2503 if (data->alarm_filter)
2504 soctherm_writel(data->alarm_filter, ALARM_FILTER(throt));
2506 soctherm_writel(0xffffffff, ALARM_FILTER(throt));
2510 * soctherm_tsense_program() - Configure sensor timing parameters based on
2511 * chip-specific data.
2513 * @sensor: The temperature sensor. This corresponds to one of the
2514 * four CPU sensors, one of the two memory
2515 * sensors, or the GPU or PLLX sensor.
2516 * @data: Information regarding a sensor. This comes from the platform
2519 * This function is called during initialization. It sets two CPU thermal sensor
2520 * configuration registers (TS_CPU0_CONFIG0 and TS_CPU0_CONFIG1)
2521 * to contain the given chip-specific sensor's configuration data.
2523 * The configuration data affects the sensor's temperature capturing.
2525 * Return: Nothing is returned (void).
2527 static void soctherm_tsense_program(enum soctherm_sense sensor,
2528 struct soctherm_sensor *data)
2532 r = REG_SET(0, TS_CPU0_CONFIG0_TALL, data->tall);
2533 soctherm_writel(r, TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG0, sensor));
2535 r = REG_SET(0, TS_CPU0_CONFIG1_TIDDQ, data->tiddq);
2536 r = REG_SET(r, TS_CPU0_CONFIG1_EN, 1);
2537 r = REG_SET(r, TS_CPU0_CONFIG1_TEN_COUNT, data->ten_count);
2538 r = REG_SET(r, TS_CPU0_CONFIG1_TSAMPLE, data->tsample - 1);
2539 soctherm_writel(r, TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG1, sensor));
2543 * soctherm_clk_init() - Initialize SOC_THERM related clocks.
2545 * The initialization will map clock aliases for SOC_THERM and TSENSE
2546 * and set their clock rates based on chip-specific defaults or
2547 * any platform-specific overrides.
2549 * Return: 0 if successful else %-EINVAL if initialization failed
2551 static int __init soctherm_clk_init(void)
2553 unsigned long default_soctherm_clk_rate;
2554 unsigned long default_tsensor_clk_rate;
2556 soctherm_clk = clk_get_sys("soc_therm", NULL);
2557 tsensor_clk = clk_get_sys("tegra-tsensor", NULL);
2559 if (IS_ERR(tsensor_clk) || IS_ERR(soctherm_clk)) {
2560 clk_put(soctherm_clk);
2561 clk_put(tsensor_clk);
2562 soctherm_clk = NULL;
2567 /* initialize default clock rates */
2569 default_soctherm_clk_rate = default_t11x_soctherm_clk_rate;
2570 default_tsensor_clk_rate = default_t11x_tsensor_clk_rate;
2571 } else if (IS_T14X) {
2572 default_soctherm_clk_rate = default_t14x_soctherm_clk_rate;
2573 default_tsensor_clk_rate = default_t14x_tsensor_clk_rate;
2574 } else if ((IS_T12X || IS_T13X)) {
2575 default_soctherm_clk_rate = default_t12x_soctherm_clk_rate;
2576 default_tsensor_clk_rate = default_t12x_tsensor_clk_rate;
2581 plat_data.soctherm_clk_rate =
2582 plat_data.soctherm_clk_rate ?: default_soctherm_clk_rate;
2583 plat_data.tsensor_clk_rate =
2584 plat_data.tsensor_clk_rate ?: default_tsensor_clk_rate;
2586 if (clk_get_rate(soctherm_clk) != plat_data.soctherm_clk_rate)
2587 if (clk_set_rate(soctherm_clk, plat_data.soctherm_clk_rate))
2590 if (clk_get_rate(tsensor_clk) != plat_data.tsensor_clk_rate)
2591 if (clk_set_rate(tsensor_clk, plat_data.tsensor_clk_rate))
2598 * soctherm_clk_enable() - enables and disables the clocks
2599 * @enable: whether the clocks should be enabled or disabled
2601 * Enables the SOC_THERM and thermal sensor clocks when SOC_THERM
2604 * Return: 0 if successful, %-EINVAL if either clock hasn't been initialized.
2606 static int soctherm_clk_enable(bool enable)
2608 if (soctherm_clk == NULL || tsensor_clk == NULL)
2612 clk_enable(soctherm_clk);
2613 clk_enable(tsensor_clk);
2615 clk_disable(soctherm_clk);
2616 clk_disable(tsensor_clk);
2623 * soctherm_fuse_read_calib_base() - Calculates calibration base temperature
2625 * Calculates the nominal temperature used for thermal sensor calibration
2626 * based on chip type and the value in fuses.
2628 * Return: 0 (success), otherwise -EINVAL.
2630 static int soctherm_fuse_read_calib_base(void)
2632 s32 calib_cp, calib_ft;
2633 s32 nominal_calib_cp, nominal_calib_ft;
2635 if (tegra_fuse_calib_base_get_cp(&fuse_calib_base_cp, &calib_cp) < 0 ||
2636 tegra_fuse_calib_base_get_ft(&fuse_calib_base_ft, &calib_ft) < 0) {
2637 pr_err("soctherm: ERROR: Improper CP or FT calib fuse.\n");
2641 nominal_calib_cp = 25;
2643 nominal_calib_ft = 90;
2644 else if (IS_T14X || IS_T12X || IS_T13X)
2645 nominal_calib_ft = 105;
2649 /* use HI precision to calculate: use fuse_temp in 0.5C */
2650 actual_temp_cp = 2 * nominal_calib_cp + calib_cp;
2651 actual_temp_ft = 2 * nominal_calib_ft + calib_ft;
2656 static struct soctherm_fuse_correction_war no_fuse_war[] = {
2657 [TSENSE_CPU0] = { 1000000, 0 },
2658 [TSENSE_CPU1] = { 1000000, 0 },
2659 [TSENSE_CPU2] = { 1000000, 0 },
2660 [TSENSE_CPU3] = { 1000000, 0 },
2661 [TSENSE_MEM0] = { 1000000, 0 },
2662 [TSENSE_MEM1] = { 1000000, 0 },
2663 [TSENSE_GPU] = { 1000000, 0 },
2664 [TSENSE_PLLX] = { 1000000, 0 },
2667 static struct soctherm_fuse_correction_war t11x_fuse_war[] = {
2668 [TSENSE_CPU0] = { 1196400, -13600000 },
2669 [TSENSE_CPU1] = { 1196400, -13600000 },
2670 [TSENSE_CPU2] = { 1196400, -13600000 },
2671 [TSENSE_CPU3] = { 1196400, -13600000 },
2672 [TSENSE_MEM0] = { 1000000, -1000000 },
2673 [TSENSE_MEM1] = { 1000000, -1000000 },
2674 [TSENSE_GPU] = { 1124500, -9793100 },
2675 [TSENSE_PLLX] = { 1224200, -14665000 },
2678 static struct soctherm_fuse_correction_war t14x_fuse_war[] = {
2679 [TSENSE_CPU0] = { 1149000, -16753000 },
2680 [TSENSE_CPU1] = { 1148800, -16287000 },
2681 [TSENSE_CPU2] = { 1139100, -12552000 },
2682 [TSENSE_CPU3] = { 1141800, -11061000 },
2683 [TSENSE_MEM0] = { 1082300, -11061000 },
2684 [TSENSE_MEM1] = { 1061800, -7596500 },
2685 [TSENSE_GPU] = { 1078900, -10480000 },
2686 [TSENSE_PLLX] = { 1125900, -14736000 },
2690 static struct soctherm_fuse_correction_war t12x_fuse_war1[] = {
2691 [TSENSE_CPU0] = { 1148300, -6572300 },
2692 [TSENSE_CPU1] = { 1126100, -5794600 },
2693 [TSENSE_CPU2] = { 1155800, -7462800 },
2694 [TSENSE_CPU3] = { 1134900, -6810800 },
2695 [TSENSE_MEM0] = { 1062700, -4463200 },
2696 [TSENSE_MEM1] = { 1084700, -5603400 },
2697 [TSENSE_GPU] = { 1084300, -5111900 },
2698 [TSENSE_PLLX] = { 1134500, -7410700 },
2702 static struct soctherm_fuse_correction_war t12x_fuse_war2[] = {
2703 [TSENSE_CPU0] = { 1135400, -6266900 },
2704 [TSENSE_CPU1] = { 1122220, -5700700 },
2705 [TSENSE_CPU2] = { 1127000, -6768200 },
2706 [TSENSE_CPU3] = { 1110900, -6232000 },
2707 [TSENSE_MEM0] = { 1122300, -5936400 },
2708 [TSENSE_MEM1] = { 1145700, -7124600 },
2709 [TSENSE_GPU] = { 1120100, -6000500 },
2710 [TSENSE_PLLX] = { 1106500, -6729300 },
2713 /* old ATE pattern */
2714 static struct soctherm_fuse_correction_war t13x_fuse_war1[] = {
2715 [TSENSE_CPU0] = { 1119800, -6330400 },
2716 [TSENSE_CPU1] = { 1094100, -3751800 },
2717 [TSENSE_CPU2] = { 1108800, -3835200 },
2718 [TSENSE_CPU3] = { 1103200, -5132100 },
2719 [TSENSE_MEM0] = { 1168400, -11266000 },
2720 [TSENSE_MEM1] = { 1185600, -10861000 },
2721 [TSENSE_GPU] = { 1158500, -10714000 },
2722 [TSENSE_PLLX] = { 1150000, -11899000 },
2725 /* new ATE pattern */
2726 static struct soctherm_fuse_correction_war t13x_fuse_war2[] = {
2727 [TSENSE_CPU0] = { 1126600, -9433500 },
2728 [TSENSE_CPU1] = { 1110800, -7383000 },
2729 [TSENSE_CPU2] = { 1113800, -6215200 },
2730 [TSENSE_CPU3] = { 1129600, -8196100 },
2731 [TSENSE_MEM0] = { 1132900, -6755300 },
2732 [TSENSE_MEM1] = { 1142300, -7374200 },
2733 [TSENSE_GPU] = { 1125100, -6350400 },
2734 [TSENSE_PLLX] = { 1118100, -8208800 },
2738 * soctherm_fuse_read_tsensor() - calculates therm_a and therm_b for a sensor
2739 * @sensor: The sensor for which to calculate.
2741 * Reads the calibration data from the thermal sensor's fuses and then uses
2742 * that data to calculate the slope of the pulse/temperature
2743 * relationship, therm_a, and its x-intercept, therm_b. After correcting the
2744 * values based on their chip ID and whether precision is high or low, it
2745 * stores them in the sensor's registers so that the hardware can convert the
2746 * raw TSOSC reading into temperature in celsius.
2748 * Return: 0 if successful, otherwise %-EINVAL
2750 static int soctherm_fuse_read_tsensor(enum soctherm_sense sensor)
2753 s32 calib, delta_sens, delta_temp;
2754 s16 therm_a, therm_b;
2755 s32 div, mult, actual_tsensor_ft, actual_tsensor_cp;
2757 struct soctherm_fuse_correction_war *war;
2759 fuse_rev = tegra_fuse_calib_base_get_cp(NULL, NULL);
2763 tegra_fuse_get_tsensor_calib(sensor2tsensorcalib[sensor], &value);
2765 /* Extract bits and convert to signed 2's complement */
2766 calib = REG_GET(value, FUSE_TSENSOR_CALIB_FT);
2767 calib = MAKE_SIGNED32(calib, FUSE_TSENSOR_CALIB_BITS);
2768 actual_tsensor_ft = (fuse_calib_base_ft * 32) + calib;
2770 calib = REG_GET(value, FUSE_TSENSOR_CALIB_CP);
2771 calib = MAKE_SIGNED32(calib, FUSE_TSENSOR_CALIB_BITS);
2772 actual_tsensor_cp = (fuse_calib_base_cp * 64) + calib;
2774 mult = plat_data.sensor_data[sensor].pdiv *
2775 plat_data.sensor_data[sensor].tsamp_ate;
2776 div = plat_data.sensor_data[sensor].tsample *
2777 plat_data.sensor_data[sensor].pdiv_ate;
2779 /* first calculate therm_a and therm_b in Hi precision */
2780 delta_sens = actual_tsensor_ft - actual_tsensor_cp;
2781 delta_temp = actual_temp_ft - actual_temp_cp;
2783 therm_a = div64_s64_precise((s64)delta_temp * (1LL << 13) * mult,
2784 (s64)delta_sens * div);
2786 therm_b = div64_s64_precise((((s64)actual_tsensor_ft * actual_temp_cp) -
2787 ((s64)actual_tsensor_cp * actual_temp_ft)),
2790 /* FUSE correction WARs */
2792 war = PRECISION_IS_LOWER() ?
2793 &t11x_fuse_war[sensor] : &no_fuse_war[sensor];
2795 war = PRECISION_IS_LOWER() ?
2796 &t14x_fuse_war[sensor] : &no_fuse_war[sensor];
2799 &t12x_fuse_war1[sensor] : &t12x_fuse_war2[sensor];
2801 war = fuse_rev == 2 ?
2802 &t13x_fuse_war1[sensor] : &t13x_fuse_war2[sensor];
2804 war = &no_fuse_war[sensor];
2806 therm_a = div64_s64_precise((s64)therm_a * war->a,
2808 therm_b = div64_s64_precise((s64)therm_b * war->a + war->b,
2810 therm_a = LOWER_PRECISION_FOR_TEMP(therm_a);
2811 therm_b = LOWER_PRECISION_FOR_TEMP(therm_b);
2813 sensor2therm_a[sensor] = (s16)therm_a;
2814 sensor2therm_b[sensor] = (s16)therm_b;
2816 r = REG_SET(0, TS_CPU0_CONFIG2_THERM_A, therm_a);
2817 r = REG_SET(r, TS_CPU0_CONFIG2_THERM_B, therm_b);
2818 soctherm_writel(r, TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG2, sensor));
2824 * soctherm_therm_trip_init() - configure PMC's thermal-shutdown behavior
2825 * @data: Power management unit thermal sensor initialization data
2827 * Takes a given set of data and writes it to SCRATCH54 and SCRATCH55, which
2828 * PMC will use if SOC_THERM requests a shutdown based on excessive
2829 * temperature (i.e. a thermtrip).
2831 static void soctherm_therm_trip_init(struct tegra_thermtrip_pmic_data *data)
2836 tegra_pmc_enable_thermal_trip();
2837 tegra_pmc_config_thermal_trip(data);
2841 * soctherm_adjust_cpu_zone() - Adjusts the soctherm CPU zone
2842 * @therm: soctherm_therm_id specifying the sensor group to adjust
2844 * Changes SOC_THERM registers based on the CPU and PLLX temperatures.
2845 * Programs hotspot offsets per CPU or GPU and PLLX difference of temperature,
2846 * stops or starts CPUn TSOSCs, and programs hotspot offsets per configuration.
2847 * This function is called in soctherm_init_platform_data(),
2848 * tegra_soctherm_adjust_cpu_zone() and tegra_soctherm_adjust_core_zone().
2850 static void soctherm_adjust_zone(int tz)
2854 long ztemp, pll_temp, diff;
2857 if (soctherm_suspended)
2860 if (tz == THERM_CPU)
2861 low_voltage = vdd_cpu_low_voltage;
2862 else if (tz == THERM_GPU)
2863 low_voltage = vdd_core_low_voltage;
2864 else if (tz == THERM_MEM)
2865 low_voltage = vdd_core_low_voltage;
2870 r = soctherm_readl(TS_TEMP1);
2871 s = soctherm_readl(TS_TEMP2);
2874 pll_temp = temp_translate(REG_GET(s, TS_TEMP2_PLLX_TEMP));
2875 ztemp = pll_temp; /* initialized */
2877 /* get therm-zone temp */
2878 if (tz == THERM_CPU)
2879 ztemp = temp_translate(REG_GET(r, TS_TEMP1_CPU_TEMP));
2880 else if (tz == THERM_GPU)
2881 ztemp = temp_translate(REG_GET(r, TS_TEMP1_GPU_TEMP));
2882 else if (tz == THERM_MEM)
2883 ztemp = temp_translate(REG_GET(s, TS_TEMP2_MEM_TEMP));
2885 if (ztemp > pll_temp)
2886 diff = ztemp - pll_temp;
2890 /* cap hotspot offset to max offset from pdata */
2891 if (diff > plat_data.therm[tz].hotspot_offset)
2892 diff = plat_data.therm[tz].hotspot_offset;
2894 /* Program hotspot offsets per <tz> ~ PLL diff */
2895 r = soctherm_readl(TS_HOTSPOT_OFF);
2896 if (tz == THERM_CPU)
2897 r = REG_SET(r, TS_HOTSPOT_OFF_CPU, diff / 1000);
2898 else if (tz == THERM_GPU)
2899 r = REG_SET(r, TS_HOTSPOT_OFF_GPU, diff / 1000);
2900 else if (tz == THERM_MEM)
2901 r = REG_SET(r, TS_HOTSPOT_OFF_MEM, diff / 1000);
2902 soctherm_writel(r, TS_HOTSPOT_OFF);
2904 /* Stop all TSENSE's mapped to <tz> */
2905 for (i = 0; i < TSENSE_SIZE; i++) {
2906 if (tsensor2therm_map[i] != tz)
2908 r = soctherm_readl(TS_TSENSE_REG_OFFSET
2909 (TS_CPU0_CONFIG0, i));
2910 r = REG_SET(r, TS_CPU0_CONFIG0_STOP, 1);
2911 soctherm_writel(r, TS_TSENSE_REG_OFFSET
2912 (TS_CPU0_CONFIG0, i));
2915 /* UN-Stop all TSENSE's mapped to <tz> */
2916 for (i = 0; i < TSENSE_SIZE; i++) {
2917 if (tsensor2therm_map[i] != tz)
2919 r = soctherm_readl(TS_TSENSE_REG_OFFSET
2920 (TS_CPU0_CONFIG0, i));
2921 r = REG_SET(r, TS_CPU0_CONFIG0_STOP, 0);
2922 soctherm_writel(r, TS_TSENSE_REG_OFFSET
2923 (TS_CPU0_CONFIG0, i));
2926 /* default to configured offset for <tz> */
2927 diff = plat_data.therm[tz].hotspot_offset;
2929 /* Program hotspot offsets per config */
2930 r = soctherm_readl(TS_HOTSPOT_OFF);
2931 if (tz == THERM_CPU)
2932 r = REG_SET(r, TS_HOTSPOT_OFF_CPU, diff / 1000);
2933 else if (tz == THERM_GPU)
2934 r = REG_SET(r, TS_HOTSPOT_OFF_GPU, diff / 1000);
2935 else if (tz == THERM_MEM)
2936 r = REG_SET(r, TS_HOTSPOT_OFF_MEM, diff / 1000);
2937 soctherm_writel(r, TS_HOTSPOT_OFF);
2942 * soctherm_init_platform_data() - Initializes the platform data.
2944 * Cleans up some platform data in preparation for configuring the
2945 * hardware and configures the hardware as specified by the cleaned up
2948 * Initializes unset parameters for CPU, GPU, MEM, and PLL
2949 * based on the default values for the sensors on the Tegra chip in use.
2951 * Sets the temperature sensor PDIV (post divider) register which
2952 * contains the temperature sensor PDIV for the CPU, GPU, MEM, and PLLX
2954 * Sets the configurations for each of the sensors.
2956 * Sanitizes thermal trips for each thermal zone.
2958 * Writes hotspot offsets to TS_HOTSPOT_OFF register.
2960 * Checks the throttling priorities and makes sure that they are
2961 * in the correct order for throttle types THROTTLE_OC1 though THROTTLE_OC4.
2963 * Initializes PSKIP parameters. These parameters are used during a thermal
2964 * trip to calculate the amount of throttling of the CPU or GPU for each
2965 * thermal trip type (i.e. THROTTLE_LIGHT or THROTTLE_HEAVY)
2967 * Initializes the throttling thresholds for the CPU, GPU, MEM, and PLL
2969 * Checks if the priorities of heavy and light throttling are in
2970 * the correct order.
2972 * Initializes the STATS_CTL and OC_STATS_CTL registers for stat collection
2974 * Enables PMC shutdown based on the platform data
2976 * Programs the temperatures at which hardware shutdowns occur.
2978 * soctherm_init_platform_data ensures that the system will function as
2979 * expected when it resumes from suspended state or on initial start up.
2981 * Return: 0 on success. -EINVAL is returned otherwise
2983 static int soctherm_init_platform_data(void)
2985 struct soctherm_therm *therm;
2986 struct soctherm_sensor *s;
2987 struct soctherm_sensor sensor_defaults;
2990 long gsh = MAX_HIGH_TEMP;
2994 sensor_defaults = default_t11x_sensor_params;
2996 sensor_defaults = default_t14x_sensor_params;
2997 else if ((IS_T12X || IS_T13X))
2998 sensor_defaults = default_t12x_sensor_params;
3002 /* initialize default values for unspecified params */
3003 for (i = 0; i < TSENSE_SIZE; i++) {
3004 therm = &plat_data.therm[tsensor2therm_map[i]];
3005 s = &plat_data.sensor_data[i];
3006 s->sensor_enable = s->sensor_enable ?: therm->zone_enable;
3007 s->tall = s->tall ?: sensor_defaults.tall;
3008 s->tiddq = s->tiddq ?: sensor_defaults.tiddq;
3009 s->ten_count = s->ten_count ?: sensor_defaults.ten_count;
3010 s->tsample = s->tsample ?: sensor_defaults.tsample;
3011 s->tsamp_ate = s->tsamp_ate ?: sensor_defaults.tsamp_ate;
3012 s->pdiv = s->pdiv ?: sensor_defaults.pdiv;
3013 s->pdiv_ate = s->pdiv_ate ?: sensor_defaults.pdiv_ate;
3017 r = soctherm_readl(TS_PDIV);
3018 r = REG_SET(r, TS_PDIV_CPU, plat_data.sensor_data[TSENSE_CPU0].pdiv);
3019 r = REG_SET(r, TS_PDIV_GPU, plat_data.sensor_data[TSENSE_GPU].pdiv);
3020 r = REG_SET(r, TS_PDIV_MEM, plat_data.sensor_data[TSENSE_MEM0].pdiv);
3021 r = REG_SET(r, TS_PDIV_PLLX, plat_data.sensor_data[TSENSE_PLLX].pdiv);
3022 soctherm_writel(r, TS_PDIV);
3024 /* Thermal Sensing programming */
3025 if (soctherm_fuse_read_calib_base() < 0)
3027 for (i = 0; i < TSENSE_SIZE; i++) {
3028 if (plat_data.sensor_data[i].sensor_enable) {
3029 soctherm_tsense_program(i, &plat_data.sensor_data[i]);
3030 if (soctherm_fuse_read_tsensor(i) < 0)
3035 soctherm_adjust_zone(THERM_CPU);
3036 soctherm_adjust_zone(THERM_GPU);
3037 soctherm_adjust_zone(THERM_MEM);
3039 /* Sanitize therm trips */
3040 for (i = 0; i < THERM_SIZE; i++) {
3041 therm = &plat_data.therm[i];
3042 if (!therm->zone_enable)
3045 for (j = 0; j < therm->num_trips; j++) {
3046 rem = therm->trips[j].trip_temp %
3047 LOWER_PRECISION_FOR_CONV(1000);
3050 "soctherm: zone%d/trip_point%d %ld mC rounded down\n",
3051 i, j, therm->trips[j].trip_temp);
3052 therm->trips[j].trip_temp -= rem;
3057 /* Program hotspot offsets per THERM */
3058 r = REG_SET(0, TS_HOTSPOT_OFF_CPU,
3059 plat_data.therm[THERM_CPU].hotspot_offset / 1000);
3060 r = REG_SET(r, TS_HOTSPOT_OFF_GPU,
3061 plat_data.therm[THERM_GPU].hotspot_offset / 1000);
3062 r = REG_SET(r, TS_HOTSPOT_OFF_MEM,
3063 plat_data.therm[THERM_MEM].hotspot_offset / 1000);
3064 soctherm_writel(r, TS_HOTSPOT_OFF);
3066 /* Thermal HW throttle programming */
3067 for (i = 0; i < THROTTLE_SIZE; i++) {
3068 /* Sanitize HW throttle priority for OC1 - OC4 (not OC5) */
3069 if ((i != THROTTLE_OC5) && (!plat_data.throttle[i].priority))
3070 plat_data.throttle[i].priority = 0xE + i;
3072 /* Setup PSKIP parameters */
3073 soctherm_throttle_program(i);
3075 /* Setup throttle thresholds per THERM */
3076 for (j = 0; j < THERM_SIZE; j++) {
3077 if ((therm2dev[j] == THROTTLE_DEV_NONE) ||
3078 (!plat_data.throttle[i].devs[therm2dev[j]].enable))
3081 therm = &plat_data.therm[j];
3082 for (k = 0; k < therm->num_trips; k++)
3083 if ((therm->trips[k].trip_type ==
3084 THERMAL_TRIP_HOT) &&
3085 strnstr(therm->trips[k].cdev_type,
3086 i == THROTTLE_HEAVY ? "heavy" :
3087 "light", THERMAL_NAME_LENGTH))
3089 if (k < therm->num_trips && i <= THROTTLE_HEAVY)
3090 prog_hw_threshold(&therm->trips[k], j, i);
3094 r = REG_SET(0, THROT_GLOBAL_ENB, 1);
3096 clk_reset13_writel(r, THROT13_GLOBAL_CFG);
3098 soctherm_writel(r, THROT_GLOBAL_CFG);
3100 if (plat_data.throttle[THROTTLE_HEAVY].priority <
3101 plat_data.throttle[THROTTLE_LIGHT].priority)
3102 pr_err("soctherm: ERROR: Priority of HEAVY less than LIGHT\n");
3104 /* initialize stats collection */
3105 r = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
3106 STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
3107 soctherm_writel(r, STATS_CTL);
3108 soctherm_writel(OC_STATS_CTL_EN_ALL, OC_STATS_CTL);
3110 /* Enable PMC to shutdown */
3111 soctherm_therm_trip_init(plat_data.tshut_pmu_trip_data);
3113 r = clk_reset_readl(CAR_SUPER_CLK_DIVIDER_REGISTER());
3114 r = REG_SET(r, CDIVG_USE_THERM_CONTROLS, 1);
3115 clk_reset_writel(r, CAR_SUPER_CLK_DIVIDER_REGISTER());
3118 for (i = 0; i < THERM_SIZE; i++) {
3119 therm = &plat_data.therm[i];
3120 if (!therm->zone_enable)
3123 for (j = 0; j < therm->num_trips; j++) {
3124 if (therm->trips[j].trip_type != THERMAL_TRIP_CRITICAL)
3126 if (i == THERM_GPU) {
3127 gsh = therm->trips[j].trip_temp;
3128 } else if ((i == THERM_MEM) &&
3129 (gsh != MAX_HIGH_TEMP) &&
3130 (therm->trips[j].trip_temp != gsh)) {
3131 pr_warn("soctherm: Force TRIP temp: MEM = GPU");
3132 therm->trips[j].trip_temp = gsh;
3134 prog_hw_shutdown(&therm->trips[j], i);
3142 * soctherm_suspend_locked() - suspends SOC_THERM IP block
3144 * Note: This function should never be directly called because
3145 * it's not thread-safe. Instead, soctherm_suspend() should be called.
3146 * Performs SOC_THERM suspension. It will disable SOC_THERM device interrupts.
3147 * SOC_THERM will need to be reinitialized.
3150 static void soctherm_suspend_locked(void)
3152 if (!soctherm_suspended) {
3153 soctherm_writel((u32)-1, TH_INTR_DISABLE);
3154 soctherm_writel((u32)-1, OC_INTR_DISABLE);
3155 disable_irq(INT_THERMAL);
3156 disable_irq(INT_EDP);
3157 soctherm_init_platform_done = false;
3158 soctherm_suspended = true;
3159 /* soctherm_clk_enable(false);*/
3164 * soctherm_suspend() - Suspends the SOC_THERM device
3166 * Suspends SOC_THERM and prevents interrupts from occurring
3167 * and SOC_THERM from interrupting the CPU.
3169 * Return: 0 on success.
3171 static int soctherm_suspend(void)
3173 mutex_lock(&soctherm_suspend_resume_lock);
3174 soctherm_suspend_locked();
3175 mutex_unlock(&soctherm_suspend_resume_lock);
3180 * soctherm_resume_locked() - Resumes soctherm if it is suspended
3182 * Enables device interrupt generation for thermal and EDP when soctherm
3183 * platform initialization is done.
3185 static void soctherm_resume_locked(void)
3187 if (soctherm_suspended) {
3188 /* soctherm_clk_enable(true);*/
3189 soctherm_suspended = false;
3190 soctherm_init_platform_data();
3191 soctherm_init_platform_done = true;
3193 enable_irq(INT_THERMAL);
3194 enable_irq(INT_EDP);
3199 * soctherm_resume() - wrapper for soctherm_resume_locked()
3201 * Grabs the soctherm_suspend_resume_lock and then resumes SOC_THERM by running
3202 * soctherm_resume_locked().
3206 static int soctherm_resume(void)
3208 mutex_lock(&soctherm_suspend_resume_lock);
3209 soctherm_resume_locked();
3210 mutex_unlock(&soctherm_suspend_resume_lock);
3215 * soctherm_sync() - Syncs soctherm
3217 * If soctherm is suspended, reinitializes the SOC_THERM IP block registers
3218 * from the platform data and updates each zone. Otherwise only the
3221 static int soctherm_sync(void)
3223 mutex_lock(&soctherm_suspend_resume_lock);
3225 if (soctherm_suspended) {
3226 soctherm_resume_locked();
3227 soctherm_suspend_locked();
3232 mutex_unlock(&soctherm_suspend_resume_lock);
3235 late_initcall_sync(soctherm_sync);
3238 * soctherm_pm_suspend() - reacts to system PM suspend event
3239 * @nb: pointer to notifier_block. Currently not being used
3240 * @event: type of action (suspend/resume)
3241 * @data: argument for callback, currently not being used
3243 * Currently supports %PM_SUSPEND_PREPARE. Ignores %PM_POST_SUSPEND
3245 * Return: %NOTIFY_OK
3247 static int soctherm_pm_suspend(struct notifier_block *nb,
3248 unsigned long event, void *data)
3250 if (event == PM_SUSPEND_PREPARE) {
3252 pr_info("tegra_soctherm: suspended\n");
3258 * soctherm_pm_resume() - reacts to system PM resume event
3259 * @nb: pointer to notifier_block. Currently not being used
3260 * @event: type of action (suspend/resume)
3261 * @data: argument for callback, currently not being used
3263 * Currently supports %PM_POST_SUSPEND. Ignores %PM_SUSPEND_PREPARE
3265 * Return: %NOTIFY_OK
3267 static int soctherm_pm_resume(struct notifier_block *nb,
3268 unsigned long event, void *data)
3270 if (event == PM_POST_SUSPEND) {
3272 pr_info("tegra_soctherm: resumed\n");
3277 static struct notifier_block soctherm_suspend_nb = {
3278 .notifier_call = soctherm_pm_suspend,
3282 static struct notifier_block soctherm_resume_nb = {
3283 .notifier_call = soctherm_pm_resume,
3288 * soctherm_oc_irq_lock() - locks the over-current interrupt request
3289 * @data: Interrupt request data
3291 * Looks up the chip data from @data and locks the mutex associated with
3292 * a particular over-current interrupt request.
3294 static void soctherm_oc_irq_lock(struct irq_data *data)
3296 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3298 mutex_lock(&d->irq_lock);
3302 * soctherm_oc_irq_sync_unlock() - Unlocks the OC interrupt request
3303 * @data: Interrupt request data
3305 * Looks up the interrupt request data @data and unlocks the mutex associated
3306 * with a particular over-current interrupt request.
3308 static void soctherm_oc_irq_sync_unlock(struct irq_data *data)
3310 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3312 mutex_unlock(&d->irq_lock);
3316 * soctherm_oc_irq_enable() - Enables the SOC_THERM over-current interrupt queue
3317 * @data: irq_data structure of the chip
3319 * Sets the irq_enable bit of SOC_THERM allowing SOC_THERM
3320 * to respond to over-current interrupts.
3323 static void soctherm_oc_irq_enable(struct irq_data *data)
3325 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3327 d->irq_enable |= BIT(data->hwirq);
3331 * soctherm_oc_irq_disable() - Disables overcurrent interrupt requests
3332 * @irq_data: The interrupt request information
3334 * Clears the interrupt request enable bit of the overcurrent
3335 * interrupt request chip data.
3337 * Return: Nothing is returned (void)
3339 static void soctherm_oc_irq_disable(struct irq_data *data)
3341 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3343 d->irq_enable &= ~BIT(data->hwirq);
3346 static int soctherm_oc_irq_set_type(struct irq_data *data, unsigned int type)
3352 * soctherm_oc_irq_set_wake() - Set the overcurrent interrupt request
3354 * @irq_data: Interrupt request information
3355 * @on: Whether to enable or disable power management wakeup
3357 * Configure the GPIO associated with a SOC_THERM over-current
3358 * interrupt to wake the system from sleep
3360 * It may be necessary to wake the system from sleep mode so that
3361 * SOC_THERM can provide proper over-current throttling.
3363 * Return: 0 on success, -EINVAL if there is no wakeup support
3364 * for that given hardware irq, or the gpio number if there is
3365 * no gpio_to_irq for that gpio.
3367 static int soctherm_oc_irq_set_wake(struct irq_data *data, unsigned int on)
3372 gpio = soctherm_ocx_to_wake_gpio[data->hwirq];
3373 if (!gpio_is_valid(gpio)) {
3374 pr_err("No wakeup supported for irq %lu\n", data->hwirq);
3378 gpio_irq = gpio_to_irq(gpio);
3380 pr_err("No gpio_to_irq for gpio %d\n", gpio);
3384 irq_set_irq_wake(gpio_irq, on);
3389 * soctherm_oc_irq_map() - SOC_THERM interrupt request domain mapper
3390 * @h: Interrupt request domain
3391 * @virq: Virtual interrupt request number
3392 * @hw: Hardware interrupt request number
3394 * Mapping callback function for SOC_THERM's irq_domain. When a SOC_THERM
3395 * interrupt request is called, the irq_domain takes the request's virtual
3396 * request number (much like a virtual memory address) and maps it to a
3397 * physical hardware request number.
3399 * When a mapping doesn't already exist for a virtual request number, the
3400 * irq_domain calls this function to associate the virtual request number with
3401 * a hardware request number.
3405 static int soctherm_oc_irq_map(struct irq_domain *h, unsigned int virq,
3408 struct soctherm_oc_irq_chip_data *data = h->host_data;
3410 irq_set_chip_data(virq, data);
3411 irq_set_chip(virq, &data->irq_chip);
3412 irq_set_nested_thread(virq, 1);
3413 set_irq_flags(virq, IRQF_VALID);
3417 static struct irq_domain_ops soctherm_oc_domain_ops = {
3418 .map = soctherm_oc_irq_map,
3419 .xlate = irq_domain_xlate_twocell,
3423 * tegra11_soctherem_oc_int_init() - Initial enabling of the over
3424 * current interrupts
3425 * @irq_base: The interrupt request base number from platform data
3426 * @num_irqs: The number of new interrupt requests
3428 * Sets the over current interrupt request chip data
3430 * Return: 0 on success or if overcurrent interrupts are not enabled,
3431 * -ENOMEM (out of memory), or irq_base if the function failed to
3434 static int tegra11_soctherem_oc_int_init(int irq_base, int num_irqs)
3436 if (irq_base <= 0 || !num_irqs) {
3437 pr_info("%s(): OC interrupts are not enabled\n", __func__);
3441 mutex_init(&soc_irq_cdata.irq_lock);
3442 soc_irq_cdata.irq_enable = 0;
3444 soc_irq_cdata.irq_chip.name = "soc_therm_oc";
3445 soc_irq_cdata.irq_chip.irq_bus_lock = soctherm_oc_irq_lock,
3446 soc_irq_cdata.irq_chip.irq_bus_sync_unlock =
3447 soctherm_oc_irq_sync_unlock,
3448 soc_irq_cdata.irq_chip.irq_disable = soctherm_oc_irq_disable,
3449 soc_irq_cdata.irq_chip.irq_enable = soctherm_oc_irq_enable,
3450 soc_irq_cdata.irq_chip.irq_set_type = soctherm_oc_irq_set_type,
3451 soc_irq_cdata.irq_chip.irq_set_wake = soctherm_oc_irq_set_wake,
3453 irq_base = irq_alloc_descs(irq_base, 0, num_irqs, 0);
3455 pr_err("%s: Failed to allocate IRQs: %d\n", __func__, irq_base);
3459 soc_irq_cdata.domain = irq_domain_add_legacy(NULL, num_irqs,
3460 irq_base, 0, &soctherm_oc_domain_ops, &soc_irq_cdata);
3461 if (!soc_irq_cdata.domain) {
3462 pr_err("%s: Failed to create IRQ domain\n", __func__);
3465 pr_info("%s(): OC interrupts enabled successful\n", __func__);
3469 static int core_rail_regulator_notifier_cb(
3470 struct notifier_block *nb, unsigned long event, void *v)
3472 int uv = (int)((long)v);
3473 int rv = NOTIFY_DONE;
3474 int core_vmin_limit_uv;
3477 core_vmin_limit_uv = 900000;
3478 if (event & REGULATOR_EVENT_OUT_POSTCHANGE) {
3479 if (uv >= core_vmin_limit_uv) {
3480 tegra_soctherm_adjust_core_zone(true);
3483 } else if (event & REGULATOR_EVENT_OUT_PRECHANGE) {
3484 if (uv < core_vmin_limit_uv) {
3485 tegra_soctherm_adjust_core_zone(false);
3493 static int __init soctherm_core_rail_notify_init(void)
3496 static struct notifier_block vmin_condition_nb;
3498 vmin_condition_nb.notifier_call = core_rail_regulator_notifier_cb;
3499 ret = tegra_dvfs_rail_register_notifier(tegra_core_rail,
3500 &vmin_condition_nb);
3502 pr_err("%s: Failed to register core rail notifier\n",
3509 late_initcall_sync(soctherm_core_rail_notify_init);
3512 * tegra11_soctherm_init() - initializes SOC_THERM IP Block
3513 * @data: pointer to board-specific information
3515 * Initialize and enable SOC_THERM clocks, sanitize platform data, configure
3516 * SOC_THERM according to platform data, and set up interrupt handling for
3519 * Return: -1 if initialization failed, 0 otherwise
3521 int __init tegra11_soctherm_init(struct soctherm_platform_data *data)
3525 tegra_chip_id = tegra_get_chip_id();
3526 if (!(IS_T11X || IS_T14X || IS_T12X || IS_T13X)) {
3527 pr_err("%s: Unknown chip_id %d", __func__, tegra_chip_id);
3531 register_pm_notifier(&soctherm_suspend_nb);
3532 register_pm_notifier(&soctherm_resume_nb);
3538 if (soctherm_clk_init() < 0)
3541 if (soctherm_clk_enable(true) < 0)
3544 if (soctherm_init_platform_data() < 0)
3547 soctherm_init_platform_done = true;
3549 ret = tegra11_soctherem_oc_int_init(data->oc_irq_base,
3552 pr_err("soctherem_oc_int_init failed: %d\n", ret);
3556 if (request_threaded_irq(INT_THERMAL, soctherm_thermal_isr,
3557 soctherm_thermal_thread_func, IRQF_ONESHOT,
3558 "soctherm_thermal", NULL) < 0)
3561 if (request_threaded_irq(INT_EDP, soctherm_edp_isr,
3562 soctherm_edp_thread_func, IRQF_ONESHOT,
3563 "soctherm_edp", NULL) < 0)
3570 * tegra_soctherm_adjust_cpu_zone() - Adjusts the CPU zone of Tegra soctherm
3571 * @high_voltage_range: Flag indicating whether or not the system is
3572 * within the highest voltage range
3574 * If a particular VDD_CPU voltage threshold has been crossed (either up or
3575 * down), invokes soctherm_adjust_cpu_zone().
3576 * This function should be called by code outside this file when VDD_CPU crosses
3577 * a particular threshold.
3579 void tegra_soctherm_adjust_cpu_zone(bool high_voltage_range)
3581 if (!vdd_cpu_low_voltage != high_voltage_range) {
3582 vdd_cpu_low_voltage = !high_voltage_range;
3583 soctherm_adjust_zone(THERM_CPU);
3587 void tegra_soctherm_adjust_core_zone(bool high_voltage_range)
3589 if ((IS_T12X || IS_T13X)) {
3590 if (!vdd_core_low_voltage != high_voltage_range) {
3591 vdd_core_low_voltage = !high_voltage_range;
3592 soctherm_adjust_zone(THERM_GPU);
3593 soctherm_adjust_zone(THERM_MEM);
3598 #ifdef CONFIG_DEBUG_FS
3601 * regs_show() - show callback for regs debugfs
3602 * @s: seq_file for registers values to be written to
3603 * @data: a void pointer for callback, currently not being used
3605 * Gathers various register values and system status, then
3606 * formats and display the information as a debugfs virtual file.
3607 * This function allows easy access to debugging information.
3609 * Return: -1 if fail, 0 otherwise
3611 static int regs_show(struct seq_file *s, void *data)
3615 int tcpu[TSENSE_SIZE];
3620 seq_printf(s, "-----TSENSE (precision %s fuse %d convert %s)-----\n",
3621 PRECISION_TO_STR(), tegra_fuse_calib_base_get_cp(NULL, NULL),
3622 read_hw_temp ? "HW" : "SW");
3624 if (soctherm_suspended) {
3625 seq_puts(s, "SOC_THERM is SUSPENDED\n");
3629 for (i = 0; i < TSENSE_SIZE; i++) {
3630 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG1, i));
3631 state = REG_GET(r, TS_CPU0_CONFIG1_EN);
3635 seq_printf(s, "%s: ", sensor_names[i]);
3637 seq_printf(s, "En(%d) ", state);
3638 state = REG_GET(r, TS_CPU0_CONFIG1_TIDDQ);
3639 seq_printf(s, "tiddq(%d) ", state);
3640 state = REG_GET(r, TS_CPU0_CONFIG1_TEN_COUNT);
3641 seq_printf(s, "ten_count(%d) ", state);
3642 state = REG_GET(r, TS_CPU0_CONFIG1_TSAMPLE);
3643 seq_printf(s, "tsample(%d) ", state + 1);
3645 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_STATUS1, i));
3646 state = REG_GET(r, TS_CPU0_STATUS1_TEMP_VALID);
3647 seq_printf(s, "Temp(%d/", state);
3648 state = REG_GET(r, TS_CPU0_STATUS1_TEMP);
3649 seq_printf(s, "%d) ", tcpu[i] = temp_translate(state));
3651 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_STATUS0, i));
3652 state = REG_GET(r, TS_CPU0_STATUS0_VALID);
3653 seq_printf(s, "Capture(%d/", state);
3654 state = REG_GET(r, TS_CPU0_STATUS0_CAPTURE);
3655 seq_printf(s, "%d) (Converted-temp(%ld) ", state,
3656 temp_convert(state, sensor2therm_a[i],
3657 sensor2therm_b[i]));
3659 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG0, i));
3660 state = REG_GET(r, TS_CPU0_CONFIG0_STOP);
3661 seq_printf(s, "Stop(%d) ", state);
3662 state = REG_GET(r, TS_CPU0_CONFIG0_TALL);
3663 seq_printf(s, "Tall(%d) ", state);
3664 state = REG_GET(r, TS_CPU0_CONFIG0_TCALC_OVER);
3665 seq_printf(s, "Over(%d/", state);
3666 state = REG_GET(r, TS_CPU0_CONFIG0_OVER);
3667 seq_printf(s, "%d/", state);
3668 state = REG_GET(r, TS_CPU0_CONFIG0_CPTR_OVER);
3669 seq_printf(s, "%d) ", state);
3671 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG2, i));
3672 state = REG_GET(r, TS_CPU0_CONFIG2_THERM_A);
3673 seq_printf(s, "Therm_A/B(%d/", state);
3674 state = REG_GET(r, TS_CPU0_CONFIG2_THERM_B);
3675 seq_printf(s, "%d)\n", (s16)state);
3678 r = soctherm_readl(TS_PDIV);
3679 seq_printf(s, "PDIV: 0x%x\n", r);
3682 seq_puts(s, "-----SOC_THERM-----\n");
3684 r = soctherm_readl(TS_TEMP1);
3685 state = REG_GET(r, TS_TEMP1_CPU_TEMP);
3686 seq_printf(s, "Temperatures: CPU(%ld) ", temp_translate(state));
3687 state = REG_GET(r, TS_TEMP1_GPU_TEMP);
3688 seq_printf(s, " GPU(%ld) ", temp_translate(state));
3689 r = soctherm_readl(TS_TEMP2);
3690 state = REG_GET(r, TS_TEMP2_PLLX_TEMP);
3691 seq_printf(s, " PLLX(%ld) ", temp_translate(state));
3692 state = REG_GET(r, TS_TEMP2_MEM_TEMP);
3693 seq_printf(s, " MEM(%ld)\n", temp_translate(state));
3695 for (i = 0; i < THERM_SIZE; i++) {
3696 seq_printf(s, "%s:\n", therm_names[i]);
3697 for (level = 0; level < 4; level++) {
3698 r = soctherm_readl(TS_THERM_REG_OFFSET(CTL_LVL0_CPU0,
3700 state = REG_GET(r, CTL_LVL0_CPU0_UP_THRESH);
3701 seq_printf(s, " %d: Up/Dn(%d/", level,
3702 LOWER_PRECISION_FOR_CONV(state));
3703 state = REG_GET(r, CTL_LVL0_CPU0_DN_THRESH);
3704 seq_printf(s, "%d) ", LOWER_PRECISION_FOR_CONV(state));
3705 state = REG_GET(r, CTL_LVL0_CPU0_EN);
3706 seq_printf(s, "En(%d) ", state);
3708 state = REG_GET(r, CTL_LVL0_CPU0_CPU_THROT);
3709 seq_puts(s, "CPU Throt");
3710 seq_printf(s, "(%s) ", state ?
3711 state == CTL_LVL0_CPU0_CPU_THROT_LIGHT ? "L" :
3712 state == CTL_LVL0_CPU0_CPU_THROT_HEAVY ? "H" :
3715 state = REG_GET(r, CTL_LVL0_CPU0_GPU_THROT);
3716 seq_puts(s, "GPU Throt");
3717 seq_printf(s, "(%s) ", state ?
3718 state == CTL_LVL0_CPU0_GPU_THROT_LIGHT ? "L" :
3719 state == CTL_LVL0_CPU0_GPU_THROT_HEAVY ? "H" :
3722 state = REG_GET(r, CTL_LVL0_CPU0_STATUS);
3723 seq_printf(s, "Status(%s)\n",
3726 state == 2 ? "??" : "HI");
3730 r = soctherm_readl(STATS_CTL);
3731 seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
3732 r & STATS_CTL_EN_UP ? "En" : "--",
3733 r & STATS_CTL_EN_DN ? "En" : "--");
3734 for (level = 0; level < 4; level++) {
3735 r = soctherm_readl(TS_TSENSE_REG_OFFSET(UP_STATS_L0, level));
3736 seq_printf(s, " Level_%d Up(%d) ", level, r);
3737 r = soctherm_readl(TS_TSENSE_REG_OFFSET(DN_STATS_L0, level));
3738 seq_printf(s, "Dn(%d)\n", r);
3741 r = soctherm_readl(THERMTRIP);
3742 state = REG_GET(r, THERMTRIP_ANY_EN);
3743 seq_printf(s, "ThermTRIP ANY En(%d)\n", state);
3745 state = REG_GET(r, THERMTRIP_CPU_EN);
3746 seq_printf(s, " CPU En(%d) ", state);
3747 state = REG_GET(r, THERMTRIP_CPU_THRESH);
3748 seq_printf(s, "Thresh(%d)\n", LOWER_PRECISION_FOR_CONV(state));
3750 state = REG_GET(r, THERMTRIP_GPU_EN);
3751 seq_printf(s, " GPU En(%d) ", state);
3752 state = REG_GET(r, THERMTRIP_GPUMEM_THRESH);
3753 seq_printf(s, "Thresh(%d)\n", LOWER_PRECISION_FOR_CONV(state));
3755 state = REG_GET(r, THERMTRIP_MEM_EN);
3756 seq_printf(s, " MEM En(%d) ", state);
3757 state = REG_GET(r, THERMTRIP_GPUMEM_THRESH);
3758 seq_printf(s, "Thresh(%d)\n", LOWER_PRECISION_FOR_CONV(state));
3760 state = REG_GET(r, THERMTRIP_TSENSE_EN);
3761 seq_printf(s, " PLLX En(%d) ", state);
3762 state = REG_GET(r, THERMTRIP_TSENSE_THRESH);
3763 seq_printf(s, "Thresh(%d)\n", LOWER_PRECISION_FOR_CONV(state));
3765 r = soctherm_readl(THROT_GLOBAL_CFG);
3766 seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
3768 seq_puts(s, "---------------------------------------------------\n");
3769 r = soctherm_readl(THROT_STATUS);
3770 state = REG_GET(r, THROT_STATUS_BREACH);
3771 seq_printf(s, "THROT STATUS: breach(%d) ", state);
3772 state = REG_GET(r, THROT_STATUS_STATE);
3773 seq_printf(s, "state(%d) ", state);
3774 state = REG_GET(r, THROT_STATUS_ENABLED);
3775 seq_printf(s, "enabled(%d)\n", state);
3777 r = soctherm_readl(CPU_PSKIP_STATUS);
3779 state = REG_GET(r, XPU_PSKIP_STATUS_ENABLED);
3780 seq_printf(s, "%s PSKIP STATUS: ",
3781 throt_dev_names[THROTTLE_DEV_CPU]);
3782 seq_printf(s, "enabled(%d)\n", state);
3784 state = REG_GET(r, XPU_PSKIP_STATUS_M);
3785 seq_printf(s, "%s PSKIP STATUS: M(%d) ",
3786 throt_dev_names[THROTTLE_DEV_CPU], state);
3787 state = REG_GET(r, XPU_PSKIP_STATUS_N);
3788 seq_printf(s, "N(%d) ", state);
3789 state = REG_GET(r, XPU_PSKIP_STATUS_ENABLED);
3790 seq_printf(s, "enabled(%d)\n", state);
3793 r = soctherm_readl(GPU_PSKIP_STATUS);
3794 if ((IS_T12X || IS_T13X)) {
3795 state = REG_GET(r, XPU_PSKIP_STATUS_ENABLED);
3796 seq_printf(s, "%s PSKIP STATUS: ",
3797 throt_dev_names[THROTTLE_DEV_GPU]);
3798 seq_printf(s, "enabled(%d)\n", state);
3800 state = REG_GET(r, XPU_PSKIP_STATUS_M);
3801 seq_printf(s, "%s PSKIP STATUS: M(%d) ",
3802 throt_dev_names[THROTTLE_DEV_GPU], state);
3803 state = REG_GET(r, XPU_PSKIP_STATUS_N);
3804 seq_printf(s, "N(%d) ", state);
3805 state = REG_GET(r, XPU_PSKIP_STATUS_ENABLED);
3806 seq_printf(s, "enabled(%d)\n", state);
3809 seq_puts(s, "---------------------------------------------------\n");
3810 seq_puts(s, "THROTTLE control and PSKIP configuration:\n");
3811 seq_printf(s, "%5s %3s %2s %7s %8s %7s %8s %4s %4s %5s ",
3812 "throt", "dev", "en", " depth ", "dividend", "divisor",
3813 "duration", "step", "prio", "delay");
3814 seq_printf(s, "%2s %2s %2s %2s %2s %2s ",
3815 "LL", "HW", "PG", "MD", "01", "EN");
3816 seq_printf(s, "%8s %8s %8s %8s %8s\n",
3817 "thresh", "period", "count", "filter", "stats");
3819 /* display throttle_cfg's of all alarms including OC5 */
3820 for (i = 0; i < THROTTLE_SIZE; i++) {
3821 for (j = 0; j < THROTTLE_DEV_SIZE; j++) {
3822 r = soctherm_readl(THROT_PSKIP_CTRL(i, j));
3823 state = REG_GET(r, THROT_PSKIP_CTRL_ENABLE);
3824 seq_printf(s, "%5s %3s %2d ",
3825 j ? "" : throt_names[i],
3826 throt_dev_names[j], state);
3832 level = THROT_LEVEL_NONE; /* invalid */
3835 if (IS_T13X && j == THROTTLE_DEV_CPU) {
3836 state = REG_GET(r, THROT_PSKIP_CTRL_VECT_CPU);
3837 if (state == THROT_VECT_HVY) {
3838 level = THROT_LEVEL_HVY;
3840 } else if (state == THROT_VECT_MED) {
3841 level = THROT_LEVEL_MED;
3843 } else if (state == THROT_VECT_LOW) {
3844 level = THROT_LEVEL_LOW;
3848 if ((IS_T12X || IS_T13X) && j == THROTTLE_DEV_GPU) {
3849 state = REG_GET(r, THROT_PSKIP_CTRL_VECT_GPU);
3850 /* Mapping is hard-coded in gk20a:nv_therm */
3851 if (state == THROT_VECT_HVY) {
3854 } else if (state == THROT_VECT_MED) {
3857 } else if (state == THROT_VECT_LOW) {
3863 if (level == THROT_LEVEL_NONE)
3865 else if (IS_T13X && j == THROTTLE_DEV_CPU)
3866 r = clk_reset13_readl(
3867 THROT13_PSKIP_CTRL_CPU(level));
3869 r = soctherm_readl(THROT_PSKIP_CTRL(i, j));
3871 m = REG_GET(r, THROT_PSKIP_CTRL_DIVIDEND);
3872 n = REG_GET(r, THROT_PSKIP_CTRL_DIVISOR);
3873 q = q ?: 100 - (((100 * (m+1)) + ((n+1) / 2)) / (n+1));
3874 seq_printf(s, "%2u%% %3s ", q, depth);
3875 seq_printf(s, "%8u ", m);
3876 seq_printf(s, "%7u ", n);
3878 if (IS_T13X && j == THROTTLE_DEV_CPU)
3879 r = clk_reset13_readl(
3880 THROT13_PSKIP_RAMP_CPU(level));
3882 r = soctherm_readl(THROT_PSKIP_RAMP(i, j));
3884 state = REG_GET(r, THROT_PSKIP_RAMP_DURATION);
3885 seq_printf(s, "%8d ", state);
3886 state = REG_GET(r, THROT_PSKIP_RAMP_STEP);
3887 seq_printf(s, "%4d ", state);
3889 r = soctherm_readl(THROT_PRIORITY_CTRL(i));
3890 state = REG_GET(r, THROT_PRIORITY_LITE_PRIO);
3891 seq_printf(s, "%4d ", state);
3893 r = soctherm_readl(THROT_DELAY_CTRL(i));
3894 state = REG_GET(r, THROT_DELAY_LITE_DELAY);
3895 seq_printf(s, "%5d ", state);
3897 if (i >= THROTTLE_OC1) {
3898 r = soctherm_readl(ALARM_CFG(i));
3899 state = REG_GET(r, OC1_CFG_LONG_LATENCY);
3900 seq_printf(s, "%2d ", state);
3901 state = REG_GET(r, OC1_CFG_HW_RESTORE);
3902 seq_printf(s, "%2d ", state);
3903 state = REG_GET(r, OC1_CFG_PWR_GOOD_MASK);
3904 seq_printf(s, "%2d ", state);
3905 state = REG_GET(r, OC1_CFG_THROTTLE_MODE);
3906 seq_printf(s, "%2d ", state);
3907 state = REG_GET(r, OC1_CFG_ALARM_POLARITY);
3908 seq_printf(s, "%2d ", state);
3909 state = REG_GET(r, OC1_CFG_EN_THROTTLE);
3910 seq_printf(s, "%2d ", state);
3912 r = soctherm_readl(ALARM_CNT_THRESHOLD(i));
3913 seq_printf(s, "%8d ", r);
3914 r = soctherm_readl(ALARM_THROTTLE_PERIOD(i));
3915 seq_printf(s, "%8d ", r);
3916 r = soctherm_readl(ALARM_ALARM_COUNT(i));
3917 seq_printf(s, "%8d ", r);
3918 r = soctherm_readl(ALARM_FILTER(i));
3919 seq_printf(s, "%8d ", r);
3920 r = soctherm_readl(ALARM_STATS(i));
3921 seq_printf(s, "%8d ", r);
3930 * temp_log_show() - "show" callback for temp_log debugfs node
3931 * @s: pointer to the seq_file record to write the log through
3934 * The temperature log contains the time (seconds.nanoseconds), and the
3935 * temperature of each of the thermal sensors, if there is a valid temperature
3936 * capture available. Makes sure that SOC_THERM is left in the same state in
3937 * which it was previously (suspended/resumed).
3941 static int temp_log_show(struct seq_file *s, void *data)
3947 bool was_suspended = false;
3950 ns = do_div(ts, 1000000000);
3951 seq_printf(s, "%6lu.%06lu", (u_long) ts, ns / 1000);
3953 if (soctherm_suspended) {
3954 mutex_lock(&soctherm_suspend_resume_lock);
3955 soctherm_resume_locked();
3956 was_suspended = true;
3959 for (i = 0; i < TSENSE_SIZE; i++) {
3960 r = soctherm_readl(TS_TSENSE_REG_OFFSET(
3961 TS_CPU0_CONFIG1, i));
3962 state = REG_GET(r, TS_CPU0_CONFIG1_EN);
3966 r = soctherm_readl(TS_TSENSE_REG_OFFSET(
3967 TS_CPU0_STATUS1, i));
3968 if (!REG_GET(r, TS_CPU0_STATUS1_TEMP_VALID)) {
3969 seq_puts(s, "\tINVALID");
3974 state = REG_GET(r, TS_CPU0_STATUS1_TEMP);
3975 seq_printf(s, "\t%ld", temp_translate(state));
3977 r = soctherm_readl(TS_TSENSE_REG_OFFSET(
3978 TS_CPU0_STATUS0, i));
3979 state = REG_GET(r, TS_CPU0_STATUS0_CAPTURE);
3980 seq_printf(s, "\t%ld",
3981 temp_convert(state, sensor2therm_a[i],
3982 sensor2therm_b[i]));
3987 if (was_suspended) {
3988 soctherm_suspend_locked();
3989 mutex_unlock(&soctherm_suspend_resume_lock);
3995 * regs_open() - wraps single_open to associate internal regs_show()
3996 * @inode: inode related to the file
3997 * @file: pointer to a file to be manipulated with single_open
3999 * Return: Passes along the return value from single_open().
4001 static int regs_open(struct inode *inode, struct file *file)
4003 return single_open(file, regs_show, inode->i_private);
4006 static const struct file_operations regs_fops = {
4009 .llseek = seq_lseek,
4010 .release = single_release,
4014 * convert_get() - indicates software or hardware temperature conversion
4015 * @data: argument for callback, currently not being used
4016 * @val: pointer to a u64 location to store flag value
4018 * Stores boolean flag into memory address pointed to by val.
4019 * The flag indicates whether SOC_THERM is using
4020 * software or hardware temperature conversion.
4024 static int convert_get(void *data, u64 *val)
4026 *val = !read_hw_temp;
4030 * convert_set() - Sets a flag indicating which temperature is
4032 * @data: Opaque pointer to data passed in from filesystem layer
4033 * @val: The flag value
4035 * Sets the read_hw_temp file static flag. This flag indicates whether
4036 * the hardware temperature or the software temperature is being
4039 * Return: 0 on success.
4041 static int convert_set(void *data, u64 val)
4043 read_hw_temp = !val;
4048 * cputemp_get() - gets the CPU temperature.
4050 * @val: a pointer in which the temperature will be placed.
4052 * Reads the temperature of the thermal sensor associated with the CPU.
4056 static int cputemp_get(void *data, u64 *val)
4060 reg = soctherm_readl(TS_TEMP1);
4061 *val = temp_translate(REG_GET(reg, TS_TEMP1_CPU_TEMP));
4066 * cputemp_set() - Puts a particular value into the CPU temperature register
4067 * @data: The pointer to data. Currently not being used.
4068 * @temp: The temperature to be written to the register
4070 * This function only works if temperature overrides have been enabled.
4071 * Clears the original register CPU temperature, converts the given
4072 * temperature to a register value, and writes it to the CPU temp register.
4075 * Return: 0 (success).
4077 static int cputemp_set(void *data, u64 temp)
4079 u32 reg_val = temp_translate_rev(temp);
4080 u32 reg_orig = soctherm_readl(TS_TEMP1);
4082 reg_val = (reg_val << 16) | (reg_orig & 0xffff);
4083 soctherm_writel(reg_val, TS_TEMP1);
4088 * gputemp_get() - retrieve GPU temperature from its register
4089 * @data: argument for callback, currently not being used
4090 * @val: pointer to a u64 location to store GPU temperature value
4092 * Reads register value associated with the temperature sensor for the GPU
4093 * and stores it in the memory address pointed by val.
4097 static int gputemp_get(void *data, u64 *val)
4101 reg = soctherm_readl(TS_TEMP1);
4102 *val = temp_translate(REG_GET(reg, TS_TEMP1_GPU_TEMP));
4107 * gputemp_set() - Puts a particular value into the GPU temperature register
4108 * @data: The pointer to data. Currently not being used.
4109 * @temp: The temperature to be written to the register
4111 * This function only works if temperature overrides have been enabled.
4112 * Clears the original GPU temperature register, converts the given
4113 * temperature to a register value, and writes it to the GPU temp register.
4114 * The @temp needs to be in the units of the SOC_THERM register temperature
4118 * Return: 0 (success).
4120 static int gputemp_set(void *data, u64 temp)
4122 u32 reg_val = temp_translate_rev(temp);
4123 u32 reg_orig = soctherm_readl(TS_TEMP1);
4125 reg_val = reg_val | (reg_orig & 0xffff0000);
4126 soctherm_writel(reg_val, TS_TEMP1);
4131 * memtemp_get() - gets the memory temperature.
4133 * @val: a pointer in which the temperature will be placed.
4135 * Reads the temperature of the thermal sensor associated with the memory.
4139 static int memtemp_get(void *data, u64 *val)
4143 reg = soctherm_readl(TS_TEMP2);
4144 *val = temp_translate(REG_GET(reg, TS_TEMP2_MEM_TEMP));
4149 * memtemp_set() - Overrides the memory temperature
4151 * @data: Opaque pointer to data; not used
4152 * @temp: The temperature to be written to the register
4154 * Clears the memory temperature register, converts @temp to
4155 * a register value, and writes the converted value to the register
4157 * Function only works when temperature overrides are enabled.
4159 * This function is called to debug/test temperature
4160 * trip points regarding MEM temperatures
4162 * Return: 0 on success.
4164 static int memtemp_set(void *data, u64 temp)
4166 u32 reg_val = temp_translate_rev(temp);
4167 u32 reg_orig = soctherm_readl(TS_TEMP2);
4169 reg_val = (reg_val << 16) | (reg_orig & 0xffff);
4170 soctherm_writel(reg_val, TS_TEMP2);
4175 * plltemp_get() - Gets the phase-locked loop temperature.
4176 * @data: Opaque pointer to data
4177 * @val: The pll temperature
4179 * The temperature value is read in from the register.
4180 * The variable pointed to by @val is set to this temperature value.
4182 * This function is used in debugfs
4184 * Return: 0 on success.
4186 static int plltemp_get(void *data, u64 *val)
4190 reg = soctherm_readl(TS_TEMP2);
4191 *val = temp_translate(REG_GET(reg, TS_TEMP2_PLLX_TEMP));
4197 * plltemp_set() - Stores a particular value into the PLLX temperature register
4198 * @data: The pointer to data. Currently not being used.
4199 * @temp: The temperature to be written to the register
4201 * This function only works if temperature overrides have been enabled.
4202 * Clears the original PLLX temperature register, converts the given
4203 * temperature to a register value, and writes it to the PLLX temp register.
4206 * Return: 0 (success).
4208 static int plltemp_set(void *data, u64 temp)
4210 u32 reg_val = temp_translate_rev(temp);
4211 u32 reg_orig = soctherm_readl(TS_TEMP2);
4213 reg_val = reg_val | (reg_orig & 0xffff0000);
4214 soctherm_writel(reg_val, TS_TEMP2);
4219 * tempoverride_get() - gets the temperature sensor software override value
4221 * @val: a pointer in which the value will be placed.
4223 * Gets whether software override of the temperature is enabled. If it is
4224 * then TSENSOR_TEMP1/TSENSOR_TEMP2 will be set by the tsense block. If not,
4225 * then software will have to set it.
4229 static int tempoverride_get(void *data, u64 *val)
4231 *val = soctherm_readl(TS_TEMP_SW_OVERRIDE);
4236 * tempoverride_set() - enables or disables software temperature override
4237 * @data: argument for callback, currently not being used
4238 * @val: val should be 1 to enable override. 0 to disable override
4240 * For debugging purposes, this function allows or disallow software
4241 * to override temperature reading. This is useful when testing how SOC_THERM
4242 * reacts to different temperature.
4246 static int tempoverride_set(void *data, u64 val)
4248 soctherm_writel(val, TS_TEMP_SW_OVERRIDE);
4252 DEFINE_SIMPLE_ATTRIBUTE(convert_fops, convert_get, convert_set, "%llu\n");
4253 DEFINE_SIMPLE_ATTRIBUTE(cputemp_fops, cputemp_get, cputemp_set, "%llu\n");
4254 DEFINE_SIMPLE_ATTRIBUTE(gputemp_fops, gputemp_get, gputemp_set, "%llu\n");
4255 DEFINE_SIMPLE_ATTRIBUTE(memtemp_fops, memtemp_get, memtemp_set, "%llu\n");
4256 DEFINE_SIMPLE_ATTRIBUTE(plltemp_fops, plltemp_get, plltemp_set, "%llu\n");
4257 DEFINE_SIMPLE_ATTRIBUTE(tempoverride_fops, tempoverride_get, tempoverride_set,
4260 static int temp_log_open(struct inode *inode, struct file *file)
4262 return single_open(file, temp_log_show, inode->i_private);
4265 static const struct file_operations temp_log_fops = {
4266 .open = temp_log_open,
4268 .llseek = seq_lseek,
4269 .release = single_release,
4273 * soctherm_debug_init() - initializes the SOC_THERM debugfs files
4275 * Creates a tegra_soctherm directory in debugfs, then creates all of the
4276 * debugfs files, setting the functions that are called when each respective
4277 * file is read or written.
4281 static int __init soctherm_debug_init(void)
4283 struct dentry *tegra_soctherm_root;
4285 tegra_soctherm_root = debugfs_create_dir("tegra_soctherm", NULL);
4286 debugfs_create_file("regs", 0644, tegra_soctherm_root,
4288 debugfs_create_file("convert", 0644, tegra_soctherm_root,
4289 NULL, &convert_fops);
4290 debugfs_create_file("cputemp", 0644, tegra_soctherm_root,
4291 NULL, &cputemp_fops);
4292 debugfs_create_file("gputemp", 0644, tegra_soctherm_root,
4293 NULL, &gputemp_fops);
4294 debugfs_create_file("memtemp", 0644, tegra_soctherm_root,
4295 NULL, &memtemp_fops);
4296 debugfs_create_file("plltemp", 0644, tegra_soctherm_root,
4297 NULL, &plltemp_fops);
4298 debugfs_create_file("tempoverride", 0644, tegra_soctherm_root,
4299 NULL, &tempoverride_fops);
4300 debugfs_create_file("temp_log", 0644, tegra_soctherm_root,
4301 NULL, &temp_log_fops);
4304 late_initcall(soctherm_debug_init);