drm/i915: Hook up pfit for DSI
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_pm.c
index 9bc9c25423e9f9f00e8caf09d5e8b9a4e3d04c59..b7c218602c6e53cfca384ccd49b1b6c0e260f552 100644 (file)
@@ -2483,7 +2483,7 @@ static void ilk_wm_merge(struct drm_device *dev,
        /* ILK/SNB/IVB: LP1+ watermarks only w/ single pipe */
        if ((INTEL_INFO(dev)->gen <= 6 || IS_IVYBRIDGE(dev)) &&
            config->num_pipes_active > 1)
-               return;
+               last_enabled_level = 0;
 
        /* ILK: FBC WM must be disabled always */
        merged->fbc_wm_enabled = INTEL_INFO(dev)->gen >= 6;
@@ -2937,25 +2937,28 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
                             const struct drm_plane_state *pstate,
                             int y)
 {
-       struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
+       struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
        struct drm_framebuffer *fb = pstate->fb;
+       uint32_t width = 0, height = 0;
+
+       width = drm_rect_width(&intel_pstate->src) >> 16;
+       height = drm_rect_height(&intel_pstate->src) >> 16;
+
+       if (intel_rotation_90_or_270(pstate->rotation))
+               swap(width, height);
 
        /* for planar format */
        if (fb->pixel_format == DRM_FORMAT_NV12) {
                if (y)  /* y-plane data rate */
-                       return intel_crtc->config->pipe_src_w *
-                               intel_crtc->config->pipe_src_h *
+                       return width * height *
                                drm_format_plane_cpp(fb->pixel_format, 0);
                else    /* uv-plane data rate */
-                       return (intel_crtc->config->pipe_src_w/2) *
-                               (intel_crtc->config->pipe_src_h/2) *
+                       return (width / 2) * (height / 2) *
                                drm_format_plane_cpp(fb->pixel_format, 1);
        }
 
        /* for packed formats */
-       return intel_crtc->config->pipe_src_w *
-               intel_crtc->config->pipe_src_h *
-               drm_format_plane_cpp(fb->pixel_format, 0);
+       return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
 }
 
 /*
@@ -3034,8 +3037,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
                struct drm_framebuffer *fb = plane->state->fb;
                int id = skl_wm_plane_id(intel_plane);
 
-               if (fb == NULL)
+               if (!to_intel_plane_state(plane->state)->visible)
                        continue;
+
                if (plane->type == DRM_PLANE_TYPE_CURSOR)
                        continue;
 
@@ -3061,7 +3065,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
                uint16_t plane_blocks, y_plane_blocks = 0;
                int id = skl_wm_plane_id(intel_plane);
 
-               if (pstate->fb == NULL)
+               if (!to_intel_plane_state(pstate)->visible)
                        continue;
                if (plane->type == DRM_PLANE_TYPE_CURSOR)
                        continue;
@@ -3184,26 +3188,36 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 {
        struct drm_plane *plane = &intel_plane->base;
        struct drm_framebuffer *fb = plane->state->fb;
+       struct intel_plane_state *intel_pstate =
+                                       to_intel_plane_state(plane->state);
        uint32_t latency = dev_priv->wm.skl_latency[level];
        uint32_t method1, method2;
        uint32_t plane_bytes_per_line, plane_blocks_per_line;
        uint32_t res_blocks, res_lines;
        uint32_t selected_result;
        uint8_t cpp;
+       uint32_t width = 0, height = 0;
 
-       if (latency == 0 || !cstate->base.active || !fb)
+       if (latency == 0 || !cstate->base.active || !intel_pstate->visible)
                return false;
 
+       width = drm_rect_width(&intel_pstate->src) >> 16;
+       height = drm_rect_height(&intel_pstate->src) >> 16;
+
+       if (intel_rotation_90_or_270(plane->state->rotation))
+               swap(width, height);
+
        cpp = drm_format_plane_cpp(fb->pixel_format, 0);
        method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
                                 cpp, latency);
        method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
                                 cstate->base.adjusted_mode.crtc_htotal,
-                                cstate->pipe_src_w,
-                                cpp, fb->modifier[0],
+                                width,
+                                cpp,
+                                fb->modifier[0],
                                 latency);
 
-       plane_bytes_per_line = cstate->pipe_src_w * cpp;
+       plane_bytes_per_line = width * cpp;
        plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
 
        if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
@@ -4288,7 +4302,7 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
         * the hw runs at the minimal clock before selecting the desired
         * frequency, if the down threshold expires in that window we will not
         * receive a down interrupt. */
