summaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorNaveen Krishna Chatradhi <ch.naveen@samsung.com>2013-12-19 01:06:31 -0500
committerEduardo Valentin <edubezval@gmail.com>2014-05-06 14:51:32 -0400
commit14a11dc7e0dbf4acdd9c7b703ebd088f14def739 (patch)
tree92b6362dab322f7c2807f2a2f131a1123ad624a0 /drivers/thermal
parent9025d563cd9bd141a7b7f2095b6a760cd9d83a4e (diff)
thermal: samsung: Add TMU support for Exynos5420 SoCs
Exynos5420 has 5 TMU channels, the TRIMINFO register is misplaced for TMU channels 2, 3 and 4 TRIMINFO at 0x1006c000 contains data for TMU channel 3 TRIMINFO at 0x100a0000 contains data for TMU channel 4 TRIMINFO at 0x10068000 contains data for TMU channel 2 This patch 1 Adds the neccessary register changes and arch information to support Exynos5420 SoCs. 2. Handles the gate clock for misplaced TRIMINFO register 3. Updates the Documentation at Documentation/devicetree/bindings/thermal/exynos-thermal.txt Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> Signed-off-by: Andrew Bresticker <abrestic@chromium.org> Acked-by: Amit Daniel Kachhap <amit.daniel@samsung.com> Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Reviewed-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/samsung/exynos_tmu.c52
-rw-r--r--drivers/thermal/samsung/exynos_tmu.h1
-rw-r--r--drivers/thermal/samsung/exynos_tmu_data.c99
-rw-r--r--drivers/thermal/samsung/exynos_tmu_data.h8
4 files changed, 156 insertions, 4 deletions
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index d9e7663fea8c..bc50912a222d 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -47,6 +47,7 @@
47 * @irq_work: pointer to the irq work structure. 47 * @irq_work: pointer to the irq work structure.
48 * @lock: lock to implement synchronization. 48 * @lock: lock to implement synchronization.
49 * @clk: pointer to the clock structure. 49 * @clk: pointer to the clock structure.
50 * @clk_sec: pointer to the clock structure for accessing the base_second.
50 * @temp_error1: fused value of the first point trim. 51 * @temp_error1: fused value of the first point trim.
51 * @temp_error2: fused value of the second point trim. 52 * @temp_error2: fused value of the second point trim.
52 * @regulator: pointer to the TMU regulator structure. 53 * @regulator: pointer to the TMU regulator structure.
@@ -61,7 +62,7 @@ struct exynos_tmu_data {
61 enum soc_type soc; 62 enum soc_type soc;
62 struct work_struct irq_work; 63 struct work_struct irq_work;
63 struct mutex lock; 64 struct mutex lock;
64 struct clk *clk; 65 struct clk *clk, *clk_sec;
65 u8 temp_error1, temp_error2; 66 u8 temp_error1, temp_error2;
66 struct regulator *regulator; 67 struct regulator *regulator;
67 struct thermal_sensor_conf *reg_conf; 68 struct thermal_sensor_conf *reg_conf;
@@ -152,6 +153,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
152 153
153 mutex_lock(&data->lock); 154 mutex_lock(&data->lock);
154 clk_enable(data->clk); 155 clk_enable(data->clk);
156 if (!IS_ERR(data->clk_sec))
157 clk_enable(data->clk_sec);
155 158
156 if (TMU_SUPPORTS(pdata, READY_STATUS)) { 159 if (TMU_SUPPORTS(pdata, READY_STATUS)) {
157 status = readb(data->base + reg->tmu_status); 160 status = readb(data->base + reg->tmu_status);
@@ -186,7 +189,12 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
186 EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); 189 EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data);
187 } 190 }
188 } else { 191 } else {
189 trim_info = readl(data->base + reg->triminfo_data); 192 /* On exynos5420 the triminfo register is in the shared space */
193 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
194 trim_info = readl(data->base_second +
195 reg->triminfo_data);
196 else
197 trim_info = readl(data->base + reg->triminfo_data);
190 } 198 }
191 data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; 199 data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK;
192 data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) & 200 data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) &
@@ -302,6 +310,8 @@ skip_calib_data:
302out: 310out:
303 clk_disable(data->clk); 311 clk_disable(data->clk);
304 mutex_unlock(&data->lock); 312 mutex_unlock(&data->lock);
313 if (!IS_ERR(data->clk_sec))
314 clk_disable(data->clk_sec);
305 315
306 return ret; 316 return ret;
307} 317}
@@ -453,12 +463,16 @@ static void exynos_tmu_work(struct work_struct *work)
453 const struct exynos_tmu_registers *reg = pdata->registers; 463 const struct exynos_tmu_registers *reg = pdata->registers;
454 unsigned int val_irq, val_type; 464 unsigned int val_irq, val_type;
455 465
466 if (!IS_ERR(data->clk_sec))
467 clk_enable(data->clk_sec);
456 /* Find which sensor generated this interrupt */ 468 /* Find which sensor generated this interrupt */
457 if (reg->tmu_irqstatus) { 469 if (reg->tmu_irqstatus) {
458 val_type = readl(data->base_second + reg->tmu_irqstatus); 470 val_type = readl(data->base_second + reg->tmu_irqstatus);
459 if (!((val_type >> data->id) & 0x1)) 471 if (!((val_type >> data->id) & 0x1))
460 goto out; 472 goto out;
461 } 473 }
474 if (!IS_ERR(data->clk_sec))
475 clk_disable(data->clk_sec);
462 476
463 exynos_report_trigger(data->reg_conf); 477 exynos_report_trigger(data->reg_conf);
464 mutex_lock(&data->lock); 478 mutex_lock(&data->lock);
@@ -499,6 +513,14 @@ static const struct of_device_id exynos_tmu_match[] = {
499 .data = (void *)EXYNOS5250_TMU_DRV_DATA, 513 .data = (void *)EXYNOS5250_TMU_DRV_DATA,
500 }, 514 },
501 { 515 {
516 .compatible = "samsung,exynos5420-tmu",
517 .data = (void *)EXYNOS5420_TMU_DRV_DATA,
518 },
519 {
520 .compatible = "samsung,exynos5420-tmu-ext-triminfo",
521 .data = (void *)EXYNOS5420_TMU_DRV_DATA,
522 },
523 {
502 .compatible = "samsung,exynos5440-tmu", 524 .compatible = "samsung,exynos5440-tmu",
503 .data = (void *)EXYNOS5440_TMU_DRV_DATA, 525 .data = (void *)EXYNOS5440_TMU_DRV_DATA,
504 }, 526 },
@@ -629,13 +651,30 @@ static int exynos_tmu_probe(struct platform_device *pdev)
629 return PTR_ERR(data->clk); 651 return PTR_ERR(data->clk);
630 } 652 }
631 653
654 data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif");
655 if (IS_ERR(data->clk_sec)) {
656 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
657 dev_err(&pdev->dev, "Failed to get triminfo clock\n");
658 return PTR_ERR(data->clk_sec);
659 }
660 } else {
661 ret = clk_prepare(data->clk_sec);
662 if (ret) {
663 dev_err(&pdev->dev, "Failed to get clock\n");
664 return ret;
665 }
666 }
667
632 ret = clk_prepare(data->clk); 668 ret = clk_prepare(data->clk);
633 if (ret) 669 if (ret) {
634 return ret; 670 dev_err(&pdev->dev, "Failed to get clock\n");
671 goto err_clk_sec;
672 }
635 673
636 if (pdata->type == SOC_ARCH_EXYNOS4210 || 674 if (pdata->type == SOC_ARCH_EXYNOS4210 ||
637 pdata->type == SOC_ARCH_EXYNOS4412 || 675 pdata->type == SOC_ARCH_EXYNOS4412 ||
638 pdata->type == SOC_ARCH_EXYNOS5250 || 676 pdata->type == SOC_ARCH_EXYNOS5250 ||
677 pdata->type == SOC_ARCH_EXYNOS5420_TRIMINFO ||
639 pdata->type == SOC_ARCH_EXYNOS5440) 678 pdata->type == SOC_ARCH_EXYNOS5440)
640 data->soc = pdata->type; 679 data->soc = pdata->type;
641 else { 680 else {
@@ -704,6 +743,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
704 return 0; 743 return 0;
705err_clk: 744err_clk:
706 clk_unprepare(data->clk); 745 clk_unprepare(data->clk);
746err_clk_sec:
747 if (!IS_ERR(data->clk_sec))
748 clk_unprepare(data->clk_sec);
707 return ret; 749 return ret;
708} 750}
709 751
@@ -716,6 +758,8 @@ static int exynos_tmu_remove(struct platform_device *pdev)
716 exynos_unregister_thermal(data->reg_conf); 758 exynos_unregister_thermal(data->reg_conf);
717 759
718 clk_unprepare(data->clk); 760 clk_unprepare(data->clk);
761 if (!IS_ERR(data->clk_sec))
762 clk_unprepare(data->clk_sec);
719 763
720 if (!IS_ERR(data->regulator)) 764 if (!IS_ERR(data->regulator))
721 regulator_disable(data->regulator); 765 regulator_disable(data->regulator);
diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
index 0d6b32fb0a4c..60cce2855fa8 100644
--- a/drivers/thermal/samsung/exynos_tmu.h
+++ b/drivers/thermal/samsung/exynos_tmu.h
@@ -43,6 +43,7 @@ enum soc_type {
43 SOC_ARCH_EXYNOS4210 = 1, 43 SOC_ARCH_EXYNOS4210 = 1,
44 SOC_ARCH_EXYNOS4412, 44 SOC_ARCH_EXYNOS4412,
45 SOC_ARCH_EXYNOS5250, 45 SOC_ARCH_EXYNOS5250,
46 SOC_ARCH_EXYNOS5420_TRIMINFO,
46 SOC_ARCH_EXYNOS5440, 47 SOC_ARCH_EXYNOS5440,
47}; 48};
48 49
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
index 9816294f7058..e597f61a15f9 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.c
+++ b/drivers/thermal/samsung/exynos_tmu_data.c
@@ -194,6 +194,105 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
194}; 194};
195#endif 195#endif
196 196
197#if defined(CONFIG_SOC_EXYNOS5420)
198static const struct exynos_tmu_registers exynos5420_tmu_registers = {
199 .triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
200 .triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
201 .triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
202 .tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
203 .buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
204 .buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
205 .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
206 .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK,
207 .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT,
208 .buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
209 .buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
210 .core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
211 .tmu_status = EXYNOS_TMU_REG_STATUS,
212 .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP,
213 .threshold_th0 = EXYNOS_THD_TEMP_RISE,
214 .threshold_th1 = EXYNOS_THD_TEMP_FALL,
215 .tmu_inten = EXYNOS_TMU_REG_INTEN,
216 .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT,
217 .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT,
218 .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
219 /* INTEN_RISE3 Not availble in exynos5420 */
220 .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
221 .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT,
222 .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
223 .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
224 .intclr_fall_shift = EXYNOS5420_TMU_CLEAR_FALL_INT_SHIFT,
225 .intclr_rise_shift = EXYNOS_TMU_RISE_INT_SHIFT,
226 .intclr_rise_mask = EXYNOS_TMU_RISE_INT_MASK,
227 .intclr_fall_mask = EXYNOS_TMU_FALL_INT_MASK,
228 .emul_con = EXYNOS_EMUL_CON,
229 .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
230 .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT,
231 .emul_time_mask = EXYNOS_EMUL_TIME_MASK,
232};
233
234#define __EXYNOS5420_TMU_DATA \
235 .threshold_falling = 10, \
236 .trigger_levels[0] = 85, \
237 .trigger_levels[1] = 103, \
238 .trigger_levels[2] = 110, \
239 .trigger_levels[3] = 120, \
240 .trigger_enable[0] = true, \
241 .trigger_enable[1] = true, \
242 .trigger_enable[2] = true, \
243 .trigger_enable[3] = false, \
244 .trigger_type[0] = THROTTLE_ACTIVE, \
245 .trigger_type[1] = THROTTLE_ACTIVE, \
246 .trigger_type[2] = SW_TRIP, \
247 .trigger_type[3] = HW_TRIP, \
248 .max_trigger_level = 4, \
249 .gain = 8, \
250 .reference_voltage = 16, \
251 .noise_cancel_mode = 4, \
252 .cal_type = TYPE_ONE_POINT_TRIMMING, \
253 .efuse_value = 55, \
254 .min_efuse_value = 40, \
255 .max_efuse_value = 100, \
256 .first_point_trim = 25, \
257 .second_point_trim = 85, \
258 .default_temp_offset = 50, \
259 .freq_tab[0] = { \
260 .freq_clip_max = 800 * 1000, \
261 .temp_level = 85, \
262 }, \
263 .freq_tab[1] = { \
264 .freq_clip_max = 200 * 1000, \
265 .temp_level = 103, \
266 }, \
267 .freq_tab_count = 2, \
268 .registers = &exynos5420_tmu_registers, \
269
270#define EXYNOS5420_TMU_DATA \
271 __EXYNOS5420_TMU_DATA \
272 .type = SOC_ARCH_EXYNOS5250, \
273 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \
274 TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \
275 TMU_SUPPORT_EMUL_TIME)
276
277#define EXYNOS5420_TMU_DATA_SHARED \
278 __EXYNOS5420_TMU_DATA \
279 .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \
280 .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \
281 TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \
282 TMU_SUPPORT_EMUL_TIME | TMU_SUPPORT_ADDRESS_MULTIPLE)
283
284struct exynos_tmu_init_data const exynos5420_default_tmu_data = {
285 .tmu_data = {
286 { EXYNOS5420_TMU_DATA },
287 { EXYNOS5420_TMU_DATA },
288 { EXYNOS5420_TMU_DATA_SHARED },
289 { EXYNOS5420_TMU_DATA_SHARED },
290 { EXYNOS5420_TMU_DATA_SHARED },
291 },
292 .tmu_count = 5,
293};
294#endif
295
197#if defined(CONFIG_SOC_EXYNOS5440) 296#if defined(CONFIG_SOC_EXYNOS5440)
198static const struct exynos_tmu_registers exynos5440_tmu_registers = { 297static const struct exynos_tmu_registers exynos5440_tmu_registers = {
199 .triminfo_data = EXYNOS5440_TMU_S0_7_TRIM, 298 .triminfo_data = EXYNOS5440_TMU_S0_7_TRIM,
diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
index d9495a441560..41f06dc70849 100644
--- a/drivers/thermal/samsung/exynos_tmu_data.h
+++ b/drivers/thermal/samsung/exynos_tmu_data.h
@@ -72,6 +72,7 @@
72#define EXYNOS_TMU_CLEAR_RISE_INT 0x111 72#define EXYNOS_TMU_CLEAR_RISE_INT 0x111
73#define EXYNOS_TMU_CLEAR_FALL_INT (0x111 << 12) 73#define EXYNOS_TMU_CLEAR_FALL_INT (0x111 << 12)
74#define EXYNOS_TMU_CLEAR_FALL_INT_SHIFT 12 74#define EXYNOS_TMU_CLEAR_FALL_INT_SHIFT 12
75#define EXYNOS5420_TMU_CLEAR_FALL_INT_SHIFT 16
75#define EXYNOS5440_TMU_CLEAR_FALL_INT_SHIFT 4 76#define EXYNOS5440_TMU_CLEAR_FALL_INT_SHIFT 4
76#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 77#define EXYNOS_TMU_TRIP_MODE_SHIFT 13
77#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 78#define EXYNOS_TMU_TRIP_MODE_MASK 0x7
@@ -156,6 +157,13 @@ extern struct exynos_tmu_init_data const exynos5250_default_tmu_data;
156#define EXYNOS5250_TMU_DRV_DATA (NULL) 157#define EXYNOS5250_TMU_DRV_DATA (NULL)
157#endif 158#endif
158 159
160#if defined(CONFIG_SOC_EXYNOS5420)
161extern struct exynos_tmu_init_data const exynos5420_default_tmu_data;
162#define EXYNOS5420_TMU_DRV_DATA (&exynos5420_default_tmu_data)
163#else
164#define EXYNOS5420_TMU_DRV_DATA (NULL)
165#endif
166
159#if defined(CONFIG_SOC_EXYNOS5440) 167#if defined(CONFIG_SOC_EXYNOS5440)
160extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; 168extern struct exynos_tmu_init_data const exynos5440_default_tmu_data;
161#define EXYNOS5440_TMU_DRV_DATA (&exynos5440_default_tmu_data) 169#define EXYNOS5440_TMU_DRV_DATA (&exynos5440_default_tmu_data)