Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Keerthy and committed by
Eduardo Valentin
e9a90d04 79010636

+45 -3
+2 -1
drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
··· 319 319 TI_BANDGAP_FEATURE_FREEZE_BIT | 320 320 TI_BANDGAP_FEATURE_TALERT | 321 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 324 .fclock_name = "l3instr_ts_gclk_div", 324 325 .div_ck_name = "l3instr_ts_gclk_div", 325 326 .conv_table = omap5430_adc_to_temp,
+40 -1
drivers/thermal/ti-soc-thermal/ti-bandgap.c
··· 445 445 { 446 446 struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data; 447 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 449 int err = 0; 450 450 451 451 tsr = bgp->conf->sensors[id].registers; ··· 477 477 ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask); 478 478 reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) | 479 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 508 ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold); 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 + } 481 520 482 521 if (err) { 483 522 dev_err(bgp->dev, "failed to reprogram thot threshold\n");
+3 -1
drivers/thermal/ti-soc-thermal/ti-bandgap.h
··· 320 320 * 321 321 * TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device 322 322 * has Errata 814 323 - * 323 + * TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device 324 + * has Errata 813 324 325 * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a 325 326 * specific feature (above) or not. Return non-zero, if yes. 326 327 */ ··· 336 335 #define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8) 337 336 #define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9) 338 337 #define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10) 338 + #define TI_BANDGAP_FEATURE_ERRATA_813 BIT(11) 339 339 #define TI_BANDGAP_HAS(b, f) \ 340 340 ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f) 341 341