aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/thermal/Kconfig2
-rw-r--r--drivers/thermal/exynos_thermal.c351
-rw-r--r--include/linux/platform_data/exynos_thermal.h19
3 files changed, 240 insertions, 132 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 8f2b6eaf46b8..edfd67d25013 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -49,7 +49,7 @@ config RCAR_THERMAL
49 49
50config EXYNOS_THERMAL 50config EXYNOS_THERMAL
51 tristate "Temperature sensor on Samsung EXYNOS" 51 tristate "Temperature sensor on Samsung EXYNOS"
52 depends on ARCH_EXYNOS4 && THERMAL 52 depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) && THERMAL
53 help 53 help
54 If you say yes here you get support for TMU (Thermal Managment 54 If you say yes here you get support for TMU (Thermal Managment
55 Unit) on SAMSUNG EXYNOS series of SoC. 55 Unit) on SAMSUNG EXYNOS series of SoC.
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
index 556d15b4b029..c9a33dd5e4d8 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -33,44 +33,83 @@
33#include <linux/kobject.h> 33#include <linux/kobject.h>
34#include <linux/io.h> 34#include <linux/io.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36
37#include <linux/platform_data/exynos_thermal.h> 36#include <linux/platform_data/exynos_thermal.h>
38 37#include <linux/of.h>
39#define EXYNOS4_TMU_REG_TRIMINFO 0x0 38
40#define EXYNOS4_TMU_REG_CONTROL 0x20 39#include <plat/cpu.h>
41#define EXYNOS4_TMU_REG_STATUS 0x28 40
42#define EXYNOS4_TMU_REG_CURRENT_TEMP 0x40 41/* Exynos generic registers */
43#define EXYNOS4_TMU_REG_THRESHOLD_TEMP 0x44 42#define EXYNOS_TMU_REG_TRIMINFO 0x0
44#define EXYNOS4_TMU_REG_TRIG_LEVEL0 0x50 43#define EXYNOS_TMU_REG_CONTROL 0x20
45#define EXYNOS4_TMU_REG_TRIG_LEVEL1 0x54 44#define EXYNOS_TMU_REG_STATUS 0x28
46#define EXYNOS4_TMU_REG_TRIG_LEVEL2 0x58 45#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40
47#define EXYNOS4_TMU_REG_TRIG_LEVEL3 0x5C 46#define EXYNOS_TMU_REG_INTEN 0x70
48#define EXYNOS4_TMU_REG_PAST_TEMP0 0x60 47#define EXYNOS_TMU_REG_INTSTAT 0x74
49#define EXYNOS4_TMU_REG_PAST_TEMP1 0x64 48#define EXYNOS_TMU_REG_INTCLEAR 0x78
50#define EXYNOS4_TMU_REG_PAST_TEMP2 0x68 49
51#define EXYNOS4_TMU_REG_PAST_TEMP3 0x6C 50#define EXYNOS_TMU_TRIM_TEMP_MASK 0xff
52#define EXYNOS4_TMU_REG_INTEN 0x70 51#define EXYNOS_TMU_GAIN_SHIFT 8
53#define EXYNOS4_TMU_REG_INTSTAT 0x74 52#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24
54#define EXYNOS4_TMU_REG_INTCLEAR 0x78 53#define EXYNOS_TMU_CORE_ON 3
55 54#define EXYNOS_TMU_CORE_OFF 2
56#define EXYNOS4_TMU_GAIN_SHIFT 8 55#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET 50
57#define EXYNOS4_TMU_REF_VOLTAGE_SHIFT 24 56
58 57/* Exynos4210 specific registers */
59#define EXYNOS4_TMU_TRIM_TEMP_MASK 0xff 58#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44
60#define EXYNOS4_TMU_CORE_ON 3 59#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50
61#define EXYNOS4_TMU_CORE_OFF 2 60#define EXYNOS4210_TMU_REG_TRIG_LEVEL1 0x54
62#define EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET 50 61#define EXYNOS4210_TMU_REG_TRIG_LEVEL2 0x58
63#define EXYNOS4_TMU_TRIG_LEVEL0_MASK 0x1 62#define EXYNOS4210_TMU_REG_TRIG_LEVEL3 0x5C
64#define EXYNOS4_TMU_TRIG_LEVEL1_MASK 0x10 63#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
65#define EXYNOS4_TMU_TRIG_LEVEL2_MASK 0x100 64#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
66#define EXYNOS4_TMU_TRIG_LEVEL3_MASK 0x1000 65#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
67#define EXYNOS4_TMU_INTCLEAR_VAL 0x1111 66#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
68 67
69struct exynos4_tmu_data { 68#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK 0x1
70 struct exynos4_tmu_platform_data *pdata; 69#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK 0x10
70#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK 0x100
71#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK 0x1000
72#define EXYNOS4210_TMU_INTCLEAR_VAL 0x1111
73
74/* Exynos5250 and Exynos4412 specific registers */
75#define EXYNOS_TMU_TRIMINFO_CON 0x14
76#define EXYNOS_THD_TEMP_RISE 0x50
77#define EXYNOS_THD_TEMP_FALL 0x54
78#define EXYNOS_EMUL_CON 0x80
79
80#define EXYNOS_TRIMINFO_RELOAD 0x1
81#define EXYNOS_TMU_CLEAR_RISE_INT 0x111
82#define EXYNOS_TMU_CLEAR_FALL_INT (0x111 << 16)
83#define EXYNOS_MUX_ADDR_VALUE 6
84#define EXYNOS_MUX_ADDR_SHIFT 20
85#define EXYNOS_TMU_TRIP_MODE_SHIFT 13
86
87#define EFUSE_MIN_VALUE 40
88#define EFUSE_MAX_VALUE 100
89
90/* In-kernel thermal framework related macros & definations */
91#define SENSOR_NAME_LEN 16
92#define MAX_TRIP_COUNT 8
93#define MAX_COOLING_DEVICE 4
94
95#define ACTIVE_INTERVAL 500
96#define IDLE_INTERVAL 10000
97
98/* CPU Zone information */
99#define PANIC_ZONE 4
100#define WARN_ZONE 3
101#define MONITOR_ZONE 2
102#define SAFE_ZONE 1
103
104#define GET_ZONE(trip) (trip + 2)
105#define GET_TRIP(zone) (zone - 2)
106
107struct exynos_tmu_data {
108 struct exynos_tmu_platform_data *pdata;
71 struct resource *mem; 109 struct resource *mem;
72 void __iomem *base; 110 void __iomem *base;
73 int irq; 111 int irq;
112 enum soc_type soc;
74 struct work_struct irq_work; 113 struct work_struct irq_work;
75 struct mutex lock; 114 struct mutex lock;
76 struct clk *clk; 115 struct clk *clk;
@@ -81,16 +120,17 @@ struct exynos4_tmu_data {
81 * TMU treats temperature as a mapped temperature code. 120 * TMU treats temperature as a mapped temperature code.
82 * The temperature is converted differently depending on the calibration type. 121 * The temperature is converted differently depending on the calibration type.
83 */ 122 */
84static int temp_to_code(struct exynos4_tmu_data *data, u8 temp) 123static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
85{ 124{
86 struct exynos4_tmu_platform_data *pdata = data->pdata; 125 struct exynos_tmu_platform_data *pdata = data->pdata;
87 int temp_code; 126 int temp_code;
88 127
89 /* temp should range between 25 and 125 */ 128 if (data->soc == SOC_ARCH_EXYNOS4210)
90 if (temp < 25 || temp > 125) { 129 /* temp should range between 25 and 125 */
91 temp_code = -EINVAL; 130 if (temp < 25 || temp > 125) {
92 goto out; 131 temp_code = -EINVAL;
93 } 132 goto out;
133 }
94 134
95 switch (pdata->cal_type) { 135 switch (pdata->cal_type) {
96 case TYPE_TWO_POINT_TRIMMING: 136 case TYPE_TWO_POINT_TRIMMING:
@@ -102,7 +142,7 @@ static int temp_to_code(struct exynos4_tmu_data *data, u8 temp)
102 temp_code = temp + data->temp_error1 - 25; 142 temp_code = temp + data->temp_error1 - 25;
103 break; 143 break;
104 default: 144 default:
105 temp_code = temp + EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET; 145 temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
106 break; 146 break;
107 } 147 }
108out: 148out:
@@ -113,16 +153,17 @@ out:
113 * Calculate a temperature value from a temperature code. 153 * Calculate a temperature value from a temperature code.
114 * The unit of the temperature is degree Celsius. 154 * The unit of the temperature is degree Celsius.
115 */ 155 */
116static int code_to_temp(struct exynos4_tmu_data *data, u8 temp_code) 156static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
117{ 157{
118 struct exynos4_tmu_platform_data *pdata = data->pdata; 158 struct exynos_tmu_platform_data *pdata = data->pdata;
119 int temp; 159 int temp;
120 160
121 /* temp_code should range between 75 and 175 */ 161 if (data->soc == SOC_ARCH_EXYNOS4210)
122 if (temp_code < 75 || temp_code > 175) { 162 /* temp_code should range between 75 and 175 */
123 temp = -ENODATA; 163 if (temp_code < 75 || temp_code > 175) {
124 goto out; 164 temp = -ENODATA;
125 } 165 goto out;
166 }
126 167
127 switch (pdata->cal_type) { 168 switch (pdata->cal_type) {
128 case TYPE_TWO_POINT_TRIMMING: 169 case TYPE_TWO_POINT_TRIMMING:
@@ -133,54 +174,92 @@ static int code_to_temp(struct exynos4_tmu_data *data, u8 temp_code)
133 temp = temp_code - data->temp_error1 + 25; 174 temp = temp_code - data->temp_error1 + 25;
134 break; 175 break;
135 default: