1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/clk.h>
15#include <linux/io.h>
16#include <linux/interrupt.h>
17#include <linux/module.h>
18#include <linux/of_device.h>
19#include <linux/of_address.h>
20#include <linux/of_irq.h>
21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
23
24#include <dt-bindings/thermal/thermal_exynos.h>
25
26#include "../thermal_core.h"
27
28
29#define EXYNOS_TMU_REG_TRIMINFO 0x0
30#define EXYNOS_TMU_REG_CONTROL 0x20
31#define EXYNOS_TMU_REG_STATUS 0x28
32#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40
33#define EXYNOS_TMU_REG_INTEN 0x70
34#define EXYNOS_TMU_REG_INTSTAT 0x74
35#define EXYNOS_TMU_REG_INTCLEAR 0x78
36
37#define EXYNOS_TMU_TEMP_MASK 0xff
38#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24
39#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f
40#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
41#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8
42#define EXYNOS_TMU_CORE_EN_SHIFT 0
43
44
45#define EXYNOS_TMU_TRIMINFO_CON1 0x10
46
47
48#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44
49#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50
50
51
52#define EXYNOS_TMU_TRIMINFO_CON2 0x14
53#define EXYNOS_THD_TEMP_RISE 0x50
54#define EXYNOS_THD_TEMP_FALL 0x54
55#define EXYNOS_EMUL_CON 0x80
56
57#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1
58#define EXYNOS_TRIMINFO_25_SHIFT 0
59#define EXYNOS_TRIMINFO_85_SHIFT 8
60#define EXYNOS_TMU_TRIP_MODE_SHIFT 13
61#define EXYNOS_TMU_TRIP_MODE_MASK 0x7
62#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12
63
64#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0
65#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16
66
67#define EXYNOS_EMUL_TIME 0x57F0
68#define EXYNOS_EMUL_TIME_MASK 0xffff
69#define EXYNOS_EMUL_TIME_SHIFT 16
70#define EXYNOS_EMUL_DATA_SHIFT 8
71#define EXYNOS_EMUL_DATA_MASK 0xFF
72#define EXYNOS_EMUL_ENABLE 0x1
73
74
75#define EXYNOS5260_TMU_REG_INTEN 0xC0
76#define EXYNOS5260_TMU_REG_INTSTAT 0xC4
77#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8
78#define EXYNOS5260_EMUL_CON 0x100
79
80
81#define EXYNOS4412_MUX_ADDR_VALUE 6
82#define EXYNOS4412_MUX_ADDR_SHIFT 20
83
84
85#define EXYNOS5433_THD_TEMP_RISE3_0 0x050
86#define EXYNOS5433_THD_TEMP_RISE7_4 0x054
87#define EXYNOS5433_THD_TEMP_FALL3_0 0x060
88#define EXYNOS5433_THD_TEMP_FALL7_4 0x064
89#define EXYNOS5433_TMU_REG_INTEN 0x0c0
90#define EXYNOS5433_TMU_REG_INTPEND 0x0c8
91#define EXYNOS5433_TMU_EMUL_CON 0x110
92#define EXYNOS5433_TMU_PD_DET_EN 0x130
93
94#define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT 16
95#define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT 23
96#define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK \
97 (0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT)
98#define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK BIT(23)
99
100#define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING 0
101#define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING 1
102
103#define EXYNOS5433_PD_DET_EN 1
104
105#define EXYNOS5433_G3D_BASE 0x10070000
106
107
108#define EXYNOS7_THD_TEMP_RISE7_6 0x50
109#define EXYNOS7_THD_TEMP_FALL7_6 0x60
110#define EXYNOS7_TMU_REG_INTEN 0x110
111#define EXYNOS7_TMU_REG_INTPEND 0x118
112#define EXYNOS7_TMU_REG_EMUL_CON 0x160
113
114#define EXYNOS7_TMU_TEMP_MASK 0x1ff
115#define EXYNOS7_PD_DET_EN_SHIFT 23
116#define EXYNOS7_TMU_INTEN_RISE0_SHIFT 0
117#define EXYNOS7_EMUL_DATA_SHIFT 7
118#define EXYNOS7_EMUL_DATA_MASK 0x1ff
119
120#define EXYNOS_FIRST_POINT_TRIM 25
121#define EXYNOS_SECOND_POINT_TRIM 85
122
123#define EXYNOS_NOISE_CANCEL_MODE 4
124
125#define MCELSIUS 1000
126
127enum soc_type {
128 SOC_ARCH_EXYNOS3250 = 1,
129 SOC_ARCH_EXYNOS4210,
130 SOC_ARCH_EXYNOS4412,
131 SOC_ARCH_EXYNOS5250,
132 SOC_ARCH_EXYNOS5260,
133 SOC_ARCH_EXYNOS5420,
134 SOC_ARCH_EXYNOS5420_TRIMINFO,
135 SOC_ARCH_EXYNOS5433,
136 SOC_ARCH_EXYNOS7,
137};
138
139
140
141
142
143
144
145
146
147
148
149
150
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
176struct exynos_tmu_data {
177 int id;
178 void __iomem *base;
179 void __iomem *base_second;
180 int irq;
181 enum soc_type soc;
182 struct work_struct irq_work;
183 struct mutex lock;
184 struct clk *clk, *clk_sec, *sclk;
185 u32 cal_type;
186 u32 efuse_value;
187 u32 min_efuse_value;
188 u32 max_efuse_value;
189 u16 temp_error1, temp_error2;
190 u8 gain;
191 u8 reference_voltage;
192 struct regulator *regulator;
193 struct thermal_zone_device *tzd;
194 unsigned int ntrip;
195 bool enabled;
196
197 void (*tmu_set_trip_temp)(struct exynos_tmu_data *data, int trip,
198 u8 temp);
199 void (*tmu_set_trip_hyst)(struct exynos_tmu_data *data, int trip,
200 u8 temp, u8 hyst);
201 void (*tmu_initialize)(struct platform_device *pdev);
202 void (*tmu_control)(struct platform_device *pdev, bool on);
203 int (*tmu_read)(struct exynos_tmu_data *data);
204 void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp);
205 void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
206};
207
208
209
210
211
212static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
213{
214 if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
215 return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM;
216
217 return (temp - EXYNOS_FIRST_POINT_TRIM) *
218 (data->temp_error2 - data->temp_error1) /
219 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) +
220 data->temp_error1;
221}
222
223
224
225
226
227static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code)
228{
229 if (data->cal_type == TYPE_ONE_POINT_TRIMMING)
230 return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM;
231
232 return (temp_code - data->temp_error1) *
233 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) /
234 (data->temp_error2 - data->temp_error1) +
235 EXYNOS_FIRST_POINT_TRIM;
236}
237
238static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
239{
240 u16 tmu_temp_mask =
241 (data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
242 : EXYNOS_TMU_TEMP_MASK;
243
244 data->temp_error1 = trim_info & tmu_temp_mask;
245 data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
246 EXYNOS_TMU_TEMP_MASK);
247
248 if (!data->temp_error1 ||
249 (data->min_efuse_value > data->temp_error1) ||
250 (data->temp_error1 > data->max_efuse_value))
251 data->temp_error1 = data->efuse_value & EXYNOS_TMU_TEMP_MASK;
252
253 if (!data->temp_error2)
254 data->temp_error2 =
255 (data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
256 EXYNOS_TMU_TEMP_MASK;
257}
258
259static int exynos_tmu_initialize(struct platform_device *pdev)
260{
261 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
262 struct thermal_zone_device *tzd = data->tzd;
263 const struct thermal_trip * const trips =
264 of_thermal_get_trip_points(tzd);
265 unsigned int status;
266 int ret = 0, temp, hyst;
267
268 if (!trips) {
269 dev_err(&pdev->dev,
270 "Cannot get trip points from device tree!\n");
271 return -ENODEV;
272 }
273
274 if (data->soc != SOC_ARCH_EXYNOS5433)
275 ret = tzd->ops->get_crit_temp(tzd, &temp);
276 if (ret) {
277 dev_err(&pdev->dev,
278 "No CRITICAL trip point defined in device tree!\n");
279 goto out;
280 }
281
282 if (of_thermal_get_ntrips(tzd) > data->ntrip) {
283 dev_info(&pdev->dev,
284 "More trip points than supported by this TMU.\n");
285 dev_info(&pdev->dev,
286 "%d trip points should be configured in polling mode.\n",
287 (of_thermal_get_ntrips(tzd) - data->ntrip));
288 }
289
290 mutex_lock(&data->lock);
291 clk_enable(data->clk);
292 if (!IS_ERR(data->clk_sec))
293 clk_enable(data->clk_sec);
294
295 status = readb(data->base + EXYNOS_TMU_REG_STATUS);
296 if (!status) {
297 ret = -EBUSY;
298 } else {
299 int i, ntrips =
300 min_t(int, of_thermal_get_ntrips(tzd), data->ntrip);
301
302 data->tmu_initialize(pdev);
303
304
305 for (i = 0; i < ntrips; i++) {
306
307 ret = tzd->ops->get_trip_temp(tzd, i, &temp);
308 if (ret)
309 goto err;
310 temp /= MCELSIUS;
311 data->tmu_set_trip_temp(data, i, temp);
312
313
314 ret = tzd->ops->get_trip_hyst(tzd, i, &hyst);
315 if (ret)
316 goto err;
317 hyst /= MCELSIUS;
318 data->tmu_set_trip_hyst(data, i, temp, hyst);
319 }
320
321 data->tmu_clear_irqs(data);
322 }
323err:
324 clk_disable(data->clk);
325 mutex_unlock(&data->lock);
326 if (!IS_ERR(data->clk_sec))
327 clk_disable(data->clk_sec);
328out:
329 return ret;
330}
331
332static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
333{
334 if (data->soc == SOC_ARCH_EXYNOS4412 ||
335 data->soc == SOC_ARCH_EXYNOS3250)
336 con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT);
337
338 con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT);
339 con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
340
341 con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
342 con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
343
344 con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT);
345 con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT);
346
347 return con;
348}
349
350static void exynos_tmu_control(struct platform_device *pdev, bool on)
351{
352 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
353
354 mutex_lock(&data->lock);
355 clk_enable(data->clk);
356 data->tmu_control(pdev, on);
357 data->enabled = on;
358 clk_disable(data->clk);
359 mutex_unlock(&data->lock);
360}
361
362static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data,
363 int trip, u8 temp)
364{
365 const struct thermal_trip * const trips =
366 of_thermal_get_trip_points(data->tzd);
367 u8 ref, th_code;
368
369 ref = trips[0].temperature / MCELSIUS;
370
371 if (trip == 0) {
372 th_code = temp_to_code(data, ref);
373 writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
374 }
375
376 temp -= ref;
377 writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip * 4);
378}
379
380
381static void exynos4210_tmu_set_trip_hyst(struct exynos_tmu_data *data,
382 int trip, u8 temp, u8 hyst)
383{
384}
385
386static void exynos4210_tmu_initialize(struct platform_device *pdev)
387{
388 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
389
390 sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO));
391}
392
393static void exynos4412_tmu_set_trip_temp(struct exynos_tmu_data *data,
394 int trip, u8 temp)
395{
396 u32 th, con;
397
398 th = readl(data->base + EXYNOS_THD_TEMP_RISE);
399 th &= ~(0xff << 8 * trip);
400 th |= temp_to_code(data, temp) << 8 * trip;
401 writel(th, data->base + EXYNOS_THD_TEMP_RISE);
402
403 if (trip == 3) {
404 con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
405 con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
406 writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
407 }
408}
409
410static void exynos4412_tmu_set_trip_hyst(struct exynos_tmu_data *data,
411 int trip, u8 temp, u8 hyst)
412{
413 u32 th;
414
415 th = readl(data->base + EXYNOS_THD_TEMP_FALL);
416 th &= ~(0xff << 8 * trip);
417 if (hyst)
418 th |= temp_to_code(data, temp - hyst) << 8 * trip;
419 writel(th, data->base + EXYNOS_THD_TEMP_FALL);
420}
421
422static void exynos4412_tmu_initialize(struct platform_device *pdev)
423{
424 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
425 unsigned int trim_info, ctrl;
426
427 if (data->soc == SOC_ARCH_EXYNOS3250 ||
428 data->soc == SOC_ARCH_EXYNOS4412 ||
429 data->soc == SOC_ARCH_EXYNOS5250) {
430 if (data->soc == SOC_ARCH_EXYNOS3250) {
431 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
432 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
433 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
434 }
435 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
436 ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
437 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
438 }
439
440
441 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
442 trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
443 else
444 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
445
446 sanitize_temp_error(data, trim_info);
447}
448
449static void exynos5433_tmu_set_trip_temp(struct exynos_tmu_data *data,
450 int trip, u8 temp)
451{
452 unsigned int reg_off, j;
453 u32 th;
454
455 if (trip > 3) {
456 reg_off = EXYNOS5433_THD_TEMP_RISE7_4;
457 j = trip - 4;
458 } else {
459 reg_off = EXYNOS5433_THD_TEMP_RISE3_0;
460 j = trip;
461 }
462
463 th = readl(data->base + reg_off);
464 th &= ~(0xff << j * 8);
465 th |= (temp_to_code(data, temp) << j * 8);
466 writel(th, data->base + reg_off);
467}
468
469static void exynos5433_tmu_set_trip_hyst(struct exynos_tmu_data *data,
470 int trip, u8 temp, u8 hyst)
471{
472 unsigned int reg_off, j;
473 u32 th;
474
475 if (trip > 3) {
476 reg_off = EXYNOS5433_THD_TEMP_FALL7_4;
477 j = trip - 4;
478 } else {
479 reg_off = EXYNOS5433_THD_TEMP_FALL3_0;
480 j = trip;
481 }
482
483 th = readl(data->base + reg_off);
484 th &= ~(0xff << j * 8);
485 th |= (temp_to_code(data, temp - hyst) << j * 8);
486 writel(th, data->base + reg_off);
487}
488
489static void exynos5433_tmu_initialize(struct platform_device *pdev)
490{
491 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
492 unsigned int trim_info;
493 int sensor_id, cal_type;
494
495 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
496 sanitize_temp_error(data, trim_info);
497
498
499 sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK)
500 >> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT;
501 dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id);
502
503
504 writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO);
505 cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK)
506 >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT;
507
508 switch (cal_type) {
509 case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
510 data->cal_type = TYPE_TWO_POINT_TRIMMING;
511 break;
512 case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
513 default:
514 data->cal_type = TYPE_ONE_POINT_TRIMMING;
515 break;
516 }
517
518 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n",
519 cal_type ? 2 : 1);
520}
521
522static void exynos7_tmu_set_trip_temp(struct exynos_tmu_data *data,
523 int trip, u8 temp)
524{
525 unsigned int reg_off, bit_off;
526 u32 th;
527
528 reg_off = ((7 - trip) / 2) * 4;
529 bit_off = ((8 - trip) % 2);
530
531 th = readl(data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
532 th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off));
533 th |= temp_to_code(data, temp) << (16 * bit_off);
534 writel(th, data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
535}
536
537static void exynos7_tmu_set_trip_hyst(struct exynos_tmu_data *data,
538 int trip, u8 temp, u8 hyst)
539{
540 unsigned int reg_off, bit_off;
541 u32 th;
542
543 reg_off = ((7 - trip) / 2) * 4;
544 bit_off = ((8 - trip) % 2);
545
546 th = readl(data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off);
547 th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off));
548 th |= temp_to_code(data, temp - hyst) << (16 * bit_off);
549 writel(th, data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off);
550}
551
552static void exynos7_tmu_initialize(struct platform_device *pdev)
553{
554 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
555 unsigned int trim_info;
556
557 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
558 sanitize_temp_error(data, trim_info);
559}
560
561static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
562{
563 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
564 struct thermal_zone_device *tz = data->tzd;
565 unsigned int con, interrupt_en = 0, i;
566
567 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
568
569 if (on) {
570 for (i = 0; i < data->ntrip; i++) {
571 if (!of_thermal_is_trip_valid(tz, i))
572 continue;
573
574 interrupt_en |=
575 (1 << (EXYNOS_TMU_INTEN_RISE0_SHIFT + i * 4));
576 }
577
578 if (data->soc != SOC_ARCH_EXYNOS4210)
579 interrupt_en |=
580 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
581
582 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
583 } else {
584 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
585 }
586
587 writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
588 writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
589}
590
591static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
592{
593 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
594 struct thermal_zone_device *tz = data->tzd;
595 unsigned int con, interrupt_en = 0, pd_det_en, i;
596
597 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
598
599 if (on) {
600 for (i = 0; i < data->ntrip; i++) {
601 if (!of_thermal_is_trip_valid(tz, i))
602 continue;
603
604 interrupt_en |=
605 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i));
606 }
607
608 interrupt_en |=
609 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
610
611 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
612 } else
613 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
614
615 pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0;
616
617 writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN);
618 writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN);
619 writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
620}
621
622static void exynos7_tmu_control(struct platform_device *pdev, bool on)
623{
624 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
625 struct thermal_zone_device *tz = data->tzd;
626 unsigned int con, interrupt_en = 0, i;
627
628 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
629
630 if (on) {
631 for (i = 0; i < data->ntrip; i++) {
632 if (!of_thermal_is_trip_valid(tz, i))
633 continue;
634
635 interrupt_en |=
636 (1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i));
637 }
638
639 interrupt_en |=
640 interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
641
642 con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
643 con |= (1 << EXYNOS7_PD_DET_EN_SHIFT);
644 } else {
645 con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
646 con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT);
647 }
648
649 writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN);
650 writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
651}
652
653static int exynos_get_temp(void *p, int *temp)
654{
655 struct exynos_tmu_data *data = p;
656 int value, ret = 0;
657
658 if (!data || !data->tmu_read)
659 return -EINVAL;
660 else if (!data->enabled)
661
662
663
664
665 return -EAGAIN;
666
667 mutex_lock(&data->lock);
668 clk_enable(data->clk);
669
670 value = data->tmu_read(data);
671 if (value < 0)
672 ret = value;
673 else
674 *temp = code_to_temp(data, value) * MCELSIUS;
675
676 clk_disable(data->clk);
677 mutex_unlock(&data->lock);
678
679 return ret;
680}
681
682#ifdef CONFIG_THERMAL_EMULATION
683static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val,
684 int temp)
685{
686 if (temp) {
687 temp /= MCELSIUS;
688
689 val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
690 val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
691 if (data->soc == SOC_ARCH_EXYNOS7) {
692 val &= ~(EXYNOS7_EMUL_DATA_MASK <<
693 EXYNOS7_EMUL_DATA_SHIFT);
694 val |= (temp_to_code(data, temp) <<
695 EXYNOS7_EMUL_DATA_SHIFT) |
696 EXYNOS_EMUL_ENABLE;
697 } else {
698 val &= ~(EXYNOS_EMUL_DATA_MASK <<
699 EXYNOS_EMUL_DATA_SHIFT);
700 val |= (temp_to_code(data, temp) <<
701 EXYNOS_EMUL_DATA_SHIFT) |
702 EXYNOS_EMUL_ENABLE;
703 }
704 } else {
705 val &= ~EXYNOS_EMUL_ENABLE;
706 }
707
708 return val;
709}
710
711static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
712 int temp)
713{
714 unsigned int val;
715 u32 emul_con;
716
717 if (data->soc == SOC_ARCH_EXYNOS5260)
718 emul_con = EXYNOS5260_EMUL_CON;
719 else if (data->soc == SOC_ARCH_EXYNOS5433)
720 emul_con = EXYNOS5433_TMU_EMUL_CON;
721 else if (data->soc == SOC_ARCH_EXYNOS7)
722 emul_con = EXYNOS7_TMU_REG_EMUL_CON;
723 else
724 emul_con = EXYNOS_EMUL_CON;
725
726 val = readl(data->base + emul_con);
727 val = get_emul_con_reg(data, val, temp);
728 writel(val, data->base + emul_con);
729}
730
731static int exynos_tmu_set_emulation(void *drv_data, int temp)
732{
733 struct exynos_tmu_data *data = drv_data;
734 int ret = -EINVAL;
735
736 if (data->soc == SOC_ARCH_EXYNOS4210)
737 goto out;
738
739 if (temp && temp < MCELSIUS)
740 goto out;
741
742 mutex_lock(&data->lock);
743 clk_enable(data->clk);
744 data->tmu_set_emulation(data, temp);
745 clk_disable(data->clk);
746 mutex_unlock(&data->lock);
747 return 0;
748out:
749 return ret;
750}
751#else
752#define exynos4412_tmu_set_emulation NULL
753static int exynos_tmu_set_emulation(void *drv_data, int temp)
754 { return -EINVAL; }
755#endif
756
757static int exynos4210_tmu_read(struct exynos_tmu_data *data)
758{
759 int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
760
761
762 return (ret < 75 || ret > 175) ? -ENODATA : ret;
763}
764
765static int exynos4412_tmu_read(struct exynos_tmu_data *data)
766{
767 return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
768}
769
770static int exynos7_tmu_read(struct exynos_tmu_data *data)
771{
772 return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) &
773 EXYNOS7_TMU_TEMP_MASK;
774}
775
776static void exynos_tmu_work(struct work_struct *work)
777{
778 struct exynos_tmu_data *data = container_of(work,
779 struct exynos_tmu_data, irq_work);
780
781 thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED);
782
783 mutex_lock(&data->lock);
784 clk_enable(data->clk);
785
786
787 data->tmu_clear_irqs(data);
788
789 clk_disable(data->clk);
790 mutex_unlock(&data->lock);
791 enable_irq(data->irq);
792}
793
794static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
795{
796 unsigned int val_irq;
797 u32 tmu_intstat, tmu_intclear;
798
799 if (data->soc == SOC_ARCH_EXYNOS5260) {
800 tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
801 tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
802 } else if (data->soc == SOC_ARCH_EXYNOS7) {
803 tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
804 tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
805 } else if (data->soc == SOC_ARCH_EXYNOS5433) {
806 tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
807 tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
808 } else {
809 tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
810 tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
811 }
812
813 val_irq = readl(data->base + tmu_intstat);
814
815
816
817
818
819
820
821
822 writel(val_irq, data->base + tmu_intclear);
823}
824
825static irqreturn_t exynos_tmu_irq(int irq, void *id)
826{
827 struct exynos_tmu_data *data = id;
828
829 disable_irq_nosync(irq);
830 schedule_work(&data->irq_work);
831
832 return IRQ_HANDLED;
833}
834
835static const struct of_device_id exynos_tmu_match[] = {
836 {
837 .compatible = "samsung,exynos3250-tmu",
838 .data = (const void *)SOC_ARCH_EXYNOS3250,
839 }, {
840 .compatible = "samsung,exynos4210-tmu",
841 .data = (const void *)SOC_ARCH_EXYNOS4210,
842 }, {
843 .compatible = "samsung,exynos4412-tmu",
844 .data = (const void *)SOC_ARCH_EXYNOS4412,
845 }, {
846 .compatible = "samsung,exynos5250-tmu",
847 .data = (const void *)SOC_ARCH_EXYNOS5250,
848 }, {
849 .compatible = "samsung,exynos5260-tmu",
850 .data = (const void *)SOC_ARCH_EXYNOS5260,
851 }, {
852 .compatible = "samsung,exynos5420-tmu",
853 .data = (const void *)SOC_ARCH_EXYNOS5420,
854 }, {
855 .compatible = "samsung,exynos5420-tmu-ext-triminfo",
856 .data = (const void *)SOC_ARCH_EXYNOS5420_TRIMINFO,
857 }, {
858 .compatible = "samsung,exynos5433-tmu",
859 .data = (const void *)SOC_ARCH_EXYNOS5433,
860 }, {
861 .compatible = "samsung,exynos7-tmu",
862 .data = (const void *)SOC_ARCH_EXYNOS7,
863 },
864 { },
865};
866MODULE_DEVICE_TABLE(of, exynos_tmu_match);
867
868static int exynos_map_dt_data(struct platform_device *pdev)
869{
870 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
871 struct resource res;
872
873 if (!data || !pdev->dev.of_node)
874 return -ENODEV;
875
876 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
877 if (data->id < 0)
878 data->id = 0;
879
880 data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
881 if (data->irq <= 0) {
882 dev_err(&pdev->dev, "failed to get IRQ\n");
883 return -ENODEV;
884 }
885
886 if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
887 dev_err(&pdev->dev, "failed to get Resource 0\n");
888 return -ENODEV;
889 }
890
891 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
892 if (!data->base) {
893 dev_err(&pdev->dev, "Failed to ioremap memory\n");
894 return -EADDRNOTAVAIL;
895 }
896
897 data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev);
898
899 switch (data->soc) {
900 case SOC_ARCH_EXYNOS4210:
901 data->tmu_set_trip_temp = exynos4210_tmu_set_trip_temp;
902 data->tmu_set_trip_hyst = exynos4210_tmu_set_trip_hyst;
903 data->tmu_initialize = exynos4210_tmu_initialize;
904 data->tmu_control = exynos4210_tmu_control;
905 data->tmu_read = exynos4210_tmu_read;
906 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
907 data->ntrip = 4;
908 data->gain = 15;
909 data->reference_voltage = 7;
910 data->efuse_value = 55;
911 data->min_efuse_value = 40;
912 data->max_efuse_value = 100;
913 break;
914 case SOC_ARCH_EXYNOS3250:
915 case SOC_ARCH_EXYNOS4412:
916 case SOC_ARCH_EXYNOS5250:
917 case SOC_ARCH_EXYNOS5260:
918 case SOC_ARCH_EXYNOS5420:
919 case SOC_ARCH_EXYNOS5420_TRIMINFO:
920 data->tmu_set_trip_temp = exynos4412_tmu_set_trip_temp;
921 data->tmu_set_trip_hyst = exynos4412_tmu_set_trip_hyst;
922 data->tmu_initialize = exynos4412_tmu_initialize;
923 data->tmu_control = exynos4210_tmu_control;
924 data->tmu_read = exynos4412_tmu_read;
925 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
926 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
927 data->ntrip = 4;
928 data->gain = 8;
929 data->reference_voltage = 16;
930 data->efuse_value = 55;
931 if (data->soc != SOC_ARCH_EXYNOS5420 &&
932 data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
933 data->min_efuse_value = 40;
934 else
935 data->min_efuse_value = 0;
936 data->max_efuse_value = 100;
937 break;
938 case SOC_ARCH_EXYNOS5433:
939 data->tmu_set_trip_temp = exynos5433_tmu_set_trip_temp;
940 data->tmu_set_trip_hyst = exynos5433_tmu_set_trip_hyst;
941 data->tmu_initialize = exynos5433_tmu_initialize;
942 data->tmu_control = exynos5433_tmu_control;
943 data->tmu_read = exynos4412_tmu_read;
944 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
945 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
946 data->ntrip = 8;
947 data->gain = 8;
948 if (res.start == EXYNOS5433_G3D_BASE)
949 data->reference_voltage = 23;
950 else
951 data->reference_voltage = 16;
952 data->efuse_value = 75;
953 data->min_efuse_value = 40;
954 data->max_efuse_value = 150;
955 break;
956 case SOC_ARCH_EXYNOS7:
957 data->tmu_set_trip_temp = exynos7_tmu_set_trip_temp;
958 data->tmu_set_trip_hyst = exynos7_tmu_set_trip_hyst;
959 data->tmu_initialize = exynos7_tmu_initialize;
960 data->tmu_control = exynos7_tmu_control;
961 data->tmu_read = exynos7_tmu_read;
962 data->tmu_set_emulation = exynos4412_tmu_set_emulation;
963 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
964 data->ntrip = 8;
965 data->gain = 9;
966 data->reference_voltage = 17;
967 data->efuse_value = 75;
968 data->min_efuse_value = 15;
969 data->max_efuse_value = 100;
970 break;
971 default:
972 dev_err(&pdev->dev, "Platform not supported\n");
973 return -EINVAL;
974 }
975
976 data->cal_type = TYPE_ONE_POINT_TRIMMING;
977
978
979
980
981
982 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
983 return 0;
984
985 if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
986 dev_err(&pdev->dev, "failed to get Resource 1\n");
987 return -ENODEV;
988 }
989
990 data->base_second = devm_ioremap(&pdev->dev, res.start,
991 resource_size(&res));
992 if (!data->base_second) {
993 dev_err(&pdev->dev, "Failed to ioremap memory\n");
994 return -ENOMEM;
995 }
996
997 return 0;
998}
999
1000static const struct thermal_zone_of_device_ops exynos_sensor_ops = {
1001 .get_temp = exynos_get_temp,
1002 .set_emul_temp = exynos_tmu_set_emulation,
1003};
1004
1005static int exynos_tmu_probe(struct platform_device *pdev)
1006{
1007 struct exynos_tmu_data *data;
1008 int ret;
1009
1010 data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
1011 GFP_KERNEL);
1012 if (!data)
1013 return -ENOMEM;
1014
1015 platform_set_drvdata(pdev, data);
1016 mutex_init(&data->lock);
1017
1018
1019
1020
1021
1022
1023 data->regulator = devm_regulator_get_optional(&pdev->dev, "vtmu");
1024 if (!IS_ERR(data->regulator)) {
1025 ret = regulator_enable(data->regulator);
1026 if (ret) {
1027 dev_err(&pdev->dev, "failed to enable vtmu\n");
1028 return ret;
1029 }
1030 } else {
1031 if (PTR_ERR(data->regulator) == -EPROBE_DEFER)
1032 return -EPROBE_DEFER;
1033 dev_info(&pdev->dev, "Regulator node (vtmu) not found\n");
1034 }
1035
1036 ret = exynos_map_dt_data(pdev);
1037 if (ret)
1038 goto err_sensor;
1039
1040 INIT_WORK(&data->irq_work, exynos_tmu_work);
1041
1042 data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
1043 if (IS_ERR(data->clk)) {
1044 dev_err(&pdev->dev, "Failed to get clock\n");
1045 ret = PTR_ERR(data->clk);
1046 goto err_sensor;
1047 }
1048
1049 data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif");
1050 if (IS_ERR(data->clk_sec)) {
1051 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
1052 dev_err(&pdev->dev, "Failed to get triminfo clock\n");
1053 ret = PTR_ERR(data->clk_sec);
1054 goto err_sensor;
1055 }
1056 } else {
1057 ret = clk_prepare(data->clk_sec);
1058 if (ret) {
1059 dev_err(&pdev->dev, "Failed to get clock\n");
1060 goto err_sensor;
1061 }
1062 }
1063
1064 ret = clk_prepare(data->clk);
1065 if (ret) {
1066 dev_err(&pdev->dev, "Failed to get clock\n");
1067 goto err_clk_sec;
1068 }
1069
1070 switch (data->soc) {
1071 case SOC_ARCH_EXYNOS5433:
1072 case SOC_ARCH_EXYNOS7:
1073 data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk");
1074 if (IS_ERR(data->sclk)) {
1075 dev_err(&pdev->dev, "Failed to get sclk\n");
1076 goto err_clk;
1077 } else {
1078 ret = clk_prepare_enable(data->sclk);
1079 if (ret) {
1080 dev_err(&pdev->dev, "Failed to enable sclk\n");
1081 goto err_clk;
1082 }
1083 }
1084 break;
1085 default:
1086 break;
1087 }
1088
1089
1090
1091
1092
1093 data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
1094 &exynos_sensor_ops);
1095 if (IS_ERR(data->tzd)) {
1096 ret = PTR_ERR(data->tzd);
1097 if (ret != -EPROBE_DEFER)
1098 dev_err(&pdev->dev, "Failed to register sensor: %d\n",
1099 ret);
1100 goto err_sclk;
1101 }
1102
1103 ret = exynos_tmu_initialize(pdev);
1104 if (ret) {
1105 dev_err(&pdev->dev, "Failed to initialize TMU\n");
1106 goto err_thermal;
1107 }
1108
1109 ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
1110 IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
1111 if (ret) {
1112 dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
1113 goto err_thermal;
1114 }
1115
1116 exynos_tmu_control(pdev, true);
1117 return 0;
1118
1119err_thermal:
1120 thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd);
1121err_sclk:
1122 clk_disable_unprepare(data->sclk);
1123err_clk:
1124 clk_unprepare(data->clk);
1125err_clk_sec:
1126 if (!IS_ERR(data->clk_sec))
1127 clk_unprepare(data->clk_sec);
1128err_sensor:
1129 if (!IS_ERR(data->regulator))
1130 regulator_disable(data->regulator);
1131
1132 return ret;
1133}
1134
1135static int exynos_tmu_remove(struct platform_device *pdev)
1136{
1137 struct exynos_tmu_data *data = platform_get_drvdata(pdev);
1138 struct thermal_zone_device *tzd = data->tzd;
1139
1140 thermal_zone_of_sensor_unregister(&pdev->dev, tzd);
1141 exynos_tmu_control(pdev, false);
1142
1143 clk_disable_unprepare(data->sclk);
1144 clk_unprepare(data->clk);
1145 if (!IS_ERR(data->clk_sec))
1146 clk_unprepare(data->clk_sec);
1147
1148 if (!IS_ERR(data->regulator))
1149 regulator_disable(data->regulator);
1150
1151 return 0;
1152}
1153
1154#ifdef CONFIG_PM_SLEEP
1155static int exynos_tmu_suspend(struct device *dev)
1156{
1157 exynos_tmu_control(to_platform_device(dev), false);
1158
1159 return 0;
1160}
1161
1162static int exynos_tmu_resume(struct device *dev)
1163{
1164 struct platform_device *pdev = to_platform_device(dev);
1165
1166 exynos_tmu_initialize(pdev);
1167 exynos_tmu_control(pdev, true);
1168
1169 return 0;
1170}
1171
1172static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
1173 exynos_tmu_suspend, exynos_tmu_resume);
1174#define EXYNOS_TMU_PM (&exynos_tmu_pm)
1175#else
1176#define EXYNOS_TMU_PM NULL
1177#endif
1178
1179static struct platform_driver exynos_tmu_driver = {
1180 .driver = {
1181 .name = "exynos-tmu",
1182 .pm = EXYNOS_TMU_PM,
1183 .of_match_table = exynos_tmu_match,
1184 },
1185 .probe = exynos_tmu_probe,
1186 .remove = exynos_tmu_remove,
1187};
1188
1189module_platform_driver(exynos_tmu_driver);
1190
1191MODULE_DESCRIPTION("Exynos TMU Driver");
1192MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
1193MODULE_LICENSE("GPL");
1194MODULE_ALIAS("platform:exynos-tmu");
1195