Hi,

I've pushed this fix into drm-misc-next. It will hopefully restore the fbdev consoles. Sorry for the inconvenience. If things still don't work, stating

  video=1024x768-32

on the kernel command line should be a safe override on most systems.

Best regards
Thomas

Am 06.01.23 um 12:23 schrieb Thomas Zimmermann:
Replace the combination of bpp and depth with a single color-mode
argument. Handle special cases in simpledrm and ofdrm. Hard-code
XRGB8888 as fallback format for cases where no given format works.

The color-mode argument accepts the same values as the kernel's video
parameter. These are mostly bpp values between 1 and 32. The exceptions
are 15, which has a color depth of 15 and a bpp value of 16; and 32,
which has a color depth of 24 and a bpp value of 32.

v4:
        * add back lost test for bpp_specified (Maira)
        * add Fixes tag (Daniel)
v3:
        * fix ofdrm build (Maxime)
v2:
        * minimize changes (Daniel)
        * use drm_driver_legacy_fb_format() (Daniel)

Signed-off-by: Thomas Zimmermann <tzimmerm...@suse.de>
Fixes: 37c90d589dc0 ("drm/fb-helper: Fix single-probe color-format selection")
Cc: Thomas Zimmermann <tzimmerm...@suse.de>
Cc: Javier Martinez Canillas <javi...@redhat.com>
Cc: Maarten Lankhorst <maarten.lankho...@linux.intel.com>
Cc: Maxime Ripard <mrip...@kernel.org>
---
  drivers/gpu/drm/drm_fb_helper.c  | 42 ++++++++++++++++++--------------
  drivers/gpu/drm/tiny/ofdrm.c     |  7 +++++-
  drivers/gpu/drm/tiny/simpledrm.c |  7 +++++-
  3 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 1369ca4ae39b..427631706128 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1756,24 +1756,21 @@ static uint32_t drm_fb_helper_find_format(struct 
drm_fb_helper *fb_helper, const
        return DRM_FORMAT_INVALID;
  }
-static uint32_t drm_fb_helper_find_cmdline_format(struct drm_fb_helper *fb_helper,
-                                                 const uint32_t *formats, 
size_t format_count,
-                                                 const struct drm_cmdline_mode 
*cmdline_mode)
+static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper 
*fb_helper,
+                                                    const uint32_t *formats, 
size_t format_count,
+                                                    unsigned int color_mode)
  {
        struct drm_device *dev = fb_helper->dev;
        uint32_t bpp, depth;
- if (!cmdline_mode->bpp_specified)
-               return DRM_FORMAT_INVALID;
-
-       switch (cmdline_mode->bpp) {
+       switch (color_mode) {
        case 1:
        case 2:
        case 4:
        case 8:
        case 16:
        case 24:
-               bpp = depth = cmdline_mode->bpp;
+               bpp = depth = color_mode;
                break;
        case 15:
                bpp = 16;
@@ -1784,7 +1781,7 @@ static uint32_t drm_fb_helper_find_cmdline_format(struct 
drm_fb_helper *fb_helpe
                depth = 24;
                break;
        default:
-               drm_info(dev, "unsupported bpp value of %d\n", 
cmdline_mode->bpp);
+               drm_info(dev, "unsupported color mode of %d\n", color_mode);
                return DRM_FORMAT_INVALID;
        }
@@ -1817,10 +1814,13 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe
                drm_client_for_each_connector_iter(connector, &conn_iter) {
                        struct drm_cmdline_mode *cmdline_mode = 
&connector->cmdline_mode;
- surface_format = drm_fb_helper_find_cmdline_format(fb_helper,
-                                                                          
plane->format_types,
-                                                                          
plane->format_count,
-                                                                          
cmdline_mode);
+                       if (!cmdline_mode->bpp_specified)
+                               continue;
+
+                       surface_format = 
drm_fb_helper_find_color_mode_format(fb_helper,
+                                                                             
plane->format_types,
+                                                                             
plane->format_count,
+                                                                             
cmdline_mode->bpp);
                        if (surface_format != DRM_FORMAT_INVALID)
                                break; /* found supported format */
                }
@@ -1829,17 +1829,23 @@ static int __drm_fb_helper_find_sizes(struct 
drm_fb_helper *fb_helper, int prefe
                if (surface_format != DRM_FORMAT_INVALID)
                        break; /* found supported format */
- /* try preferred bpp/depth */
-               surface_format = drm_fb_helper_find_format(fb_helper, 
plane->format_types,
-                                                          plane->format_count, 
preferred_bpp,
-                                                          
dev->mode_config.preferred_depth);
+               /* try preferred color mode */
+               surface_format = drm_fb_helper_find_color_mode_format(fb_helper,
+                                                                     
plane->format_types,
+                                                                     
plane->format_count,
+                                                                     
preferred_bpp);
                if (surface_format != DRM_FORMAT_INVALID)
                        break; /* found supported format */
        }
if (surface_format == DRM_FORMAT_INVALID) {
+               /*
+                * If none of the given color modes works, fall back
+                * to XRGB8888. Drivers are expected to provide this
+                * format for compatibility with legacy applications.
+                */
                drm_warn(dev, "No compatible format found\n");
-               return -EAGAIN;
+               surface_format = drm_driver_legacy_fb_format(dev, 32, 24);
        }
info = drm_format_info(surface_format);
diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
index 39c5fd463fec..6e349ca42485 100644
--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -1352,6 +1352,7 @@ static int ofdrm_probe(struct platform_device *pdev)
  {
        struct ofdrm_device *odev;
        struct drm_device *dev;
+       unsigned int color_mode;
        int ret;
odev = ofdrm_device_create(&ofdrm_driver, pdev);
@@ -1363,7 +1364,11 @@ static int ofdrm_probe(struct platform_device *pdev)
        if (ret)
                return ret;
- drm_fbdev_generic_setup(dev, drm_format_info_bpp(odev->format, 0));
+       color_mode = drm_format_info_bpp(odev->format, 0);
+       if (color_mode == 16)
+               color_mode = odev->format->depth; // can be 15 or 16
+
+       drm_fbdev_generic_setup(dev, color_mode);
return 0;
  }
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 7355617f38d3..f658b99c796a 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -802,6 +802,7 @@ static int simpledrm_probe(struct platform_device *pdev)
  {
        struct simpledrm_device *sdev;
        struct drm_device *dev;
+       unsigned int color_mode;
        int ret;
sdev = simpledrm_device_create(&simpledrm_driver, pdev);
@@ -813,7 +814,11 @@ static int simpledrm_probe(struct platform_device *pdev)
        if (ret)
                return ret;
- drm_fbdev_generic_setup(dev, drm_format_info_bpp(sdev->format, 0));
+       color_mode = drm_format_info_bpp(sdev->format, 0);
+       if (color_mode == 16)
+               color_mode = sdev->format->depth; // can be 15 or 16
+
+       drm_fbdev_generic_setup(dev, color_mode);
return 0;
  }

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to