From 0e94043ee1d98d5112aa4e1d68733b0197dfdafa Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 5 Sep 2018 08:04:40 +0200 Subject: drm: replace DRIVER_PREFER_XBGR_30BPP driver flag with mode_config quirk Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20180905060445.15008-2-kraxel@redhat.com --- drivers/gpu/drm/drm_framebuffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_framebuffer.c') diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 781af1d42d76..17b7b8944de5 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -120,8 +120,8 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or, r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); r.handles[0] = or->handle; - if (r.pixel_format == DRM_FORMAT_XRGB2101010 && - dev->driver->driver_features & DRIVER_PREFER_XBGR_30BPP) + if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp && + r.pixel_format == DRM_FORMAT_XRGB2101010) r.pixel_format = DRM_FORMAT_XBGR2101010; ret = drm_mode_addfb2(dev, &r, file_priv); -- cgit From 00409fd6f14f1a3f06c6ea50a6f2fba17c5573d9 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 5 Sep 2018 08:04:42 +0200 Subject: drm: do not mask out DRM_FORMAT_BIG_ENDIAN framebuffer_check() expects that drm_get_format_info() will not fail if the __drm_format_info() call was successful. That'll work only in case both are called with the same pixel_format value, so masking out the DRM_FORMAT_BIG_ENDIAN flag isn't a good idea. Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20180905060445.15008-4-kraxel@redhat.com --- drivers/gpu/drm/drm_framebuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/drm_framebuffer.c') diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 17b7b8944de5..888c4d53cf23 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -164,7 +164,7 @@ static int framebuffer_check(struct drm_device *dev, int i; /* check if the format is supported at all */ - info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); + info = __drm_format_info(r->pixel_format); if (!info) { struct drm_format_name_buf format_name; -- cgit From 6960e6da9cec3f6638121527c728305827ec12ab Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 5 Sep 2018 08:04:43 +0200 Subject: drm: fix drm_mode_addfb() on big endian machines. Userspace on big endian machhines typically expects the ADDFB ioctl returns a big endian framebuffer. drm_mode_addfb() will call drm_mode_addfb2() unconditionally with little endian DRM_FORMAT_* values though, which is wrong. This patch fixes that. Drivers (both kernel and xorg) have quirks in place to deal with the broken drm_mode_addfb() behavior. Because of this we can't just change drm_mode_addfb() behavior for everybody without breaking things. Add the quirk_addfb_prefer_host_byte_order field to mode_config, so drivers can opt-in. Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20180905060445.15008-5-kraxel@redhat.com --- drivers/gpu/drm/drm_framebuffer.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/gpu/drm/drm_framebuffer.c') diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 888c4d53cf23..f863f8a20f8c 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -124,6 +124,17 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or, r.pixel_format == DRM_FORMAT_XRGB2101010) r.pixel_format = DRM_FORMAT_XBGR2101010; + if (dev->mode_config.quirk_addfb_prefer_host_byte_order) { + if (r.pixel_format == DRM_FORMAT_XRGB8888) + r.pixel_format = DRM_FORMAT_HOST_XRGB8888; + if (r.pixel_format == DRM_FORMAT_ARGB8888) + r.pixel_format = DRM_FORMAT_HOST_ARGB8888; + if (r.pixel_format == DRM_FORMAT_RGB565) + r.pixel_format = DRM_FORMAT_HOST_RGB565; + if (r.pixel_format == DRM_FORMAT_XRGB1555) + r.pixel_format = DRM_FORMAT_HOST_XRGB1555; + } + ret = drm_mode_addfb2(dev, &r, file_priv); if (ret) return ret; -- cgit From 70109354fed232dfce8fb2c7cadf635acbe03e19 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 5 Sep 2018 16:31:16 +0100 Subject: drm: Reject unknown legacy bpp and depth for drm_mode_addfb ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since this is handling user provided bpp and depth, we need to sanity check and propagate the EINVAL back rather than assume what the insane client intended and fill the logs with DRM_ERROR. v2: Check both bpp and depth match the builtin pixel format, and introduce a canonical DRM_FORMAT_INVALID to reserve 0 against any future fourcc. v3: Mark up DRM_FORMAT_C8 as being {bpp:8, depth:8} Testcase: igt/kms_addfb_basic/legacy-format Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Ville Syrjälä Cc: Michel Dänzer Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180905153116.28924-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_framebuffer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/drm_framebuffer.c') diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index f863f8a20f8c..c8a7829d73d6 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -112,12 +112,17 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or, struct drm_mode_fb_cmd2 r = {}; int ret; + r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); + if (r.pixel_format == DRM_FORMAT_INVALID) { + DRM_DEBUG("bad {bpp:%d, depth:%d}\n", or->bpp, or->depth); + return -EINVAL; + } + /* convert to new format and call new ioctl */ r.fb_id = or->fb_id; r.width = or->width; r.height = or->height; r.pitches[0] = or->pitch; - r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); r.handles[0] = or->handle; if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp && -- cgit From 72fdb40c1a4b48f5fa6f6083ea7419b94639ed57 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 5 Sep 2018 15:57:11 +0200 Subject: drm: extract drm_atomic_uapi.c This leaves all the commit/check and state handling in drm_atomic.c, while pulling all the uapi glue and the huge ioctl itself into a seprate file. This seems to almost perfectly split the rather big drm_atomic.c file into 2 equal sizes. Also adjust the kerneldoc and type a very terse overview text. v2: Rebase. v3: Fix tiny typo. v4: - Fixup armada, newly converted atomic driver hooray! - Fixup msm/dpu1, newly added too. Signed-off-by: Daniel Vetter Cc: David Airlie Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Rob Clark Cc: Eric Anholt Cc: intel-gfx@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Acked-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180905135711.28370-7-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_framebuffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/drm_framebuffer.c') diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index c8a7829d73d6..227f52e55d05 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "drm_internal.h" -- cgit From eae06120f1974e1a4cab0f80f4b07d27eb80ab32 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 7 Sep 2018 09:32:13 +0200 Subject: drm: refuse ADDFB2 ioctl for broken bigendian drivers Drivers must set the quirk_addfb_prefer_host_byte_order quirk to make the drm_mode_addfb() compat code work correctly on bigendian machines. If they don't they interpret pixel_format values incorrectly for bug compatibility, which in turn implies the ADDFB2 ioctl does not work correctly then. So block it to make userspace fallback to ADDFB. Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20180907073213.20410-1-kraxel@redhat.com --- drivers/gpu/drm/drm_framebuffer.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/gpu/drm/drm_framebuffer.c') diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 227f52e55d05..6eaacd4eb8cc 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -369,6 +369,30 @@ int drm_mode_addfb2(struct drm_device *dev, return 0; } +int drm_mode_addfb2_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ +#ifdef __BIG_ENDIAN + if (!dev->mode_config.quirk_addfb_prefer_host_byte_order) { + /* + * Drivers must set the + * quirk_addfb_prefer_host_byte_order quirk to make + * the drm_mode_addfb() compat code work correctly on + * bigendian machines. + * + * If they don't they interpret pixel_format values + * incorrectly for bug compatibility, which in turn + * implies the ADDFB2 ioctl does not work correctly + * then. So block it to make userspace fallback to + * ADDFB. + */ + DRM_DEBUG_KMS("addfb2 broken on bigendian"); + return -EINVAL; + } +#endif + return drm_mode_addfb2(dev, data, file_priv); +} + struct drm_mode_rmfb_work { struct work_struct work; struct list_head fbs; -- cgit