]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/thermal/samsung/exynos_tmu.c
thermal: exynos: Correct sanity check at exynos_report_trigger() function
[karo-tx-linux.git] / drivers / thermal / samsung / exynos_tmu.c
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
9  *  Donggeun Kim <dg77.kim@samsung.com>
10  *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
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>
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"
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
47 #define EXYNOS_TMU_REG_INTSTAT          0x74
48 #define EXYNOS_TMU_REG_INTCLEAR         0x78
49
50 #define EXYNOS_TMU_TEMP_MASK            0xff
51 #define EXYNOS_TMU_REF_VOLTAGE_SHIFT    24
52 #define EXYNOS_TMU_REF_VOLTAGE_MASK     0x1f
53 #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK   0xf
54 #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT  8
55 #define EXYNOS_TMU_CORE_EN_SHIFT        0
56
57 /* Exynos3250 specific registers */
58 #define EXYNOS_TMU_TRIMINFO_CON1        0x10
59
60 /* Exynos4210 specific registers */
61 #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP       0x44
62 #define EXYNOS4210_TMU_REG_TRIG_LEVEL0  0x50
63
64 /* Exynos5250, Exynos4412, Exynos3250 specific registers */
65 #define EXYNOS_TMU_TRIMINFO_CON2        0x14
66 #define EXYNOS_THD_TEMP_RISE            0x50
67 #define EXYNOS_THD_TEMP_FALL            0x54
68 #define EXYNOS_EMUL_CON         0x80
69
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
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
89
90 /* Exynos5260 specific */
91 #define EXYNOS5260_TMU_REG_INTEN                0xC0
92 #define EXYNOS5260_TMU_REG_INTSTAT              0xC4
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 /*exynos5440 specific registers*/
101 #define EXYNOS5440_TMU_S0_7_TRIM                0x000
102 #define EXYNOS5440_TMU_S0_7_CTRL                0x020
103 #define EXYNOS5440_TMU_S0_7_DEBUG               0x040
104 #define EXYNOS5440_TMU_S0_7_TEMP                0x0f0
105 #define EXYNOS5440_TMU_S0_7_TH0                 0x110
106 #define EXYNOS5440_TMU_S0_7_TH1                 0x130
107 #define EXYNOS5440_TMU_S0_7_TH2                 0x150
108 #define EXYNOS5440_TMU_S0_7_IRQEN               0x210
109 #define EXYNOS5440_TMU_S0_7_IRQ                 0x230
110 /* exynos5440 common registers */
111 #define EXYNOS5440_TMU_IRQ_STATUS               0x000
112 #define EXYNOS5440_TMU_PMIN                     0x004
113
114 #define EXYNOS5440_TMU_INTEN_RISE0_SHIFT        0
115 #define EXYNOS5440_TMU_INTEN_RISE1_SHIFT        1
116 #define EXYNOS5440_TMU_INTEN_RISE2_SHIFT        2
117 #define EXYNOS5440_TMU_INTEN_RISE3_SHIFT        3
118 #define EXYNOS5440_TMU_INTEN_FALL0_SHIFT        4
119 #define EXYNOS5440_TMU_TH_RISE4_SHIFT           24
120 #define EXYNOS5440_EFUSE_SWAP_OFFSET            8
121
122 #define MCELSIUS        1000
123 /**
124  * struct exynos_tmu_data : A structure to hold the private data of the TMU
125         driver
126  * @id: identifier of the one instance of the TMU controller.
127  * @pdata: pointer to the tmu platform/configuration data
128  * @base: base address of the single instance of the TMU controller.
129  * @base_second: base address of the common registers of the TMU controller.
130  * @irq: irq number of the TMU controller.
131  * @soc: id of the SOC type.
132  * @irq_work: pointer to the irq work structure.
133  * @lock: lock to implement synchronization.
134  * @clk: pointer to the clock structure.
135  * @clk_sec: pointer to the clock structure for accessing the base_second.
136  * @temp_error1: fused value of the first point trim.
137  * @temp_error2: fused value of the second point trim.
138  * @regulator: pointer to the TMU regulator structure.
139  * @reg_conf: pointer to structure to register with core thermal.
140  * @tmu_initialize: SoC specific TMU initialization method
141  * @tmu_control: SoC specific TMU control method
142  * @tmu_read: SoC specific TMU temperature read method
143  * @tmu_set_emulation: SoC specific TMU emulation setting method
144  * @tmu_clear_irqs: SoC specific TMU interrupts clearing method
145  */
146 struct exynos_tmu_data {
147         int id;
148         struct exynos_tmu_platform_data *pdata;
149         void __iomem *base;
150         void __iomem *base_second;
151         int irq;
152         enum soc_type soc;
153         struct work_struct irq_work;
154         struct mutex lock;
155         struct clk *clk, *clk_sec;
156         u8 temp_error1, temp_error2;
157         struct regulator *regulator;
158         struct thermal_zone_device *tzd;
159
160         int (*tmu_initialize)(struct platform_device *pdev);
161         void (*tmu_control)(struct platform_device *pdev, bool on);
162         int (*tmu_read)(struct exynos_tmu_data *data);
163         void (*tmu_set_emulation)(struct exynos_tmu_data *data,
164                                   unsigned long temp);
165         void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
166 };
167
168 static void exynos_report_trigger(struct exynos_tmu_data *p)
169 {
170         char data[10], *envp[] = { data, NULL };
171         struct thermal_zone_device *tz = p->tzd;
172         unsigned long temp;
173         unsigned int i;
174
175         if (!tz) {
176                 pr_err("No thermal zone device defined\n");
177                 return;
178         }
179
180         thermal_zone_device_update(tz);
181
182         mutex_lock(&tz->lock);
183         /* Find the level for which trip happened */
184         for (i = 0; i < of_thermal_get_ntrips(tz); i++) {
185                 tz->ops->get_trip_temp(tz, i, &temp);
186                 if (tz->last_temperature < temp)
187                         break;
188         }
189
190         snprintf(data, sizeof(data), "%u", i);
191         kobject_uevent_env(&tz->device.kobj, KOBJ_CHANGE, envp);
192         mutex_unlock(&tz->lock);
193 }
194
195 /*
196  * TMU treats temperature as a mapped temperature code.
197  * The temperature is converted differently depending on the calibration type.
198  */
199 static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
200 {
201         struct exynos_tmu_platform_data *pdata = data->pdata;
202         int temp_code;
203
204         switch (pdata->cal_type) {
205         case TYPE_TWO_POINT_TRIMMING:
206                 temp_code = (temp - pdata->first_point_trim) *
207                         (data->temp_error2 - data->temp_error1) /
208                         (pdata->second_point_trim - pdata->first_point_trim) +
209                         data->temp_error1;
210                 break;
211         case TYPE_ONE_POINT_TRIMMING:
212                 temp_code = temp + data->temp_error1 - pdata->first_point_trim;
213                 break;
214         default:
215                 temp_code = temp + pdata->default_temp_offset;
216                 break;
217         }
218
219         return temp_code;
220 }
221
222 /*
223  * Calculate a temperature value from a temperature code.
224  * The unit of the temperature is degree Celsius.
225  */
226 static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
227 {
228         struct exynos_tmu_platform_data *pdata = data->pdata;
229         int temp;
230
231         switch (pdata->cal_type) {
232         case TYPE_TWO_POINT_TRIMMING:
233                 temp = (temp_code - data->temp_error1) *
234                         (pdata->second_point_trim - pdata->first_point_trim) /
235                         (data->temp_error2 - data->temp_error1) +
236                         pdata->first_point_trim;
237                 break;
238         case TYPE_ONE_POINT_TRIMMING:
239                 temp = temp_code - data->temp_error1 + pdata->first_point_trim;
240                 break;
241         default:
242                 temp = temp_code - pdata->default_temp_offset;
243                 break;
244         }
245
246         return temp;
247 }
248
249 static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
250 {
251         struct exynos_tmu_platform_data *pdata = data->pdata;
252
253         data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK;
254         data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
255                                 EXYNOS_TMU_TEMP_MASK);
256
257         if (!data->temp_error1 ||
258                 (pdata->min_efuse_value > data->temp_error1) ||
259                 (data->temp_error1 > pdata->max_efuse_value))
260                 data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK;
261
262         if (!data->temp_error2)
263                 data->temp_error2 =
264                         (pdata->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
265                         EXYNOS_TMU_TEMP_MASK;
266 }
267
268 static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling)
269 {
270         struct thermal_zone_device *tz = data->tzd;
271         const struct thermal_trip * const trips =
272                 of_thermal_get_trip_points(tz);
273         unsigned long temp;
274         int i;
275
276         if (!trips) {
277                 pr_err("%s: Cannot get trip points from of-thermal.c!\n",
278                        __func__);
279                 return 0;
280         }
281
282         for (i = 0; i < of_thermal_get_ntrips(tz); i++) {
283                 if (trips[i].type == THERMAL_TRIP_CRITICAL)
284                         continue;
285
286                 temp = trips[i].temperature / MCELSIUS;
287                 if (falling)
288                         temp -= (trips[i].hysteresis / MCELSIUS);
289                 else
290                         threshold &= ~(0xff << 8 * i);
291
292                 threshold |= temp_to_code(data, temp) << 8 * i;
293         }
294
295         return threshold;
296 }
297
298 static int exynos_tmu_initialize(struct platform_device *pdev)
299 {
300         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
301         int ret;
302
303         mutex_lock(&data->lock);
304         clk_enable(data->clk);
305         if (!IS_ERR(data->clk_sec))
306                 clk_enable(data->clk_sec);
307         ret = data->tmu_initialize(pdev);
308         clk_disable(data->clk);
309         mutex_unlock(&data->lock);
310         if (!IS_ERR(data->clk_sec))
311                 clk_disable(data->clk_sec);
312
313         return ret;
314 }
315
316 static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
317 {
318         struct exynos_tmu_platform_data *pdata = data->pdata;
319
320         if (data->soc == SOC_ARCH_EXYNOS4412 ||
321             data->soc == SOC_ARCH_EXYNOS3250)
322                 con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT);
323
324         con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT);
325         con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
326
327         con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
328         con |= (pdata->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
329
330         if (pdata->noise_cancel_mode) {
331                 con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT);
332                 con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT);
333         }
334
335         return con;
336 }
337
338 static void exynos_tmu_control(struct platform_device *pdev, bool on)
339 {
340         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
341
342         mutex_lock(&data->lock);
343         clk_enable(data->clk);
344         data->tmu_control(pdev, on);
345         clk_disable(data->clk);
346         mutex_unlock(&data->lock);
347 }
348
349 static int exynos4210_tmu_initialize(struct platform_device *pdev)
350 {
351         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
352         struct thermal_zone_device *tz = data->tzd;
353         const struct thermal_trip * const trips =
354                 of_thermal_get_trip_points(tz);
355         int ret = 0, threshold_code, i;
356         unsigned long reference, temp;
357         unsigned int status;
358
359         if (!trips) {
360                 pr_err("%s: Cannot get trip points from of-thermal.c!\n",
361                        __func__);
362                 ret = -ENODEV;
363                 goto out;
364         }
365
366         status = readb(data->base + EXYNOS_TMU_REG_STATUS);
367         if (!status) {
368                 ret = -EBUSY;
369                 goto out;
370         }
371
372         sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO));
373
374         /* Write temperature code for threshold */
375         reference = trips[0].temperature / MCELSIUS;
376         threshold_code = temp_to_code(data, reference);
377         if (threshold_code < 0) {
378                 ret = threshold_code;
379                 goto out;
380         }
381         writeb(threshold_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
382
383         for (i = 0; i < of_thermal_get_ntrips(tz); i++) {
384                 temp = trips[i].temperature / MCELSIUS;
385                 writeb(temp - reference, data->base +
386                        EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
387         }
388
389         data->tmu_clear_irqs(data);
390 out:
391         return ret;
392 }
393
394 static int exynos4412_tmu_initialize(struct platform_device *pdev)
395 {
396         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
397         const struct thermal_trip * const trips =
398                 of_thermal_get_trip_points(data->tzd);
399         unsigned int status, trim_info, con, ctrl, rising_threshold;
400         int ret = 0, threshold_code, i;
401         unsigned long crit_temp = 0;
402
403         status = readb(data->base + EXYNOS_TMU_REG_STATUS);
404         if (!status) {
405                 ret = -EBUSY;
406                 goto out;
407         }
408
409         if (data->soc == SOC_ARCH_EXYNOS3250 ||
410             data->soc == SOC_ARCH_EXYNOS4412 ||
411             data->soc == SOC_ARCH_EXYNOS5250) {
412                 if (data->soc == SOC_ARCH_EXYNOS3250) {
413                         ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
414                         ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
415                         writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
416                 }
417                 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
418                 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
419                 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
420         }
421
422         /* On exynos5420 the triminfo register is in the shared space */
423         if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
424                 trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
425         else
426                 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
427
428         sanitize_temp_error(data, trim_info);
429
430         /* Write temperature code for rising and falling threshold */
431         rising_threshold = readl(data->base + EXYNOS_THD_TEMP_RISE);
432         rising_threshold = get_th_reg(data, rising_threshold, false);
433         writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE);
434         writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL);
435
436         data->tmu_clear_irqs(data);
437
438         /* if last threshold limit is also present */
439         for (i = 0; i < of_thermal_get_ntrips(data->tzd); i++) {
440                 if (trips[i].type == THERMAL_TRIP_CRITICAL) {
441                         crit_temp = trips[i].temperature;
442                         break;
443                 }
444         }
445
446         if (i == of_thermal_get_ntrips(data->tzd)) {
447                 pr_err("%s: No CRITICAL trip point defined at of-thermal.c!\n",
448                        __func__);
449                 ret = -EINVAL;
450                 goto out;
451         }
452
453         threshold_code = temp_to_code(data, crit_temp / MCELSIUS);
454         /* 1-4 level to be assigned in th0 reg */
455         rising_threshold &= ~(0xff << 8 * i);
456         rising_threshold |= threshold_code << 8 * i;
457         writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE);
458         con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
459         con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
460         writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
461
462 out:
463         return ret;
464 }
465
466 static int exynos5440_tmu_initialize(struct platform_device *pdev)
467 {
468         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
469         unsigned int trim_info = 0, con, rising_threshold;
470         int ret = 0, threshold_code;
471         unsigned long crit_temp = 0;
472
473         /*
474          * For exynos5440 soc triminfo value is swapped between TMU0 and
475          * TMU2, so the below logic is needed.
476          */
477         switch (data->id) {
478         case 0:
479                 trim_info = readl(data->base + EXYNOS5440_EFUSE_SWAP_OFFSET +
480                                  EXYNOS5440_TMU_S0_7_TRIM);
481                 break;
482         case 1:
483                 trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM);
484                 break;
485         case 2:
486                 trim_info = readl(data->base - EXYNOS5440_EFUSE_SWAP_OFFSET +
487                                   EXYNOS5440_TMU_S0_7_TRIM);
488         }
489         sanitize_temp_error(data, trim_info);
490
491         /* Write temperature code for rising and falling threshold */
492         rising_threshold = readl(data->base + EXYNOS5440_TMU_S0_7_TH0);
493         rising_threshold = get_th_reg(data, rising_threshold, false);
494         writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0);
495         writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1);
496
497         data->tmu_clear_irqs(data);
498
499         /* if last threshold limit is also present */
500         if (!data->tzd->ops->get_crit_temp(data->tzd, &crit_temp)) {
501                 threshold_code = temp_to_code(data, crit_temp / MCELSIUS);
502                 /* 5th level to be assigned in th2 reg */
503                 rising_threshold =
504                         threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT;
505                 writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH2);
506                 con = readl(data->base + EXYNOS5440_TMU_S0_7_CTRL);
507                 con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
508                 writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL);
509         }
510         /* Clear the PMIN in the common TMU register */
511         if (!data->id)
512                 writel(0, data->base_second + EXYNOS5440_TMU_PMIN);
513         return ret;
514 }
515
516 static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
517 {
518         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
519         struct thermal_zone_device *tz = data->tzd;
520         unsigned int con, interrupt_en;
521
522         con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
523
524         if (on) {
525                 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
526                 interrupt_en =
527                         (of_thermal_is_trip_valid(tz, 3)
528                          << EXYNOS_TMU_INTEN_RISE3_SHIFT) |
529                         (of_thermal_is_trip_valid(tz, 2)
530                          << EXYNOS_TMU_INTEN_RISE2_SHIFT) |
531                         (of_thermal_is_trip_valid(tz, 1)
532                          << EXYNOS_TMU_INTEN_RISE1_SHIFT) |
533                         (of_thermal_is_trip_valid(tz, 0)
534                          << EXYNOS_TMU_INTEN_RISE0_SHIFT);
535
536                 if (data->soc != SOC_ARCH_EXYNOS4210)
537                         interrupt_en |=
538                                 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
539         } else {
540                 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
541                 interrupt_en = 0; /* Disable all interrupts */
542         }
543         writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
544         writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
545 }
546
547 static void exynos5440_tmu_control(struct platform_device *pdev, bool on)
548 {
549         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
550         struct thermal_zone_device *tz = data->tzd;
551         unsigned int con, interrupt_en;
552
553         con = get_con_reg(data, readl(data->base + EXYNOS5440_TMU_S0_7_CTRL));
554
555         if (on) {
556                 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
557                 interrupt_en =
558                         (of_thermal_is_trip_valid(tz, 3)
559                          << EXYNOS5440_TMU_INTEN_RISE3_SHIFT) |
560                         (of_thermal_is_trip_valid(tz, 2)
561                          << EXYNOS5440_TMU_INTEN_RISE2_SHIFT) |
562                         (of_thermal_is_trip_valid(tz, 1)
563                          << EXYNOS5440_TMU_INTEN_RISE1_SHIFT) |
564                         (of_thermal_is_trip_valid(tz, 0)
565                          << EXYNOS5440_TMU_INTEN_RISE0_SHIFT);
566                 interrupt_en |=
567                         interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT;
568         } else {
569                 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
570                 interrupt_en = 0; /* Disable all interrupts */
571         }
572         writel(interrupt_en, data->base + EXYNOS5440_TMU_S0_7_IRQEN);
573         writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL);
574 }
575
576 static int exynos_get_temp(void *p, long *temp)
577 {
578         struct exynos_tmu_data *data = p;
579
580         if (!data)
581                 return -EINVAL;
582
583         mutex_lock(&data->lock);
584         clk_enable(data->clk);
585
586         *temp = code_to_temp(data, data->tmu_read(data)) * MCELSIUS;
587
588         clk_disable(data->clk);
589         mutex_unlock(&data->lock);
590
591         return 0;
592 }
593
594 #ifdef CONFIG_THERMAL_EMULATION
595 static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val,
596                             unsigned long temp)
597 {
598         if (temp) {
599                 temp /= MCELSIUS;
600
601                 if (data->soc != SOC_ARCH_EXYNOS5440) {
602                         val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
603                         val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
604                 }
605                 val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT);
606                 val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) |
607                         EXYNOS_EMUL_ENABLE;
608         } else {
609                 val &= ~EXYNOS_EMUL_ENABLE;
610         }
611
612         return val;
613 }
614
615 static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
616                                          unsigned long temp)
617 {
618         unsigned int val;
619         u32 emul_con;
620
621         if (data->soc == SOC_ARCH_EXYNOS5260)
622                 emul_con = EXYNOS5260_EMUL_CON;
623         else
624                 emul_con = EXYNOS_EMUL_CON;
625
626         val = readl(data->base + emul_con);
627         val = get_emul_con_reg(data, val, temp);
628         writel(val, data->base + emul_con);
629 }
630
631 static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data,
632                                          unsigned long temp)
633 {
634         unsigned int val;
635
636         val = readl(data->base + EXYNOS5440_TMU_S0_7_DEBUG);
637         val = get_emul_con_reg(data, val, temp);
638         writel(val, data->base + EXYNOS5440_TMU_S0_7_DEBUG);
639 }
640
641 static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
642 {
643         struct exynos_tmu_data *data = drv_data;
644         int ret = -EINVAL;
645
646         if (data->soc == SOC_ARCH_EXYNOS4210)
647                 goto out;
648
649         if (temp && temp < MCELSIUS)
650                 goto out;
651
652         mutex_lock(&data->lock);
653         clk_enable(data->clk);
654         data->tmu_set_emulation(data, temp);
655         clk_disable(data->clk);
656         mutex_unlock(&data->lock);
657         return 0;
658 out:
659         return ret;
660 }
661 #else
662 #define exynos4412_tmu_set_emulation NULL
663 #define exynos5440_tmu_set_emulation NULL
664 static int exynos_tmu_set_emulation(void *drv_data,     unsigned long temp)
665         { return -EINVAL; }
666 #endif /* CONFIG_THERMAL_EMULATION */
667
668 static int exynos4210_tmu_read(struct exynos_tmu_data *data)
669 {
670         int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
671
672         /* "temp_code" should range between 75 and 175 */
673         return (ret < 75 || ret > 175) ? -ENODATA : ret;
674 }
675
676 static int exynos4412_tmu_read(struct exynos_tmu_data *data)
677 {
678         return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
679 }
680
681 static int exynos5440_tmu_read(struct exynos_tmu_data *data)
682 {
683         return readb(data->base + EXYNOS5440_TMU_S0_7_TEMP);
684 }
685
686 static void exynos_tmu_work(struct work_struct *work)
687 {
688         struct exynos_tmu_data *data = container_of(work,
689                         struct exynos_tmu_data, irq_work);
690         unsigned int val_type;
691
692         if (!IS_ERR(data->clk_sec))
693                 clk_enable(data->clk_sec);
694         /* Find which sensor generated this interrupt */
695         if (data->soc == SOC_ARCH_EXYNOS5440) {
696                 val_type = readl(data->base_second + EXYNOS5440_TMU_IRQ_STATUS);
697                 if (!((val_type >> data->id) & 0x1))
698                         goto out;
699         }
700         if (!IS_ERR(data->clk_sec))
701                 clk_disable(data->clk_sec);
702
703         exynos_report_trigger(data);
704         mutex_lock(&data->lock);
705         clk_enable(data->clk);
706
707         /* TODO: take action based on particular interrupt */
708         data->tmu_clear_irqs(data);
709
710         clk_disable(data->clk);
711         mutex_unlock(&data->lock);
712 out:
713         enable_irq(data->irq);
714 }
715
716 static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
717 {
718         unsigned int val_irq;
719         u32 tmu_intstat, tmu_intclear;
720
721         if (data->soc == SOC_ARCH_EXYNOS5260) {
722                 tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
723                 tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
724         } else {
725                 tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
726                 tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
727         }
728
729         val_irq = readl(data->base + tmu_intstat);
730         /*
731          * Clear the interrupts.  Please note that the documentation for
732          * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
733          * states that INTCLEAR register has a different placing of bits
734          * responsible for FALL IRQs than INTSTAT register.  Exynos5420
735          * and Exynos5440 documentation is correct (Exynos4210 doesn't
736          * support FALL IRQs at all).
737          */
738         writel(val_irq, data->base + tmu_intclear);
739 }
740
741 static void exynos5440_tmu_clear_irqs(struct exynos_tmu_data *data)
742 {
743         unsigned int val_irq;
744
745         val_irq = readl(data->base + EXYNOS5440_TMU_S0_7_IRQ);
746         /* clear the interrupts */
747         writel(val_irq, data->base + EXYNOS5440_TMU_S0_7_IRQ);
748 }
749
750 static irqreturn_t exynos_tmu_irq(int irq, void *id)
751 {
752         struct exynos_tmu_data *data = id;
753
754         disable_irq_nosync(irq);
755         schedule_work(&data->irq_work);
756
757         return IRQ_HANDLED;
758 }
759
760 static const struct of_device_id exynos_tmu_match[] = {
761         {
762                 .compatible = "samsung,exynos3250-tmu",
763         },
764         {
765                 .compatible = "samsung,exynos4210-tmu",
766         },
767         {
768                 .compatible = "samsung,exynos4412-tmu",
769         },
770         {
771                 .compatible = "samsung,exynos5250-tmu",
772         },
773         {
774                 .compatible = "samsung,exynos5260-tmu",
775         },
776         {
777                 .compatible = "samsung,exynos5420-tmu",
778         },
779         {
780                 .compatible = "samsung,exynos5420-tmu-ext-triminfo",
781         },
782         {
783                 .compatible = "samsung,exynos5440-tmu",
784         },
785         {},
786 };
787 MODULE_DEVICE_TABLE(of, exynos_tmu_match);
788
789 static int exynos_of_get_soc_type(struct device_node *np)
790 {
791         if (of_device_is_compatible(np, "samsung,exynos3250-tmu"))
792                 return SOC_ARCH_EXYNOS3250;
793         else if (of_device_is_compatible(np, "samsung,exynos4210-tmu"))
794                 return SOC_ARCH_EXYNOS4210;
795         else if (of_device_is_compatible(np, "samsung,exynos4412-tmu"))
796                 return SOC_ARCH_EXYNOS4412;
797         else if (of_device_is_compatible(np, "samsung,exynos5250-tmu"))
798                 return SOC_ARCH_EXYNOS5250;
799         else if (of_device_is_compatible(np, "samsung,exynos5260-tmu"))
800                 return SOC_ARCH_EXYNOS5260;
801         else if (of_device_is_compatible(np, "samsung,exynos5420-tmu"))
802                 return SOC_ARCH_EXYNOS5420;
803         else if (of_device_is_compatible(np,
804                                          "samsung,exynos5420-tmu-ext-triminfo"))
805                 return SOC_ARCH_EXYNOS5420_TRIMINFO;
806         else if (of_device_is_compatible(np, "samsung,exynos5440-tmu"))
807                 return SOC_ARCH_EXYNOS5440;
808
809         return -EINVAL;
810 }
811
812 static int exynos_of_sensor_conf(struct device_node *np,
813                                  struct exynos_tmu_platform_data *pdata)
814 {
815         u32 value;
816         int ret;
817
818         of_node_get(np);
819
820         ret = of_property_read_u32(np, "samsung,tmu_gain", &value);
821         pdata->gain = (u8)value;
822         of_property_read_u32(np, "samsung,tmu_reference_voltage", &value);
823         pdata->reference_voltage = (u8)value;
824         of_property_read_u32(np, "samsung,tmu_noise_cancel_mode", &value);
825         pdata->noise_cancel_mode = (u8)value;
826
827         of_property_read_u32(np, "samsung,tmu_efuse_value",
828                              &pdata->efuse_value);
829         of_property_read_u32(np, "samsung,tmu_min_efuse_value",
830                              &pdata->min_efuse_value);
831         of_property_read_u32(np, "samsung,tmu_max_efuse_value",
832                              &pdata->max_efuse_value);
833
834         of_property_read_u32(np, "samsung,tmu_first_point_trim", &value);
835         pdata->first_point_trim = (u8)value;
836         of_property_read_u32(np, "samsung,tmu_second_point_trim", &value);
837         pdata->second_point_trim = (u8)value;
838         of_property_read_u32(np, "samsung,tmu_default_temp_offset", &value);
839         pdata->default_temp_offset = (u8)value;
840
841         of_property_read_u32(np, "samsung,tmu_cal_type", &pdata->cal_type);
842         of_property_read_u32(np, "samsung,tmu_cal_mode", &pdata->cal_mode);
843
844         of_node_put(np);
845         return 0;
846 }
847
848 static int exynos_map_dt_data(struct platform_device *pdev)
849 {
850         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
851         struct exynos_tmu_platform_data *pdata;
852         struct resource res;
853         int ret;
854
855         if (!data || !pdev->dev.of_node)
856                 return -ENODEV;
857
858         /*
859          * Try enabling the regulator if found
860          * TODO: Add regulator as an SOC feature, so that regulator enable
861          * is a compulsory call.
862          */
863         data->regulator = devm_regulator_get(&pdev->dev, "vtmu");
864         if (!IS_ERR(data->regulator)) {
865                 ret = regulator_enable(data->regulator);
866                 if (ret) {
867                         dev_err(&pdev->dev, "failed to enable vtmu\n");
868                         return ret;
869                 }
870         } else {
871                 dev_info(&pdev->dev, "Regulator node (vtmu) not found\n");
872         }
873
874         data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
875         if (data->id < 0)
876                 data->id = 0;
877
878         data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
879         if (data->irq <= 0) {
880                 dev_err(&pdev->dev, "failed to get IRQ\n");
881                 return -ENODEV;
882         }
883
884         if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
885                 dev_err(&pdev->dev, "failed to get Resource 0\n");
886                 return -ENODEV;
887         }
888
889         data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
890         if (!data->base) {
891                 dev_err(&pdev->dev, "Failed to ioremap memory\n");
892                 return -EADDRNOTAVAIL;
893         }
894
895         pdata = devm_kzalloc(&pdev->dev,
896                              sizeof(struct exynos_tmu_platform_data),
897                              GFP_KERNEL);
898         if (!pdata)
899                 return -ENOMEM;
900
901         exynos_of_sensor_conf(pdev->dev.of_node, pdata);
902         data->pdata = pdata;
903         data->soc = exynos_of_get_soc_type(pdev->dev.of_node);
904
905         switch (data->soc) {
906         case SOC_ARCH_EXYNOS4210:
907                 data->tmu_initialize = exynos4210_tmu_initialize;
908                 data->tmu_control = exynos4210_tmu_control;
909                 data->tmu_read = exynos4210_tmu_read;
910                 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
911                 break;
912         case SOC_ARCH_EXYNOS3250:
913         case SOC_ARCH_EXYNOS4412:
914         case SOC_ARCH_EXYNOS5250:
915         case SOC_ARCH_EXYNOS5260:
916         case SOC_ARCH_EXYNOS5420:
917         case SOC_ARCH_EXYNOS5420_TRIMINFO:
918                 data->tmu_initialize = exynos4412_tmu_initialize;
919                 data->tmu_control = exynos4210_tmu_control;
920                 data->tmu_read = exynos4412_tmu_read;
921                 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
922                 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
923                 break;
924         case SOC_ARCH_EXYNOS5440:
925                 data->tmu_initialize = exynos5440_tmu_initialize;
926                 data->tmu_control = exynos5440_tmu_control;
927                 data->tmu_read = exynos5440_tmu_read;
928                 data->tmu_set_emulation = exynos5440_tmu_set_emulation;
929                 data->tmu_clear_irqs = exynos5440_tmu_clear_irqs;
930                 break;
931         default:
932                 dev_err(&pdev->dev, "Platform not supported\n");
933                 return -EINVAL;
934         }
935
936         /*
937          * Check if the TMU shares some registers and then try to map the
938          * memory of common registers.
939          */
940         if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO &&
941             data->soc != SOC_ARCH_EXYNOS5440)
942                 return 0;
943
944         if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
945                 dev_err(&pdev->dev, "failed to get Resource 1\n");
946                 return -ENODEV;
947         }
948
949         data->base_second = devm_ioremap(&pdev->dev, res.start,
950                                         resource_size(&res));
951         if (!data->base_second) {
952                 dev_err(&pdev->dev, "Failed to ioremap memory\n");
953                 return -ENOMEM;
954         }
955
956         return 0;
957 }
958
959 static struct thermal_zone_of_device_ops exynos_sensor_ops = {
960         .get_temp = exynos_get_temp,
961         .set_emul_temp = exynos_tmu_set_emulation,
962 };
963
964 static int exynos_tmu_probe(struct platform_device *pdev)
965 {
966         struct exynos_tmu_platform_data *pdata;
967         struct exynos_tmu_data *data;
968         int ret;
969
970         data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
971                                         GFP_KERNEL);
972         if (!data)
973                 return -ENOMEM;
974
975         platform_set_drvdata(pdev, data);
976         mutex_init(&data->lock);
977
978         data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
979                                                     &exynos_sensor_ops);
980         if (IS_ERR(data->tzd)) {
981                 pr_err("thermal: tz: %p ERROR\n", data->tzd);
982                 return PTR_ERR(data->tzd);
983         }
984         ret = exynos_map_dt_data(pdev);
985         if (ret)
986                 goto err_sensor;
987
988         pdata = data->pdata;
989
990         INIT_WORK(&data->irq_work, exynos_tmu_work);
991
992         data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
993         if (IS_ERR(data->clk)) {
994                 dev_err(&pdev->dev, "Failed to get clock\n");
995                 ret = PTR_ERR(data->clk);
996                 goto err_sensor;
997         }
998
999         data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif");
1000         if (IS_ERR(data->clk_sec)) {
1001                 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
1002                         dev_err(&pdev->dev, "Failed to get triminfo clock\n");
1003                         ret = PTR_ERR(data->clk_sec);
1004                         goto err_sensor;
1005                 }
1006         } else {
1007                 ret = clk_prepare(data->clk_sec);
1008                 if (ret) {
1009                         dev_err(&pdev->dev, "Failed to get clock\n");
1010                         goto err_sensor;
1011                 }
1012         }
1013
1014         ret = clk_prepare(data->clk);
1015         if (ret) {
1016                 dev_err(&pdev->dev, "Failed to get clock\n");
1017                 goto err_clk_sec;
1018         }
1019
1020         ret = exynos_tmu_initialize(pdev);
1021         if (ret) {
1022                 dev_err(&pdev->dev, "Failed to initialize TMU\n");
1023                 goto err_clk;
1024         }
1025
1026         ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
1027                 IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
1028         if (ret) {
1029                 dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
1030                 goto err_clk;
1031         }
1032
1033         exynos_tmu_control(pdev, true);
1034         return 0;
1035 err_clk:
1036         clk_unprepare(data->clk);
1037 err_clk_sec:
1038         if (!IS_ERR(data->clk_sec))
1039                 clk_unprepare(data->clk_sec);
1040 err_sensor:
1041         thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd);
1042
1043         return ret;
1044 }
1045
1046 static int exynos_tmu_remove(struct platform_device *pdev)
1047 {
1048         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
1049         struct thermal_zone_device *tzd = data->tzd;
1050
1051         thermal_zone_of_sensor_unregister(&pdev->dev, tzd);
1052         exynos_tmu_control(pdev, false);
1053
1054         clk_unprepare(data->clk);
1055         if (!IS_ERR(data->clk_sec))
1056                 clk_unprepare(data->clk_sec);
1057
1058         if (!IS_ERR(data->regulator))
1059                 regulator_disable(data->regulator);
1060
1061         return 0;
1062 }
1063
1064 #ifdef CONFIG_PM_SLEEP
1065 static int exynos_tmu_suspend(struct device *dev)
1066 {
1067         exynos_tmu_control(to_platform_device(dev), false);
1068
1069         return 0;
1070 }
1071
1072 static int exynos_tmu_resume(struct device *dev)
1073 {
1074         struct platform_device *pdev = to_platform_device(dev);
1075
1076         exynos_tmu_initialize(pdev);
1077         exynos_tmu_control(pdev, true);
1078
1079         return 0;
1080 }
1081
1082 static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
1083                          exynos_tmu_suspend, exynos_tmu_resume);
1084 #define EXYNOS_TMU_PM   (&exynos_tmu_pm)
1085 #else
1086 #define EXYNOS_TMU_PM   NULL
1087 #endif
1088
1089 static struct platform_driver exynos_tmu_driver = {
1090         .driver = {
1091                 .name   = "exynos-tmu",
1092                 .pm     = EXYNOS_TMU_PM,
1093                 .of_match_table = exynos_tmu_match,
1094         },
1095         .probe = exynos_tmu_probe,
1096         .remove = exynos_tmu_remove,
1097 };
1098
1099 module_platform_driver(exynos_tmu_driver);
1100
1101 MODULE_DESCRIPTION("EXYNOS TMU Driver");
1102 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
1103 MODULE_LICENSE("GPL");
1104 MODULE_ALIAS("platform:exynos-tmu");