drm/i915: Update RAWCLK_FREQ register on VLV/CHV
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 27 Apr 2016 14:43:22 +0000 (17:43 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 27 Apr 2016 17:38:57 +0000 (20:38 +0300)
I just noticed that VLV/CHV have a RAWCLK_FREQ register just like PCH
platforms. It lives in the display power well, so we should update it
when enabling the power well.

Interestingly the BIOS seems to leave it at the reset value (125) which
doesn't match the rawclk frequency on VLV/CHV (200 MHz). As always with
these register, the spec is extremely vague what the register does. All
it says is: "This is used to generate a divided down clock for
miscellaneous timers in display." Based on a quick test, at least AUX
and PWM appear to be unaffected by this.

But since the register is there, let's configure it in accordance with
the spec.

Note that we have to move intel_update_rawclk() to occur before we
touch the power wells, so that the dev_priv->rawclk_freq is already
populated when the disp2 enable hook gets called for the first time.
I think this should be safe to do on other platforms as well.

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1461768202-17544-1-git-send-email-ville.syrjala@linux.intel.com
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_runtime_pm.c

index 5c7615041b31b9e60c72549f3dda994a0f6474d4..fd1260d2b6ec2f1a80e1a129dc650c7d0096e169 100644 (file)
@@ -454,6 +454,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
        if (ret)
                goto cleanup_vga_client;
 
+       /* must happen before intel_power_domains_init_hw() on VLV/CHV */
+       intel_update_rawclk(dev_priv);
+
        intel_power_domains_init_hw(dev_priv, false);
 
        intel_csr_ucode_init(dev_priv);
index 25e229b609a74f1ed5bd28e757ae09bb45b8765b..0a2fd3000f944c85fdf5953ae66a36f3898e4303 100644 (file)
@@ -2449,6 +2449,8 @@ enum skl_disp_power_wells {
 #define   DPLL_MD_VGA_UDI_MULTIPLIER_MASK      0x0000003f
 #define   DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT     0
 
+#define RAWCLK_FREQ_VLV                _MMIO(VLV_DISPLAY_BASE + 0x6024)
+
 #define _FPA0  0x6040
 #define _FPA1  0x6044
 #define _FPB0  0x6048
index b7cb632a2a315fe296239284e37360c27c135b76..eb7cb94312095aeb67c4d36c29247cac2c845d8f 100644 (file)
@@ -185,6 +185,7 @@ intel_pch_rawclk(struct drm_i915_private *dev_priv)
 static int
 intel_vlv_hrawclk(struct drm_i915_private *dev_priv)
 {
+       /* RAWCLK_FREQ_VLV register updated from power well code */
        return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
                                      CCK_DISPLAY_REF_CLOCK_CONTROL);
 }
@@ -218,7 +219,7 @@ intel_g4x_hrawclk(struct drm_i915_private *dev_priv)
        }
 }
 
-static void intel_update_rawclk(struct drm_i915_private *dev_priv)
+void intel_update_rawclk(struct drm_i915_private *dev_priv)
 {
        if (HAS_PCH_SPLIT(dev_priv))
                dev_priv->rawclk_freq = intel_pch_rawclk(dev_priv);
@@ -15455,7 +15456,6 @@ void intel_modeset_init(struct drm_device *dev)
        }
 
        intel_update_czclk(dev_priv);
-       intel_update_rawclk(dev_priv);
        intel_update_cdclk(dev);
 
        intel_shared_dpll_init(dev);
index cb89a35a6755cc3e38e49cbc99feccb786f14ddb..ce78afefe3cd4508698b2fd4bbf5196f81bd8406 100644 (file)
@@ -1110,6 +1110,7 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv);
 void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
 
 /* intel_display.c */
+void intel_update_rawclk(struct drm_i915_private *dev_priv);
 int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
                      const char *name, u32 reg, int ref_freq);
 extern const struct drm_plane_funcs intel_plane_funcs;
index 7fb1da4e7fc349dfdfe26bb32dd7e97192b2ec04..b69b935516fbbddabf01b29b5295389e8c956dd2 100644 (file)
@@ -948,6 +948,11 @@ static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
         */
        I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
        I915_WRITE(CBR1_VLV, 0);
+
+       WARN_ON(dev_priv->rawclk_freq == 0);
+
+       I915_WRITE(RAWCLK_FREQ_VLV,
+                  DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 1000));
 }
 
 static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)