Skip to content

Commit c4a62a7

Browse files
mupufBen Skeggs
authored andcommitted
drm/nouveau/therm: survive to suspend/resume cycles
Therm uses 3 ptimer alarms. Two to drive the fan and one for polling the temperature. When suspending/resuming, alarms will never be fired. As we are checking if there isn't an alarm pending before rescheduling another one, we end up never checking temperature or updating the fan speed. This commit also adds debug messages to be able to spot more easily if this case happens again in the future. Sorry for the spam if you activate the debug level though. Tested-by: Dash Four <[email protected]> v2: - fix temperature polling too Signed-off-by: Martin Peres <[email protected]> Tested-by: Martin Peres <[email protected]> Signed-off-by: Ben Skeggs <[email protected]>
1 parent b925a75 commit c4a62a7

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

drivers/gpu/drm/nouveau/core/subdev/therm/base.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,14 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
9595
int duty;
9696

9797
spin_lock_irqsave(&priv->lock, flags);
98+
nv_debug(therm, "FAN speed check\n");
9899
if (mode < 0)
99100
mode = priv->mode;
100101
priv->mode = mode;
101102

102103
switch (mode) {
103104
case NOUVEAU_THERM_CTRL_MANUAL:
105+
ptimer->alarm_cancel(ptimer, &priv->alarm);
104106
duty = nouveau_therm_fan_get(therm);
105107
if (duty < 0)
106108
duty = 100;
@@ -113,6 +115,7 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
113115
break;
114116
case NOUVEAU_THERM_CTRL_NONE:
115117
default:
118+
ptimer->alarm_cancel(ptimer, &priv->alarm);
116119
goto done;
117120
}
118121

@@ -122,6 +125,8 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
122125
done:
123126
if (list_empty(&priv->alarm.head) && (mode == NOUVEAU_THERM_CTRL_AUTO))
124127
ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm);
128+
else if (!list_empty(&priv->alarm.head))
129+
nv_debug(therm, "therm fan alarm list is not empty\n");
125130
spin_unlock_irqrestore(&priv->lock, flags);
126131
}
127132

@@ -274,7 +279,8 @@ _nouveau_therm_init(struct nouveau_object *object)
274279

275280
nouveau_therm_fan_mode(therm, priv->suspend);
276281
}
277-
priv->sensor.program_alarms(therm);
282+
nouveau_therm_sensor_init(therm);
283+
nouveau_therm_fan_init(therm);
278284
return 0;
279285
}
280286

@@ -284,6 +290,8 @@ _nouveau_therm_fini(struct nouveau_object *object, bool suspend)
284290
struct nouveau_therm *therm = (void *)object;
285291
struct nouveau_therm_priv *priv = (void *)therm;
286292

293+
nouveau_therm_fan_fini(therm, suspend);
294+
nouveau_therm_sensor_fini(therm, suspend);
287295
if (suspend) {
288296
priv->suspend = priv->mode;
289297
priv->mode = NOUVEAU_THERM_CTRL_NONE;

drivers/gpu/drm/nouveau/core/subdev/therm/fan.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,23 @@ nouveau_therm_fan_safety_checks(struct nouveau_therm *therm)
203203
priv->fan->bios.min_duty = priv->fan->bios.max_duty;
204204
}
205205

206+
int
207+
nouveau_therm_fan_init(struct nouveau_therm *therm)
208+
{
209+
return 0;
210+
}
211+
212+
int
213+
nouveau_therm_fan_fini(struct nouveau_therm *therm, bool suspend)
214+
{
215+
struct nouveau_therm_priv *priv = (void *)therm;
216+
struct nouveau_timer *ptimer = nouveau_timer(therm);
217+
218+
if (suspend)
219+
ptimer->alarm_cancel(ptimer, &priv->fan->alarm);
220+
return 0;
221+
}
222+
206223
int
207224
nouveau_therm_fan_ctor(struct nouveau_therm *therm)
208225
{

drivers/gpu/drm/nouveau/core/subdev/therm/priv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ void nouveau_therm_ic_ctor(struct nouveau_therm *therm);
113113
int nouveau_therm_sensor_ctor(struct nouveau_therm *therm);
114114

115115
int nouveau_therm_fan_ctor(struct nouveau_therm *therm);
116+
int nouveau_therm_fan_init(struct nouveau_therm *therm);
117+
int nouveau_therm_fan_fini(struct nouveau_therm *therm, bool suspend);
116118
int nouveau_therm_fan_get(struct nouveau_therm *therm);
117119
int nouveau_therm_fan_set(struct nouveau_therm *therm, bool now, int percent);
118120
int nouveau_therm_fan_user_get(struct nouveau_therm *therm);
@@ -122,6 +124,8 @@ int nouveau_therm_fan_sense(struct nouveau_therm *therm);
122124

123125
int nouveau_therm_preinit(struct nouveau_therm *);
124126

127+
int nouveau_therm_sensor_init(struct nouveau_therm *therm);
128+
int nouveau_therm_sensor_fini(struct nouveau_therm *therm, bool suspend);
125129
void nouveau_therm_sensor_preinit(struct nouveau_therm *);
126130
void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm,
127131
enum nouveau_therm_thrs thrs,

drivers/gpu/drm/nouveau/core/subdev/therm/temp.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ alarm_timer_callback(struct nouveau_alarm *alarm)
180180

181181
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
182182

183+
nv_debug(therm, "polling the internal temperature\n");
184+
183185
nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_fan_boost,
184186
NOUVEAU_THERM_THRS_FANBOOST);
185187

@@ -216,6 +218,25 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm)
216218
alarm_timer_callback(&priv->sensor.therm_poll_alarm);
217219
}
218220

221+
int
222+
nouveau_therm_sensor_init(struct nouveau_therm *therm)
223+
{
224+
struct nouveau_therm_priv *priv = (void *)therm;
225+
priv->sensor.program_alarms(therm);
226+
return 0;
227+
}
228+
229+
int
230+
nouveau_therm_sensor_fini(struct nouveau_therm *therm, bool suspend)
231+
{
232+
struct nouveau_therm_priv *priv = (void *)therm;
233+
struct nouveau_timer *ptimer = nouveau_timer(therm);
234+
235+
if (suspend)
236+
ptimer->alarm_cancel(ptimer, &priv->sensor.therm_poll_alarm);
237+
return 0;
238+
}
239+
219240
void
220241
nouveau_therm_sensor_preinit(struct nouveau_therm *therm)
221242
{

0 commit comments

Comments
 (0)