From f2ecf2e3bc01868f244fc6ba9cf8fe5d8446db5b Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:27 +0100 Subject: drm: Make drm_match_cea_mode() return the underlying 2D VIC for 3d modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When scanning out a stereo mode, the AVI infoframe vic field has to be the underlyng 2D VIC. Before that commit, we weren't matching the CEA mode because of the extra stereo flag and then were setting the VIC field in the AVI infoframe to 0. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_modes.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/drm_modes.c') diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index fc2adb62b75..c2cb2c80f94 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -830,12 +830,16 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ } else if (mode1->clock != mode2->clock) return false; - return drm_mode_equal_no_clocks(mode1, mode2); + if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) != + (mode2->flags & DRM_MODE_FLAG_3D_MASK)) + return false; + + return drm_mode_equal_no_clocks_no_stereo(mode1, mode2); } EXPORT_SYMBOL(drm_mode_equal); /** - * drm_mode_equal_no_clocks - test modes for equality + * drm_mode_equal_no_clocks_no_stereo - test modes for equality * @mode1: first mode * @mode2: second mode * @@ -843,12 +847,13 @@ EXPORT_SYMBOL(drm_mode_equal); * None. * * Check to see if @mode1 and @mode2 are equivalent, but - * don't check the pixel clocks. + * don't check the pixel clocks nor the stereo layout. * * RETURNS: * True if the modes are equal, false otherwise. */ -bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) +bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, + const struct drm_display_mode *mode2) { if (mode1->hdisplay == mode2->hdisplay && mode1->hsync_start == mode2->hsync_start && @@ -860,12 +865,13 @@ bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct mode1->vsync_end == mode2->vsync_end && mode1->vtotal == mode2->vtotal && mode1->vscan == mode2->vscan && - mode1->flags == mode2->flags) + (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) == + (mode2->flags & ~DRM_MODE_FLAG_3D_MASK)) return true; return false; } -EXPORT_SYMBOL(drm_mode_equal_no_clocks); +EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); /** * drm_mode_validate_size - make sure modes adhere to size constraints -- cgit v1.2.3-70-g09d2 From bde2dcf701db9fa6d010afa8e9254c3d7b0331fb Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:34 +0100 Subject: drm: Introduce a crtc_clock for struct drm_display_mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just like the various timings, make it possible to have a clock field what we can tweak before giving it to hardware. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_modes.c | 1 + include/drm/drm_crtc.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/gpu/drm/drm_modes.c') diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index c2cb2c80f94..ef26eb28364 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -719,6 +719,7 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) return; + p->crtc_clock = p->clock; p->crtc_hdisplay = p->hdisplay; p->crtc_hsync_start = p->hsync_start; p->crtc_hsync_end = p->hsync_end; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 8e9716e362e..73478bc8f9e 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -156,6 +156,7 @@ struct drm_display_mode { int height_mm; /* Actual mode we give to hw */ + int crtc_clock; /* in KHz */ int crtc_hdisplay; int crtc_hblank_start; int crtc_hblank_end; -- cgit v1.2.3-70-g09d2 From 448cce25f408be4c933f88ed8962455a0c16d0f8 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 25 Sep 2013 16:45:35 +0100 Subject: drm: Implement timings adjustments for frame packing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using the frame packing and a single big framebuffer, some hardware requires that we do everything like if we were scanning out the big buffer itself. Let's instrument drm_mode_set_crtcinfo() to be able to do this adjustement if the driver is asking for it. v2: Use crtc_vtotal and multiply the clock by 2 instead of reconstructing it (Ville Syrjälä) Suggested-by: Daniel Vetter Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_modes.c | 22 +++++++++++++++++++++- include/drm/drm_crtc.h | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/drm_modes.c') diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index ef26eb28364..b0733153dfd 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -707,12 +707,18 @@ EXPORT_SYMBOL(drm_mode_vrefresh); /** * drm_mode_set_crtcinfo - set CRTC modesetting parameters * @p: mode - * @adjust_flags: unused? (FIXME) + * @adjust_flags: a combination of adjustment flags * * LOCKING: * None. * * Setup the CRTC modesetting parameters for @p, adjusting if necessary. + * + * - The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of + * interlaced modes. + * - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for + * buffers containing two eyes (only adjust the timings when needed, eg. for + * "frame packing" or "side by side full"). */ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) { @@ -753,6 +759,20 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) p->crtc_vtotal *= p->vscan; } + if (adjust_flags & CRTC_STEREO_DOUBLE) { + unsigned int layout = p->flags & DRM_MODE_FLAG_3D_MASK; + + switch (layout) { + case DRM_MODE_FLAG_3D_FRAME_PACKING: + p->crtc_clock *= 2; + p->crtc_vdisplay += p->crtc_vtotal; + p->crtc_vsync_start += p->crtc_vtotal; + p->crtc_vsync_end += p->crtc_vtotal; + p->crtc_vtotal += p->crtc_vtotal; + break; + } + } + p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay); p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 73478bc8f9e..b2d08ca68ee 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -125,7 +125,8 @@ enum drm_mode_status { .vscan = (vs), .flags = (f), \ .base.type = DRM_MODE_OBJECT_MODE -#define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */ +#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */ +#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */ struct drm_display_mode { /* Header */ -- cgit v1.2.3-70-g09d2 From 3fbd6439e4639ecaeaae6c079e0aa497a1ac3482 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 18 Oct 2013 16:11:30 +0200 Subject: drm: copy mode type in drm_mode_connector_list_update() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 38d5487db7f289be1d56ac7df704ee49ed3213b9, Keith explained: This patch simply merges the two mode type bits together; that seems reasonable to me, but perhaps only a subset of the bits should be used? None of these can be user defined as they all come from looking at just the hardware. However, merging the bits means that a flag becomes sticky. It is not possible, for example to update the mode type to remove the DRM_MODE_TYPE_PREFERRED bit. After a brief discussion with Dave Airlie on irc, it was agreed to propose that change, instead of introducing another function to remove a bit from exisiting modes type. Signed-off-by: Marc-André Lureau Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_modes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/drm_modes.c') diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index b0733153dfd..85071a1c454 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1041,7 +1041,7 @@ void drm_mode_connector_list_update(struct drm_connector *connector) /* if equal delete the probed mode */ mode->status = pmode->status; /* Merge type bits together */ - mode->type |= pmode->type; + mode->type = pmode->type; list_del(&pmode->head); drm_mode_destroy(connector->dev, pmode); break; -- cgit v1.2.3-70-g09d2