thermal: sprd: remove build warnings
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / thermal / sprd_ddie_thm.c
1 /*
2  * Copyright (C) 2013 Spreadtrum Communications Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/err.h>
18 #include <soc/sprd/sci.h>
19 #include <soc/sprd/sci_glb_regs.h>
20 #include <linux/io.h>
21 #include <soc/sprd/adi.h>
22 #include "thm.h"
23 #include <linux/sprd_thm.h>
24 #include <soc/sprd/arch_misc.h>
25 #include <soc/sprd/hardware.h>
26
27 #define SPRD_THM_DEBUG
28 #ifdef SPRD_THM_DEBUG
29 #define THM_DEBUG(format, arg...) printk( "sprd thm: " "@@@" format, ## arg)
30 #else
31 #define THM_DEBUG(format, arg...)
32 #endif
33
34 #define THM_CTRL            (0x0000)
35 #define THM_INT_CTRL       (0x0004)
36 #define SENSOR_CTRL         (0x0020)
37 #define SENSOR_DET_PERI     (0x0024)
38 #define SENSOR_INT_CTRL     (0x0028)
39 #define SENSOR_INT_STS      (0x002C)
40 #define SENSOR_INT_RAW_STS      (0x0030)
41 #define SENSOR_INT_CLR      (0x0034)
42 #define SENSOR_OVERHEAT_THRES   (0X0040)
43 #define SENSOR_HOT_THRES   (0X0044)
44 #define SENSOR_HOT2NOR_THRES   (0X0048)
45 #define SENSOR_HIGHOFF_THRES   (0X004C)
46 #define SENSOR_LOWOFF_THRES (0X0050)
47 #define SENSOR_MON_PERI         (0X0058)
48 #define SENSOR_MON_CTL          (0X005c)
49 #define SENSOR_TEMPER0_READ     (0x0060)
50 #define SENSOR_READ_STATUS      (0x0070)
51
52
53 #define A_SEN_OVERHEAT_INT_BIT (1 << 5)
54 #define A_SEN_HOT_INT_BIT      (1 << 4)
55 #define A_SEN_HOT2NOR_INT_BIT  (1 << 3)
56 #define A_SEN_HIGHOFF_BIT  (1 << 2)
57 #define A_SEN_LOWOFF_INT_BIT  (1 << 1)
58
59 #define A_RAW_TEMP_OFFSET 8
60 #define A_RAW_TEMP_RANGE_MSK  0x7F
61
62 #define A_HIGH_BITS_OFFSET   4
63
64 #define A_HIGH_TAB_SZ 8
65 #define A_LOW_TAB_SZ  16
66
67 #define A_HOT2NOR_RANGE   15
68 #define A_LOCAL_SENSOR_ADDR_OFF 0x100
69 #define A_DELAY_TEMPERATURE 3
70 #define INTOFFSET 3
71
72 #define A_TSMC_DOLPHINW4T_CHIP_ID_1  0x7715A001
73 #define A_TSMC_DOLPHINW4T_CHIP_ID_2  0x7715A003
74 #define A_TSMC_DOLPHINWT4T_CHIP_ID_1 0x8815A001
75
76 static const short a_temp_search_high_152nm[A_HIGH_TAB_SZ] =
77     { -56, -29, -2, 26, 53, 79, 106, 133 };
78 static const short a_temp_search_low_152nm[A_LOW_TAB_SZ] =
79     { 0, 2, 3, 5, 7, 8, 10, 11, 13, 15, 17, 18, 20, 21, 23, 25 };
80
81 #define SEN_OVERHEAT_INT_BIT (1 << 5)
82 #define SEN_HOT_INT_BIT      (1 << 4)
83 #define SEN_HOT2NOR_INT_BIT  (1 << 3)
84 #define SEN_HIGHOFF_BIT  (1 << 2)
85 #define SEN_LOWOFF_INT_BIT  (1 << 1)
86
87 #define RAW_TEMP_RANGE_MSK  0x3FFF
88 #define RAW_READ_RANGE_MSK  0x7FFF
89
90 #define HIGH_BITS_OFFSET   4
91
92 #define HOT2NOR_RANGE   15
93 #define LOCAL_SENSOR_ADDR_OFF  0x100
94 #define DELAY_TEMPERATURE 3
95
96 #define SEN_DET_PRECISION  (0x50)
97
98 #define TSMC_DOLPHINW4T_CHIP_ID_1  0x7715A001
99 #define TSMC_DOLPHINW4T_CHIP_ID_2  0x7715A003
100 #define TSMC_DOLPHINWT4T_CHIP_ID_1 0x8815A001
101
102 #define TEMP_TO_RAM_DEGREE 8
103 #define TEMP_LOW         (-40)
104 #define TEMP_HIGH        (120)
105 #ifdef CONFIG_ARCH_SCX35LT8
106 #define RAW_DATA_LOW         (627)
107 #define RAW_DATA_HIGH        (1075)
108 #else
109 #define RAW_DATA_LOW         (623)
110 #define RAW_DATA_HIGH        (1030)
111 #endif
112
113 //static const u32 temp_to_raw[TEMP_TO_RAM_DEGREE + 1] = { RAW_DATA_LOW, 676, 725, 777, 828, 878, 928, 980,RAW_DATA_HIGH };
114
115 static u32 current_trip_num = 0;
116 static int arm_sen_cal_offset = 0;
117 static int pmic_sen_cal_offset = 0;
118
119 unsigned long SPRD_THM_BASE = 0;
120 unsigned int SPRD_THM_SIZE = 0;
121
122 static inline int __thm_reg_write(unsigned long reg, u16 bits, u16 clear_msk);
123 static inline u32 __thm_reg_read(unsigned long reg);
124 int sprd_thm_set_active_trip(struct sprd_thermal_zone *pzone, int trip );
125 u32 sprd_thm_temp2rawdata( int temp);
126
127 static inline int __thm_reg_write(unsigned long reg, u16 bits, u16 clear_msk)
128 {
129         if (reg >= SPRD_THM_BASE && reg <= (SPRD_THM_BASE + SPRD_THM_SIZE)) {
130                 __raw_writel(((__raw_readl((volatile void *)reg) & ~clear_msk) | bits), ((volatile void *)reg));
131          }else {
132                 printk(KERN_ERR "error thm reg0x:%lx \n", reg);
133         }
134         return 0;
135 }
136
137 static inline u32 __thm_reg_read(unsigned long reg)
138 {
139         if (reg >= SPRD_THM_BASE && reg <= (SPRD_THM_BASE + SPRD_THM_SIZE)) {
140                 return __raw_readl((volatile void *)reg);
141         } else {
142                 printk(KERN_ERR "error thm reg0x:%lx \n", reg);
143         }
144         return 0;
145 }
146
147 static int sprd_thm_get_reg_base(struct sprd_thermal_zone *pzone ,struct resource *regs)
148 {
149         if(SPRD_THM_BASE ==0)
150         {
151                 pzone->reg_base = (void __iomem *)ioremap_nocache(regs->start,
152                         resource_size(regs));
153                 if (!pzone->reg_base)
154                         return -ENOMEM;
155                 SPRD_THM_BASE = (unsigned long) pzone->reg_base;
156                 SPRD_THM_SIZE= resource_size(regs);
157         }else{
158                 pzone->reg_base = (void __iomem *)SPRD_THM_BASE;
159         }
160         return 0;
161 }
162
163 int sprd_thm_set_active_trip(struct sprd_thermal_zone *pzone, int trip )
164 {
165         u32 raw_temp = 0;
166         u32 local_sen_id = 0;
167         unsigned long  local_sensor_addr = 0;
168         struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
169
170         THM_DEBUG("thm sensor id:%d, trip:%d \n", pzone->sensor_id, trip);
171         if (trip < 0 || trip > (trip_tab->num_trips - 1))
172                 return -1;
173         if (trip_tab->trip_points[trip].type != THERMAL_TRIP_ACTIVE)
174                 return -1;
175
176         local_sen_id = pzone->sensor_id;
177         local_sensor_addr =
178                 (unsigned long ) pzone->reg_base + local_sen_id * LOCAL_SENSOR_ADDR_OFF;
179
180         //Disable sensor int except OVERHEAT
181         __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL), 0, (0x7F & (~SEN_OVERHEAT_INT_BIT)));
182
183         //set hot int temp value
184         THM_DEBUG("thm sensor trip:%d, temperature:%ld \n", trip, trip_tab->trip_points[trip].temp);
185         raw_temp = sprd_thm_temp2rawdata(trip_tab->trip_points[trip].temp + arm_sen_cal_offset);
186         if (raw_temp < RAW_TEMP_RANGE_MSK) {
187                 raw_temp++;
188         }
189         __thm_reg_write((local_sensor_addr + SENSOR_HOT_THRES),
190                                                 raw_temp, RAW_TEMP_RANGE_MSK);
191
192         //set Hot2Normal int temp value
193         raw_temp =
194         sprd_thm_temp2rawdata(trip_tab->trip_points[trip].lowoff  + 2 + pmic_sen_cal_offset);
195         __thm_reg_write((local_sensor_addr + SENSOR_HOT2NOR_THRES),
196                 raw_temp, RAW_TEMP_RANGE_MSK);
197
198         raw_temp =
199         sprd_thm_temp2rawdata( trip_tab->trip_points[trip].lowoff  + 1 + pmic_sen_cal_offset);
200         __thm_reg_write((local_sensor_addr + SENSOR_HIGHOFF_THRES),
201                 raw_temp, RAW_TEMP_RANGE_MSK);
202
203         //set cold int temp value
204         raw_temp =
205         sprd_thm_temp2rawdata( trip_tab->trip_points[trip].lowoff + pmic_sen_cal_offset);
206         __thm_reg_write((local_sensor_addr + SENSOR_LOWOFF_THRES),
207                 raw_temp,RAW_TEMP_RANGE_MSK);
208
209         THM_DEBUG("thm set HOT:0x%x, HOT2NOR:0x%x, LOWOFF:0x%x\n", __thm_reg_read(local_sensor_addr + SENSOR_HOT_THRES),
210          __thm_reg_read(local_sensor_addr + SENSOR_HOT2NOR_THRES), __thm_reg_read(local_sensor_addr + SENSOR_LOWOFF_THRES));
211
212         // Restart sensor to enable new paramter
213         __thm_reg_write((local_sensor_addr + SENSOR_CTRL), 0x9, 0x9);
214
215         if (trip > 0)
216         {
217                 //enable Hot int and Lowoff int
218                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL),
219                         SEN_HOT_INT_BIT | SEN_LOWOFF_INT_BIT,
220                         SEN_HOT_INT_BIT | SEN_LOWOFF_INT_BIT);
221         }
222         else
223         {
224                 //enable Hot int and disable LOWOFF int
225                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL),
226                         SEN_HOT_INT_BIT,
227                         SEN_HOT_INT_BIT | SEN_LOWOFF_INT_BIT);
228         }
229
230         return 0;
231 }
232
233
234 u32 sprd_thm_temp2rawdata( int temp)
235 {
236         u32 raw_result;
237          if ((temp < TEMP_LOW) || (temp > TEMP_HIGH))
238                 return 0;
239          raw_result = RAW_DATA_LOW +
240                 (temp - TEMP_LOW) * (RAW_DATA_HIGH - RAW_DATA_LOW) / (TEMP_HIGH - TEMP_LOW);
241
242         return raw_result;
243 }
244
245 int sprd_thm_rawdata2temp( int rawdata)
246 {
247         int temp_result;
248
249         temp_result = TEMP_LOW +
250                 (rawdata - RAW_DATA_LOW) * (TEMP_HIGH - TEMP_LOW) / (RAW_DATA_HIGH - RAW_DATA_LOW);
251
252         return temp_result;
253 }
254 #ifdef THM_TEST
255 static int sprd_thm_regs_read(struct sprd_thermal_zone *pzone,unsigned int *regs)
256 {
257         unsigned long base_addr = 0;
258         printk(" sprd_thm_regs_read\n");
259         if(pzone->sensor_id == SPRD_ARM_SENSOR){
260                 base_addr = (unsigned long) pzone->reg_base;
261                 *regs =  __thm_reg_read((base_addr + SENSOR_DET_PERI));
262                 *(regs + 1) =  __thm_reg_read((base_addr + SENSOR_MON_CTL));
263                 *(regs + 2) =  __thm_reg_read((base_addr + SENSOR_MON_PERI));
264                 *(regs + 3) =  __thm_reg_read((base_addr + SENSOR_CTRL));
265         }
266         return 0;
267 }
268
269 static int sprd_thm_regs_set(struct sprd_thermal_zone *pzone,unsigned int*regs)
270 {
271         u32 pre_data[4] = {0};
272         unsigned long  gpu_sensor_addr,base_addr;
273         gpu_sensor_addr =
274             (unsigned long ) pzone->reg_base +LOCAL_SENSOR_ADDR_OFF;
275         printk("sprd_thm_regs_set\n");
276         base_addr = (unsigned long) pzone->reg_base;
277         pre_data[0] = __thm_reg_read(base_addr + SENSOR_DET_PERI);
278         pre_data[1] = __thm_reg_read(base_addr + SENSOR_MON_CTL);
279         pre_data[2] = __thm_reg_read(base_addr + SENSOR_MON_PERI);
280         pre_data[3] = __thm_reg_read(base_addr + SENSOR_CTRL);
281         __thm_reg_write((base_addr + SENSOR_CTRL), 0x00, 0x01);
282         __thm_reg_write((base_addr+ SENSOR_CTRL), 0x8, 0x08);
283         __thm_reg_write((base_addr + SENSOR_DET_PERI), regs[0], pre_data[0]);
284         __thm_reg_write((base_addr + SENSOR_MON_CTL), regs[1], pre_data[1]);
285         __thm_reg_write((base_addr + SENSOR_MON_PERI), regs[2], pre_data[2] |0x100 );
286         __thm_reg_write((base_addr + SENSOR_CTRL), regs[3], pre_data[3]);
287         __thm_reg_write((base_addr + SENSOR_CTRL), 0x8, 0x8);
288
289         pre_data[0] = __thm_reg_read(gpu_sensor_addr + SENSOR_DET_PERI);
290         pre_data[1] = __thm_reg_read(gpu_sensor_addr + SENSOR_MON_CTL);
291         pre_data[2] = __thm_reg_read(gpu_sensor_addr + SENSOR_MON_PERI);
292         pre_data[3] = __thm_reg_read(gpu_sensor_addr + SENSOR_CTRL);
293         __thm_reg_write((gpu_sensor_addr + SENSOR_CTRL), 0x00, 0x01);
294         __thm_reg_write((gpu_sensor_addr+ SENSOR_CTRL), 0x8, 0x08);     
295         __thm_reg_write((gpu_sensor_addr + SENSOR_DET_PERI), regs[0], pre_data[0]);
296         __thm_reg_write((gpu_sensor_addr + SENSOR_MON_CTL), regs[1], pre_data[1]);
297         __thm_reg_write((gpu_sensor_addr + SENSOR_MON_PERI), regs[2], pre_data[2] |0x100 );
298         __thm_reg_write((gpu_sensor_addr + SENSOR_CTRL), regs[3], pre_data[3]);
299         __thm_reg_write((gpu_sensor_addr + SENSOR_CTRL), 0x8, 0x8);
300         return 0;
301 }
302 #endif
303 static unsigned long sprd_thm_temp_read(struct sprd_thermal_zone *pzone)
304 {
305         u32 rawdata = 0;
306         int cal_offset = 0;
307         u32 sensor = pzone->sensor_id, local_sen_id = 0;
308         unsigned long  local_sensor_addr;
309         if(pzone->sensor_id == SPRD_GPU_SENSOR)
310                 local_sen_id = 1;
311         local_sensor_addr =
312             (unsigned long ) pzone->reg_base + local_sen_id * LOCAL_SENSOR_ADDR_OFF;
313
314         rawdata = __thm_reg_read(local_sensor_addr + SENSOR_TEMPER0_READ);
315         rawdata = rawdata & RAW_READ_RANGE_MSK;
316         cal_offset = arm_sen_cal_offset;
317
318         THM_DEBUG("D thm sensor id:%d, cal_offset:%d, rawdata:0x%x\n", sensor,
319                         cal_offset, rawdata);
320         return (sprd_thm_rawdata2temp( rawdata) -cal_offset);
321 }
322 #ifdef  THM_TEST
323 static int sprd_thm_trip_set(struct sprd_thermal_zone *pzone,int trip)
324 {
325         THM_DEBUG("sprd_thm_trip_set trip=%d, temp=%ld,lowoff =%ld\n",
326                 trip,pzone->trip_tab->trip_points[trip].temp,pzone->trip_tab->trip_points[trip].lowoff);
327         return sprd_thm_set_active_trip(pzone,current_trip_num);
328 }
329 #endif
330 int sprd_thm_chip_id_check(void)
331 {
332         u32 chip_id_tmp;
333
334         chip_id_tmp = sci_get_chip_id();
335
336 #if !defined(CONFIG_ARCH_SCX15)
337         return 0;
338 #else
339         if ((TSMC_DOLPHINW4T_CHIP_ID_1 == chip_id_tmp) || (TSMC_DOLPHINW4T_CHIP_ID_2 == chip_id_tmp) ||
340            (TSMC_DOLPHINWT4T_CHIP_ID_1 == chip_id_tmp)) {
341                 //printk("Sprd thm the chip support thermal CHIP_ID:0x%x \n",chip_id_tmp);
342                 return 0;
343         } else {
344                 printk("Sprd thm the chip don't support thermal CHIP_ID:0x%x \n",chip_id_tmp);
345                 return -1;
346         }
347 #endif
348 }
349 int init_flag=0;
350
351 static int sprd_thm_hw_init(struct sprd_thermal_zone *pzone)
352 {
353         unsigned long  local_sensor_addr, base_addr = 0;
354         u32 local_sen_id = 0;
355         u32 raw_temp = 0;
356         int cal_offset = 0,ret = 0;
357         int i;
358         struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
359         ret = sci_efuse_thermal_cal_get(&arm_sen_cal_offset) ;
360
361         THM_DEBUG("arm_sen_cal_offset =%d,ret =%d\n",arm_sen_cal_offset,ret);
362         base_addr = (unsigned long) pzone->reg_base;
363         local_sen_id = pzone->sensor_id;
364         local_sensor_addr = base_addr + local_sen_id * LOCAL_SENSOR_ADDR_OFF;
365
366         printk(KERN_NOTICE "sprd_thm_hw_init 2713s_thm id:%d,base 0x%lx \n",
367                 pzone->sensor_id, base_addr);
368         sci_glb_set(REG_AON_APB_APB_EB1, BIT_THM_EB);
369 #ifdef CONFIG_ARCH_SCX35LT8
370         sci_glb_set(REG_AON_APB_APB_RTC_EB,
371                         (BIT_THM_RTC_EB | BIT_GPU_THMA_RTC_EB |
372                         BIT_GPU_THMA_RTC_AUTO_EN | BIT_CA53_LIT_THMA_RTC_EB |
373                         BIT_CA53_BIG_THMA_RTC_EB |BIT_ARM_THMA_RTC_AUTO_EN ) );
374 #else
375         sci_glb_set(REG_AON_APB_APB_RTC_EB,
376                         (BIT_THM_RTC_EB | BIT_GPU_THMA_RTC_EB |
377                         BIT_GPU_THMA_RTC_AUTO_EN | BIT_ARM_THMA_RTC_EB |BIT_ARM_THMA_RTC_AUTO_EN ) );
378 #endif
379         if(init_flag ==0)
380                 {
381                         sci_glb_set(REG_AON_APB_APB_RST1,BIT_THM_SOFT_RST);
382                         for(i=0; i < 10000; i++);
383                         sci_glb_clr(REG_AON_APB_APB_RST1,BIT_THM_SOFT_RST);
384                         __thm_reg_write((base_addr + THM_CTRL), 0x3, 0);
385                         __thm_reg_write((base_addr + THM_INT_CTRL), 0x1, 0);
386                         init_flag =1;
387                 }
388
389                         __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL), 0, ~0);  //disable all int
390                         __thm_reg_write((local_sensor_addr + SENSOR_INT_CLR), ~0, 0);   //clr all int
391
392
393                 //set int
394         if (trip_tab->num_trips > 0) {
395                 current_trip_num = 0;
396                 sprd_thm_set_active_trip(pzone,current_trip_num);
397                         //set overheat
398                 if (trip_tab->trip_points[trip_tab->num_trips - 1].type ==
399                         THERMAL_TRIP_CRITICAL) {
400                         raw_temp =
401                                 sprd_thm_temp2rawdata( trip_tab->trip_points[trip_tab->num_trips - 1].temp - cal_offset);
402                                 //set overheat int temp value
403                         __thm_reg_write((local_sensor_addr +
404                                                  SENSOR_OVERHEAT_THRES),
405                                                  raw_temp, RAW_TEMP_RANGE_MSK);
406                         __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL),  //enable int
407                                                 SEN_OVERHEAT_INT_BIT, 0);
408                 }
409         }
410         printk(KERN_NOTICE "sprd_thm_hw_init addr 0x:%lx,int ctrl 0x%x\n",
411                         local_sensor_addr,
412                         __thm_reg_read((local_sensor_addr + SENSOR_INT_CTRL)));
413
414         __thm_reg_write((local_sensor_addr + SENSOR_DET_PERI), 0x4000, 0x4000);
415         __thm_reg_write((local_sensor_addr + SENSOR_MON_CTL), 0x21, 0X21);
416         __thm_reg_write((local_sensor_addr + SENSOR_MON_PERI), 0x400, 0x100);
417         if (SPRD_ARM_SENSOR== pzone->sensor_id)
418                 __thm_reg_write((base_addr + SENSOR_CTRL + LOCAL_SENSOR_ADDR_OFF), 0x030, 0x030);
419         __thm_reg_write((local_sensor_addr + SENSOR_CTRL), 0x39, 0x030);
420         return 0;
421 }
422
423 int sprd_thm_hw_disable_sensor(struct sprd_thermal_zone *pzone)
424 {
425         int ret = 0;
426         /* Sensor minitor disable */
427         if (SPRD_ARM_SENSOR == pzone->sensor_id) {
428                 /*__thm_reg_write((u32)(pzone->reg_base + SENSOR_CTRL), 0x00, 0x01);*/
429                 __thm_reg_write((unsigned long )(pzone->reg_base + SENSOR_CTRL), 0x8, 0x01);
430         } else if (SPRD_GPU_SENSOR == pzone->sensor_id) {
431                 /*__thm_reg_write((u32)(pzone->reg_base + SENSOR_CTRL+ LOCAL_SENSOR_ADDR_OFF), 0x00, 0x01);*/
432                 __thm_reg_write((unsigned long )(pzone->reg_base + SENSOR_CTRL + LOCAL_SENSOR_ADDR_OFF), 0x8, 0x01);
433         } else {
434                 THM_DEBUG("the sensor id is error \n");
435         }
436         return ret;
437 }
438
439 int sprd_thm_hw_enable_sensor(struct sprd_thermal_zone *pzone)
440 {
441         int ret = 0;
442         // Sensor minitor enable
443         THM_DEBUG("enable sensor sensor_ID:0x%x \n",pzone->sensor_id);
444         if (SPRD_ARM_SENSOR == pzone->sensor_id) {
445 #ifdef CONFIG_ARCH_SCX35LT8
446                 sci_glb_set(REG_AON_APB_APB_RTC_EB,
447                         (BIT_THM_RTC_EB | BIT_GPU_THMA_RTC_EB |
448                         BIT_GPU_THMA_RTC_AUTO_EN | BIT_CA53_LIT_THMA_RTC_EB |
449                         BIT_CA53_BIG_THMA_RTC_EB |BIT_ARM_THMA_RTC_AUTO_EN ) );
450 #else
451                 sci_glb_set(REG_AON_APB_APB_RTC_EB,
452                                 (BIT_THM_RTC_EB | BIT_GPU_THMA_RTC_EB |
453                                 BIT_GPU_THMA_RTC_AUTO_EN | BIT_ARM_THMA_RTC_EB | BIT_ARM_THMA_RTC_AUTO_EN));
454 #endif
455                 __thm_reg_write((uintptr_t)(pzone->reg_base + SENSOR_CTRL + LOCAL_SENSOR_ADDR_OFF), 0x030, 0x0);
456                 __thm_reg_write((uintptr_t)(pzone->reg_base + SENSOR_CTRL), 0x31, 0x0);
457         } else if (SPRD_GPU_SENSOR == pzone->sensor_id) {
458                 /*sci_glb_set(REG_AON_APB_APB_RTC_EB,
459                                 (BIT_THM_RTC_EB | BIT_GPU_THMA_RTC_EB |
460                                 BIT_GPU_THMA_RTC_AUTO_EN | BIT_ARM_THMA_RTC_EB |BIT_ARM_THMA_RTC_AUTO_EN ) );*/
461                 __thm_reg_write((uintptr_t)(pzone->reg_base + SENSOR_CTRL+LOCAL_SENSOR_ADDR_OFF), 0x31, 0x0);
462         } else {
463                 THM_DEBUG("the sensor id is error \n");
464         }
465
466         return ret;
467 }
468
469 u16 int_ctrl_reg[SPRD_MAX_SENSOR];
470 int sprd_thm_hw_suspend(struct sprd_thermal_zone *pzone)
471 {
472         unsigned long local_sensor_addr;
473         int ret = 0;
474
475         local_sensor_addr = (unsigned long )pzone->reg_base ;
476         /*int_ctrl_reg[pzone->sensor_id] = __thm_reg_read((local_sensor_addr + SENSOR_INT_CTRL));*/
477
478         sprd_thm_hw_disable_sensor(pzone);
479         if (SPRD_ARM_SENSOR == pzone->sensor_id) {
480                 int_ctrl_reg[pzone->sensor_id] = __thm_reg_read((local_sensor_addr + SENSOR_INT_CTRL));
481                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL), 0, ~0);  //disable all int
482                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CLR), ~0, 0);   //clr all int
483
484         } else if (SPRD_GPU_SENSOR == pzone->sensor_id) {
485                 int_ctrl_reg[pzone->sensor_id] =
486                         __thm_reg_read((local_sensor_addr + SENSOR_INT_CTRL+LOCAL_SENSOR_ADDR_OFF));
487                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL+LOCAL_SENSOR_ADDR_OFF), 0, ~0);    /*disable all int*/
488                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL+LOCAL_SENSOR_ADDR_OFF), ~0, 0);    /*clr all int*/
489
490         } else {
491                 THM_DEBUG("the sensor id is error \n");
492         }
493         return ret;
494 }
495 int sprd_thm_hw_resume(struct sprd_thermal_zone *pzone)
496 {
497         unsigned long local_sensor_addr;
498         int ret = 0;
499
500         local_sensor_addr = (unsigned long )pzone->reg_base ;
501
502         sprd_thm_hw_enable_sensor(pzone);
503         if (SPRD_ARM_SENSOR == pzone->sensor_id) {
504                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CLR), ~0, 0);   //clr all int
505                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL), int_ctrl_reg[pzone->sensor_id], ~0);     //enable int of saved
506                 __thm_reg_write((local_sensor_addr + SENSOR_CTRL+LOCAL_SENSOR_ADDR_OFF), 0x30, 0);
507                 __thm_reg_write((local_sensor_addr + SENSOR_CTRL), 0x39, 0);
508         } else if (SPRD_GPU_SENSOR == pzone->sensor_id) {
509                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CLR+LOCAL_SENSOR_ADDR_OFF), ~0, 0);     /*clr all int*/
510                 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL+LOCAL_SENSOR_ADDR_OFF), int_ctrl_reg[pzone->sensor_id], ~0);       /*enable int of saved*/
511                 __thm_reg_write((local_sensor_addr + SENSOR_CTRL+LOCAL_SENSOR_ADDR_OFF), 0x39, 0);
512         } else {
513                 THM_DEBUG("the sensor id is error \n");
514         }
515         return ret;
516 }
517
518 int sprd_thm_get_trend(struct sprd_thermal_zone *pzone, int trip, enum thermal_trend *ptrend)
519 {
520     *ptrend = pzone->trend_val;
521     return 0;
522 }
523
524
525 int sprd_thm_get_hyst(struct sprd_thermal_zone *pzone, int trip, unsigned long *physt)
526 {
527         struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
528         if (trip >= trip_tab->num_trips - 2){
529         *physt = 0;
530         }else{
531         *physt = trip_tab->trip_points[trip].temp - trip_tab->trip_points[trip + 1].lowoff;
532         }
533         return 0;
534 }
535
536 static int sprd_thm_hw_irq_handle(struct sprd_thermal_zone *pzone)
537 {
538         u32 local_sen_id = 0;
539         unsigned long  local_sensor_addr;
540         u32 int_sts;
541         int ret = 0;
542         u32 overhead_hot_tem_cur = 0;
543         struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
544         int temp;
545         if(pzone->sensor_id == SPRD_GPU_SENSOR)
546                 local_sen_id = 1;
547         local_sensor_addr =
548             (unsigned long ) pzone->reg_base + local_sen_id * LOCAL_SENSOR_ADDR_OFF;
549         int_sts = __thm_reg_read(local_sensor_addr + SENSOR_INT_STS);
550
551         __thm_reg_write((local_sensor_addr + SENSOR_INT_CLR), int_sts, ~0);     //CLR INT
552
553         printk("sprd_thm_hw_irq_handle --------@@@------id:%d, int_sts :0x%x \n",
554                         pzone->sensor_id, int_sts);
555         temp = sprd_thm_temp_read(pzone);
556         printk("sprd_thm_hw_irq_handle ------$$$--------temp:%d\n", temp);
557
558         overhead_hot_tem_cur = __thm_reg_read((local_sensor_addr + SENSOR_HOT_THRES))
559                                                                                         & RAW_TEMP_RANGE_MSK;
560
561         if(SPRD_ARM_SENSOR != pzone->sensor_id){
562                 return ret;
563         }
564         if (int_sts & SEN_HOT_INT_BIT){
565                  pzone->trend_val = THERMAL_TREND_RAISING;
566                 if ((current_trip_num) >= (trip_tab->num_trips - 2)){
567                         current_trip_num = trip_tab->num_trips - 2;
568                         return ret;
569                 }
570                 if (temp >= trip_tab->trip_points[current_trip_num].temp - INTOFFSET){
571                         current_trip_num++;
572                         sprd_thm_set_active_trip(pzone,current_trip_num);
573                 }
574         }else if (int_sts & SEN_LOWOFF_INT_BIT){
575                 pzone->trend_val = THERMAL_TREND_DROPPING;
576                 if (temp < trip_tab->trip_points[current_trip_num].lowoff + INTOFFSET){
577                         current_trip_num--;
578                         sprd_thm_set_active_trip(pzone,current_trip_num);
579                 }
580         }else{
581                 THM_DEBUG("sprd_thm_hw_irq_handle NOT a HOT or LOWOFF interrupt \n");
582                 return ret;
583         }
584
585         return ret;
586 }
587
588 struct thm_handle_ops sprd_ddie_ops[2] =
589 {
590         {
591                 .hw_init = sprd_thm_hw_init,
592                 .get_reg_base = sprd_thm_get_reg_base,
593                 .read_temp = sprd_thm_temp_read,
594                 .get_trend = sprd_thm_get_trend,
595                 .get_hyst = sprd_thm_get_hyst,
596                 .irq_handle = sprd_thm_hw_irq_handle,
597                 .suspend = sprd_thm_hw_suspend,
598                 .resume = sprd_thm_hw_resume,
599                 .trip_debug_set = sprd_thm_trip_set,
600                 .reg_debug_get = sprd_thm_regs_read,
601                 .reg_debug_set = sprd_thm_regs_set,
602         },
603         {
604                 .hw_init = sprd_thm_hw_init,
605                 .get_reg_base = sprd_thm_get_reg_base,
606                 .read_temp = sprd_thm_temp_read,
607                 .get_trend = sprd_thm_get_trend,
608                 .get_hyst = sprd_thm_get_hyst,
609                 .irq_handle = sprd_thm_hw_irq_handle,
610                 .suspend = sprd_thm_hw_suspend,
611                 .resume = sprd_thm_hw_resume,
612                 .trip_debug_set = sprd_thm_trip_set,
613                 .reg_debug_get = sprd_thm_regs_read,
614                 .reg_debug_set = sprd_thm_regs_set,
615         }
616 };
617
618 static int __init sprd_ddie_thermal_init(void)
619 {
620         if (0 == sprd_thm_chip_id_check()) {
621                 sprd_thm_add(&sprd_ddie_ops[0],"sprd_arm_thm",SPRD_ARM_SENSOR);
622                 sprd_thm_add(&sprd_ddie_ops[1],"sprd_gpu_thm",SPRD_GPU_SENSOR);
623         }
624         return 0;
625 }
626
627 static void __exit sprd_ddie_thermal_exit(void)
628 {
629         sprd_thm_delete(SPRD_ARM_SENSOR);
630         sprd_thm_delete(SPRD_GPU_SENSOR);
631 }
632
633 module_init(sprd_ddie_thermal_init);
634 module_exit(sprd_ddie_thermal_exit);