-       if (IS_GEN9(dev_priv->dev)) {
+       if (IS_GEN9(dev_priv)) {
                limits = (dev_priv->rps.max_freq_softlimit) << 23;
                if (val <= dev_priv->rps.min_freq_softlimit)
                        limits |= (dev_priv->rps.min_freq_softlimit) << 14;
@@ -4808,7 +4822,7 @@ static void gen9_enable_rps(struct drm_device *dev)
         * Up/Down EI & threshold registers, as well as the RP_CONTROL,
         * RP_INTERRUPT_LIMITS & RPNSWREQ registers */
        dev_priv->rps.power = HIGH_POWER; /* force a reset */
-       gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
+       gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
@@ -4983,7 +4997,8 @@ static void gen6_enable_rps(struct drm_device *dev)
        I915_WRITE(GEN6_RC_STATE, 0);
 
        /* Clear the DBG now so we don't confuse earlier errors */
-       if ((gtfifodbg = I915_READ(GTFIFODBG))) {
+       gtfifodbg = I915_READ(GTFIFODBG);
+       if (gtfifodbg) {
                DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
                I915_WRITE(GTFIFODBG, gtfifodbg);
        }
@@ -5366,6 +5381,17 @@ static void valleyview_cleanup_pctx(struct drm_device *dev)
        dev_priv->vlv_pctx = NULL;
 }
 
+static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv)
+{
+       dev_priv->rps.gpll_ref_freq =
+               vlv_get_cck_clock(dev_priv, "GPLL ref",
+                                 CCK_GPLL_CLOCK_CONTROL,
+                                 dev_priv->czclk_freq);
+
+       DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n",
+                        dev_priv->rps.gpll_ref_freq);
+}
+
 static void valleyview_init_gt_powersave(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5373,6 +5399,8 @@ static void valleyview_init_gt_powersave(struct drm_device *dev)
 
        valleyview_setup_pctx(dev);
 
+       vlv_init_gpll_ref_freq(dev_priv);
+
        mutex_lock(&dev_priv->rps.hw_lock);
 
        val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
@@ -5430,6 +5458,8 @@ static void cherryview_init_gt_powersave(struct drm_device *dev)
 
        cherryview_setup_pctx(dev);
 
+       vlv_init_gpll_ref_freq(dev_priv);
+
        mutex_lock(&dev_priv->rps.hw_lock);
 
        mutex_lock(&dev_priv->sb_lock);
@@ -5499,7 +5529,8 @@ static void cherryview_enable_rps(struct drm_device *dev)
 
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
 
-       gtfifodbg = I915_READ(GTFIFODBG);
+       gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV |
+                                            GT_FIFO_FREE_ENTRIES_CHV);
        if (gtfifodbg) {
                DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
                                 gtfifodbg);
@@ -5580,10 +5611,10 @@ static void cherryview_enable_rps(struct drm_device *dev)
                         dev_priv->rps.cur_freq);
 
        DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
-                        intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
-                        dev_priv->rps.efficient_freq);
+                        intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq),
+                        dev_priv->rps.idle_freq);
 
-       valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
+       valleyview_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
@@ -5598,7 +5629,8 @@ static void valleyview_enable_rps(struct drm_device *dev)
 
        valleyview_check_pctx(dev_priv);
 
-       if ((gtfifodbg = I915_READ(GTFIFODBG))) {
+       gtfifodbg = I915_READ(GTFIFODBG);
+       if (gtfifodbg) {
                DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
                                 gtfifodbg);
                I915_WRITE(GTFIFODBG, gtfifodbg);
@@ -5669,10 +5701,10 @@ static void valleyview_enable_rps(struct drm_device *dev)
                         dev_priv->rps.cur_freq);
 
        DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
