2 * arch/arm/mach-tegra/tegra11_soctherm.c
4 * Copyright (c) 2011-2013, 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>
40 #include <mach/tegra_fuse.h>
43 #include "tegra3_tsensor.h"
45 #include "tegra11_soctherm.h"
46 #include "gpio-names.h"
48 /* Min temp granularity specified as X in 2^X.
49 * -1: Hi precision option: 2^-1 = 0.5C
50 * 0: Lo precision option: 2^0 = 1.0C
51 * NB: We must use lower precision (0) due to cp_fuse corrections
52 * (see Sec9.2 T35_Thermal_Sensing_IAS.docx)
54 static const int precision; /* default 0 -> low precision */
55 #define LOWER_PRECISION_FOR_CONV(val) ((!precision) ? ((val)*2) : (val))
56 #define LOWER_PRECISION_FOR_TEMP(val) ((!precision) ? ((val)/2) : (val))
57 #define PRECISION_IS_LOWER() ((!precision))
58 #define PRECISION_TO_STR() ((!precision) ? "Lo" : "Hi")
60 #define TS_TSENSE_REGS_SIZE 0x20
61 #define TS_TSENSE_REG_OFFSET(reg, ts) ((reg) + ((ts) * TS_TSENSE_REGS_SIZE))
63 #define TS_THERM_LVL_REGS_SIZE 0x20
64 #define TS_THERM_GRP_REGS_SIZE 0x04
65 #define TS_THERM_REG_OFFSET(rg, lv, gr) ((rg) + ((lv) * TS_THERM_LVL_REGS_SIZE)\
66 + ((gr) * TS_THERM_GRP_REGS_SIZE))
68 #define CTL_LVL0_CPU0 0x0
69 #define CTL_LVL0_CPU0_UP_THRESH_SHIFT 17
70 #define CTL_LVL0_CPU0_UP_THRESH_MASK 0xff
71 #define CTL_LVL0_CPU0_DN_THRESH_SHIFT 9
72 #define CTL_LVL0_CPU0_DN_THRESH_MASK 0xff
73 #define CTL_LVL0_CPU0_EN_SHIFT 8
74 #define CTL_LVL0_CPU0_EN_MASK 0x1
75 #define CTL_LVL0_CPU0_CPU_THROT_SHIFT 5
76 #define CTL_LVL0_CPU0_CPU_THROT_MASK 0x3
77 #define CTL_LVL0_CPU0_CPU_THROT_LIGHT 0x1
78 #define CTL_LVL0_CPU0_CPU_THROT_HEAVY 0x2
79 #define CTL_LVL0_CPU0_MEM_THROT_SHIFT 2
80 #define CTL_LVL0_CPU0_MEM_THROT_MASK 0x1
81 #define CTL_LVL0_CPU0_STATUS_SHIFT 0
82 #define CTL_LVL0_CPU0_STATUS_MASK 0x3
84 #define THERMTRIP 0x80
85 #define THERMTRIP_ANY_EN_SHIFT 28
86 #define THERMTRIP_ANY_EN_MASK 0x1
87 #define THERMTRIP_MEM_EN_SHIFT 27
88 #define THERMTRIP_MEM_EN_MASK 0x1
89 #define THERMTRIP_GPU_EN_SHIFT 26
90 #define THERMTRIP_GPU_EN_MASK 0x1
91 #define THERMTRIP_CPU_EN_SHIFT 25
92 #define THERMTRIP_CPU_EN_MASK 0x1
93 #define THERMTRIP_TSENSE_EN_SHIFT 24
94 #define THERMTRIP_TSENSE_EN_MASK 0x1
95 #define THERMTRIP_GPUMEM_THRESH_SHIFT 16
96 #define THERMTRIP_GPUMEM_THRESH_MASK 0xff
97 #define THERMTRIP_CPU_THRESH_SHIFT 8
98 #define THERMTRIP_CPU_THRESH_MASK 0xff
99 #define THERMTRIP_TSENSE_THRESH_SHIFT 0
100 #define THERMTRIP_TSENSE_THRESH_MASK 0xff
102 #define TS_CPU0_CONFIG0 0xc0
103 #define TS_CPU0_CONFIG0_TALL_SHIFT 8
104 #define TS_CPU0_CONFIG0_TALL_MASK 0xfffff
105 #define TS_CPU0_CONFIG0_TCALC_OVER_SHIFT 4
106 #define TS_CPU0_CONFIG0_TCALC_OVER_MASK 0x1
107 #define TS_CPU0_CONFIG0_OVER_SHIFT 3
108 #define TS_CPU0_CONFIG0_OVER_MASK 0x1
109 #define TS_CPU0_CONFIG0_CPTR_OVER_SHIFT 2
110 #define TS_CPU0_CONFIG0_CPTR_OVER_MASK 0x1
111 #define TS_CPU0_CONFIG0_STOP_SHIFT 0
112 #define TS_CPU0_CONFIG0_STOP_MASK 0x1
114 #define TS_CPU0_CONFIG1 0xc4
115 #define TS_CPU0_CONFIG1_EN_SHIFT 31
116 #define TS_CPU0_CONFIG1_EN_MASK 0x1
117 #define TS_CPU0_CONFIG1_TIDDQ_SHIFT 15
118 #define TS_CPU0_CONFIG1_TIDDQ_MASK 0x3f
119 #define TS_CPU0_CONFIG1_TEN_COUNT_SHIFT 24
120 #define TS_CPU0_CONFIG1_TEN_COUNT_MASK 0x3f
121 #define TS_CPU0_CONFIG1_TSAMPLE_SHIFT 0
122 #define TS_CPU0_CONFIG1_TSAMPLE_MASK 0x3ff
124 #define TS_CPU0_CONFIG2 0xc8
125 #define TS_CPU0_CONFIG2_THERM_A_SHIFT 16
126 #define TS_CPU0_CONFIG2_THERM_A_MASK 0xffff
127 #define TS_CPU0_CONFIG2_THERM_B_SHIFT 0
128 #define TS_CPU0_CONFIG2_THERM_B_MASK 0xffff
130 #define TS_CPU0_STATUS0 0xcc
131 #define TS_CPU0_STATUS0_VALID_SHIFT 31
132 #define TS_CPU0_STATUS0_VALID_MASK 0x1
133 #define TS_CPU0_STATUS0_CAPTURE_SHIFT 0
134 #define TS_CPU0_STATUS0_CAPTURE_MASK 0xffff
136 #define TS_CPU0_STATUS1 0xd0
137 #define TS_CPU0_STATUS1_TEMP_VALID_SHIFT 31
138 #define TS_CPU0_STATUS1_TEMP_VALID_MASK 0x1
139 #define TS_CPU0_STATUS1_TEMP_SHIFT 0
140 #define TS_CPU0_STATUS1_TEMP_MASK 0xffff
142 #define TS_CPU0_STATUS2 0xd4
144 #define TS_PDIV 0x1c0
145 #define TS_PDIV_CPU_SHIFT 12
146 #define TS_PDIV_CPU_MASK 0xf
147 #define TS_PDIV_GPU_SHIFT 8
148 #define TS_PDIV_GPU_MASK 0xf
149 #define TS_PDIV_MEM_SHIFT 4
150 #define TS_PDIV_MEM_MASK 0xf
151 #define TS_PDIV_PLLX_SHIFT 0
152 #define TS_PDIV_PLLX_MASK 0xf
154 #define TS_HOTSPOT_OFF 0x1c4
155 #define TS_HOTSPOT_OFF_CPU_SHIFT 16
156 #define TS_HOTSPOT_OFF_CPU_MASK 0xff
157 #define TS_HOTSPOT_OFF_GPU_SHIFT 8
158 #define TS_HOTSPOT_OFF_GPU_MASK 0xff
159 #define TS_HOTSPOT_OFF_MEM_SHIFT 0
160 #define TS_HOTSPOT_OFF_MEM_MASK 0xff
162 #define TS_TEMP1 0x1c8
163 #define TS_TEMP1_CPU_TEMP_SHIFT 16
164 #define TS_TEMP1_CPU_TEMP_MASK 0xffff
165 #define TS_TEMP1_GPU_TEMP_SHIFT 0
166 #define TS_TEMP1_GPU_TEMP_MASK 0xffff
168 #define TS_TEMP2 0x1cc
169 #define TS_TEMP2_MEM_TEMP_SHIFT 16
170 #define TS_TEMP2_MEM_TEMP_MASK 0xffff
171 #define TS_TEMP2_PLLX_TEMP_SHIFT 0
172 #define TS_TEMP2_PLLX_TEMP_MASK 0xffff
174 #define TH_INTR_STATUS 0x84
175 #define TH_INTR_ENABLE 0x88
176 #define TH_INTR_DISABLE 0x8c
178 #define LOCK_CTL 0x90
180 #define TH_INTR_POS_MD3_SHIFT 31
181 #define TH_INTR_POS_MD3_MASK 0x1
182 #define TH_INTR_POS_MU3_SHIFT 30
183 #define TH_INTR_POS_MU3_MASK 0x1
184 #define TH_INTR_POS_MD2_SHIFT 29
185 #define TH_INTR_POS_MD2_MASK 0x1
186 #define TH_INTR_POS_MU2_SHIFT 28
187 #define TH_INTR_POS_MU2_MASK 0x1
188 #define TH_INTR_POS_MD1_SHIFT 27
189 #define TH_INTR_POS_MD1_MASK 0x1
190 #define TH_INTR_POS_MU1_SHIFT 26
191 #define TH_INTR_POS_MU1_MASK 0x1
192 #define TH_INTR_POS_MD0_SHIFT 25
193 #define TH_INTR_POS_MD0_MASK 0x1
194 #define TH_INTR_POS_MU0_SHIFT 24
195 #define TH_INTR_POS_MU0_MASK 0x1
196 #define TH_INTR_POS_GD3_SHIFT 23
197 #define TH_INTR_POS_GD3_MASK 0x1
198 #define TH_INTR_POS_GU3_SHIFT 22
199 #define TH_INTR_POS_GU3_MASK 0x1
200 #define TH_INTR_POS_GD2_SHIFT 21
201 #define TH_INTR_POS_GD2_MASK 0x1
202 #define TH_INTR_POS_GU2_SHIFT 20
203 #define TH_INTR_POS_GU2_MASK 0x1
204 #define TH_INTR_POS_GD1_SHIFT 19
205 #define TH_INTR_POS_GD1_MASK 0x1
206 #define TH_INTR_POS_GU1_SHIFT 18
207 #define TH_INTR_POS_GU1_MASK 0x1
208 #define TH_INTR_POS_GD0_SHIFT 17
209 #define TH_INTR_POS_GD0_MASK 0x1
210 #define TH_INTR_POS_GU0_SHIFT 16
211 #define TH_INTR_POS_GU0_MASK 0x1
212 #define TH_INTR_POS_CD3_SHIFT 15
213 #define TH_INTR_POS_CD3_MASK 0x1
214 #define TH_INTR_POS_CU3_SHIFT 14
215 #define TH_INTR_POS_CU3_MASK 0x1
216 #define TH_INTR_POS_CD2_SHIFT 13
217 #define TH_INTR_POS_CD2_MASK 0x1
218 #define TH_INTR_POS_CU2_SHIFT 12
219 #define TH_INTR_POS_CU2_MASK 0x1
220 #define TH_INTR_POS_CD1_SHIFT 11
221 #define TH_INTR_POS_CD1_MASK 0x1
222 #define TH_INTR_POS_CU1_SHIFT 10
223 #define TH_INTR_POS_CU1_MASK 0x1
224 #define TH_INTR_POS_CD0_SHIFT 9
225 #define TH_INTR_POS_CD0_MASK 0x1
226 #define TH_INTR_POS_CU0_SHIFT 8
227 #define TH_INTR_POS_CU0_MASK 0x1
228 #define TH_INTR_POS_PD3_SHIFT 7
229 #define TH_INTR_POS_PD3_MASK 0x1
230 #define TH_INTR_POS_PU3_SHIFT 6
231 #define TH_INTR_POS_PU3_MASK 0x1
232 #define TH_INTR_POS_PD2_SHIFT 5
233 #define TH_INTR_POS_PD2_MASK 0x1
234 #define TH_INTR_POS_PU2_SHIFT 4
235 #define TH_INTR_POS_PU2_MASK 0x1
236 #define TH_INTR_POS_PD1_SHIFT 3
237 #define TH_INTR_POS_PD1_MASK 0x1
238 #define TH_INTR_POS_PU1_SHIFT 2
239 #define TH_INTR_POS_PU1_MASK 0x1
240 #define TH_INTR_POS_PD0_SHIFT 1
241 #define TH_INTR_POS_PD0_MASK 0x1
242 #define TH_INTR_POS_PU0_SHIFT 0
243 #define TH_INTR_POS_PU0_MASK 0x1
246 #define UP_STATS_L0 0x10
247 #define DN_STATS_L0 0x14
249 #define STATS_CTL 0x94
250 #define STATS_CTL_CLR_DN 0x8
251 #define STATS_CTL_EN_DN 0x4
252 #define STATS_CTL_CLR_UP 0x2
253 #define STATS_CTL_EN_UP 0x1
255 #define THROT_GLOBAL_CFG 0x400
257 #define OC1_CFG 0x310
258 #define OC1_CFG_LONG_LATENCY_SHIFT 6
259 #define OC1_CFG_LONG_LATENCY_MASK 0x1
260 #define OC1_CFG_HW_RESTORE_SHIFT 5
261 #define OC1_CFG_HW_RESTORE_MASK 0x1
262 #define OC1_CFG_PWR_GOOD_MASK_SHIFT 4
263 #define OC1_CFG_PWR_GOOD_MASK_MASK 0x1
264 #define OC1_CFG_THROTTLE_MODE_SHIFT 2
265 #define OC1_CFG_THROTTLE_MODE_MASK 0x3
266 #define OC1_CFG_ALARM_POLARITY_SHIFT 1
267 #define OC1_CFG_ALARM_POLARITY_MASK 0x1
268 #define OC1_CFG_EN_THROTTLE_SHIFT 0
269 #define OC1_CFG_EN_THROTTLE_MASK 0x1
271 #define OC1_CNT_THRESHOLD 0x314
272 #define OC1_THRESHOLD_PERIOD 0x318
273 #define OC1_ALARM_COUNT 0x31c
274 #define OC1_FILTER 0x320
276 #define OC1_STATS 0x3a8
278 #define OC_INTR_STATUS 0x39c
279 #define OC_INTR_ENABLE 0x3a0
280 #define OC_INTR_DISABLE 0x3a4
281 #define OC_INTR_POS_OC1_SHIFT 0
282 #define OC_INTR_POS_OC1_MASK 0x1
283 #define OC_INTR_POS_OC2_SHIFT 1
284 #define OC_INTR_POS_OC2_MASK 0x1
285 #define OC_INTR_POS_OC3_SHIFT 2
286 #define OC_INTR_POS_OC3_MASK 0x1
287 #define OC_INTR_POS_OC4_SHIFT 3
288 #define OC_INTR_POS_OC4_MASK 0x1
289 #define OC_INTR_POS_OC5_SHIFT 4
290 #define OC_INTR_POS_OC5_MASK 0x1
292 #define OC_STATS_CTL 0x3c4
293 #define OC_STATS_CTL_CLR_ALL 0x2
294 #define OC_STATS_CTL_EN_ALL 0x1
296 #define CPU_PSKIP_STATUS 0x418
297 #define CPU_PSKIP_STATUS_M_SHIFT 12
298 #define CPU_PSKIP_STATUS_M_MASK 0xff
299 #define CPU_PSKIP_STATUS_N_SHIFT 4
300 #define CPU_PSKIP_STATUS_N_MASK 0xff
301 #define CPU_PSKIP_STATUS_ENABLED_SHIFT 0
302 #define CPU_PSKIP_STATUS_ENABLED_MASK 0x1
304 #define THROT_PRIORITY_LOCK 0x424
305 #define THROT_PRIORITY_LOCK_PRIORITY_SHIFT 0
306 #define THROT_PRIORITY_LOCK_PRIORITY_MASK 0xff
308 #define THROT_STATUS 0x428
309 #define THROT_STATUS_BREACH_SHIFT 12
310 #define THROT_STATUS_BREACH_MASK 0x1
311 #define THROT_STATUS_STATE_SHIFT 4
312 #define THROT_STATUS_STATE_MASK 0xff
313 #define THROT_STATUS_ENABLED_SHIFT 0
314 #define THROT_STATUS_ENABLED_MASK 0x1
316 #define THROT_PSKIP_CTRL_LITE_CPU 0x430
317 #define THROT_PSKIP_CTRL_ENABLE_SHIFT 31
318 #define THROT_PSKIP_CTRL_ENABLE_MASK 0x1
319 #define THROT_PSKIP_CTRL_DIVIDEND_SHIFT 8
320 #define THROT_PSKIP_CTRL_DIVIDEND_MASK 0xff
321 #define THROT_PSKIP_CTRL_DIVISOR_SHIFT 0
322 #define THROT_PSKIP_CTRL_DIVISOR_MASK 0xff
324 #define THROT_PSKIP_RAMP_LITE_CPU 0x434
325 #define THROT_PSKIP_RAMP_DURATION_SHIFT 8
326 #define THROT_PSKIP_RAMP_DURATION_MASK 0xffff
327 #define THROT_PSKIP_RAMP_STEP_SHIFT 0
328 #define THROT_PSKIP_RAMP_STEP_MASK 0xff
330 #define THROT_PRIORITY_LITE 0x444
331 #define THROT_PRIORITY_LITE_PRIO_SHIFT 0
332 #define THROT_PRIORITY_LITE_PRIO_MASK 0xff
334 #define THROT_DELAY_LITE 0x448
335 #define THROT_DELAY_LITE_DELAY_SHIFT 0
336 #define THROT_DELAY_LITE_DELAY_MASK 0xff
338 #define THROT_OFFSET 0x30
339 #define ALARM_OFFSET 0x14
341 #define FUSE_BASE_CP_SHIFT 0
342 #define FUSE_BASE_CP_MASK 0x3ff
343 #define FUSE_BASE_FT_SHIFT 16
344 #define FUSE_BASE_FT_MASK 0x7ff
345 #define FUSE_SHIFT_CP_SHIFT 10
346 #define FUSE_SHIFT_CP_MASK 0x3f
347 #define FUSE_SHIFT_CP_BITS 6
348 #define FUSE_SHIFT_FT_SHIFT 27
349 #define FUSE_SHIFT_FT_MASK 0x1f
350 #define FUSE_SHIFT_FT_BITS 5
352 #define FUSE_TSENSOR_CALIB_FT_SHIFT 13
353 #define FUSE_TSENSOR_CALIB_FT_MASK 0x1fff
354 #define FUSE_TSENSOR_CALIB_CP_SHIFT 0
355 #define FUSE_TSENSOR_CALIB_CP_MASK 0x1fff
356 #define FUSE_TSENSOR_CALIB_BITS 13
358 /* car register offsets needed for enabling HW throttling */
359 #define CAR_SUPER_CCLK_DIVIDER 0x24
360 #define CDIV_USE_THERM_CONTROLS_SHIFT 30
361 #define CDIV_USE_THERM_CONTROLS_MASK 0x1
363 /* pmc register offsets needed for powering off PMU */
364 #define PMC_SCRATCH_WRITE_SHIFT 2
365 #define PMC_SCRATCH_WRITE_MASK 0x1
366 #define PMC_ENABLE_RST_SHIFT 1
367 #define PMC_ENABLE_RST_MASK 0x1
368 #define PMC_SENSOR_CTRL 0x1B0
369 #define PMC_SCRATCH54 0x258
370 #define PMC_SCRATCH55 0x25C
372 /* scratch54 register bit fields */
373 #define PMU_OFF_DATA_SHIFT 8
374 #define PMU_OFF_DATA_MASK 0xff
375 #define PMU_OFF_ADDR_SHIFT 0
376 #define PMU_OFF_ADDR_MASK 0xff
378 /* scratch55 register bit fields */
379 #define RESET_TEGRA_SHIFT 31
380 #define RESET_TEGRA_MASK 0x1
381 #define CONTROLLER_TYPE_SHIFT 30
382 #define CONTROLLER_TYPE_MASK 0x1
383 #define I2C_CONTROLLER_ID_SHIFT 27
384 #define I2C_CONTROLLER_ID_MASK 0x7
385 #define PINMUX_SHIFT 24
386 #define PINMUX_MASK 0x7
387 #define CHECKSUM_SHIFT 16
388 #define CHECKSUM_MASK 0xff
389 #define PMU_16BIT_SUPPORT_SHIFT 15
390 #define PMU_16BIT_SUPPORT_MASK 0x1
391 #define PMU_I2C_ADDRESS_SHIFT 0
392 #define PMU_I2C_ADDRESS_MASK 0x7f
395 #define THROT_PSKIP_CTRL(throt, dev) (THROT_PSKIP_CTRL_LITE_CPU + \
396 (THROT_OFFSET * throt) + \
398 #define THROT_PSKIP_RAMP(throt, dev) (THROT_PSKIP_RAMP_LITE_CPU + \
399 (THROT_OFFSET * throt) + \
401 #define THROT_PRIORITY_CTRL(throt) (THROT_PRIORITY_LITE + \
402 (THROT_OFFSET * throt))
403 #define THROT_DELAY_CTRL(throt) (THROT_DELAY_LITE + \
404 (THROT_OFFSET * throt))
405 #define ALARM_CFG(throt) (OC1_CFG + \
406 (ALARM_OFFSET * (throt - \
408 #define ALARM_CNT_THRESHOLD(throt) (OC1_CNT_THRESHOLD + \
409 (ALARM_OFFSET * (throt - \
411 #define ALARM_THRESHOLD_PERIOD(throt) (OC1_THRESHOLD_PERIOD + \
412 (ALARM_OFFSET * (throt - \
414 #define ALARM_ALARM_COUNT(throt) (OC1_ALARM_COUNT + \
415 (ALARM_OFFSET * (throt - \
417 #define ALARM_FILTER(throt) (OC1_FILTER + \
418 (ALARM_OFFSET * (throt - \
420 #define ALARM_STATS(throt) (OC1_STATS + \
421 (4 * (throt - THROTTLE_OC1)))
423 #define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
424 #define THROT_DEPTH_DEFAULT (80)
425 #define THROT_DEPTH(th, dp) { \
426 (th)->depth = (dp); \
427 (th)->dividend = THROT_DEPTH_DIVIDEND(dp); \
428 (th)->divisor = 255; \
429 (th)->duration = 0xff; \
433 #define REG_SET(r, _name, val) (((r) & ~(_name##_MASK << _name##_SHIFT)) | \
434 (((val) & _name##_MASK) << _name##_SHIFT))
435 #define REG_GET_BIT(r, _name) ((r) & (_name##_MASK << _name##_SHIFT))
436 #define REG_GET(r, _name) (REG_GET_BIT(r, _name) >> _name##_SHIFT)
437 #define MAKE_SIGNED32(val, nb) ((s32)(val) << (32 - (nb)) >> (32 - (nb)))
439 static void __iomem *reg_soctherm_base = IO_ADDRESS(TEGRA_SOCTHERM_BASE);
440 static void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
441 static void __iomem *clk_reset_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
443 #define clk_reset_writel(value, reg) \
444 __raw_writel(value, clk_reset_base + (reg))
445 #define clk_reset_readl(reg) __raw_readl(clk_reset_base + (reg))
447 #define pmc_writel(value, reg) __raw_writel(value, pmc_base + (reg))
448 #define pmc_readl(reg) __raw_readl(pmc_base + (reg))
450 #define soctherm_writel(value, reg) \
451 (soctherm_suspended ?: \
452 __raw_writel(value, reg_soctherm_base + (reg)))
453 #define soctherm_readl(reg) \
454 (soctherm_suspended ? 0 : \
455 __raw_readl(reg_soctherm_base + (reg)))
457 static DEFINE_MUTEX(soctherm_suspend_resume_lock);
459 static int soctherm_suspend(void);
460 static int soctherm_resume(void);
462 static struct soctherm_platform_data plat_data;
465 * Remove this flag once this "driver" is structured as a platform driver and
466 * the board files calls platform_device_register instead of directly calling
467 * tegra11_soctherm_init(). See nvbug 1206311.
469 static bool soctherm_init_platform_done;
470 static bool read_hw_temp = true;
471 static bool soctherm_suspended;
473 static struct clk *soctherm_clk;
474 static struct clk *tsensor_clk;
476 static inline long temp_convert(int cap, int a, int b)
481 cap *= LOWER_PRECISION_FOR_CONV(500);
486 #ifdef CONFIG_THERMAL
487 static struct thermal_zone_device *thz[THERM_SIZE];
489 struct soctherm_oc_irq_chip_data {
491 struct mutex irq_lock;
492 struct irq_chip irq_chip;
493 struct irq_domain *domain;
496 static struct soctherm_oc_irq_chip_data soc_irq_cdata;
498 static u32 fuse_calib_base_cp;
499 static u32 fuse_calib_base_ft;
500 static s32 actual_temp_cp;
501 static s32 actual_temp_ft;
503 static const char *const therm_names[] = {
510 static const char *const throt_names[] = {
511 [THROTTLE_LIGHT] = "light",
512 [THROTTLE_HEAVY] = "heavy",
513 [THROTTLE_OC1] = "oc1",
514 [THROTTLE_OC2] = "oc2",
515 [THROTTLE_OC3] = "oc3",
516 [THROTTLE_OC4] = "oc4",
517 [THROTTLE_OC5] = "oc5",
520 static const char *const throt_dev_names[] = {
521 [THROTTLE_DEV_CPU] = "CPU",
522 [THROTTLE_DEV_GPU] = "GPU",
525 static const char *const sensor_names[] = {
526 [TSENSE_CPU0] = "cpu0",
527 [TSENSE_CPU1] = "cpu1",
528 [TSENSE_CPU2] = "cpu2",
529 [TSENSE_CPU3] = "cpu3",
530 [TSENSE_MEM0] = "mem0",
531 [TSENSE_MEM1] = "mem1",
532 [TSENSE_GPU] = "gpu0",
533 [TSENSE_PLLX] = "pllx",
536 static const int sensor2tsensorcalib[] = {
547 static const int tsensor2therm_map[] = {
548 [TSENSE_CPU0] = THERM_CPU,
549 [TSENSE_CPU1] = THERM_CPU,
550 [TSENSE_CPU2] = THERM_CPU,
551 [TSENSE_CPU3] = THERM_CPU,
552 [TSENSE_GPU] = THERM_GPU,
553 [TSENSE_MEM0] = THERM_MEM,
554 [TSENSE_MEM1] = THERM_MEM,
555 [TSENSE_PLLX] = THERM_PLL,
558 static const enum soctherm_throttle_dev_id therm2dev[] = {
559 [THERM_CPU] = THROTTLE_DEV_CPU,
561 [THERM_GPU] = THROTTLE_DEV_GPU,
565 static const struct soctherm_sensor default_t11x_sensor_params = {
574 static const struct soctherm_sensor default_t14x_sensor_params = {
584 static const unsigned long default_t11x_soctherm_clk_rate = 51000000;
585 static const unsigned long default_t11x_tsensor_clk_rate = 500000;
586 static const unsigned long default_t14x_soctherm_clk_rate = 51000000;
587 static const unsigned long default_t14x_tsensor_clk_rate = 400000;
589 /* SOC- OCx to theirt GPIO which is wakeup capable. This is T114 specific */
590 static int soctherm_ocx_to_wake_gpio[TEGRA_SOC_OC_IRQ_MAX] = {
591 TEGRA_GPIO_PEE3, /* TEGRA_SOC_OC_IRQ_1 */
592 TEGRA_GPIO_INVALID, /* TEGRA_SOC_OC_IRQ_2 */
593 TEGRA_GPIO_INVALID, /* TEGRA_SOC_OC_IRQ_3 */
594 TEGRA_GPIO_PJ2, /* TEGRA_SOC_OC_IRQ_4 */
595 TEGRA_GPIO_INVALID, /* TEGRA_SOC_OC_IRQ_5 */
598 static int sensor2therm_a[TSENSE_SIZE];
599 static int sensor2therm_b[TSENSE_SIZE];
601 static inline s64 div64_s64_precise(s64 a, s32 b)
605 /* scale up for increased precision in division */
608 r = div64_s64((al * 2) + 1, 2 * b);
612 static inline long temp_translate(int readback)
614 int abs = readback >> 8;
615 int lsb = (readback & 0x80) >> 7;
616 int sign = readback & 0x01 ? -1 : 1;
618 return (abs * LOWER_PRECISION_FOR_CONV(1000) +
619 lsb * LOWER_PRECISION_FOR_CONV(500)) * sign;
622 #ifdef CONFIG_THERMAL
623 static inline void prog_hw_shutdown(struct thermal_trip_info *trip_state,
629 trip_temp = LOWER_PRECISION_FOR_TEMP(trip_state->trip_temp / 1000);
632 r = soctherm_readl(THERMTRIP);
633 if (therm == THERM_CPU) {
634 r = REG_SET(r, THERMTRIP_CPU_EN, 1);
635 r = REG_SET(r, THERMTRIP_CPU_THRESH, trip_temp);
636 } else if (therm == THERM_GPU) {
637 r = REG_SET(r, THERMTRIP_GPU_EN, 1);
638 r = REG_SET(r, THERMTRIP_GPUMEM_THRESH, trip_temp);
639 } else if (therm == THERM_PLL) {
640 r = REG_SET(r, THERMTRIP_TSENSE_EN, 1);
641 r = REG_SET(r, THERMTRIP_TSENSE_THRESH, trip_temp);
642 } else if (therm == THERM_MEM) {
643 r = REG_SET(r, THERMTRIP_MEM_EN, 1);
644 r = REG_SET(r, THERMTRIP_GPUMEM_THRESH, trip_temp);
646 r = REG_SET(r, THERMTRIP_ANY_EN, 0);
647 soctherm_writel(r, THERMTRIP);
650 static inline void prog_hw_threshold(struct thermal_trip_info *trip_state,
651 int therm, int throt)
656 trip_temp = LOWER_PRECISION_FOR_TEMP(trip_state->trip_temp / 1000);
658 /* Hardcode LITE on level-1 and HEAVY on level-2 */
659 reg_off = TS_THERM_REG_OFFSET(CTL_LVL0_CPU0, throt + 1, therm);
661 r = soctherm_readl(reg_off);
662 r = REG_SET(r, CTL_LVL0_CPU0_UP_THRESH, trip_temp);
664 r = REG_SET(r, CTL_LVL0_CPU0_DN_THRESH, trip_temp);
665 r = REG_SET(r, CTL_LVL0_CPU0_EN, 1);
666 r = REG_SET(r, CTL_LVL0_CPU0_CPU_THROT,
667 throt == THROTTLE_HEAVY ?
668 CTL_LVL0_CPU0_CPU_THROT_HEAVY :
669 CTL_LVL0_CPU0_CPU_THROT_LIGHT);
671 soctherm_writel(r, reg_off);
674 static void soctherm_set_limits(enum soctherm_therm_id therm,
675 long lo_limit, long hi_limit)
679 reg_off = TS_THERM_REG_OFFSET(CTL_LVL0_CPU0, 0, therm);
680 r = soctherm_readl(reg_off);
682 lo_limit = LOWER_PRECISION_FOR_TEMP(lo_limit);
683 hi_limit = LOWER_PRECISION_FOR_TEMP(hi_limit);
685 r = REG_SET(r, CTL_LVL0_CPU0_DN_THRESH, lo_limit);
686 r = REG_SET(r, CTL_LVL0_CPU0_UP_THRESH, hi_limit);
687 r = REG_SET(r, CTL_LVL0_CPU0_EN, 1);
688 soctherm_writel(r, reg_off);
692 r = REG_SET(0, TH_INTR_POS_CD0, 1);
693 r = REG_SET(r, TH_INTR_POS_CU0, 1);
696 r = REG_SET(0, TH_INTR_POS_GD0, 1);
697 r = REG_SET(r, TH_INTR_POS_GU0, 1);
700 r = REG_SET(0, TH_INTR_POS_PD0, 1);
701 r = REG_SET(r, TH_INTR_POS_PU0, 1);
704 r = REG_SET(0, TH_INTR_POS_MD0, 1);
705 r = REG_SET(r, TH_INTR_POS_MU0, 1);
711 soctherm_writel(r, TH_INTR_ENABLE);
714 static void soctherm_update_zone(int zn)
716 const int MAX_HIGH_TEMP = 128000;
717 long low_temp = 0, high_temp = MAX_HIGH_TEMP;
718 long trip_temp, passive_low_temp = MAX_HIGH_TEMP, zone_temp;
719 enum thermal_trip_type trip_type;
720 struct thermal_trip_info *trip_state;
721 struct thermal_zone_device *cur_thz = thz[zn];
724 thermal_zone_device_update(cur_thz);
726 trips = cur_thz->trips;
727 for (count = 0; count < trips; count++) {
728 cur_thz->ops->get_trip_type(cur_thz, count, &trip_type);
729 if ((trip_type == THERMAL_TRIP_HOT) ||
730 (trip_type == THERMAL_TRIP_CRITICAL))
731 continue; /* handled in HW */
733 cur_thz->ops->get_trip_temp(cur_thz, count, &trip_temp);
735 trip_state = &plat_data.therm[zn].trips[count];
736 zone_temp = cur_thz->temperature;
738 if (!trip_state->tripped) { /* not tripped? update high */
739 if (trip_temp < high_temp)
740 high_temp = trip_temp;
741 } else { /* tripped? update low */
742 if (trip_type != THERMAL_TRIP_PASSIVE) {
743 /* get highest ACTIVE */
744 if (trip_temp > low_temp)
745 low_temp = trip_temp;
747 /* get lowest PASSIVE */
748 if (trip_temp < passive_low_temp)
749 passive_low_temp = trip_temp;
754 if (passive_low_temp != MAX_HIGH_TEMP)
755 low_temp = max(low_temp, passive_low_temp);
757 soctherm_set_limits(zn, low_temp/1000, high_temp/1000);
760 static void soctherm_update(void)
764 if (!soctherm_init_platform_done)
767 for (i = 0; i < THERM_SIZE; i++) {
768 if (thz[i] && thz[i]->trips)
769 soctherm_update_zone(i);
773 static int soctherm_hw_action_get_max_state(struct thermal_cooling_device *cdev,
774 unsigned long *max_state)
776 struct thermal_trip_info *trip_state = cdev->devdata;
781 *max_state = 3; /* bit 1: CPU bit 2: GPU */
785 static int soctherm_hw_action_get_cur_state(struct thermal_cooling_device *cdev,
786 unsigned long *cur_state)
788 struct thermal_trip_info *trip_state = cdev->devdata;
796 if (trip_state->trip_type != THERMAL_TRIP_HOT)
799 for (j = 0; j < THROTTLE_DEV_SIZE; j++) {
800 r = soctherm_readl(CPU_PSKIP_STATUS + (j * 4));
801 if (!REG_GET(r, CPU_PSKIP_STATUS_ENABLED))
804 m = REG_GET(r, CPU_PSKIP_STATUS_M);
805 n = REG_GET(r, CPU_PSKIP_STATUS_N);
806 for (i = THROTTLE_LIGHT; i <= THROTTLE_HEAVY; i++) {
807 if (strnstr(trip_state->cdev_type,
808 throt_names[i], THERMAL_NAME_LENGTH) &&
809 plat_data.throttle[i].devs[j].enable &&
810 m == plat_data.throttle[i].devs[j].dividend &&
811 n == plat_data.throttle[i].devs[j].divisor)
812 *cur_state |= (j + 1); /* bit1: CPU bit2: GPU */
818 static int soctherm_hw_action_set_cur_state(struct thermal_cooling_device *cdev,
819 unsigned long cur_state)
821 return 0; /* hw sets this state */
824 static struct thermal_cooling_device_ops soctherm_hw_action_ops = {
825 .get_max_state = soctherm_hw_action_get_max_state,
826 .get_cur_state = soctherm_hw_action_get_cur_state,
827 .set_cur_state = soctherm_hw_action_set_cur_state,
830 static int soctherm_suspend_get_max_state(struct thermal_cooling_device *cdev,
831 unsigned long *max_state)
837 static int soctherm_suspend_get_cur_state(struct thermal_cooling_device *cdev,
838 unsigned long *cur_state)
840 *cur_state = !soctherm_suspended;
844 static int soctherm_suspend_set_cur_state(struct thermal_cooling_device *cdev,
845 unsigned long cur_state)
847 if (!cur_state != soctherm_suspended) {
856 static struct thermal_cooling_device_ops soctherm_suspend_ops = {
857 .get_max_state = soctherm_suspend_get_max_state,
858 .get_cur_state = soctherm_suspend_get_cur_state,
859 .set_cur_state = soctherm_suspend_set_cur_state,
862 static int soctherm_bind(struct thermal_zone_device *thz,
863 struct thermal_cooling_device *cdev)
865 int i, index = ((int)thz->devdata) - TSENSE_SIZE;
866 struct thermal_trip_info *trip_state;
871 for (i = 0; i < plat_data.therm[index].num_trips; i++) {
872 trip_state = &plat_data.therm[index].trips[i];
873 if (trip_state->bound)
875 if (trip_state->cdev_type &&
876 !strncmp(trip_state->cdev_type, cdev->type,
877 THERMAL_NAME_LENGTH)) {
878 thermal_zone_bind_cooling_device(thz, i, cdev,
881 trip_state->bound = true;
888 static int soctherm_unbind(struct thermal_zone_device *thz,
889 struct thermal_cooling_device *cdev)
891 int i, index = ((int)thz->devdata) - TSENSE_SIZE;
892 struct thermal_trip_info *trip_state;
897 for (i = 0; i < plat_data.therm[index].num_trips; i++) {
898 trip_state = &plat_data.therm[index].trips[i];
899 if (!trip_state->bound)
901 if (trip_state->cdev_type &&
902 !strncmp(trip_state->cdev_type, cdev->type,
903 THERMAL_NAME_LENGTH)) {
904 thermal_zone_unbind_cooling_device(thz, 0, cdev);
905 trip_state->bound = false;
912 static int soctherm_get_temp(struct thermal_zone_device *thz,
915 int index = (int)thz->devdata;
916 u32 r, regv, shft, mask;
917 enum soctherm_sense i, j;
920 if (index < TSENSE_SIZE) { /* 'TSENSE_XXX' thermal zone */
921 regv = TS_CPU0_STATUS1;
922 shft = TS_CPU0_STATUS1_TEMP_SHIFT;
923 mask = TS_CPU0_STATUS1_TEMP_MASK;
926 index -= TSENSE_SIZE; /* 'THERM_XXX' thermal zone */
931 shft = TS_TEMP1_CPU_TEMP_SHIFT;
932 mask = TS_TEMP1_CPU_TEMP_MASK;
939 shft = TS_TEMP1_GPU_TEMP_SHIFT;
940 mask = TS_TEMP1_GPU_TEMP_MASK;
946 shft = TS_TEMP2_PLLX_TEMP_SHIFT;
947 mask = TS_TEMP2_PLLX_TEMP_MASK;
953 shft = TS_TEMP2_MEM_TEMP_SHIFT;
954 mask = TS_TEMP2_MEM_TEMP_MASK;
960 return 0; /* error really */
965 r = soctherm_readl(regv);
966 *temp = temp_translate((r & (mask << shft)) >> shft);
968 for (tt = 0; i <= j; i++) {
969 r = soctherm_readl(TS_TSENSE_REG_OFFSET(
970 TS_CPU0_STATUS0, i));
971 ti = temp_convert(REG_GET(r, TS_CPU0_STATUS0_CAPTURE),
974 *temp = tt = max(tt, ti);
980 static int soctherm_get_trip_type(struct thermal_zone_device *thz,
981 int trip, enum thermal_trip_type *type)
983 int index = ((int)thz->devdata) - TSENSE_SIZE;
984 struct thermal_trip_info *trip_state;
989 trip_state = &plat_data.therm[index].trips[trip];
990 *type = trip_state->trip_type;
994 static int soctherm_get_trip_temp(struct thermal_zone_device *thz,
995 int trip, unsigned long *temp)
997 int index = ((int)thz->devdata) - TSENSE_SIZE;
998 struct thermal_trip_info *trip_state;
999 unsigned long trip_temp, zone_temp;
1004 trip_state = &plat_data.therm[index].trips[trip];
1005 trip_temp = trip_state->trip_temp;
1006 zone_temp = thz->temperature;
1008 if (zone_temp >= trip_temp) {
1009 trip_temp -= trip_state->hysteresis;
1010 trip_state->tripped = true;
1011 } else if (trip_state->tripped) {
1012 trip_temp -= trip_state->hysteresis;
1013 if (zone_temp < trip_temp)
1014 trip_state->tripped = false;
1022 static int soctherm_set_trip_temp(struct thermal_zone_device *thz,
1023 int trip, unsigned long temp)
1025 int index = ((int)thz->devdata) - TSENSE_SIZE;
1026 struct thermal_trip_info *trip_state;
1032 trip_state = &plat_data.therm[index].trips[trip];
1034 trip_state->trip_temp = temp;
1036 rem = trip_state->trip_temp % LOWER_PRECISION_FOR_CONV(1000);
1038 pr_warn("soctherm: zone%d/trip_point%d %ld mC rounded down\n",
1039 index, trip, trip_state->trip_temp);
1040 trip_state->trip_temp -= rem;
1043 if (trip_state->trip_type == THERMAL_TRIP_HOT) {
1044 if (strnstr(trip_state->cdev_type,
1045 "heavy", THERMAL_NAME_LENGTH))
1046 prog_hw_threshold(trip_state, index, THROTTLE_HEAVY);
1047 else if (strnstr(trip_state->cdev_type,
1048 "light", THERMAL_NAME_LENGTH))
1049 prog_hw_threshold(trip_state, index, THROTTLE_LIGHT);
1052 /* Allow SW to shutdown at 'Critical temperature reached' */
1053 soctherm_update_zone(index);
1055 /* Reprogram HW thermtrip */
1056 if (trip_state->trip_type == THERMAL_TRIP_CRITICAL)
1057 prog_hw_shutdown(trip_state, index);
1062 static int soctherm_get_crit_temp(struct thermal_zone_device *thz,
1063 unsigned long *temp)
1065 int i, index = ((int)thz->devdata) - TSENSE_SIZE;
1066 struct thermal_trip_info *trip_state;
1071 for (i = 0; i < plat_data.therm[index].num_trips; i++) {
1072 trip_state = &plat_data.therm[index].trips[i];
1073 if (trip_state->trip_type != THERMAL_TRIP_CRITICAL)
1075 *temp = trip_state->trip_temp;
1082 static int soctherm_get_trend(struct thermal_zone_device *thz,
1084 enum thermal_trend *trend)
1086 int index = ((int)thz->devdata) - TSENSE_SIZE;
1087 struct thermal_trip_info *trip_state;
1093 trip_state = &plat_data.therm[index].trips[trip];
1094 thz->ops->get_trip_temp(thz, trip, &trip_temp);
1096 switch (trip_state->trip_type) {
1097 case THERMAL_TRIP_ACTIVE:
1098 /* aggressive active cooling */
1099 *trend = THERMAL_TREND_RAISING;
1101 case THERMAL_TRIP_PASSIVE:
1102 if (thz->temperature > trip_state->trip_temp)
1103 *trend = THERMAL_TREND_RAISING;
1104 else if (thz->temperature < trip_temp)
1105 *trend = THERMAL_TREND_DROPPING;
1107 *trend = THERMAL_TREND_STABLE;
1115 static struct thermal_zone_device_ops soctherm_ops = {
1116 .bind = soctherm_bind,
1117 .unbind = soctherm_unbind,
1118 .get_temp = soctherm_get_temp,
1119 .get_trip_type = soctherm_get_trip_type,
1120 .get_trip_temp = soctherm_get_trip_temp,
1121 .set_trip_temp = soctherm_set_trip_temp,
1122 .get_crit_temp = soctherm_get_crit_temp,
1123 .get_trend = soctherm_get_trend,
1126 static int __init soctherm_thermal_sys_init(void)
1128 char name[THERMAL_NAME_LENGTH];
1129 struct soctherm_therm *therm;
1133 if (!soctherm_init_platform_done)
1137 for (i = 0; i < TSENSE_SIZE; i++) {
1138 if (plat_data.sensor_data[i].zone_enable) {
1139 snprintf(name, THERMAL_NAME_LENGTH,
1140 "%s-tsensor", sensor_names[i]);
1141 /* Create a thermal zone device for each sensor */
1142 thermal_zone_device_register(
1154 for (i = 0; i < THERM_SIZE; i++) {
1155 therm = &plat_data.therm[i];
1156 if (!therm->zone_enable)
1159 for (j = 0; j < therm->num_trips; j++) {
1160 switch (therm->trips[j].trip_type) {
1161 case THERMAL_TRIP_CRITICAL:
1162 thermal_cooling_device_register(
1163 therm->trips[j].cdev_type,
1165 &soctherm_hw_action_ops);
1168 case THERMAL_TRIP_HOT:
1169 for (k = 0; k < THROTTLE_SIZE; k++) {
1170 if (!plat_data.throttle[k].
1171 devs[therm2dev[i]].enable)
1174 if ((strnstr(therm->trips[j].cdev_type,
1176 THERMAL_NAME_LENGTH)
1177 && k == THROTTLE_LIGHT) ||
1178 (strnstr(therm->trips[j].cdev_type,
1180 THERMAL_NAME_LENGTH)
1181 && k == THROTTLE_HEAVY) ||
1182 (strnstr(therm->trips[j].cdev_type,
1184 THERMAL_NAME_LENGTH)
1185 && k == THROTTLE_OC1) ||
1186 (strnstr(therm->trips[j].cdev_type,
1188 THERMAL_NAME_LENGTH)
1189 && k == THROTTLE_OC2) ||
1190 (strnstr(therm->trips[j].cdev_type,
1192 THERMAL_NAME_LENGTH)
1193 && k == THROTTLE_OC3) ||
1194 (strnstr(therm->trips[j].cdev_type,
1196 THERMAL_NAME_LENGTH)
1197 && k == THROTTLE_OC4) ||
1198 (strnstr(therm->trips[j].cdev_type,
1200 THERMAL_NAME_LENGTH)
1201 && k == THROTTLE_OC5))
1204 thermal_cooling_device_register(
1205 therm->trips[j].cdev_type,
1207 &soctherm_hw_action_ops);
1211 case THERMAL_TRIP_PASSIVE:
1212 case THERMAL_TRIP_ACTIVE:
1213 break; /* done elsewhere */
1217 snprintf(name, THERMAL_NAME_LENGTH,
1218 "%s-therm", therm_names[i]);
1219 thz[i] = thermal_zone_device_register(
1222 (1 << therm->num_trips) - 1,
1223 (void *)TSENSE_SIZE + i,
1226 therm->passive_delay,
1229 for (k = THROTTLE_OC1; !oc_en && k < THROTTLE_SIZE; k++)
1230 if (plat_data.throttle[k].devs[therm2dev[i]].enable)
1234 /* do not enable suspend feature if any OC alarms are enabled */
1236 thermal_cooling_device_register("suspend_soctherm", 0,
1237 &soctherm_suspend_ops);
1239 pr_warn("soctherm: Suspend feature CANNOT be enabled %s\n",
1240 "when any OC alarm is enabled");
1245 module_init(soctherm_thermal_sys_init);
1248 static void soctherm_update_zone(int zn)
1251 static void soctherm_update(void)
1256 static irqreturn_t soctherm_thermal_thread_func(int irq, void *arg)
1258 u32 st, ex = 0, cp = 0, gp = 0;
1260 st = soctherm_readl(TH_INTR_STATUS);
1262 /* deliberately clear expected interrupts handled in SW */
1263 cp |= REG_GET_BIT(st, TH_INTR_POS_CD0);
1264 cp |= REG_GET_BIT(st, TH_INTR_POS_CU0);
1267 gp |= REG_GET_BIT(st, TH_INTR_POS_GD0);
1268 gp |= REG_GET_BIT(st, TH_INTR_POS_GU0);
1272 soctherm_writel(ex, TH_INTR_STATUS);
1275 soctherm_update_zone(THERM_CPU);
1277 soctherm_update_zone(THERM_GPU);
1281 /* deliberately ignore expected interrupts NOT handled in SW */
1282 ex |= REG_GET_BIT(st, TH_INTR_POS_PD0);
1283 ex |= REG_GET_BIT(st, TH_INTR_POS_PU0);
1284 ex |= REG_GET_BIT(st, TH_INTR_POS_MD0);
1285 ex |= REG_GET_BIT(st, TH_INTR_POS_MU0);
1287 ex |= REG_GET_BIT(st, TH_INTR_POS_CD1);
1288 ex |= REG_GET_BIT(st, TH_INTR_POS_CU1);
1289 ex |= REG_GET_BIT(st, TH_INTR_POS_CD2);
1290 ex |= REG_GET_BIT(st, TH_INTR_POS_CU2);
1291 ex |= REG_GET_BIT(st, TH_INTR_POS_CD3);
1292 ex |= REG_GET_BIT(st, TH_INTR_POS_CU3);
1294 ex |= REG_GET_BIT(st, TH_INTR_POS_GD1);
1295 ex |= REG_GET_BIT(st, TH_INTR_POS_GU1);
1296 ex |= REG_GET_BIT(st, TH_INTR_POS_GD2);
1297 ex |= REG_GET_BIT(st, TH_INTR_POS_GU2);
1298 ex |= REG_GET_BIT(st, TH_INTR_POS_GD3);
1299 ex |= REG_GET_BIT(st, TH_INTR_POS_GU3);
1301 ex |= REG_GET_BIT(st, TH_INTR_POS_PD1);
1302 ex |= REG_GET_BIT(st, TH_INTR_POS_PU1);
1303 ex |= REG_GET_BIT(st, TH_INTR_POS_PD2);
1304 ex |= REG_GET_BIT(st, TH_INTR_POS_PU2);
1305 ex |= REG_GET_BIT(st, TH_INTR_POS_PD3);
1306 ex |= REG_GET_BIT(st, TH_INTR_POS_PU3);
1308 ex |= REG_GET_BIT(st, TH_INTR_POS_MD1);
1309 ex |= REG_GET_BIT(st, TH_INTR_POS_MU1);
1310 ex |= REG_GET_BIT(st, TH_INTR_POS_MD2);
1311 ex |= REG_GET_BIT(st, TH_INTR_POS_MU2);
1312 ex |= REG_GET_BIT(st, TH_INTR_POS_MD3);
1313 ex |= REG_GET_BIT(st, TH_INTR_POS_MU3);
1317 /* Whine about any other unexpected INTR bits still set */
1318 pr_err("soctherm: Ignored unexpected INTRs 0x%08x\n", st);
1319 soctherm_writel(st, TH_INTR_STATUS);
1325 static inline void soctherm_oc_intr_enable(enum soctherm_throttle_id alarm,
1335 r = REG_SET(0, OC_INTR_POS_OC1, 1);
1338 r = REG_SET(0, OC_INTR_POS_OC2, 1);
1341 r = REG_SET(0, OC_INTR_POS_OC3, 1);
1344 r = REG_SET(0, OC_INTR_POS_OC4, 1);
1347 r = REG_SET(0, OC_INTR_POS_OC5, 1);
1353 soctherm_writel(r, OC_INTR_ENABLE);
1356 /* Return 0 (success) if you want to reenable OC alarm intr. */
1357 static int soctherm_handle_alarm(enum soctherm_throttle_id alarm)
1363 pr_warn("soctherm: Unexpected OC1 alarm\n");
1364 /* add OC1 alarm handling code here */
1368 pr_info("soctherm: Successfully handled OC2 alarm\n");
1369 /* TODO: add OC2 alarm handling code here */
1374 pr_warn("soctherm: Unexpected OC3 alarm\n");
1375 /* add OC3 alarm handling code here */
1379 pr_debug("soctherm: Successfully handled OC4 alarm\n");
1380 /* TODO: add OC4 alarm handling code here */
1385 pr_warn("soctherm: Unexpected OC5 alarm\n");
1386 /* add OC5 alarm handling code here */
1394 pr_err("soctherm: ERROR in handling %s alarm\n",
1395 throt_names[alarm]);
1400 static irqreturn_t soctherm_edp_thread_func(int irq, void *arg)
1402 u32 st, ex, oc1, oc2, oc3, oc4, oc5;
1404 st = soctherm_readl(OC_INTR_STATUS);
1406 /* deliberately clear expected interrupts handled in SW */
1407 oc1 = REG_GET_BIT(st, OC_INTR_POS_OC1);
1408 oc2 = REG_GET_BIT(st, OC_INTR_POS_OC2);
1409 oc3 = REG_GET_BIT(st, OC_INTR_POS_OC3);
1410 oc4 = REG_GET_BIT(st, OC_INTR_POS_OC4);
1411 oc5 = REG_GET_BIT(st, OC_INTR_POS_OC5);
1412 ex = oc1 | oc2 | oc3 | oc4 | oc5;
1415 soctherm_writel(st, OC_INTR_STATUS);
1418 if (oc1 && !soctherm_handle_alarm(THROTTLE_OC1))
1419 soctherm_oc_intr_enable(THROTTLE_OC1, true);
1421 if (oc2 && !soctherm_handle_alarm(THROTTLE_OC2))
1422 soctherm_oc_intr_enable(THROTTLE_OC2, true);
1424 if (oc3 && !soctherm_handle_alarm(THROTTLE_OC3))
1425 soctherm_oc_intr_enable(THROTTLE_OC3, true);
1427 if (oc4 && !soctherm_handle_alarm(THROTTLE_OC4))
1428 soctherm_oc_intr_enable(THROTTLE_OC4, true);
1430 if (oc5 && !soctherm_handle_alarm(THROTTLE_OC5))
1431 soctherm_oc_intr_enable(THROTTLE_OC5, true);
1433 if (oc1 && soc_irq_cdata.irq_enable & BIT(0))
1435 irq_find_mapping(soc_irq_cdata.domain, 0));
1437 if (oc2 && soc_irq_cdata.irq_enable & BIT(1))
1439 irq_find_mapping(soc_irq_cdata.domain, 1));
1441 if (oc3 && soc_irq_cdata.irq_enable & BIT(2))
1443 irq_find_mapping(soc_irq_cdata.domain, 2));
1445 if (oc4 && soc_irq_cdata.irq_enable & BIT(3))
1447 irq_find_mapping(soc_irq_cdata.domain, 3));
1449 if (oc5 && soc_irq_cdata.irq_enable & BIT(4))
1451 irq_find_mapping(soc_irq_cdata.domain, 0));
1455 pr_err("soctherm: Ignored unexpected OC ALARM 0x%08x\n", st);
1456 soctherm_writel(st, OC_INTR_STATUS);
1462 static irqreturn_t soctherm_thermal_isr(int irq, void *arg)
1466 r = soctherm_readl(TH_INTR_STATUS);
1467 soctherm_writel(r, TH_INTR_DISABLE);
1469 return IRQ_WAKE_THREAD;
1472 static irqreturn_t soctherm_edp_isr(int irq, void *arg)
1476 r = soctherm_readl(OC_INTR_STATUS);
1477 soctherm_writel(r, OC_INTR_DISABLE);
1479 return IRQ_WAKE_THREAD;
1482 static void tegra11_soctherm_throttle_program(enum soctherm_throttle_id throt)
1486 bool throt_enable = false;
1487 struct soctherm_throttle_dev *dev;
1488 struct soctherm_throttle *data = &plat_data.throttle[throt];
1490 for (i = 0; i < THROTTLE_DEV_SIZE; i++) {
1491 dev = &data->devs[i];
1494 throt_enable = true;
1497 THROT_DEPTH(dev, dev->depth);
1498 } else if (!dev->dividend || !dev->divisor || !dev->duration ||
1500 THROT_DEPTH(dev, THROT_DEPTH_DEFAULT);
1503 r = soctherm_readl(THROT_PSKIP_CTRL(throt, i));
1504 r = REG_SET(r, THROT_PSKIP_CTRL_ENABLE, dev->enable);
1505 r = REG_SET(r, THROT_PSKIP_CTRL_DIVIDEND, dev->dividend);
1506 r = REG_SET(r, THROT_PSKIP_CTRL_DIVISOR, dev->divisor);
1507 soctherm_writel(r, THROT_PSKIP_CTRL(throt, i));
1509 r = soctherm_readl(THROT_PSKIP_RAMP(throt, i));
1510 r = REG_SET(r, THROT_PSKIP_RAMP_DURATION, dev->duration);
1511 r = REG_SET(r, THROT_PSKIP_RAMP_STEP, dev->step);
1512 soctherm_writel(r, THROT_PSKIP_RAMP(throt, i));
1515 r = REG_SET(0, THROT_PRIORITY_LITE_PRIO, data->priority);
1516 soctherm_writel(r, THROT_PRIORITY_CTRL(throt));
1518 r = REG_SET(0, THROT_DELAY_LITE_DELAY, 0);
1519 soctherm_writel(r, THROT_DELAY_CTRL(throt));
1521 r = soctherm_readl(THROT_PRIORITY_LOCK);
1522 if (r < data->priority) {
1523 r = REG_SET(0, THROT_PRIORITY_LOCK_PRIORITY, data->priority);
1524 soctherm_writel(r, THROT_PRIORITY_LOCK);
1527 if (!throt_enable || (throt < THROTTLE_OC1))
1530 /* ----- configure OC alarms ----- */
1532 if (!(data->throt_mode == BRIEF || data->throt_mode == STICKY))
1533 pr_warn("soctherm: Invalid throt_mode in %s\n",
1534 throt_names[throt]);
1536 r = soctherm_readl(ALARM_CFG(throt));
1537 r = REG_SET(r, OC1_CFG_HW_RESTORE, 1);
1538 r = REG_SET(r, OC1_CFG_THROTTLE_MODE, data->throt_mode);
1539 r = REG_SET(r, OC1_CFG_ALARM_POLARITY, data->polarity);
1540 r = REG_SET(r, OC1_CFG_EN_THROTTLE, 1);
1541 soctherm_writel(r, ALARM_CFG(throt));
1543 soctherm_oc_intr_enable(throt, data->intr);
1545 soctherm_writel(data->period, ALARM_THRESHOLD_PERIOD(throt)); /* usec */
1546 soctherm_writel(0xffffffff, ALARM_FILTER(throt));
1549 static void soctherm_tsense_program(enum soctherm_sense sensor,
1550 struct soctherm_sensor *data)
1554 r = REG_SET(0, TS_CPU0_CONFIG0_TALL, data->tall);
1555 soctherm_writel(r, TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG0, sensor));
1557 r = REG_SET(0, TS_CPU0_CONFIG1_TIDDQ, data->tiddq);
1558 r = REG_SET(r, TS_CPU0_CONFIG1_EN, 1);
1559 r = REG_SET(r, TS_CPU0_CONFIG1_TEN_COUNT, data->ten_count);
1560 r = REG_SET(r, TS_CPU0_CONFIG1_TSAMPLE, data->tsample - 1);
1561 soctherm_writel(r, TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG1, sensor));
1564 static int __init soctherm_clk_init(void)
1566 unsigned long default_soctherm_clk_rate;
1567 unsigned long default_tsensor_clk_rate;
1569 soctherm_clk = clk_get_sys("soc_therm", NULL);
1570 tsensor_clk = clk_get_sys("tegra-tsensor", NULL);
1572 if (IS_ERR(tsensor_clk) || IS_ERR(soctherm_clk)) {
1573 clk_put(soctherm_clk);
1574 clk_put(tsensor_clk);
1575 soctherm_clk = tsensor_clk = NULL;
1579 /* initialize default clock rates */
1580 default_soctherm_clk_rate =
1581 tegra_chip_id == TEGRA_CHIPID_TEGRA14 ?
1582 default_t14x_soctherm_clk_rate :
1583 default_t11x_soctherm_clk_rate;
1584 default_tsensor_clk_rate =
1585 tegra_chip_id == TEGRA_CHIPID_TEGRA14 ?
1586 default_t14x_tsensor_clk_rate :
1587 default_t11x_tsensor_clk_rate;
1589 plat_data.soctherm_clk_rate =
1590 plat_data.soctherm_clk_rate ?: default_soctherm_clk_rate;
1591 plat_data.tsensor_clk_rate =
1592 plat_data.tsensor_clk_rate ?: default_tsensor_clk_rate;
1594 if (clk_get_rate(soctherm_clk) != plat_data.soctherm_clk_rate)
1595 if (clk_set_rate(soctherm_clk, plat_data.soctherm_clk_rate))
1598 if (clk_get_rate(tsensor_clk) != plat_data.tsensor_clk_rate)
1599 if (clk_set_rate(tsensor_clk, plat_data.tsensor_clk_rate))
1605 static int soctherm_clk_enable(bool enable)
1607 if (soctherm_clk == NULL || tsensor_clk == NULL)
1611 clk_enable(soctherm_clk);
1612 clk_enable(tsensor_clk);
1614 clk_disable(soctherm_clk);
1615 clk_disable(tsensor_clk);
1621 static int soctherm_fuse_read_vsensor(void)
1624 s32 calib_cp, calib_ft;
1625 s32 nominal_calib_cp, nominal_calib_ft;
1627 tegra_fuse_get_vsensor_calib(&value);
1630 fuse_calib_base_cp = REG_GET(value, FUSE_BASE_CP);
1631 fuse_calib_base_ft = REG_GET(value, FUSE_BASE_FT);
1633 /* Extract bits and convert to signed 2's complement */
1634 calib_cp = REG_GET(value, FUSE_SHIFT_CP);
1635 calib_cp = MAKE_SIGNED32(calib_cp, FUSE_SHIFT_CP_BITS);
1637 calib_ft = REG_GET(value, FUSE_SHIFT_FT);
1638 calib_ft = MAKE_SIGNED32(calib_ft, FUSE_SHIFT_FT_BITS);
1640 nominal_calib_cp = 25;
1641 nominal_calib_ft = tegra_chip_id == TEGRA_CHIPID_TEGRA14 ? 105 : 90;
1643 /* use HI precision to calculate: use fuse_temp in 0.5C */
1644 actual_temp_cp = 2 * nominal_calib_cp + calib_cp;
1645 actual_temp_ft = 2 * nominal_calib_ft + calib_ft;
1647 if (!actual_temp_ft || !actual_temp_cp) {
1648 pr_err("soctherm: ERROR: Improper FUSE. SOC_THERM disabled\n");
1654 static int t11x_fuse_corr_alpha[] = { /* scaled *1000000 */
1655 [TSENSE_CPU0] = 1196400,
1656 [TSENSE_CPU1] = 1196400,
1657 [TSENSE_CPU2] = 1196400,
1658 [TSENSE_CPU3] = 1196400,
1659 [TSENSE_GPU] = 1124500,
1660 [TSENSE_PLLX] = 1224200,
1663 static int t11x_fuse_corr_beta[] = { /* scaled *1000000 */
1664 [TSENSE_CPU0] = -13600000,
1665 [TSENSE_CPU1] = -13600000,
1666 [TSENSE_CPU2] = -13600000,
1667 [TSENSE_CPU3] = -13600000,
1668 [TSENSE_GPU] = -9793100,
1669 [TSENSE_PLLX] = -14665000,
1672 static int t14x_fuse_corr_alpha[] = { /* scaled *1000000 */
1673 [TSENSE_CPU0] = 1149000,
1674 [TSENSE_CPU1] = 1148800,
1675 [TSENSE_CPU2] = 1139100,
1676 [TSENSE_CPU3] = 1141800,
1677 [TSENSE_MEM0] = 1082300,
1678 [TSENSE_MEM1] = 1061800,
1679 [TSENSE_GPU] = 1078900,
1680 [TSENSE_PLLX] = 1125900,
1683 static int t14x_fuse_corr_beta[] = { /* scaled *1000000 */
1684 [TSENSE_CPU0] = -16753000,
1685 [TSENSE_CPU1] = -16287000,
1686 [TSENSE_CPU2] = -12552000,
1687 [TSENSE_CPU3] = -11061000,
1688 [TSENSE_MEM0] = -11061000,
1689 [TSENSE_MEM1] = -7596500,
1690 [TSENSE_GPU] = -10480000,
1691 [TSENSE_PLLX] = -14736000,
1694 static int soctherm_fuse_read_tsensor(enum soctherm_sense sensor)
1697 s32 calib, delta_sens, delta_temp;
1698 s16 therm_a, therm_b;
1699 s32 div, mult, actual_tsensor_ft, actual_tsensor_cp;
1701 tegra_fuse_get_tsensor_calib(sensor2tsensorcalib[sensor], &value);
1703 /* Extract bits and convert to signed 2's complement */
1704 calib = REG_GET(value, FUSE_TSENSOR_CALIB_FT);
1705 calib = MAKE_SIGNED32(calib, FUSE_TSENSOR_CALIB_BITS);
1706 actual_tsensor_ft = (fuse_calib_base_ft * 32) + calib;
1708 calib = REG_GET(value, FUSE_TSENSOR_CALIB_CP);
1709 calib = MAKE_SIGNED32(calib, FUSE_TSENSOR_CALIB_BITS);
1710 actual_tsensor_cp = (fuse_calib_base_cp * 64) + calib;
1712 if (!actual_tsensor_ft || !actual_tsensor_cp) {
1713 pr_err("soctherm: ERROR: Improper FUSE. SOC_THERM disabled\n");
1717 mult = plat_data.sensor_data[sensor].pdiv *
1718 plat_data.sensor_data[sensor].tsamp_ATE;
1719 div = plat_data.sensor_data[sensor].tsample *
1720 plat_data.sensor_data[sensor].pdiv_ATE;
1722 /* first calculate therm_a and therm_b in Hi precision */
1723 delta_sens = actual_tsensor_ft - actual_tsensor_cp;
1724 delta_temp = actual_temp_ft - actual_temp_cp;
1726 therm_a = div64_s64_precise((s64)delta_temp * (1LL << 13) * mult,
1727 (s64)delta_sens * div);
1729 therm_b = div64_s64_precise((((s64)actual_tsensor_ft * actual_temp_cp) -
1730 ((s64)actual_tsensor_cp * actual_temp_ft)),
1733 /* FUSE corrections for Tegra when precision is set LOW */
1734 if (PRECISION_IS_LOWER()) {
1735 if (tegra_chip_id == TEGRA_CHIPID_TEGRA11) {
1736 t11x_fuse_corr_alpha[sensor] =
1737 t11x_fuse_corr_alpha[sensor] ?: 1000000;
1738 therm_a = div64_s64_precise(
1739 (s64)therm_a * t11x_fuse_corr_alpha[sensor],
1741 therm_b = div64_s64_precise(
1742 (s64)therm_b * t11x_fuse_corr_alpha[sensor] +
1743 t11x_fuse_corr_beta[sensor], (s64)1000000LL);
1744 } else if (tegra_chip_id == TEGRA_CHIPID_TEGRA14) {
1745 t14x_fuse_corr_alpha[sensor] =
1746 t14x_fuse_corr_alpha[sensor] ?: 1000000;
1747 therm_a = div64_s64_precise(
1748 (s64)therm_a * t14x_fuse_corr_alpha[sensor],
1750 therm_b = div64_s64_precise(
1751 (s64)therm_b * t14x_fuse_corr_alpha[sensor] +
1752 t14x_fuse_corr_beta[sensor], (s64)1000000LL);
1756 therm_a = LOWER_PRECISION_FOR_TEMP(therm_a);
1757 therm_b = LOWER_PRECISION_FOR_TEMP(therm_b);
1759 sensor2therm_a[sensor] = (s16)therm_a;
1760 sensor2therm_b[sensor] = (s16)therm_b;
1762 r = REG_SET(0, TS_CPU0_CONFIG2_THERM_A, therm_a);
1763 r = REG_SET(r, TS_CPU0_CONFIG2_THERM_B, therm_b);
1764 soctherm_writel(r, TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG2, sensor));
1769 static void soctherm_therm_trip_init(struct tegra_tsensor_pmu_data *data)
1773 /* enable therm trip at PMC */
1774 val = pmc_readl(PMC_SENSOR_CTRL);
1775 val = REG_SET(val, PMC_SCRATCH_WRITE, 1);
1776 val = REG_SET(val, PMC_ENABLE_RST, 1);
1777 pmc_writel(val, PMC_SENSOR_CTRL);
1782 /* Fill scratch registers to shutdown device on therm TRIP */
1783 val = REG_SET(0, PMU_OFF_DATA, data->poweroff_reg_data);
1784 val = REG_SET(val, PMU_OFF_ADDR, data->poweroff_reg_addr);
1785 pmc_writel(val, PMC_SCRATCH54);
1787 val = REG_SET(0, RESET_TEGRA, 1);
1788 val = REG_SET(val, CONTROLLER_TYPE, data->controller_type);
1789 val = REG_SET(val, I2C_CONTROLLER_ID, data->i2c_controller_id);
1790 val = REG_SET(val, PINMUX, data->pinmux);
1791 val = REG_SET(val, PMU_16BIT_SUPPORT, data->pmu_16bit_ops);
1792 val = REG_SET(val, PMU_I2C_ADDRESS, data->pmu_i2c_addr);
1794 checksum = data->poweroff_reg_addr +
1795 data->poweroff_reg_data +
1797 ((val >> 8) & 0xFF) +
1798 ((val >> 24) & 0xFF);
1800 checksum = 0x100 - checksum;
1802 val = REG_SET(val, CHECKSUM, checksum);
1803 pmc_writel(val, PMC_SCRATCH55);
1806 static int soctherm_init_platform_data(void)
1808 struct soctherm_therm *therm;
1809 struct soctherm_sensor *s;
1810 struct soctherm_sensor sensor_defaults;
1815 sensor_defaults = tegra_chip_id == TEGRA_CHIPID_TEGRA14 ?
1816 default_t14x_sensor_params : default_t11x_sensor_params;
1818 /* initialize default values for unspecified params */
1819 for (i = 0; i < TSENSE_SIZE; i++) {
1820 therm = &plat_data.therm[tsensor2therm_map[i]];
1821 s = &plat_data.sensor_data[i];
1822 s->sensor_enable = s->zone_enable;
1823 s->sensor_enable = s->sensor_enable ?: therm->zone_enable;
1824 s->tall = s->tall ?: sensor_defaults.tall;
1825 s->tiddq = s->tiddq ?: sensor_defaults.tiddq;
1826 s->ten_count = s->ten_count ?: sensor_defaults.ten_count;
1827 s->tsample = s->tsample ?: sensor_defaults.tsample;
1828 s->tsamp_ATE = s->tsamp_ATE ?: sensor_defaults.tsamp_ATE;
1829 s->pdiv = s->pdiv ?: sensor_defaults.pdiv;
1830 s->pdiv_ATE = s->pdiv_ATE ?: sensor_defaults.pdiv_ATE;
1834 r = soctherm_readl(TS_PDIV);
1835 r = REG_SET(r, TS_PDIV_CPU, plat_data.sensor_data[TSENSE_CPU0].pdiv);
1836 r = REG_SET(r, TS_PDIV_GPU, plat_data.sensor_data[TSENSE_GPU].pdiv);
1837 r = REG_SET(r, TS_PDIV_MEM, plat_data.sensor_data[TSENSE_MEM0].pdiv);
1838 r = REG_SET(r, TS_PDIV_PLLX, plat_data.sensor_data[TSENSE_PLLX].pdiv);
1839 soctherm_writel(r, TS_PDIV);
1841 /* Thermal Sensing programming */
1842 if (soctherm_fuse_read_vsensor() < 0)
1844 for (i = 0; i < TSENSE_SIZE; i++) {
1845 if (plat_data.sensor_data[i].sensor_enable) {
1846 soctherm_tsense_program(i, &plat_data.sensor_data[i]);
1847 if (soctherm_fuse_read_tsensor(i) < 0)
1852 /* Sanitize therm trips */
1853 for (i = 0; i < THERM_SIZE; i++) {
1854 therm = &plat_data.therm[i];
1855 if (!therm->zone_enable)
1858 for (j = 0; j < therm->num_trips; j++) {
1859 rem = therm->trips[j].trip_temp %
1860 LOWER_PRECISION_FOR_CONV(1000);
1863 "soctherm: zone%d/trip_point%d %ld mC rounded down\n",
1864 i, j, therm->trips[j].trip_temp);
1865 therm->trips[j].trip_temp -= rem;
1870 /* Program hotspot offsets per THERM */
1871 r = REG_SET(0, TS_HOTSPOT_OFF_CPU,
1872 plat_data.therm[THERM_CPU].hotspot_offset / 1000);
1873 r = REG_SET(r, TS_HOTSPOT_OFF_GPU,
1874 plat_data.therm[THERM_GPU].hotspot_offset / 1000);
1875 r = REG_SET(r, TS_HOTSPOT_OFF_MEM,
1876 plat_data.therm[THERM_MEM].hotspot_offset / 1000);
1877 soctherm_writel(r, TS_HOTSPOT_OFF);
1879 /* Sanitize HW throttle priority */
1880 for (i = 0; i < THROTTLE_SIZE; i++)
1881 if (!plat_data.throttle[i].priority)
1882 plat_data.throttle[i].priority = 0xE + i;
1883 if (plat_data.throttle[THROTTLE_HEAVY].priority <
1884 plat_data.throttle[THROTTLE_LIGHT].priority)
1885 pr_err("soctherm: ERROR: Priority of HEAVY less than LIGHT\n");
1887 /* Thermal HW throttle programming */
1888 for (i = 0; i < THROTTLE_SIZE; i++) {
1889 /* Setup PSKIP parameters */
1890 tegra11_soctherm_throttle_program(i);
1892 /* Setup throttle thresholds per THERM */
1893 for (j = 0; j < THERM_SIZE; j++) {
1894 /* Check if PSKIP params are enabled */
1895 if ((therm2dev[j] == -1) ||
1896 (!plat_data.throttle[i].devs[therm2dev[j]].enable))
1899 therm = &plat_data.therm[j];
1900 for (k = 0; k < therm->num_trips; k++)
1901 if ((therm->trips[k].trip_type ==
1902 THERMAL_TRIP_HOT) &&
1903 strnstr(therm->trips[k].cdev_type,
1904 i == THROTTLE_HEAVY ? "heavy" :
1905 "light", THERMAL_NAME_LENGTH))
1907 if (k < therm->num_trips && i <= THROTTLE_HEAVY)
1908 prog_hw_threshold(&therm->trips[k], j, i);
1912 /* initialize stats collection */
1913 r = STATS_CTL_CLR_DN | STATS_CTL_EN_DN |
1914 STATS_CTL_CLR_UP | STATS_CTL_EN_UP;
1915 soctherm_writel(r, STATS_CTL);
1916 soctherm_writel(OC_STATS_CTL_EN_ALL, OC_STATS_CTL);
1918 /* Enable PMC to shutdown */
1919 soctherm_therm_trip_init(plat_data.tshut_pmu_trip_data);
1921 r = clk_reset_readl(CAR_SUPER_CCLK_DIVIDER);
1922 r = REG_SET(r, CDIV_USE_THERM_CONTROLS, 1);
1923 clk_reset_writel(r, CAR_SUPER_CCLK_DIVIDER);
1926 for (i = 0; i < THERM_SIZE; i++) {
1927 therm = &plat_data.therm[i];
1928 if (!therm->zone_enable)
1931 for (j = 0; j < therm->num_trips; j++)
1932 if (therm->trips[j].trip_type == THERMAL_TRIP_CRITICAL)
1933 prog_hw_shutdown(&therm->trips[j], i);
1939 static void soctherm_suspend_locked(void)
1941 if (!soctherm_suspended) {
1942 soctherm_writel((u32)-1, TH_INTR_DISABLE);
1943 soctherm_writel((u32)-1, OC_INTR_DISABLE);
1944 disable_irq(INT_THERMAL);
1945 disable_irq(INT_EDP);
1946 soctherm_clk_enable(false);
1947 soctherm_init_platform_done = false;
1948 soctherm_suspended = true;
1952 static int soctherm_suspend(void)
1954 mutex_lock(&soctherm_suspend_resume_lock);
1955 soctherm_suspend_locked();
1956 mutex_unlock(&soctherm_suspend_resume_lock);
1960 static void soctherm_resume_locked(void)
1962 if (soctherm_suspended) {
1963 soctherm_suspended = false;
1964 soctherm_clk_enable(true);
1965 soctherm_init_platform_data();
1966 soctherm_init_platform_done = true;
1968 enable_irq(INT_THERMAL);
1969 enable_irq(INT_EDP);
1973 static int soctherm_resume(void)
1975 mutex_lock(&soctherm_suspend_resume_lock);
1976 soctherm_resume_locked();
1977 mutex_unlock(&soctherm_suspend_resume_lock);
1981 static int soctherm_sync(void)
1983 mutex_lock(&soctherm_suspend_resume_lock);
1985 if (soctherm_suspended) {
1986 soctherm_resume_locked();
1987 soctherm_suspend_locked();
1992 mutex_unlock(&soctherm_suspend_resume_lock);
1995 late_initcall_sync(soctherm_sync);
1997 static int soctherm_pm_notify(struct notifier_block *nb,
1998 unsigned long event, void *data)
2001 case PM_SUSPEND_PREPARE:
2004 case PM_POST_SUSPEND:
2012 static struct notifier_block soctherm_nb = {
2013 .notifier_call = soctherm_pm_notify,
2016 static void soctherm_oc_irq_lock(struct irq_data *data)
2018 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
2020 mutex_lock(&d->irq_lock);
2022 static void soctherm_oc_irq_sync_unlock(struct irq_data *data)
2024 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
2026 mutex_unlock(&d->irq_lock);
2028 static void soctherm_oc_irq_enable(struct irq_data *data)
2030 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
2032 d->irq_enable |= BIT(data->hwirq);
2035 static void soctherm_oc_irq_disable(struct irq_data *data)
2037 struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
2039 d->irq_enable &= ~BIT(data->hwirq);
2042 static int soctherm_oc_irq_set_type(struct irq_data *data, unsigned int type)
2047 static int soctherm_oc_irq_set_wake(struct irq_data *data, unsigned int on)
2052 gpio = soctherm_ocx_to_wake_gpio[data->hwirq];
2053 if (!gpio_is_valid(gpio)) {
2054 pr_err("No wakeup supported for irq %lu\n", data->hwirq);
2058 gpio_irq = gpio_to_irq(gpio);
2060 pr_err("No gpio_to_irq for gpio %d\n", gpio);
2064 irq_set_irq_wake(gpio_irq, on);
2068 static int soctherm_oc_irq_map(struct irq_domain *h, unsigned int virq,
2071 struct soctherm_oc_irq_chip_data *data = h->host_data;
2073 irq_set_chip_data(virq, data);
2074 irq_set_chip(virq, &data->irq_chip);
2075 irq_set_nested_thread(virq, 1);
2076 set_irq_flags(virq, IRQF_VALID);
2080 static struct irq_domain_ops soctherm_oc_domain_ops = {
2081 .map = soctherm_oc_irq_map,
2082 .xlate = irq_domain_xlate_twocell,
2085 static int tegra11_soctherem_oc_int_init(int irq_base, int num_irqs)
2087 if (irq_base <= 0 || !num_irqs) {
2088 pr_info("%s(): OC interrupts are not enabled\n", __func__);
2092 mutex_init(&soc_irq_cdata.irq_lock);
2093 soc_irq_cdata.irq_enable = 0;
2095 soc_irq_cdata.irq_chip.name = "sco_therm_oc";
2096 soc_irq_cdata.irq_chip.irq_bus_lock = soctherm_oc_irq_lock,
2097 soc_irq_cdata.irq_chip.irq_bus_sync_unlock = soctherm_oc_irq_sync_unlock,
2098 soc_irq_cdata.irq_chip.irq_disable = soctherm_oc_irq_disable,
2099 soc_irq_cdata.irq_chip.irq_enable = soctherm_oc_irq_enable,
2100 soc_irq_cdata.irq_chip.irq_set_type = soctherm_oc_irq_set_type,
2101 soc_irq_cdata.irq_chip.irq_set_wake = soctherm_oc_irq_set_wake,
2103 irq_base = irq_alloc_descs(irq_base, 0, num_irqs, 0);
2105 pr_err("%s: Failed to allocate IRQs: %d\n", __func__, irq_base);
2109 soc_irq_cdata.domain = irq_domain_add_legacy(NULL, num_irqs,
2110 irq_base, 0, &soctherm_oc_domain_ops, &soc_irq_cdata);
2111 if (!soc_irq_cdata.domain) {
2112 pr_err("%s: Failed to create IRQ domain\n", __func__);
2115 pr_info("%s(): OC interrupts enabled successful\n", __func__);
2119 int __init tegra11_soctherm_init(struct soctherm_platform_data *data)
2123 if (!(tegra_chip_id == TEGRA_CHIPID_TEGRA11 ||
2124 tegra_chip_id == TEGRA_CHIPID_TEGRA14)) {
2125 pr_err("%s: Unknown chip_id %d", __func__, tegra_chip_id);
2129 register_pm_notifier(&soctherm_nb);
2135 if (soctherm_clk_init() < 0)
2138 if (soctherm_clk_enable(true) < 0)
2141 if (soctherm_init_platform_data() < 0)
2144 soctherm_init_platform_done = true;
2146 ret = tegra11_soctherem_oc_int_init(data->oc_irq_base,
2149 pr_err("soctherem_oc_int_init failed: %d\n", ret);
2154 /* enable threaded interrupts */
2155 if (request_threaded_irq(INT_THERMAL, soctherm_thermal_isr,
2156 soctherm_thermal_thread_func, IRQF_ONESHOT,
2157 "soctherm_thermal", NULL) < 0)
2160 if (request_threaded_irq(INT_EDP, soctherm_edp_isr,
2161 soctherm_edp_thread_func, IRQF_ONESHOT,
2162 "soctherm_edp", NULL) < 0)
2168 #ifdef CONFIG_DEBUG_FS
2170 static int regs_show(struct seq_file *s, void *data)
2174 int tcpu[TSENSE_SIZE];
2177 if (soctherm_suspended) {
2178 seq_printf(s, "SOC_THERM is SUSPENDED\n");
2182 seq_printf(s, "-----TSENSE (precision %s convert %s)-----\n",
2183 PRECISION_TO_STR(), read_hw_temp ? "HW" : "SW");
2184 for (i = 0; i < TSENSE_SIZE; i++) {
2185 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG1, i));
2186 state = REG_GET(r, TS_CPU0_CONFIG1_EN);
2190 seq_printf(s, "%s: ", sensor_names[i]);
2192 seq_printf(s, "En(%d) ", state);
2193 state = REG_GET(r, TS_CPU0_CONFIG1_TIDDQ);
2194 seq_printf(s, "tiddq(%d) ", state);
2195 state = REG_GET(r, TS_CPU0_CONFIG1_TEN_COUNT);
2196 seq_printf(s, "ten_count(%d) ", state);
2197 state = REG_GET(r, TS_CPU0_CONFIG1_TSAMPLE);
2198 seq_printf(s, "tsample(%d) ", state + 1);
2200 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_STATUS1, i));
2201 state = REG_GET(r, TS_CPU0_STATUS1_TEMP_VALID);
2202 seq_printf(s, "Temp(%d/", state);
2203 state = REG_GET(r, TS_CPU0_STATUS1_TEMP);
2204 seq_printf(s, "%d) ", tcpu[i] = temp_translate(state));
2206 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_STATUS0, i));
2207 state = REG_GET(r, TS_CPU0_STATUS0_VALID);
2208 seq_printf(s, "Capture(%d/", state);
2209 state = REG_GET(r, TS_CPU0_STATUS0_CAPTURE);
2210 seq_printf(s, "%d) (Converted-temp(%ld) ", state,
2211 temp_convert(state, sensor2therm_a[i],
2212 sensor2therm_b[i]));
2214 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG0, i));
2215 state = REG_GET(r, TS_CPU0_CONFIG0_TALL);
2216 seq_printf(s, "Tall(%d) ", state);
2217 state = REG_GET(r, TS_CPU0_CONFIG0_TCALC_OVER);
2218 seq_printf(s, "Over(%d/", state);
2219 state = REG_GET(r, TS_CPU0_CONFIG0_OVER);
2220 seq_printf(s, "%d/", state);
2221 state = REG_GET(r, TS_CPU0_CONFIG0_CPTR_OVER);
2222 seq_printf(s, "%d) ", state);
2224 r = soctherm_readl(TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG2, i));
2225 state = REG_GET(r, TS_CPU0_CONFIG2_THERM_A);
2226 seq_printf(s, "Therm_A/B(%d/", state);
2227 state = REG_GET(r, TS_CPU0_CONFIG2_THERM_B);
2228 seq_printf(s, "%d)\n", (s16)state);
2231 r = soctherm_readl(TS_PDIV);
2232 seq_printf(s, "PDIV: 0x%x\n", r);
2234 seq_printf(s, "\n");
2235 seq_printf(s, "-----SOC_THERM-----\n");
2237 r = soctherm_readl(TS_TEMP1);
2238 state = REG_GET(r, TS_TEMP1_CPU_TEMP);
2239 seq_printf(s, "Temperatures: CPU(%ld) ", temp_translate(state));
2240 state = REG_GET(r, TS_TEMP1_GPU_TEMP);
2241 seq_printf(s, " GPU(%ld) ", temp_translate(state));
2242 r = soctherm_readl(TS_TEMP2);
2243 state = REG_GET(r, TS_TEMP2_PLLX_TEMP);
2244 seq_printf(s, " PLLX(%ld) ", temp_translate(state));
2245 state = REG_GET(r, TS_TEMP2_MEM_TEMP);
2246 seq_printf(s, " MEM(%ld)\n", temp_translate(state));
2248 for (i = 0; i < THERM_SIZE; i++) {
2251 seq_printf(s, "%s:\n", therm_names[i]);
2253 for (level = 0; level < 4; level++) {
2254 r = soctherm_readl(TS_THERM_REG_OFFSET(CTL_LVL0_CPU0,
2256 state = REG_GET(r, CTL_LVL0_CPU0_UP_THRESH);
2257 seq_printf(s, " %d: Up/Dn(%d/", level,
2258 LOWER_PRECISION_FOR_CONV(state));
2259 state = REG_GET(r, CTL_LVL0_CPU0_DN_THRESH);
2260 seq_printf(s, "%d) ", LOWER_PRECISION_FOR_CONV(state));
2261 state = REG_GET(r, CTL_LVL0_CPU0_EN);
2262 seq_printf(s, "En(%d) ", state);
2263 state = REG_GET(r, CTL_LVL0_CPU0_CPU_THROT);
2264 seq_printf(s, "Throt");
2265 seq_printf(s, "(%s) ", state ?
2266 state == CTL_LVL0_CPU0_CPU_THROT_LIGHT ? "L" :
2267 state == CTL_LVL0_CPU0_CPU_THROT_HEAVY ? "H" :
2269 state = REG_GET(r, CTL_LVL0_CPU0_STATUS);
2270 seq_printf(s, "Status(%s)\n",
2273 state == 2 ? "??" : "HI");
2277 r = soctherm_readl(STATS_CTL);
2278 seq_printf(s, "STATS: Up(%s) Dn(%s)\n",
2279 r & STATS_CTL_EN_UP ? "En" : "--",
2280 r & STATS_CTL_EN_DN ? "En" : "--");
2281 for (level = 0; level < 4; level++) {
2282 r = soctherm_readl(TS_TSENSE_REG_OFFSET(UP_STATS_L0, level));
2283 seq_printf(s, " Level_%d Up(%d) ", level, r);
2284 r = soctherm_readl(TS_TSENSE_REG_OFFSET(DN_STATS_L0, level));
2285 seq_printf(s, "Dn(%d)\n", r);
2288 r = soctherm_readl(THERMTRIP);
2289 state = REG_GET(r, THERMTRIP_ANY_EN);
2290 seq_printf(s, "ThermTRIP ANY En(%d)\n", state);
2291 state = REG_GET(r, THERMTRIP_CPU_EN);
2292 seq_printf(s, " CPU En(%d) ", state);
2293 state = REG_GET(r, THERMTRIP_CPU_THRESH);
2294 seq_printf(s, "Thresh(%d)\n", LOWER_PRECISION_FOR_CONV(state));
2295 state = REG_GET(r, THERMTRIP_GPU_EN);
2296 seq_printf(s, " GPU En(%d) ", state);
2297 state = REG_GET(r, THERMTRIP_GPUMEM_THRESH);
2298 seq_printf(s, "Thresh(%d)\n", LOWER_PRECISION_FOR_CONV(state));
2299 state = REG_GET(r, THERMTRIP_TSENSE_EN);
2300 seq_printf(s, " PLLX En(%d) ", state);
2301 state = REG_GET(r, THERMTRIP_TSENSE_THRESH);
2302 seq_printf(s, "Thresh(%d)\n", LOWER_PRECISION_FOR_CONV(state));
2304 r = soctherm_readl(THROT_GLOBAL_CFG);
2305 seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
2307 seq_printf(s, "---------------------------------------------------\n");
2308 r = soctherm_readl(THROT_STATUS);
2309 state = REG_GET(r, THROT_STATUS_BREACH);
2310 seq_printf(s, "THROT STATUS: breach(%d) ", state);
2311 state = REG_GET(r, THROT_STATUS_STATE);
2312 seq_printf(s, "state(%d) ", state);
2313 state = REG_GET(r, THROT_STATUS_ENABLED);
2314 seq_printf(s, "enabled(%d)\n", state);
2316 for (j = 0; j < THROTTLE_DEV_SIZE; j++) {
2317 r = soctherm_readl(CPU_PSKIP_STATUS + (j * 4));
2318 state = REG_GET(r, CPU_PSKIP_STATUS_M);
2319 seq_printf(s, "%s PSKIP STATUS: M(%d) ",
2320 throt_dev_names[j], state);
2321 state = REG_GET(r, CPU_PSKIP_STATUS_N);
2322 seq_printf(s, "N(%d) ", state);
2323 state = REG_GET(r, CPU_PSKIP_STATUS_ENABLED);
2324 seq_printf(s, "enabled(%d)\n", state);
2327 seq_printf(s, "---------------------------------------------------\n");
2328 seq_printf(s, "THROTTLE control and PSKIP configuration:\n");
2329 seq_printf(s, "%5s %3s %2s %8s %7s %8s %4s %4s %5s ",
2330 "throt", "dev", "en", "dividend", "divisor", "duration",
2331 "step", "prio", "delay");
2332 seq_printf(s, "%2s %2s %2s %2s %2s %2s ",
2333 "LL", "HW", "PG", "MD", "01", "EN");
2334 seq_printf(s, "%8s %8s %8s %8s %8s\n",
2335 "thresh", "period", "count", "filter", "stats");
2336 for (i = 0; i < THROTTLE_SIZE; i++) {
2337 for (j = 0; j < THROTTLE_DEV_SIZE; j++) {
2338 r = soctherm_readl(THROT_PSKIP_CTRL(i, j));
2339 state = REG_GET(r, THROT_PSKIP_CTRL_ENABLE);
2340 seq_printf(s, "%5s %3s %2d ",
2341 j ? "" : throt_names[i],
2342 throt_dev_names[j], state);
2343 state = REG_GET(r, THROT_PSKIP_CTRL_DIVIDEND);
2344 seq_printf(s, "%8d ", state);
2345 state = REG_GET(r, THROT_PSKIP_CTRL_DIVISOR);
2346 seq_printf(s, "%7d ", state);
2347 r = soctherm_readl(THROT_PSKIP_RAMP(i, j));
2348 state = REG_GET(r, THROT_PSKIP_RAMP_DURATION);
2349 seq_printf(s, "%8d ", state);
2350 state = REG_GET(r, THROT_PSKIP_RAMP_STEP);
2351 seq_printf(s, "%4d ", state);
2354 seq_printf(s, "\n");
2358 r = soctherm_readl(THROT_PRIORITY_CTRL(i));
2359 state = REG_GET(r, THROT_PRIORITY_LITE_PRIO);
2360 seq_printf(s, "%4d ", state);
2362 r = soctherm_readl(THROT_DELAY_CTRL(i));
2363 state = REG_GET(r, THROT_DELAY_LITE_DELAY);
2364 seq_printf(s, "%5d ", state);
2366 if (i >= THROTTLE_OC1) {
2367 r = soctherm_readl(ALARM_CFG(i));
2368 state = REG_GET(r, OC1_CFG_LONG_LATENCY);
2369 seq_printf(s, "%2d ", state);
2370 state = REG_GET(r, OC1_CFG_HW_RESTORE);
2371 seq_printf(s, "%2d ", state);
2372 state = REG_GET(r, OC1_CFG_PWR_GOOD_MASK);
2373 seq_printf(s, "%2d ", state);
2374 state = REG_GET(r, OC1_CFG_THROTTLE_MODE);
2375 seq_printf(s, "%2d ", state);
2376 state = REG_GET(r, OC1_CFG_ALARM_POLARITY);
2377 seq_printf(s, "%2d ", state);
2378 state = REG_GET(r, OC1_CFG_EN_THROTTLE);
2379 seq_printf(s, "%2d ", state);
2381 r = soctherm_readl(ALARM_CNT_THRESHOLD(i));
2382 seq_printf(s, "%8d ", r);
2383 r = soctherm_readl(ALARM_THRESHOLD_PERIOD(i));
2384 seq_printf(s, "%8d ", r);
2385 r = soctherm_readl(ALARM_ALARM_COUNT(i));
2386 seq_printf(s, "%8d ", r);
2387 r = soctherm_readl(ALARM_FILTER(i));
2388 seq_printf(s, "%8d ", r);
2389 r = soctherm_readl(ALARM_STATS(i));
2390 seq_printf(s, "%8d ", r);
2392 seq_printf(s, "\n");
2398 static int regs_open(struct inode *inode, struct file *file)
2400 return single_open(file, regs_show, inode->i_private);
2403 static const struct file_operations regs_fops = {
2406 .llseek = seq_lseek,
2407 .release = single_release,
2410 static int convert_get(void *data, u64 *val)
2412 *val = !read_hw_temp;
2415 static int convert_set(void *data, u64 val)
2417 read_hw_temp = !val;
2420 DEFINE_SIMPLE_ATTRIBUTE(convert_fops, convert_get, convert_set, "%llu\n");
2422 static int __init soctherm_debug_init(void)
2424 struct dentry *tegra_soctherm_root;
2426 tegra_soctherm_root = debugfs_create_dir("tegra_soctherm", 0);
2427 debugfs_create_file("regs", 0644, tegra_soctherm_root,
2429 debugfs_create_file("convert", 0644, tegra_soctherm_root,
2430 NULL, &convert_fops);
2433 late_initcall(soctherm_debug_init);