From a99b57dbc09bfff57acd8a7c20f25dfa6cb892a5 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:19 +0100 Subject: drm: Move the GET_CAP macros next to the corresponding ioctl structure It's a tiny bit more logical to find the different capabilities you can use with the GET_CAP ioctl next to the structure rather than putting them at the end of the file. v2: Tab align the litterals (David Herrmann) v3: Make it clearer that DRM_PRIME_CAP_EXPORT/IMPORT are flags of DRM_CAP_PRIME. v4: Rebase on top of latest bits (DRM_CAP_ASYNC_PAGE_FLIP was introduced) Reviewed-by: David Herrmann (for v2) Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- include/uapi/drm/drm.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index ece867889cc7..1e09e8f257ba 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -611,6 +611,16 @@ struct drm_gem_open { __u64 size; }; +#define DRM_CAP_DUMB_BUFFER 0x1 +#define DRM_CAP_VBLANK_HIGH_CRTC 0x2 +#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 +#define DRM_CAP_DUMB_PREFER_SHADOW 0x4 +#define DRM_CAP_PRIME 0x5 +#define DRM_PRIME_CAP_IMPORT 0x1 +#define DRM_PRIME_CAP_EXPORT 0x2 +#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 +#define DRM_CAP_ASYNC_PAGE_FLIP 0x7 + /** DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap { __u64 capability; @@ -774,17 +784,6 @@ struct drm_event_vblank { __u32 reserved; }; -#define DRM_CAP_DUMB_BUFFER 0x1 -#define DRM_CAP_VBLANK_HIGH_CRTC 0x2 -#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 -#define DRM_CAP_DUMB_PREFER_SHADOW 0x4 -#define DRM_CAP_PRIME 0x5 -#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 -#define DRM_CAP_ASYNC_PAGE_FLIP 0x7 - -#define DRM_PRIME_CAP_IMPORT 0x1 -#define DRM_PRIME_CAP_EXPORT 0x2 - /* typedef area */ #ifndef __KERNEL__ typedef struct drm_clip_rect drm_clip_rect_t; -- cgit v1.2.3 From 1c0814fed3a558146402713028cb7114734ec172 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:20 +0100 Subject: drm: Add a SET_CLIENT_CAP ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ioctl can be used to turn some knobs in a DRM driver. The client can ask the DRM core for an alternate view of the reality: it can be useful to be able to instruct the core that the DRM client can handle new functionnality that would otherwise break current ABI. v2: Rename to ioctl from SET_CAP to SET_CLIENT_CAP (Chris Wilson) Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_drv.c | 1 + drivers/gpu/drm/drm_ioctl.c | 9 +++++++++ include/drm/drmP.h | 2 ++ include/uapi/drm/drm.h | 7 +++++++ 4 files changed, 19 insertions(+) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index e572dd20bdee..e79d8d9ca203 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -69,6 +69,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 07247e2855a2..15da4124ee12 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -302,6 +302,15 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) return 0; } +/** + * Set device/driver capabilities + */ +int +drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + return -EINVAL; +} + /** * Setversion ioctl. * diff --git a/include/drm/drmP.h b/include/drm/drmP.h index b46fb45f2cca..dbc86b06a724 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1303,6 +1303,8 @@ extern int drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_setclientcap(struct drm_device *dev, void *data, + struct drm_file *file_priv); extern int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_noop(struct drm_device *dev, void *data, diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 1e09e8f257ba..526baed365ff 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -627,6 +627,12 @@ struct drm_get_cap { __u64 value; }; +/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ +struct drm_set_client_cap { + __u64 capability; + __u64 value; +}; + #define DRM_CLOEXEC O_CLOEXEC struct drm_prime_handle { __u32 handle; @@ -659,6 +665,7 @@ struct drm_prime_handle { #define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) #define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) #define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap) +#define DRM_IOCTL_SET_CLIENT_CAP DRM_IOW( 0x0d, struct drm_set_client_cap) #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) -- cgit v1.2.3 From 4aa17cf0d889cfc984b68a78ae02070cef21bb6b Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:21 +0100 Subject: drm: Add HDMI stereo 3D flags to struct drm_mode_modeinfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HDMI 1.4a defines a few layouts that we'd like to expose. This commits add new modeinfo flags that can be used to list the supported stereo layouts (when querying the list of modes) and to set a given stereo 3D mode (when setting a mode). v2: Add a drm_mode_is_stereo() helper Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 14 ++++++++++++++ include/uapi/drm/drm_mode.h | 36 ++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 14 deletions(-) (limited to 'include/uapi') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 24f499569a2f..825d6fad0981 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -180,6 +180,20 @@ struct drm_display_mode { int hsync; /* in kHz */ }; +#define DRM_MODE_FLAG_3D_MASK (DRM_MODE_FLAG_3D_FRAME_PACKING | \ + DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE | \ + DRM_MODE_FLAG_3D_LINE_ALTERNATIVE | \ + DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL | \ + DRM_MODE_FLAG_3D_L_DEPTH | \ + DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH | \ + DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | \ + DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF) + +static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode) +{ + return mode->flags & DRM_MODE_FLAG_3D_MASK; +} + enum drm_connector_status { connector_status_connected = 1, connector_status_disconnected = 2, diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 113d32457fa4..bafe61252754 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -44,20 +44,28 @@ /* Video mode flags */ /* bit compatible with the xorg definitions. */ -#define DRM_MODE_FLAG_PHSYNC (1<<0) -#define DRM_MODE_FLAG_NHSYNC (1<<1) -#define DRM_MODE_FLAG_PVSYNC (1<<2) -#define DRM_MODE_FLAG_NVSYNC (1<<3) -#define DRM_MODE_FLAG_INTERLACE (1<<4) -#define DRM_MODE_FLAG_DBLSCAN (1<<5) -#define DRM_MODE_FLAG_CSYNC (1<<6) -#define DRM_MODE_FLAG_PCSYNC (1<<7) -#define DRM_MODE_FLAG_NCSYNC (1<<8) -#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ -#define DRM_MODE_FLAG_BCAST (1<<10) -#define DRM_MODE_FLAG_PIXMUX (1<<11) -#define DRM_MODE_FLAG_DBLCLK (1<<12) -#define DRM_MODE_FLAG_CLKDIV2 (1<<13) +#define DRM_MODE_FLAG_PHSYNC (1<<0) +#define DRM_MODE_FLAG_NHSYNC (1<<1) +#define DRM_MODE_FLAG_PVSYNC (1<<2) +#define DRM_MODE_FLAG_NVSYNC (1<<3) +#define DRM_MODE_FLAG_INTERLACE (1<<4) +#define DRM_MODE_FLAG_DBLSCAN (1<<5) +#define DRM_MODE_FLAG_CSYNC (1<<6) +#define DRM_MODE_FLAG_PCSYNC (1<<7) +#define DRM_MODE_FLAG_NCSYNC (1<<8) +#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ +#define DRM_MODE_FLAG_BCAST (1<<10) +#define DRM_MODE_FLAG_PIXMUX (1<<11) +#define DRM_MODE_FLAG_DBLCLK (1<<12) +#define DRM_MODE_FLAG_CLKDIV2 (1<<13) +#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) +#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (1<<15) +#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (1<<16) +#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (1<<17) +#define DRM_MODE_FLAG_3D_L_DEPTH (1<<18) +#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (1<<19) +#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (1<<20) +#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (1<<21) /* DPMS flags */ /* bit compatible with the xorg definitions. */ -- cgit v1.2.3 From 61d8e3282541139cf5bb31e4c42f952a6cc168f8 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:22 +0100 Subject: drm: Add a STEREO_3D capability to the SET_CLIENT_CAP ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This capability allows user space to control the delivery of modes with the 3D flags set. This is to not play games with current user space users not knowing anything about stereo 3D flags and that could try to set a mode with one or several of those bits set. So, the plan is to remove the stereo modes from the list of modes we give to DRM clients by default, and let them through if we are being told otherwise. stereo_allowed is bound to the drm_file structure to make it a per-client setting, not a global one. v2: Replace clearing 3D flags by discarding the stereo modes now that they are regular modes. v3: SET_CAP -> SET_CLIENT_CAP rename (Chris Wilson) Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 19 ++++++++++++++++++- drivers/gpu/drm/drm_ioctl.c | 14 +++++++++++++- include/drm/drmP.h | 3 +++ include/uapi/drm/drm.h | 9 +++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e79577cb4665..454ac8a6381c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1581,6 +1581,19 @@ out: return ret; } +static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, + const struct drm_file *file_priv) +{ + /* + * If user-space hasn't configured the driver to expose the stereo 3D + * modes, don't expose them. + */ + if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode)) + return false; + + return true; +} + /** * drm_mode_getconnector - get connector configuration * @dev: drm device for the ioctl @@ -1646,7 +1659,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, /* delayed so we get modes regardless of pre-fill_modes state */ list_for_each_entry(mode, &connector->modes, head) - mode_count++; + if (drm_mode_expose_to_userspace(mode, file_priv)) + mode_count++; out_resp->connector_id = connector->base.id; out_resp->connector_type = connector->connector_type; @@ -1668,6 +1682,9 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, copied = 0; mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr; list_for_each_entry(mode, &connector->modes, head) { + if (!drm_mode_expose_to_userspace(mode, file_priv)) + continue; + drm_crtc_convert_to_umode(&u_mode, mode); if (copy_to_user(mode_ptr + copied, &u_mode, sizeof(u_mode))) { diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 15da4124ee12..dffc836144cc 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -308,7 +308,19 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) int drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv) { - return -EINVAL; + struct drm_set_client_cap *req = data; + + switch (req->capability) { + case DRM_CLIENT_CAP_STEREO_3D: + if (req->value > 1) + return -EINVAL; + file_priv->stereo_allowed = req->value; + break; + default: + return -EINVAL; + } + + return 0; } /** diff --git a/include/drm/drmP.h b/include/drm/drmP.h index dbc86b06a724..c65f496ad6b6 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -433,6 +433,9 @@ struct drm_file { struct drm_master *master; /* master this node is currently associated with N.B. not always minor->master */ + /* true when the client has asked us to expose stereo 3D mode flags */ + bool stereo_allowed; + /** * fbs - List of framebuffers associated with this file. * diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 526baed365ff..9b24d65fed72 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -627,6 +627,15 @@ struct drm_get_cap { __u64 value; }; +/** + * DRM_CLIENT_CAP_STEREO_3D + * + * if set to 1, the DRM core will expose the stereo 3D capabilities of the + * monitor by advertising the supported 3D layouts in the flags of struct + * drm_mode_modeinfo. + */ +#define DRM_CLIENT_CAP_STEREO_3D 1 + /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ struct drm_set_client_cap { __u64 capability; -- cgit v1.2.3 From f7e121b76469624459152542c1b809a1ebc835fe Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 27 Sep 2013 12:11:48 +0100 Subject: drm: Code stereo layouts as an enum rather than a bit field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to use fewer bits in the mode structure, leaving room for future work while allowing more stereo layouts types than we could have ever dreamt of. I also exposed the previously private DRM_MODE_FLAG_3D_MASK to set in stone that we are using 5 bits for the stereo layout enum, reserving 32 values. Even with that reservation, we gain 3 bits from the previous encoding. The code adding the mandatory stereo modes needeed to be adapted as it was relying or being able to or stereo layouts together. Suggested-by: Daniel Vetter Signed-off-by: Damien Lespiau Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_edid.c | 47 +++++++++++++++------------------------------ include/drm/drm_crtc.h | 9 --------- include/uapi/drm/drm_mode.h | 19 ++++++++++-------- 3 files changed, 26 insertions(+), 49 deletions(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c24af1d6cb47..7d1e8a90480a 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2562,16 +2562,16 @@ struct stereo_mandatory_mode { }; static const struct stereo_mandatory_mode stereo_mandatory_modes[] = { - { 1920, 1080, 24, - DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, + { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, + { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING }, { 1920, 1080, 50, DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, { 1920, 1080, 60, DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, - { 1280, 720, 50, - DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, - { 1280, 720, 60, - DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING } + { 1280, 720, 50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, + { 1280, 720, 50, DRM_MODE_FLAG_3D_FRAME_PACKING }, + { 1280, 720, 60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, + { 1280, 720, 60, DRM_MODE_FLAG_3D_FRAME_PACKING } }; static bool @@ -2586,50 +2586,33 @@ stereo_match_mandatory(const struct drm_display_mode *mode, drm_mode_vrefresh(mode) == stereo_mode->vrefresh; } -static const struct stereo_mandatory_mode * -hdmi_find_stereo_mandatory_mode(const struct drm_display_mode *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) - if (stereo_match_mandatory(mode, &stereo_mandatory_modes[i])) - return &stereo_mandatory_modes[i]; - - return NULL; -} - static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; const struct drm_display_mode *mode; struct list_head stereo_modes; - int modes = 0; + int modes = 0, i; INIT_LIST_HEAD(&stereo_modes); list_for_each_entry(mode, &connector->probed_modes, head) { - const struct stereo_mandatory_mode *mandatory; - u32 stereo_layouts, layout; - - mandatory = hdmi_find_stereo_mandatory_mode(mode); - if (!mandatory) - continue; - - stereo_layouts = mandatory->flags & DRM_MODE_FLAG_3D_MASK; - do { + for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) { + const struct stereo_mandatory_mode *mandatory; struct drm_display_mode *new_mode; - layout = 1 << (ffs(stereo_layouts) - 1); - stereo_layouts &= ~layout; + if (!stereo_match_mandatory(mode, + &stereo_mandatory_modes[i])) + continue; + mandatory = &stereo_mandatory_modes[i]; new_mode = drm_mode_duplicate(dev, mode); if (!new_mode) continue; - new_mode->flags |= layout; + new_mode->flags |= mandatory->flags; list_add_tail(&new_mode->head, &stereo_modes); modes++; - } while (stereo_layouts); + } } list_splice_tail(&stereo_modes, &connector->probed_modes); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index b2d08ca68ee7..eb6b8dc971d9 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -181,15 +181,6 @@ struct drm_display_mode { int hsync; /* in kHz */ }; -#define DRM_MODE_FLAG_3D_MASK (DRM_MODE_FLAG_3D_FRAME_PACKING | \ - DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE | \ - DRM_MODE_FLAG_3D_LINE_ALTERNATIVE | \ - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL | \ - DRM_MODE_FLAG_3D_L_DEPTH | \ - DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH | \ - DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | \ - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF) - static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode) { return mode->flags & DRM_MODE_FLAG_3D_MASK; diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index bafe61252754..7980f8994070 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -58,14 +58,17 @@ #define DRM_MODE_FLAG_PIXMUX (1<<11) #define DRM_MODE_FLAG_DBLCLK (1<<12) #define DRM_MODE_FLAG_CLKDIV2 (1<<13) -#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) -#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (1<<15) -#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (1<<16) -#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (1<<17) -#define DRM_MODE_FLAG_3D_L_DEPTH (1<<18) -#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (1<<19) -#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (1<<20) -#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (1<<21) +#define DRM_MODE_FLAG_3D_MASK (0x1f<<14) +#define DRM_MODE_FLAG_3D_NONE (0<<14) +#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) +#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14) +#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14) +#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (4<<14) +#define DRM_MODE_FLAG_3D_L_DEPTH (5<<14) +#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (6<<14) +#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14) +#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14) + /* DPMS flags */ /* bit compatible with the xorg definitions. */ -- cgit v1.2.3 From 5848ad409c1817f5b70507e6b4440fcbd002f6c5 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 27 Sep 2013 12:11:50 +0100 Subject: drm: Reject stereo modes with an unknown layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel shouldn't accept invalid modes, just say No. Signed-off-by: Damien Lespiau Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 3 +++ include/drm/drm_crtc.h | 2 ++ include/uapi/drm/drm_mode.h | 4 ++++ 3 files changed, 9 insertions(+) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 2ce80ed55b08..d7a8370e3cdc 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1319,6 +1319,9 @@ static int drm_crtc_convert_umode(struct drm_display_mode *out, if (in->clock > INT_MAX || in->vrefresh > INT_MAX) return -ERANGE; + if ((in->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX) + return -EINVAL; + out->clock = in->clock; out->hdisplay = in->hdisplay; out->hsync_start = in->hsync_start; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index eb6b8dc971d9..50cedadc9fcc 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -128,6 +128,8 @@ enum drm_mode_status { #define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */ #define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */ +#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF + struct drm_display_mode { /* Header */ struct list_head head; diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 7980f8994070..c2c4ace3db61 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -58,6 +58,10 @@ #define DRM_MODE_FLAG_PIXMUX (1<<11) #define DRM_MODE_FLAG_DBLCLK (1<<12) #define DRM_MODE_FLAG_CLKDIV2 (1<<13) + /* + * When adding a new stereo mode don't forget to adjust DRM_MODE_FLAGS_3D_MAX + * (define not exposed to user space). + */ #define DRM_MODE_FLAG_3D_MASK (0x1f<<14) #define DRM_MODE_FLAG_3D_NONE (0<<14) #define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) -- cgit v1.2.3