Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bcda4f0 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

drm/i915: Cache HPLL frequency on VLV/CHV



We need the HPLL frequency when calculating cdclk. Currently we read
that out from the hardware every single time, which isn't going to fly
very well if the device is runtime suspended. So cache the HPLL
frequency in dev_priv and use the cached value.

Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reference: https://bugs.freedesktop.org/show_bug.cgi?id=82939


Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 95009861
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -1613,6 +1613,7 @@ struct drm_i915_private {


	unsigned int fsb_freq, mem_freq, is_ddr3;
	unsigned int fsb_freq, mem_freq, is_ddr3;
	unsigned int vlv_cdclk_freq;
	unsigned int vlv_cdclk_freq;
	unsigned int hpll_freq;


	/**
	/**
	 * wq - Driver workqueue for GEM.
	 * wq - Driver workqueue for GEM.
+7 −7
Original line number Original line Diff line number Diff line
@@ -4756,10 +4756,9 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
	mutex_unlock(&dev_priv->rps.hw_lock);
	mutex_unlock(&dev_priv->rps.hw_lock);


	if (cdclk == 400000) {
	if (cdclk == 400000) {
		u32 divider, vco;
		u32 divider;


		vco = valleyview_get_vco(dev_priv);
		divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
		divider = DIV_ROUND_CLOSEST(vco << 1, cdclk) - 1;


		mutex_lock(&dev_priv->dpio_lock);
		mutex_lock(&dev_priv->dpio_lock);
		/* adjust cdclk divider */
		/* adjust cdclk divider */
@@ -4838,8 +4837,7 @@ static void cherryview_set_cdclk(struct drm_device *dev, int cdclk)
static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
				 int max_pixclk)
				 int max_pixclk)
{
{
	int vco = valleyview_get_vco(dev_priv);
	int freq_320 = (dev_priv->hpll_freq <<  1) % 320000 != 0 ? 333333 : 320000;
	int freq_320 = (vco <<  1) % 320000 != 0 ? 333333 : 320000;


	/* FIXME: Punit isn't quite ready yet */
	/* FIXME: Punit isn't quite ready yet */
	if (IS_CHERRYVIEW(dev_priv->dev))
	if (IS_CHERRYVIEW(dev_priv->dev))
@@ -5544,7 +5542,6 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
static int valleyview_get_display_clock_speed(struct drm_device *dev)
static int valleyview_get_display_clock_speed(struct drm_device *dev)
{
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	int vco = valleyview_get_vco(dev_priv);
	u32 val;
	u32 val;
	int divider;
	int divider;


@@ -5552,6 +5549,9 @@ static int valleyview_get_display_clock_speed(struct drm_device *dev)
	if (IS_CHERRYVIEW(dev))
	if (IS_CHERRYVIEW(dev))
		return 400000;
		return 400000;


	if (dev_priv->hpll_freq == 0)
		dev_priv->hpll_freq = valleyview_get_vco(dev_priv);

	mutex_lock(&dev_priv->dpio_lock);
	mutex_lock(&dev_priv->dpio_lock);
	val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
	val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
	mutex_unlock(&dev_priv->dpio_lock);
	mutex_unlock(&dev_priv->dpio_lock);
@@ -5562,7 +5562,7 @@ static int valleyview_get_display_clock_speed(struct drm_device *dev)
	     (divider << DISPLAY_FREQUENCY_STATUS_SHIFT),
	     (divider << DISPLAY_FREQUENCY_STATUS_SHIFT),
	     "cdclk change in progress\n");
	     "cdclk change in progress\n");


	return DIV_ROUND_CLOSEST(vco << 1, divider + 1);
	return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1);
}
}


static int i945_get_display_clock_speed(struct drm_device *dev)
static int i945_get_display_clock_speed(struct drm_device *dev)