drm/i915: Enable fastboot by default on VLV and CHV
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_display.c
index 3da9c0f9e9485c7c4b9ccf8fefe5c71f72f1ea02..8b36ee183c7ebb9060db39a9841721da84a397b3 100644 (file)
 #include <linux/slab.h>
 #include <linux/vgaarb.h>
 #include <drm/drm_edid.h>
-#include <drm/drmP.h>
-#include "intel_drv.h"
-#include "intel_frontbuffer.h"
 #include <drm/i915_drm.h>
-#include "i915_drv.h"
-#include "i915_gem_clflush.h"
-#include "intel_dsi.h"
-#include "i915_trace.h"
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <linux/intel-iommu.h>
 #include <linux/reservation.h>
 
+#include "intel_drv.h"
+#include "intel_dsi.h"
+#include "intel_frontbuffer.h"
+
+#include "i915_drv.h"
+#include "i915_gem_clflush.h"
+#include "i915_reset.h"
+#include "i915_trace.h"
+
 /* Primary plane formats for gen <= 3 */
-static const uint32_t i8xx_primary_formats[] = {
+static const u32 i8xx_primary_formats[] = {
        DRM_FORMAT_C8,
        DRM_FORMAT_RGB565,
        DRM_FORMAT_XRGB1555,
@@ -58,7 +60,7 @@ static const uint32_t i8xx_primary_formats[] = {
 };
 
 /* Primary plane formats for gen >= 4 */
-static const uint32_t i965_primary_formats[] = {
+static const u32 i965_primary_formats[] = {
        DRM_FORMAT_C8,
        DRM_FORMAT_RGB565,
        DRM_FORMAT_XRGB8888,
@@ -67,18 +69,18 @@ static const uint32_t i965_primary_formats[] = {
        DRM_FORMAT_XBGR2101010,
 };
 
-static const uint64_t i9xx_format_modifiers[] = {
+static const u64 i9xx_format_modifiers[] = {
        I915_FORMAT_MOD_X_TILED,
        DRM_FORMAT_MOD_LINEAR,
        DRM_FORMAT_MOD_INVALID
 };
 
 /* Cursor formats */
-static const uint32_t intel_cursor_formats[] = {
+static const u32 intel_cursor_formats[] = {
        DRM_FORMAT_ARGB8888,
 };
 
-static const uint64_t cursor_format_modifiers[] = {
+static const u64 cursor_format_modifiers[] = {
        DRM_FORMAT_MOD_LINEAR,
        DRM_FORMAT_MOD_INVALID
 };
@@ -494,7 +496,7 @@ static int pnv_calc_dpll_params(int refclk, struct dpll *clock)
        return clock->dot;
 }
 
-static uint32_t i9xx_dpll_compute_m(struct dpll *dpll)
+static u32 i9xx_dpll_compute_m(struct dpll *dpll)
 {
        return 5 * (dpll->m1 + 2) + (dpll->m2 + 2);
 }
@@ -529,8 +531,8 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock)
        clock->p = clock->p1 * clock->p2;
        if (WARN_ON(clock->n == 0 || clock->p == 0))
                return 0;
-       clock->vco = DIV_ROUND_CLOSEST_ULL((uint64_t)refclk * clock->m,
-                       clock->n << 22);
+       clock->vco = DIV_ROUND_CLOSEST_ULL((u64)refclk * clock->m,
+                                          clock->n << 22);
        clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);
 
        return clock->dot / 5;
@@ -892,7 +894,7 @@ chv_find_best_dpll(const struct intel_limit *limit,
        struct drm_device *dev = crtc->base.dev;
        unsigned int best_error_ppm;
        struct dpll clock;
-       uint64_t m2;
+       u64 m2;
        int found = false;
 
        memset(best_clock, 0, sizeof(*best_clock));
@@ -914,7 +916,7 @@ chv_find_best_dpll(const struct intel_limit *limit,
 
                        clock.p = clock.p1 * clock.p2;
 
-                       m2 = DIV_ROUND_CLOSEST_ULL(((uint64_t)target * clock.p *
+                       m2 = DIV_ROUND_CLOSEST_ULL(((u64)target * clock.p *
                                        clock.n) << 22, refclk * clock.m1);
 
                        if (m2 > INT_MAX/clock.m1)
@@ -984,7 +986,7 @@ static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,
        u32 line1, line2;
        u32 line_mask;
 
-       if (IS_GEN2(dev_priv))
+       if (IS_GEN(dev_priv, 2))
                line_mask = DSL_LINEMASK_GEN2;
        else
                line_mask = DSL_LINEMASK_GEN3;
@@ -1110,7 +1112,7 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
        u32 val;
 
        /* ILK FDI PLL is always enabled */
-       if (IS_GEN5(dev_priv))
+       if (IS_GEN(dev_priv, 5))
                return;
 
        /* On Haswell, DDI ports are responsible for the FDI PLL setup */
@@ -1198,17 +1200,19 @@ void assert_pipe(struct drm_i915_private *dev_priv,
        enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
                                                                      pipe);
        enum intel_display_power_domain power_domain;
+       intel_wakeref_t wakeref;
 
        /* we keep both pipes enabled on 830 */
        if (IS_I830(dev_priv))
                state = true;
 
        power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
-       if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
+       wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+       if (wakeref) {
                u32 val = I915_READ(PIPECONF(cpu_transcoder));
                cur_state = !!(val & PIPECONF_ENABLE);
 
-               intel_display_power_put(dev_priv, power_domain);
+               intel_display_power_put(dev_priv, power_domain, wakeref);
        } else {
                cur_state = false;
        }
@@ -1609,7 +1613,7 @@ static void ironlake_enable_pch_transcoder(const struct intel_crtc_state *crtc_s
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum pipe pipe = crtc->pipe;
        i915_reg_t reg;
-       uint32_t val, pipeconf_val;
+       u32 val, pipeconf_val;
 
        /* Make sure PCH DPLL is enabled */
        assert_shared_dpll_enabled(dev_priv, crtc_state->shared_dpll);
@@ -1697,7 +1701,7 @@ static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv,
                                            enum pipe pipe)
 {
        i915_reg_t reg;
-       uint32_t val;
+       u32 val;
 
        /* FDI relies on the transcoder */
        assert_fdi_tx_disabled(dev_priv, pipe);
@@ -1754,6 +1758,35 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
                return crtc->pipe;
 }
 
+static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+
+       /*
+        * On i965gm the hardware frame counter reads
+        * zero when the TV encoder is enabled :(
+        */
+       if (IS_I965GM(dev_priv) &&
+           (crtc_state->output_types & BIT(INTEL_OUTPUT_TVOUT)))
+               return 0;
+
+       if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
+               return 0xffffffff; /* full 32 bit counter */
+       else if (INTEL_GEN(dev_priv) >= 3)
+               return 0xffffff; /* only 24 bits of frame count */
+       else
+               return 0; /* Gen2 doesn't have a hardware frame counter */
+}
+
+static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
+{
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+
+       drm_crtc_set_max_vblank_count(&crtc->base,
+                                     intel_crtc_max_vblank_count(crtc_state));
+       drm_crtc_vblank_on(&crtc->base);
+}
+
 static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
@@ -1806,7 +1839,7 @@ static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
         * when it's derived from the timestamps. So let's wait for the
         * pipe to start properly before we call drm_crtc_vblank_on()
         */
-       if (dev_priv->drm.max_vblank_count == 0)
+       if (intel_crtc_max_vblank_count(new_crtc_state) == 0)
                intel_wait_for_pipe_scanline_moving(crtc);
 }
 
@@ -1850,7 +1883,7 @@ static void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state)
 
 static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv)
 {
-       return IS_GEN2(dev_priv) ? 2048 : 4096;
+       return IS_GEN(dev_priv, 2) ? 2048 : 4096;
 }
 
 static unsigned int
@@ -1863,7 +1896,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
        case DRM_FORMAT_MOD_LINEAR:
                return cpp;
        case I915_FORMAT_MOD_X_TILED:
-               if (IS_GEN2(dev_priv))
+               if (IS_GEN(dev_priv, 2))
                        return 128;
                else
                        return 512;
@@ -1872,7 +1905,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
                        return 128;
                /* fall through */
        case I915_FORMAT_MOD_Y_TILED:
-               if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv))
+               if (IS_GEN(dev_priv, 2) || HAS_128_BYTE_Y_TILING(dev_priv))
                        return 128;
                else
                        return 512;
@@ -2024,6 +2057,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
        struct drm_device *dev = fb->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+       intel_wakeref_t wakeref;
        struct i915_vma *vma;
        unsigned int pinctl;
        u32 alignment;
@@ -2047,7 +2081,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
         * intel_runtime_pm_put(), so it is correct to wrap only the
         * pin/unpin/fence and not more.
         */
-       intel_runtime_pm_get(dev_priv);
+       wakeref = intel_runtime_pm_get(dev_priv);
 
        atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
 
@@ -2102,7 +2136,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
 err:
        atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
 
-       intel_runtime_pm_put(dev_priv);
+       intel_runtime_pm_put(dev_priv, wakeref);
        return vma;
 }
 
@@ -2373,7 +2407,7 @@ static int intel_fb_offset_to_xy(int *x, int *y,
        return 0;
 }
 
-static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier)
+static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier)
 {
        switch (fb_modifier) {
        case I915_FORMAT_MOD_X_TILED:
@@ -3193,8 +3227,8 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
 
        dspcntr = DISPLAY_PLANE_ENABLE | DISPPLANE_GAMMA_ENABLE;
 
-       if (IS_G4X(dev_priv) || IS_GEN5(dev_priv) ||
-           IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
+       if (IS_G4X(dev_priv) || IS_GEN(dev_priv, 5) ||
+           IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
                dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
 
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
@@ -3412,6 +3446,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
+       intel_wakeref_t wakeref;
        bool ret;
        u32 val;
 
@@ -3421,7 +3456,8 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
         * display power wells.
         */
        power_domain = POWER_DOMAIN_PIPE(plane->pipe);
-       if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+       wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+       if (!wakeref)
                return false;
 
        val = I915_READ(DSPCNTR(i9xx_plane));
@@ -3434,7 +3470,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
                *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
                        DISPPLANE_SEL_PIPE_SHIFT;
 
-       intel_display_power_put(dev_priv, power_domain);
+       intel_display_power_put(dev_priv, power_domain, wakeref);
 
        return ret;
 }
@@ -3503,7 +3539,7 @@ u32 skl_plane_stride(const struct intel_plane_state *plane_state,
        return stride / skl_plane_stride_mult(fb, color_plane, rotation);
 }
 
-static u32 skl_plane_ctl_format(uint32_t pixel_format)
+static u32 skl_plane_ctl_format(u32 pixel_format)
 {
        switch (pixel_format) {
        case DRM_FORMAT_C8:
@@ -3573,7 +3609,7 @@ static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state *plane_state
        }
 }
 
-static u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
+static u32 skl_plane_ctl_tiling(u64 fb_modifier)
 {
        switch (fb_modifier) {
        case DRM_FORMAT_MOD_LINEAR:
@@ -3746,8 +3782,8 @@ __intel_display_resume(struct drm_device *dev,
 
 static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
 {
-       return intel_has_gpu_reset(dev_priv) &&
-               INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv);
+       return (INTEL_INFO(dev_priv)->gpu_reset_clobbers_display &&
+               intel_has_gpu_reset(dev_priv));
 }
 
 void intel_prepare_reset(struct drm_i915_private *dev_priv)
@@ -3894,6 +3930,16 @@ static void intel_update_pipe_config(const struct intel_crtc_state *old_crtc_sta
                else if (old_crtc_state->pch_pfit.enabled)
                        ironlake_pfit_disable(old_crtc_state);
        }
+
+       /*
+        * We don't (yet) allow userspace to control the pipe background color,
+        * so force it to black, but apply pipe gamma and CSC so that its
+        * handling will match how we program our planes.
+        */
+       if (INTEL_GEN(dev_priv) >= 9)
+               I915_WRITE(SKL_BOTTOM_COLOR(crtc->pipe),
+                          SKL_BOTTOM_COLOR_GAMMA_ENABLE |
+                          SKL_BOTTOM_COLOR_CSC_ENABLE);
 }
 
 static void intel_fdi_normal_train(struct intel_crtc *crtc)
@@ -4120,7 +4166,7 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc,
        temp = I915_READ(reg);
        temp &= ~FDI_LINK_TRAIN_NONE;
        temp |= FDI_LINK_TRAIN_PATTERN_2;
-       if (IS_GEN6(dev_priv)) {
+       if (IS_GEN(dev_priv, 6)) {
                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
                /* SNB-B */
                temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
@@ -4593,7 +4639,7 @@ static void ironlake_pch_transcoder_set_timings(const struct intel_crtc_state *c
 
 static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable)
 {
-       uint32_t temp;
+       u32 temp;
 
        temp = I915_READ(SOUTH_CHICKEN1);
        if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable)
@@ -4919,10 +4965,10 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
        /* range checks */
        if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H ||
            dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
-           (IS_GEN11(dev_priv) &&
+           (IS_GEN(dev_priv, 11) &&
             (src_w > ICL_MAX_SRC_W || src_h > ICL_MAX_SRC_H ||
              dst_w > ICL_MAX_DST_W || dst_h > ICL_MAX_DST_H)) ||
-           (!IS_GEN11(dev_priv) &&
+           (!IS_GEN(dev_priv, 11) &&
             (src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
              dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H))) {
                DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u "
@@ -5213,7 +5259,7 @@ intel_post_enable_primary(struct drm_crtc *crtc,
         * FIXME: Need to fix the logic to work when we turn off all planes
         * but leave the pipe running.
         */
-       if (IS_GEN2(dev_priv))
+       if (IS_GEN(dev_priv, 2))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
        /* Underruns don't always raise interrupts, so check manually. */
@@ -5234,7 +5280,7 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
         * Gen2 reports pipe underruns whenever all planes are disabled.
         * So disable underrun reporting before all the planes get disabled.
         */
-       if (IS_GEN2(dev_priv))
+       if (IS_GEN(dev_priv, 2))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
 
        hsw_disable_ips(to_intel_crtc_state(crtc->state));
@@ -5292,7 +5338,7 @@ static bool needs_nv12_wa(struct drm_i915_private *dev_priv,
                return false;
 
        /* WA Display #0827: Gen9:all */
-       if (IS_GEN9(dev_priv) && !IS_GEMINILAKE(dev_priv))
+       if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv))
                return true;
 
        return false;
@@ -5365,7 +5411,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
                 * Gen2 reports pipe underruns whenever all planes are disabled.
                 * So disable underrun reporting before all the planes get disabled.
                 */
-               if (IS_GEN2(dev_priv) && old_primary_state->visible &&
+               if (IS_GEN(dev_priv, 2) && old_primary_state->visible &&
                    (modeset || !new_primary_state->base.visible))
                        intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
        }
@@ -5578,6 +5624,26 @@ static void intel_encoders_post_pll_disable(struct drm_crtc *crtc,
        }
 }
 
+static void intel_encoders_update_pipe(struct drm_crtc *crtc,
+                                      struct intel_crtc_state *crtc_state,
+                                      struct drm_atomic_state *old_state)
+{
+       struct drm_connector_state *conn_state;
+       struct drm_connector *conn;
+       int i;
+
+       for_each_new_connector_in_state(old_state, conn, conn_state, i) {
+               struct intel_encoder *encoder =
+                       to_intel_encoder(conn_state->best_encoder);
+
+               if (conn_state->crtc != crtc)
+                       continue;
+
+               if (encoder->update_pipe)
+                       encoder->update_pipe(encoder, crtc_state, conn_state);
+       }
+}
+
 static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
                                 struct drm_atomic_state *old_state)
 {
@@ -5641,7 +5707,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
         * On ILK+ LUT must be loaded before the pipe is running but with
         * clocks enabled
         */
-       intel_color_load_luts(&pipe_config->base);
+       intel_color_load_luts(pipe_config);
 
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state, pipe_config);
@@ -5651,7 +5717,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
                ironlake_pch_enable(old_intel_state, pipe_config);
 
        assert_vblank_disabled(crtc);
-       drm_crtc_vblank_on(crtc);
+       intel_crtc_vblank_on(pipe_config);
 
        intel_encoders_enable(crtc, pipe_config, old_state);
 
@@ -5696,7 +5762,7 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum pipe pipe = crtc->pipe;
-       uint32_t val;
+       u32 val;
 
        val = MBUS_DBOX_A_CREDIT(2);
        val |= MBUS_DBOX_BW_CREDIT(1);
@@ -5752,7 +5818,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 
        haswell_set_pipemisc(pipe_config);
 
-       intel_color_set_csc(&pipe_config->base);
+       intel_color_set_csc(pipe_config);
 
        intel_crtc->active = true;
 
@@ -5771,7 +5837,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
         * On ILK+ LUT must be loaded before the pipe is running but with
         * clocks enabled
         */
-       intel_color_load_luts(&pipe_config->base);
+       intel_color_load_luts(pipe_config);
 
        /*
         * Display WA #1153: enable hardware to bypass the alpha math
@@ -5805,7 +5871,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
                intel_ddi_set_vc_payload_alloc(pipe_config, true);
 
        assert_vblank_disabled(crtc);
-       drm_crtc_vblank_on(crtc);
+       intel_crtc_vblank_on(pipe_config);
 
        intel_encoders_enable(crtc, pipe_config, old_state);
 
@@ -6087,7 +6153,7 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
        enum intel_display_power_domain domain;
 
        for_each_power_domain(domain, domains)
-               intel_display_power_put(dev_priv, domain);
+               intel_display_power_put_unchecked(dev_priv, domain);
 }
 
 static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
@@ -6117,7 +6183,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 
        i9xx_set_pipeconf(pipe_config);
 
-       intel_color_set_csc(&pipe_config->base);
+       intel_color_set_csc(pipe_config);
 
        intel_crtc->active = true;
 
@@ -6137,14 +6203,14 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 
        i9xx_pfit_enable(pipe_config);
 
-       intel_color_load_luts(&pipe_config->base);
+       intel_color_load_luts(pipe_config);
 
        dev_priv->display.initial_watermarks(old_intel_state,
                                             pipe_config);
        intel_enable_pipe(pipe_config);
 
        assert_vblank_disabled(crtc);
-       drm_crtc_vblank_on(crtc);
+       intel_crtc_vblank_on(pipe_config);
 
        intel_encoders_enable(crtc, pipe_config, old_state);
 }
@@ -6184,7 +6250,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
 
        intel_crtc->active = true;
 
-       if (!IS_GEN2(dev_priv))
+       if (!IS_GEN(dev_priv, 2))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
        intel_encoders_pre_enable(crtc, pipe_config, old_state);
@@ -6193,7 +6259,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
 
        i9xx_pfit_enable(pipe_config);
 
-       intel_color_load_luts(&pipe_config->base);
+       intel_color_load_luts(pipe_config);
 
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state,
@@ -6203,7 +6269,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
        intel_enable_pipe(pipe_config);
 
        assert_vblank_disabled(crtc);
-       drm_crtc_vblank_on(crtc);
+       intel_crtc_vblank_on(pipe_config);
 
        intel_encoders_enable(crtc, pipe_config, old_state);
 }
@@ -6236,7 +6302,7 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
         * On gen2 planes are double buffered but the pipe isn't, so we must
         * wait for planes to fully turn off before disabling the pipe.
         */
-       if (IS_GEN2(dev_priv))
+       if (IS_GEN(dev_priv, 2))
                intel_wait_for_vblank(dev_priv, pipe);
 
        intel_encoders_disable(crtc, old_crtc_state, old_state);
@@ -6261,7 +6327,7 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
 
        intel_encoders_post_pll_disable(crtc, old_crtc_state, old_state);
 
-       if (!IS_GEN2(dev_priv))
+       if (!IS_GEN(dev_priv, 2))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
 
        if (!dev_priv->display.initial_watermarks)
@@ -6334,7 +6400,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
 
        domains = intel_crtc->enabled_power_domains;
        for_each_power_domain(domain, domains)
-               intel_display_power_put(dev_priv, domain);
+               intel_display_power_put_unchecked(dev_priv, domain);
        intel_crtc->enabled_power_domains = 0;
 
        dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe);
@@ -6600,9 +6666,9 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
                (crtc->pipe == PIPE_A || IS_I915G(dev_priv));
 }
 
-static uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
+static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 {
-       uint32_t pixel_rate;
+       u32 pixel_rate;
 
        pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
 
@@ -6612,8 +6678,8 @@ static uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
         */
 
        if (pipe_config->pch_pfit.enabled) {
-               uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
-               uint32_t pfit_size = pipe_config->pch_pfit.size;
+               u64 pipe_w, pipe_h, pfit_w, pfit_h;
+               u32 pfit_size = pipe_config->pch_pfit.size;
 
                pipe_w = pipe_config->pipe_src_w;
                pipe_h = pipe_config->pipe_src_h;
@@ -6628,7 +6694,7 @@ static uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
                if (WARN_ON(!pfit_w || !pfit_h))
                        return pixel_rate;
 
-               pixel_rate = div_u64((uint64_t) pixel_rate * pipe_w * pipe_h,
+               pixel_rate = div_u64((u64)pixel_rate * pipe_w * pipe_h,
                                     pfit_w * pfit_h);
        }
 
@@ -6724,7 +6790,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 }
 
 static void
-intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
+intel_reduce_m_n_ratio(u32 *num, u32 *den)
 {
        while (*num > DATA_LINK_M_N_MASK ||
               *den > DATA_LINK_M_N_MASK) {
@@ -6734,7 +6800,7 @@ intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
 }
 
 static void compute_m_n(unsigned int m, unsigned int n,
-                       uint32_t *ret_m, uint32_t *ret_n,
+                       u32 *ret_m, u32 *ret_n,
                        bool constant_n)
 {
        /*
@@ -6749,7 +6815,7 @@ static void compute_m_n(unsigned int m, unsigned int n,
        else
                *ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
 
-       *ret_m = div_u64((uint64_t) m * *ret_n, n);
+       *ret_m = div_u64((u64)m * *ret_n, n);
        intel_reduce_m_n_ratio(ret_m, ret_n);
 }
 
@@ -6779,12 +6845,12 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
                && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
 }
 
-static uint32_t pnv_dpll_compute_fp(struct dpll *dpll)
+static u32 pnv_dpll_compute_fp(struct dpll *dpll)
 {
        return (1 << dpll->n) << 16 | dpll->m2;
 }
 
-static uint32_t i9xx_dpll_compute_fp(struct dpll *dpll)
+static u32 i9xx_dpll_compute_fp(struct dpll *dpll)
 {
        return dpll->n << 16 | dpll->m1 << 8 | dpll->m2;
 }
@@ -6868,7 +6934,7 @@ static bool transcoder_has_m2_n2(struct drm_i915_private *dev_priv,
         * Strictly speaking some registers are available before
         * gen7, but we only support DRRS on gen7+
         */
-       return IS_GEN7(dev_priv) || IS_CHERRYVIEW(dev_priv);
+       return IS_GEN(dev_priv, 7) || IS_CHERRYVIEW(dev_priv);
 }
 
 static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
@@ -7340,7 +7406,7 @@ static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
        enum pipe pipe = crtc->pipe;
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
        const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
-       uint32_t crtc_vtotal, crtc_vblank_end;
+       u32 crtc_vtotal, crtc_vblank_end;
        int vsyncshift = 0;
 
        /* We need to be careful not to changed the adjusted mode, for otherwise
@@ -7415,7 +7481,7 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
-       uint32_t tmp;
+       u32 tmp;
 
        tmp = I915_READ(HTOTAL(cpu_transcoder));
        pipe_config->base.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
@@ -7486,7 +7552,7 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       uint32_t pipeconf;
+       u32 pipeconf;
 
        pipeconf = 0;
 
@@ -7731,7 +7797,7 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc,
                                 struct intel_crtc_state *pipe_config)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       uint32_t tmp;
+       u32 tmp;
 
        if (INTEL_GEN(dev_priv) <= 3 &&
            (IS_I830(dev_priv) || !IS_MOBILE(dev_priv)))
@@ -7946,11 +8012,13 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum intel_display_power_domain power_domain;
-       uint32_t tmp;
+       intel_wakeref_t wakeref;
+       u32 tmp;
        bool ret;
 
        power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
-       if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+       wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+       if (!wakeref)
                return false;
 
        pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
@@ -8051,7 +8119,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
        ret = true;
 
 out:
-       intel_display_power_put(dev_priv, power_domain);
+       intel_display_power_put(dev_priv, power_domain, wakeref);
 
        return ret;
 }
@@ -8225,7 +8293,7 @@ static void ironlake_init_pch_refclk(struct drm_i915_private *dev_priv)
 
 static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv)
 {
-       uint32_t tmp;
+       u32 tmp;
 
        tmp = I915_READ(SOUTH_CHICKEN2);
        tmp |= FDI_MPHY_IOSFSB_RESET_CTL;
@@ -8247,7 +8315,7 @@ static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv)
 /* WaMPhyProgramming:hsw */
 static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv)
 {
-       uint32_t tmp;
+       u32 tmp;
 
        tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY);
        tmp &= ~(0xFF << 24);
@@ -8328,7 +8396,7 @@ static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv)
 static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv,
                                 bool with_spread, bool with_fdi)
 {
-       uint32_t reg, tmp;
+       u32 reg, tmp;
 
        if (WARN(with_fdi && !with_spread, "FDI requires downspread\n"))
                with_spread = true;
@@ -8367,7 +8435,7 @@ static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv,
 /* Sequence to disable CLKOUT_DP */
 static void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv)
 {
-       uint32_t reg, tmp;
+       u32 reg, tmp;
 
        mutex_lock(&dev_priv->sb_lock);
 
@@ -8392,7 +8460,7 @@ static void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv)
 
 #define BEND_IDX(steps) ((50 + (steps)) / 5)
 
-static const uint16_t sscdivintphase[] = {
+static const u16 sscdivintphase[] = {
        [BEND_IDX( 50)] = 0x3B23,
        [BEND_IDX( 45)] = 0x3B23,
        [BEND_IDX( 40)] = 0x3C23,
@@ -8424,7 +8492,7 @@ static const uint16_t sscdivintphase[] = {
  */
 static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
 {
-       uint32_t tmp;
+       u32 tmp;
        int idx = BEND_IDX(steps);
 
        if (WARN_ON(steps % 5 != 0))
@@ -8490,7 +8558,7 @@ static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum pipe pipe = crtc->pipe;
-       uint32_t val;
+       u32 val;
 
        val = 0;
 
@@ -8837,7 +8905,7 @@ static void skylake_get_pfit_config(struct intel_crtc *crtc,
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc_scaler_state *scaler_state = &pipe_config->scaler_state;
-       uint32_t ps_ctrl = 0;
+       u32 ps_ctrl = 0;
        int id = -1;
        int i;
 
@@ -8849,6 +8917,7 @@ static void skylake_get_pfit_config(struct intel_crtc *crtc,
                        pipe_config->pch_pfit.enabled = true;
                        pipe_config->pch_pfit.pos = I915_READ(SKL_PS_WIN_POS(crtc->pipe, i));
                        pipe_config->pch_pfit.size = I915_READ(SKL_PS_WIN_SZ(crtc->pipe, i));
+                       scaler_state->scalers[i].in_use = true;
                        break;
                }
        }
@@ -8993,7 +9062,7 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc,
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       uint32_t tmp;
+       u32 tmp;
 
        tmp = I915_READ(PF_CTL(crtc->pipe));
 
@@ -9005,7 +9074,7 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc,
                /* We currently do not free assignements of panel fitters on
                 * ivb/hsw (since we don't use the higher upscaling modes which
                 * differentiates them) so just WARN about this case for now. */
-               if (IS_GEN7(dev_priv)) {
+               if (IS_GEN(dev_priv, 7)) {
                        WARN_ON((tmp & PF_PIPE_SEL_MASK_IVB) !=
                                PF_PIPE_SEL_IVB(crtc->pipe));
                }
@@ -9018,11 +9087,13 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        enum intel_display_power_domain power_domain;
-       uint32_t tmp;
+       intel_wakeref_t wakeref;
+       u32 tmp;
        bool ret;
 
        power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
-       if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+       wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+       if (!wakeref)
                return false;
 
        pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
@@ -9105,7 +9176,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
        ret = true;
 
 out:
-       intel_display_power_put(dev_priv, power_domain);
+       intel_display_power_put(dev_priv, power_domain, wakeref);
 
        return ret;
 }
@@ -9145,7 +9216,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
        I915_STATE_WARN(intel_irqs_enabled(dev_priv), "IRQs enabled\n");
 }
 
-static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
+static u32 hsw_read_dcomp(struct drm_i915_private *dev_priv)
 {
        if (IS_HASWELL(dev_priv))
                return I915_READ(D_COMP_HSW);
@@ -9153,7 +9224,7 @@ static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
                return I915_READ(D_COMP_BDW);
 }
 
-static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
+static void hsw_write_dcomp(struct drm_i915_private *dev_priv, u32 val)
 {
        if (IS_HASWELL(dev_priv)) {
                mutex_lock(&dev_priv->pcu_lock);
@@ -9178,7 +9249,7 @@ static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
 static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
                              bool switch_to_fclk, bool allow_power_down)
 {
-       uint32_t val;
+       u32 val;
 
        assert_can_disable_lcpll(dev_priv);
 
@@ -9225,7 +9296,7 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
  */
 static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
 {
-       uint32_t val;
+       u32 val;
 
        val = I915_READ(LCPLL_CTL);
 
@@ -9300,7 +9371,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
  */
 void hsw_enable_pc8(struct drm_i915_private *dev_priv)
 {
-       uint32_t val;
+       u32 val;
 
        DRM_DEBUG_KMS("Enabling package C8+\n");
 
@@ -9316,7 +9387,7 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv)
 
 void hsw_disable_pc8(struct drm_i915_private *dev_priv)
 {
-       uint32_t val;
+       u32 val;
 
        DRM_DEBUG_KMS("Disabling package C8+\n");
 
@@ -9384,7 +9455,7 @@ static void icelake_get_ddi_pll(struct drm_i915_private *dev_priv,
                if (WARN_ON(!intel_dpll_is_combophy(id)))
                        return;
        } else if (intel_port_is_tc(dev_priv, port)) {
-               id = icl_port_to_mg_pll_id(port);
+               id = icl_tc_port_to_pll_id(intel_port_to_tc(dev_priv, port));
        } else {
                WARN(1, "Invalid port %x\n", port);
                return;
@@ -9438,7 +9509,7 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
                                struct intel_crtc_state *pipe_config)
 {
        enum intel_dpll_id id;
-       uint32_t ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
+       u32 ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
 
        switch (ddi_pll_sel) {
        case PORT_CLK_SEL_WRPLL1:
@@ -9495,7 +9566,9 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
         * XXX: Do intel_display_power_get_if_enabled before reading this (for
         * consistency and less surprising code; it's in always on power).
         */
-       for_each_set_bit(panel_transcoder, &panel_transcoder_mask, 32) {
+       for_each_set_bit(panel_transcoder,
+                        &panel_transcoder_mask,
+                        ARRAY_SIZE(INTEL_INFO(dev_priv)->trans_offsets)) {
                enum pipe trans_pipe;
 
                tmp = I915_READ(TRANS_DDI_FUNC_CTL(panel_transcoder));
@@ -9541,6 +9614,8 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
        power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
+
+       WARN_ON(*power_domain_mask & BIT_ULL(power_domain));
        *power_domain_mask |= BIT_ULL(power_domain);
 
        tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
@@ -9568,6 +9643,8 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
                power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
                if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                        continue;
+
+               WARN_ON(*power_domain_mask & BIT_ULL(power_domain));
                *power_domain_mask |= BIT_ULL(power_domain);
 
                /*
@@ -9602,7 +9679,7 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct intel_shared_dpll *pll;
        enum port port;
-       uint32_t tmp;
+       u32 tmp;
 
        tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
 
@@ -9684,7 +9761,9 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 
        power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
        if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
+               WARN_ON(power_domain_mask & BIT_ULL(power_domain));
                power_domain_mask |= BIT_ULL(power_domain);
+
                if (INTEL_GEN(dev_priv) >= 9)
                        skylake_get_pfit_config(crtc, pipe_config);
                else
@@ -9714,7 +9793,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 
 out:
        for_each_power_domain(power_domain, power_domain_mask)
-               intel_display_power_put(dev_priv, power_domain);
+               intel_display_power_put_unchecked(dev_priv, power_domain);
 
        return active;
 }
@@ -9964,17 +10043,19 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane,
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
+       intel_wakeref_t wakeref;
        bool ret;
 
        power_domain = POWER_DOMAIN_PIPE(PIPE_A);
-       if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+       wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+       if (!wakeref)
                return false;
 
        ret = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
 
        *pipe = PIPE_A;
 
-       intel_display_power_put(dev_priv, power_domain);
+       intel_display_power_put(dev_priv, power_domain, wakeref);
 
        return ret;
 }
@@ -9995,7 +10076,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
        u32 cntl = 0;
 
-       if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
+       if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
                cntl |= MCURSOR_TRICKLE_FEED_DISABLE;
 
        if (INTEL_GEN(dev_priv) <= 10) {
@@ -10197,6 +10278,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
+       intel_wakeref_t wakeref;
        bool ret;
        u32 val;
 
@@ -10206,7 +10288,8 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
         * display power wells.
         */
        power_domain = POWER_DOMAIN_PIPE(plane->pipe);
-       if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+       wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+       if (!wakeref)
                return false;
 
        val = I915_READ(CURCNTR(plane->pipe));
@@ -10219,7 +10302,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
                *pipe = (val & MCURSOR_PIPE_SELECT_MASK) >>
                        MCURSOR_PIPE_SELECT_SHIFT;
 
-       intel_display_power_put(dev_priv, power_domain);
+       intel_display_power_put(dev_priv, power_domain, wakeref);
 
        return ret;
 }
@@ -10468,7 +10551,7 @@ static int i9xx_pll_refclk(struct drm_device *dev,
                return dev_priv->vbt.lvds_ssc_freq;
        else if (HAS_PCH_SPLIT(dev_priv))
                return 120000;
-       else if (!IS_GEN2(dev_priv))
+       else if (!IS_GEN(dev_priv, 2))
                return 96000;
        else
                return 48000;
@@ -10501,7 +10584,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
                clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
        }
 
-       if (!IS_GEN2(dev_priv)) {
+       if (!IS_GEN(dev_priv, 2)) {
                if (IS_PINEVIEW(dev_priv))
                        clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
                                DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
@@ -10653,20 +10736,17 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
 
 /**
  * intel_wm_need_update - Check whether watermarks need updating
- * @plane: drm plane
- * @state: new plane state
+ * @cur: current plane state
+ * @new: new plane state
  *
  * Check current plane state versus the new one to determine whether
  * watermarks need to be recalculated.
  *
  * Returns true or false.
  */
-static bool intel_wm_need_update(struct drm_plane *plane,
-                                struct drm_plane_state *state)
+static bool intel_wm_need_update(struct intel_plane_state *cur,
+                                struct intel_plane_state *new)
 {
-       struct intel_plane_state *new = to_intel_plane_state(state);
-       struct intel_plane_state *cur = to_intel_plane_state(plane->state);
-
        /* Update watermarks on tiling or size changes. */
        if (new->base.visible != cur->base.visible)
                return true;
@@ -10775,7 +10855,8 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
                /* must disable cxsr around plane enable/disable */
                if (plane->id != PLANE_CURSOR)
                        pipe_config->disable_cxsr = true;
-       } else if (intel_wm_need_update(&plane->base, plane_state)) {
+       } else if (intel_wm_need_update(to_intel_plane_state(plane->base.state),
+                                       to_intel_plane_state(plane_state))) {
                if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv)) {
                        /* FIXME bollocks */
                        pipe_config->update_wm_pre = true;
@@ -10815,9 +10896,12 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
         * Despite the w/a only being listed for IVB we assume that
         * the ILK/SNB note has similar ramifications, hence we apply
         * the w/a on all three platforms.
+        *
+        * With experimental results seems this is needed also for primary
+        * plane, not only sprite plane.
         */
-       if (plane->id == PLANE_SPRITE0 &&
-           (IS_GEN5(dev_priv) || IS_GEN6(dev_priv) ||
+       if (plane->id != PLANE_CURSOR &&
+           (IS_GEN_RANGE(dev_priv, 5, 6) ||
             IS_IVYBRIDGE(dev_priv)) &&
            (turn_on || (!needs_scaling(old_plane_state) &&
                         needs_scaling(to_intel_plane_state(plane_state)))))
@@ -10954,8 +11038,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 static int intel_crtc_atomic_check(struct drm_crtc *crtc,
                                   struct drm_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(crtc->dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_crtc_state *pipe_config =
                to_intel_crtc_state(crtc_state);
@@ -10975,7 +11058,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
        }
 
        if (crtc_state->color_mgmt_changed) {
-               ret = intel_color_check(crtc, crtc_state);
+               ret = intel_color_check(pipe_config);
                if (ret)
                        return ret;
 
@@ -11004,9 +11087,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
                 * old state and the new state.  We can program these
                 * immediately.
                 */
-               ret = dev_priv->display.compute_intermediate_wm(dev,
-                                                               intel_crtc,
-                                                               pipe_config);
+               ret = dev_priv->display.compute_intermediate_wm(pipe_config);
                if (ret) {
                        DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n");
                        return ret;
@@ -11014,7 +11095,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
        }
 
        if (INTEL_GEN(dev_priv) >= 9) {
-               if (mode_changed)
+               if (mode_changed || pipe_config->update_pipe)
                        ret = skl_update_scaler_crtc(pipe_config);
 
                if (!ret)
@@ -11517,10 +11598,13 @@ encoder_retry:
                        continue;
 
                encoder = to_intel_encoder(connector_state->best_encoder);
-
-               if (!(encoder->compute_config(encoder, pipe_config, connector_state))) {
-                       DRM_DEBUG_KMS("Encoder config failure\n");
-                       return -EINVAL;
+               ret = encoder->compute_config(encoder, pipe_config,
+                                             connector_state);
+               if (ret < 0) {
+                       if (ret != -EDEADLK)
+                               DRM_DEBUG_KMS("Encoder config failure: %d\n",
+                                             ret);
+                       return ret;
                }
        }
 
@@ -11645,6 +11729,23 @@ pipe_config_err(bool adjust, const char *name, const char *format, ...)
        va_end(args);
 }
 
+static bool fastboot_enabled(struct drm_i915_private *dev_priv)
+{
+       if (i915_modparams.fastboot != -1)
+               return i915_modparams.fastboot;
+
+       /* Enable fastboot by default on Skylake and newer */
+       if (INTEL_GEN(dev_priv) >= 9)
+               return true;
+
+       /* Enable fastboot by default on VLV and CHV */
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               return true;
+
+       /* Disabled by default on all others */
+       return false;
+}
+
 static bool
 intel_pipe_config_compare(struct drm_i915_private *dev_priv,
                          struct intel_crtc_state *current_config,
@@ -11656,6 +11757,11 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
                (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
                !(pipe_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED);
 
+       if (fixup_inherited && !fastboot_enabled(dev_priv)) {
+               DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
+               ret = false;
+       }
+
 #define PIPE_CONF_CHECK_X(name) do { \
        if (current_config->name != pipe_config->name) { \
                pipe_config_err(adjust, __stringify(name), \
@@ -11964,7 +12070,7 @@ static void verify_wm_state(struct drm_crtc *crtc,
        if (INTEL_GEN(dev_priv) < 9 || !new_state->active)
                return;
 
-       skl_pipe_wm_get_hw_state(crtc, &hw_wm);
+       skl_pipe_wm_get_hw_state(intel_crtc, &hw_wm);
        sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal;
 
        skl_pipe_ddb_get_hw_state(intel_crtc, hw_ddb_y, hw_ddb_uv);
@@ -12378,7 +12484,7 @@ static void update_scanline_offset(const struct intel_crtc_state *crtc_state)
         * However if queried just before the start of vblank we'll get an
         * answer that's slightly in the future.
         */
-       if (IS_GEN2(dev_priv)) {
+       if (IS_GEN(dev_priv, 2)) {
                const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
                int vtotal;
 
@@ -12619,9 +12725,9 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
  * phase.  The code here should be run after the per-crtc and per-plane 'check'
  * handlers to ensure that all derived state has been updated.
  */
-static int calc_watermark_data(struct drm_atomic_state *state)
+static int calc_watermark_data(struct intel_atomic_state *state)
 {
-       struct drm_device *dev = state->dev;
+       struct drm_device *dev = state->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
 
        /* Is there platform-specific watermark information to calculate? */
@@ -12679,8 +12785,7 @@ static int intel_atomic_check(struct drm_device *dev,
                        return ret;
                }
 
-               if (i915_modparams.fastboot &&
-                   intel_pipe_config_compare(dev_priv,
+               if (intel_pipe_config_compare(dev_priv,
                                        to_intel_crtc_state(old_crtc_state),
                                        pipe_config, true)) {
                        crtc_state->mode_changed = false;
@@ -12695,6 +12800,10 @@ static int intel_atomic_check(struct drm_device *dev,
                                       "[modeset]" : "[fastset]");
        }
 
+       ret = drm_dp_mst_atomic_check(state);
+       if (ret)
+               return ret;
+
        if (any_ms) {
                ret = intel_modeset_checks(state);
 
@@ -12713,7 +12822,7 @@ static int intel_atomic_check(struct drm_device *dev,
                return ret;
 
        intel_fbc_choose_crtc(dev_priv, intel_state);
-       return calc_watermark_data(state);
+       return calc_watermark_data(intel_state);
 }
 
 static int intel_atomic_prepare_commit(struct drm_device *dev,
@@ -12725,8 +12834,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
 u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
 {
        struct drm_device *dev = crtc->base.dev;
+       struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(&crtc->base)];
 
-       if (!dev->max_vblank_count)
+       if (!vblank->max_vblank_count)
                return (u32)drm_crtc_accurate_vblank_count(&crtc->base);
 
        return dev->driver->get_vblank_counter(dev, crtc->pipe);
@@ -12755,9 +12865,14 @@ static void intel_update_crtc(struct drm_crtc *crtc,
        } else {
                intel_pre_plane_update(to_intel_crtc_state(old_crtc_state),
                                       pipe_config);
+
+               if (pipe_config->update_pipe)
+                       intel_encoders_update_pipe(crtc, pipe_config, state);
        }
 
-       if (new_plane_state)
+       if (pipe_config->update_pipe && !pipe_config->enable_fbc)
+               intel_fbc_disable(intel_crtc);
+       else if (new_plane_state)
                intel_fbc_enable(intel_crtc, pipe_config, new_plane_state);
 
        intel_begin_crtc_commit(crtc, old_crtc_state);
@@ -12930,6 +13045,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
        struct drm_crtc *crtc;
        struct intel_crtc *intel_crtc;
        u64 put_domains[I915_MAX_PIPES] = {};
+       intel_wakeref_t wakeref = 0;
        int i;
 
        intel_atomic_commit_fence_wait(intel_state);
@@ -12937,7 +13053,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
        drm_atomic_helper_wait_for_dependencies(state);
 
        if (intel_state->modeset)
-               intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
+               wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
 
        for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
                old_intel_crtc_state = to_intel_crtc_state(old_crtc_state);
@@ -13074,7 +13190,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
                 * the culprit.
                 */
                intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
-               intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
+               intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref);
        }
 
        /*
@@ -13552,8 +13668,8 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
        if (!modeset &&
            (intel_cstate->base.color_mgmt_changed ||
             intel_cstate->update_pipe)) {
-               intel_color_set_csc(&intel_cstate->base);
-               intel_color_load_luts(&intel_cstate->base);
+               intel_color_set_csc(intel_cstate);
+               intel_color_load_luts(intel_cstate);
        }
 
        /* Perform vblank evasion around commit operation */
@@ -13578,7 +13694,7 @@ void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
-       if (!IS_GEN2(dev_priv))
+       if (!IS_GEN(dev_priv, 2))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
 
        if (crtc_state->has_pch_encoder) {
@@ -13702,8 +13818,8 @@ intel_legacy_cursor_update(struct drm_plane *plane,
                           struct drm_framebuffer *fb,
                           int crtc_x, int crtc_y,
                           unsigned int crtc_w, unsigned int crtc_h,
-                          uint32_t src_x, uint32_t src_y,
-                          uint32_t src_w, uint32_t src_h,
+                          u32 src_x, u32 src_y,
+                          u32 src_w, u32 src_h,
                           struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->dev);
@@ -14040,7 +14156,7 @@ static void intel_crtc_init_scalers(struct intel_crtc *crtc,
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        int i;
 
-       crtc->num_scalers = dev_priv->info.num_scalers[crtc->pipe];
+       crtc->num_scalers = RUNTIME_INFO(dev_priv)->num_scalers[crtc->pipe];
        if (!crtc->num_scalers)
                return;
 
@@ -14126,7 +14242,7 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
 
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
 
-       intel_color_init(&intel_crtc->base);
+       intel_color_init(intel_crtc);
 
        WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
 
@@ -14177,7 +14293,7 @@ static int intel_encoder_clones(struct intel_encoder *encoder)
        return index_mask;
 }
 
-static bool has_edp_a(struct drm_i915_private *dev_priv)
+static bool ilk_has_edp_a(struct drm_i915_private *dev_priv)
 {
        if (!IS_MOBILE(dev_priv))
                return false;
@@ -14185,13 +14301,13 @@ static bool has_edp_a(struct drm_i915_private *dev_priv)
        if ((I915_READ(DP_A) & DP_DETECTED) == 0)
                return false;
 
-       if (IS_GEN5(dev_priv) && (I915_READ(FUSE_STRAP) & ILK_eDP_A_DISABLE))
+       if (IS_GEN(dev_priv, 5) && (I915_READ(FUSE_STRAP) & ILK_eDP_A_DISABLE))
                return false;
 
        return true;
 }
 
-static bool intel_crt_present(struct drm_i915_private *dev_priv)
+static bool intel_ddi_crt_present(struct drm_i915_private *dev_priv)
 {
        if (INTEL_GEN(dev_priv) >= 9)
                return false;
@@ -14199,15 +14315,12 @@ static bool intel_crt_present(struct drm_i915_private *dev_priv)
        if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
                return false;
 
-       if (IS_CHERRYVIEW(dev_priv))
-               return false;
-
        if (HAS_PCH_LPT_H(dev_priv) &&
            I915_READ(SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED)
                return false;
 
        /* DDI E can't be used if DDI A requires 4 lanes */
-       if (HAS_DDI(dev_priv) && I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
+       if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
                return false;
 
        if (!dev_priv->vbt.int_crt_support)
@@ -14262,23 +14375,21 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
        if (!HAS_DISPLAY(dev_priv))
                return;
 
-       /*
-        * intel_edp_init_connector() depends on this completing first, to
-        * prevent the registeration of both eDP and LVDS and the incorrect
-        * sharing of the PPS.
-        */
-       intel_lvds_init(dev_priv);
-
-       if (intel_crt_present(dev_priv))
-               intel_crt_init(dev_priv);
-
        if (IS_ICELAKE(dev_priv)) {
                intel_ddi_init(dev_priv, PORT_A);
                intel_ddi_init(dev_priv, PORT_B);
                intel_ddi_init(dev_priv, PORT_C);
                intel_ddi_init(dev_priv, PORT_D);
                intel_ddi_init(dev_priv, PORT_E);
-               intel_ddi_init(dev_priv, PORT_F);
+               /*
+                * On some ICL SKUs port F is not present. No strap bits for
+                * this, so rely on VBT.
+                * Work around broken VBTs on SKUs known to have no port F.
+                */
+               if (IS_ICL_WITH_PORT_F(dev_priv) &&
+                   intel_bios_is_port_present(dev_priv, PORT_F))
+                       intel_ddi_init(dev_priv, PORT_F);
+
                icl_dsi_init(dev_priv);
        } else if (IS_GEN9_LP(dev_priv)) {
                /*
@@ -14294,6 +14405,9 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
        } else if (HAS_DDI(dev_priv)) {
                int found;
 
+               if (intel_ddi_crt_present(dev_priv))
+                       intel_crt_init(dev_priv);
+
                /*
                 * Haswell uses DDI functions to detect digital outputs.
                 * On SKL pre-D0 the strap isn't connected, so we assume
@@ -14320,16 +14434,23 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
                 * On SKL we don't have a way to detect DDI-E so we rely on VBT.
                 */
                if (IS_GEN9_BC(dev_priv) &&
-                   (dev_priv->vbt.ddi_port_info[PORT_E].supports_dp ||
-                    dev_priv->vbt.ddi_port_info[PORT_E].supports_dvi ||
-                    dev_priv->vbt.ddi_port_info[PORT_E].supports_hdmi))
+                   intel_bios_is_port_present(dev_priv, PORT_E))
                        intel_ddi_init(dev_priv, PORT_E);
 
        } else if (HAS_PCH_SPLIT(dev_priv)) {
                int found;
+
+               /*
+                * intel_edp_init_connector() depends on this completing first,
+                * to prevent the registration of both eDP and LVDS and the
+                * incorrect sharing of the PPS.
+                */
+               intel_lvds_init(dev_priv);
+               intel_crt_init(dev_priv);
+
                dpd_is_edp = intel_dp_is_port_edp(dev_priv, PORT_D);
 
-               if (has_edp_a(dev_priv))
+               if (ilk_has_edp_a(dev_priv))
                        intel_dp_init(dev_priv, DP_A, PORT_A);
 
                if (I915_READ(PCH_HDMIB) & SDVO_DETECTED) {
@@ -14355,6 +14476,9 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
        } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                bool has_edp, has_port;
 
+               if (IS_VALLEYVIEW(dev_priv) && dev_priv->vbt.int_crt_support)
+                       intel_crt_init(dev_priv);
+
                /*
                 * The DP_DETECTED bit is the latched state of the DDC
                 * SDA pin at boot. However since eDP doesn't require DDC
@@ -14397,9 +14521,17 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
                }
 
                vlv_dsi_init(dev_priv);
-       } else if (!IS_GEN2(dev_priv) && !IS_PINEVIEW(dev_priv)) {
+       } else if (IS_PINEVIEW(dev_priv)) {
+               intel_lvds_init(dev_priv);
+               intel_crt_init(dev_priv);
+       } else if (IS_GEN_RANGE(dev_priv, 3, 4)) {
                bool found = false;
 
+               if (IS_MOBILE(dev_priv))
+                       intel_lvds_init(dev_priv);
+
+               intel_crt_init(dev_priv);
+
                if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
                        DRM_DEBUG_KMS("probing SDVOB\n");
                        found = intel_sdvo_init(dev_priv, GEN3_SDVOB, PORT_B);
@@ -14431,11 +14563,16 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
 
                if (IS_G4X(dev_priv) && (I915_READ(DP_D) & DP_DETECTED))
                        intel_dp_init(dev_priv, DP_D, PORT_D);
-       } else if (IS_GEN2(dev_priv))
-               intel_dvo_init(dev_priv);
 
-       if (SUPPORTS_TV(dev_priv))
-               intel_tv_init(dev_priv);
+               if (SUPPORTS_TV(dev_priv))
+                       intel_tv_init(dev_priv);
+       } else if (IS_GEN(dev_priv, 2)) {
+               if (IS_I85X(dev_priv))
+                       intel_lvds_init(dev_priv);
+
+               intel_crt_init(dev_priv);
+               intel_dvo_init(dev_priv);
+       }
 
        intel_psr_init(dev_priv);
 
@@ -14602,14 +14739,6 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
 
        drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
 
-       if (fb->format->format == DRM_FORMAT_NV12 &&
-           (fb->width < SKL_MIN_YUV_420_SRC_W ||
-            fb->height < SKL_MIN_YUV_420_SRC_H ||
-            (fb->width % 4) != 0 || (fb->height % 4) != 0)) {
-               DRM_DEBUG_KMS("src dimensions not correct for NV12\n");
-               goto err;
-       }
-
        for (i = 0; i < fb->format->num_planes; i++) {
                u32 stride_alignment;
 
@@ -14629,7 +14758,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
                 * require the entire fb to accommodate that to avoid
                 * potential runtime errors at plane configuration time.
                 */
-               if (IS_GEN9(dev_priv) && i == 0 && fb->width > 3840 &&
+               if (IS_GEN(dev_priv, 9) && i == 0 && fb->width > 3840 &&
                    is_ccs_modifier(fb->modifier))
                        stride_alignment *= 4;
 
@@ -14834,7 +14963,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
                dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock;
                dev_priv->display.crtc_enable = i9xx_crtc_enable;
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
-       } else if (!IS_GEN2(dev_priv)) {
+       } else if (!IS_GEN(dev_priv, 2)) {
                dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
                        i9xx_get_initial_plane_config;
@@ -14850,9 +14979,9 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
        }
 
-       if (IS_GEN5(dev_priv)) {
+       if (IS_GEN(dev_priv, 5)) {
                dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
-       } else if (IS_GEN6(dev_priv)) {
+       } else if (IS_GEN(dev_priv, 6)) {
                dev_priv->display.fdi_link_train = gen6_fdi_link_train;
        } else if (IS_IVYBRIDGE(dev_priv)) {
                /* FIXME: detect B0+ stepping and use auto training */
@@ -14984,12 +15113,12 @@ fail:
 
 static void intel_update_fdi_pll_freq(struct drm_i915_private *dev_priv)
 {
-       if (IS_GEN5(dev_priv)) {
+       if (IS_GEN(dev_priv, 5)) {
                u32 fdi_pll_clk =
                        I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK;
 
                dev_priv->fdi_pll_freq = (fdi_pll_clk + 2) * 10000;
-       } else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
+       } else if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv)) {
                dev_priv->fdi_pll_freq = 270000;
        } else {
                return;
@@ -15105,10 +15234,10 @@ int intel_modeset_init(struct drm_device *dev)
        }
 
        /* maximum framebuffer dimensions */
-       if (IS_GEN2(dev_priv)) {
+       if (IS_GEN(dev_priv, 2)) {
                dev->mode_config.max_width = 2048;
                dev->mode_config.max_height = 2048;
-       } else if (IS_GEN3(dev_priv)) {
+       } else if (IS_GEN(dev_priv, 3)) {
                dev->mode_config.max_width = 4096;
                dev->mode_config.max_height = 4096;
        } else {
@@ -15119,7 +15248,7 @@ int intel_modeset_init(struct drm_device *dev)
        if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
                dev->mode_config.cursor_width = IS_I845G(dev_priv) ? 64 : 512;
                dev->mode_config.cursor_height = 1023;
-       } else if (IS_GEN2(dev_priv)) {
+       } else if (IS_GEN(dev_priv, 2)) {
                dev->mode_config.cursor_width = 64;
                dev->mode_config.cursor_height = 64;
        } else {
@@ -15379,6 +15508,15 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
                            plane->base.type != DRM_PLANE_TYPE_PRIMARY)
                                intel_plane_disable_noatomic(crtc, plane);
                }
+
+               /*
+                * Disable any background color set by the BIOS, but enable the
+                * gamma and CSC to match how we program our planes.
+                */
+               if (INTEL_GEN(dev_priv) >= 9)
+                       I915_WRITE(SKL_BOTTOM_COLOR(crtc->pipe),
+                                  SKL_BOTTOM_COLOR_GAMMA_ENABLE |
+                                  SKL_BOTTOM_COLOR_CSC_ENABLE);
        }
 
        /* Adjust the state of the output pipe according to whether we
@@ -15415,16 +15553,45 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
        }
 }
 
+static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+
+       /*
+        * Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram
+        * the hardware when a high res displays plugged in. DPLL P
+        * divider is zero, and the pipe timings are bonkers. We'll
+        * try to disable everything in that case.
+        *
+        * FIXME would be nice to be able to sanitize this state
+        * without several WARNs, but for now let's take the easy
+        * road.
+        */
+       return IS_GEN(dev_priv, 6) &&
+               crtc_state->base.active &&
+               crtc_state->shared_dpll &&
+               crtc_state->port_clock == 0;
+}
+
 static void intel_sanitize_encoder(struct intel_encoder *encoder)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_connector *connector;
+       struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+       struct intel_crtc_state *crtc_state = crtc ?
+               to_intel_crtc_state(crtc->base.state) : NULL;
 
        /* We need to check both for a crtc link (meaning that the
         * encoder is active and trying to read from a pipe) and the
         * pipe itself being active. */
-       bool has_active_crtc = encoder->base.crtc &&
-               to_intel_crtc(encoder->base.crtc)->active;
+       bool has_active_crtc = crtc_state &&
+               crtc_state->base.active;
+
+       if (crtc_state && has_bogus_dpll_config(crtc_state)) {
+               DRM_DEBUG_KMS("BIOS has misprogrammed the hardware. Disabling pipe %c\n",
+                             pipe_name(crtc->pipe));
+               has_active_crtc = false;
+       }
 
        connector = intel_encoder_find_connector(encoder);
        if (connector && !has_active_crtc) {
@@ -15435,16 +15602,25 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
                /* Connector is active, but has no active pipe. This is
                 * fallout from our resume register restoring. Disable
                 * the encoder manually again. */
-               if (encoder->base.crtc) {
-                       struct drm_crtc_state *crtc_state = encoder->base.crtc->state;
+               if (crtc_state) {
+                       struct drm_encoder *best_encoder;
 
                        DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n",
                                      encoder->base.base.id,
                                      encoder->base.name);
+
+                       /* avoid oopsing in case the hooks consult best_encoder */
+                       best_encoder = connector->base.state->best_encoder;
+                       connector->base.state->best_encoder = &encoder->base;
+
                        if (encoder->disable)
-                               encoder->disable(encoder, to_intel_crtc_state(crtc_state), connector->base.state);
+                               encoder->disable(encoder, crtc_state,
+                                                connector->base.state);
                        if (encoder->post_disable)
-                               encoder->post_disable(encoder, to_intel_crtc_state(crtc_state), connector->base.state);
+                               encoder->post_disable(encoder, crtc_state,
+                                                     connector->base.state);
+
+                       connector->base.state->best_encoder = best_encoder;
                }
                encoder->base.crtc = NULL;
 
@@ -15476,19 +15652,25 @@ void i915_redisable_vga_power_on(struct drm_i915_private *dev_priv)
 
 void i915_redisable_vga(struct drm_i915_private *dev_priv)
 {
-       /* This function can be called both from intel_modeset_setup_hw_state or
+       intel_wakeref_t wakeref;
+
+       /*
+        * This function can be called both from intel_modeset_setup_hw_state or
         * at a very early point in our resume sequence, where the power well
         * structures are not yet restored. Since this function is at a very
         * paranoid "someone might have enabled VGA while we were not looking"
         * level, just check if the power well is enabled instead of trying to
         * follow the "don't touch the power well if we don't need it" policy
-        * the rest of the driver uses. */
-       if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_VGA))
+        * the rest of the driver uses.
+        */
+       wakeref = intel_display_power_get_if_enabled(dev_priv,
+                                                    POWER_DOMAIN_VGA);
+       if (!wakeref)
                return;
 
        i915_redisable_vga_power_on(dev_priv);
 
-       intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
+       intel_display_power_put(dev_priv, POWER_DOMAIN_VGA, wakeref);
 }
 
 /* FIXME read out full plane state for all planes */
@@ -15788,12 +15970,13 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
                             struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *crtc;
        struct intel_crtc_state *crtc_state;
        struct intel_encoder *encoder;
+       struct intel_crtc *crtc;
+       intel_wakeref_t wakeref;
        int i;
 
-       intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+       wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
 
        intel_early_display_was(dev_priv);
        intel_modeset_readout_hw_state(dev);
@@ -15809,10 +15992,12 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
         * waits, so we need vblank interrupts restored beforehand.
         */
        for_each_intel_crtc(&dev_priv->drm, crtc) {
+               crtc_state = to_intel_crtc_state(crtc->base.state);
+
                drm_crtc_vblank_reset(&crtc->base);
 
-               if (crtc->base.state->active)
-                       drm_crtc_vblank_on(&crtc->base);
+               if (crtc_state->base.active)
+                       intel_crtc_vblank_on(crtc_state);
        }
 
        intel_sanitize_plane_mapping(dev_priv);
@@ -15843,15 +16028,15 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
        }
 
        if (IS_G4X(dev_priv)) {
-               g4x_wm_get_hw_state(dev);
+               g4x_wm_get_hw_state(dev_priv);
                g4x_wm_sanitize(dev_priv);
        } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-               vlv_wm_get_hw_state(dev);
+               vlv_wm_get_hw_state(dev_priv);
                vlv_wm_sanitize(dev_priv);
        } else if (INTEL_GEN(dev_priv) >= 9) {
-               skl_wm_get_hw_state(dev);
+               skl_wm_get_hw_state(dev_priv);
        } else if (HAS_PCH_SPLIT(dev_priv)) {
-               ilk_wm_get_hw_state(dev);
+               ilk_wm_get_hw_state(dev_priv);
        }
 
        for_each_intel_crtc(dev, crtc) {
@@ -15863,7 +16048,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
                        modeset_put_power_domains(dev_priv, put_domains);
        }
 
-       intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+       intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
 
        intel_fbc_init_pipe_state(dev_priv);
 }