All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulo Zanoni <przanoni@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 8/8] drm/i915: add overscan compensation CRTC properties
Date: Thu, 29 Mar 2012 18:27:26 -0300	[thread overview]
Message-ID: <1333056446-3383-8-git-send-email-przanoni@gmail.com> (raw)
In-Reply-To: <1333056446-3383-1-git-send-email-przanoni@gmail.com>

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

They're named "underscan hborder" and "underscan vborder". The
properties accept values from 0 to 100, where 0 is "don't compensate"
and 100 is "shrink the screen as much as possible" (not necessarily
100 pixels).

V2: Rename to "underscan hborder" and "underscan vborder" to match the
radeon properties. Note that we have a range of 0-100 (not pixels) and
radeon has a range of 0-128 (pixels). Fix compilation on 32 bit
systems.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    2 +
 drivers/gpu/drm/i915/intel_display.c |  117 +++++++++++++++++++++++++++++++++-
 2 files changed, 118 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 98d7d74..0373723 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -780,6 +780,8 @@ typedef struct drm_i915_private {
 	struct drm_property *broadcast_rgb_property;
 	struct drm_property *force_audio_property;
 	struct drm_property *rotation_property;
+	struct drm_property *underscan_hborder_property;
+	struct drm_property *underscan_vborder_property;
 } drm_i915_private_t;
 
 enum hdmi_force_audio {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d621a54..b80c508 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5621,6 +5621,84 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
 	return 120000;
 }
 
+/*
+ * The overscan compensation property (aka underscan property) has values from 0
+ * to 100, where 0 means that the compensation is disabled and 100 means the
+ * screen should shrink as much as possible. The current maximum supported value
+ * (from the specifications) is "src/dst < 1.125".
+ *
+ * In short:
+ * - if val == 0   -> dst = src
+ * - if val == 100 -> dst = src * 8/9
+ * - dst can't be odd
+ * - dst can't be < src * 8 / (double)9
+ * - so the formulae, not considering rounding, should be:
+ *   - dst = 9*src - prop*src/100 / 9
+ */
+static void ironlake_crtc_overscan_compensate(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	uint64_t prop_x_64 = 0, prop_y_64 = 0;
+	uint32_t prop_x, prop_y;
+	int tot_x, tot_y, src_x, src_y, dst_x, dst_y, pos_x, pos_y;
+	u32 reg;
+
+	drm_object_property_get_value(&crtc->base,
+				      dev_priv->underscan_hborder_property,
+				      &prop_x_64);
+	drm_object_property_get_value(&crtc->base,
+				      dev_priv->underscan_vborder_property,
+				      &prop_y_64);
+
+	/* This is needed to avoid 64 bit division later. Values should be
+	 * between 0 and 100, so no problem. */
+	prop_x = prop_x_64;
+	prop_y = prop_y_64;
+
+	if (prop_x == 0 && prop_y == 0 &&
+	    !(dev_priv->pch_pf_size &&
+	      (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP))) {
+		I915_WRITE(PF_CTL(pipe), 0);
+		I915_WRITE(PF_WIN_POS(pipe), 0);
+		I915_WRITE(PF_WIN_SZ(pipe), 0);
+		return;
+	}
+
+	reg = I915_READ(HTOTAL(pipe));
+	tot_x = (reg & 0xFFF) + 1;
+	reg = I915_READ(VTOTAL(pipe));
+	tot_y = (reg & 0xFFF) + 1;
+	reg = I915_READ(PIPESRC(pipe));
+	src_x = ((reg >> 16) & 0xFFF) + 1;
+	src_y = (reg & 0xFFF) + 1;
+
+	dst_x = (src_x * 9 - src_x * prop_x / 100 + 8) / 9;
+	dst_x &= ~1;
+	if (dst_x < ((src_x * 8 + 8) / 9))
+		dst_x += 2;
+
+	dst_y = (src_y * 9 - src_y * prop_y / 100 + 8) / 9;
+	dst_y &= ~1;
+	if (dst_y < ((src_y * 8 + 8) / 9))
+		dst_y += 2;
+
+	pos_x = (tot_x - dst_x) / 2;
+	pos_y = (tot_y - dst_y) / 2;
+
+	if (pos_x == 1)
+		pos_x = 0;
+	reg = I915_READ(PIPECONF(pipe));
+	if ((reg & PIPECONF_INTERLACE_MASK) != PIPECONF_PROGRESSIVE)
+		pos_y &= ~1;
+
+	I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
+	I915_WRITE(PF_WIN_POS(pipe), (pos_x << 16) | pos_y);
+	I915_WRITE(PF_WIN_SZ(pipe), (dst_x << 16) | dst_y);
+}
+
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 				  struct drm_display_mode *mode,
 				  struct drm_display_mode *adjusted_mode,
