intel_p2_t p2;
};
+/* returns HPLL frequency in kHz */
+static int valleyview_get_vco(struct drm_i915_private *dev_priv)
+{
+ int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
+
+ /* Obtain SKU information */
+ mutex_lock(&dev_priv->sb_lock);
+ hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
+ CCK_FUSE_HPLL_FREQ_MASK;
+ mutex_unlock(&dev_priv->sb_lock);
+
+ return vco_freq[hpll_freq] * 1000;
+}
+
+static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
+ const char *name, u32 reg)
+{
+ u32 val;
+ int divider;
+
+ if (dev_priv->hpll_freq == 0)
+ dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
+
+ mutex_lock(&dev_priv->sb_lock);
+ val = vlv_cck_read(dev_priv, reg);
+ mutex_unlock(&dev_priv->sb_lock);
+
+ divider = val & CCK_FREQUENCY_VALUES;
+
+ WARN((val & CCK_FREQUENCY_STATUS) !=
+ (divider << CCK_FREQUENCY_STATUS_SHIFT),
+ "%s change in progress\n", name);
+
+ return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1);
+}
+
int
intel_pch_rawclk(struct drm_device *dev)
{
}
}
+static void intel_update_czclk(struct drm_i915_private *dev_priv)
+{
+ if (!IS_VALLEYVIEW(dev_priv))
+ return;
+
+ dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk",
+ CCK_CZ_CLOCK_CONTROL);
+
+ DRM_DEBUG_DRIVER("CZ clock rate: %d kHz\n", dev_priv->czclk_freq);
+}
+
static inline u32 /* units of 100MHz */
intel_fdi_link_freq(struct drm_device *dev)
{
DRM_ERROR("DBuf power enable timeout\n");
}
-/* returns HPLL frequency in kHz */
-static int valleyview_get_vco(struct drm_i915_private *dev_priv)
-{
- int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
-
- /* Obtain SKU information */
- mutex_lock(&dev_priv->sb_lock);
- hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
- CCK_FUSE_HPLL_FREQ_MASK;
- mutex_unlock(&dev_priv->sb_lock);
-
- return vco_freq[hpll_freq] * 1000;
-}
-
/* Adjust CDclk dividers to allow high res or save power if possible */
static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
{
else
default_credits = PFI_CREDIT(8);
- if (DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 1000) >= dev_priv->rps.cz_freq) {
+ if (dev_priv->cdclk_freq >= dev_priv->czclk_freq) {
/* CHV suggested value is 31 or 63 */
if (IS_CHERRYVIEW(dev_priv))
credits = PFI_CREDIT_63;
static int valleyview_get_display_clock_speed(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 val;
- int divider;
-
- if (dev_priv->hpll_freq == 0)
- dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
-
- mutex_lock(&dev_priv->sb_lock);
- val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
- mutex_unlock(&dev_priv->sb_lock);
-
- divider = val & CCK_FREQUENCY_VALUES;
-
- WARN((val & CCK_FREQUENCY_STATUS) !=
- (divider << CCK_FREQUENCY_STATUS_SHIFT),
- "cdclk change in progress\n");
-
- return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1);
+ return vlv_get_cck_clock_hpll(to_i915(dev), "cdclk",
+ CCK_DISPLAY_CLOCK_CONTROL);
}
static int ilk_get_display_clock_speed(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- intel_update_cdclk(dev);
-
if (HAS_DDI(dev))
intel_ddi_pll_init(dev);
else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
}
}
+ intel_update_czclk(dev_priv);
+ intel_update_cdclk(dev);
+
intel_shared_dpll_init(dev);
/* Just disable it once at startup */
mutex_unlock(&dev_priv->sb_lock);
switch ((val >> 2) & 0x7) {
- case 0:
- case 1:
- dev_priv->rps.cz_freq = 200;
- dev_priv->mem_freq = 1600;
- break;
- case 2:
- dev_priv->rps.cz_freq = 267;
- dev_priv->mem_freq = 1600;
- break;
case 3:
- dev_priv->rps.cz_freq = 333;
dev_priv->mem_freq = 2000;
break;
- case 4:
- dev_priv->rps.cz_freq = 320;
- dev_priv->mem_freq = 1600;
- break;
- case 5:
- dev_priv->rps.cz_freq = 400;
+ default:
dev_priv->mem_freq = 1600;
break;
}
static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
- int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);
+ int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
div = vlv_gpu_freq_div(czclk_freq);
if (div < 0)
static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
- int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);
+ int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
mul = vlv_gpu_freq_div(czclk_freq);
if (mul < 0)
static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
- int div, czclk_freq = dev_priv->rps.cz_freq;
+ int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
div = vlv_gpu_freq_div(czclk_freq) / 2;
if (div < 0)
static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
- int mul, czclk_freq = dev_priv->rps.cz_freq;
+ int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
mul = vlv_gpu_freq_div(czclk_freq) / 2;
if (mul < 0)