Skip to content

Commit

Permalink
drm/i915: use pipe_config for lvds dithering
Browse files Browse the repository at this point in the history
Up to now we've relied on the bios to get this right for us. Let's try
out whether our code has improved a bit, since we should dither
always when the output bpp doesn't match the plane bpp.
- gen5+ should be fine, since we only use the bios hint as an upgrade.
- gen4 changes, since here dithering is still controlled in the lvds
  register.
- gen2/3 has implicit dithering depeding upon whether you use 2 or 3
  lvds pairs (which makes sense, since it only supports 8bpc pipe
  outpu configurations).
- hsw doesn't support lvds.

v2: Remove redudant dither setting.

v3: Completly drop reliance on dev_priv->lvds_dither.

v4: Enable dithering on gen2/3 only when we have a 18bpp panel, since
up-dithering to a 24bpp panel is not supported by the hw. Spotted by
Ville.

v5: Also only enable lvds port dithering on gen4 for 18bpp modes. In
practice this only excludes dithering a 10bpc plane down for a 24bpp
lvds panel. Not something we truly care about. Again noticed by Ville.

v6: Actually git add.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Daniel Vetter committed Apr 25, 2013
1 parent c6bb353 commit d8b3224
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 23 deletions.
25 changes: 7 additions & 18 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -5146,8 +5146,7 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
}

static void ironlake_set_pipeconf(struct drm_crtc *crtc,
struct drm_display_mode *adjusted_mode,
bool dither)
struct drm_display_mode *adjusted_mode)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Expand Down Expand Up @@ -5176,7 +5175,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
}

val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
if (dither)
if (intel_crtc->config.dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);

val &= ~PIPECONF_INTERLACE_MASK;
Expand Down Expand Up @@ -5259,8 +5258,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
}

static void haswell_set_pipeconf(struct drm_crtc *crtc,
struct drm_display_mode *adjusted_mode,
bool dither)
struct drm_display_mode *adjusted_mode)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Expand All @@ -5270,7 +5268,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc,
val = I915_READ(PIPECONF(cpu_transcoder));

val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
if (dither)
if (intel_crtc->config.dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);

val &= ~PIPECONF_INTERLACE_MASK_HSW;
Expand Down Expand Up @@ -5631,7 +5629,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
bool is_lvds = false;
struct intel_encoder *encoder;
int ret;
bool dither, fdi_config_ok;
bool fdi_config_ok;

for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
Expand Down Expand Up @@ -5666,11 +5664,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true);

/* determine panel color depth */
dither = intel_crtc->config.dither;
if (is_lvds && dev_priv->lvds_dither)
dither = true;

DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe));
drm_mode_debug_printmodeline(mode);

Expand Down Expand Up @@ -5737,7 +5730,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,

fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);

ironlake_set_pipeconf(crtc, adjusted_mode, dither);
ironlake_set_pipeconf(crtc, adjusted_mode);

/* Set up the display plane register */
I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
Expand Down Expand Up @@ -5814,7 +5807,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
bool is_cpu_edp = false;
struct intel_encoder *encoder;
int ret;
bool dither;

for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
Expand Down Expand Up @@ -5850,9 +5842,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true);

/* determine panel color depth */
dither = intel_crtc->config.dither;

DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe));
drm_mode_debug_printmodeline(mode);

Expand All @@ -5866,7 +5855,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
if (intel_crtc->config.has_pch_encoder)
ironlake_fdi_set_m_n(crtc);

haswell_set_pipeconf(crtc, adjusted_mode, dither);
haswell_set_pipeconf(crtc, adjusted_mode);

intel_set_pipe_csc(crtc);

Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ struct intel_crtc_config {
/* DP has a bunch of special case unfortunately, so mark the pipe
* accordingly. */
bool has_dp_encoder;

/*
* Enable dithering, used when the selected pipe bpp doesn't match the
* plane bpp.
*/
bool dither;

/* Controls for the clock computation, to override various stages. */
Expand Down
15 changes: 10 additions & 5 deletions drivers/gpu/drm/i915/intel_lvds.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder)
* special lvds dither control bit on pch-split platforms, dithering is
* only controlled through the PIPECONF reg. */
if (INTEL_INFO(dev)->gen == 4) {
if (dev_priv->lvds_dither)
/* Bspec wording suggests that LVDS port dithering only exists
* for 18bpp panels. */
if (intel_crtc->config.dither &&
intel_crtc->config.pipe_bpp == 18)
temp |= LVDS_ENABLE_DITHER;
else
temp &= ~LVDS_ENABLE_DITHER;
Expand Down Expand Up @@ -335,7 +338,13 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
pipe_config->pipe_bpp, lvds_bpp);
pipe_config->pipe_bpp = lvds_bpp;

/* Make sure pre-965 set dither correctly for 18bpp panels. */
if (INTEL_INFO(dev)->gen < 4 && lvds_bpp == 18)
pfit_control |= PANEL_8TO6_DITHER_ENABLE;

}

/*
* We have timings from the BIOS for the panel, put them in
* to the adjusted mode. The CRTC will be set up for this mode,
Expand Down Expand Up @@ -470,10 +479,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
pfit_pgm_ratios = 0;
}

/* Make sure pre-965 set dither correctly */
if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither)
pfit_control |= PANEL_8TO6_DITHER_ENABLE;

if (pfit_control != lvds_encoder->pfit_control ||
pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) {
lvds_encoder->pfit_control = pfit_control;
Expand Down

0 comments on commit d8b3224

Please sign in to comment.