summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_tv.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2019-01-29 17:19:13 +0300
committerVille Syrjälä <ville.syrjala@linux.intel.com>2019-01-30 00:27:31 +0300
commit68e94f62cfbe1650fb783979150a2b2f0a3eca1c (patch)
treeefe8c51cc36d6d3077023e15365f20c3c48855b0 /drivers/gpu/drm/i915/intel_tv.c
parentaddc80f0bba9f015208132b804397d9d08399465 (diff)
downloadlinux-68e94f62cfbe1650fb783979150a2b2f0a3eca1c.tar.xz
drm/i915/tv: Bypass the vertical filter if possible
Let's switch the pipe into interlaced mode and switch off the TV encoder vertical filter if the pipe vdisplay matches the TV YSIZE exactly. While I didn't measure it I presume this might reduce the power consumption a little bit, and the pixel rate is halved as the pipe will now fetching in interlaced mode rather than in progressive mode (effectively the same difference as between IF-ID vs. PF-ID pfit modes on more modern hardware) so a bit easier on the memory bandwidth. Cc: Imre Deak <imre.deak@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190129141913.5515-2-ville.syrjala@linux.intel.com Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_tv.c')
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 3a5682f44e55..3924c4944e1f 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1159,6 +1159,22 @@ intel_tv_get_config(struct intel_encoder *encoder,
I915_MODE_FLAG_USE_SCANLINE_COUNTER;
}
+static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv,
+ int hdisplay)
+{
+ return IS_GEN(dev_priv, 3) && hdisplay > 1024;
+}
+
+static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
+ const struct drm_connector_state *conn_state,
+ int vdisplay)
+{
+ return tv_mode->crtc_vdisplay -
+ conn_state->tv.margins.top -
+ conn_state->tv.margins.bottom !=
+ vdisplay;
+}
+
static int
intel_tv_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -1189,7 +1205,8 @@ intel_tv_compute_config(struct intel_encoder *encoder,
intel_tv_mode_to_mode(adjusted_mode, tv_mode);
drm_mode_set_crtcinfo(adjusted_mode, 0);
- if (IS_GEN(dev_priv, 3) && hdisplay > 1024) {
+ if (intel_tv_source_too_wide(dev_priv, hdisplay) ||
+ !intel_tv_vert_scaling(adjusted_mode, conn_state, vdisplay)) {
int extra, top, bottom;
extra = adjusted_mode->crtc_vdisplay - vdisplay;