summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorJesse Barnes2013-04-25 21:55:01 +0200
committerDaniel Vetter2013-04-25 22:16:22 +0200
commit2dd24552cab40ea829ba3fda890eeafd2c4816d8 (patch)
treefee957bf6e4c7824ffbd82125930f316634884b0 /drivers/gpu/drm/i915/intel_display.c
parentdrm/i915: simplify config->pixel_multiplier handling (diff)
downloadkernel-qcow2-linux-2dd24552cab40ea829ba3fda890eeafd2c4816d8.tar.gz
kernel-qcow2-linux-2dd24552cab40ea829ba3fda890eeafd2c4816d8.tar.xz
kernel-qcow2-linux-2dd24552cab40ea829ba3fda890eeafd2c4816d8.zip
drm/i915: factor out GMCH panel fitting code and use for eDP v3
This gets the panel fitter working on eDP on VLV, and should also apply to eDP panels on G4x chipsets (if we ever detect and mark an all-in-one panel as eDP anyway). A few cleanups are still possible on top of this, for example the LVDS border control could be placed in the LVDS encoder structure and updated based on the result of the panel fitter calculation. Multi-pipe fitting isn't handled correctly either if we ever get a config that wants to try the panel fitter on more than one output at a time. v2: use pipe_config for storing pfit values (Daniel) add i9xx_pfit_enable function for use by 9xx and VLV (Daniel) v3: fixup conflicts and lvds_dither check Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [danvet: fix up botched conflict resolution from Jesse: - border = LVDS_BORDER_ENABLE was lost for CENTER scaling - comment about gen2/3 panel fitter scaling was lost - dev_priv->lvds_dither reintroduced.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2e83dbe5ecc0..fc6f76837437 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3601,6 +3601,33 @@ g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe)
}
}
+static void i9xx_pfit_enable(struct intel_crtc *crtc)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc_config *pipe_config = &crtc->config;
+
+ if (!(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) ||
+ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)))
+ return;
+
+ WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE);
+ assert_pipe_disabled(dev_priv, crtc->pipe);
+
+ /*
+ * Enable automatic panel scaling so that non-native modes
+ * fill the screen. The panel fitter should only be
+ * adjusted whilst the pipe is disabled, according to
+ * register description and PRM.
+ */
+ DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
+ pipe_config->pfit_control,
+ pipe_config->pfit_pgm_ratios);
+
+ I915_WRITE(PFIT_PGM_RATIOS, pipe_config->pfit_pgm_ratios);
+ I915_WRITE(PFIT_CONTROL, pipe_config->pfit_control);
+}
+
static void valleyview_crtc_enable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -3634,6 +3661,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
+ /* Enable panel fitting for eDP */
+ i9xx_pfit_enable(intel_crtc);
+
intel_enable_pipe(dev_priv, pipe, false);
intel_enable_plane(dev_priv, plane, pipe);
@@ -3670,6 +3700,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
if (encoder->pre_enable)
encoder->pre_enable(encoder);
+ /* Enable panel fitting for LVDS */
+ i9xx_pfit_enable(intel_crtc);
+
intel_enable_pipe(dev_priv, pipe, false);
intel_enable_plane(dev_priv, plane, pipe);
if (IS_G4X(dev))