@@ -6066,6 +6144,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 
 	intel_update_watermarks(dev);
 
+	ironlake_crtc_overscan_compensate(crtc);
+
 	return ret;
 }
 
@@ -7667,6 +7747,11 @@ static int intel_crtc_set_property(struct drm_crtc *crtc,
 
 	if (property == dev_priv->rotation_property)
 		intel_crtc_set_rotation(crtc, val);
+	if (property == dev_priv->underscan_hborder_property ||
+	    property == dev_priv->underscan_vborder_property) {
+		drm_object_property_set_value(&crtc->base, property, val);
+		ironlake_crtc_overscan_compensate(crtc);
+	}
 	return 0;
 }
 
@@ -7709,6 +7794,34 @@ static void intel_attach_rotation_property(struct drm_crtc *crtc)
 	drm_object_attach_property(&crtc->base, prop, 0);
 }
 
+static void intel_attach_underscan_properties(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_property *prop_h, *prop_v;
+
+	prop_h = dev_priv->underscan_hborder_property;
+	if (prop_h == NULL) {
+		prop_h = drm_property_create_range(dev, 0, "underscan hborder",
+						   0, 100);
+		if (prop_h != NULL)
+			dev_priv->underscan_hborder_property = prop_h;
+	}
+
+	prop_v = dev_priv->underscan_vborder_property;
+	if (prop_v == NULL) {
+		prop_v = drm_property_create_range(dev, 0, "underscan vborder",
+						   0, 100);
+		if (prop_v != NULL)
+			dev_priv->underscan_vborder_property = prop_v;
+	}
+
+	if (prop_h)
+		drm_object_attach_property(&crtc->base, prop_h, 0);
+	if (prop_v)
+		drm_object_attach_property(&crtc->base, prop_v, 0);
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -7728,8 +7841,10 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 		intel_crtc->lut_b[i] = i;
 	}
 
-	if (INTEL_INFO(dev)->gen >= 5)
+	if (INTEL_INFO(dev)->gen >= 5) {
 		intel_attach_rotation_property(&intel_crtc->base);
+		intel_attach_underscan_properties(&intel_crtc->base);
+	}
 
 	/* Swap pipes & planes for FBC on pre-965 */
 	intel_crtc->pipe = pipe;
-- 
1.7.9.1

  parent reply	other threads:[~2012-03-29 21:28 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-29 21:27 [PATCH 1/8] drm: add drm_property_change_is_valid Paulo Zanoni
2012-03-29 21:27 ` [PATCH 2/8] drm: WARN() when drm_connector_attach_property fails Paulo Zanoni
2012-03-29 21:49   ` Chris Wilson
2012-03-29 21:27 ` [PATCH 3/8] drm: create struct drm_object_properties and use it Paulo Zanoni
2012-03-30  2:41   ` Eugeni Dodonov
2012-03-30 12:52   ` Ville Syrjälä
2012-03-29 21:27 ` [PATCH 4/8] drm: add generic ioctls to get/set properties on any object Paulo Zanoni
2012-03-30  2:47   ` Eugeni Dodonov
2012-03-30 13:04   ` Ville Syrjälä
2012-03-29 21:27 ` [PATCH 5/8] drm: make the connector properties code use the object properties code Paulo Zanoni
2012-03-30  2:49   ` Eugeni Dodonov
2012-03-29 21:27 ` [PATCH 6/8] drm: add CRTC properties Paulo Zanoni
2012-03-29 21:27 ` [PATCH RFC 7/8] drm/i915: add 'rotation' CRTC property Paulo Zanoni
2012-03-29 21:27 ` Paulo Zanoni [this message]
2012-03-30  2:38 ` [PATCH 1/8] drm: add drm_property_change_is_valid Eugeni Dodonov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1333056446-3383-8-git-send-email-przanoni@gmail.com \
    --to=przanoni@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=paulo.r.zanoni@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.