aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeerthy <j-keerthy@ti.com>2015-04-22 08:51:42 -0400
committerEduardo Valentin <edubezval@gmail.com>2015-05-08 21:02:29 -0400
commite9a90d046b9c9fe8f7c8efefe7b0e64c3c0daa8f (patch)
tree5892eedab25e84bf4c96d481a5a8165ecdeb2cec
parent79010636174c78209e20c4f44370b2b13312e08c (diff)
thermal: ti-soc-thermal: OMAP5: Implement Workaround for Errata i813
DESCRIPTION Spurious Thermal Alert: Talert can happen randomly while the device remains under the temperature limit defined for this event to trig. This spurious event is caused by a incorrect re-synchronization between clock domains. The comparison between configured threshold and current temperature value can happen while the value is transitioning (metastable), thus causing inappropriate event generation. No spurious event occurs as long as the threshold value stays unchanged. Spurious event can be generated while a thermal alert threshold is modified in CONTROL_BANDGAP_THRESHOLD_MPU/GPU/CORE/DSPEVE/IVA_n. WORKAROUND Spurious event generation can be avoided by performing following sequence when the threshold is modified: 1. Mask the hot/cold events at the thermal IP level. 2. Modify Threshold. 3. Unmask the hot/cold events at the thermal IP level. Signed-off-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
-rw-r--r--drivers/thermal/ti-soc-thermal/omap5-thermal-data.c3
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-bandgap.c41
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-bandgap.h4
3 files changed, 45 insertions, 3 deletions
diff --git a/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
index eff0c80fd4af..79ff70c446ba 100644
--- a/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
+++ b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
@@ -319,7 +319,8 @@ const struct ti_bandgap_data omap5430_data = {
319 TI_BANDGAP_FEATURE_FREEZE_BIT | 319 TI_BANDGAP_FEATURE_FREEZE_BIT |
320 TI_BANDGAP_FEATURE_TALERT | 320 TI_BANDGAP_FEATURE_TALERT |
321 TI_BANDGAP_FEATURE_COUNTER_DELAY | 321 TI_BANDGAP_FEATURE_COUNTER_DELAY |
322 TI_BANDGAP_FEATURE_HISTORY_BUFFER, 322 TI_BANDGAP_FEATURE_HISTORY_BUFFER |
323 TI_BANDGAP_FEATURE_ERRATA_813,
323 .fclock_name = "l3instr_ts_gclk_div", 324 .fclock_name = "l3instr_ts_gclk_div",
324 .div_ck_name = "l3instr_ts_gclk_div", 325 .div_ck_name = "l3instr_ts_gclk_div",
325 .conv_table = omap5430_adc_to_temp, 326 .conv_table = omap5430_adc_to_temp,
diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 9747523858a1..bc14dc874594 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -445,7 +445,7 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
445{ 445{
446 struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data; 446 struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data;
447 struct temp_sensor_registers *tsr; 447 struct temp_sensor_registers *tsr;
448 u32 thresh_val, reg_val, t_hot, t_cold; 448 u32 thresh_val, reg_val, t_hot, t_cold, ctrl;
449 int err = 0; 449 int err = 0;
450 450
451 tsr = bgp->conf->sensors[id].registers; 451 tsr = bgp->conf->sensors[id].registers;
@@ -477,8 +477,47 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
477 ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask); 477 ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask);
478 reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) | 478 reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) |
479 (t_cold << __ffs(tsr->threshold_tcold_mask)); 479 (t_cold << __ffs(tsr->threshold_tcold_mask));
480
481 /**
482 * Errata i813:
483 * Spurious Thermal Alert: Talert can happen randomly while the device
484 * remains under the temperature limit defined for this event to trig.
485 * This spurious event is caused by a incorrect re-synchronization
486 * between clock domains. The comparison between configured threshold
487 * and current temperature value can happen while the value is
488 * transitioning (metastable), thus causing inappropriate event
489 * generation. No spurious event occurs as long as the threshold value
490 * stays unchanged. Spurious event can be generated while a thermal
491 * alert threshold is modified in
492 * CONTROL_BANDGAP_THRESHOLD_MPU/GPU/CORE/DSPEVE/IVA_n.
493 */
494
495 if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
496 /* Mask t_hot and t_cold events at the IP Level */
497 ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
498
499 if (hot)
500 ctrl &= ~tsr->mask_hot_mask;
501 else
502 ctrl &= ~tsr->mask_cold_mask;
503
504 ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
505 }
506
507 /* Write the threshold value */
480 ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold); 508 ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold);
481 509
510 if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
511 /* Unmask t_hot and t_cold events at the IP Level */
512 ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
513 if (hot)
514 ctrl |= tsr->mask_hot_mask;
515 else
516 ctrl |= tsr->mask_cold_mask;
517
518 ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
519 }
520
482 if (err) { 521 if (err) {
483 dev_err(bgp->dev, "failed to reprogram thot threshold\n"); 522 dev_err(bgp->dev, "failed to reprogram thot threshold\n");
484 err = -EIO; 523 err = -EIO;
diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.h b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
index b2da3fc42b51..0c52f7afba00 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.h
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
@@ -320,7 +320,8 @@ struct ti_temp_sensor {
320 * 320 *
321 * TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device 321 * TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device
322 * has Errata 814 322 * has Errata 814
323 * 323 * TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device
324 * has Errata 813
324 * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a 325 * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
325 * specific feature (above) or not. Return non-zero, if yes. 326 * specific feature (above) or not. Return non-zero, if yes.
326 */ 327 */
@@ -335,6 +336,7 @@ struct ti_temp_sensor {
335#define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8) 336#define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8)
336#define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9) 337#define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9)
337#define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10) 338#define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10)
339#define TI_BANDGAP_FEATURE_ERRATA_813 BIT(11)
338#define TI_BANDGAP_HAS(b, f) \ 340#define TI_BANDGAP_HAS(b, f) \
339 ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f) 341 ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)
340 342