diff options
Diffstat (limited to 'drivers/thermal/ti-soc-thermal/ti-bandgap.c')
-rw-r--r-- | drivers/thermal/ti-soc-thermal/ti-bandgap.c | 41 |
1 files changed, 40 insertions, 1 deletions
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, { struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data; struct temp_sensor_registers *tsr; - u32 thresh_val, reg_val, t_hot, t_cold; + u32 thresh_val, reg_val, t_hot, t_cold, ctrl; int err = 0; tsr = bgp->conf->sensors[id].registers; @@ -477,8 +477,47 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id, ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask); reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) | (t_cold << __ffs(tsr->threshold_tcold_mask)); + + /** + * Errata i813: + * 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. + */ + + if (TI_BANDGAP_HAS(bgp, ERRATA_813)) { + /* Mask t_hot and t_cold events at the IP Level */ + ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl); + + if (hot) + ctrl &= ~tsr->mask_hot_mask; + else + ctrl &= ~tsr->mask_cold_mask; + + ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl); + } + + /* Write the threshold value */ ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold); + if (TI_BANDGAP_HAS(bgp, ERRATA_813)) { + /* Unmask t_hot and t_cold events at the IP Level */ + ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl); + if (hot) + ctrl |= tsr->mask_hot_mask; + else + ctrl |= tsr->mask_cold_mask; + + ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl); + } + if (err) { dev_err(bgp->dev, "failed to reprogram thot threshold\n"); err = -EIO; |