diff options
-rw-r--r-- | drivers/thermal/samsung/exynos_thermal_common.h | 7 | ||||
-rw-r--r-- | drivers/thermal/samsung/exynos_tmu.c | 43 | ||||
-rw-r--r-- | drivers/thermal/samsung/exynos_tmu.h | 49 | ||||
-rw-r--r-- | drivers/thermal/samsung/exynos_tmu_data.c | 34 |
4 files changed, 85 insertions, 48 deletions
diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h index 57ce33b39b54..fee15889f9fa 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.h +++ b/drivers/thermal/samsung/exynos_thermal_common.h | |||
@@ -44,6 +44,13 @@ | |||
44 | 44 | ||
45 | #define EXYNOS_ZONE_COUNT 3 | 45 | #define EXYNOS_ZONE_COUNT 3 |
46 | 46 | ||
47 | enum trigger_type { | ||
48 | THROTTLE_ACTIVE = 1, | ||
49 | THROTTLE_PASSIVE, | ||
50 | SW_TRIP, | ||
51 | HW_TRIP, | ||
52 | }; | ||
53 | |||
47 | /** | 54 | /** |
48 | * struct freq_clip_table | 55 | * struct freq_clip_table |
49 | * @freq_clip_max: maximum frequency allowed for this cooling state. | 56 | * @freq_clip_max: maximum frequency allowed for this cooling state. |
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index fa33a485ee5b..401ec980c592 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf | 49 | #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf |
50 | #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 | 50 | #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 |
51 | #define EXYNOS_TMU_CORE_EN_SHIFT 0 | 51 | #define EXYNOS_TMU_CORE_EN_SHIFT 0 |
52 | #define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET 50 | ||
53 | 52 | ||
54 | /* Exynos4210 specific registers */ | 53 | /* Exynos4210 specific registers */ |
55 | #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 | 54 | #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 |
@@ -94,9 +93,6 @@ | |||
94 | #define EXYNOS_TMU_INTEN_FALL1_SHIFT 20 | 93 | #define EXYNOS_TMU_INTEN_FALL1_SHIFT 20 |
95 | #define EXYNOS_TMU_INTEN_FALL2_SHIFT 24 | 94 | #define EXYNOS_TMU_INTEN_FALL2_SHIFT 24 |
96 | 95 | ||
97 | #define EFUSE_MIN_VALUE 40 | ||
98 | #define EFUSE_MAX_VALUE 100 | ||
99 | |||
100 | #ifdef CONFIG_THERMAL_EMULATION | 96 | #ifdef CONFIG_THERMAL_EMULATION |
101 | #define EXYNOS_EMUL_TIME 0x57F0 | 97 | #define EXYNOS_EMUL_TIME 0x57F0 |
102 | #define EXYNOS_EMUL_TIME_MASK 0xffff | 98 | #define EXYNOS_EMUL_TIME_MASK 0xffff |
@@ -136,15 +132,16 @@ static int temp_to_code(struct exynos_tmu_data *data, u8 temp) | |||
136 | 132 | ||
137 | switch (pdata->cal_type) { | 133 | switch (pdata->cal_type) { |
138 | case TYPE_TWO_POINT_TRIMMING: | 134 | case TYPE_TWO_POINT_TRIMMING: |
139 | temp_code = (temp - 25) * | 135 | temp_code = (temp - pdata->first_point_trim) * |
140 | (data->temp_error2 - data->temp_error1) / | 136 | (data->temp_error2 - data->temp_error1) / |
141 | (85 - 25) + data->temp_error1; | 137 | (pdata->second_point_trim - pdata->first_point_trim) + |
138 | data->temp_error1; | ||
142 | break; | 139 | break; |
143 | case TYPE_ONE_POINT_TRIMMING: | 140 | case TYPE_ONE_POINT_TRIMMING: |
144 | temp_code = temp + data->temp_error1 - 25; | 141 | temp_code = temp + data->temp_error1 - pdata->first_point_trim; |
145 | break; | 142 | break; |
146 | default: | 143 | default: |
147 | temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET; | 144 | temp_code = temp + pdata->default_temp_offset; |
148 | break; | 145 | break; |
149 | } | 146 | } |
150 | out: | 147 | out: |
@@ -169,14 +166,16 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code) | |||
169 | 166 | ||
170 | switch (pdata->cal_type) { | 167 | switch (pdata->cal_type) { |
171 | case TYPE_TWO_POINT_TRIMMING: | 168 | case TYPE_TWO_POINT_TRIMMING: |
172 | temp = (temp_code - data->temp_error1) * (85 - 25) / | 169 | temp = (temp_code - data->temp_error1) * |
173 | (data->temp_error2 - data->temp_error1) + 25; | 170 | (pdata->second_point_trim - pdata->first_point_trim) / |
171 | (data->temp_error2 - data->temp_error1) + | ||
172 | pdata->first_point_trim; | ||
174 | break; | 173 | break; |
175 | case TYPE_ONE_POINT_TRIMMING: | 174 | case TYPE_ONE_POINT_TRIMMING: |
176 | temp = temp_code - data->temp_error1 + 25; | 175 | temp = temp_code - data->temp_error1 + pdata->first_point_trim; |
177 | break; | 176 | break; |
178 | default: | 177 | default: |
179 | temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET; | 178 | temp = temp_code - pdata->default_temp_offset; |
180 | break; | 179 | break; |
181 | } | 180 | } |
182 | out: | 181 | out: |
@@ -209,8 +208,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev) | |||
209 | data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK; | 208 | data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK; |
210 | data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK); | 209 | data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK); |
211 | 210 | ||
212 | if ((EFUSE_MIN_VALUE > data->temp_error1) || | 211 | if ((pdata->min_efuse_value > data->temp_error1) || |
213 | (data->temp_error1 > EFUSE_MAX_VALUE) || | 212 | (data->temp_error1 > pdata->max_efuse_value) || |
214 | (data->temp_error2 != 0)) | 213 | (data->temp_error2 != 0)) |
215 | data->temp_error1 = pdata->efuse_value; | 214 | data->temp_error1 = pdata->efuse_value; |
216 | 215 | ||
@@ -300,10 +299,10 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) | |||
300 | if (on) { | 299 | if (on) { |
301 | con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); | 300 | con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); |
302 | interrupt_en = | 301 | interrupt_en = |
303 | pdata->trigger_level3_en << EXYNOS_TMU_INTEN_RISE3_SHIFT | | 302 | pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT | |
304 | pdata->trigger_level2_en << EXYNOS_TMU_INTEN_RISE2_SHIFT | | 303 | pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT | |
305 | pdata->trigger_level1_en << EXYNOS_TMU_INTEN_RISE1_SHIFT | | 304 | pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT | |
306 | pdata->trigger_level0_en << EXYNOS_TMU_INTEN_RISE0_SHIFT; | 305 | pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT; |
307 | if (pdata->threshold_falling) | 306 | if (pdata->threshold_falling) |
308 | interrupt_en |= | 307 | interrupt_en |= |
309 | interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; | 308 | interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; |
@@ -533,9 +532,9 @@ static int exynos_tmu_probe(struct platform_device *pdev) | |||
533 | 532 | ||
534 | /* Register the sensor with thermal management interface */ | 533 | /* Register the sensor with thermal management interface */ |
535 | (&exynos_sensor_conf)->private_data = data; | 534 | (&exynos_sensor_conf)->private_data = data; |
536 | exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en + | 535 | exynos_sensor_conf.trip_data.trip_count = pdata->trigger_enable[0] + |
537 | pdata->trigger_level1_en + pdata->trigger_level2_en + | 536 | pdata->trigger_enable[1] + pdata->trigger_enable[2]+ |
538 | pdata->trigger_level3_en; | 537 | pdata->trigger_enable[3]; |
539 | 538 | ||
540 | for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++) | 539 | for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++) |
541 | exynos_sensor_conf.trip_data.trip_val[i] = | 540 | exynos_sensor_conf.trip_data.trip_val[i] = |
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 1857609518f2..473acae04f82 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h | |||
@@ -32,6 +32,11 @@ enum calibration_type { | |||
32 | TYPE_NONE, | 32 | TYPE_NONE, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | enum calibration_mode { | ||
36 | SW_MODE, | ||
37 | HW_MODE, | ||
38 | }; | ||
39 | |||
35 | enum soc_type { | 40 | enum soc_type { |
36 | SOC_ARCH_EXYNOS4210 = 1, | 41 | SOC_ARCH_EXYNOS4210 = 1, |
37 | SOC_ARCH_EXYNOS, | 42 | SOC_ARCH_EXYNOS, |
@@ -57,18 +62,15 @@ enum soc_type { | |||
57 | * 3: temperature for trigger_level3 interrupt | 62 | * 3: temperature for trigger_level3 interrupt |
58 | * condition for trigger_level3 interrupt: | 63 | * condition for trigger_level3 interrupt: |
59 | * current temperature > threshold + trigger_levels[3] | 64 | * current temperature > threshold + trigger_levels[3] |
60 | * @trigger_level0_en: | 65 | * @trigger_type: defines the type of trigger. Possible values are, |
61 | * 1 = enable trigger_level0 interrupt, | 66 | * THROTTLE_ACTIVE trigger type |
62 | * 0 = disable trigger_level0 interrupt | 67 | * THROTTLE_PASSIVE trigger type |
63 | * @trigger_level1_en: | 68 | * SW_TRIP trigger type |
64 | * 1 = enable trigger_level1 interrupt, | 69 | * HW_TRIP |
65 | * 0 = disable trigger_level1 interrupt | 70 | * @trigger_enable[]: array to denote which trigger levels are enabled. |
66 | * @trigger_level2_en: | 71 | * 1 = enable trigger_level[] interrupt, |
67 | * 1 = enable trigger_level2 interrupt, | 72 | * 0 = disable trigger_level[] interrupt |
68 | * 0 = disable trigger_level2 interrupt | 73 | * @max_trigger_level: max trigger level supported by the TMU |
69 | * @trigger_level3_en: | ||
70 | * 1 = enable trigger_level3 interrupt, | ||
71 | * 0 = disable trigger_level3 interrupt | ||
72 | * @gain: gain of amplifier in the positive-TC generator block | 74 | * @gain: gain of amplifier in the positive-TC generator block |
73 | * 0 <= gain <= 15 | 75 | * 0 <= gain <= 15 |
74 | * @reference_voltage: reference voltage of amplifier | 76 | * @reference_voltage: reference voltage of amplifier |
@@ -78,7 +80,13 @@ enum soc_type { | |||
78 | * 000, 100, 101, 110 and 111 can be different modes | 80 | * 000, 100, 101, 110 and 111 can be different modes |
79 | * @type: determines the type of SOC | 81 | * @type: determines the type of SOC |
80 | * @efuse_value: platform defined fuse value | 82 | * @efuse_value: platform defined fuse value |
83 | * @min_efuse_value: minimum valid trimming data | ||
84 | * @max_efuse_value: maximum valid trimming data | ||
85 | * @first_point_trim: temp value of the first point trimming | ||
86 | * @second_point_trim: temp value of the second point trimming | ||
87 | * @default_temp_offset: default temperature offset in case of no trimming | ||
81 | * @cal_type: calibration type for temperature | 88 | * @cal_type: calibration type for temperature |
89 | * @cal_mode: calibration mode for temperature | ||
82 | * @freq_clip_table: Table representing frequency reduction percentage. | 90 | * @freq_clip_table: Table representing frequency reduction percentage. |
83 | * @freq_tab_count: Count of the above table as frequency reduction may | 91 | * @freq_tab_count: Count of the above table as frequency reduction may |
84 | * applicable to only some of the trigger levels. | 92 | * applicable to only some of the trigger levels. |
@@ -88,18 +96,23 @@ enum soc_type { | |||
88 | struct exynos_tmu_platform_data { | 96 | struct exynos_tmu_platform_data { |
89 | u8 threshold; | 97 | u8 threshold; |
90 | u8 threshold_falling; | 98 | u8 threshold_falling; |
91 | u8 trigger_levels[4]; | 99 | u8 trigger_levels[MAX_TRIP_COUNT]; |
92 | bool trigger_level0_en; | 100 | enum trigger_type trigger_type[MAX_TRIP_COUNT]; |
93 | bool trigger_level1_en; | 101 | bool trigger_enable[MAX_TRIP_COUNT]; |
94 | bool trigger_level2_en; | 102 | u8 max_trigger_level; |
95 | bool trigger_level3_en; | ||
96 | |||
97 | u8 gain; | 103 | u8 gain; |
98 | u8 reference_voltage; | 104 | u8 reference_voltage; |
99 | u8 noise_cancel_mode; | 105 | u8 noise_cancel_mode; |
106 | |||
100 | u32 efuse_value; | 107 | u32 efuse_value; |
108 | u32 min_efuse_value; | ||
109 | u32 max_efuse_value; | ||
110 | u8 first_point_trim; | ||
111 | u8 second_point_trim; | ||
112 | u8 default_temp_offset; | ||
101 | 113 | ||
102 | enum calibration_type cal_type; | 114 | enum calibration_type cal_type; |
115 | enum calibration_mode cal_mode; | ||
103 | enum soc_type type; | 116 | enum soc_type type; |
104 | struct freq_clip_table freq_tab[4]; | 117 | struct freq_clip_table freq_tab[4]; |
105 | unsigned int freq_tab_count; | 118 | unsigned int freq_tab_count; |
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 144ba44cc29c..24934d7c7f05 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c | |||
@@ -30,13 +30,22 @@ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = { | |||
30 | .trigger_levels[0] = 5, | 30 | .trigger_levels[0] = 5, |
31 | .trigger_levels[1] = 20, | 31 | .trigger_levels[1] = 20, |
32 | .trigger_levels[2] = 30, | 32 | .trigger_levels[2] = 30, |
33 | .trigger_level0_en = 1, | 33 | .trigger_enable[0] = true, |
34 | .trigger_level1_en = 1, | 34 | .trigger_enable[1] = true, |
35 | .trigger_level2_en = 1, | 35 | .trigger_enable[2] = true, |
36 | .trigger_level3_en = 0, | 36 | .trigger_enable[3] = false, |
37 | .trigger_type[0] = THROTTLE_ACTIVE, | ||
38 | .trigger_type[1] = THROTTLE_ACTIVE, | ||
39 | .trigger_type[2] = SW_TRIP, | ||
40 | .max_trigger_level = 4, | ||
37 | .gain = 15, | 41 | .gain = 15, |
38 | .reference_voltage = 7, | 42 | .reference_voltage = 7, |
39 | .cal_type = TYPE_ONE_POINT_TRIMMING, | 43 | .cal_type = TYPE_ONE_POINT_TRIMMING, |
44 | .min_efuse_value = 40, | ||
45 | .max_efuse_value = 100, | ||
46 | .first_point_trim = 25, | ||
47 | .second_point_trim = 85, | ||
48 | .default_temp_offset = 50, | ||
40 | .freq_tab[0] = { | 49 | .freq_tab[0] = { |
41 | .freq_clip_max = 800 * 1000, | 50 | .freq_clip_max = 800 * 1000, |
42 | .temp_level = 85, | 51 | .temp_level = 85, |
@@ -56,15 +65,24 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = { | |||
56 | .trigger_levels[0] = 85, | 65 | .trigger_levels[0] = 85, |
57 | .trigger_levels[1] = 103, | 66 | .trigger_levels[1] = 103, |
58 | .trigger_levels[2] = 110, | 67 | .trigger_levels[2] = 110, |
59 | .trigger_level0_en = 1, | 68 | .trigger_enable[0] = true, |
60 | .trigger_level1_en = 1, | 69 | .trigger_enable[1] = true, |
61 | .trigger_level2_en = 1, | 70 | .trigger_enable[2] = true, |
62 | .trigger_level3_en = 0, | 71 | .trigger_enable[3] = false, |
72 | .trigger_type[0] = THROTTLE_ACTIVE, | ||
73 | .trigger_type[1] = THROTTLE_ACTIVE, | ||
74 | .trigger_type[2] = SW_TRIP, | ||
75 | .max_trigger_level = 4, | ||
63 | .gain = 8, | 76 | .gain = 8, |
64 | .reference_voltage = 16, | 77 | .reference_voltage = 16, |
65 | .noise_cancel_mode = 4, | 78 | .noise_cancel_mode = 4, |
66 | .cal_type = TYPE_ONE_POINT_TRIMMING, | 79 | .cal_type = TYPE_ONE_POINT_TRIMMING, |
67 | .efuse_value = 55, | 80 | .efuse_value = 55, |
81 | .min_efuse_value = 40, | ||
82 | .max_efuse_value = 100, | ||
83 | .first_point_trim = 25, | ||
84 | .second_point_trim = 85, | ||
85 | .default_temp_offset = 50, | ||
68 | .freq_tab[0] = { | 86 | .freq_tab[0] = { |
69 | .freq_clip_max = 800 * 1000, | 87 | .freq_clip_max = 800 * 1000, |
70 | .temp_level = 85, | 88 | .temp_level = 85, |