Skip to content

Commit a1c008b

Browse files
Thomas ZimmermannMaarten Lankhorst
authored andcommitted
drm/i915/display: fbdev: Move custom suspend code to new callback
If the fbdev buffer is backed by stolen memory, it has to be cleared upon resume from hibernation. Move the code into the new callback fb_set_suspend, so that it can run from DRM's generic fbdev client. No functional change. Other drivers are not affected. Signed-off-by: Thomas Zimmermann <[email protected]> Reviewed-by: Maarten Lankhorst <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Maarten Lankhorst <[email protected]>
1 parent 2ef5754 commit a1c008b

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

drivers/gpu/drm/drm_fb_helper.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,12 @@ EXPORT_SYMBOL(drm_fb_helper_deferred_io);
757757
*/
758758
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)
759759
{
760-
if (fb_helper && fb_helper->info)
760+
if (!fb_helper || !fb_helper->info)
761+
return;
762+
763+
if (fb_helper->funcs->fb_set_suspend)
764+
fb_helper->funcs->fb_set_suspend(fb_helper, suspend);
765+
else
761766
fb_set_suspend(fb_helper->info, suspend);
762767
}
763768
EXPORT_SYMBOL(drm_fb_helper_set_suspend);
@@ -803,7 +808,7 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
803808
}
804809
}
805810

806-
fb_set_suspend(fb_helper->info, suspend);
811+
drm_fb_helper_set_suspend(fb_helper, suspend);
807812
console_unlock();
808813
}
809814
EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked);

drivers/gpu/drm/i915/display/intel_fbdev.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,27 @@ static void intelfb_restore(struct drm_fb_helper *fb_helper)
285285
intel_fbdev_invalidate(ifbdev);
286286
}
287287

288+
static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)
289+
{
290+
struct fb_info *info = fb_helper->info;
291+
292+
/*
293+
* When resuming from hibernation, Linux restores the object's
294+
* content from swap if the buffer is backed by shmemfs. If the
295+
* object is stolen however, it will be full of whatever garbage
296+
* was left in there. Clear it to zero in this case.
297+
*/
298+
if (!suspend && !intel_bo_is_shmem(intel_fb_bo(fb_helper->fb)))
299+
memset_io(info->screen_base, 0, info->screen_size);
300+
301+
fb_set_suspend(info, suspend);
302+
}
303+
288304
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
289305
.fb_probe = intelfb_create,
290306
.fb_dirty = intelfb_dirty,
291307
.fb_restore = intelfb_restore,
308+
.fb_set_suspend = intelfb_set_suspend,
292309
};
293310

294311
/*
@@ -457,7 +474,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
457474
{
458475
struct drm_i915_private *dev_priv = to_i915(dev);
459476
struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
460-
struct fb_info *info;
461477

462478
if (!ifbdev)
463479
return;
@@ -468,8 +484,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
468484
if (!ifbdev->vma)
469485
return;
470486

471-
info = ifbdev->helper.info;
472-
473487
if (synchronous) {
474488
/* Flush any pending work to turn the console on, and then
475489
* wait to turn it off. It must be synchronous as we are
@@ -499,14 +513,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
499513
}
500514
}
501515

502-
/* On resume from hibernation: If the object is shmemfs backed, it has
503-
* been restored from swap. If the object is stolen however, it will be
504-
* full of whatever garbage was left in there.
505-
*/
506-
if (state == FBINFO_STATE_RUNNING &&
507-
!intel_bo_is_shmem(intel_fb_bo(&ifbdev->fb->base)))
508-
memset_io(info->screen_base, 0, info->screen_size);
509-
510516
drm_fb_helper_set_suspend(&ifbdev->helper, state);
511517
console_unlock();
512518
}

include/drm/drm_fb_helper.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,20 @@ struct drm_fb_helper_funcs {
112112
* TODO: Fix i915 to not require this callback.
113113
*/
114114
void (*fb_restore)(struct drm_fb_helper *helper);
115+
116+
/**
117+
* @fb_set_suspend:
118+
*
119+
* Driver callback to suspend or resume, if set, fbdev emulation will
120+
* invoke this callback during suspend and resume. Driver should call
121+
* fb_set_suspend() from their implementation. If not set, fbdev
122+
* emulation will invoke fb_set_suspend() directly.
123+
*
124+
* Only for i915. Do not use in new code.
125+
*
126+
* TODO: Fix i915 to not require this callback.
127+
*/
128+
void (*fb_set_suspend)(struct drm_fb_helper *helper, bool suspend);
115129
};
116130

117131
/**

0 commit comments

Comments
 (0)