Skip to content
Permalink
Browse files
drm: Fix fbcon blank on QEMU graphics drivers
Currently the DRM fbcon helper for console blank,
drm_fb_helper_blank(), simply calls drm_fb_helper_dpms() and always
returns zero, supposing the driver dealing with DPMS or atomic
crtc->active flip to handle blanking the screen.  It works on most of
devices, but broken on most of KVM/QEMU graphics: bochs, qxl and
cirrus drivers just ignore crtc->active state change as blanking (or
cirrus ignoring DPMS).  In practice, when you run like
  % setterm --blank force
on a VT console, the screen freezes without actually blanking.

A simple fix for this problem would be not to rely on DPMS but let
fbcon performs the generic blank code.  This can be achieved just by
returning an error from drm_fb_helper_blank().

In this patch, we add a flag, no_dpms_blank, to drm_fb_helper for
indicating that the driver doesn't handle blank via DPMS or
crtc->active flip.  When this flag is set, drm_fb_helper_blank()
simply returns an error, so that fbcon falls back to its generic blank
handler.  The flag is set to both bochs and qxl drivers in this patch,
while cirrus is left untouched as it's declared as to-be-deprecated.

Link: https://lore.kernel.org/dri-devel/20170726205636.19144-1-tiwai@suse.de/
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1095700
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
tiwai authored and intel-lab-lkp committed Apr 16, 2021
1 parent 1884b57 commit 4b1a07505589e5f12ae52f249fa93b400e35e602
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 0 deletions.
@@ -132,6 +132,9 @@ static int bochs_pci_probe(struct pci_dev *pdev,
goto err_unload;

drm_fbdev_generic_setup(dev, 32);
if (dev->fb_helper)
dev->fb_helper->no_dpms_blank = true;

return ret;

err_unload:
@@ -332,9 +332,14 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
*/
int drm_fb_helper_blank(int blank, struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;

if (oops_in_progress)
return -EBUSY;

if (fb_helper->no_dpms_blank)
return -EINVAL;

switch (blank) {
/* Display: On; HSync: On, VSync: On */
case FB_BLANK_UNBLANK:
@@ -120,6 +120,9 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto modeset_cleanup;

drm_fbdev_generic_setup(&qdev->ddev, 32);
if (qdev->fb_helper)
qdev->fb_helper->no_dpms_blank = true;

return 0;

modeset_cleanup:
@@ -176,6 +176,14 @@ struct drm_fb_helper {
*/
bool deferred_setup;

/**
* @no_dpms_blank:
*
* A flag indicating that the driver doesn't support blanking.
* Then fbcon core code falls back to its generic handler.
*/
bool no_dpms_blank;

/**
* @preferred_bpp:
*

0 comments on commit 4b1a075

Please sign in to comment.