From: Thomas Zimmermann <tzimmermann@suse.de>
To: daniel@ffwll.ch, airlied@gmail.com, javierm@redhat.com,
jose.exposito89@gmail.com, mairacanal@riseup.net,
mripard@kernel.org, maarten.lankhorst@linux.intel.com
Cc: Thomas Zimmermann <tzimmermann@suse.de>, dri-devel@lists.freedesktop.org
Subject: [PATCH v2 11/13] drm/fb-helper: Fix single-probe color-format selection
Date: Tue, 20 Dec 2022 17:11:43 +0100 [thread overview]
Message-ID: <20221220161145.27568-12-tzimmermann@suse.de> (raw)
In-Reply-To: <20221220161145.27568-1-tzimmermann@suse.de>
Fix the color-format selection of the single-probe helper. Go
through all user-specified values and test each for compatibility
with the driver. If none is supported, use the driver-provided
default. This guarantees that the console is always available in
any color format at least.
Until now, the format selection of the single-probe helper tried
to either use a user-specified format or a 32-bit default format.
If the user-specified format was not supported by the driver, the
selection failed and the display remained blank.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
drivers/gpu/drm/drm_fb_helper.c | 172 +++++++++++++++++---------------
1 file changed, 94 insertions(+), 78 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index af1495394d38..1369ca4ae39b 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1726,6 +1726,70 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
}
EXPORT_SYMBOL(drm_fb_helper_pan_display);
+static uint32_t drm_fb_helper_find_format(struct drm_fb_helper *fb_helper, const uint32_t *formats,
+ size_t format_count, uint32_t bpp, uint32_t depth)
+{
+ struct drm_device *dev = fb_helper->dev;
+ uint32_t format;
+ size_t i;
+
+ /*
+ * Do not consider YUV or other complicated formats
+ * for framebuffers. This means only legacy formats
+ * are supported (fmt->depth is a legacy field), but
+ * the framebuffer emulation can only deal with such
+ * formats, specifically RGB/BGA formats.
+ */
+ format = drm_mode_legacy_fb_format(bpp, depth);
+ if (!format)
+ goto err;
+
+ for (i = 0; i < format_count; ++i) {
+ if (formats[i] == format)
+ return format;
+ }
+
+err:
+ /* We found nothing. */
+ drm_warn(dev, "bpp/depth value of %u/%u not supported\n", bpp, depth);
+
+ 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)
+{
+ struct drm_device *dev = fb_helper->dev;
+ uint32_t bpp, depth;
+
+ if (!cmdline_mode->bpp_specified)
+ return DRM_FORMAT_INVALID;
+
+ switch (cmdline_mode->bpp) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ case 24:
+ bpp = depth = cmdline_mode->bpp;
+ break;
+ case 15:
+ bpp = 16;
+ depth = 15;
+ break;
+ case 32:
+ bpp = 32;
+ depth = 24;
+ break;
+ default:
+ drm_info(dev, "unsupported bpp value of %d\n", cmdline_mode->bpp);
+ return DRM_FORMAT_INVALID;
+ }
+
+ return drm_fb_helper_find_format(fb_helper, formats, format_count, bpp, depth);
+}
static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp,
struct drm_fb_helper_surface_size *sizes)
@@ -1736,100 +1800,52 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe
struct drm_connector_list_iter conn_iter;
struct drm_connector *connector;
struct drm_mode_set *mode_set;
- int best_depth = 0;
+ uint32_t surface_format = DRM_FORMAT_INVALID;
+ const struct drm_format_info *info;
- memset(sizes, 0, sizeof(struct drm_fb_helper_surface_size));
- sizes->surface_depth = 24;
- sizes->surface_bpp = 32;
+ memset(sizes, 0, sizeof(*sizes));
sizes->fb_width = (u32)-1;
sizes->fb_height = (u32)-1;
- /*
- * If driver picks 8 or 16 by default use that for both depth/bpp
- * to begin with
- */
- if (preferred_bpp != sizes->surface_bpp)
- sizes->surface_depth = sizes->surface_bpp = preferred_bpp;
-
- drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
- drm_client_for_each_connector_iter(connector, &conn_iter) {
- struct drm_cmdline_mode *cmdline_mode;
-
- cmdline_mode = &connector->cmdline_mode;
-
- if (cmdline_mode->bpp_specified) {
- switch (cmdline_mode->bpp) {
- case 8:
- sizes->surface_depth = sizes->surface_bpp = 8;
- break;
- case 15:
- sizes->surface_depth = 15;
- sizes->surface_bpp = 16;
- break;
- case 16:
- sizes->surface_depth = sizes->surface_bpp = 16;
- break;
- case 24:
- sizes->surface_depth = sizes->surface_bpp = 24;
- break;
- case 32:
- sizes->surface_depth = 24;
- sizes->surface_bpp = 32;
- break;
- }
- break;
- }
- }
- drm_connector_list_iter_end(&conn_iter);
-
- /*
- * If we run into a situation where, for example, the primary plane
- * supports RGBA5551 (16 bpp, depth 15) but not RGB565 (16 bpp, depth
- * 16) we need to scale down the depth of the sizes we request.
- */
drm_client_for_each_modeset(mode_set, client) {
struct drm_crtc *crtc = mode_set->crtc;
struct drm_plane *plane = crtc->primary;
- int j;
drm_dbg_kms(dev, "test CRTC %u primary plane\n", drm_crtc_index(crtc));
- for (j = 0; j < plane->format_count; j++) {
- const struct drm_format_info *fmt;
-
- fmt = drm_format_info(plane->format_types[j]);
+ drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
+ drm_client_for_each_connector_iter(connector, &conn_iter) {
+ struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
- /*
- * Do not consider YUV or other complicated formats
- * for framebuffers. This means only legacy formats
- * are supported (fmt->depth is a legacy field) but
- * the framebuffer emulation can only deal with such
- * formats, specifically RGB/BGA formats.
- */
- if (fmt->depth == 0)
- continue;
-
- /* We found a perfect fit, great */
- if (fmt->depth == sizes->surface_depth) {
- best_depth = fmt->depth;
- break;
- }
+ surface_format = drm_fb_helper_find_cmdline_format(fb_helper,
+ plane->format_types,
+ plane->format_count,
+ cmdline_mode);
+ if (surface_format != DRM_FORMAT_INVALID)
+ break; /* found supported format */
+ }
+ drm_connector_list_iter_end(&conn_iter);
- /* Skip depths above what we're looking for */
- if (fmt->depth > sizes->surface_depth)
- continue;
+ if (surface_format != DRM_FORMAT_INVALID)
+ break; /* found supported format */
- /* Best depth found so far */
- if (fmt->depth > best_depth)
- best_depth = fmt->depth;
- }
+ /* 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);
+ if (surface_format != DRM_FORMAT_INVALID)
+ break; /* found supported format */
}
- if (sizes->surface_depth != best_depth && best_depth) {
- drm_info(dev, "requested bpp %d, scaled depth down to %d",
- sizes->surface_bpp, best_depth);
- sizes->surface_depth = best_depth;
+
+ if (surface_format == DRM_FORMAT_INVALID) {
+ drm_warn(dev, "No compatible format found\n");
+ return -EAGAIN;
}
+ info = drm_format_info(surface_format);
+ sizes->surface_bpp = drm_format_info_bpp(info, 0);
+ sizes->surface_depth = info->depth;
+
/* first up get a count of crtcs now in use and new min/maxes width/heights */
crtc_count = 0;
drm_client_for_each_modeset(mode_set, client) {
--
2.39.0
next prev parent reply other threads:[~2022-12-20 16:12 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-20 16:11 [PATCH v2 00/13] drm: Fix color-format selection in fbdev emulation Thomas Zimmermann
2022-12-20 16:11 ` [PATCH v2 01/13] firmware/sysfb: Fix EFI/VESA format selection Thomas Zimmermann
2022-12-20 16:11 ` [PATCH v2 02/13] drm/format-helper: Comment on RGB888 byte order Thomas Zimmermann
2022-12-21 19:30 ` Maíra Canal
2022-12-23 12:37 ` José Expósito
2022-12-20 16:11 ` [PATCH v2 03/13] drm/format-helper: Fix test-input format conversion Thomas Zimmermann
2022-12-21 19:40 ` Maíra Canal
2022-12-23 12:38 ` José Expósito
2022-12-20 16:11 ` [PATCH v2 04/13] drm/format-helper: Store RGB565 in little-endian order Thomas Zimmermann
2022-12-21 19:55 ` Maíra Canal
2022-12-23 12:39 ` José Expósito
2022-12-20 16:11 ` [PATCH v2 05/13] drm/format-helper: Type fixes in format-helper tests Thomas Zimmermann
2022-12-21 19:58 ` Maíra Canal
2022-12-23 12:40 ` José Expósito
2022-12-20 16:11 ` [PATCH v2 06/13] drm/format-helper: Flip src/dst-format branches in blit helper Thomas Zimmermann
2022-12-20 16:11 ` [PATCH v2 07/13] drm/format-helper: Add conversion from XRGB8888 to ARGB8888 Thomas Zimmermann
2022-12-21 12:37 ` kernel test robot
2022-12-21 12:37 ` kernel test robot
2022-12-21 20:07 ` Maíra Canal
2023-01-02 10:00 ` Thomas Zimmermann
2022-12-23 12:44 ` José Expósito
2023-01-02 10:01 ` Thomas Zimmermann
2022-12-20 16:11 ` [PATCH v2 08/13] drm/format-helper: Add conversion from XRGB8888 to ARGB2101010 Thomas Zimmermann
2022-12-23 12:45 ` José Expósito
2022-12-20 16:11 ` [PATCH v2 09/13] drm/format-helper: Add conversion from XRGB8888 to 15-bit RGB555 formats Thomas Zimmermann
2022-12-21 13:58 ` kernel test robot
2022-12-21 13:58 ` kernel test robot
2022-12-23 12:48 ` José Expósito
2022-12-20 16:11 ` [PATCH v2 10/13] drm/fh-helper: Split fbdev single-probe helper Thomas Zimmermann
2022-12-20 16:11 ` Thomas Zimmermann [this message]
2022-12-20 16:11 ` [PATCH v2 12/13] drm/format-helper: Simplify drm_fb_build_fourcc_list() Thomas Zimmermann
2022-12-20 16:11 ` [PATCH v2 13/13] drm/format-helper: Remove unnecessary conversion helpers Thomas Zimmermann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221220161145.27568-12-tzimmermann@suse.de \
--to=tzimmermann@suse.de \
--cc=airlied@gmail.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=javierm@redhat.com \
--cc=jose.exposito89@gmail.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mairacanal@riseup.net \
--cc=mripard@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.