Commit d60c4473 authored by Imre Deak's avatar Imre Deak Committed by Daniel Vetter

drm/i915: vlv: cache current CD clock rate

Instead of reading out the CD clock rate from the HW at each modeset, do
this only during driver init and resume and use the cached value during
modeset. This moves things towards a state where the sw and hw side
setup is separated. It's also needed for VLV RPM, where we don't put
device into D0 state until modeset_global_resources is called and thus
can't access any display/gfx registers.
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarAntti Koskipää <antti.koskipaa@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 0d8f9491
......@@ -1339,6 +1339,7 @@ typedef struct drm_i915_private {
int num_fence_regs; /* 8 on pre-965, 16 otherwise */
unsigned int fsb_freq, mem_freq, is_ddr3;
unsigned int vlv_cdclk_freq;
/**
* wq - Driver workqueue for GEM.
......
......@@ -4201,6 +4201,9 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, cmd;
WARN_ON(valleyview_cur_cdclk(dev_priv) != dev_priv->vlv_cdclk_freq);
dev_priv->vlv_cdclk_freq = cdclk;
if (cdclk >= 320) /* jump to highest voltage for 400MHz too */
cmd = 2;
else if (cdclk == 266)
......@@ -4255,7 +4258,7 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
intel_i2c_reset(dev);
}
static int valleyview_cur_cdclk(struct drm_i915_private *dev_priv)
int valleyview_cur_cdclk(struct drm_i915_private *dev_priv)
{
int cur_cdclk, vco;
int divider;
......@@ -4276,10 +4279,6 @@ static int valleyview_cur_cdclk(struct drm_i915_private *dev_priv)
static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
int max_pixclk)
{
int cur_cdclk;
cur_cdclk = valleyview_cur_cdclk(dev_priv);
/*
* Really only a few cases to deal with, as only 4 CDclks are supported:
* 200MHz
......@@ -4321,9 +4320,9 @@ static void valleyview_modeset_global_pipes(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc;
int max_pixclk = intel_mode_max_pixclk(dev_priv);
int cur_cdclk = valleyview_cur_cdclk(dev_priv);
if (valleyview_calc_cdclk(dev_priv, max_pixclk) == cur_cdclk)
if (valleyview_calc_cdclk(dev_priv, max_pixclk) ==
dev_priv->vlv_cdclk_freq)
return;
/* disable/enable all currently active pipes while we change cdclk */
......@@ -4337,10 +4336,9 @@ static void valleyview_modeset_global_resources(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int max_pixclk = intel_mode_max_pixclk(dev_priv);
int cur_cdclk = valleyview_cur_cdclk(dev_priv);
int req_cdclk = valleyview_calc_cdclk(dev_priv, max_pixclk);
if (req_cdclk != cur_cdclk)
if (req_cdclk != dev_priv->vlv_cdclk_freq)
valleyview_set_cdclk(dev, req_cdclk);
modeset_update_crtc_power_domains(dev);
}
......
......@@ -665,6 +665,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
const char *intel_output_name(int output);
bool intel_has_pending_fb_unpin(struct drm_device *dev);
int intel_pch_rawclk(struct drm_device *dev);
int valleyview_cur_cdclk(struct drm_i915_private *dev_priv);
void intel_mark_busy(struct drm_device *dev);
void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *ring);
......
......@@ -5078,6 +5078,10 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
}
DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
dev_priv->vlv_cdclk_freq = valleyview_cur_cdclk(dev_priv);
DRM_DEBUG_DRIVER("Current CD clock rate: %d MHz",
dev_priv->vlv_cdclk_freq);
I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
/* WaDisableEarlyCull:vlv */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment