exynos_tmu.c (f33ecec9bb5199c5a4dd296af604f70273d2636e) | exynos_tmu.c (ffe6e16f14faf5af6bae7293ebddb481a1d77ae6) |
---|---|
1/* 2 * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit) 3 * 4 * Copyright (C) 2014 Samsung Electronics 5 * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> 6 * Lukasz Majewski <l.majewski@samsung.com> 7 * 8 * Copyright (C) 2011 Samsung Electronics --- 15 unchanged lines hidden (view full) --- 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 * 26 */ 27 28#include <linux/clk.h> 29#include <linux/io.h> 30#include <linux/interrupt.h> 31#include <linux/module.h> | 1/* 2 * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit) 3 * 4 * Copyright (C) 2014 Samsung Electronics 5 * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> 6 * Lukasz Majewski <l.majewski@samsung.com> 7 * 8 * Copyright (C) 2011 Samsung Electronics --- 15 unchanged lines hidden (view full) --- 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 * 26 */ 27 28#include <linux/clk.h> 29#include <linux/io.h> 30#include <linux/interrupt.h> 31#include <linux/module.h> |
32#include <linux/of.h> | 32#include <linux/of_device.h> |
33#include <linux/of_address.h> 34#include <linux/of_irq.h> 35#include <linux/platform_device.h> 36#include <linux/regulator/consumer.h> 37 | 33#include <linux/of_address.h> 34#include <linux/of_irq.h> 35#include <linux/platform_device.h> 36#include <linux/regulator/consumer.h> 37 |
38#include "exynos_tmu.h" | 38#include <dt-bindings/thermal/thermal_exynos.h> 39 |
39#include "../thermal_core.h" 40 41/* Exynos generic registers */ 42#define EXYNOS_TMU_REG_TRIMINFO 0x0 43#define EXYNOS_TMU_REG_CONTROL 0x20 44#define EXYNOS_TMU_REG_STATUS 0x28 45#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 46#define EXYNOS_TMU_REG_INTEN 0x70 --- 23 unchanged lines hidden (view full) --- 70#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 71#define EXYNOS_TRIMINFO_25_SHIFT 0 72#define EXYNOS_TRIMINFO_85_SHIFT 8 73#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 74#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 75#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 76 77#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 | 40#include "../thermal_core.h" 41 42/* Exynos generic registers */ 43#define EXYNOS_TMU_REG_TRIMINFO 0x0 44#define EXYNOS_TMU_REG_CONTROL 0x20 45#define EXYNOS_TMU_REG_STATUS 0x28 46#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 47#define EXYNOS_TMU_REG_INTEN 0x70 --- 23 unchanged lines hidden (view full) --- 71#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 72#define EXYNOS_TRIMINFO_25_SHIFT 0 73#define EXYNOS_TRIMINFO_85_SHIFT 8 74#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 75#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 76#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 77 78#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 |
78#define EXYNOS_TMU_INTEN_RISE1_SHIFT 4 79#define EXYNOS_TMU_INTEN_RISE2_SHIFT 8 80#define EXYNOS_TMU_INTEN_RISE3_SHIFT 12 | |
81#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 82 83#define EXYNOS_EMUL_TIME 0x57F0 84#define EXYNOS_EMUL_TIME_MASK 0xffff 85#define EXYNOS_EMUL_TIME_SHIFT 16 86#define EXYNOS_EMUL_DATA_SHIFT 8 87#define EXYNOS_EMUL_DATA_MASK 0xFF 88#define EXYNOS_EMUL_ENABLE 0x1 --- 4 unchanged lines hidden (view full) --- 93#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 94#define EXYNOS5260_EMUL_CON 0x100 95 96/* Exynos4412 specific */ 97#define EXYNOS4412_MUX_ADDR_VALUE 6 98#define EXYNOS4412_MUX_ADDR_SHIFT 20 99 100/* Exynos5433 specific registers */ | 79#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 80 81#define EXYNOS_EMUL_TIME 0x57F0 82#define EXYNOS_EMUL_TIME_MASK 0xffff 83#define EXYNOS_EMUL_TIME_SHIFT 16 84#define EXYNOS_EMUL_DATA_SHIFT 8 85#define EXYNOS_EMUL_DATA_MASK 0xFF 86#define EXYNOS_EMUL_ENABLE 0x1 --- 4 unchanged lines hidden (view full) --- 91#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 92#define EXYNOS5260_EMUL_CON 0x100 93 94/* Exynos4412 specific */ 95#define EXYNOS4412_MUX_ADDR_VALUE 6 96#define EXYNOS4412_MUX_ADDR_SHIFT 20 97 98/* Exynos5433 specific registers */ |
101#define EXYNOS5433_TMU_REG_CONTROL1 0x024 102#define EXYNOS5433_TMU_SAMPLING_INTERVAL 0x02c 103#define EXYNOS5433_TMU_COUNTER_VALUE0 0x030 104#define EXYNOS5433_TMU_COUNTER_VALUE1 0x034 105#define EXYNOS5433_TMU_REG_CURRENT_TEMP1 0x044 | |
106#define EXYNOS5433_THD_TEMP_RISE3_0 0x050 107#define EXYNOS5433_THD_TEMP_RISE7_4 0x054 108#define EXYNOS5433_THD_TEMP_FALL3_0 0x060 109#define EXYNOS5433_THD_TEMP_FALL7_4 0x064 110#define EXYNOS5433_TMU_REG_INTEN 0x0c0 111#define EXYNOS5433_TMU_REG_INTPEND 0x0c8 112#define EXYNOS5433_TMU_EMUL_CON 0x110 113#define EXYNOS5433_TMU_PD_DET_EN 0x130 --- 4 unchanged lines hidden (view full) --- 118 (0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT) 119#define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK BIT(23) 120 121#define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING 0 122#define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING 1 123 124#define EXYNOS5433_PD_DET_EN 1 125 | 99#define EXYNOS5433_THD_TEMP_RISE3_0 0x050 100#define EXYNOS5433_THD_TEMP_RISE7_4 0x054 101#define EXYNOS5433_THD_TEMP_FALL3_0 0x060 102#define EXYNOS5433_THD_TEMP_FALL7_4 0x064 103#define EXYNOS5433_TMU_REG_INTEN 0x0c0 104#define EXYNOS5433_TMU_REG_INTPEND 0x0c8 105#define EXYNOS5433_TMU_EMUL_CON 0x110 106#define EXYNOS5433_TMU_PD_DET_EN 0x130 --- 4 unchanged lines hidden (view full) --- 111 (0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT) 112#define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK BIT(23) 113 114#define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING 0 115#define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING 1 116 117#define EXYNOS5433_PD_DET_EN 1 118 |
126/*exynos5440 specific registers*/ 127#define EXYNOS5440_TMU_S0_7_TRIM 0x000 128#define EXYNOS5440_TMU_S0_7_CTRL 0x020 129#define EXYNOS5440_TMU_S0_7_DEBUG 0x040 130#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 131#define EXYNOS5440_TMU_S0_7_TH0 0x110 132#define EXYNOS5440_TMU_S0_7_TH1 0x130 133#define EXYNOS5440_TMU_S0_7_TH2 0x150 134#define EXYNOS5440_TMU_S0_7_IRQEN 0x210 135#define EXYNOS5440_TMU_S0_7_IRQ 0x230 136/* exynos5440 common registers */ 137#define EXYNOS5440_TMU_IRQ_STATUS 0x000 138#define EXYNOS5440_TMU_PMIN 0x004 | 119#define EXYNOS5433_G3D_BASE 0x10070000 |
139 | 120 |
140#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 141#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 142#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2 143#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3 144#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4 145#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 146#define EXYNOS5440_EFUSE_SWAP_OFFSET 8 147 | |
148/* Exynos7 specific registers */ 149#define EXYNOS7_THD_TEMP_RISE7_6 0x50 150#define EXYNOS7_THD_TEMP_FALL7_6 0x60 151#define EXYNOS7_TMU_REG_INTEN 0x110 152#define EXYNOS7_TMU_REG_INTPEND 0x118 153#define EXYNOS7_TMU_REG_EMUL_CON 0x160 154 155#define EXYNOS7_TMU_TEMP_MASK 0x1ff 156#define EXYNOS7_PD_DET_EN_SHIFT 23 157#define EXYNOS7_TMU_INTEN_RISE0_SHIFT 0 | 121/* Exynos7 specific registers */ 122#define EXYNOS7_THD_TEMP_RISE7_6 0x50 123#define EXYNOS7_THD_TEMP_FALL7_6 0x60 124#define EXYNOS7_TMU_REG_INTEN 0x110 125#define EXYNOS7_TMU_REG_INTPEND 0x118 126#define EXYNOS7_TMU_REG_EMUL_CON 0x160 127 128#define EXYNOS7_TMU_TEMP_MASK 0x1ff 129#define EXYNOS7_PD_DET_EN_SHIFT 23 130#define EXYNOS7_TMU_INTEN_RISE0_SHIFT 0 |
158#define EXYNOS7_TMU_INTEN_RISE1_SHIFT 1 159#define EXYNOS7_TMU_INTEN_RISE2_SHIFT 2 160#define EXYNOS7_TMU_INTEN_RISE3_SHIFT 3 161#define EXYNOS7_TMU_INTEN_RISE4_SHIFT 4 162#define EXYNOS7_TMU_INTEN_RISE5_SHIFT 5 163#define EXYNOS7_TMU_INTEN_RISE6_SHIFT 6 164#define EXYNOS7_TMU_INTEN_RISE7_SHIFT 7 | |
165#define EXYNOS7_EMUL_DATA_SHIFT 7 166#define EXYNOS7_EMUL_DATA_MASK 0x1ff 167 | 131#define EXYNOS7_EMUL_DATA_SHIFT 7 132#define EXYNOS7_EMUL_DATA_MASK 0x1ff 133 |
134#define EXYNOS_FIRST_POINT_TRIM 25 135#define EXYNOS_SECOND_POINT_TRIM 85 136 137#define EXYNOS_NOISE_CANCEL_MODE 4 138 |
|
168#define MCELSIUS 1000 | 139#define MCELSIUS 1000 |
140 141enum soc_type { 142 SOC_ARCH_EXYNOS3250 = 1, 143 SOC_ARCH_EXYNOS4210, 144 SOC_ARCH_EXYNOS4412, 145 SOC_ARCH_EXYNOS5250, 146 SOC_ARCH_EXYNOS5260, 147 SOC_ARCH_EXYNOS5420, 148 SOC_ARCH_EXYNOS5420_TRIMINFO, 149 SOC_ARCH_EXYNOS5433, 150 SOC_ARCH_EXYNOS7, 151}; 152 |
|
169/** 170 * struct exynos_tmu_data : A structure to hold the private data of the TMU 171 driver 172 * @id: identifier of the one instance of the TMU controller. | 153/** 154 * struct exynos_tmu_data : A structure to hold the private data of the TMU 155 driver 156 * @id: identifier of the one instance of the TMU controller. |
173 * @pdata: pointer to the tmu platform/configuration data | |
174 * @base: base address of the single instance of the TMU controller. 175 * @base_second: base address of the common registers of the TMU controller. 176 * @irq: irq number of the TMU controller. 177 * @soc: id of the SOC type. 178 * @irq_work: pointer to the irq work structure. 179 * @lock: lock to implement synchronization. 180 * @clk: pointer to the clock structure. 181 * @clk_sec: pointer to the clock structure for accessing the base_second. 182 * @sclk: pointer to the clock structure for accessing the tmu special clk. | 157 * @base: base address of the single instance of the TMU controller. 158 * @base_second: base address of the common registers of the TMU controller. 159 * @irq: irq number of the TMU controller. 160 * @soc: id of the SOC type. 161 * @irq_work: pointer to the irq work structure. 162 * @lock: lock to implement synchronization. 163 * @clk: pointer to the clock structure. 164 * @clk_sec: pointer to the clock structure for accessing the base_second. 165 * @sclk: pointer to the clock structure for accessing the tmu special clk. |
166 * @cal_type: calibration type for temperature 167 * @efuse_value: SoC defined fuse value 168 * @min_efuse_value: minimum valid trimming data 169 * @max_efuse_value: maximum valid trimming data |
|
183 * @temp_error1: fused value of the first point trim. 184 * @temp_error2: fused value of the second point trim. | 170 * @temp_error1: fused value of the first point trim. 171 * @temp_error2: fused value of the second point trim. |
172 * @gain: gain of amplifier in the positive-TC generator block 173 * 0 < gain <= 15 174 * @reference_voltage: reference voltage of amplifier 175 * in the positive-TC generator block 176 * 0 < reference_voltage <= 31 |
|
185 * @regulator: pointer to the TMU regulator structure. 186 * @reg_conf: pointer to structure to register with core thermal. 187 * @ntrip: number of supported trip points. 188 * @enabled: current status of TMU device 189 * @tmu_initialize: SoC specific TMU initialization method 190 * @tmu_control: SoC specific TMU control method 191 * @tmu_read: SoC specific TMU temperature read method 192 * @tmu_set_emulation: SoC specific TMU emulation setting method 193 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method 194 */ 195struct exynos_tmu_data { 196 int id; | 177 * @regulator: pointer to the TMU regulator structure. 178 * @reg_conf: pointer to structure to register with core thermal. 179 * @ntrip: number of supported trip points. 180 * @enabled: current status of TMU device 181 * @tmu_initialize: SoC specific TMU initialization method 182 * @tmu_control: SoC specific TMU control method 183 * @tmu_read: SoC specific TMU temperature read method 184 * @tmu_set_emulation: SoC specific TMU emulation setting method 185 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method 186 */ 187struct exynos_tmu_data { 188 int id; |
197 struct exynos_tmu_platform_data *pdata; | |
198 void __iomem *base; 199 void __iomem *base_second; 200 int irq; 201 enum soc_type soc; 202 struct work_struct irq_work; 203 struct mutex lock; 204 struct clk *clk, *clk_sec, *sclk; | 189 void __iomem *base; 190 void __iomem *base_second; 191 int irq; 192 enum soc_type soc; 193 struct work_struct irq_work; 194 struct mutex lock; 195 struct clk *clk, *clk_sec, *sclk; |
196 u32 cal_type; 197 u32 efuse_value; 198 u32 min_efuse_value; 199 u32 max_efuse_value; |
|
205 u16 temp_error1, temp_error2; | 200 u16 temp_error1, temp_error2; |
201 u8 gain; 202 u8 reference_voltage; |
|
206 struct regulator *regulator; 207 struct thermal_zone_device *tzd; 208 unsigned int ntrip; 209 bool enabled; 210 | 203 struct regulator *regulator; 204 struct thermal_zone_device *tzd; 205 unsigned int ntrip; 206 bool enabled; 207 |
211 int (*tmu_initialize)(struct platform_device *pdev); | 208 void (*tmu_set_trip_temp)(struct exynos_tmu_data *data, int trip, 209 u8 temp); 210 void (*tmu_set_trip_hyst)(struct exynos_tmu_data *data, int trip, 211 u8 temp, u8 hyst); 212 void (*tmu_initialize)(struct platform_device *pdev); |
212 void (*tmu_control)(struct platform_device *pdev, bool on); 213 int (*tmu_read)(struct exynos_tmu_data *data); 214 void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp); 215 void (*tmu_clear_irqs)(struct exynos_tmu_data *data); 216}; 217 | 213 void (*tmu_control)(struct platform_device *pdev, bool on); 214 int (*tmu_read)(struct exynos_tmu_data *data); 215 void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp); 216 void (*tmu_clear_irqs)(struct exynos_tmu_data *data); 217}; 218 |
218static void exynos_report_trigger(struct exynos_tmu_data *p) 219{ 220 char data[10], *envp[] = { data, NULL }; 221 struct thermal_zone_device *tz = p->tzd; 222 int temp; 223 unsigned int i; 224 225 if (!tz) { 226 pr_err("No thermal zone device defined\n"); 227 return; 228 } 229 230 thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); 231 232 mutex_lock(&tz->lock); 233 /* Find the level for which trip happened */ 234 for (i = 0; i < of_thermal_get_ntrips(tz); i++) { 235 tz->ops->get_trip_temp(tz, i, &temp); 236 if (tz->last_temperature < temp) 237 break; 238 } 239 240 snprintf(data, sizeof(data), "%u", i); 241 kobject_uevent_env(&tz->device.kobj, KOBJ_CHANGE, envp); 242 mutex_unlock(&tz->lock); 243} 244 | |
245/* 246 * TMU treats temperature as a mapped temperature code. 247 * The temperature is converted differently depending on the calibration type. 248 */ 249static int temp_to_code(struct exynos_tmu_data *data, u8 temp) 250{ | 219/* 220 * TMU treats temperature as a mapped temperature code. 221 * The temperature is converted differently depending on the calibration type. 222 */ 223static int temp_to_code(struct exynos_tmu_data *data, u8 temp) 224{ |
251 struct exynos_tmu_platform_data *pdata = data->pdata; 252 int temp_code; | 225 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) 226 return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM; |
253 | 227 |
254 switch (pdata->cal_type) { 255 case TYPE_TWO_POINT_TRIMMING: 256 temp_code = (temp - pdata->first_point_trim) * 257 (data->temp_error2 - data->temp_error1) / 258 (pdata->second_point_trim - pdata->first_point_trim) + 259 data->temp_error1; 260 break; 261 case TYPE_ONE_POINT_TRIMMING: 262 temp_code = temp + data->temp_error1 - pdata->first_point_trim; 263 break; 264 default: 265 temp_code = temp + pdata->default_temp_offset; 266 break; 267 } 268 269 return temp_code; | 228 return (temp - EXYNOS_FIRST_POINT_TRIM) * 229 (data->temp_error2 - data->temp_error1) / 230 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) + 231 data->temp_error1; |
270} 271 272/* 273 * Calculate a temperature value from a temperature code. 274 * The unit of the temperature is degree Celsius. 275 */ 276static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code) 277{ | 232} 233 234/* 235 * Calculate a temperature value from a temperature code. 236 * The unit of the temperature is degree Celsius. 237 */ 238static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code) 239{ |
278 struct exynos_tmu_platform_data *pdata = data->pdata; 279 int temp; | 240 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) 241 return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM; |
280 | 242 |
281 switch (pdata->cal_type) { 282 case TYPE_TWO_POINT_TRIMMING: 283 temp = (temp_code - data->temp_error1) * 284 (pdata->second_point_trim - pdata->first_point_trim) / 285 (data->temp_error2 - data->temp_error1) + 286 pdata->first_point_trim; 287 break; 288 case TYPE_ONE_POINT_TRIMMING: 289 temp = temp_code - data->temp_error1 + pdata->first_point_trim; 290 break; 291 default: 292 temp = temp_code - pdata->default_temp_offset; 293 break; 294 } 295 296 return temp; | 243 return (temp_code - data->temp_error1) * 244 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) / 245 (data->temp_error2 - data->temp_error1) + 246 EXYNOS_FIRST_POINT_TRIM; |
297} 298 299static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) 300{ | 247} 248 249static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) 250{ |
301 struct exynos_tmu_platform_data *pdata = data->pdata; | 251 u16 tmu_temp_mask = 252 (data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK 253 : EXYNOS_TMU_TEMP_MASK; |
302 | 254 |
303 data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; | 255 data->temp_error1 = trim_info & tmu_temp_mask; |
304 data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & 305 EXYNOS_TMU_TEMP_MASK); 306 307 if (!data->temp_error1 || | 256 data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & 257 EXYNOS_TMU_TEMP_MASK); 258 259 if (!data->temp_error1 || |
308 (pdata->min_efuse_value > data->temp_error1) || 309 (data->temp_error1 > pdata->max_efuse_value)) 310 data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK; | 260 (data->min_efuse_value > data->temp_error1) || 261 (data->temp_error1 > data->max_efuse_value)) 262 data->temp_error1 = data->efuse_value & EXYNOS_TMU_TEMP_MASK; |
311 312 if (!data->temp_error2) 313 data->temp_error2 = | 263 264 if (!data->temp_error2) 265 data->temp_error2 = |
314 (pdata->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & | 266 (data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & |
315 EXYNOS_TMU_TEMP_MASK; 316} 317 | 267 EXYNOS_TMU_TEMP_MASK; 268} 269 |
318static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling) | 270static int exynos_tmu_initialize(struct platform_device *pdev) |
319{ | 271{ |
320 struct thermal_zone_device *tz = data->tzd; | 272 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 273 struct thermal_zone_device *tzd = data->tzd; |
321 const struct thermal_trip * const trips = | 274 const struct thermal_trip * const trips = |
322 of_thermal_get_trip_points(tz); 323 unsigned long temp; 324 int i; | 275 of_thermal_get_trip_points(tzd); 276 unsigned int status; 277 int ret = 0, temp, hyst; |
325 326 if (!trips) { | 278 279 if (!trips) { |
327 pr_err("%s: Cannot get trip points from of-thermal.c!\n", 328 __func__); 329 return 0; | 280 dev_err(&pdev->dev, 281 "Cannot get trip points from device tree!\n"); 282 return -ENODEV; |
330 } 331 | 283 } 284 |
332 for (i = 0; i < of_thermal_get_ntrips(tz); i++) { 333 if (trips[i].type == THERMAL_TRIP_CRITICAL) 334 continue; 335 336 temp = trips[i].temperature / MCELSIUS; 337 if (falling) 338 temp -= (trips[i].hysteresis / MCELSIUS); 339 else 340 threshold &= ~(0xff << 8 * i); 341 342 threshold |= temp_to_code(data, temp) << 8 * i; | 285 if (data->soc != SOC_ARCH_EXYNOS5433) /* FIXME */ 286 ret = tzd->ops->get_crit_temp(tzd, &temp); 287 if (ret) { 288 dev_err(&pdev->dev, 289 "No CRITICAL trip point defined in device tree!\n"); 290 goto out; |
343 } 344 | 291 } 292 |
345 return threshold; 346} 347 348static int exynos_tmu_initialize(struct platform_device *pdev) 349{ 350 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 351 int ret; 352 353 if (of_thermal_get_ntrips(data->tzd) > data->ntrip) { | 293 if (of_thermal_get_ntrips(tzd) > data->ntrip) { |
354 dev_info(&pdev->dev, 355 "More trip points than supported by this TMU.\n"); 356 dev_info(&pdev->dev, 357 "%d trip points should be configured in polling mode.\n", | 294 dev_info(&pdev->dev, 295 "More trip points than supported by this TMU.\n"); 296 dev_info(&pdev->dev, 297 "%d trip points should be configured in polling mode.\n", |
358 (of_thermal_get_ntrips(data->tzd) - data->ntrip)); | 298 (of_thermal_get_ntrips(tzd) - data->ntrip)); |
359 } 360 361 mutex_lock(&data->lock); 362 clk_enable(data->clk); 363 if (!IS_ERR(data->clk_sec)) 364 clk_enable(data->clk_sec); | 299 } 300 301 mutex_lock(&data->lock); 302 clk_enable(data->clk); 303 if (!IS_ERR(data->clk_sec)) 304 clk_enable(data->clk_sec); |
365 ret = data->tmu_initialize(pdev); | 305 306 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 307 if (!status) { 308 ret = -EBUSY; 309 } else { 310 int i, ntrips = 311 min_t(int, of_thermal_get_ntrips(tzd), data->ntrip); 312 313 data->tmu_initialize(pdev); 314 315 /* Write temperature code for rising and falling threshold */ 316 for (i = 0; i < ntrips; i++) { 317 /* Write temperature code for rising threshold */ 318 ret = tzd->ops->get_trip_temp(tzd, i, &temp); 319 if (ret) 320 goto err; 321 temp /= MCELSIUS; 322 data->tmu_set_trip_temp(data, i, temp); 323 324 /* Write temperature code for falling threshold */ 325 ret = tzd->ops->get_trip_hyst(tzd, i, &hyst); 326 if (ret) 327 goto err; 328 hyst /= MCELSIUS; 329 data->tmu_set_trip_hyst(data, i, temp, hyst); 330 } 331 332 data->tmu_clear_irqs(data); 333 } 334err: |
366 clk_disable(data->clk); 367 mutex_unlock(&data->lock); 368 if (!IS_ERR(data->clk_sec)) 369 clk_disable(data->clk_sec); | 335 clk_disable(data->clk); 336 mutex_unlock(&data->lock); 337 if (!IS_ERR(data->clk_sec)) 338 clk_disable(data->clk_sec); |
370 | 339out: |
371 return ret; 372} 373 374static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) 375{ | 340 return ret; 341} 342 343static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) 344{ |
376 struct exynos_tmu_platform_data *pdata = data->pdata; 377 | |
378 if (data->soc == SOC_ARCH_EXYNOS4412 || 379 data->soc == SOC_ARCH_EXYNOS3250) 380 con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT); 381 382 con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); | 345 if (data->soc == SOC_ARCH_EXYNOS4412 || 346 data->soc == SOC_ARCH_EXYNOS3250) 347 con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT); 348 349 con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); |
383 con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; | 350 con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; |
384 385 con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); | 351 352 con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); |
386 con |= (pdata->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); | 353 con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); |
387 | 354 |
388 if (pdata->noise_cancel_mode) { 389 con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT); 390 con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT); 391 } | 355 con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT); 356 con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT); |
392 393 return con; 394} 395 396static void exynos_tmu_control(struct platform_device *pdev, bool on) 397{ 398 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 399 400 mutex_lock(&data->lock); 401 clk_enable(data->clk); 402 data->tmu_control(pdev, on); 403 data->enabled = on; 404 clk_disable(data->clk); 405 mutex_unlock(&data->lock); 406} 407 | 357 358 return con; 359} 360 361static void exynos_tmu_control(struct platform_device *pdev, bool on) 362{ 363 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 364 365 mutex_lock(&data->lock); 366 clk_enable(data->clk); 367 data->tmu_control(pdev, on); 368 data->enabled = on; 369 clk_disable(data->clk); 370 mutex_unlock(&data->lock); 371} 372 |
408static int exynos4210_tmu_initialize(struct platform_device *pdev) | 373static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data, 374 int trip, u8 temp) |
409{ | 375{ |
410 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 411 struct thermal_zone_device *tz = data->tzd; | |
412 const struct thermal_trip * const trips = | 376 const struct thermal_trip * const trips = |
413 of_thermal_get_trip_points(tz); 414 int ret = 0, threshold_code, i; 415 unsigned long reference, temp; 416 unsigned int status; | 377 of_thermal_get_trip_points(data->tzd); 378 u8 ref, th_code; |
417 | 379 |
418 if (!trips) { 419 pr_err("%s: Cannot get trip points from of-thermal.c!\n", 420 __func__); 421 ret = -ENODEV; 422 goto out; 423 } | 380 ref = trips[0].temperature / MCELSIUS; |
424 | 381 |
425 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 426 if (!status) { 427 ret = -EBUSY; 428 goto out; | 382 if (trip == 0) { 383 th_code = temp_to_code(data, ref); 384 writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); |
429 } 430 | 385 } 386 |
387 temp -= ref; 388 writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip * 4); 389} 390 391/* failing thresholds are not supported on Exynos4210 */ 392static void exynos4210_tmu_set_trip_hyst(struct exynos_tmu_data *data, 393 int trip, u8 temp, u8 hyst) 394{ 395} 396 397static void exynos4210_tmu_initialize(struct platform_device *pdev) 398{ 399 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 400 |
|
431 sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO)); | 401 sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO)); |
402} |
|
432 | 403 |
433 /* Write temperature code for threshold */ 434 reference = trips[0].temperature / MCELSIUS; 435 threshold_code = temp_to_code(data, reference); 436 if (threshold_code < 0) { 437 ret = threshold_code; 438 goto out; 439 } 440 writeb(threshold_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); | 404static void exynos4412_tmu_set_trip_temp(struct exynos_tmu_data *data, 405 int trip, u8 temp) 406{ 407 u32 th, con; |
441 | 408 |
442 for (i = 0; i < of_thermal_get_ntrips(tz); i++) { 443 temp = trips[i].temperature / MCELSIUS; 444 writeb(temp - reference, data->base + 445 EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); | 409 th = readl(data->base + EXYNOS_THD_TEMP_RISE); 410 th &= ~(0xff << 8 * trip); 411 th |= temp_to_code(data, temp) << 8 * trip; 412 writel(th, data->base + EXYNOS_THD_TEMP_RISE); 413 414 if (trip == 3) { 415 con = readl(data->base + EXYNOS_TMU_REG_CONTROL); 416 con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); 417 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); |
446 } | 418 } |
419} |
|
447 | 420 |
448 data->tmu_clear_irqs(data); 449out: 450 return ret; | 421static void exynos4412_tmu_set_trip_hyst(struct exynos_tmu_data *data, 422 int trip, u8 temp, u8 hyst) 423{ 424 u32 th; 425 426 th = readl(data->base + EXYNOS_THD_TEMP_FALL); 427 th &= ~(0xff << 8 * trip); 428 if (hyst) 429 th |= temp_to_code(data, temp - hyst) << 8 * trip; 430 writel(th, data->base + EXYNOS_THD_TEMP_FALL); |
451} 452 | 431} 432 |
453static int exynos4412_tmu_initialize(struct platform_device *pdev) | 433static void exynos4412_tmu_initialize(struct platform_device *pdev) |
454{ 455 struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 434{ 435 struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
456 const struct thermal_trip * const trips = 457 of_thermal_get_trip_points(data->tzd); 458 unsigned int status, trim_info, con, ctrl, rising_threshold; 459 int ret = 0, threshold_code, i; 460 unsigned long crit_temp = 0; | 436 unsigned int trim_info, ctrl; |
461 | 437 |
462 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 463 if (!status) { 464 ret = -EBUSY; 465 goto out; 466 } 467 | |
468 if (data->soc == SOC_ARCH_EXYNOS3250 || 469 data->soc == SOC_ARCH_EXYNOS4412 || 470 data->soc == SOC_ARCH_EXYNOS5250) { 471 if (data->soc == SOC_ARCH_EXYNOS3250) { 472 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); 473 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; 474 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); 475 } --- 4 unchanged lines hidden (view full) --- 480 481 /* On exynos5420 the triminfo register is in the shared space */ 482 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) 483 trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO); 484 else 485 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); 486 487 sanitize_temp_error(data, trim_info); | 438 if (data->soc == SOC_ARCH_EXYNOS3250 || 439 data->soc == SOC_ARCH_EXYNOS4412 || 440 data->soc == SOC_ARCH_EXYNOS5250) { 441 if (data->soc == SOC_ARCH_EXYNOS3250) { 442 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); 443 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; 444 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); 445 } --- 4 unchanged lines hidden (view full) --- 450 451 /* On exynos5420 the triminfo register is in the shared space */ 452 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) 453 trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO); 454 else 455 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); 456 457 sanitize_temp_error(data, trim_info); |
458} |
|
488 | 459 |
489 /* Write temperature code for rising and falling threshold */ 490 rising_threshold = readl(data->base + EXYNOS_THD_TEMP_RISE); 491 rising_threshold = get_th_reg(data, rising_threshold, false); 492 writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); 493 writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL); | 460static void exynos5433_tmu_set_trip_temp(struct exynos_tmu_data *data, 461 int trip, u8 temp) 462{ 463 unsigned int reg_off, j; 464 u32 th; |
494 | 465 |
495 data->tmu_clear_irqs(data); 496 497 /* if last threshold limit is also present */ 498 for (i = 0; i < of_thermal_get_ntrips(data->tzd); i++) { 499 if (trips[i].type == THERMAL_TRIP_CRITICAL) { 500 crit_temp = trips[i].temperature; 501 break; 502 } | 466 if (trip > 3) { 467 reg_off = EXYNOS5433_THD_TEMP_RISE7_4; 468 j = trip - 4; 469 } else { 470 reg_off = EXYNOS5433_THD_TEMP_RISE3_0; 471 j = trip; |
503 } 504 | 472 } 473 |
505 if (i == of_thermal_get_ntrips(data->tzd)) { 506 pr_err("%s: No CRITICAL trip point defined at of-thermal.c!\n", 507 __func__); 508 ret = -EINVAL; 509 goto out; 510 } | 474 th = readl(data->base + reg_off); 475 th &= ~(0xff << j * 8); 476 th |= (temp_to_code(data, temp) << j * 8); 477 writel(th, data->base + reg_off); 478} |
511 | 479 |
512 threshold_code = temp_to_code(data, crit_temp / MCELSIUS); 513 /* 1-4 level to be assigned in th0 reg */ 514 rising_threshold &= ~(0xff << 8 * i); 515 rising_threshold |= threshold_code << 8 * i; 516 writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); 517 con = readl(data->base + EXYNOS_TMU_REG_CONTROL); 518 con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); 519 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); | 480static void exynos5433_tmu_set_trip_hyst(struct exynos_tmu_data *data, 481 int trip, u8 temp, u8 hyst) 482{ 483 unsigned int reg_off, j; 484 u32 th; |
520 | 485 |
521out: 522 return ret; | 486 if (trip > 3) { 487 reg_off = EXYNOS5433_THD_TEMP_FALL7_4; 488 j = trip - 4; 489 } else { 490 reg_off = EXYNOS5433_THD_TEMP_FALL3_0; 491 j = trip; 492 } 493 494 th = readl(data->base + reg_off); 495 th &= ~(0xff << j * 8); 496 th |= (temp_to_code(data, temp - hyst) << j * 8); 497 writel(th, data->base + reg_off); |
523} 524 | 498} 499 |
525static int exynos5433_tmu_initialize(struct platform_device *pdev) | 500static void exynos5433_tmu_initialize(struct platform_device *pdev) |
526{ 527 struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 501{ 502 struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
528 struct exynos_tmu_platform_data *pdata = data->pdata; 529 struct thermal_zone_device *tz = data->tzd; 530 unsigned int status, trim_info; 531 unsigned int rising_threshold = 0, falling_threshold = 0; 532 int temp, temp_hist; 533 int ret = 0, threshold_code, i, sensor_id, cal_type; | 503 unsigned int trim_info; 504 int sensor_id, cal_type; |
534 | 505 |
535 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 536 if (!status) { 537 ret = -EBUSY; 538 goto out; 539 } 540 | |
541 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); 542 sanitize_temp_error(data, trim_info); 543 544 /* Read the temperature sensor id */ 545 sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK) 546 >> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT; 547 dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id); 548 549 /* Read the calibration mode */ 550 writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO); 551 cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK) 552 >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; 553 554 switch (cal_type) { | 506 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); 507 sanitize_temp_error(data, trim_info); 508 509 /* Read the temperature sensor id */ 510 sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK) 511 >> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT; 512 dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id); 513 514 /* Read the calibration mode */ 515 writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO); 516 cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK) 517 >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; 518 519 switch (cal_type) { |
555 case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING: 556 pdata->cal_type = TYPE_ONE_POINT_TRIMMING; 557 break; | |
558 case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING: | 520 case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING: |
559 pdata->cal_type = TYPE_TWO_POINT_TRIMMING; | 521 data->cal_type = TYPE_TWO_POINT_TRIMMING; |
560 break; | 522 break; |
523 case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING: |
|
561 default: | 524 default: |
562 pdata->cal_type = TYPE_ONE_POINT_TRIMMING; | 525 data->cal_type = TYPE_ONE_POINT_TRIMMING; |
563 break; 564 } 565 566 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", 567 cal_type ? 2 : 1); | 526 break; 527 } 528 529 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", 530 cal_type ? 2 : 1); |
531} |
|
568 | 532 |
569 /* Write temperature code for rising and falling threshold */ 570 for (i = 0; i < of_thermal_get_ntrips(tz); i++) { 571 int rising_reg_offset, falling_reg_offset; 572 int j = 0; | 533static void exynos7_tmu_set_trip_temp(struct exynos_tmu_data *data, 534 int trip, u8 temp) 535{ 536 unsigned int reg_off, bit_off; 537 u32 th; |
573 | 538 |
574 switch (i) { 575 case 0: 576 case 1: 577 case 2: 578 case 3: 579 rising_reg_offset = EXYNOS5433_THD_TEMP_RISE3_0; 580 falling_reg_offset = EXYNOS5433_THD_TEMP_FALL3_0; 581 j = i; 582 break; 583 case 4: 584 case 5: 585 case 6: 586 case 7: 587 rising_reg_offset = EXYNOS5433_THD_TEMP_RISE7_4; 588 falling_reg_offset = EXYNOS5433_THD_TEMP_FALL7_4; 589 j = i - 4; 590 break; 591 default: 592 continue; 593 } | 539 reg_off = ((7 - trip) / 2) * 4; 540 bit_off = ((8 - trip) % 2); |
594 | 541 |
595 /* Write temperature code for rising threshold */ 596 tz->ops->get_trip_temp(tz, i, &temp); 597 temp /= MCELSIUS; 598 threshold_code = temp_to_code(data, temp); 599 600 rising_threshold = readl(data->base + rising_reg_offset); 601 rising_threshold |= (threshold_code << j * 8); 602 writel(rising_threshold, data->base + rising_reg_offset); 603 604 /* Write temperature code for falling threshold */ 605 tz->ops->get_trip_hyst(tz, i, &temp_hist); 606 temp_hist = temp - (temp_hist / MCELSIUS); 607 threshold_code = temp_to_code(data, temp_hist); 608 609 falling_threshold = readl(data->base + falling_reg_offset); 610 falling_threshold &= ~(0xff << j * 8); 611 falling_threshold |= (threshold_code << j * 8); 612 writel(falling_threshold, data->base + falling_reg_offset); 613 } 614 615 data->tmu_clear_irqs(data); 616out: 617 return ret; | 542 th = readl(data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off); 543 th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off)); 544 th |= temp_to_code(data, temp) << (16 * bit_off); 545 writel(th, data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off); |
618} 619 | 546} 547 |
620static int exynos5440_tmu_initialize(struct platform_device *pdev) | 548static void exynos7_tmu_set_trip_hyst(struct exynos_tmu_data *data, 549 int trip, u8 temp, u8 hyst) |
621{ | 550{ |
622 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 623 unsigned int trim_info = 0, con, rising_threshold; 624 int threshold_code; 625 int crit_temp = 0; | 551 unsigned int reg_off, bit_off; 552 u32 th; |
626 | 553 |
627 /* 628 * For exynos5440 soc triminfo value is swapped between TMU0 and 629 * TMU2, so the below logic is needed. 630 */ 631 switch (data->id) { 632 case 0: 633 trim_info = readl(data->base + EXYNOS5440_EFUSE_SWAP_OFFSET + 634 EXYNOS5440_TMU_S0_7_TRIM); 635 break; 636 case 1: 637 trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); 638 break; 639 case 2: 640 trim_info = readl(data->base - EXYNOS5440_EFUSE_SWAP_OFFSET + 641 EXYNOS5440_TMU_S0_7_TRIM); 642 } 643 sanitize_temp_error(data, trim_info); | 554 reg_off = ((7 - trip) / 2) * 4; 555 bit_off = ((8 - trip) % 2); |
644 | 556 |
645 /* Write temperature code for rising and falling threshold */ 646 rising_threshold = readl(data->base + EXYNOS5440_TMU_S0_7_TH0); 647 rising_threshold = get_th_reg(data, rising_threshold, false); 648 writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0); 649 writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1); 650 651 data->tmu_clear_irqs(data); 652 653 /* if last threshold limit is also present */ 654 if (!data->tzd->ops->get_crit_temp(data->tzd, &crit_temp)) { 655 threshold_code = temp_to_code(data, crit_temp / MCELSIUS); 656 /* 5th level to be assigned in th2 reg */ 657 rising_threshold = 658 threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; 659 writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH2); 660 con = readl(data->base + EXYNOS5440_TMU_S0_7_CTRL); 661 con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); 662 writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); 663 } 664 /* Clear the PMIN in the common TMU register */ 665 if (!data->id) 666 writel(0, data->base_second + EXYNOS5440_TMU_PMIN); 667 668 return 0; | 557 th = readl(data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off); 558 th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off)); 559 th |= temp_to_code(data, temp - hyst) << (16 * bit_off); 560 writel(th, data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off); |
669} 670 | 561} 562 |
671static int exynos7_tmu_initialize(struct platform_device *pdev) | 563static void exynos7_tmu_initialize(struct platform_device *pdev) |
672{ 673 struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 564{ 565 struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
674 struct thermal_zone_device *tz = data->tzd; 675 struct exynos_tmu_platform_data *pdata = data->pdata; 676 unsigned int status, trim_info; 677 unsigned int rising_threshold = 0, falling_threshold = 0; 678 int ret = 0, threshold_code, i; 679 int temp, temp_hist; 680 unsigned int reg_off, bit_off; | 566 unsigned int trim_info; |
681 | 567 |
682 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 683 if (!status) { 684 ret = -EBUSY; 685 goto out; 686 } 687 | |
688 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); | 568 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); |
689 690 data->temp_error1 = trim_info & EXYNOS7_TMU_TEMP_MASK; 691 if (!data->temp_error1 || 692 (pdata->min_efuse_value > data->temp_error1) || 693 (data->temp_error1 > pdata->max_efuse_value)) 694 data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK; 695 696 /* Write temperature code for rising and falling threshold */ 697 for (i = (of_thermal_get_ntrips(tz) - 1); i >= 0; i--) { 698 /* 699 * On exynos7 there are 4 rising and 4 falling threshold 700 * registers (0x50-0x5c and 0x60-0x6c respectively). Each 701 * register holds the value of two threshold levels (at bit 702 * offsets 0 and 16). Based on the fact that there are atmost 703 * eight possible trigger levels, calculate the register and 704 * bit offsets where the threshold levels are to be written. 705 * 706 * e.g. EXYNOS7_THD_TEMP_RISE7_6 (0x50) 707 * [24:16] - Threshold level 7 708 * [8:0] - Threshold level 6 709 * e.g. EXYNOS7_THD_TEMP_RISE5_4 (0x54) 710 * [24:16] - Threshold level 5 711 * [8:0] - Threshold level 4 712 * 713 * and similarly for falling thresholds. 714 * 715 * Based on the above, calculate the register and bit offsets 716 * for rising/falling threshold levels and populate them. 717 */ 718 reg_off = ((7 - i) / 2) * 4; 719 bit_off = ((8 - i) % 2); 720 721 tz->ops->get_trip_temp(tz, i, &temp); 722 temp /= MCELSIUS; 723 724 tz->ops->get_trip_hyst(tz, i, &temp_hist); 725 temp_hist = temp - (temp_hist / MCELSIUS); 726 727 /* Set 9-bit temperature code for rising threshold levels */ 728 threshold_code = temp_to_code(data, temp); 729 rising_threshold = readl(data->base + 730 EXYNOS7_THD_TEMP_RISE7_6 + reg_off); 731 rising_threshold &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off)); 732 rising_threshold |= threshold_code << (16 * bit_off); 733 writel(rising_threshold, 734 data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off); 735 736 /* Set 9-bit temperature code for falling threshold levels */ 737 threshold_code = temp_to_code(data, temp_hist); 738 falling_threshold &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off)); 739 falling_threshold |= threshold_code << (16 * bit_off); 740 writel(falling_threshold, 741 data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off); 742 } 743 744 data->tmu_clear_irqs(data); 745out: 746 return ret; | 569 sanitize_temp_error(data, trim_info); |
747} 748 749static void exynos4210_tmu_control(struct platform_device *pdev, bool on) 750{ 751 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 752 struct thermal_zone_device *tz = data->tzd; | 570} 571 572static void exynos4210_tmu_control(struct platform_device *pdev, bool on) 573{ 574 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 575 struct thermal_zone_device *tz = data->tzd; |
753 unsigned int con, interrupt_en; | 576 unsigned int con, interrupt_en = 0, i; |
754 755 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 756 757 if (on) { | 577 578 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 579 580 if (on) { |
758 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 759 interrupt_en = 760 (of_thermal_is_trip_valid(tz, 3) 761 << EXYNOS_TMU_INTEN_RISE3_SHIFT) | 762 (of_thermal_is_trip_valid(tz, 2) 763 << EXYNOS_TMU_INTEN_RISE2_SHIFT) | 764 (of_thermal_is_trip_valid(tz, 1) 765 << EXYNOS_TMU_INTEN_RISE1_SHIFT) | 766 (of_thermal_is_trip_valid(tz, 0) 767 << EXYNOS_TMU_INTEN_RISE0_SHIFT); | 581 for (i = 0; i < data->ntrip; i++) { 582 if (!of_thermal_is_trip_valid(tz, i)) 583 continue; |
768 | 584 |
585 interrupt_en |= 586 (1 << (EXYNOS_TMU_INTEN_RISE0_SHIFT + i * 4)); 587 } 588 |
|
769 if (data->soc != SOC_ARCH_EXYNOS4210) 770 interrupt_en |= 771 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; | 589 if (data->soc != SOC_ARCH_EXYNOS4210) 590 interrupt_en |= 591 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; |
592 593 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); |
|
772 } else { 773 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); | 594 } else { 595 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); |
774 interrupt_en = 0; /* Disable all interrupts */ | |
775 } | 596 } |
597 |
|
776 writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN); 777 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 778} 779 780static void exynos5433_tmu_control(struct platform_device *pdev, bool on) 781{ 782 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 783 struct thermal_zone_device *tz = data->tzd; | 598 writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN); 599 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 600} 601 602static void exynos5433_tmu_control(struct platform_device *pdev, bool on) 603{ 604 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 605 struct thermal_zone_device *tz = data->tzd; |
784 unsigned int con, interrupt_en, pd_det_en; | 606 unsigned int con, interrupt_en = 0, pd_det_en, i; |
785 786 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 787 788 if (on) { | 607 608 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 609 610 if (on) { |
789 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 790 interrupt_en = 791 (of_thermal_is_trip_valid(tz, 7) 792 << EXYNOS7_TMU_INTEN_RISE7_SHIFT) | 793 (of_thermal_is_trip_valid(tz, 6) 794 << EXYNOS7_TMU_INTEN_RISE6_SHIFT) | 795 (of_thermal_is_trip_valid(tz, 5) 796 << EXYNOS7_TMU_INTEN_RISE5_SHIFT) | 797 (of_thermal_is_trip_valid(tz, 4) 798 << EXYNOS7_TMU_INTEN_RISE4_SHIFT) | 799 (of_thermal_is_trip_valid(tz, 3) 800 << EXYNOS7_TMU_INTEN_RISE3_SHIFT) | 801 (of_thermal_is_trip_valid(tz, 2) 802 << EXYNOS7_TMU_INTEN_RISE2_SHIFT) | 803 (of_thermal_is_trip_valid(tz, 1) 804 << EXYNOS7_TMU_INTEN_RISE1_SHIFT) | 805 (of_thermal_is_trip_valid(tz, 0) 806 << EXYNOS7_TMU_INTEN_RISE0_SHIFT); | 611 for (i = 0; i < data->ntrip; i++) { 612 if (!of_thermal_is_trip_valid(tz, i)) 613 continue; |
807 | 614 |
615 interrupt_en |= 616 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i)); 617 } 618 |
|
808 interrupt_en |= 809 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; | 619 interrupt_en |= 620 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; |
810 } else { | 621 622 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 623 } else |
811 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); | 624 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); |
812 interrupt_en = 0; /* Disable all interrupts */ 813 } | |
814 815 pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0; 816 817 writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN); 818 writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN); 819 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 820} 821 | 625 626 pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0; 627 628 writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN); 629 writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN); 630 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 631} 632 |
822static void exynos5440_tmu_control(struct platform_device *pdev, bool on) 823{ 824 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 825 struct thermal_zone_device *tz = data->tzd; 826 unsigned int con, interrupt_en; 827 828 con = get_con_reg(data, readl(data->base + EXYNOS5440_TMU_S0_7_CTRL)); 829 830 if (on) { 831 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 832 interrupt_en = 833 (of_thermal_is_trip_valid(tz, 3) 834 << EXYNOS5440_TMU_INTEN_RISE3_SHIFT) | 835 (of_thermal_is_trip_valid(tz, 2) 836 << EXYNOS5440_TMU_INTEN_RISE2_SHIFT) | 837 (of_thermal_is_trip_valid(tz, 1) 838 << EXYNOS5440_TMU_INTEN_RISE1_SHIFT) | 839 (of_thermal_is_trip_valid(tz, 0) 840 << EXYNOS5440_TMU_INTEN_RISE0_SHIFT); 841 interrupt_en |= 842 interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; 843 } else { 844 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); 845 interrupt_en = 0; /* Disable all interrupts */ 846 } 847 writel(interrupt_en, data->base + EXYNOS5440_TMU_S0_7_IRQEN); 848 writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); 849} 850 | |
851static void exynos7_tmu_control(struct platform_device *pdev, bool on) 852{ 853 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 854 struct thermal_zone_device *tz = data->tzd; | 633static void exynos7_tmu_control(struct platform_device *pdev, bool on) 634{ 635 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 636 struct thermal_zone_device *tz = data->tzd; |
855 unsigned int con, interrupt_en; | 637 unsigned int con, interrupt_en = 0, i; |
856 857 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 858 859 if (on) { | 638 639 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); 640 641 if (on) { |
860 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 861 con |= (1 << EXYNOS7_PD_DET_EN_SHIFT); 862 interrupt_en = 863 (of_thermal_is_trip_valid(tz, 7) 864 << EXYNOS7_TMU_INTEN_RISE7_SHIFT) | 865 (of_thermal_is_trip_valid(tz, 6) 866 << EXYNOS7_TMU_INTEN_RISE6_SHIFT) | 867 (of_thermal_is_trip_valid(tz, 5) 868 << EXYNOS7_TMU_INTEN_RISE5_SHIFT) | 869 (of_thermal_is_trip_valid(tz, 4) 870 << EXYNOS7_TMU_INTEN_RISE4_SHIFT) | 871 (of_thermal_is_trip_valid(tz, 3) 872 << EXYNOS7_TMU_INTEN_RISE3_SHIFT) | 873 (of_thermal_is_trip_valid(tz, 2) 874 << EXYNOS7_TMU_INTEN_RISE2_SHIFT) | 875 (of_thermal_is_trip_valid(tz, 1) 876 << EXYNOS7_TMU_INTEN_RISE1_SHIFT) | 877 (of_thermal_is_trip_valid(tz, 0) 878 << EXYNOS7_TMU_INTEN_RISE0_SHIFT); | 642 for (i = 0; i < data->ntrip; i++) { 643 if (!of_thermal_is_trip_valid(tz, i)) 644 continue; |
879 | 645 |
646 interrupt_en |= 647 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i)); 648 } 649 |
|
880 interrupt_en |= 881 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; | 650 interrupt_en |= 651 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; |
652 653 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); 654 con |= (1 << EXYNOS7_PD_DET_EN_SHIFT); |
|
882 } else { 883 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); 884 con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT); | 655 } else { 656 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); 657 con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT); |
885 interrupt_en = 0; /* Disable all interrupts */ | |
886 } 887 888 writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN); 889 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 890} 891 892static int exynos_get_temp(void *p, int *temp) 893{ 894 struct exynos_tmu_data *data = p; 895 int value, ret = 0; 896 | 658 } 659 660 writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN); 661 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); 662} 663 664static int exynos_get_temp(void *p, int *temp) 665{ 666 struct exynos_tmu_data *data = p; 667 int value, ret = 0; 668 |
897 if (!data || !data->tmu_read || !data->enabled) | 669 if (!data || !data->tmu_read) |
898 return -EINVAL; | 670 return -EINVAL; |
671 else if (!data->enabled) 672 /* 673 * Called too early, probably 674 * from thermal_zone_of_sensor_register(). 675 */ 676 return -EAGAIN; |
|
899 900 mutex_lock(&data->lock); 901 clk_enable(data->clk); 902 903 value = data->tmu_read(data); 904 if (value < 0) 905 ret = value; 906 else --- 7 unchanged lines hidden (view full) --- 914 915#ifdef CONFIG_THERMAL_EMULATION 916static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, 917 int temp) 918{ 919 if (temp) { 920 temp /= MCELSIUS; 921 | 677 678 mutex_lock(&data->lock); 679 clk_enable(data->clk); 680 681 value = data->tmu_read(data); 682 if (value < 0) 683 ret = value; 684 else --- 7 unchanged lines hidden (view full) --- 692 693#ifdef CONFIG_THERMAL_EMULATION 694static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, 695 int temp) 696{ 697 if (temp) { 698 temp /= MCELSIUS; 699 |
922 if (data->soc != SOC_ARCH_EXYNOS5440) { 923 val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); 924 val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); 925 } | 700 val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); 701 val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); |
926 if (data->soc == SOC_ARCH_EXYNOS7) { 927 val &= ~(EXYNOS7_EMUL_DATA_MASK << 928 EXYNOS7_EMUL_DATA_SHIFT); 929 val |= (temp_to_code(data, temp) << 930 EXYNOS7_EMUL_DATA_SHIFT) | 931 EXYNOS_EMUL_ENABLE; 932 } else { 933 val &= ~(EXYNOS_EMUL_DATA_MASK << --- 24 unchanged lines hidden (view full) --- 958 else 959 emul_con = EXYNOS_EMUL_CON; 960 961 val = readl(data->base + emul_con); 962 val = get_emul_con_reg(data, val, temp); 963 writel(val, data->base + emul_con); 964} 965 | 702 if (data->soc == SOC_ARCH_EXYNOS7) { 703 val &= ~(EXYNOS7_EMUL_DATA_MASK << 704 EXYNOS7_EMUL_DATA_SHIFT); 705 val |= (temp_to_code(data, temp) << 706 EXYNOS7_EMUL_DATA_SHIFT) | 707 EXYNOS_EMUL_ENABLE; 708 } else { 709 val &= ~(EXYNOS_EMUL_DATA_MASK << --- 24 unchanged lines hidden (view full) --- 734 else 735 emul_con = EXYNOS_EMUL_CON; 736 737 val = readl(data->base + emul_con); 738 val = get_emul_con_reg(data, val, temp); 739 writel(val, data->base + emul_con); 740} 741 |
966static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, 967 int temp) 968{ 969 unsigned int val; 970 971 val = readl(data->base + EXYNOS5440_TMU_S0_7_DEBUG); 972 val = get_emul_con_reg(data, val, temp); 973 writel(val, data->base + EXYNOS5440_TMU_S0_7_DEBUG); 974} 975 | |
976static int exynos_tmu_set_emulation(void *drv_data, int temp) 977{ 978 struct exynos_tmu_data *data = drv_data; 979 int ret = -EINVAL; 980 981 if (data->soc == SOC_ARCH_EXYNOS4210) 982 goto out; 983 --- 6 unchanged lines hidden (view full) --- 990 clk_disable(data->clk); 991 mutex_unlock(&data->lock); 992 return 0; 993out: 994 return ret; 995} 996#else 997#define exynos4412_tmu_set_emulation NULL | 742static int exynos_tmu_set_emulation(void *drv_data, int temp) 743{ 744 struct exynos_tmu_data *data = drv_data; 745 int ret = -EINVAL; 746 747 if (data->soc == SOC_ARCH_EXYNOS4210) 748 goto out; 749 --- 6 unchanged lines hidden (view full) --- 756 clk_disable(data->clk); 757 mutex_unlock(&data->lock); 758 return 0; 759out: 760 return ret; 761} 762#else 763#define exynos4412_tmu_set_emulation NULL |
998#define exynos5440_tmu_set_emulation NULL | |
999static int exynos_tmu_set_emulation(void *drv_data, int temp) 1000 { return -EINVAL; } 1001#endif /* CONFIG_THERMAL_EMULATION */ 1002 1003static int exynos4210_tmu_read(struct exynos_tmu_data *data) 1004{ 1005 int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); 1006 1007 /* "temp_code" should range between 75 and 175 */ 1008 return (ret < 75 || ret > 175) ? -ENODATA : ret; 1009} 1010 1011static int exynos4412_tmu_read(struct exynos_tmu_data *data) 1012{ 1013 return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); 1014} 1015 | 764static int exynos_tmu_set_emulation(void *drv_data, int temp) 765 { return -EINVAL; } 766#endif /* CONFIG_THERMAL_EMULATION */ 767 768static int exynos4210_tmu_read(struct exynos_tmu_data *data) 769{ 770 int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); 771 772 /* "temp_code" should range between 75 and 175 */ 773 return (ret < 75 || ret > 175) ? -ENODATA : ret; 774} 775 776static int exynos4412_tmu_read(struct exynos_tmu_data *data) 777{ 778 return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); 779} 780 |
1016static int exynos5440_tmu_read(struct exynos_tmu_data *data) 1017{ 1018 return readb(data->base + EXYNOS5440_TMU_S0_7_TEMP); 1019} 1020 | |
1021static int exynos7_tmu_read(struct exynos_tmu_data *data) 1022{ 1023 return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) & 1024 EXYNOS7_TMU_TEMP_MASK; 1025} 1026 1027static void exynos_tmu_work(struct work_struct *work) 1028{ 1029 struct exynos_tmu_data *data = container_of(work, 1030 struct exynos_tmu_data, irq_work); | 781static int exynos7_tmu_read(struct exynos_tmu_data *data) 782{ 783 return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) & 784 EXYNOS7_TMU_TEMP_MASK; 785} 786 787static void exynos_tmu_work(struct work_struct *work) 788{ 789 struct exynos_tmu_data *data = container_of(work, 790 struct exynos_tmu_data, irq_work); |
1031 unsigned int val_type; | |
1032 1033 if (!IS_ERR(data->clk_sec)) 1034 clk_enable(data->clk_sec); | 791 792 if (!IS_ERR(data->clk_sec)) 793 clk_enable(data->clk_sec); |
1035 /* Find which sensor generated this interrupt */ 1036 if (data->soc == SOC_ARCH_EXYNOS5440) { 1037 val_type = readl(data->base_second + EXYNOS5440_TMU_IRQ_STATUS); 1038 if (!((val_type >> data->id) & 0x1)) 1039 goto out; 1040 } | |
1041 if (!IS_ERR(data->clk_sec)) 1042 clk_disable(data->clk_sec); 1043 | 794 if (!IS_ERR(data->clk_sec)) 795 clk_disable(data->clk_sec); 796 |
1044 exynos_report_trigger(data); | 797 thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED); 798 |
1045 mutex_lock(&data->lock); 1046 clk_enable(data->clk); 1047 1048 /* TODO: take action based on particular interrupt */ 1049 data->tmu_clear_irqs(data); 1050 1051 clk_disable(data->clk); 1052 mutex_unlock(&data->lock); | 799 mutex_lock(&data->lock); 800 clk_enable(data->clk); 801 802 /* TODO: take action based on particular interrupt */ 803 data->tmu_clear_irqs(data); 804 805 clk_disable(data->clk); 806 mutex_unlock(&data->lock); |
1053out: | |
1054 enable_irq(data->irq); 1055} 1056 1057static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data) 1058{ 1059 unsigned int val_irq; 1060 u32 tmu_intstat, tmu_intclear; 1061 --- 18 unchanged lines hidden (view full) --- 1080 * states that INTCLEAR register has a different placing of bits 1081 * responsible for FALL IRQs than INTSTAT register. Exynos5420 1082 * and Exynos5440 documentation is correct (Exynos4210 doesn't 1083 * support FALL IRQs at all). 1084 */ 1085 writel(val_irq, data->base + tmu_intclear); 1086} 1087 | 807 enable_irq(data->irq); 808} 809 810static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data) 811{ 812 unsigned int val_irq; 813 u32 tmu_intstat, tmu_intclear; 814 --- 18 unchanged lines hidden (view full) --- 833 * states that INTCLEAR register has a different placing of bits 834 * responsible for FALL IRQs than INTSTAT register. Exynos5420 835 * and Exynos5440 documentation is correct (Exynos4210 doesn't 836 * support FALL IRQs at all). 837 */ 838 writel(val_irq, data->base + tmu_intclear); 839} 840 |
1088static void exynos5440_tmu_clear_irqs(struct exynos_tmu_data *data) 1089{ 1090 unsigned int val_irq; 1091 1092 val_irq = readl(data->base + EXYNOS5440_TMU_S0_7_IRQ); 1093 /* clear the interrupts */ 1094 writel(val_irq, data->base + EXYNOS5440_TMU_S0_7_IRQ); 1095} 1096 | |
1097static irqreturn_t exynos_tmu_irq(int irq, void *id) 1098{ 1099 struct exynos_tmu_data *data = id; 1100 1101 disable_irq_nosync(irq); 1102 schedule_work(&data->irq_work); 1103 1104 return IRQ_HANDLED; 1105} 1106 1107static const struct of_device_id exynos_tmu_match[] = { | 841static irqreturn_t exynos_tmu_irq(int irq, void *id) 842{ 843 struct exynos_tmu_data *data = id; 844 845 disable_irq_nosync(irq); 846 schedule_work(&data->irq_work); 847 848 return IRQ_HANDLED; 849} 850 851static const struct of_device_id exynos_tmu_match[] = { |
1108 { .compatible = "samsung,exynos3250-tmu", }, 1109 { .compatible = "samsung,exynos4210-tmu", }, 1110 { .compatible = "samsung,exynos4412-tmu", }, 1111 { .compatible = "samsung,exynos5250-tmu", }, 1112 { .compatible = "samsung,exynos5260-tmu", }, 1113 { .compatible = "samsung,exynos5420-tmu", }, 1114 { .compatible = "samsung,exynos5420-tmu-ext-triminfo", }, 1115 { .compatible = "samsung,exynos5433-tmu", }, 1116 { .compatible = "samsung,exynos5440-tmu", }, 1117 { .compatible = "samsung,exynos7-tmu", }, 1118 { /* sentinel */ }, | 852 { 853 .compatible = "samsung,exynos3250-tmu", 854 .data = (const void *)SOC_ARCH_EXYNOS3250, 855 }, { 856 .compatible = "samsung,exynos4210-tmu", 857 .data = (const void *)SOC_ARCH_EXYNOS4210, 858 }, { 859 .compatible = "samsung,exynos4412-tmu", 860 .data = (const void *)SOC_ARCH_EXYNOS4412, 861 }, { 862 .compatible = "samsung,exynos5250-tmu", 863 .data = (const void *)SOC_ARCH_EXYNOS5250, 864 }, { 865 .compatible = "samsung,exynos5260-tmu", 866 .data = (const void *)SOC_ARCH_EXYNOS5260, 867 }, { 868 .compatible = "samsung,exynos5420-tmu", 869 .data = (const void *)SOC_ARCH_EXYNOS5420, 870 }, { 871 .compatible = "samsung,exynos5420-tmu-ext-triminfo", 872 .data = (const void *)SOC_ARCH_EXYNOS5420_TRIMINFO, 873 }, { 874 .compatible = "samsung,exynos5433-tmu", 875 .data = (const void *)SOC_ARCH_EXYNOS5433, 876 }, { 877 .compatible = "samsung,exynos7-tmu", 878 .data = (const void *)SOC_ARCH_EXYNOS7, 879 }, 880 { }, |
1119}; 1120MODULE_DEVICE_TABLE(of, exynos_tmu_match); 1121 | 881}; 882MODULE_DEVICE_TABLE(of, exynos_tmu_match); 883 |
1122static int exynos_of_get_soc_type(struct device_node *np) 1123{ 1124 if (of_device_is_compatible(np, "samsung,exynos3250-tmu")) 1125 return SOC_ARCH_EXYNOS3250; 1126 else if (of_device_is_compatible(np, "samsung,exynos4210-tmu")) 1127 return SOC_ARCH_EXYNOS4210; 1128 else if (of_device_is_compatible(np, "samsung,exynos4412-tmu")) 1129 return SOC_ARCH_EXYNOS4412; 1130 else if (of_device_is_compatible(np, "samsung,exynos5250-tmu")) 1131 return SOC_ARCH_EXYNOS5250; 1132 else if (of_device_is_compatible(np, "samsung,exynos5260-tmu")) 1133 return SOC_ARCH_EXYNOS5260; 1134 else if (of_device_is_compatible(np, "samsung,exynos5420-tmu")) 1135 return SOC_ARCH_EXYNOS5420; 1136 else if (of_device_is_compatible(np, 1137 "samsung,exynos5420-tmu-ext-triminfo")) 1138 return SOC_ARCH_EXYNOS5420_TRIMINFO; 1139 else if (of_device_is_compatible(np, "samsung,exynos5433-tmu")) 1140 return SOC_ARCH_EXYNOS5433; 1141 else if (of_device_is_compatible(np, "samsung,exynos5440-tmu")) 1142 return SOC_ARCH_EXYNOS5440; 1143 else if (of_device_is_compatible(np, "samsung,exynos7-tmu")) 1144 return SOC_ARCH_EXYNOS7; 1145 1146 return -EINVAL; 1147} 1148 1149static int exynos_of_sensor_conf(struct device_node *np, 1150 struct exynos_tmu_platform_data *pdata) 1151{ 1152 u32 value; 1153 int ret; 1154 1155 of_node_get(np); 1156 1157 ret = of_property_read_u32(np, "samsung,tmu_gain", &value); 1158 pdata->gain = (u8)value; 1159 of_property_read_u32(np, "samsung,tmu_reference_voltage", &value); 1160 pdata->reference_voltage = (u8)value; 1161 of_property_read_u32(np, "samsung,tmu_noise_cancel_mode", &value); 1162 pdata->noise_cancel_mode = (u8)value; 1163 1164 of_property_read_u32(np, "samsung,tmu_efuse_value", 1165 &pdata->efuse_value); 1166 of_property_read_u32(np, "samsung,tmu_min_efuse_value", 1167 &pdata->min_efuse_value); 1168 of_property_read_u32(np, "samsung,tmu_max_efuse_value", 1169 &pdata->max_efuse_value); 1170 1171 of_property_read_u32(np, "samsung,tmu_first_point_trim", &value); 1172 pdata->first_point_trim = (u8)value; 1173 of_property_read_u32(np, "samsung,tmu_second_point_trim", &value); 1174 pdata->second_point_trim = (u8)value; 1175 of_property_read_u32(np, "samsung,tmu_default_temp_offset", &value); 1176 pdata->default_temp_offset = (u8)value; 1177 1178 of_property_read_u32(np, "samsung,tmu_cal_type", &pdata->cal_type); 1179 1180 of_node_put(np); 1181 return 0; 1182} 1183 | |
1184static int exynos_map_dt_data(struct platform_device *pdev) 1185{ 1186 struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 884static int exynos_map_dt_data(struct platform_device *pdev) 885{ 886 struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
1187 struct exynos_tmu_platform_data *pdata; | |
1188 struct resource res; 1189 1190 if (!data || !pdev->dev.of_node) 1191 return -ENODEV; 1192 1193 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); 1194 if (data->id < 0) 1195 data->id = 0; --- 10 unchanged lines hidden (view full) --- 1206 } 1207 1208 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); 1209 if (!data->base) { 1210 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 1211 return -EADDRNOTAVAIL; 1212 } 1213 | 887 struct resource res; 888 889 if (!data || !pdev->dev.of_node) 890 return -ENODEV; 891 892 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); 893 if (data->id < 0) 894 data->id = 0; --- 10 unchanged lines hidden (view full) --- 905 } 906 907 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); 908 if (!data->base) { 909 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 910 return -EADDRNOTAVAIL; 911 } 912 |
1214 pdata = devm_kzalloc(&pdev->dev, 1215 sizeof(struct exynos_tmu_platform_data), 1216 GFP_KERNEL); 1217 if (!pdata) 1218 return -ENOMEM; | 913 data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev); |
1219 | 914 |
1220 exynos_of_sensor_conf(pdev->dev.of_node, pdata); 1221 data->pdata = pdata; 1222 data->soc = exynos_of_get_soc_type(pdev->dev.of_node); 1223 | |
1224 switch (data->soc) { 1225 case SOC_ARCH_EXYNOS4210: | 915 switch (data->soc) { 916 case SOC_ARCH_EXYNOS4210: |
917 data->tmu_set_trip_temp = exynos4210_tmu_set_trip_temp; 918 data->tmu_set_trip_hyst = exynos4210_tmu_set_trip_hyst; |
|
1226 data->tmu_initialize = exynos4210_tmu_initialize; 1227 data->tmu_control = exynos4210_tmu_control; 1228 data->tmu_read = exynos4210_tmu_read; 1229 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1230 data->ntrip = 4; | 919 data->tmu_initialize = exynos4210_tmu_initialize; 920 data->tmu_control = exynos4210_tmu_control; 921 data->tmu_read = exynos4210_tmu_read; 922 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 923 data->ntrip = 4; |
924 data->gain = 15; 925 data->reference_voltage = 7; 926 data->efuse_value = 55; 927 data->min_efuse_value = 40; 928 data->max_efuse_value = 100; |
|
1231 break; 1232 case SOC_ARCH_EXYNOS3250: 1233 case SOC_ARCH_EXYNOS4412: 1234 case SOC_ARCH_EXYNOS5250: 1235 case SOC_ARCH_EXYNOS5260: 1236 case SOC_ARCH_EXYNOS5420: 1237 case SOC_ARCH_EXYNOS5420_TRIMINFO: | 929 break; 930 case SOC_ARCH_EXYNOS3250: 931 case SOC_ARCH_EXYNOS4412: 932 case SOC_ARCH_EXYNOS5250: 933 case SOC_ARCH_EXYNOS5260: 934 case SOC_ARCH_EXYNOS5420: 935 case SOC_ARCH_EXYNOS5420_TRIMINFO: |
936 data->tmu_set_trip_temp = exynos4412_tmu_set_trip_temp; 937 data->tmu_set_trip_hyst = exynos4412_tmu_set_trip_hyst; |
|
1238 data->tmu_initialize = exynos4412_tmu_initialize; 1239 data->tmu_control = exynos4210_tmu_control; 1240 data->tmu_read = exynos4412_tmu_read; 1241 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 1242 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1243 data->ntrip = 4; | 938 data->tmu_initialize = exynos4412_tmu_initialize; 939 data->tmu_control = exynos4210_tmu_control; 940 data->tmu_read = exynos4412_tmu_read; 941 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 942 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 943 data->ntrip = 4; |
944 data->gain = 8; 945 data->reference_voltage = 16; 946 data->efuse_value = 55; 947 if (data->soc != SOC_ARCH_EXYNOS5420 && 948 data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO) 949 data->min_efuse_value = 40; 950 else 951 data->min_efuse_value = 0; 952 data->max_efuse_value = 100; |
|
1244 break; 1245 case SOC_ARCH_EXYNOS5433: | 953 break; 954 case SOC_ARCH_EXYNOS5433: |
955 data->tmu_set_trip_temp = exynos5433_tmu_set_trip_temp; 956 data->tmu_set_trip_hyst = exynos5433_tmu_set_trip_hyst; |
|
1246 data->tmu_initialize = exynos5433_tmu_initialize; 1247 data->tmu_control = exynos5433_tmu_control; 1248 data->tmu_read = exynos4412_tmu_read; 1249 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 1250 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1251 data->ntrip = 8; | 957 data->tmu_initialize = exynos5433_tmu_initialize; 958 data->tmu_control = exynos5433_tmu_control; 959 data->tmu_read = exynos4412_tmu_read; 960 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 961 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 962 data->ntrip = 8; |
963 data->gain = 8; 964 if (res.start == EXYNOS5433_G3D_BASE) 965 data->reference_voltage = 23; 966 else 967 data->reference_voltage = 16; 968 data->efuse_value = 75; 969 data->min_efuse_value = 40; 970 data->max_efuse_value = 150; |
|
1252 break; | 971 break; |
1253 case SOC_ARCH_EXYNOS5440: 1254 data->tmu_initialize = exynos5440_tmu_initialize; 1255 data->tmu_control = exynos5440_tmu_control; 1256 data->tmu_read = exynos5440_tmu_read; 1257 data->tmu_set_emulation = exynos5440_tmu_set_emulation; 1258 data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; 1259 data->ntrip = 4; 1260 break; | |
1261 case SOC_ARCH_EXYNOS7: | 972 case SOC_ARCH_EXYNOS7: |
973 data->tmu_set_trip_temp = exynos7_tmu_set_trip_temp; 974 data->tmu_set_trip_hyst = exynos7_tmu_set_trip_hyst; |
|
1262 data->tmu_initialize = exynos7_tmu_initialize; 1263 data->tmu_control = exynos7_tmu_control; 1264 data->tmu_read = exynos7_tmu_read; 1265 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 1266 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1267 data->ntrip = 8; | 975 data->tmu_initialize = exynos7_tmu_initialize; 976 data->tmu_control = exynos7_tmu_control; 977 data->tmu_read = exynos7_tmu_read; 978 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 979 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 980 data->ntrip = 8; |
981 data->gain = 9; 982 data->reference_voltage = 17; 983 data->efuse_value = 75; 984 data->min_efuse_value = 15; 985 data->max_efuse_value = 100; |
|
1268 break; 1269 default: 1270 dev_err(&pdev->dev, "Platform not supported\n"); 1271 return -EINVAL; 1272 } 1273 | 986 break; 987 default: 988 dev_err(&pdev->dev, "Platform not supported\n"); 989 return -EINVAL; 990 } 991 |
992 data->cal_type = TYPE_ONE_POINT_TRIMMING; 993 |
|
1274 /* 1275 * Check if the TMU shares some registers and then try to map the 1276 * memory of common registers. 1277 */ | 994 /* 995 * Check if the TMU shares some registers and then try to map the 996 * memory of common registers. 997 */ |
1278 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO && 1279 data->soc != SOC_ARCH_EXYNOS5440) | 998 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO) |
1280 return 0; 1281 1282 if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { 1283 dev_err(&pdev->dev, "failed to get Resource 1\n"); 1284 return -ENODEV; 1285 } 1286 1287 data->base_second = devm_ioremap(&pdev->dev, res.start, --- 202 unchanged lines hidden --- | 999 return 0; 1000 1001 if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { 1002 dev_err(&pdev->dev, "failed to get Resource 1\n"); 1003 return -ENODEV; 1004 } 1005 1006 data->base_second = devm_ioremap(&pdev->dev, res.start, --- 202 unchanged lines hidden --- |