diff mbox

[3/3] drm/i915/vlv: update czclk freq if needed for high bandwidth modes

Message ID 1382993199-19121-3-git-send-email-jbarnes@virtuousgeek.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes Oct. 28, 2013, 8:46 p.m. UTC
Needed to support large panel resolutions.

Tested-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_reg.h      |  2 ++
 drivers/gpu/drm/i915/intel_display.c | 64 ++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

Comments

Daniel Vetter Oct. 29, 2013, 7:37 a.m. UTC | #1
On Mon, Oct 28, 2013 at 01:46:39PM -0700, Jesse Barnes wrote:
> Needed to support large panel resolutions.
> 
> Tested-by: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> ---
>  drivers/gpu/drm/i915/i915_reg.h      |  2 ++
>  drivers/gpu/drm/i915/intel_display.c | 64 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 66 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 6a6eb8b..89109c4 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1447,6 +1447,8 @@
>  #define   CZCLK_FREQ_MASK	0xf
>  #define GMBUSFREQ_VLV		(VLV_DISPLAY_BASE + 0x6510)
>  
> +#define CZCLK_CDCLK_FREQ_RATIO	(VLV_DISPLAY_BASE + 0x6508)
> +
>  /*
>   * Palette regs
>   */
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 152d6a8..1bf811a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3851,6 +3851,67 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
>  	I915_WRITE(BCLRPAT(crtc->pipe), 0);
>  }
>  
> +static void valleyview_adjust_czclk(struct drm_device *dev, bool up)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 val, divider;
> +
> +	switch (dev_priv->mem_freq) {
> +	default:
> +	case 800:
> +		if (up)
> +			divider = 3;
> +		else
> +			divider = 4;
> +		break;
> +	case 1066:
> +		if (up)
> +			divider = 7;
> +		else
> +			divider = 9;
> +		break;
> +	case 1333:
> +		if (up)
> +			divider = 9;
> +		else
> +			divider = 11;
> +		break;
> +	}
> +
> +	/* adjust czclk ratio */
> +	mutex_lock(&dev_priv->dpio_lock);
> +	val = vlv_cck_read(dev_priv, 0x6b);
> +	val &= ~0xf;
> +	val |= divider;
> +	vlv_cck_write(dev_priv, 0x6b, val);
> +
> +	/* adjust self-refresh exit latency value */
> +	val = vlv_bunit_read(dev_priv, 0x11);
> +	val &= ~0x7f;
> +	if (up)
> +		val |= 0x12;
> +	else
> +		val |= 0xc;
> +	vlv_bunit_write(dev_priv, 0x11, val);
> +	mutex_unlock(&dev_priv->dpio_lock);
> +}
> +
> +static void valleyview_modeset_global_resources(struct drm_device *dev)
> +{
> +	struct intel_crtc *crtc;
> +	bool need_czclk_increase = false;
> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
> +		if (!crtc->base.enabled)
> +			continue;
> +
> +		if (crtc->config.adjusted_mode.clock >= 3600)

All our clocks are in kHz, so this is _really_ slow. To make debugging
this a bit easier I think we need a DRM_DEBUG_KMS line here that tells us
why we need the higher clock, e.g.
			
			DRM_DEBUG_KMS("Increasing czclk due to pipe %s with dotclock %i\n",
				pipe_name(crtc->pipe), crtc->config.adjusted_mode.clock);

Also, a quick comment either in the code or in the commit message that
explains quickly what this clock controls and why you've picked the right
one of the three clocks we have in the config would be good.
-Daniel

> +			need_czclk_increase = true;
> +	}
> +
> +	valleyview_adjust_czclk(dev, need_czclk_increase);
> +}
> +
>  static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
> @@ -10218,6 +10279,9 @@ static void intel_init_display(struct drm_device *dev)
>  		}
>  	} else if (IS_G4X(dev)) {
>  		dev_priv->display.write_eld = g4x_write_eld;
> +	} else if (IS_VALLEYVIEW(dev)) {
> +		dev_priv->display.modeset_global_resources =
> +			valleyview_modeset_global_resources;
>  	}
>  
>  	/* Default just returns -ENODEV to indicate unsupported */
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6a6eb8b..89109c4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1447,6 +1447,8 @@ 
 #define   CZCLK_FREQ_MASK	0xf
 #define GMBUSFREQ_VLV		(VLV_DISPLAY_BASE + 0x6510)
 
+#define CZCLK_CDCLK_FREQ_RATIO	(VLV_DISPLAY_BASE + 0x6508)
+
 /*
  * Palette regs
  */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 152d6a8..1bf811a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3851,6 +3851,67 @@  static void i9xx_pfit_enable(struct intel_crtc *crtc)
 	I915_WRITE(BCLRPAT(crtc->pipe), 0);
 }
 
+static void valleyview_adjust_czclk(struct drm_device *dev, bool up)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val, divider;
+
+	switch (dev_priv->mem_freq) {
+	default:
+	case 800:
+		if (up)
+			divider = 3;
+		else
+			divider = 4;
+		break;
+	case 1066:
+		if (up)
+			divider = 7;
+		else
+			divider = 9;
+		break;
+	case 1333:
+		if (up)
+			divider = 9;
+		else
+			divider = 11;
+		break;
+	}
+
+	/* adjust czclk ratio */
+	mutex_lock(&dev_priv->dpio_lock);
+	val = vlv_cck_read(dev_priv, 0x6b);
+	val &= ~0xf;
+	val |= divider;
+	vlv_cck_write(dev_priv, 0x6b, val);
+
+	/* adjust self-refresh exit latency value */
+	val = vlv_bunit_read(dev_priv, 0x11);
+	val &= ~0x7f;
+	if (up)
+		val |= 0x12;
+	else
+		val |= 0xc;
+	vlv_bunit_write(dev_priv, 0x11, val);
+	mutex_unlock(&dev_priv->dpio_lock);
+}
+
+static void valleyview_modeset_global_resources(struct drm_device *dev)
+{
+	struct intel_crtc *crtc;
+	bool need_czclk_increase = false;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+		if (!crtc->base.enabled)
+			continue;
+
+		if (crtc->config.adjusted_mode.clock >= 3600)
+			need_czclk_increase = true;
+	}
+
+	valleyview_adjust_czclk(dev, need_czclk_increase);
+}
+
 static void valleyview_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -10218,6 +10279,9 @@  static void intel_init_display(struct drm_device *dev)
 		}
 	} else if (IS_G4X(dev)) {
 		dev_priv->display.write_eld = g4x_write_eld;
+	} else if (IS_VALLEYVIEW(dev)) {
+		dev_priv->display.modeset_global_resources =
+			valleyview_modeset_global_resources;
 	}
 
 	/* Default just returns -ENODEV to indicate unsupported */