-                        intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
-                        dev_priv->rps.efficient_freq);
+                        intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq),
+                        dev_priv->rps.idle_freq);
 
-       valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
+       valleyview_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
@@ -6853,23 +6885,10 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
        gen6_check_mch_setup(dev);
 }
 
-static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
-{
-       I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
-
-       /*
-        * Disable trickle feed and enable pnd deadline calculation
-        */
-       I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
-       I915_WRITE(CBR1_VLV, 0);
-}
-
 static void valleyview_init_clock_gating(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       vlv_init_display_clock_gating(dev_priv);
-
        /* WaDisableEarlyCull:vlv */
        I915_WRITE(_3D_CHICKEN3,
                   _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
@@ -6952,8 +6971,6 @@ static void cherryview_init_clock_gating(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       vlv_init_display_clock_gating(dev_priv);
-
        /* WaVSRefCountFullforceMissDisable:chv */
        /* WaDSRefCountFullforceMissDisable:chv */
        I915_WRITE(GEN7_FF_THREAD_MODE,
@@ -7280,78 +7297,43 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val
        return 0;
 }
 
-static int vlv_gpu_freq_div(unsigned int czclk_freq)
-{
-       switch (czclk_freq) {
-       case 200:
-               return 10;
-       case 267:
-               return 12;
-       case 320:
-       case 333:
-               return 16;
-       case 400:
-               return 20;
-       default:
-               return -1;
-       }
-}
-
 static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
-       int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-
-       div = vlv_gpu_freq_div(czclk_freq);
-       if (div < 0)
-               return div;
-
-       return DIV_ROUND_CLOSEST(czclk_freq * (val + 6 - 0xbd), div);
+       /*
+        * N = val - 0xb7
+        * Slow = Fast = GPLL ref * N
+        */
+       return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * (val - 0xb7), 1000);
 }
 
 static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
-       int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-
-       mul = vlv_gpu_freq_div(czclk_freq);
-       if (mul < 0)
-               return mul;
-
-       return DIV_ROUND_CLOSEST(mul * val, czclk_freq) + 0xbd - 6;
+       return DIV_ROUND_CLOSEST(1000 * val, dev_priv->rps.gpll_ref_freq) + 0xb7;
 }
 
 static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
-       int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-
-       div = vlv_gpu_freq_div(czclk_freq);
-       if (div < 0)
-               return div;
-       div /= 2;
-
-       return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2;
+       /*
+        * N = val / 2
+        * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2
+        */
+       return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * val, 2 * 2 * 1000);
 }
 
 static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
-       int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-
-       mul = vlv_gpu_freq_div(czclk_freq);
-       if (mul < 0)
-               return mul;
-       mul /= 2;
-
        /* CHV needs even values */
-       return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2;
+       return DIV_ROUND_CLOSEST(2 * 1000 * val, dev_priv->rps.gpll_ref_freq) * 2;
 }
 
 int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
-       if (IS_GEN9(dev_priv->dev))
+       if (IS_GEN9(dev_priv))
                return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER,
                                         GEN9_FREQ_SCALER);
-       else if (IS_CHERRYVIEW(dev_priv->dev))
+       else if (IS_CHERRYVIEW(dev_priv))
                return chv_gpu_freq(dev_priv, val);
-       else if (IS_VALLEYVIEW(dev_priv->dev))
+       else if (IS_VALLEYVIEW(dev_priv))
                return byt_gpu_freq(dev_priv, val);
        else
                return val * GT_FREQUENCY_MULTIPLIER;
@@ -7359,12 +7341,12 @@ int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
 
 int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
-       if (IS_GEN9(dev_priv->dev))
+       if (IS_GEN9(dev_priv))
                return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER,
                                         GT_FREQUENCY_MULTIPLIER);
-       else if (IS_CHERRYVIEW(dev_priv->dev))
+       else if (IS_CHERRYVIEW(dev_priv))
                return chv_freq_opcode(dev_priv, val);
-       else if (IS_VALLEYVIEW(dev_priv->dev))
+       else if (IS_VALLEYVIEW(dev_priv))
                return byt_freq_opcode(dev_priv, val);
        else
                return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER);
This page took 0.04675 seconds and 5 git commands to generate.