aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_framebuffer.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-09-13 19:43:06 -0400
committerDave Airlie <airlied@redhat.com>2018-09-13 19:43:16 -0400
commit2dc7bad71cd310dc94d1c9907909324dd2b0618f (patch)
treea087555dd4b1588eeac02c1af5d8dde7b5bb15fa /drivers/gpu/drm/drm_framebuffer.c
parentb1c1566822ab489a945dfdafee651aa29de160c7 (diff)
parent169cc4c7a14e988985c8833ddec2f3e897de2c28 (diff)
Merge tag 'drm-misc-next-2018-09-13' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 4.20: UAPI Changes: - Add host endian variants for the most common formats (Gerd) - Fail ADDFB2 for big-endian drivers that don't advertise BE quirk (Gerd) - clear smem_start in fbdev for drm drivers to avoid leaking fb addr (Daniel) Cross-subsystem Changes: Core Changes: - fix drm_mode_addfb() on big endian machines (Gerd) - add timeline point to syncobj find+replace (Chunming) - more drmP.h removal effort (Daniel) - split uapi portions of drm_atomic.c into drm_atomic_uapi.c (Daniel) Driver Changes: - bochs: Convert open-coded portions to use helpers (Peter) - vkms: Add cursor support (Haneen) - udmabuf: Lots of fixups (mostly cosmetic afaict) (Gerd) - qxl: Convert to use fbdev helper (Peter) Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Chunming Zhou <david1.zhou@amd.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Peter Wu <peter@lekensteyn.nl> Cc: Haneen Mohammed <hamohammed.sa@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com> From: Sean Paul <sean@poorly.run> Link: https://patchwork.freedesktop.org/patch/msgid/20180913130254.GA156437@art_vandelay
Diffstat (limited to 'drivers/gpu/drm/drm_framebuffer.c')
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 781af1d42d76..6eaacd4eb8cc 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -25,6 +25,7 @@
25#include <drm/drm_auth.h> 25#include <drm/drm_auth.h>
26#include <drm/drm_framebuffer.h> 26#include <drm/drm_framebuffer.h>
27#include <drm/drm_atomic.h> 27#include <drm/drm_atomic.h>
28#include <drm/drm_atomic_uapi.h>
28#include <drm/drm_print.h> 29#include <drm/drm_print.h>
29 30
30#include "drm_internal.h" 31#include "drm_internal.h"
@@ -112,18 +113,34 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,
112 struct drm_mode_fb_cmd2 r = {}; 113 struct drm_mode_fb_cmd2 r = {};
113 int ret; 114 int ret;
114 115
116 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
117 if (r.pixel_format == DRM_FORMAT_INVALID) {
118 DRM_DEBUG("bad {bpp:%d, depth:%d}\n", or->bpp, or->depth);
119 return -EINVAL;
120 }
121
115 /* convert to new format and call new ioctl */ 122 /* convert to new format and call new ioctl */
116 r.fb_id = or->fb_id; 123 r.fb_id = or->fb_id;
117 r.width = or->width; 124 r.width = or->width;
118 r.height = or->height; 125 r.height = or->height;
119 r.pitches[0] = or->pitch; 126 r.pitches[0] = or->pitch;
120 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
121 r.handles[0] = or->handle; 127 r.handles[0] = or->handle;
122 128
123 if (r.pixel_format == DRM_FORMAT_XRGB2101010 && 129 if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp &&
124 dev->driver->driver_features & DRIVER_PREFER_XBGR_30BPP) 130 r.pixel_format == DRM_FORMAT_XRGB2101010)
125 r.pixel_format = DRM_FORMAT_XBGR2101010; 131 r.pixel_format = DRM_FORMAT_XBGR2101010;
126 132
133 if (dev->mode_config.quirk_addfb_prefer_host_byte_order) {
134 if (r.pixel_format == DRM_FORMAT_XRGB8888)
135 r.pixel_format = DRM_FORMAT_HOST_XRGB8888;
136 if (r.pixel_format == DRM_FORMAT_ARGB8888)
137 r.pixel_format = DRM_FORMAT_HOST_ARGB8888;
138 if (r.pixel_format == DRM_FORMAT_RGB565)
139 r.pixel_format = DRM_FORMAT_HOST_RGB565;
140 if (r.pixel_format == DRM_FORMAT_XRGB1555)
141 r.pixel_format = DRM_FORMAT_HOST_XRGB1555;
142 }
143
127 ret = drm_mode_addfb2(dev, &r, file_priv); 144 ret = drm_mode_addfb2(dev, &r, file_priv);
128 if (ret) 145 if (ret)
129 return ret; 146 return ret;
@@ -164,7 +181,7 @@ static int framebuffer_check(struct drm_device *dev,
164 int i; 181 int i;
165 182
166 /* check if the format is supported at all */ 183 /* check if the format is supported at all */
167 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); 184 info = __drm_format_info(r->pixel_format);
168 if (!info) { 185 if (!info) {
169 struct drm_format_name_buf format_name; 186 struct drm_format_name_buf format_name;
170 187
@@ -352,6 +369,30 @@ int drm_mode_addfb2(struct drm_device *dev,
352 return 0; 369 return 0;
353} 370}
354 371
372int drm_mode_addfb2_ioctl(struct drm_device *dev,
373 void *data, struct drm_file *file_priv)
374{
375#ifdef __BIG_ENDIAN
376 if (!dev->mode_config.quirk_addfb_prefer_host_byte_order) {
377 /*
378 * Drivers must set the
379 * quirk_addfb_prefer_host_byte_order quirk to make
380 * the drm_mode_addfb() compat code work correctly on
381 * bigendian machines.
382 *
383 * If they don't they interpret pixel_format values
384 * incorrectly for bug compatibility, which in turn
385 * implies the ADDFB2 ioctl does not work correctly
386 * then. So block it to make userspace fallback to
387 * ADDFB.
388 */
389 DRM_DEBUG_KMS("addfb2 broken on bigendian");
390 return -EINVAL;
391 }
392#endif
393 return drm_mode_addfb2(dev, data, file_priv);
394}
395
355struct drm_mode_rmfb_work { 396struct drm_mode_rmfb_work {
356 struct work_struct work; 397 struct work_struct work;
357 struct list_head fbs; 398 struct list_head fbs;