diff mbox series

[v4] drm/fb-helper: Replace bpp/depth parameter by color mode

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

Commit Message

Thomas Zimmermann Jan. 6, 2023, 11:23 a.m. UTC
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(-)

Comments

Maíra Canal Jan. 6, 2023, 11:39 a.m. UTC | #1
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;
>   }
Thomas Zimmermann Jan. 6, 2023, 2:05 p.m. UTC | #2
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;
>   }
Steev Klimaszewski Jan. 6, 2023, 9:03 p.m. UTC | #3
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 mbox series

Patch

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;
 }