]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - arch/arm/mach-tegra/tegra11_soctherm.c
bbe96a413788a9faf9ba2a5122956d9b2f5f17f9
[sojka/nv-tegra/linux-3.10.git] / arch / arm / mach-tegra / tegra11_soctherm.c
1 /*
2  * arch/arm/mach-tegra/tegra11_soctherm.c
3  *
4  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
5  *
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.
9  *
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
13  * more details.
14  *
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/>.
17  */
18
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>
27 #include <linux/io.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>
44
45 #include "iomap.h"
46 #include "tegra11_soctherm.h"
47 #include "gpio-names.h"
48 #include "common.h"
49 #include "dvfs.h"
50
51 static const int MAX_HIGH_TEMP = 127000;
52 static const int MIN_LOW_TEMP = -127000;
53
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
57  */
58 #ifdef CONFIG_ARCH_TEGRA_12x_SOC
59 static const int precision = -1; /* Use high precision on T12x */
60 #else
61 static const int precision; /* default 0 -> low precision */
62 #endif
63
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")
68
69 #define TS_TSENSE_REGS_SIZE             0x20
70 #define TS_TSENSE_REG_OFFSET(reg, ts)   ((reg) + ((ts) * TS_TSENSE_REGS_SIZE))
71
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))
76
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
96
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
114
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
126
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
136
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
142
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
148
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
154
155 #define TS_CPU0_STATUS2                 0xd4
156
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
166
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
174
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
180
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
186
187 #define TS_TEMP_SW_OVERRIDE             0x1d8
188
189 #define TH_INTR_STATUS                  0x84
190 #define TH_INTR_ENABLE                  0x88
191 #define TH_INTR_DISABLE                 0x8c
192
193 #define LOCK_CTL                        0x90
194
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
259
260
261 #define UP_STATS_L0             0x10
262 #define DN_STATS_L0             0x14
263
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
269
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
274
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
288
289 #define OC1_CNT_THRESHOLD               0x314
290 #define OC1_THROTTLE_PERIOD             0x318
291 #define OC1_ALARM_COUNT                 0x31c
292 #define OC1_FILTER                      0x320
293
294 #define OC1_STATS                       0x3a8
295
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
309
310 #define OC_STATS_CTL                    0x3c4
311 #define OC_STATS_CTL_CLR_ALL            0x2
312 #define OC_STATS_CTL_EN_ALL             0x1
313
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
324
325 #define THROT_PRIORITY_LOCK                     0x424
326 #define THROT_PRIORITY_LOCK_PRIORITY_SHIFT      0
327 #define THROT_PRIORITY_LOCK_PRIORITY_MASK       0xff
328
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
336
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
351
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
360
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 */
365
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 */
370
371 #define THROT_PRIORITY_LITE                     0x444
372 #define THROT_PRIORITY_LITE_PRIO_SHIFT          0
373 #define THROT_PRIORITY_LITE_PRIO_MASK           0xff
374
375 #define THROT_DELAY_LITE                        0x448
376 #define THROT_DELAY_LITE_DELAY_SHIFT            0
377 #define THROT_DELAY_LITE_DELAY_MASK             0xff
378
379 #define THROT_OFFSET                            0x30
380 #define THROT13_OFFSET                          0x0c
381 #define ALARM_OFFSET                            0x14
382
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
388
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
400
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) + \
406                                                 (8 * dev))
407 #define THROT_PSKIP_RAMP(throt, dev)            (THROT_PSKIP_RAMP_LITE_CPU + \
408                                                 (THROT_OFFSET * throt) + \
409                                                 (8 * dev))
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 - \
420                                                                 THROTTLE_OC1)))
421 #define ALARM_CNT_THRESHOLD(throt)              (OC1_CNT_THRESHOLD + \
422                                                 (ALARM_OFFSET * (throt - \
423                                                                 THROTTLE_OC1)))
424 #define ALARM_THROTTLE_PERIOD(throt)            (OC1_THROTTLE_PERIOD + \
425                                                 (ALARM_OFFSET * (throt - \
426                                                                 THROTTLE_OC1)))
427 #define ALARM_ALARM_COUNT(throt)                (OC1_ALARM_COUNT + \
428                                                 (ALARM_OFFSET * (throt - \
429                                                                 THROTTLE_OC1)))
430 #define ALARM_FILTER(throt)                     (OC1_FILTER + \
431                                                 (ALARM_OFFSET * (throt - \
432                                                                 THROTTLE_OC1)))
433 #define ALARM_STATS(throt)                      (OC1_STATS + \
434                                                 (4 * (throt - THROTTLE_OC1)))
435
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;                          \
442                 (th)->step     = 0xf;                           \
443         }
444
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)))
450
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)
455
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));
459
460 static DEFINE_MUTEX(soctherm_suspend_resume_lock);
461
462 static int soctherm_suspend(void);
463 static int soctherm_resume(void);
464
465 static struct soctherm_platform_data plat_data;
466
467 /*
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.
471  */
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;
478
479 static struct clk *soctherm_clk;
480 static struct clk *tsensor_clk;
481
482 /**
483  * soctherm_writel() - Writes a value to a SOC_THERM register
484  * @value:              The value to write
485  * @reg:                The register offset
486  *
487  * Writes the @value to @reg if the soctherm device is not suspended.
488  */
489 static inline void soctherm_writel(u32 value, u32 reg)
490 {
491         if (!soctherm_suspended)
492                 __raw_writel(value, (void __iomem *)
493                         (reg_soctherm_base + reg));
494 }
495
496 /**
497  * soctherm_readl() - reads specified register from SOC_THERM IP block
498  * @reg:        register address to be read
499  *
500  * Return: 0 if SOC_THERM is suspended, else the value of the register
501  */
502 static inline u32 soctherm_readl(u32 reg)
503 {
504         if (soctherm_suspended)
505                 return 0;
506         return __raw_readl(reg_soctherm_base + reg);
507 }
508
509 /* XXX Temporary until CCROC accesses are split out */
510 static void clk_reset13_writel(u32 value, u32 reg)
511 {
512         BUG_ON(!IS_T13X);
513         __raw_writel(value, clk13_rst_base + reg);
514         __raw_readl(clk13_rst_base + reg);
515 }
516
517 /* XXX Temporary until CCROC accesses are split out */
518 static u32 clk_reset13_readl(u32 reg)
519 {
520         BUG_ON(!IS_T13X);
521         return __raw_readl(clk13_rst_base + reg);
522 }
523
524 static inline void clk_reset_writel(u32 value, u32 reg)
525 {
526         if (IS_T13X) {
527                 __raw_writel(value, clk13_rst_base + reg);
528                 __raw_readl(clk13_rst_base + reg);
529         } else
530                 __raw_writel(value, clk_reset_base + reg);
531 }
532
533 static inline u32 clk_reset_readl(u32 reg)
534 {
535         if (IS_T13X)
536                 return __raw_readl(clk13_rst_base + reg);
537         else
538                 return __raw_readl(clk_reset_base + reg);
539 }
540
541 /**
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
546  *
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.
550  *
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.
554  *
555  * Return: temperature in millicelsius.
556  */
557 static inline long temp_convert(int cap, int a, int b)
558 {
559         cap *= a;
560         cap >>= 10;
561         cap += (b << 3);
562         cap *= LOWER_PRECISION_FOR_CONV(500);
563         cap /= 8;
564         return cap;
565 }
566
567 /**
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
571  *
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
575  *
576  * This function is the inverse of the temp_translate() function
577  *
578  * Return: The register value.
579  */
580 static inline u32 temp_translate_rev(long temp)
581 {
582         int sign;
583         int low_bit;
584
585         u32 lsb = 0;
586         u32 abs = 0;
587         u32 reg = 0;
588         sign = (temp > 0 ? 1 : -1);
589         low_bit = (sign > 0 ? 0 : 1);
590         temp *= sign;
591         /* high precision only */
592         if (!PRECISION_IS_LOWER()) {
593                 lsb = ((temp % 1000) > 0) ? 1 : 0;
594                 abs = (temp - 500 * lsb) / 1000;
595                 abs &= 0xff;
596                 reg = ((abs << 8) | (lsb << 7) | low_bit);
597         }
598         return reg;
599 }
600
601 #ifdef CONFIG_THERMAL
602 static struct thermal_zone_device *soctherm_th_zones[THERM_SIZE];
603 #endif
604 struct soctherm_oc_irq_chip_data {
605         int                     irq_base;
606         struct mutex            irq_lock; /* serialize OC IRQs */
607         struct irq_chip         irq_chip;
608         struct irq_domain       *domain;
609         int                     irq_enable;
610 };
611 static struct soctherm_oc_irq_chip_data soc_irq_cdata;
612
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;
617
618 static const char *const therm_names[] = {
619         [THERM_CPU] = "CPU",
620         [THERM_MEM] = "MEM",
621         [THERM_GPU] = "GPU",
622         [THERM_PLL] = "PLL",
623 };
624
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 */
633 };
634
635 static const char *const throt_dev_names[] = {
636         [THROTTLE_DEV_CPU] = "CPU",
637         [THROTTLE_DEV_GPU] = "GPU",
638 };
639
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",
649 };
650
651 static const int sensor2tsensorcalib[] = {
652         [TSENSE_CPU0] = 0,
653         [TSENSE_CPU1] = 1,
654         [TSENSE_CPU2] = 2,
655         [TSENSE_CPU3] = 3,
656         [TSENSE_MEM0] = 5,
657         [TSENSE_MEM1] = 6,
658         [TSENSE_GPU]  = 4,
659         [TSENSE_PLLX] = 7,
660 };
661
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,
671 };
672
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,
678 };
679
680 static const struct soctherm_sensor default_t11x_sensor_params = {
681         .tall      = 16300,
682         .tiddq     = 1,
683         .ten_count = 1,
684         .tsample   = 163,
685         .tsamp_ate = 655,
686         .pdiv      = 10,
687         .pdiv_ate  = 10,
688 };
689 static const struct soctherm_sensor default_t14x_sensor_params = {
690         .tall      = 16300,
691         .tiddq     = 1,
692         .ten_count = 1,
693         .tsample   = 120,
694         .tsamp_ate = 481,
695         .pdiv      = 8,
696         .pdiv_ate  = 8,
697 };
698
699 /* Used for T124 and T132 */
700 static const struct soctherm_sensor default_t12x_sensor_params = {
701         .tall      = 16300,
702         .tiddq     = 1,
703         .ten_count = 1,
704         .tsample   = 120,
705         .tsamp_ate = 480,
706         .pdiv      = 8,
707         .pdiv_ate  = 8,
708 };
709
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;
717
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 */
725 };
726
727 static int sensor2therm_a[TSENSE_SIZE];
728 static int sensor2therm_b[TSENSE_SIZE];
729
730 /**
731  * div64_s64_precise() - wrapper for div64_s64()
732  * @a:  the dividend
733  * @b:  the divisor
734  *
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.
738  *
739  * Return: the quotient of a / b.
740  */
741
742 static inline s64 div64_s64_precise(s64 a, s32 b)
743 {
744         s64 r, al;
745
746         /* scale up for increased precision in division */
747         al = a << 16;
748
749         r = div64_s64((al * 2) + 1, 2 * b);
750         return r >> 16;
751 }
752
753 /**
754  * temp_translate() - Converts temperature
755  * @readback:           The value from a SOC_THERM sensor temperature
756  *                      register
757  *
758  * Converts temperature from the format used in registers to a (signed)
759  * long. This function is the inverse of temp_translate_rev().
760  *
761  * Return: the translated temperature in millicelsius
762  */
763 static inline long temp_translate(int readback)
764 {
765         int abs = readback >> 8;
766         int lsb = (readback & 0x80) >> 7;
767         int sign = readback & 0x01 ? -1 : 1;
768
769         return (abs * LOWER_PRECISION_FOR_CONV(1000) +
770                 lsb * LOWER_PRECISION_FOR_CONV(500)) * sign;
771 }
772
773 #ifdef CONFIG_THERMAL
774
775 /**
776  * soctherm_has_mn_cpu_pskip_status() - does CPU use M,N values for pskip status?
777  *
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.
782  *
783  * Return: true if CPU thermal pulse-skipper M,N status values are available via
784  * SOC_THERM, or false if not.
785  */
786 static int soctherm_has_mn_cpu_pskip_status(void)
787 {
788         return IS_T11X || IS_T14X || IS_T12X;
789 }
790
791 /**
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
797  *
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
806  *
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.
810  */
811 int soctherm_get_mn_cpu_pskip_status(u8 *enabled, u8 *sw_override, u16 *m,
812                                      u16 *n)
813 {
814         u32 v;
815
816         if (!enabled || !m || !n || !sw_override)
817                 return -EINVAL;
818
819         /*
820          * XXX should be replaced with an earlier DT property read to
821          * determine the GPU type (or GPU->SOC_THERM integration) in
822          * use
823          */
824         if (!soctherm_has_mn_cpu_pskip_status())
825                 return -ENOTSUPP;
826
827         v = soctherm_readl(CPU_PSKIP_STATUS);
828         if (REG_GET(v, XPU_PSKIP_STATUS_ENABLED)) {
829                 *enabled = 1;
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;
833         } else {
834                 *enabled = 0;
835         }
836
837         return 0;
838 }
839
840 /**
841  * soctherm_has_gpu_pskip_status() - is GPU pskip state readable via SOC_THERM?
842  *
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.
847  *
848  * Return: true if GPU thermal pulse-skipper status is readable via
849  * SOC_THERM, or false if not.
850  */
851 static int soctherm_has_gpu_pskip_status(void)
852 {
853         return IS_T11X || IS_T14X;
854 }
855
856 /**
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
862  *
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.
869  *
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.
873  */
874 int soctherm_get_gpu_pskip_status(u8 *enabled, u8 *sw_override, u16 *m, u16 *n)
875 {
876         u32 v;
877
878         if (!enabled || !m || !n || !sw_override)
879                 return -EINVAL;
880
881         /*
882          * XXX should be replaced with an earlier DT property read to
883          * determine the GPU type (or GPU->SOC_THERM integration) in
884          * use
885          */
886         if (!soctherm_has_gpu_pskip_status())
887                 return -ENOTSUPP;
888
889         v = soctherm_readl(GPU_PSKIP_STATUS);
890         if (REG_GET(v, XPU_PSKIP_STATUS_ENABLED)) {
891                 *enabled = 1;
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;
895         } else {
896                 *enabled = 0;
897         }
898
899         return 0;
900 }
901
902 /**
903  * enforce_temp_range() - check and enforce temperature range [min, max]
904  * @trip_temp:          The trip temperature to check
905  *
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.
909  *
910  * Return: The precsion adjusted capped temperature in millicelsius.
911  */
912 static int enforce_temp_range(long trip_temp)
913 {
914         long temp = LOWER_PRECISION_FOR_TEMP(trip_temp);
915
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));
919                 temp = 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;
924         }
925
926         return temp;
927 }
928
929 /**
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.
938  *
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.
942  *
943  * Return: No return value (void).
944  */
945 static inline void prog_hw_shutdown(struct thermal_trip_info *trip_state,
946                                     int therm)
947 {
948         u32 r;
949         int temp;
950
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);
953
954         temp = enforce_temp_range(temp) / 1000;
955
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);
969         }
970         r = REG_SET(r, THERMTRIP_ANY_EN, 0);
971         soctherm_writel(r, THERMTRIP);
972 }
973
974 /**
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
980  *
981  * Configure sensor group @therm to engage a hardware throttling response at
982  * the threshold indicated by @trip_state.
983  *
984  * Checks to see if HW config register needs reprogramming:
985  *
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).
989  *
990  * Avoid unnecessary events by checking if the trip config register is
991  * being configured to the same settings and skipping the write.
992  */
993 static inline void prog_hw_threshold(struct thermal_trip_info *trip_state,
994                                      int therm, int throt)
995 {
996         u32 r, reg_off;
997         int temp;
998         bool reprogram;
999         int cpu_throt, gpu_throt;
1000
1001         temp = enforce_temp_range(trip_state->trip_temp) / 1000;
1002
1003         /* Hardcode LITE on level-1 and HEAVY on level-2 */
1004         reg_off = TS_THERM_REG_OFFSET(CTL_LVL0_CPU0, throt + 1, therm);
1005
1006         if (throt == THROTTLE_LIGHT) {
1007                 cpu_throt = CTL_LVL0_CPU0_CPU_THROT_LIGHT;
1008                 gpu_throt = CTL_LVL0_CPU0_GPU_THROT_LIGHT;
1009         } else {
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",
1014                                 throt);
1015         }
1016
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));
1023
1024         if (reprogram) {
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);
1031         }
1032 }
1033
1034 /**
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
1040  *
1041  * Configures sensor group @therm to raise an interrupt when temperature goes
1042  * above @hi_limit or below @lo_limit.
1043  *
1044  * Checks to see if HW config register needs reprogramming. See comment in
1045  * prog_hw_threshold().
1046  */
1047 static void soctherm_set_limits(enum soctherm_therm_id therm,
1048                                 long lo_limit, long hi_limit)
1049 {
1050         u32 r, reg_off;
1051         int rlo_limit, rhi_limit;
1052         bool reprogram;
1053
1054         rlo_limit = LOWER_PRECISION_FOR_TEMP(lo_limit) / 1000;
1055         rhi_limit = LOWER_PRECISION_FOR_TEMP(hi_limit) / 1000;
1056
1057         reg_off = TS_THERM_REG_OFFSET(CTL_LVL0_CPU0, 0, therm);
1058         r = soctherm_readl(reg_off);
1059
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));
1063
1064         if (reprogram) {
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);
1069         }
1070
1071         switch (therm) {
1072         case THERM_CPU:
1073                 r = REG_SET(0, TH_INTR_POS_CD0, 1);
1074                 r = REG_SET(r, TH_INTR_POS_CU0, 1);
1075                 break;
1076         case THERM_GPU:
1077                 r = REG_SET(0, TH_INTR_POS_GD0, 1);
1078                 r = REG_SET(r, TH_INTR_POS_GU0, 1);
1079                 break;
1080         case THERM_PLL:
1081                 r = REG_SET(0, TH_INTR_POS_PD0, 1);
1082                 r = REG_SET(r, TH_INTR_POS_PU0, 1);
1083                 break;
1084         case THERM_MEM:
1085                 r = REG_SET(0, TH_INTR_POS_MD0, 1);
1086                 r = REG_SET(r, TH_INTR_POS_MU0, 1);
1087                 break;
1088         default:
1089                 r = 0;
1090                 break;
1091         }
1092         soctherm_writel(r, TH_INTR_ENABLE);
1093 }
1094
1095 /**
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.
1100  *
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.
1104  *
1105  * Return: Nothing is returned (void).
1106  */
1107 static void soctherm_update_zone(int zn)
1108 {
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];
1114         int count, trips;
1115
1116         thermal_zone_device_update(cur_thz);
1117
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 */
1123
1124                 cur_thz->ops->get_trip_temp(cur_thz, count, &trip_temp);
1125
1126                 trip_state = &plat_data.therm[zn].trips[count];
1127                 zone_temp = cur_thz->temperature;
1128
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;
1137                         } else {
1138                                 /* get lowest PASSIVE */
1139                                 if (trip_temp < passive_low_temp)
1140                                         passive_low_temp = trip_temp;
1141                         }
1142                 }
1143         }
1144
1145         if (passive_low_temp != MAX_HIGH_TEMP)
1146                 low_temp = max(low_temp, passive_low_temp);
1147
1148         soctherm_set_limits(zn, low_temp, high_temp);
1149 }
1150
1151 /**
1152  * soctherm_update() - updates all thermal zones
1153  *
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.
1157  */
1158 static void soctherm_update(void)
1159 {
1160         int i;
1161
1162         if (!soctherm_init_platform_done)
1163                 return;
1164
1165         for (i = 0; i < THERM_SIZE; i++) {
1166                 if (soctherm_th_zones[i] && soctherm_th_zones[i]->trips)
1167                         soctherm_update_zone(i);
1168         }
1169 }
1170
1171 /**
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
1176   *
1177   * Sets @max_state = 3. See soctherm_hw_action_get_cur_state.
1178   *
1179   * Return: 0
1180   */
1181 static int soctherm_hw_action_get_max_state(struct thermal_cooling_device *cdev,
1182                                             unsigned long *max_state)
1183 {
1184         struct thermal_trip_info *trip_state = cdev->devdata;
1185
1186         if (!trip_state)
1187                 return 0;
1188
1189         *max_state = 3; /* bit 1: CPU  bit 2: GPU */
1190         return 0;
1191 }
1192
1193 /**
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
1198  *
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.
1207  *
1208  * FIXME: For T132 switch to Denver:CCROC NV_THERM style status.  Does
1209  * not currently work on T132.
1210  *
1211  * Return: 0 upon success, -ENOTSUPP on T12x and T13x, or -EINVAL if
1212  * the arguments are invalid or out of range.
1213  *
1214  */
1215 static int soctherm_get_cpu_throt_state(u16 dividend, u16 divisor,
1216                                         unsigned long *cur_state)
1217 {
1218         u16 m, n;
1219         u8 enabled, sw_override;
1220
1221         if (!cur_state || dividend == 0 || divisor == 0 ||
1222             dividend > 256 || divisor > 256)
1223                 return -EINVAL;
1224
1225         if (soctherm_has_mn_cpu_pskip_status()) {
1226                 soctherm_get_mn_cpu_pskip_status(&enabled, &sw_override, &m, &n);
1227
1228                 if (enabled && m == dividend && n == divisor)
1229                         *cur_state |= (1 << THROTTLE_DEV_CPU);
1230         } else {
1231                 pr_warn_once("CPU throttling status not yet available on this SoC\n");
1232                 return -EINVAL;
1233         }
1234
1235         return 0;
1236 }
1237
1238 /**
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
1243  *
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.
1252  *
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.
1256  *
1257  * Return: 0 upon success, -ENOTSUPP on T12x and T13x, or -EINVAL if
1258  * the arguments are invalid or out of range.
1259  */
1260 static int soctherm_get_gpu_throt_state(u16 dividend, u16 divisor,
1261                                         unsigned long *cur_state)
1262 {
1263         u16 m, n;
1264         u8 enabled, sw_override;
1265         int r;
1266
1267         if (!cur_state || dividend == 0 || divisor == 0 ||
1268             dividend > 256 || divisor > 256)
1269                 return -EINVAL;
1270
1271         /*
1272          * XXX should be replaced with an earlier DT property read to
1273          * determine the GPU type (or GPU->SOC_THERM integration) in
1274          * use
1275          */
1276         if (!soctherm_has_gpu_pskip_status())
1277                 return -ENOTSUPP;
1278
1279         r = soctherm_get_gpu_pskip_status(&enabled, &sw_override, &m, &n);
1280         if (r) {
1281                 WARN_ON(1);
1282                 return r;
1283         }
1284
1285         if (!enabled)
1286                 return 0;
1287
1288         *cur_state |= (m == dividend && n == divisor) ?
1289                 (1 << THROTTLE_DEV_GPU) : 0;
1290
1291         return r;
1292 }
1293
1294 /**
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
1298  *
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
1302  * function.
1303  *
1304  * Return: 0.
1305  */
1306 static int soctherm_hw_action_get_cur_state(struct thermal_cooling_device *cdev,
1307                                             unsigned long *cur_state)
1308 {
1309         struct thermal_trip_info *trip_state = cdev->devdata;
1310         struct soctherm_throttle_dev *devs;
1311         int i, r;
1312
1313         if (!trip_state)
1314                 return 0;
1315
1316         *cur_state = 0;
1317         if (trip_state->trip_type != THERMAL_TRIP_HOT)
1318                 return 0;
1319
1320         for (i = THROTTLE_LIGHT; i <= THROTTLE_HEAVY; i++) {
1321                 if (!strnstr(trip_state->cdev_type, throt_names[i],
1322                              THERMAL_NAME_LENGTH))
1323                         continue;
1324
1325                 devs = &plat_data.throttle[i].devs[THROTTLE_DEV_CPU];
1326                 if (devs->enable)
1327                         soctherm_get_cpu_throt_state(devs->dividend + 1,
1328                                                      devs->divisor + 1,
1329                                                      cur_state);
1330
1331                 devs = &plat_data.throttle[i].devs[THROTTLE_DEV_GPU];
1332                 if (devs->enable) {
1333                         r = soctherm_get_gpu_throt_state(devs->dividend + 1,
1334                                                          devs->divisor + 1,
1335                                                          cur_state);
1336                         /*
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
1352                          * CPU status.
1353                          */
1354                         if (r == -ENOTSUPP)
1355                                 if (*cur_state & (1 << THROTTLE_DEV_CPU))
1356                                         *cur_state |= (1 << THROTTLE_DEV_GPU);
1357                 }
1358
1359         }
1360
1361         return 0;
1362 }
1363
1364 static int soctherm_hw_action_set_cur_state(struct thermal_cooling_device *cdev,
1365                                             unsigned long cur_state)
1366 {
1367         return 0; /* hw sets this state */
1368 }
1369
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,
1377 };
1378
1379 static int soctherm_suspend_get_max_state(struct thermal_cooling_device *cdev,
1380                                           unsigned long *max_state)
1381 {
1382         *max_state = 1;
1383         return 0;
1384 }
1385
1386 static int soctherm_suspend_get_cur_state(struct thermal_cooling_device *cdev,
1387                                           unsigned long *cur_state)
1388 {
1389         *cur_state = !soctherm_suspended;
1390         return 0;
1391 }
1392
1393 /**
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
1397  *
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
1403  * be removed
1404  * Return: 0 (success).
1405  */
1406 static int soctherm_suspend_set_cur_state(struct thermal_cooling_device *cdev,
1407                                           unsigned long cur_state)
1408 {
1409         if (!cur_state != soctherm_suspended) {
1410                 if (cur_state)
1411                         soctherm_resume();
1412                 else
1413                         soctherm_suspend();
1414         }
1415         return 0;
1416 }
1417
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,
1422 };
1423
1424 /**
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
1429  *
1430  * If thermal sensor calibration data is missing from fuses,
1431  * the cooling devices are not bound.
1432  *
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.
1436  *
1437  * soctherm_bind is called as a thermal_zone_device_ops bind function.
1438  *
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
1442  * occur.
1443  */
1444 static int soctherm_bind(struct thermal_zone_device *thz,
1445                                 struct thermal_cooling_device *cdev)
1446 {
1447         int i;
1448         struct soctherm_therm *therm = thz->devdata;
1449         struct thermal_trip_info *trip_state;
1450
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)
1454                 return 0;
1455
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,
1462                                                          trip_state->upper,
1463                                                          trip_state->lower);
1464                         trip_state->bound = true;
1465                 }
1466         }
1467
1468         return 0;
1469 }
1470
1471 /**
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
1475  *
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.
1479  *
1480  * Return: 0
1481  */
1482 static int soctherm_unbind(struct thermal_zone_device *thz,
1483                                 struct thermal_cooling_device *cdev)
1484 {
1485         int i;
1486         struct soctherm_therm *therm = thz->devdata;
1487         struct thermal_trip_info *trip_state;
1488
1489         for (i = 0; i < therm->num_trips; i++) {
1490                 trip_state = &therm->trips[i];
1491                 if (!trip_state->bound)
1492                         continue;
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;
1498                 }
1499         }
1500
1501         return 0;
1502 }
1503
1504 /**
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
1508  *
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
1512  * registered.
1513  *
1514  * Return: 0
1515  */
1516 static int soctherm_get_temp(struct thermal_zone_device *thz, long *temp)
1517 {
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;
1522         int tt, ti;
1523
1524         switch (index) {
1525         case THERM_CPU:
1526                 regv = TS_TEMP1;
1527                 shft = TS_TEMP1_CPU_TEMP_SHIFT;
1528                 mask = TS_TEMP1_CPU_TEMP_MASK;
1529                 i = TSENSE_CPU0;
1530                 j = TSENSE_CPU3;
1531                 break;
1532
1533         case THERM_GPU:
1534                 regv = TS_TEMP1;
1535                 shft = TS_TEMP1_GPU_TEMP_SHIFT;
1536                 mask = TS_TEMP1_GPU_TEMP_MASK;
1537                 i = TSENSE_GPU;
1538                 j = TSENSE_GPU;
1539                 break;
1540
1541         case THERM_MEM:
1542                 regv = TS_TEMP2;
1543                 shft = TS_TEMP2_MEM_TEMP_SHIFT;
1544                 mask = TS_TEMP2_MEM_TEMP_MASK;
1545                 i = TSENSE_MEM0;
1546                 j = TSENSE_MEM1;
1547                 break;
1548
1549         case THERM_PLL:
1550         default: /* if devdata has error, return PLL temp to be safe */
1551                 regv = TS_TEMP2;
1552                 shft = TS_TEMP2_PLLX_TEMP_SHIFT;
1553                 mask = TS_TEMP2_PLLX_TEMP_MASK;
1554                 i = TSENSE_PLLX;
1555                 j = TSENSE_PLLX;
1556                 break;
1557         }
1558
1559         if (read_hw_temp) {
1560                 r = soctherm_readl(regv);
1561                 *temp = temp_translate((r & (mask << shft)) >> shft);
1562         } else {
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),
1567                                                 sensor2therm_a[i],
1568                                                 sensor2therm_b[i]);
1569                         *temp = tt = max(tt, ti);
1570                 }
1571         }
1572         return 0;
1573 }
1574
1575 /**
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.
1581  *
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
1585  *
1586  * This function is passed to the thermal framework as a callback
1587  * for each of the SOC_THERM-related thermal zones
1588  *
1589  * Return: Returns 0 on success, -EINVAL when passed an invalid argument.
1590  */
1591 static int soctherm_get_trip_type(struct thermal_zone_device *thz,
1592                                 int trip, enum thermal_trip_type *type)
1593 {
1594         struct soctherm_therm *therm = thz->devdata;
1595
1596         *type = therm->trips[trip].trip_type;
1597         return 0;
1598 }
1599
1600 /**
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
1605  *
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.
1610  *
1611  * Return: 0 if success, otherwise %-EINVAL.
1612  */
1613
1614 static int soctherm_get_trip_temp(struct thermal_zone_device *thz,
1615                                 int trip, long *temp)
1616 {
1617         struct soctherm_therm *therm = thz->devdata;
1618         struct thermal_trip_info *trip_state;
1619         long trip_temp, zone_temp;
1620
1621         trip_state = &therm->trips[trip];
1622         trip_temp = trip_state->trip_temp;
1623         zone_temp = thz->temperature;
1624
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;
1632         }
1633
1634         *temp = trip_temp;
1635         return 0;
1636 }
1637
1638 /**
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
1644  *
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.
1648  *
1649  * Return: 0 if successful else %-EINVAL
1650  */
1651 static int soctherm_set_trip_temp(struct thermal_zone_device *thz,
1652                                 int trip, long temp)
1653 {
1654         struct soctherm_therm *therm = thz->devdata;
1655         struct thermal_trip_info *trip_state;
1656         ptrdiff_t index = therm - plat_data.therm;
1657         long rem;
1658
1659         trip_state = &therm->trips[trip];
1660         trip_state->trip_temp = enforce_temp_range(temp);
1661
1662         rem = trip_state->trip_temp % LOWER_PRECISION_FOR_CONV(1000);
1663         if (rem) {
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;
1667         }
1668
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);
1676         }
1677
1678         /* Allow SW to shutdown at 'Critical temperature reached' */
1679         thermal_notify_framework(thz, trip);
1680
1681         /* Reprogram HW thermtrip */
1682         if (trip_state->trip_type == THERMAL_TRIP_CRITICAL)
1683                 prog_hw_shutdown(trip_state, index);
1684
1685         return 0;
1686 }
1687
1688 /**
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
1692  *
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.
1695  *
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.
1698  */
1699 static int soctherm_get_crit_temp(struct thermal_zone_device *thz, long *temp)
1700 {
1701         int i;
1702         struct soctherm_therm *therm = thz->devdata;
1703         struct thermal_trip_info *trip_state;
1704
1705         for (i = 0; i < therm->num_trips; i++) {
1706                 trip_state = &therm->trips[i];
1707                 if (trip_state->trip_type != THERMAL_TRIP_CRITICAL)
1708                         continue;
1709                 *temp = trip_state->trip_temp;
1710                 return 0;
1711         }
1712
1713         return -EINVAL;
1714 }
1715
1716 /**
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
1722  *
1723  * This function is passed to the thermal framework as a callback
1724  * for SOC_THERM's thermal zone devices
1725  *
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
1732  *
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.
1739  *
1740  * Return: 0 on success. Returns -EINVAL if the function was
1741  * passed an invalid argument.
1742  */
1743 static int soctherm_get_trend(struct thermal_zone_device *thz,
1744                                 int trip,
1745                                 enum thermal_trend *trend)
1746 {
1747         struct soctherm_therm *therm = thz->devdata;
1748         struct thermal_trip_info *trip_state;
1749         long trip_temp;
1750
1751         trip_state = &therm->trips[trip];
1752         thz->ops->get_trip_temp(thz, trip, &trip_temp);
1753
1754         switch (trip_state->trip_type) {
1755         case THERMAL_TRIP_ACTIVE:
1756                 /* aggressive active cooling */
1757                 *trend = THERMAL_TREND_RAISING;
1758                 break;
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;
1764                 else
1765                         *trend = THERMAL_TREND_STABLE;
1766                 break;
1767         default:
1768                 return -EINVAL;
1769         }
1770         return 0;
1771 }
1772
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,
1782 };
1783
1784 /**
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
1789   *
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
1793   * sensor group @i
1794   *
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.
1798   *
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.
1802   */
1803 static void __init soctherm_hot_cdev_register(int i, int trip)
1804 {
1805         struct soctherm_therm *therm;
1806         int k;
1807
1808         therm = &plat_data.therm[i];
1809
1810         for (k = 0; k < THROTTLE_SIZE; k++) {
1811                 if ((therm2dev[i] == THROTTLE_DEV_NONE) ||
1812                     (!plat_data.throttle[k].devs[therm2dev[i]].enable))
1813                         continue;
1814
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))
1823                         continue;
1824
1825                 if (strnstr(therm->trips[trip].cdev_type,
1826                             "heavy",
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);
1835                         continue;
1836                 }
1837
1838                 if (strnstr(therm->trips[trip].cdev_type,
1839                             "light",
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);
1848                         continue;
1849                 }
1850         }
1851 }
1852
1853 /**
1854  * soctherm_thermal_sys_init() - initializes the SOC_THERM thermal system
1855  *
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.
1861  *
1862  * Once all of the thermal zones have been registered, it runs
1863  * soctherm_update(), which sets high and low temperature thresholds.
1864  *
1865  * Runs at kernel boot-time.
1866  *
1867  * Return: 0
1868  */
1869 static int __init soctherm_thermal_sys_init(void)
1870 {
1871         char name[THERMAL_NAME_LENGTH];
1872         struct soctherm_therm *therm;
1873         bool oc_en = false;
1874         int i, j;
1875
1876         if (!soctherm_init_platform_done)
1877                 return 0;
1878
1879         for (i = 0; i < THERM_SIZE; i++) {
1880                 therm = &plat_data.therm[i];
1881                 if (!therm->zone_enable)
1882                         continue;
1883
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)
1888                                         break;
1889                                 soctherm_hw_critical_cdev =
1890                                         thermal_cooling_device_register(
1891                                                 therm->trips[j].cdev_type,
1892                                                 &therm->trips[j],
1893                                                 &soctherm_hw_action_ops);
1894                                 break;
1895
1896                         case THERMAL_TRIP_HOT:
1897                                 soctherm_hot_cdev_register(i, j);
1898                                 break;
1899
1900                         case THERMAL_TRIP_PASSIVE:
1901                         case THERMAL_TRIP_ACTIVE:
1902                                 break; /* done elsewhere */
1903                         }
1904                 }
1905
1906                 snprintf(name, THERMAL_NAME_LENGTH, "%s-therm", therm_names[i]);
1907                 soctherm_th_zones[i] = thermal_zone_device_register(
1908                                                 name,
1909                                                 therm->num_trips,
1910                                                 (1ULL << therm->num_trips) - 1,
1911                                                 therm,
1912                                                 &soctherm_ops,
1913                                                 therm->tzp,
1914                                                 therm->passive_delay,
1915                                                 0);
1916
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))
1920                                 oc_en = true;
1921         }
1922
1923         /* do not enable suspend feature if any OC alarms are enabled */
1924         if (!oc_en)
1925                 thermal_cooling_device_register("suspend_soctherm", NULL,
1926                                                 &soctherm_suspend_ops);
1927         else
1928                 pr_warn("soctherm: Suspend feature CANNOT be enabled %s\n",
1929                         "when any OC alarm is enabled");
1930
1931         soctherm_update();
1932         return 0;
1933 }
1934 module_init(soctherm_thermal_sys_init);
1935
1936 #else
1937 static void soctherm_update_zone(int zn)
1938 {
1939 }
1940 static void soctherm_update(void)
1941 {
1942 }
1943 #endif
1944
1945 /**
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
1949  *
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
1953  * thermal zones.
1954  *
1955  * An error is logged if any unexpected interrupt bits are set.
1956  *
1957  * Disabled interrupts are re-enabled.
1958  *
1959  * Return: %IRQ_HANDLED. Interrupt was handled and no further processing
1960  * is needed.
1961  */
1962 static irqreturn_t soctherm_thermal_thread_func(int irq, void *arg)
1963 {
1964         u32 st, ex = 0, cp = 0, gp = 0, pl = 0;
1965
1966         st = soctherm_readl(TH_INTR_STATUS);
1967
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);
1971         ex |= cp;
1972
1973         gp |= REG_GET_BIT(st, TH_INTR_POS_GD0);
1974         gp |= REG_GET_BIT(st, TH_INTR_POS_GU0);
1975         ex |= gp;
1976
1977         pl |= REG_GET_BIT(st, TH_INTR_POS_PD0);
1978         pl |= REG_GET_BIT(st, TH_INTR_POS_PU0);
1979         ex |= pl;
1980
1981         if (ex) {
1982                 soctherm_writel(ex, TH_INTR_STATUS);
1983                 st &= ~ex;
1984                 if (cp)
1985                         soctherm_update_zone(THERM_CPU);
1986                 if (gp)
1987                         soctherm_update_zone(THERM_GPU);
1988                 if (pl)
1989                         soctherm_update_zone(THERM_PLL);
1990         }
1991
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);
1995
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);
2002
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);
2009
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);
2016
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);
2023         st &= ~ex;
2024
2025         if (st) {
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);
2029         }
2030
2031         return IRQ_HANDLED;
2032 }
2033
2034 /**
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
2039  *
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.
2042  */
2043 static inline void soctherm_oc_intr_enable(enum soctherm_throttle_id alarm,
2044                                            bool enable)
2045 {
2046         u32 r;
2047
2048         if (!enable)
2049                 return;
2050
2051         r = soctherm_readl(OC_INTR_ENABLE);
2052         switch (alarm) {
2053         case THROTTLE_OC1:
2054                 r = REG_SET(r, OC_INTR_POS_OC1, 1);
2055                 break;
2056         case THROTTLE_OC2:
2057                 r = REG_SET(r, OC_INTR_POS_OC2, 1);
2058                 break;
2059         case THROTTLE_OC3:
2060                 r = REG_SET(r, OC_INTR_POS_OC3, 1);
2061                 break;
2062         case THROTTLE_OC4:
2063                 r = REG_SET(r, OC_INTR_POS_OC4, 1);
2064                 break;
2065         default:
2066                 r = 0;
2067                 break;
2068         }
2069         soctherm_writel(r, OC_INTR_ENABLE);
2070 }
2071
2072 /**
2073  * soctherm_handle_alarm() - Handles soctherm alarms
2074  * @alarm:              The soctherm throttle id
2075  *
2076  * "Handles" over-current alarms (OC1, OC2, OC3, and OC4) by printing
2077  * a warning or informative message.
2078  *
2079  * Return: -EINVAL for @alarm = THROTTLE_OC3, otherwise 0 (success).
2080  */
2081 static int soctherm_handle_alarm(enum soctherm_throttle_id alarm)
2082 {
2083         int rv = -EINVAL;
2084
2085         switch (alarm) {
2086         case THROTTLE_OC1:
2087                 pr_debug("soctherm: Successfully handled OC1 alarm\n");
2088                 /* add OC1 alarm handling code here */
2089                 rv = 0;
2090                 break;
2091
2092         case THROTTLE_OC2:
2093                 pr_info("soctherm: Successfully handled OC2 alarm\n");
2094                 /* TODO: add OC2 alarm handling code here */
2095                 rv = 0;
2096                 break;
2097
2098         case THROTTLE_OC3:
2099                 pr_warn("soctherm: Unexpected OC3 alarm\n");
2100                 /* add OC3 alarm handling code here */
2101                 break;
2102
2103         case THROTTLE_OC4:
2104                 pr_debug("soctherm: Successfully handled OC4 alarm\n");
2105                 /* TODO: add OC4 alarm handling code here */
2106                 rv = 0;
2107                 break;
2108
2109         default:
2110                 break;
2111         }
2112
2113         if (rv)
2114                 pr_err("soctherm: ERROR in handling %s alarm\n",
2115                        throt_names[alarm]);
2116
2117         return rv;
2118 }
2119
2120 /**
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
2124  *
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.
2130  *
2131  * Return: %IRQ_HANDLED
2132  */
2133 static irqreturn_t soctherm_edp_thread_func(int irq, void *arg)
2134 {
2135         u32 st, ex, oc1, oc2, oc3, oc4;
2136
2137         st = soctherm_readl(OC_INTR_STATUS);
2138
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;
2145
2146         if (ex) {
2147                 soctherm_writel(st, OC_INTR_STATUS);
2148                 st &= ~ex;
2149
2150                 if (oc1 && !soctherm_handle_alarm(THROTTLE_OC1))
2151                         soctherm_oc_intr_enable(THROTTLE_OC1, true);
2152
2153                 if (oc2 && !soctherm_handle_alarm(THROTTLE_OC2))
2154                         soctherm_oc_intr_enable(THROTTLE_OC2, true);
2155
2156                 if (oc3 && !soctherm_handle_alarm(THROTTLE_OC3))
2157                         soctherm_oc_intr_enable(THROTTLE_OC3, true);
2158
2159                 if (oc4 && !soctherm_handle_alarm(THROTTLE_OC4))
2160                         soctherm_oc_intr_enable(THROTTLE_OC4, true);
2161
2162                 if (oc1 && soc_irq_cdata.irq_enable & BIT(0))
2163                         handle_nested_irq(
2164                                 irq_find_mapping(soc_irq_cdata.domain, 0));
2165
2166                 if (oc2 && soc_irq_cdata.irq_enable & BIT(1))
2167                         handle_nested_irq(
2168                                 irq_find_mapping(soc_irq_cdata.domain, 1));
2169
2170                 if (oc3 && soc_irq_cdata.irq_enable & BIT(2))
2171                         handle_nested_irq(
2172                                 irq_find_mapping(soc_irq_cdata.domain, 2));
2173
2174                 if (oc4 && soc_irq_cdata.irq_enable & BIT(3))
2175                         handle_nested_irq(
2176                                 irq_find_mapping(soc_irq_cdata.domain, 3));
2177         }
2178
2179         if (st) {
2180                 pr_err("soctherm: Ignored unexpected OC ALARM 0x%08x\n", st);
2181                 soctherm_writel(st, OC_INTR_STATUS);
2182         }
2183
2184         return IRQ_HANDLED;
2185 }
2186
2187 /**
2188  * soctherm_thermal_isr() - thermal interrupt request handler
2189  * @irq:        Interrupt request number
2190  * @arg:        Not used.
2191  *
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.
2195  *
2196  * Return: %IRQ_WAKE_THREAD
2197  */
2198 static irqreturn_t soctherm_thermal_isr(int irq, void *arg)
2199 {
2200         u32 r;
2201
2202         r = soctherm_readl(TH_INTR_STATUS);
2203         soctherm_writel(r, TH_INTR_DISABLE);
2204
2205         return IRQ_WAKE_THREAD;
2206 }
2207
2208 /**
2209  * soctherm_edp_isr() - Disables any active interrupts
2210  * @irq:        The interrupt request number
2211  * @arg:        Opaque pointer to an argument
2212  *
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.
2217  *
2218  * The OC_INTR_DISABLE register indicates which OC interrupts
2219  * have been disabled.
2220  *
2221  * Return: %IRQ_WAKE_THREAD, handler requests to wake the handler thread
2222  */
2223 static irqreturn_t soctherm_edp_isr(int irq, void *arg)
2224 {
2225         u32 r;
2226
2227         r = soctherm_readl(OC_INTR_STATUS);
2228         soctherm_writel(r, OC_INTR_DISABLE);
2229
2230         return IRQ_WAKE_THREAD;
2231 }
2232
2233 /**
2234  * throttlectl_cpu_mn() - program CPU pulse skipper configuration
2235  * @throt: soctherm_throttle_id describing the level of throttling
2236  *
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
2242  * complex.)
2243  *
2244  * Return: boolean true if HW was programmed, or false if the desired
2245  * configuration is not supported.
2246  */
2247 static bool throttlectl_cpu_mn(enum soctherm_throttle_id throt)
2248 {
2249         u32 r;
2250         struct soctherm_throttle *data = &plat_data.throttle[throt];
2251         struct soctherm_throttle_dev *dev = &data->devs[THROTTLE_DEV_CPU];
2252
2253         if (!dev->enable)
2254                 return false;
2255
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));
2261
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));
2266
2267         return true;
2268 }
2269
2270 /**
2271  * throttlectl_cpu_level() - program CPU pulse skipper configuration
2272  * @throt: soctherm_throttle_id describing the level of throttling
2273  *
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.
2280  *
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.
2284  *
2285  * Return: boolean true if HW was programmed, or false if the desired
2286  * configuration is not supported.
2287  */
2288 static bool throttlectl_cpu_level(enum soctherm_throttle_id throt)
2289 {
2290         u32 r, throt_vect;
2291         int throt_level;
2292         struct soctherm_throttle *data = &plat_data.throttle[throt];
2293         struct soctherm_throttle_dev *dev = &data->devs[THROTTLE_DEV_CPU];
2294
2295         if (!dev->enable)
2296                 return false;
2297
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;
2308         } else {
2309                 throt_level = THROT_LEVEL_NONE;
2310                 throt_vect = THROT_VECT_NONE;
2311         }
2312
2313         if (dev->depth)
2314                 THROT_DEPTH(dev, dev->depth);
2315
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));
2322
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));
2326
2327         if (throt_level == THROT_LEVEL_NONE)
2328                 return true;
2329
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));
2335
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));
2341
2342         return true;
2343 }
2344
2345 /**
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
2349  *
2350  * This function programs soctherm's interface to GK20a NV_THERM in
2351  * terms of Low, Medium and Heavy throttling preset levels.
2352  *
2353  * Return: boolean true if HW was programmed
2354  */
2355 static bool throttlectl_gpu_gk20a_nv_therm_style(
2356                                 struct soctherm_throttle_dev *dev,
2357                                 enum soctherm_throttle_id throt)
2358 {
2359         u32 r, throt_vect;
2360
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;
2366         else
2367                 throt_vect = THROT_VECT_LOW;
2368
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));
2373
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));
2377
2378         return true;
2379 }
2380
2381 /**
2382  * throttlectl_gpu() - programs GPU pulse skippers' configuration
2383  * @throt       soctherm_throttle_id describing the level of throttling
2384  *
2385  * Pulse skippers are used to throttle clock frequencies.
2386  * This function programs the pulse skippers based on @throt and platform data.
2387  *
2388  * Return: boolean true if HW was programmed
2389  */
2390 static bool throttlectl_gpu(enum soctherm_throttle_id throt)
2391 {
2392         u32 r;
2393         struct soctherm_throttle *data = &plat_data.throttle[throt];
2394         struct soctherm_throttle_dev *dev = &data->devs[THROTTLE_DEV_GPU];
2395
2396         if (!dev->enable)
2397                 return false;
2398
2399         if (IS_T12X || IS_T13X)
2400                 return throttlectl_gpu_gk20a_nv_therm_style(dev, throt);
2401
2402         if (dev->depth)
2403                 THROT_DEPTH(dev, dev->depth);
2404
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));
2410
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));
2415
2416         return true;
2417 }
2418
2419 /**
2420  * soctherm_throttle_program() - programs pulse skippers' configuration
2421  * @throt       soctherm_throttle_id describing the level of throttling
2422  *
2423  * Pulse skippers are used to throttle clock frequencies.
2424  * This function programs the pulse skippers based on @throt and platform data.
2425  *
2426  * Return: Nothing is returned (void).
2427  */
2428 static void soctherm_throttle_program(enum soctherm_throttle_id throt)
2429 {
2430         u32 r;
2431         bool throt_enable;
2432         struct soctherm_throttle *data = &plat_data.throttle[throt];
2433
2434         throt_enable = (IS_T13X) ? throttlectl_cpu_level(throt) :
2435                 throttlectl_cpu_mn(throt);
2436         throt_enable |= throttlectl_gpu(throt);
2437
2438         r = REG_SET(0, THROT_PRIORITY_LITE_PRIO, data->priority);
2439         soctherm_writel(r, THROT_PRIORITY_CTRL(throt));
2440
2441         r = REG_SET(0, THROT_DELAY_LITE_DELAY, 0);
2442         soctherm_writel(r, THROT_DELAY_CTRL(throt));
2443
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);
2448         }
2449
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));
2457
2458                 r = REG_SET(r, OC1_CFG_ALARM_POLARITY, 1);
2459                 soctherm_writel(r, ALARM_CFG(throt));
2460
2461                 r = REG_SET(r, OC1_CFG_ALARM_POLARITY, 0);
2462                 soctherm_writel(r, ALARM_CFG(throt));
2463
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));
2468
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));
2473
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));
2477
2478                 r = REG_SET(0, THROT_PRIORITY_LITE_PRIO, 1);
2479                 soctherm_writel(r, THROT_PRIORITY_CTRL(throt));
2480                 return;
2481         }
2482
2483         if (!throt_enable || (throt < THROTTLE_OC1))
2484                 return;
2485
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]);
2490
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));
2498
2499         soctherm_oc_intr_enable(throt, data->intr);
2500
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));
2505         else
2506                 soctherm_writel(0xffffffff, ALARM_FILTER(throt));
2507 }
2508
2509 /**
2510  * soctherm_tsense_program() - Configure sensor timing parameters based on
2511  * chip-specific data.
2512  *
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
2517  *              data
2518  *
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.
2522  *
2523  * The configuration data affects the sensor's temperature capturing.
2524  *
2525  * Return: Nothing is returned (void).
2526  */
2527 static void soctherm_tsense_program(enum soctherm_sense sensor,
2528                                                 struct soctherm_sensor *data)
2529 {
2530         u32 r;
2531
2532         r = REG_SET(0, TS_CPU0_CONFIG0_TALL, data->tall);
2533         soctherm_writel(r, TS_TSENSE_REG_OFFSET(TS_CPU0_CONFIG0, sensor));
2534
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));
2540 }
2541
2542 /**
2543  * soctherm_clk_init() - Initialize SOC_THERM related clocks.
2544  *
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.
2548  *
2549  * Return: 0 if successful else %-EINVAL if initialization failed
2550  */
2551 static int __init soctherm_clk_init(void)
2552 {
2553         unsigned long default_soctherm_clk_rate;
2554         unsigned long default_tsensor_clk_rate;
2555
2556         soctherm_clk = clk_get_sys("soc_therm", NULL);
2557         tsensor_clk = clk_get_sys("tegra-tsensor", NULL);
2558
2559         if (IS_ERR(tsensor_clk) || IS_ERR(soctherm_clk)) {
2560                 clk_put(soctherm_clk);
2561                 clk_put(tsensor_clk);
2562                 soctherm_clk = NULL;
2563                 tsensor_clk = NULL;
2564                 return -EINVAL;
2565         }
2566
2567         /* initialize default clock rates */
2568         if (IS_T11X) {
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;
2577         } else {
2578                 BUG();
2579         }
2580
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;
2585
2586         if (clk_get_rate(soctherm_clk) != plat_data.soctherm_clk_rate)
2587                 if (clk_set_rate(soctherm_clk, plat_data.soctherm_clk_rate))
2588                         return -EINVAL;
2589
2590         if (clk_get_rate(tsensor_clk) != plat_data.tsensor_clk_rate)
2591                 if (clk_set_rate(tsensor_clk, plat_data.tsensor_clk_rate))
2592                         return -EINVAL;
2593
2594         return 0;
2595 }
2596
2597 /**
2598  * soctherm_clk_enable() - enables and disables the clocks
2599  * @enable:     whether the clocks should be enabled or disabled
2600  *
2601  * Enables the SOC_THERM and thermal sensor clocks when SOC_THERM
2602  * is initialized.
2603  *
2604  * Return: 0 if successful, %-EINVAL if either clock hasn't been initialized.
2605  */
2606 static int soctherm_clk_enable(bool enable)
2607 {
2608         if (soctherm_clk == NULL || tsensor_clk == NULL)
2609                 return -EINVAL;
2610
2611         if (enable) {
2612                 clk_enable(soctherm_clk);
2613                 clk_enable(tsensor_clk);
2614         } else {
2615                 clk_disable(soctherm_clk);
2616                 clk_disable(tsensor_clk);
2617         }
2618
2619         return 0;
2620 }
2621
2622 /**
2623  * soctherm_fuse_read_calib_base() - Calculates calibration base temperature
2624  *
2625  * Calculates the nominal temperature used for thermal sensor calibration
2626  * based on chip type and the value in fuses.
2627  *
2628  * Return: 0 (success), otherwise -EINVAL.
2629  */
2630 static int soctherm_fuse_read_calib_base(void)
2631 {
2632         s32 calib_cp, calib_ft;
2633         s32 nominal_calib_cp, nominal_calib_ft;
2634
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");
2638                 return -EINVAL;
2639         }
2640
2641         nominal_calib_cp = 25;
2642         if (IS_T11X)
2643                 nominal_calib_ft = 90;
2644         else if (IS_T14X || IS_T12X || IS_T13X)
2645                 nominal_calib_ft = 105;
2646         else
2647                 BUG();
2648
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;
2652
2653         return 0;
2654 }
2655
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 },
2665 };
2666
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 },
2676 };
2677
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 },
2687 };
2688
2689 /* old CP/FT */
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 },
2699 };
2700
2701 /* new CP1/CP2 */
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 },
2711 };
2712
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 },
2723 };
2724
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 },
2735 };
2736
2737 /**
2738  * soctherm_fuse_read_tsensor() - calculates therm_a and therm_b for a sensor
2739  * @sensor:     The sensor for which to calculate.
2740  *
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.
2747  *
2748  * Return: 0 if successful, otherwise %-EINVAL
2749  */
2750 static int soctherm_fuse_read_tsensor(enum soctherm_sense sensor)
2751 {
2752         u32 r, value;
2753         s32 calib, delta_sens, delta_temp;
2754         s16 therm_a, therm_b;
2755         s32 div, mult, actual_tsensor_ft, actual_tsensor_cp;
2756         int fuse_rev;
2757         struct soctherm_fuse_correction_war *war;
2758
2759         fuse_rev = tegra_fuse_calib_base_get_cp(NULL, NULL);
2760         if (fuse_rev < 0)
2761                 return fuse_rev;
2762
2763         tegra_fuse_get_tsensor_calib(sensor2tsensorcalib[sensor], &value);
2764
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;
2769
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;
2773
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;
2778
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;
2782
2783         therm_a = div64_s64_precise((s64)delta_temp * (1LL << 13) * mult,
2784                                     (s64)delta_sens * div);
2785
2786         therm_b = div64_s64_precise((((s64)actual_tsensor_ft * actual_temp_cp) -
2787                                      ((s64)actual_tsensor_cp * actual_temp_ft)),
2788                                     (s64)delta_sens);
2789
2790         /* FUSE correction WARs */
2791         if (IS_T11X)
2792                 war = PRECISION_IS_LOWER() ?
2793                         &t11x_fuse_war[sensor] : &no_fuse_war[sensor];
2794         else if (IS_T14X)
2795                 war = PRECISION_IS_LOWER() ?
2796                         &t14x_fuse_war[sensor] : &no_fuse_war[sensor];
2797         else if (IS_T12X)
2798                 war = fuse_rev ?
2799                         &t12x_fuse_war1[sensor] : &t12x_fuse_war2[sensor];
2800         else if (IS_T13X)
2801                 war = fuse_rev == 2 ?
2802                         &t13x_fuse_war1[sensor] : &t13x_fuse_war2[sensor];
2803         else
2804                 war = &no_fuse_war[sensor];
2805
2806         therm_a = div64_s64_precise((s64)therm_a * war->a,
2807                                     (s64)1000000LL);
2808         therm_b = div64_s64_precise((s64)therm_b * war->a + war->b,
2809                                     (s64)1000000LL);
2810         therm_a = LOWER_PRECISION_FOR_TEMP(therm_a);
2811         therm_b = LOWER_PRECISION_FOR_TEMP(therm_b);
2812
2813         sensor2therm_a[sensor] = (s16)therm_a;
2814         sensor2therm_b[sensor] = (s16)therm_b;
2815
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));
2819
2820         return 0;
2821 }
2822
2823 /**
2824  * soctherm_therm_trip_init() - configure PMC's thermal-shutdown behavior
2825  * @data:       Power management unit thermal sensor initialization data
2826  *
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).
2830  */
2831 static void soctherm_therm_trip_init(struct tegra_thermtrip_pmic_data *data)
2832 {
2833         if (!data)
2834                 return;
2835
2836         tegra_pmc_enable_thermal_trip();
2837         tegra_pmc_config_thermal_trip(data);
2838 }
2839
2840 /**
2841  * soctherm_adjust_cpu_zone() - Adjusts the soctherm CPU zone
2842  * @therm:      soctherm_therm_id specifying the sensor group to adjust
2843  *
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().
2849  */
2850 static void soctherm_adjust_zone(int tz)
2851 {
2852         u32 r, s;
2853         int i;
2854         long ztemp, pll_temp, diff;
2855         bool low_voltage;
2856
2857         if (soctherm_suspended)
2858                 return;
2859
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;
2866         else
2867                 return;
2868
2869         if (low_voltage) {
2870                 r = soctherm_readl(TS_TEMP1);
2871                 s = soctherm_readl(TS_TEMP2);
2872
2873                 /* get pllx temp */
2874                 pll_temp = temp_translate(REG_GET(s, TS_TEMP2_PLLX_TEMP));
2875                 ztemp = pll_temp; /* initialized */
2876
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));
2884
2885                 if (ztemp > pll_temp)
2886                         diff = ztemp - pll_temp;
2887                 else
2888                         diff = 0;
2889
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;
2893
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);
2903
2904                 /* Stop all TSENSE's mapped to <tz> */
2905                 for (i = 0; i < TSENSE_SIZE; i++) {
2906                         if (tsensor2therm_map[i] != tz)
2907                                 continue;
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));
2913                 }
2914         } else {
2915                 /* UN-Stop all TSENSE's mapped to <tz> */
2916                 for (i = 0; i < TSENSE_SIZE; i++) {
2917                         if (tsensor2therm_map[i] != tz)
2918                                 continue;
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));
2924                 }
2925
2926                 /* default to configured offset for <tz> */
2927                 diff = plat_data.therm[tz].hotspot_offset;
2928
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);
2938         }
2939 }
2940
2941 /**
2942  * soctherm_init_platform_data() - Initializes the platform data.
2943  *
2944  * Cleans up some platform data in preparation for configuring the
2945  * hardware and configures the hardware as specified by the cleaned up
2946  * platform data.
2947  *
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.
2950  *
2951  * Sets the temperature sensor PDIV (post divider) register which
2952  * contains the temperature sensor PDIV for the CPU, GPU, MEM, and PLLX
2953  *
2954  * Sets the configurations for each of the sensors.
2955  *
2956  * Sanitizes thermal trips for each thermal zone.
2957  *
2958  * Writes hotspot offsets to TS_HOTSPOT_OFF register.
2959  *
2960  * Checks the throttling priorities and makes sure that they are
2961  * in the correct order for throttle types THROTTLE_OC1 though THROTTLE_OC4.
2962  *
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)
2966  *
2967  * Initializes the throttling thresholds for the CPU, GPU, MEM, and PLL
2968  *
2969  * Checks if the priorities of heavy and light throttling are in
2970  * the correct order.
2971  *
2972  * Initializes the STATS_CTL and OC_STATS_CTL registers for stat collection
2973  *
2974  * Enables PMC shutdown based on the platform data
2975  *
2976  * Programs the temperatures at which hardware shutdowns occur.
2977  *
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.
2980  *
2981  * Return: 0 on success. -EINVAL is returned otherwise
2982  */
2983 static int soctherm_init_platform_data(void)
2984 {
2985         struct soctherm_therm *therm;
2986         struct soctherm_sensor *s;
2987         struct soctherm_sensor sensor_defaults;
2988         int i, j, k;
2989         long rem;
2990         long gsh = MAX_HIGH_TEMP;
2991         u32 r;
2992
2993         if (IS_T11X)
2994                 sensor_defaults = default_t11x_sensor_params;
2995         else if (IS_T14X)
2996                 sensor_defaults = default_t14x_sensor_params;
2997         else if ((IS_T12X || IS_T13X))
2998                 sensor_defaults = default_t12x_sensor_params;
2999         else
3000                 BUG();
3001
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;
3014         }
3015
3016         /* Pdiv */
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);
3023
3024         /* Thermal Sensing programming */
3025         if (soctherm_fuse_read_calib_base() < 0)
3026                 return -EINVAL;
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)
3031                                 return -EINVAL;
3032                 }
3033         }
3034
3035         soctherm_adjust_zone(THERM_CPU);
3036         soctherm_adjust_zone(THERM_GPU);
3037         soctherm_adjust_zone(THERM_MEM);
3038
3039         /* Sanitize therm trips */
3040         for (i = 0; i < THERM_SIZE; i++) {
3041                 therm = &plat_data.therm[i];
3042                 if (!therm->zone_enable)
3043                         continue;
3044
3045                 for (j = 0; j < therm->num_trips; j++) {
3046                         rem = therm->trips[j].trip_temp %
3047                                 LOWER_PRECISION_FOR_CONV(1000);
3048                         if (rem) {
3049                                 pr_warn(
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;
3053                         }
3054                 }
3055         }
3056
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);
3065
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;
3071
3072                 /* Setup PSKIP parameters */
3073                 soctherm_throttle_program(i);
3074
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))
3079                                 continue;
3080
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))
3088                                         break;
3089                         if (k < therm->num_trips && i <= THROTTLE_HEAVY)
3090                                 prog_hw_threshold(&therm->trips[k], j, i);
3091                 }
3092         }
3093
3094         r = REG_SET(0, THROT_GLOBAL_ENB, 1);
3095         if (IS_T13X)
3096                 clk_reset13_writel(r, THROT13_GLOBAL_CFG);
3097         else
3098                 soctherm_writel(r, THROT_GLOBAL_CFG);
3099
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");
3103
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);
3109
3110         /* Enable PMC to shutdown */
3111         soctherm_therm_trip_init(plat_data.tshut_pmu_trip_data);
3112
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());
3116
3117         /* Thermtrip */
3118         for (i = 0; i < THERM_SIZE; i++) {
3119                 therm = &plat_data.therm[i];
3120                 if (!therm->zone_enable)
3121                         continue;
3122
3123                 for (j = 0; j < therm->num_trips; j++) {
3124                         if (therm->trips[j].trip_type != THERMAL_TRIP_CRITICAL)
3125                                 continue;
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;
3133                         }
3134                         prog_hw_shutdown(&therm->trips[j], i);
3135                 }
3136         }
3137
3138         return 0;
3139 }
3140
3141 /**
3142  * soctherm_suspend_locked() - suspends SOC_THERM IP block
3143  *
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.
3148  *
3149  */
3150 static void soctherm_suspend_locked(void)
3151 {
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);*/
3160         }
3161 }
3162
3163 /**
3164  * soctherm_suspend() - Suspends the SOC_THERM device
3165  *
3166  * Suspends SOC_THERM and prevents interrupts from occurring
3167  * and SOC_THERM from interrupting the CPU.
3168  *
3169  * Return: 0 on success.
3170  */
3171 static int soctherm_suspend(void)
3172 {
3173         mutex_lock(&soctherm_suspend_resume_lock);
3174         soctherm_suspend_locked();
3175         mutex_unlock(&soctherm_suspend_resume_lock);
3176         return 0;
3177 }
3178
3179 /**
3180  * soctherm_resume_locked() - Resumes soctherm if it is suspended
3181  *
3182  * Enables device interrupt generation for thermal and EDP when soctherm
3183  * platform initialization is done.
3184  */
3185 static void soctherm_resume_locked(void)
3186 {
3187         if (soctherm_suspended) {
3188                 /* soctherm_clk_enable(true);*/
3189                 soctherm_suspended = false;
3190                 soctherm_init_platform_data();
3191                 soctherm_init_platform_done = true;
3192                 soctherm_update();
3193                 enable_irq(INT_THERMAL);
3194                 enable_irq(INT_EDP);
3195         }
3196 }
3197
3198 /**
3199  * soctherm_resume() - wrapper for soctherm_resume_locked()
3200  *
3201  * Grabs the soctherm_suspend_resume_lock and then resumes SOC_THERM by running
3202  * soctherm_resume_locked().
3203  *
3204  * Return: 0
3205  */
3206 static int soctherm_resume(void)
3207 {
3208         mutex_lock(&soctherm_suspend_resume_lock);
3209         soctherm_resume_locked();
3210         mutex_unlock(&soctherm_suspend_resume_lock);
3211         return 0;
3212 }
3213
3214 /**
3215  * soctherm_sync() - Syncs soctherm
3216  *
3217  * If soctherm is suspended, reinitializes the SOC_THERM IP block registers
3218  * from the platform data and updates each zone. Otherwise only the
3219  * latter occurs.
3220  */
3221 static int soctherm_sync(void)
3222 {
3223         mutex_lock(&soctherm_suspend_resume_lock);
3224
3225         if (soctherm_suspended) {
3226                 soctherm_resume_locked();
3227                 soctherm_suspend_locked();
3228         } else {
3229                 soctherm_update();
3230         }
3231
3232         mutex_unlock(&soctherm_suspend_resume_lock);
3233         return 0;
3234 }
3235 late_initcall_sync(soctherm_sync);
3236
3237 /**
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
3242  *
3243  * Currently supports %PM_SUSPEND_PREPARE. Ignores %PM_POST_SUSPEND
3244  *
3245  * Return: %NOTIFY_OK
3246  */
3247 static int soctherm_pm_suspend(struct notifier_block *nb,
3248                                 unsigned long event, void *data)
3249 {
3250         if (event == PM_SUSPEND_PREPARE) {
3251                 soctherm_suspend();
3252                 pr_info("tegra_soctherm: suspended\n");
3253         }
3254         return NOTIFY_OK;
3255 }
3256
3257 /**
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
3262  *
3263  * Currently supports %PM_POST_SUSPEND. Ignores %PM_SUSPEND_PREPARE
3264  *
3265  * Return: %NOTIFY_OK
3266  */
3267 static int soctherm_pm_resume(struct notifier_block *nb,
3268                                 unsigned long event, void *data)
3269 {
3270         if (event == PM_POST_SUSPEND) {
3271                 soctherm_resume();
3272                 pr_info("tegra_soctherm: resumed\n");
3273         }
3274         return NOTIFY_OK;
3275 }
3276
3277 static struct notifier_block soctherm_suspend_nb = {
3278         .notifier_call = soctherm_pm_suspend,
3279         .priority = -2,
3280 };
3281
3282 static struct notifier_block soctherm_resume_nb = {
3283         .notifier_call = soctherm_pm_resume,
3284         .priority = 2,
3285 };
3286
3287 /**
3288  * soctherm_oc_irq_lock() - locks the over-current interrupt request
3289  * @data:       Interrupt request data
3290  *
3291  * Looks up the chip data from @data and locks the mutex associated with
3292  * a particular over-current interrupt request.
3293  */
3294 static void soctherm_oc_irq_lock(struct irq_data *data)
3295 {
3296         struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3297
3298         mutex_lock(&d->irq_lock);
3299 }
3300
3301 /**
3302  * soctherm_oc_irq_sync_unlock() - Unlocks the OC interrupt request
3303  * @data:               Interrupt request data
3304  *
3305  * Looks up the interrupt request data @data and unlocks the mutex associated
3306  * with a particular over-current interrupt request.
3307  */
3308 static void soctherm_oc_irq_sync_unlock(struct irq_data *data)
3309 {
3310         struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3311
3312         mutex_unlock(&d->irq_lock);
3313 }
3314
3315 /**
3316  * soctherm_oc_irq_enable() - Enables the SOC_THERM over-current interrupt queue
3317  * @data:       irq_data structure of the chip
3318  *
3319  * Sets the irq_enable bit of SOC_THERM allowing SOC_THERM
3320  * to respond to over-current interrupts.
3321  *
3322  */
3323 static void soctherm_oc_irq_enable(struct irq_data *data)
3324 {
3325         struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3326
3327         d->irq_enable |= BIT(data->hwirq);
3328 }
3329
3330 /**
3331  * soctherm_oc_irq_disable() - Disables overcurrent interrupt requests
3332  * @irq_data:   The interrupt request information
3333  *
3334  * Clears the interrupt request enable bit of the overcurrent
3335  * interrupt request chip data.
3336  *
3337  * Return: Nothing is returned (void)
3338  */
3339 static void soctherm_oc_irq_disable(struct irq_data *data)
3340 {
3341         struct soctherm_oc_irq_chip_data *d = irq_data_get_irq_chip_data(data);
3342
3343         d->irq_enable &= ~BIT(data->hwirq);
3344 }
3345
3346 static int soctherm_oc_irq_set_type(struct irq_data *data, unsigned int type)
3347 {
3348         return 0;
3349 }
3350
3351 /**
3352  * soctherm_oc_irq_set_wake() - Set the overcurrent interrupt request
3353  * to "wake"
3354  * @irq_data:   Interrupt request information
3355  * @on:         Whether to enable or disable power management wakeup
3356  *
3357  * Configure the GPIO associated with a SOC_THERM over-current
3358  * interrupt to wake the system from sleep
3359  *
3360  * It may be necessary to wake the system from sleep mode so that
3361  * SOC_THERM can provide proper over-current throttling.
3362  *
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.
3366  */
3367 static int soctherm_oc_irq_set_wake(struct irq_data *data, unsigned int on)
3368 {
3369         int gpio;
3370         int gpio_irq;
3371
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);
3375                 return -EINVAL;
3376         }
3377
3378         gpio_irq = gpio_to_irq(gpio);
3379         if (gpio_irq < 0) {
3380                 pr_err("No gpio_to_irq for gpio %d\n", gpio);
3381                 return gpio;
3382         }
3383
3384         irq_set_irq_wake(gpio_irq, on);
3385         return 0;
3386 }
3387
3388 /**
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
3393  *
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.
3398  *
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.
3402  *
3403  * Return: 0
3404  */
3405 static int soctherm_oc_irq_map(struct irq_domain *h, unsigned int virq,
3406                 irq_hw_number_t hw)
3407 {
3408         struct soctherm_oc_irq_chip_data *data = h->host_data;
3409
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);
3414         return 0;
3415 }
3416
3417 static struct irq_domain_ops soctherm_oc_domain_ops = {
3418         .map    = soctherm_oc_irq_map,
3419         .xlate  = irq_domain_xlate_twocell,
3420 };
3421
3422 /**
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
3427  *
3428  * Sets the over current interrupt request chip data
3429  *
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
3432  * allocate the irqs
3433  */
3434 static int tegra11_soctherem_oc_int_init(int irq_base, int num_irqs)
3435 {
3436         if (irq_base <= 0 || !num_irqs) {
3437                 pr_info("%s(): OC interrupts are not enabled\n", __func__);
3438                 return 0;
3439         }
3440
3441         mutex_init(&soc_irq_cdata.irq_lock);
3442         soc_irq_cdata.irq_enable = 0;
3443
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,
3452
3453         irq_base = irq_alloc_descs(irq_base, 0, num_irqs, 0);
3454         if (irq_base < 0) {
3455                 pr_err("%s: Failed to allocate IRQs: %d\n", __func__, irq_base);
3456                 return irq_base;
3457         }
3458
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__);
3463                 return -ENOMEM;
3464         }
3465         pr_info("%s(): OC interrupts enabled successful\n", __func__);
3466         return 0;
3467 }
3468
3469 static int core_rail_regulator_notifier_cb(
3470         struct notifier_block *nb, unsigned long event, void *v)
3471 {
3472         int uv = (int)((long)v);
3473         int rv = NOTIFY_DONE;
3474         int core_vmin_limit_uv;
3475
3476         if (IS_T12X) {
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);
3481                                 rv = NOTIFY_OK;
3482                         }
3483                 } else if (event & REGULATOR_EVENT_OUT_PRECHANGE) {
3484                         if (uv < core_vmin_limit_uv) {
3485                                 tegra_soctherm_adjust_core_zone(false);
3486                                 rv = NOTIFY_OK;
3487                         }
3488                 }
3489         }
3490         return rv;
3491 }
3492
3493 static int __init soctherm_core_rail_notify_init(void)
3494 {
3495         int ret;
3496         static struct notifier_block vmin_condition_nb;
3497
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);
3501         if (ret) {
3502                 pr_err("%s: Failed to register core rail notifier\n",
3503                        __func__);
3504                 return ret;
3505         }
3506
3507         return 0;
3508 }
3509 late_initcall_sync(soctherm_core_rail_notify_init);
3510
3511 /**
3512  * tegra11_soctherm_init() - initializes SOC_THERM IP Block
3513  * @data:       pointer to board-specific information
3514  *
3515  * Initialize and enable SOC_THERM clocks, sanitize platform data, configure
3516  * SOC_THERM according to platform data, and set up interrupt handling for
3517  * OC events.
3518  *
3519  * Return: -1 if initialization failed, 0 otherwise
3520  */
3521 int __init tegra11_soctherm_init(struct soctherm_platform_data *data)
3522 {
3523         int ret;
3524
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);
3528                 return -1;
3529         }
3530
3531         register_pm_notifier(&soctherm_suspend_nb);
3532         register_pm_notifier(&soctherm_resume_nb);
3533
3534         if (!data)
3535                 return -1;
3536         plat_data = *data;
3537
3538         if (soctherm_clk_init() < 0)
3539                 return -1;
3540
3541         if (soctherm_clk_enable(true) < 0)
3542                 return -1;
3543
3544         if (soctherm_init_platform_data() < 0)
3545                 return -1;
3546
3547         soctherm_init_platform_done = true;
3548
3549         ret = tegra11_soctherem_oc_int_init(data->oc_irq_base,
3550                         data->num_oc_irqs);
3551         if (ret < 0) {
3552                 pr_err("soctherem_oc_int_init failed: %d\n", ret);
3553                 return ret;
3554         }
3555
3556         if (request_threaded_irq(INT_THERMAL, soctherm_thermal_isr,
3557                                  soctherm_thermal_thread_func, IRQF_ONESHOT,
3558                                  "soctherm_thermal", NULL) < 0)
3559                 return -1;
3560
3561         if (request_threaded_irq(INT_EDP, soctherm_edp_isr,
3562                                  soctherm_edp_thread_func, IRQF_ONESHOT,
3563                                  "soctherm_edp", NULL) < 0)
3564                 return -1;
3565
3566         return 0;
3567 }
3568
3569 /**
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
3573  *
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.
3578  */
3579 void tegra_soctherm_adjust_cpu_zone(bool high_voltage_range)
3580 {
3581         if (!vdd_cpu_low_voltage != high_voltage_range) {
3582                 vdd_cpu_low_voltage = !high_voltage_range;
3583                 soctherm_adjust_zone(THERM_CPU);
3584         }
3585 }
3586
3587 void tegra_soctherm_adjust_core_zone(bool high_voltage_range)
3588 {
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);
3594                 }
3595         }
3596 }
3597
3598 #ifdef CONFIG_DEBUG_FS
3599
3600 /**
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
3604  *
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.
3608  *
3609  * Return: -1 if fail, 0 otherwise
3610  */
3611 static int regs_show(struct seq_file *s, void *data)
3612 {
3613         u32 r;
3614         u32 state;
3615         int tcpu[TSENSE_SIZE];
3616         int i, j, level;
3617         uint m, n, q;
3618         char *depth;
3619
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");
3623
3624         if (soctherm_suspended) {
3625                 seq_puts(s, "SOC_THERM is SUSPENDED\n");
3626                 return 0;
3627         }
3628
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);
3632                 if (!state)
3633                         continue;
3634
3635                 seq_printf(s, "%s: ", sensor_names[i]);
3636
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);
3644
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));
3650
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]));
3658
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);
3670
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);
3676         }
3677
3678         r = soctherm_readl(TS_PDIV);
3679         seq_printf(s, "PDIV: 0x%x\n", r);
3680
3681         seq_puts(s, "\n");
3682         seq_puts(s, "-----SOC_THERM-----\n");
3683
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));
3694
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,
3699                                                                 level, i));
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);
3707
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" :
3713                                 "H+L" : "none");
3714
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" :
3720                                 "H+L" : "none");
3721
3722                         state = REG_GET(r, CTL_LVL0_CPU0_STATUS);
3723                         seq_printf(s, "Status(%s)\n",
3724                                    state == 0 ? "LO" :
3725                                    state == 1 ? "in" :
3726                                    state == 2 ? "??" : "HI");
3727                 }
3728         }
3729
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);
3739         }
3740
3741         r = soctherm_readl(THERMTRIP);
3742         state = REG_GET(r, THERMTRIP_ANY_EN);
3743         seq_printf(s, "ThermTRIP ANY En(%d)\n", state);
3744
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));
3749
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));
3754
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));
3759
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));
3764
3765         r = soctherm_readl(THROT_GLOBAL_CFG);
3766         seq_printf(s, "GLOBAL THROTTLE CONFIG: 0x%08x\n", r);
3767
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);
3776
3777         r = soctherm_readl(CPU_PSKIP_STATUS);
3778         if (IS_T13X) {
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);
3783         } else {
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);
3791         }
3792
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);
3799         } else {
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);
3807         }
3808
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");
3818
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);
3827                         if (!state) {
3828                                 seq_puts(s, "\n");
3829                                 continue;
3830                         }
3831
3832                         level = THROT_LEVEL_NONE; /* invalid */
3833                         depth = "";
3834                         q = 0;
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;
3839                                         depth = "hi";
3840                                 } else if (state == THROT_VECT_MED) {
3841                                         level = THROT_LEVEL_MED;
3842                                         depth = "med";
3843                                 } else if (state == THROT_VECT_LOW) {
3844                                         level = THROT_LEVEL_LOW;
3845                                         depth = "low";
3846                                 }
3847                         }
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) {
3852                                         q = 87;
3853                                         depth = "hi";
3854                                 } else if (state == THROT_VECT_MED) {
3855                                         q = 75;
3856                                         depth = "med";
3857                                 } else if (state == THROT_VECT_LOW) {
3858                                         q = 50;
3859                                         depth = "low";
3860                                 }
3861                         }
3862
3863                         if (level == THROT_LEVEL_NONE)
3864                                 r = 0;
3865                         else if (IS_T13X && j == THROTTLE_DEV_CPU)
3866                                 r = clk_reset13_readl(
3867                                         THROT13_PSKIP_CTRL_CPU(level));
3868                         else
3869                                 r = soctherm_readl(THROT_PSKIP_CTRL(i, j));
3870
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);
3877
3878                         if (IS_T13X && j == THROTTLE_DEV_CPU)
3879                                 r = clk_reset13_readl(
3880                                         THROT13_PSKIP_RAMP_CPU(level));
3881                         else
3882                                 r = soctherm_readl(THROT_PSKIP_RAMP(i, j));
3883
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);
3888
3889                         r = soctherm_readl(THROT_PRIORITY_CTRL(i));
3890                         state = REG_GET(r, THROT_PRIORITY_LITE_PRIO);
3891                         seq_printf(s, "%4d  ", state);
3892
3893                         r = soctherm_readl(THROT_DELAY_CTRL(i));
3894                         state = REG_GET(r, THROT_DELAY_LITE_DELAY);
3895                         seq_printf(s, "%5d  ", state);
3896
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);
3911
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);
3922                         }
3923                         seq_puts(s, "\n");
3924                 }
3925         }
3926         return 0;
3927 }
3928
3929 /**
3930  * temp_log_show() - "show" callback for temp_log debugfs node
3931  * @s:          pointer to the seq_file record to write the log through
3932  * @data:       not used
3933  *
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).
3938  *
3939  * Return: 0
3940  */
3941 static int temp_log_show(struct seq_file *s, void *data)
3942 {
3943         u32 r, state;
3944         int i;
3945         u64 ts;
3946         u_long ns;
3947         bool was_suspended = false;
3948
3949         ts = cpu_clock(0);
3950         ns = do_div(ts, 1000000000);
3951         seq_printf(s, "%6lu.%06lu", (u_long) ts, ns / 1000);
3952
3953         if (soctherm_suspended) {
3954                 mutex_lock(&soctherm_suspend_resume_lock);
3955                 soctherm_resume_locked();
3956                 was_suspended = true;
3957         }
3958
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);
3963                 if (!state)
3964                         continue;
3965
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");
3970                         continue;
3971                 }
3972
3973                 if (read_hw_temp) {
3974                         state = REG_GET(r, TS_CPU0_STATUS1_TEMP);
3975                         seq_printf(s, "\t%ld", temp_translate(state));
3976                 } else {
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]));
3983                 }
3984         }
3985         seq_puts(s, "\n");
3986
3987         if (was_suspended) {
3988                 soctherm_suspend_locked();
3989                 mutex_unlock(&soctherm_suspend_resume_lock);
3990         }
3991         return 0;
3992 }
3993
3994 /**
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
3998  *
3999  * Return: Passes along the return value from single_open().
4000  */
4001 static int regs_open(struct inode *inode, struct file *file)
4002 {
4003         return single_open(file, regs_show, inode->i_private);
4004 }
4005
4006 static const struct file_operations regs_fops = {
4007         .open           = regs_open,
4008         .read           = seq_read,
4009         .llseek         = seq_lseek,
4010         .release        = single_release,
4011 };
4012
4013 /**
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
4017  *
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.
4021  *
4022  * Return: 0
4023  */
4024 static int convert_get(void *data, u64 *val)
4025 {
4026         *val = !read_hw_temp;
4027         return 0;
4028 }
4029 /**
4030  * convert_set() - Sets a flag indicating which temperature is
4031  * being read.
4032  * @data:       Opaque pointer to data passed in from filesystem layer
4033  * @val:        The flag value
4034  *
4035  * Sets the read_hw_temp file static flag. This flag indicates whether
4036  * the hardware temperature or the software temperature is being
4037  * read.
4038  *
4039  * Return: 0 on success.
4040  */
4041 static int convert_set(void *data, u64 val)
4042 {
4043         read_hw_temp = !val;
4044         return 0;
4045 }
4046
4047 /**
4048  * cputemp_get() - gets the CPU temperature.
4049  * @data:       not used
4050  * @val:        a pointer in which the temperature will be placed.
4051  *
4052  * Reads the temperature of the thermal sensor associated with the CPU.
4053  *
4054  * Return: 0
4055  */
4056 static int cputemp_get(void *data, u64 *val)
4057 {
4058         u32 reg;
4059
4060         reg = soctherm_readl(TS_TEMP1);
4061         *val = temp_translate(REG_GET(reg, TS_TEMP1_CPU_TEMP));
4062         return 0;
4063 }
4064
4065 /**
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
4069  *
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.
4073  * Used for debugfs.
4074  *
4075  * Return: 0 (success).
4076  */
4077 static int cputemp_set(void *data, u64 temp)
4078 {
4079         u32 reg_val = temp_translate_rev(temp);
4080         u32 reg_orig = soctherm_readl(TS_TEMP1);
4081
4082         reg_val = (reg_val << 16) | (reg_orig & 0xffff);
4083         soctherm_writel(reg_val, TS_TEMP1);
4084         return 0;
4085 }
4086
4087 /**
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
4091  *
4092  * Reads register value associated with the temperature sensor for the GPU
4093  * and stores it in the memory address pointed by val.
4094  *
4095  * Return: 0
4096  */
4097 static int gputemp_get(void *data, u64 *val)
4098 {
4099         u32 reg;
4100
4101         reg = soctherm_readl(TS_TEMP1);
4102         *val = temp_translate(REG_GET(reg, TS_TEMP1_GPU_TEMP));
4103         return 0;
4104 }
4105
4106 /**
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
4110  *
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
4115  * bitfield.
4116  * Used for debugfs.
4117  *
4118  * Return: 0 (success).
4119  */
4120 static int gputemp_set(void *data, u64 temp)
4121 {
4122         u32 reg_val = temp_translate_rev(temp);
4123         u32 reg_orig = soctherm_readl(TS_TEMP1);
4124
4125         reg_val = reg_val | (reg_orig & 0xffff0000);
4126         soctherm_writel(reg_val, TS_TEMP1);
4127         return 0;
4128 }
4129
4130 /**
4131  * memtemp_get() - gets the memory temperature.
4132  * @data:       not used
4133  * @val:        a pointer in which the temperature will be placed.
4134  *
4135  * Reads the temperature of the thermal sensor associated with the memory.
4136  *
4137  * Return: 0
4138  */
4139 static int memtemp_get(void *data, u64 *val)
4140 {
4141         u32 reg;
4142
4143         reg = soctherm_readl(TS_TEMP2);
4144         *val = temp_translate(REG_GET(reg, TS_TEMP2_MEM_TEMP));
4145         return 0;
4146 }
4147
4148 /**
4149  * memtemp_set() - Overrides the memory temperature
4150  * in hardware
4151  * @data:       Opaque pointer to data; not used
4152  * @temp:       The temperature to be written to the register
4153  *
4154  * Clears the memory temperature register, converts @temp to
4155  * a register value, and writes the converted value to the register
4156  *
4157  * Function only works when temperature overrides are enabled.
4158  *
4159  * This function is called to debug/test temperature
4160  * trip points regarding MEM temperatures
4161  *
4162  * Return: 0 on success.
4163  */
4164 static int memtemp_set(void *data, u64 temp)
4165 {
4166         u32 reg_val = temp_translate_rev(temp);
4167         u32 reg_orig = soctherm_readl(TS_TEMP2);
4168
4169         reg_val = (reg_val << 16) | (reg_orig & 0xffff);
4170         soctherm_writel(reg_val, TS_TEMP2);
4171         return 0;
4172 }
4173
4174 /**
4175  * plltemp_get() - Gets the phase-locked loop temperature.
4176  * @data:       Opaque pointer to data
4177  * @val:        The pll temperature
4178  *
4179  * The temperature value is read in from the register.
4180  * The variable pointed to by @val is set to this temperature value.
4181  *
4182  * This function is used in debugfs
4183  *
4184  * Return: 0 on success.
4185  */
4186 static int plltemp_get(void *data, u64 *val)
4187 {
4188         u32 reg;
4189
4190         reg = soctherm_readl(TS_TEMP2);
4191         *val = temp_translate(REG_GET(reg, TS_TEMP2_PLLX_TEMP));
4192         return 0;
4193 }
4194
4195
4196 /**
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
4200  *
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.
4204  * Used for debugfs.
4205  *
4206  * Return: 0 (success).
4207  */
4208 static int plltemp_set(void *data, u64 temp)
4209 {
4210         u32 reg_val = temp_translate_rev(temp);
4211         u32 reg_orig = soctherm_readl(TS_TEMP2);
4212
4213         reg_val = reg_val | (reg_orig & 0xffff0000);
4214         soctherm_writel(reg_val, TS_TEMP2);
4215         return 0;
4216 }
4217
4218 /**
4219  * tempoverride_get() - gets the temperature sensor software override value
4220  * @data:       not used
4221  * @val:        a pointer in which the value will be placed.
4222  *
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.
4226  *
4227  * Return: 0
4228  */
4229 static int tempoverride_get(void *data, u64 *val)
4230 {
4231         *val = soctherm_readl(TS_TEMP_SW_OVERRIDE);
4232         return 0;
4233 }
4234
4235 /**
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
4239  *
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.
4243  *
4244  * Return: 0
4245  */
4246 static int tempoverride_set(void *data, u64 val)
4247 {
4248         soctherm_writel(val, TS_TEMP_SW_OVERRIDE);
4249         return 0;
4250 }
4251
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,
4258                         "%llu\n");
4259
4260 static int temp_log_open(struct inode *inode, struct file *file)
4261 {
4262         return single_open(file, temp_log_show, inode->i_private);
4263 }
4264
4265 static const struct file_operations temp_log_fops = {
4266         .open           = temp_log_open,
4267         .read           = seq_read,
4268         .llseek         = seq_lseek,
4269         .release        = single_release,
4270 };
4271
4272 /**
4273  * soctherm_debug_init() - initializes the SOC_THERM debugfs files
4274  *
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.
4278  *
4279  * Return: 0
4280  */
4281 static int __init soctherm_debug_init(void)
4282 {
4283         struct dentry *tegra_soctherm_root;
4284
4285         tegra_soctherm_root = debugfs_create_dir("tegra_soctherm", NULL);
4286         debugfs_create_file("regs", 0644, tegra_soctherm_root,
4287                             NULL, &regs_fops);
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);
4302         return 0;
4303 }
4304 late_initcall(soctherm_debug_init);
4305
4306 #endif