1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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_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
38#include <dt-bindings/thermal/thermal_exynos.h>
39
40#include "../thermal_core.h"
41
42
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
48#define EXYNOS_TMU_REG_INTSTAT 0x74
49#define EXYNOS_TMU_REG_INTCLEAR 0x78
50
51#define EXYNOS_TMU_TEMP_MASK 0xff
52#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24
53#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f
54#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
55#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8
56#define EXYNOS_TMU_CORE_EN_SHIFT 0
57
58
59#define EXYNOS_TMU_TRIMINFO_CON1 0x10
60
61
62#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44
63#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50
64
65
66#define EXYNOS_TMU_TRIMINFO_CON2 0x14
67#define EXYNOS_THD_TEMP_RISE 0x50
68#define EXYNOS_THD_TEMP_FALL 0x54
69#define EXYNOS_EMUL_CON 0x80
70
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
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
87
88
89#define EXYNOS5260_TMU_REG_INTEN 0xC0
90#define EXYNOS5260_TMU_REG_INTSTAT 0xC4
91#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8
92#define EXYNOS5260_EMUL_CON 0x100
93
94
95#define EXYNOS4412_MUX_ADDR_VALUE 6
96#define EXYNOS4412_MUX_ADDR_SHIFT 20
97
98
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
107
108#define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT 16
109#define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT 23
110#define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK \
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
119#define EXYNOS5433_G3D_BASE 0x10070000
120
121
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
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
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187struct exynos_tmu_data {
188 int id;
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;
200 u16 temp_error1, temp_error2;
201 u8 gain;
202 u8 reference_voltage;
203 struct regulator *regulator;
204 struct thermal_zone_device *tzd;
205 unsigned int ntrip;
206 bool enabled;
207
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);
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
219
220
221
222
223static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
224{
225 if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
226 return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM;
227
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;
232}
233
234
235
236
237
238static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code)
239{
240 if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
241 return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM;
242
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;
247}
248
249static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
250{
251 u16 tmu_temp_mask =
252 (data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
253 : EXYNOS_TMU_TEMP_MASK;
254
255 data->temp_error1 = trim_info & tmu_temp_mask;
256 data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
257 EXYNOS_TMU_TEMP_MASK);
258
259 if (!data->temp_error1 ||
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;
263
264 if (!data->temp_error2)
265 data->temp_error2 =
266 (data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
267 EXYNOS_TMU_TEMP_MASK;
268}
269
270static int exynos_tmu_initialize(struct platform_device *pdev)
271{
272 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
273 struct thermal_zone_device *tzd = data->tzd;
274 const struct thermal_trip * const trips =
275 of_thermal_get_trip_points(tzd);
276 unsigned int status;
277 int ret = 0, temp, hyst;
278
279 if (!trips) {
280 dev_err(&pdev->dev,
281 "Cannot get trip points from device tree!\n");
282 return -ENODEV;
283 }
284
285 if (data->soc != SOC_ARCH_EXYNOS5433)
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;
291 }
292
293 if (of_thermal_get_ntrips(tzd) > data->ntrip) {
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",
298 (of_thermal_get_ntrips(tzd) - data->ntrip));
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);
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
316 for (i = 0; i < ntrips; i++) {
317
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
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:
335 clk_disable(data->clk);
336 mutex_unlock(&data->lock);
337 if (!IS_ERR(data->clk_sec))
338 clk_disable(data->clk_sec);
339out:
340 return ret;
341}
342
343static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
344{
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);
350 con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
351
352 con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
353 con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
354
355 con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT);
356 con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT);
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
373static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data,
374 int trip, u8 temp)
375{
376 const struct thermal_trip * const trips =
377 of_thermal_get_trip_points(data->tzd);
378 u8 ref, th_code;
379
380 ref = trips[0].temperature / MCELSIUS;
381
382 if (trip == 0) {
383 th_code = temp_to_code(data, ref);
384 writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
385 }
386
387 temp -= ref;
388 writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip * 4);
389}
390
391
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
401 sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO));
402}
403
404static void exynos4412_tmu_set_trip_temp(struct exynos_tmu_data *data,
405 int trip, u8 temp)
406{
407 u32 th, con;
408
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);
418 }
419}
420
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);
431}
432
433static void exynos4412_tmu_initialize(struct platform_device *pdev)
434{
435 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
436 unsigned int trim_info, ctrl;
437
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 }
446 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
447 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
448 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
449 }
450
451
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}
459
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;
465
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;
472 }
473
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}
479
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;
485
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);
498}
499
500static void exynos5433_tmu_initialize(struct platform_device *pdev)
501{
502 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
503 unsigned int trim_info;
504 int sensor_id, cal_type;
505
506 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
507 sanitize_temp_error(data, trim_info);
508
509
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
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) {
520 case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
521 data->cal_type = TYPE_TWO_POINT_TRIMMING;
522 break;
523 case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
524 default:
525 data->cal_type = TYPE_ONE_POINT_TRIMMING;
526 break;
527 }
528
529 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n",
530 cal_type ? 2 : 1);
531}
532
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;
538
539 reg_off = ((7 - trip) / 2) * 4;
540 bit_off = ((8 - trip) % 2);
541
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);
546}
547
548static void exynos7_tmu_set_trip_hyst(struct exynos_tmu_data *data,
549 int trip, u8 temp, u8 hyst)
550{
551 unsigned int reg_off, bit_off;
552 u32 th;
553
554 reg_off = ((7 - trip) / 2) * 4;
555 bit_off = ((8 - trip) % 2);
556
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);
561}
562
563static void exynos7_tmu_initialize(struct platform_device *pdev)
564{
565 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
566 unsigned int trim_info;
567
568 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
569 sanitize_temp_error(data, trim_info);
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;
576 unsigned int con, interrupt_en = 0, i;
577
578 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
579
580 if (on) {
581 for (i = 0; i < data->ntrip; i++) {
582 if (!of_thermal_is_trip_valid(tz, i))
583 continue;
584
585 interrupt_en |=
586 (1 << (EXYNOS_TMU_INTEN_RISE0_SHIFT + i * 4));
587 }
588
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);
594 } else {
595 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
596 }
597
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;
606 unsigned int con, interrupt_en = 0, pd_det_en, i;
607
608 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
609
610 if (on) {
611 for (i = 0; i < data->ntrip; i++) {
612 if (!of_thermal_is_trip_valid(tz, i))
613 continue;
614
615 interrupt_en |=
616 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i));
617 }
618
619 interrupt_en |=
620 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
621
622 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
623 } else
624 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
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
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;
637 unsigned int con, interrupt_en = 0, i;
638
639 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
640
641 if (on) {
642 for (i = 0; i < data->ntrip; i++) {
643 if (!of_thermal_is_trip_valid(tz, i))
644 continue;
645
646 interrupt_en |=
647 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i));
648 }
649
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);
655 } else {
656 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
657 con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT);
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
669 if (!data || !data->tmu_read || !data->enabled)
670 return -EINVAL;
671 else if (!data->enabled)
672
673
674
675
676 return -EAGAIN;
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
685 *temp = code_to_temp(data, value) * MCELSIUS;
686
687 clk_disable(data->clk);
688 mutex_unlock(&data->lock);
689
690 return ret;
691}
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
700 val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
701 val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
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 <<
710 EXYNOS_EMUL_DATA_SHIFT);
711 val |= (temp_to_code(data, temp) <<
712 EXYNOS_EMUL_DATA_SHIFT) |
713 EXYNOS_EMUL_ENABLE;
714 }
715 } else {
716 val &= ~EXYNOS_EMUL_ENABLE;
717 }
718
719 return val;
720}
721
722static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
723 int temp)
724{
725 unsigned int val;
726 u32 emul_con;
727
728 if (data->soc == SOC_ARCH_EXYNOS5260)
729 emul_con = EXYNOS5260_EMUL_CON;
730 else if (data->soc == SOC_ARCH_EXYNOS5433)
731 emul_con = EXYNOS5433_TMU_EMUL_CON;
732 else if (data->soc == SOC_ARCH_EXYNOS7)
733 emul_con = EXYNOS7_TMU_REG_EMUL_CON;
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
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
750 if (temp && temp < MCELSIUS)
751 goto out;
752
753 mutex_lock(&data->lock);
754 clk_enable(data->clk);
755 data->tmu_set_emulation(data, temp);
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
764static int exynos_tmu_set_emulation(void *drv_data, int temp)
765 { return -EINVAL; }
766#endif
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
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
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);
791
792 thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED);
793
794 mutex_lock(&data->lock);
795 clk_enable(data->clk);
796
797
798 data->tmu_clear_irqs(data);
799
800 clk_disable(data->clk);
801 mutex_unlock(&data->lock);
802 enable_irq(data->irq);
803}
804
805static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
806{
807 unsigned int val_irq;
808 u32 tmu_intstat, tmu_intclear;
809
810 if (data->soc == SOC_ARCH_EXYNOS5260) {
811 tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
812 tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
813 } else if (data->soc == SOC_ARCH_EXYNOS7) {
814 tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
815 tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
816 } else if (data->soc == SOC_ARCH_EXYNOS5433) {
817 tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
818 tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
819 } else {
820 tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
821 tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
822 }
823
824 val_irq = readl(data->base + tmu_intstat);
825
826
827
828
829
830
831
832
833 writel(val_irq, data->base + tmu_intclear);
834}
835
836static irqreturn_t exynos_tmu_irq(int irq, void *id)
837{
838 struct exynos_tmu_data *data = id;
839
840 disable_irq_nosync(irq);
841 schedule_work(&data->irq_work);
842
843 return IRQ_HANDLED;
844}
845
846static const struct of_device_id exynos_tmu_match[] = {
847 {
848 .compatible = "samsung,exynos3250-tmu",
849 .data = (const void *)SOC_ARCH_EXYNOS3250,
850 }, {
851 .compatible = "samsung,exynos4210-tmu",
852 .data = (const void *)SOC_ARCH_EXYNOS4210,
853 }, {
854 .compatible = "samsung,exynos4412-tmu",
855 .data = (const void *)SOC_ARCH_EXYNOS4412,
856 }, {
857 .compatible = "samsung,exynos5250-tmu",
858 .data = (const void *)SOC_ARCH_EXYNOS5250,
859 }, {
860 .compatible = "samsung,exynos5260-tmu",
861 .data = (const void *)SOC_ARCH_EXYNOS5260,
862 }, {
863 .compatible = "samsung,exynos5420-tmu",
864 .data = (const void *)SOC_ARCH_EXYNOS5420,
865 }, {
866 .compatible = "samsung,exynos5420-tmu-ext-triminfo",
867 .data = (const void *)SOC_ARCH_EXYNOS5420_TRIMINFO,
868 }, {
869 .compatible = "samsung,exynos5433-tmu",
870 .data = (const void *)SOC_ARCH_EXYNOS5433,
871 }, {
872 .compatible = "samsung,exynos7-tmu",
873 .data = (const void *)SOC_ARCH_EXYNOS7,
874 },
875 { },
876};
877MODULE_DEVICE_TABLE(of, exynos_tmu_match);
878
879static int exynos_map_dt_data(struct platform_device *pdev)
880{
881 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
882 struct resource res;
883
884 if (!data || !pdev->dev.of_node)
885 return -ENODEV;
886
887 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
888 if (data->id < 0)
889 data->id = 0;
890
891 data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
892 if (data->irq <= 0) {
893 dev_err(&pdev->dev, "failed to get IRQ\n");
894 return -ENODEV;
895 }
896
897 if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
898 dev_err(&pdev->dev, "failed to get Resource 0\n");
899 return -ENODEV;
900 }
901
902 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
903 if (!data->base) {
904 dev_err(&pdev->dev, "Failed to ioremap memory\n");
905 return -EADDRNOTAVAIL;
906 }
907
908 data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev);
909
910 switch (data->soc) {
911 case SOC_ARCH_EXYNOS4210:
912 data->tmu_set_trip_temp = exynos4210_tmu_set_trip_temp;
913 data->tmu_set_trip_hyst = exynos4210_tmu_set_trip_hyst;
914 data->tmu_initialize = exynos4210_tmu_initialize;
915 data->tmu_control = exynos4210_tmu_control;
916 data->tmu_read = exynos4210_tmu_read;
917 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
918 data->ntrip = 4;
919 data->gain = 15;
920 data->reference_voltage = 7;
921 data->efuse_value = 55;
922 data->min_efuse_value = 40;
923 data->max_efuse_value = 100;
924 break;
925 case SOC_ARCH_EXYNOS3250:
926 case SOC_ARCH_EXYNOS4412:
927 case SOC_ARCH_EXYNOS5250:
928 case SOC_ARCH_EXYNOS5260:
929 case SOC_ARCH_EXYNOS5420:
930 case SOC_ARCH_EXYNOS5420_TRIMINFO:
931 data->tmu_set_trip_temp = exynos4412_tmu_set_trip_temp;
932 data->tmu_set_trip_hyst = exynos4412_tmu_set_trip_hyst;
933 data->tmu_initialize = exynos4412_tmu_initialize;
934 data->tmu_control = exynos4210_tmu_control;
935 data->tmu_read = exynos4412_tmu_read;
936 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
937 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
938 data->ntrip = 4;
939 data->gain = 8;
940 data->reference_voltage = 16;
941 data->efuse_value = 55;
942 if (data->soc != SOC_ARCH_EXYNOS5420 &&
943 data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
944 data->min_efuse_value = 40;
945 else
946 data->min_efuse_value = 0;
947 data->max_efuse_value = 100;
948 break;
949 case SOC_ARCH_EXYNOS5433:
950 data->tmu_set_trip_temp = exynos5433_tmu_set_trip_temp;
951 data->tmu_set_trip_hyst = exynos5433_tmu_set_trip_hyst;
952 data->tmu_initialize = exynos5433_tmu_initialize;
953 data->tmu_control = exynos5433_tmu_control;
954 data->tmu_read = exynos4412_tmu_read;
955 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
956 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
957 data->ntrip = 8;
958 data->gain = 8;
959 if (res.start == EXYNOS5433_G3D_BASE)
960 data->reference_voltage = 23;
961 else
962 data->reference_voltage = 16;
963 data->efuse_value = 75;
964 data->min_efuse_value = 40;
965 data->max_efuse_value = 150;
966 break;
967 case SOC_ARCH_EXYNOS7:
968 data->tmu_set_trip_temp = exynos7_tmu_set_trip_temp;
969 data->tmu_set_trip_hyst = exynos7_tmu_set_trip_hyst;
970 data->tmu_initialize = exynos7_tmu_initialize;
971 data->tmu_control = exynos7_tmu_control;
972 data->tmu_read = exynos7_tmu_read;
973 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
974 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
975 data->ntrip = 8;
976 data->gain = 9;
977 data->reference_voltage = 17;
978 data->efuse_value = 75;
979 data->min_efuse_value = 15;
980 data->max_efuse_value = 100;
981 break;
982 default:
983 dev_err(&pdev->dev, "Platform not supported\n");
984 return -EINVAL;
985 }
986
987 data->cal_type = TYPE_ONE_POINT_TRIMMING;
988
989
990
991
992
993 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
994 return 0;
995
996 if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
997 dev_err(&pdev->dev, "failed to get Resource 1\n");
998 return -ENODEV;
999 }
1000
1001 data->base_second = devm_ioremap(&pdev->dev, res.start,
1002 resource_size(&res));
1003 if (!data->base_second) {
1004 dev_err(&pdev->dev, "Failed to ioremap memory\n");
1005 return -ENOMEM;
1006 }
1007
1008 return 0;
1009}
1010
1011static const struct thermal_zone_of_device_ops exynos_sensor_ops = {
1012 .get_temp = exynos_get_temp,
1013 .set_emul_temp = exynos_tmu_set_emulation,
1014};
1015
1016static int exynos_tmu_probe(struct platform_device *pdev)
1017{
1018 struct exynos_tmu_data *data;
1019 int ret;
1020
1021 data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
1022 GFP_KERNEL);
1023 if (!data)
1024 return -ENOMEM;
1025
1026 platform_set_drvdata(pdev, data);
1027 mutex_init(&data->lock);
1028
1029
1030
1031
1032
1033
1034 data->regulator = devm_regulator_get_optional(&pdev->dev, "vtmu");
1035 if (!IS_ERR(data->regulator)) {
1036 ret = regulator_enable(data->regulator);
1037 if (ret) {
1038 dev_err(&pdev->dev, "failed to enable vtmu\n");
1039 return ret;
1040 }
1041 } else {
1042 if (PTR_ERR(data->regulator) == -EPROBE_DEFER)
1043 return -EPROBE_DEFER;
1044 dev_info(&pdev->dev, "Regulator node (vtmu) not found\n");
1045 }
1046
1047 ret = exynos_map_dt_data(pdev);
1048 if (ret)
1049 goto err_sensor;
1050
1051 INIT_WORK(&data->irq_work, exynos_tmu_work);
1052
1053 data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
1054 if (IS_ERR(data->clk)) {
1055 dev_err(&pdev->dev, "Failed to get clock\n");
1056 ret = PTR_ERR(data->clk);
1057 goto err_sensor;
1058 }
1059
1060 data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif");
1061 if (IS_ERR(data->clk_sec)) {
1062 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
1063 dev_err(&pdev->dev, "Failed to get triminfo clock\n");
1064 ret = PTR_ERR(data->clk_sec);
1065 goto err_sensor;
1066 }
1067 } else {
1068 ret = clk_prepare(data->clk_sec);
1069 if (ret) {
1070 dev_err(&pdev->dev, "Failed to get clock\n");
1071 goto err_sensor;
1072 }
1073 }
1074
1075 ret = clk_prepare(data->clk);
1076 if (ret) {
1077 dev_err(&pdev->dev, "Failed to get clock\n");
1078 goto err_clk_sec;
1079 }
1080
1081 switch (data->soc) {
1082 case SOC_ARCH_EXYNOS5433:
1083 case SOC_ARCH_EXYNOS7:
1084 data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk");
1085 if (IS_ERR(data->sclk)) {
1086 dev_err(&pdev->dev, "Failed to get sclk\n");
1087 goto err_clk;
1088 } else {
1089 ret = clk_prepare_enable(data->sclk);
1090 if (ret) {
1091 dev_err(&pdev->dev, "Failed to enable sclk\n");
1092 goto err_clk;
1093 }
1094 }
1095 break;
1096 default:
1097 break;
1098 }
1099
1100
1101
1102
1103
1104 data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
1105 &exynos_sensor_ops);
1106 if (IS_ERR(data->tzd)) {
1107 ret = PTR_ERR(data->tzd);
1108 dev_err(&pdev->dev, "Failed to register sensor: %d\n", ret);
1109 goto err_sclk;
1110 }
1111
1112 ret = exynos_tmu_initialize(pdev);
1113 if (ret) {
1114 dev_err(&pdev->dev, "Failed to initialize TMU\n");
1115 goto err_thermal;
1116 }
1117
1118 ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
1119 IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
1120 if (ret) {
1121 dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
1122 goto err_thermal;
1123 }
1124
1125 exynos_tmu_control(pdev, true);
1126 return 0;
1127
1128err_thermal:
1129 thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd);
1130err_sclk:
1131 clk_disable_unprepare(data->sclk);
1132err_clk:
1133 clk_unprepare(data->clk);
1134err_clk_sec:
1135 if (!IS_ERR(data->clk_sec))
1136 clk_unprepare(data->clk_sec);
1137err_sensor:
1138 if (!IS_ERR(data->regulator))
1139 regulator_disable(data->regulator);
1140
1141 return ret;
1142}
1143
1144static int exynos_tmu_remove(struct platform_device *pdev)
1145{
1146 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
1147 struct thermal_zone_device *tzd = data->tzd;
1148
1149 thermal_zone_of_sensor_unregister(&pdev->dev, tzd);
1150 exynos_tmu_control(pdev, false);
1151
1152 clk_disable_unprepare(data->sclk);
1153 clk_unprepare(data->clk);
1154 if (!IS_ERR(data->clk_sec))
1155 clk_unprepare(data->clk_sec);
1156
1157 if (!IS_ERR(data->regulator))
1158 regulator_disable(data->regulator);
1159
1160 return 0;
1161}
1162
1163#ifdef CONFIG_PM_SLEEP
1164static int exynos_tmu_suspend(struct device *dev)
1165{
1166 exynos_tmu_control(to_platform_device(dev), false);
1167
1168 return 0;
1169}
1170
1171static int exynos_tmu_resume(struct device *dev)
1172{
1173 struct platform_device *pdev = to_platform_device(dev);
1174
1175 exynos_tmu_initialize(pdev);
1176 exynos_tmu_control(pdev, true);
1177
1178 return 0;
1179}
1180
1181static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
1182 exynos_tmu_suspend, exynos_tmu_resume);
1183#define EXYNOS_TMU_PM (&exynos_tmu_pm)
1184#else
1185#define EXYNOS_TMU_PM NULL
1186#endif
1187
1188static struct platform_driver exynos_tmu_driver = {
1189 .driver = {
1190 .name = "exynos-tmu",
1191 .pm = EXYNOS_TMU_PM,
1192 .of_match_table = exynos_tmu_match,
1193 },
1194 .probe = exynos_tmu_probe,
1195 .remove = exynos_tmu_remove,
1196};
1197
1198module_platform_driver(exynos_tmu_driver);
1199
1200MODULE_DESCRIPTION("EXYNOS TMU Driver");
1201MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
1202MODULE_LICENSE("GPL");
1203MODULE_ALIAS("platform:exynos-tmu");
1204