Commit e9a90d04 authored by Keerthy's avatar Keerthy Committed by Eduardo Valentin

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: default avatarKeerthy <j-keerthy@ti.com>
Signed-off-by: default avatarEduardo Valentin <edubezval@gmail.com>
parent 79010636
...@@ -319,7 +319,8 @@ const struct ti_bandgap_data omap5430_data = { ...@@ -319,7 +319,8 @@ const struct ti_bandgap_data omap5430_data = {
TI_BANDGAP_FEATURE_FREEZE_BIT | TI_BANDGAP_FEATURE_FREEZE_BIT |
TI_BANDGAP_FEATURE_TALERT | TI_BANDGAP_FEATURE_TALERT |
TI_BANDGAP_FEATURE_COUNTER_DELAY | TI_BANDGAP_FEATURE_COUNTER_DELAY |
TI_BANDGAP_FEATURE_HISTORY_BUFFER, TI_BANDGAP_FEATURE_HISTORY_BUFFER |
TI_BANDGAP_FEATURE_ERRATA_813,
.fclock_name = "l3instr_ts_gclk_div", .fclock_name = "l3instr_ts_gclk_div",
.div_ck_name = "l3instr_ts_gclk_div", .div_ck_name = "l3instr_ts_gclk_div",
.conv_table = omap5430_adc_to_temp, .conv_table = omap5430_adc_to_temp,
......
...@@ -445,7 +445,7 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id, ...@@ -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_data *ts_data = bgp->conf->sensors[id].ts_data;
struct temp_sensor_registers *tsr; 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; int err = 0;
tsr = bgp->conf->sensors[id].registers; tsr = bgp->conf->sensors[id].registers;
...@@ -477,8 +477,47 @@ static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id, ...@@ -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); ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask);
reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) | reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) |
(t_cold << __ffs(tsr->threshold_tcold_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); 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) { if (err) {
dev_err(bgp->dev, "failed to reprogram thot threshold\n"); dev_err(bgp->dev, "failed to reprogram thot threshold\n");
err = -EIO; err = -EIO;
......
...@@ -320,7 +320,8 @@ struct ti_temp_sensor { ...@@ -320,7 +320,8 @@ struct ti_temp_sensor {
* *
* TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device * TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device
* has Errata 814 * has Errata 814
* * TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device
* has Errata 813
* TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
* specific feature (above) or not. Return non-zero, if yes. * specific feature (above) or not. Return non-zero, if yes.
*/ */
...@@ -335,6 +336,7 @@ struct ti_temp_sensor { ...@@ -335,6 +336,7 @@ struct ti_temp_sensor {
#define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8) #define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8)
#define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9) #define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9)
#define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10) #define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10)
#define TI_BANDGAP_FEATURE_ERRATA_813 BIT(11)
#define TI_BANDGAP_HAS(b, f) \ #define TI_BANDGAP_HAS(b, f) \
((b)->conf->features & TI_BANDGAP_FEATURE_ ## f) ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment