From: Paulo Zanoni <przanoni@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 5/5] drm/i915: add overscan compensation CRTC properties
Date: Tue, 20 Mar 2012 11:48:32 -0300 [thread overview]
Message-ID: <1332254912-4352-5-git-send-email-przanoni@gmail.com> (raw)
In-Reply-To: <1332254912-4352-1-git-send-email-przanoni@gmail.com>
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
They're named "underscan x" and "underscan y". The properties accept
values from 0 to 100, where 0 is "don't compensate" and 100 is "shrink
the screen as much as possible".
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 | 110 +++++++++++++++++++++++++++++++++-
2 files changed, 111 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7994c4f..fb9062d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -781,6 +781,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 *x_underscan_property;
+ struct drm_property *y_underscan_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 4842de8..b36572d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5620,6 +5620,77 @@ 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 = 0, prop_y = 0;
+ int tot_x, tot_y, src_x, src_y, dst_x, dst_y, pos_x, pos_y;
+ u32 reg;
+
+ drm_crtc_property_get_value(crtc, dev_priv->x_underscan_property,
+ &prop_x);
+ drm_crtc_property_get_value(crtc, dev_priv->y_underscan_property,
+ &prop_y);
+
+ 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,
@@ -6065,6 +6136,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
intel_update_watermarks(dev);
+ ironlake_crtc_overscan_compensate(crtc);
+
return ret;
}
@@ -7666,6 +7739,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->x_underscan_property ||
+ property == dev_priv->y_underscan_property) {
+ drm_crtc_property_set_value(crtc, property, val);
+ ironlake_crtc_overscan_compensate(crtc);
+ }
return 0;
}
@@ -7708,6 +7786,34 @@ static void intel_attach_rotation_property(struct drm_crtc *crtc)
drm_crtc_attach_property(crtc, 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_x, *prop_y;
+
+ prop_x = dev_priv->x_underscan_property;
+ if (prop_x == NULL) {
+ prop_x = drm_property_create_range(dev, 0, "underscan x",
+ 0, 100);
+ if (prop_x != NULL)
+ dev_priv->x_underscan_property = prop_x;
+ }
+
+ prop_y = dev_priv->y_underscan_property;
+ if (prop_y == NULL) {
+ prop_y = drm_property_create_range(dev, 0, "underscan y",
+ 0, 100);
+ if (prop_y != NULL)
+ dev_priv->y_underscan_property = prop_y;
+ }
+
+ if (prop_x)
+ drm_crtc_attach_property(crtc, prop_x, 0);
+ if (prop_y)
+ drm_crtc_attach_property(crtc, prop_y, 0);
+}
+
static void intel_crtc_init(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -7727,8 +7833,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
next prev parent reply other threads:[~2012-03-20 14:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-20 14:48 [PATCH 1/5] drm: add drm_property_change_is_valid Paulo Zanoni
2012-03-20 14:48 ` [PATCH 2/5] drm: WARN() when drm_connector_attach_property fails Paulo Zanoni
2012-03-20 14:48 ` [PATCH 3/5] drm: add CRTC properties Paulo Zanoni
2012-03-20 15:00 ` Rob Clark
2012-03-20 15:09 ` Alex Deucher
2012-03-20 15:48 ` Daniel Vetter
2012-03-20 14:48 ` [PATCH 4/5] drm/i915: add 'rotation' CRTC property Paulo Zanoni
2012-03-20 16:48 ` Marcus Lorentzon
2012-03-20 18:49 ` Ville Syrjälä
2012-03-20 14:48 ` Paulo Zanoni [this message]
2012-03-20 15:00 ` [PATCH 5/5] drm/i915: add overscan compensation CRTC properties Alex Deucher
2012-03-20 15:37 ` [PATCH 1/5] drm: add drm_property_change_is_valid Ville Syrjälä
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=1332254912-4352-5-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.