2 * Copyright (C) 2013 Spreadtrum Communications Inc.
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.
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.
16 #include <linux/kernel.h>
17 #include <linux/err.h>
18 #include <soc/sprd/sci.h>
19 #include <soc/sprd/sci_glb_regs.h>
21 #include <soc/sprd/adi.h>
23 #include <linux/sprd_thm.h>
24 #include <soc/sprd/arch_misc.h>
25 #include <soc/sprd/hardware.h>
27 #define SPRD_THM_DEBUG
29 #define THM_DEBUG(format, arg...) printk( "sprd thm: " "@@@" format, ## arg)
31 #define THM_DEBUG(format, arg...)
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)
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)
59 #define A_RAW_TEMP_OFFSET 8
60 #define A_RAW_TEMP_RANGE_MSK 0x7F
62 #define A_HIGH_BITS_OFFSET 4
64 #define A_HIGH_TAB_SZ 8
65 #define A_LOW_TAB_SZ 16
67 #define A_HOT2NOR_RANGE 15
68 #define A_LOCAL_SENSOR_ADDR_OFF 0x100
69 #define A_DELAY_TEMPERATURE 3
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
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 };
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)
87 #define RAW_TEMP_RANGE_MSK 0x3FFF
88 #define RAW_READ_RANGE_MSK 0x7FFF
90 #define HIGH_BITS_OFFSET 4
92 #define HOT2NOR_RANGE 15
93 #define LOCAL_SENSOR_ADDR_OFF 0x100
94 #define DELAY_TEMPERATURE 3
96 #define SEN_DET_PRECISION (0x50)
98 #define TSMC_DOLPHINW4T_CHIP_ID_1 0x7715A001
99 #define TSMC_DOLPHINW4T_CHIP_ID_2 0x7715A003
100 #define TSMC_DOLPHINWT4T_CHIP_ID_1 0x8815A001
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)
109 #define RAW_DATA_LOW (623)
110 #define RAW_DATA_HIGH (1030)
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 };
115 static u32 current_trip_num = 0;
116 static int arm_sen_cal_offset = 0;
117 static int pmic_sen_cal_offset = 0;
119 unsigned long SPRD_THM_BASE = 0;
120 unsigned int SPRD_THM_SIZE = 0;
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);
127 static inline int __thm_reg_write(unsigned long reg, u16 bits, u16 clear_msk)
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));
132 printk(KERN_ERR "error thm reg0x:%lx \n", reg);
137 static inline u32 __thm_reg_read(unsigned long reg)
139 if (reg >= SPRD_THM_BASE && reg <= (SPRD_THM_BASE + SPRD_THM_SIZE)) {
140 return __raw_readl((volatile void *)reg);
142 printk(KERN_ERR "error thm reg0x:%lx \n", reg);
147 static int sprd_thm_get_reg_base(struct sprd_thermal_zone *pzone ,struct resource *regs)
149 if(SPRD_THM_BASE ==0)
151 pzone->reg_base = (void __iomem *)ioremap_nocache(regs->start,
152 resource_size(regs));
153 if (!pzone->reg_base)
155 SPRD_THM_BASE = (unsigned long) pzone->reg_base;
156 SPRD_THM_SIZE= resource_size(regs);
158 pzone->reg_base = (void __iomem *)SPRD_THM_BASE;
163 int sprd_thm_set_active_trip(struct sprd_thermal_zone *pzone, int trip )
166 u32 local_sen_id = 0;
167 unsigned long local_sensor_addr = 0;
168 struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
170 THM_DEBUG("thm sensor id:%d, trip:%d \n", pzone->sensor_id, trip);
171 if (trip < 0 || trip > (trip_tab->num_trips - 1))
173 if (trip_tab->trip_points[trip].type != THERMAL_TRIP_ACTIVE)
176 local_sen_id = pzone->sensor_id;
178 (unsigned long ) pzone->reg_base + local_sen_id * LOCAL_SENSOR_ADDR_OFF;
180 //Disable sensor int except OVERHEAT
181 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL), 0, (0x7F & (~SEN_OVERHEAT_INT_BIT)));
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) {
189 __thm_reg_write((local_sensor_addr + SENSOR_HOT_THRES),
190 raw_temp, RAW_TEMP_RANGE_MSK);
192 //set Hot2Normal int temp value
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);
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);
203 //set cold int temp value
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);
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));
212 // Restart sensor to enable new paramter
213 __thm_reg_write((local_sensor_addr + SENSOR_CTRL), 0x9, 0x9);
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);
224 //enable Hot int and disable LOWOFF int
225 __thm_reg_write((local_sensor_addr + SENSOR_INT_CTRL),
227 SEN_HOT_INT_BIT | SEN_LOWOFF_INT_BIT);
234 u32 sprd_thm_temp2rawdata( int temp)
237 if ((temp < TEMP_LOW) || (temp > TEMP_HIGH))
239 raw_result = RAW_DATA_LOW +
240 (temp - TEMP_LOW) * (RAW_DATA_HIGH - RAW_DATA_LOW) / (TEMP_HIGH - TEMP_LOW);
245 int sprd_thm_rawdata2temp( int rawdata)
249 temp_result = TEMP_LOW +
250 (rawdata - RAW_DATA_LOW) * (TEMP_HIGH - TEMP_LOW) / (RAW_DATA_HIGH - RAW_DATA_LOW);
255 static int sprd_thm_regs_read(struct sprd_thermal_zone *pzone,unsigned int *regs)
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));
269 static int sprd_thm_regs_set(struct sprd_thermal_zone *pzone,unsigned int*regs)
271 u32 pre_data[4] = {0};
272 unsigned long gpu_sensor_addr,base_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);
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);
303 static unsigned long sprd_thm_temp_read(struct sprd_thermal_zone *pzone)
307 u32 sensor = pzone->sensor_id, local_sen_id = 0;
308 unsigned long local_sensor_addr;
309 if(pzone->sensor_id == SPRD_GPU_SENSOR)
312 (unsigned long ) pzone->reg_base + local_sen_id * LOCAL_SENSOR_ADDR_OFF;
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;
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);
323 static int sprd_thm_trip_set(struct sprd_thermal_zone *pzone,int trip)
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);
330 int sprd_thm_chip_id_check(void)
334 chip_id_tmp = sci_get_chip_id();
336 #if !defined(CONFIG_ARCH_SCX15)
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);
344 printk("Sprd thm the chip don't support thermal CHIP_ID:0x%x \n",chip_id_tmp);
351 static int sprd_thm_hw_init(struct sprd_thermal_zone *pzone)
353 unsigned long local_sensor_addr, base_addr = 0;
354 u32 local_sen_id = 0;
356 int cal_offset = 0,ret = 0;
358 struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
359 ret = sci_efuse_thermal_cal_get(&arm_sen_cal_offset) ;
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;
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 ) );
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 ) );
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);
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
394 if (trip_tab->num_trips > 0) {
395 current_trip_num = 0;
396 sprd_thm_set_active_trip(pzone,current_trip_num);
398 if (trip_tab->trip_points[trip_tab->num_trips - 1].type ==
399 THERMAL_TRIP_CRITICAL) {
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);
410 printk(KERN_NOTICE "sprd_thm_hw_init addr 0x:%lx,int ctrl 0x%x\n",
412 __thm_reg_read((local_sensor_addr + SENSOR_INT_CTRL)));
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);
423 int sprd_thm_hw_disable_sensor(struct sprd_thermal_zone *pzone)
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);
434 THM_DEBUG("the sensor id is error \n");
439 int sprd_thm_hw_enable_sensor(struct sprd_thermal_zone *pzone)
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 ) );
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));
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);
463 THM_DEBUG("the sensor id is error \n");
469 u16 int_ctrl_reg[SPRD_MAX_SENSOR];
470 int sprd_thm_hw_suspend(struct sprd_thermal_zone *pzone)
472 unsigned long local_sensor_addr;
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));*/
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
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*/
491 THM_DEBUG("the sensor id is error \n");
495 int sprd_thm_hw_resume(struct sprd_thermal_zone *pzone)
497 unsigned long local_sensor_addr;
500 local_sensor_addr = (unsigned long )pzone->reg_base ;
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);
513 THM_DEBUG("the sensor id is error \n");
518 int sprd_thm_get_trend(struct sprd_thermal_zone *pzone, int trip, enum thermal_trend *ptrend)
520 *ptrend = pzone->trend_val;
525 int sprd_thm_get_hyst(struct sprd_thermal_zone *pzone, int trip, unsigned long *physt)
527 struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
528 if (trip >= trip_tab->num_trips - 2){
531 *physt = trip_tab->trip_points[trip].temp - trip_tab->trip_points[trip + 1].lowoff;
536 static int sprd_thm_hw_irq_handle(struct sprd_thermal_zone *pzone)
538 u32 local_sen_id = 0;
539 unsigned long local_sensor_addr;
542 u32 overhead_hot_tem_cur = 0;
543 struct sprd_thm_platform_data *trip_tab = pzone->trip_tab;
545 if(pzone->sensor_id == SPRD_GPU_SENSOR)
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);
551 __thm_reg_write((local_sensor_addr + SENSOR_INT_CLR), int_sts, ~0); //CLR INT
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);
558 overhead_hot_tem_cur = __thm_reg_read((local_sensor_addr + SENSOR_HOT_THRES))
559 & RAW_TEMP_RANGE_MSK;
561 if(SPRD_ARM_SENSOR != pzone->sensor_id){
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;
570 if (temp >= trip_tab->trip_points[current_trip_num].temp - INTOFFSET){
572 sprd_thm_set_active_trip(pzone,current_trip_num);
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){
578 sprd_thm_set_active_trip(pzone,current_trip_num);
581 THM_DEBUG("sprd_thm_hw_irq_handle NOT a HOT or LOWOFF interrupt \n");
588 struct thm_handle_ops sprd_ddie_ops[2] =
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,
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,
618 static int __init sprd_ddie_thermal_init(void)
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);
627 static void __exit sprd_ddie_thermal_exit(void)
629 sprd_thm_delete(SPRD_ARM_SENSOR);
630 sprd_thm_delete(SPRD_GPU_SENSOR);
633 module_init(sprd_ddie_thermal_init);
634 module_exit(sprd_ddie_thermal_exit);