Commit d3533a8a authored by Thomas Zimmermann's avatar Thomas Zimmermann

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

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: default avatarThomas Zimmermann <tzimmermann@suse.de>
Tested-by: Maíra Canal <mcanal@igalia.com> # vc4 and vkms
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Fixes: 37c90d58 ("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>
Link: https://patchwork.freedesktop.org/patch/msgid/20230106112324.22055-1-tzimmermann@suse.de
parent 4c00ac50
...@@ -1756,24 +1756,21 @@ static uint32_t drm_fb_helper_find_format(struct drm_fb_helper *fb_helper, const ...@@ -1756,24 +1756,21 @@ static uint32_t drm_fb_helper_find_format(struct drm_fb_helper *fb_helper, const
return DRM_FORMAT_INVALID; return DRM_FORMAT_INVALID;
} }
static uint32_t drm_fb_helper_find_cmdline_format(struct drm_fb_helper *fb_helper, static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper *fb_helper,
const uint32_t *formats, size_t format_count, const uint32_t *formats, size_t format_count,
const struct drm_cmdline_mode *cmdline_mode) unsigned int color_mode)
{ {
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
uint32_t bpp, depth; uint32_t bpp, depth;
if (!cmdline_mode->bpp_specified) switch (color_mode) {
return DRM_FORMAT_INVALID;
switch (cmdline_mode->bpp) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
case 8: case 8:
case 16: case 16:
case 24: case 24:
bpp = depth = cmdline_mode->bpp; bpp = depth = color_mode;
break; break;
case 15: case 15:
bpp = 16; bpp = 16;
...@@ -1784,7 +1781,7 @@ static uint32_t drm_fb_helper_find_cmdline_format(struct drm_fb_helper *fb_helpe ...@@ -1784,7 +1781,7 @@ static uint32_t drm_fb_helper_find_cmdline_format(struct drm_fb_helper *fb_helpe
depth = 24; depth = 24;
break; break;
default: 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; return DRM_FORMAT_INVALID;
} }
...@@ -1817,10 +1814,13 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe ...@@ -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) { drm_client_for_each_connector_iter(connector, &conn_iter) {
struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode; struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
surface_format = drm_fb_helper_find_cmdline_format(fb_helper, if (!cmdline_mode->bpp_specified)
continue;
surface_format = drm_fb_helper_find_color_mode_format(fb_helper,
plane->format_types, plane->format_types,
plane->format_count, plane->format_count,
cmdline_mode); cmdline_mode->bpp);
if (surface_format != DRM_FORMAT_INVALID) if (surface_format != DRM_FORMAT_INVALID)
break; /* found supported format */ break; /* found supported format */
} }
...@@ -1829,17 +1829,23 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe ...@@ -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) if (surface_format != DRM_FORMAT_INVALID)
break; /* found supported format */ break; /* found supported format */
/* try preferred bpp/depth */ /* try preferred color mode */
surface_format = drm_fb_helper_find_format(fb_helper, plane->format_types, surface_format = drm_fb_helper_find_color_mode_format(fb_helper,
plane->format_count, preferred_bpp, plane->format_types,
dev->mode_config.preferred_depth); plane->format_count,
preferred_bpp);
if (surface_format != DRM_FORMAT_INVALID) if (surface_format != DRM_FORMAT_INVALID)
break; /* found supported format */ break; /* found supported format */
} }
if (surface_format == DRM_FORMAT_INVALID) { 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"); 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); info = drm_format_info(surface_format);
......
...@@ -1352,6 +1352,7 @@ static int ofdrm_probe(struct platform_device *pdev) ...@@ -1352,6 +1352,7 @@ static int ofdrm_probe(struct platform_device *pdev)
{ {
struct ofdrm_device *odev; struct ofdrm_device *odev;
struct drm_device *dev; struct drm_device *dev;
unsigned int color_mode;
int ret; int ret;
odev = ofdrm_device_create(&ofdrm_driver, pdev); odev = ofdrm_device_create(&ofdrm_driver, pdev);
...@@ -1363,7 +1364,11 @@ static int ofdrm_probe(struct platform_device *pdev) ...@@ -1363,7 +1364,11 @@ static int ofdrm_probe(struct platform_device *pdev)
if (ret) if (ret)
return 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; return 0;
} }
......
...@@ -802,6 +802,7 @@ static int simpledrm_probe(struct platform_device *pdev) ...@@ -802,6 +802,7 @@ static int simpledrm_probe(struct platform_device *pdev)
{ {
struct simpledrm_device *sdev; struct simpledrm_device *sdev;
struct drm_device *dev; struct drm_device *dev;
unsigned int color_mode;
int ret; int ret;
sdev = simpledrm_device_create(&simpledrm_driver, pdev); sdev = simpledrm_device_create(&simpledrm_driver, pdev);
...@@ -813,7 +814,11 @@ static int simpledrm_probe(struct platform_device *pdev) ...@@ -813,7 +814,11 @@ static int simpledrm_probe(struct platform_device *pdev)
if (ret) if (ret)
return 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; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment