Merge tag 'drm-intel-next-2017-10-12' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <airlied@redhat.com>
Fri, 20 Oct 2017 00:56:10 +0000 (10:56 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 20 Oct 2017 00:56:10 +0000 (10:56 +1000)
Last batch of drm/i915 features for v4.15:

- transparent huge pages support (Matthew)
- uapi: I915_PARAM_HAS_SCHEDULER into a capability bitmask (Chris)
- execlists: preemption (Chris)
- scheduler: user defined priorities (Chris)
- execlists optimization (MichaƂ)
- plenty of display fixes (Imre)
- has_ipc fix (Rodrigo)
- platform features definition refactoring (Rodrigo)
- legacy cursor update fix (Maarten)
- fix vblank waits for cursor updates (Maarten)
- reprogram dmc firmware on resume, dmc state fix (Imre)
- remove use_mmio_flip module parameter (Maarten)
- wa fixes (Oscar)
- huc/guc firmware refacoring (Sagar, Michal)
- push encoder specific code to encoder hooks (Jani)
- DP MST fixes (Dhinakaran)
- eDP power sequencing fixes (Manasi)
- selftest updates (Chris, Matthew)
- mmu notifier cpu hotplug deadlock fix (Daniel)
- more VBT parser refactoring (Jani)
- max pipe refactoring (Mika Kahola)
- rc6/rps refactoring and separation (Sagar)
- userptr lockdep fix (Chris)
- tracepoint fixes and defunct tracepoint removal (Chris)
- use rcu instead of abusing stop_machine (Daniel)
- plenty of other fixes all around (Everyone)

* tag 'drm-intel-next-2017-10-12' of git://anongit.freedesktop.org/drm/drm-intel: (145 commits)
  drm/i915: Update DRIVER_DATE to 20171012
  drm/i915: Simplify intel_sanitize_enable_ppgtt
  drm/i915/userptr: Drop struct_mutex before cleanup
  drm/i915/dp: limit sink rates based on rate
  drm/i915/dp: centralize max source rate conditions more
  drm/i915: Allow PCH platforms fall back to BIOS LVDS mode
  drm/i915: Reuse normal state readout for LVDS/DVO fixed mode
  drm/i915: Use rcu instead of stop_machine in set_wedged
  drm/i915: Introduce separate status variable for RC6 and LLC ring frequency setup
  drm/i915: Create generic functions to control RC6, RPS
  drm/i915: Create generic function to setup LLC ring frequency table
  drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled
  drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "gt_pm"
  drm/i915: Move rps.hw_lock to dev_priv and s/hw_lock/pcu_lock
  drm/i915: Name i915_runtime_pm structure in dev_priv as "runtime_pm"
  drm/i915: Separate RPS and RC6 handling for CHV
  drm/i915: Separate RPS and RC6 handling for VLV
  drm/i915: Separate RPS and RC6 handling for BDW
  drm/i915: Remove superfluous IS_BDW checks and non-BDW changes from gen8_enable_rps
  drm/i915: Separate RPS and RC6 handling for gen6+
  ...

1  2 
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_sprite.c

@@@ -1539,7 -1539,7 +1539,7 @@@ static void chv_enable_pll(struct intel
                 * DPLLCMD is AWOL. Use chicken bits to propagate
                 * the value from DPLLBMD to either pipe B or C.
                 */
-               I915_WRITE(CBR4_VLV, pipe == PIPE_B ? CBR_DPLLBMD_PIPE_B : CBR_DPLLBMD_PIPE_C);
+               I915_WRITE(CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
                I915_WRITE(DPLL_MD(PIPE_B), pipe_config->dpll_hw_state.dpll_md);
                I915_WRITE(CBR4_VLV, 0);
                dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
@@@ -1568,11 -1568,12 +1568,12 @@@ static int intel_num_dvo_pipes(struct d
        return count;
  }
  
- static void i9xx_enable_pll(struct intel_crtc *crtc)
+ static void i9xx_enable_pll(struct intel_crtc *crtc,
+                           const struct intel_crtc_state *crtc_state)
  {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        i915_reg_t reg = DPLL(crtc->pipe);
-       u32 dpll = crtc->config->dpll_hw_state.dpll;
+       u32 dpll = crtc_state->dpll_hw_state.dpll;
        int i;
  
        assert_pipe_disabled(dev_priv, crtc->pipe);
  
        if (INTEL_GEN(dev_priv) >= 4) {
                I915_WRITE(DPLL_MD(crtc->pipe),
-                          crtc->config->dpll_hw_state.dpll_md);
+                          crtc_state->dpll_hw_state.dpll_md);
        } else {
                /* The pixel multiplier can only be updated once the
                 * DPLL is enabled and the clocks are stable.
        }
  }
  
- /**
-  * i9xx_disable_pll - disable a PLL
-  * @dev_priv: i915 private structure
-  * @pipe: pipe PLL to disable
-  *
-  * Disable the PLL for @pipe, making sure the pipe is off first.
-  *
-  * Note!  This is for pre-ILK only.
-  */
  static void i9xx_disable_pll(struct intel_crtc *crtc)
  {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@@ -2219,8 -2211,7 +2211,7 @@@ intel_pin_and_fence_fb_obj(struct drm_f
                 * something and try to run the system in a "less than optimal"
                 * mode that matches the user configuration.
                 */
-               if (i915_vma_get_fence(vma) == 0)
-                       i915_vma_pin_fence(vma);
+               i915_vma_pin_fence(vma);
        }
  
        i915_vma_get(vma);
@@@ -4955,10 -4946,10 +4946,10 @@@ void hsw_enable_ips(struct intel_crtc *
  
        assert_plane_enabled(dev_priv, crtc->plane);
        if (IS_BROADWELL(dev_priv)) {
-               mutex_lock(&dev_priv->rps.hw_lock);
+               mutex_lock(&dev_priv->pcu_lock);
                WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL,
                                                IPS_ENABLE | IPS_PCODE_CONTROL));
-               mutex_unlock(&dev_priv->rps.hw_lock);
+               mutex_unlock(&dev_priv->pcu_lock);
                /* Quoting Art Runyan: "its not safe to expect any particular
                 * value in IPS_CTL bit 31 after enabling IPS through the
                 * mailbox." Moreover, the mailbox may return a bogus state,
@@@ -4988,9 -4979,9 +4979,9 @@@ void hsw_disable_ips(struct intel_crtc 
  
        assert_plane_enabled(dev_priv, crtc->plane);
        if (IS_BROADWELL(dev_priv)) {
-               mutex_lock(&dev_priv->rps.hw_lock);
+               mutex_lock(&dev_priv->pcu_lock);
                WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
-               mutex_unlock(&dev_priv->rps.hw_lock);
+               mutex_unlock(&dev_priv->pcu_lock);
                /* wait for pcode to finish disabling IPS, which may take up to 42ms */
                if (intel_wait_for_register(dev_priv,
                                            IPS_CTL, IPS_ENABLE, 0,
@@@ -5459,6 -5450,20 +5450,20 @@@ static bool hsw_crtc_supports_ips(struc
        return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
  }
  
+ static void glk_pipe_scaler_clock_gating_wa(struct drm_i915_private *dev_priv,
+                                           enum pipe pipe, bool apply)
+ {
+       u32 val = I915_READ(CLKGATE_DIS_PSL(pipe));
+       u32 mask = DPF_GATING_DIS | DPF_RAM_GATING_DIS | DPFR_GATING_DIS;
+       if (apply)
+               val |= mask;
+       else
+               val &= ~mask;
+       I915_WRITE(CLKGATE_DIS_PSL(pipe), val);
+ }
  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
                                struct drm_atomic_state *old_state)
  {
        enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
        struct intel_atomic_state *old_intel_state =
                to_intel_atomic_state(old_state);
+       bool psl_clkgate_wa;
  
        if (WARN_ON(intel_crtc->active))
                return;
  
-       if (intel_crtc->config->has_pch_encoder)
-               intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
        intel_encoders_pre_pll_enable(crtc, pipe_config, old_state);
  
        if (intel_crtc->config->shared_dpll)
  
        intel_crtc->active = true;
  
-       if (intel_crtc->config->has_pch_encoder)
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
-       else
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
        intel_encoders_pre_enable(crtc, pipe_config, old_state);
  
-       if (intel_crtc->config->has_pch_encoder)
-               dev_priv->display.fdi_link_train(intel_crtc, pipe_config);
        if (!transcoder_is_dsi(cpu_transcoder))
                intel_ddi_enable_pipe_clock(pipe_config);
  
+       /* Display WA #1180: WaDisableScalarClockGating: glk, cnl */
+       psl_clkgate_wa = (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
+                        intel_crtc->config->pch_pfit.enabled;
+       if (psl_clkgate_wa)
+               glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, true);
        if (INTEL_GEN(dev_priv) >= 9)
                skylake_pfit_enable(intel_crtc);
        else
  
        intel_encoders_enable(crtc, pipe_config, old_state);
  
-       if (intel_crtc->config->has_pch_encoder) {
+       if (psl_clkgate_wa) {
                intel_wait_for_vblank(dev_priv, pipe);
-               intel_wait_for_vblank(dev_priv, pipe);
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
-               intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+               glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);
        }
  
        /* If we change the relative order between pipe/planes enabling, we need
@@@ -5655,9 -5654,6 +5654,6 @@@ static void haswell_crtc_disable(struc
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
  
-       if (intel_crtc->config->has_pch_encoder)
-               intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
        intel_encoders_disable(crtc, old_crtc_state, old_state);
  
        drm_crtc_vblank_off(crtc);
                intel_ddi_disable_pipe_clock(intel_crtc->config);
  
        intel_encoders_post_disable(crtc, old_crtc_state, old_state);
-       if (old_crtc_state->has_pch_encoder)
-               intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
  }
  
  static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@@ -5894,7 -5887,7 +5887,7 @@@ static void i9xx_crtc_enable(struct int
  
        intel_encoders_pre_enable(crtc, pipe_config, old_state);
  
-       i9xx_enable_pll(intel_crtc);
+       i9xx_enable_pll(intel_crtc, pipe_config);
  
        i9xx_pfit_enable(intel_crtc);
  
@@@ -8846,11 -8839,11 +8839,11 @@@ static uint32_t hsw_read_dcomp(struct d
  static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
  {
        if (IS_HASWELL(dev_priv)) {
-               mutex_lock(&dev_priv->rps.hw_lock);
+               mutex_lock(&dev_priv->pcu_lock);
                if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP,
                                            val))
                        DRM_DEBUG_KMS("Failed to write to D_COMP\n");
-               mutex_unlock(&dev_priv->rps.hw_lock);
+               mutex_unlock(&dev_priv->pcu_lock);
        } else {
                I915_WRITE(D_COMP_BDW, val);
                POSTING_READ(D_COMP_BDW);
@@@ -10245,58 -10238,44 +10238,44 @@@ static void ironlake_pch_clock_get(stru
                                         &pipe_config->fdi_m_n);
  }
  
- /** Returns the currently programmed mode of the given pipe. */
- struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
                                           struct drm_crtc *crtc)
+ /* Returns the currently programmed mode of the given encoder. */
+ struct drm_display_mode *
intel_encoder_current_mode(struct intel_encoder *encoder)
  {
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_crtc_state *crtc_state;
        struct drm_display_mode *mode;
-       struct intel_crtc_state *pipe_config;
-       int htot = I915_READ(HTOTAL(cpu_transcoder));
-       int hsync = I915_READ(HSYNC(cpu_transcoder));
-       int vtot = I915_READ(VTOTAL(cpu_transcoder));
-       int vsync = I915_READ(VSYNC(cpu_transcoder));
-       enum pipe pipe = intel_crtc->pipe;
+       struct intel_crtc *crtc;
+       enum pipe pipe;
+       if (!encoder->get_hw_state(encoder, &pipe))
+               return NULL;
+       crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
  
        mode = kzalloc(sizeof(*mode), GFP_KERNEL);
        if (!mode)
                return NULL;
  
-       pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
-       if (!pipe_config) {
+       crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
+       if (!crtc_state) {
                kfree(mode);
                return NULL;
        }
  
-       /*
-        * Construct a pipe_config sufficient for getting the clock info
-        * back out of crtc_clock_get.
-        *
-        * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
-        * to use a real value here instead.
-        */
-       pipe_config->cpu_transcoder = (enum transcoder) pipe;
-       pipe_config->pixel_multiplier = 1;
-       pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(pipe));
-       pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(pipe));
-       pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe));
-       i9xx_crtc_clock_get(intel_crtc, pipe_config);
-       mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier;
-       mode->hdisplay = (htot & 0xffff) + 1;
-       mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
-       mode->hsync_start = (hsync & 0xffff) + 1;
-       mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
-       mode->vdisplay = (vtot & 0xffff) + 1;
-       mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
-       mode->vsync_start = (vsync & 0xffff) + 1;
-       mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
+       crtc_state->base.crtc = &crtc->base;
  
-       drm_mode_set_name(mode);
+       if (!dev_priv->display.get_pipe_config(crtc, crtc_state)) {
+               kfree(crtc_state);
+               kfree(mode);
+               return NULL;
+       }
  
-       kfree(pipe_config);
+       encoder->get_config(encoder, crtc_state);
+       intel_mode_from_pipe_config(mode, crtc_state);
+       kfree(crtc_state);
  
        return mode;
  }
@@@ -11336,6 -11315,18 +11315,18 @@@ intel_pipe_config_compare(struct drm_i9
        PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
        PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
        PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
+       PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
+       PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
+       PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
+       PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
  
        PIPE_CONF_CHECK_X(dsi_pll.ctrl);
        PIPE_CONF_CHECK_X(dsi_pll.div);
@@@ -12220,7 -12211,10 +12211,10 @@@ static void skl_update_crtcs(struct drm
                        if (updated & cmask || !cstate->base.active)
                                continue;
  
-                       if (skl_ddb_allocation_overlaps(entries, &cstate->wm.skl.ddb, i))
+                       if (skl_ddb_allocation_overlaps(dev_priv,
+                                                       entries,
+                                                       &cstate->wm.skl.ddb,
+                                                       i))
                                continue;
  
                        updated |= cmask;
@@@ -12515,21 -12509,10 +12509,10 @@@ static int intel_atomic_commit(struct d
        struct drm_i915_private *dev_priv = to_i915(dev);
        int ret = 0;
  
-       ret = drm_atomic_helper_setup_commit(state, nonblock);
-       if (ret)
-               return ret;
        drm_atomic_state_get(state);
        i915_sw_fence_init(&intel_state->commit_ready,
                           intel_atomic_commit_ready);
  
-       ret = intel_atomic_prepare_commit(dev, state);
-       if (ret) {
-               DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
-               i915_sw_fence_commit(&intel_state->commit_ready);
-               return ret;
-       }
        /*
         * The intel_legacy_cursor_update() fast path takes care
         * of avoiding the vblank waits for simple cursor
         * updates happen during the correct frames. Gen9+ have
         * double buffered watermarks and so shouldn't need this.
         *
-        * Do this after drm_atomic_helper_setup_commit() and
-        * intel_atomic_prepare_commit() because we still want
-        * to skip the flip and fb cleanup waits. Although that
-        * does risk yanking the mapping from under the display
-        * engine.
+        * Unset state->legacy_cursor_update before the call to
+        * drm_atomic_helper_setup_commit() because otherwise
+        * drm_atomic_helper_wait_for_flip_done() is a noop and
+        * we get FIFO underruns because we didn't wait
+        * for vblank.
         *
         * FIXME doing watermarks and fb cleanup from a vblank worker
         * (assuming we had any) would solve these problems.
         */
-       if (INTEL_GEN(dev_priv) < 9)
-               state->legacy_cursor_update = false;
+       if (INTEL_GEN(dev_priv) < 9 && state->legacy_cursor_update) {
+               struct intel_crtc_state *new_crtc_state;
+               struct intel_crtc *crtc;
+               int i;
+               for_each_new_intel_crtc_in_state(intel_state, crtc, new_crtc_state, i)
+                       if (new_crtc_state->wm.need_postvbl_update ||
+                           new_crtc_state->update_wm_post)
+                               state->legacy_cursor_update = false;
+       }
+       ret = intel_atomic_prepare_commit(dev, state);
+       if (ret) {
+               DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
+               i915_sw_fence_commit(&intel_state->commit_ready);
+               return ret;
+       }
+       ret = drm_atomic_helper_setup_commit(state, nonblock);
+       if (!ret)
+               ret = drm_atomic_helper_swap_state(state, true);
  
-       ret = drm_atomic_helper_swap_state(state, true);
        if (ret) {
                i915_sw_fence_commit(&intel_state->commit_ready);
  
@@@ -13510,7 -13511,7 +13511,7 @@@ int intel_get_pipe_from_crtc_id(struct 
        struct drm_crtc *drmmode_crtc;
        struct intel_crtc *crtc;
  
 -      drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
 +      drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
        if (!drmmode_crtc)
                return -ENOENT;
  
@@@ -14748,10 -14749,10 +14749,10 @@@ static struct intel_connector *intel_en
  }
  
  static bool has_pch_trancoder(struct drm_i915_private *dev_priv,
-                             enum transcoder pch_transcoder)
+                             enum pipe pch_transcoder)
  {
        return HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) ||
-               (HAS_PCH_LPT_H(dev_priv) && pch_transcoder == TRANSCODER_A);
+               (HAS_PCH_LPT_H(dev_priv) && pch_transcoder == PIPE_A);
  }
  
  static void intel_sanitize_crtc(struct intel_crtc *crtc,
                 * PCH transcoders B and C would prevent enabling the south
                 * error interrupt (see cpt_can_enable_serr_int()).
                 */
-               if (has_pch_trancoder(dev_priv, (enum transcoder)crtc->pipe))
+               if (has_pch_trancoder(dev_priv, crtc->pipe))
                        crtc->pch_fifo_underrun_disabled = true;
        }
  }
@@@ -66,7 -66,13 +66,13 @@@ int intel_usecs_to_scanlines(const stru
                            1000 * adjusted_mode->crtc_htotal);
  }
  
+ /* FIXME: We should instead only take spinlocks once for the entire update
+  * instead of once per mmio. */
+ #if IS_ENABLED(CONFIG_PROVE_LOCKING)
+ #define VBLANK_EVASION_TIME_US 250
+ #else
  #define VBLANK_EVASION_TIME_US 100
+ #endif
  
  /**
   * intel_pipe_update_start() - start update of a set of display registers
@@@ -994,7 -1000,7 +1000,7 @@@ int intel_sprite_set_colorkey(struct dr
            set->flags & I915_SET_COLORKEY_DESTINATION)
                return -EINVAL;
  
 -      plane = drm_plane_find(dev, set->plane_id);
 +      plane = drm_plane_find(dev, file_priv, set->plane_id);
        if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
                return -ENOENT;