Message ID | 20230106112324.22055-1-tzimmermann@suse.de (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | [v4] drm/fb-helper: Replace bpp/depth parameter by color mode | expand |
On 1/6/23 08:23, Thomas Zimmermann wrote: > 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 <tzimmermann@suse.de> Tested-by: Maíra Canal <mcanal@igalia.com> # vc4 and vkms Thanks for taking care of this! Best Regards, - Maíra Canal > Fixes: 37c90d589dc0 ("drm/fb-helper: Fix single-probe color-format selection") > Cc: Thomas Zimmermann <tzimmermann@suse.de> > Cc: Javier Martinez Canillas <javierm@redhat.com> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > Cc: Maxime Ripard <mripard@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; > }
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 <tzimmermann@suse.de> > Fixes: 37c90d589dc0 ("drm/fb-helper: Fix single-probe color-format selection") > Cc: Thomas Zimmermann <tzimmermann@suse.de> > Cc: Javier Martinez Canillas <javierm@redhat.com> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > Cc: Maxime Ripard <mripard@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; > }
On Fri, Jan 6, 2023 at 8:05 AM Thomas Zimmermann <tzimmermann@suse.de> wrote: > > 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 <tzimmermann@suse.de> > > Fixes: 37c90d589dc0 ("drm/fb-helper: Fix single-probe color-format selection") > > Cc: Thomas Zimmermann <tzimmermann@suse.de> > > Cc: Javier Martinez Canillas <javierm@redhat.com> > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > > Cc: Maxime Ripard <mripard@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 I know it's already in drm-misc-next, but wanted to chime in... I've tested v4 on the Thinkpad X13s as well as the Yoga C630 WoS, both msm based systems and this does fix the issue I was seeing as well as make my patch not needed and can be considered abandoned. Tested-by: Steev Klimaszewski <steev@kali.org>
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; }
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 <tzimmermann@suse.de> Fixes: 37c90d589dc0 ("drm/fb-helper: Fix single-probe color-format selection") Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Javier Martinez Canillas <javierm@redhat.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@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(-)