]> Git Repo - linux.git/commitdiff
Merge tag 'drm-intel-next-2019-03-20' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <[email protected]>
Mon, 25 Mar 2019 20:15:27 +0000 (06:15 +1000)
committerDave Airlie <[email protected]>
Mon, 25 Mar 2019 20:15:27 +0000 (06:15 +1000)
UAPI Changes:
- Report an error early instead of SIGBUS later when mmap beyond BO size

Core Changes:
- This includes backmerge of drm-next and two merges of Maarten's
  topic/hdr-formats

Driver Changes:
- Add Comet Lake (Gen9) PCI IDs to Coffee Lake ID list (Anusha)
- Add missing ICL PCI ID (Jose)
- Fix legacy gamma mode for ICL (Ville)
- Assume eDP is present on port A when there is no VBT (Thomas)
- Corrections to eDP training patterns (Jose)
- Fix PSR2 selective update corruption after PSR1 setup (Jose)
- Fix CRC mismatch error for DP link layer compliance (Aditya)
- Fix CNL DPLL readout and clean up code (Ville)
- Turn off the CUS when turning off a HDR plane (Ville)
- Avoid a race with execlist tasklet during race (Chris)
- Add missing CSC readout and clean up code (Ville)
- Avoid unnecessary wakeref during debugfs/drop_caches/set (Chris, Caz)
- Hold references to ring/HW context/context explicitly when used (Chris)

- Assume next platforms inherit old platform (Rodrigo)
- Use HWS indices rather than addresses for breadcrumbs (Chris)
- Add REG_BIT/REG_GENMASK and REG_FIELD_PREP macros (Jani)
- Convert crept in C99 types to kernel fixed size types (Jani)
- Avoid passing full dev_priv in forcewake functions (Daniele)
- Reset GuC on GPU reset (Sujaritha)
- Rework MG and Combo PLLs to vfuncs (Lucas)
- Explicitly track ppGTT size (Chris, Bob)
- Coding style improvements and code modularization (Ville)
- Selftest and debugging improvements (Chris)

Signed-off-by: Dave Airlie <[email protected]>
# Conflicts:
# drivers/gpu/drm/i915/intel_hdmi.c
From: Joonas Lahtinen <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1  2 
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/intel_connector.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_sprite.c
include/sound/hdaudio.h

index 9df65d386d11b40349df879fec224f0990a40b62,b3d2524ce7cc81b74a3d5c84fb17c4fb0e83d941..9e380cd317dcd0faf2a7bdfa9ed78316db208969
@@@ -188,6 -188,11 +188,11 @@@ intel_pch_type(const struct drm_i915_pr
                DRM_DEBUG_KMS("Found Cannon Lake LP PCH (CNP-LP)\n");
                WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_COFFEELAKE(dev_priv));
                return PCH_CNP;
+       case INTEL_PCH_CMP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found Comet Lake PCH (CMP)\n");
+               WARN_ON(!IS_COFFEELAKE(dev_priv));
+               /* CometPoint is CNP Compatible */
+               return PCH_CNP;
        case INTEL_PCH_ICP_DEVICE_ID_TYPE:
                DRM_DEBUG_KMS("Found Ice Lake PCH\n");
                WARN_ON(!IS_ICELAKE(dev_priv));
@@@ -219,20 -224,20 +224,20 @@@ intel_virt_detect_pch(const struct drm_
         * make an educated guess as to which PCH is really there.
         */
  
-       if (IS_GEN(dev_priv, 5))
-               id = INTEL_PCH_IBX_DEVICE_ID_TYPE;
-       else if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
-               id = INTEL_PCH_CPT_DEVICE_ID_TYPE;
+       if (IS_ICELAKE(dev_priv))
+               id = INTEL_PCH_ICP_DEVICE_ID_TYPE;
+       else if (IS_CANNONLAKE(dev_priv) || IS_COFFEELAKE(dev_priv))
+               id = INTEL_PCH_CNP_DEVICE_ID_TYPE;
+       else if (IS_KABYLAKE(dev_priv) || IS_SKYLAKE(dev_priv))
+               id = INTEL_PCH_SPT_DEVICE_ID_TYPE;
        else if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
                id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
        else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
                id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
-       else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
-               id = INTEL_PCH_SPT_DEVICE_ID_TYPE;
-       else if (IS_COFFEELAKE(dev_priv) || IS_CANNONLAKE(dev_priv))
-               id = INTEL_PCH_CNP_DEVICE_ID_TYPE;
-       else if (IS_ICELAKE(dev_priv))
-               id = INTEL_PCH_ICP_DEVICE_ID_TYPE;
+       else if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
+               id = INTEL_PCH_CPT_DEVICE_ID_TYPE;
+       else if (IS_GEN(dev_priv, 5))
+               id = INTEL_PCH_IBX_DEVICE_ID_TYPE;
  
        if (id)
                DRM_DEBUG_KMS("Assuming PCH ID %04x\n", id);
@@@ -330,16 -335,16 +335,16 @@@ static int i915_getparam_ioctl(struct d
                value = dev_priv->overlay ? 1 : 0;
                break;
        case I915_PARAM_HAS_BSD:
-               value = !!dev_priv->engine[VCS];
+               value = !!dev_priv->engine[VCS0];
                break;
        case I915_PARAM_HAS_BLT:
-               value = !!dev_priv->engine[BCS];
+               value = !!dev_priv->engine[BCS0];
                break;
        case I915_PARAM_HAS_VEBOX:
-               value = !!dev_priv->engine[VECS];
+               value = !!dev_priv->engine[VECS0];
                break;
        case I915_PARAM_HAS_BSD2:
-               value = !!dev_priv->engine[VCS2];
+               value = !!dev_priv->engine[VCS1];
                break;
        case I915_PARAM_HAS_LLC:
                value = HAS_LLC(dev_priv);
                value = HAS_WT(dev_priv);
                break;
        case I915_PARAM_HAS_ALIASING_PPGTT:
-               value = min_t(int, INTEL_PPGTT(dev_priv), I915_GEM_PPGTT_FULL);
+               value = INTEL_PPGTT(dev_priv);
                break;
        case I915_PARAM_HAS_SEMAPHORES:
-               value = 0;
+               value = !!(dev_priv->caps.scheduler & I915_SCHEDULER_CAP_SEMAPHORES);
                break;
        case I915_PARAM_HAS_SECURE_BATCHES:
                value = capable(CAP_SYS_ADMIN);
@@@ -714,8 -719,7 +719,7 @@@ static int i915_load_modeset_init(struc
        return 0;
  
  cleanup_gem:
-       if (i915_gem_suspend(dev_priv))
-               DRM_ERROR("failed to idle hardware; continuing to unload!\n");
+       i915_gem_suspend(dev_priv);
        i915_gem_fini(dev_priv);
  cleanup_modeset:
        intel_modeset_cleanup(dev);
@@@ -757,6 -761,39 +761,6 @@@ static int i915_kick_out_firmware_fb(st
        return ret;
  }
  
 -#if !defined(CONFIG_VGA_CONSOLE)
 -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
 -{
 -      return 0;
 -}
 -#elif !defined(CONFIG_DUMMY_CONSOLE)
 -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
 -{
 -      return -ENODEV;
 -}
 -#else
 -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
 -{
 -      int ret = 0;
 -
 -      DRM_INFO("Replacing VGA console driver\n");
 -
 -      console_lock();
 -      if (con_is_bound(&vga_con))
 -              ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
 -      if (ret == 0) {
 -              ret = do_unregister_con_driver(&vga_con);
 -
 -              /* Ignore "already unregistered". */
 -              if (ret == -ENODEV)
 -                      ret = 0;
 -      }
 -      console_unlock();
 -
 -      return ret;
 -}
 -#endif
 -
  static void intel_init_dpio(struct drm_i915_private *dev_priv)
  {
        /*
@@@ -873,6 -910,7 +877,7 @@@ static int i915_driver_init_early(struc
        mutex_init(&dev_priv->av_mutex);
        mutex_init(&dev_priv->wm.wm_mutex);
        mutex_init(&dev_priv->pps_mutex);
+       mutex_init(&dev_priv->hdcp_comp_mutex);
  
        i915_memcpy_init_early(dev_priv);
        intel_runtime_pm_init_early(dev_priv);
@@@ -1034,110 -1072,180 +1039,180 @@@ static void intel_sanitize_options(stru
        intel_gvt_sanitize_options(dev_priv);
  }
  
- static enum dram_rank skl_get_dimm_rank(u8 size, u32 rank)
+ #define DRAM_TYPE_STR(type) [INTEL_DRAM_ ## type] = #type
+ static const char *intel_dram_type_str(enum intel_dram_type type)
  {
-       if (size == 0)
-               return I915_DRAM_RANK_INVALID;
-       if (rank == SKL_DRAM_RANK_SINGLE)
-               return I915_DRAM_RANK_SINGLE;
-       else if (rank == SKL_DRAM_RANK_DUAL)
-               return I915_DRAM_RANK_DUAL;
+       static const char * const str[] = {
+               DRAM_TYPE_STR(UNKNOWN),
+               DRAM_TYPE_STR(DDR3),
+               DRAM_TYPE_STR(DDR4),
+               DRAM_TYPE_STR(LPDDR3),
+               DRAM_TYPE_STR(LPDDR4),
+       };
+       if (type >= ARRAY_SIZE(str))
+               type = INTEL_DRAM_UNKNOWN;
+       return str[type];
+ }
  
-       return I915_DRAM_RANK_INVALID;
+ #undef DRAM_TYPE_STR
+ static int intel_dimm_num_devices(const struct dram_dimm_info *dimm)
+ {
+       return dimm->ranks * 64 / (dimm->width ?: 1);
  }
  
- static bool
- skl_is_16gb_dimm(enum dram_rank rank, u8 size, u8 width)
+ /* Returns total GB for the whole DIMM */
+ static int skl_get_dimm_size(u16 val)
  {
-       if (rank == I915_DRAM_RANK_SINGLE && width == 8 && size == 16)
-               return true;
-       else if (rank == I915_DRAM_RANK_DUAL && width == 8 && size == 32)
-               return true;
-       else if (rank == SKL_DRAM_RANK_SINGLE && width == 16 && size == 8)
-               return true;
-       else if (rank == SKL_DRAM_RANK_DUAL && width == 16 && size == 16)
-               return true;
+       return val & SKL_DRAM_SIZE_MASK;
+ }
  
-       return false;
+ static int skl_get_dimm_width(u16 val)
+ {
+       if (skl_get_dimm_size(val) == 0)
+               return 0;
+       switch (val & SKL_DRAM_WIDTH_MASK) {
+       case SKL_DRAM_WIDTH_X8:
+       case SKL_DRAM_WIDTH_X16:
+       case SKL_DRAM_WIDTH_X32:
+               val = (val & SKL_DRAM_WIDTH_MASK) >> SKL_DRAM_WIDTH_SHIFT;
+               return 8 << val;
+       default:
+               MISSING_CASE(val);
+               return 0;
+       }
  }
  
- static int
- skl_dram_get_channel_info(struct dram_channel_info *ch, u32 val)
+ static int skl_get_dimm_ranks(u16 val)
  {
-       u32 tmp_l, tmp_s;
-       u32 s_val = val >> SKL_DRAM_S_SHIFT;
+       if (skl_get_dimm_size(val) == 0)
+               return 0;
  
-       if (!val)
-               return -EINVAL;
+       val = (val & SKL_DRAM_RANK_MASK) >> SKL_DRAM_RANK_SHIFT;
  
-       tmp_l = val & SKL_DRAM_SIZE_MASK;
-       tmp_s = s_val & SKL_DRAM_SIZE_MASK;
+       return val + 1;
+ }
  
-       if (tmp_l == 0 && tmp_s == 0)
+ /* Returns total GB for the whole DIMM */
+ static int cnl_get_dimm_size(u16 val)
+ {
+       return (val & CNL_DRAM_SIZE_MASK) / 2;
+ }
+ static int cnl_get_dimm_width(u16 val)
+ {
+       if (cnl_get_dimm_size(val) == 0)
+               return 0;
+       switch (val & CNL_DRAM_WIDTH_MASK) {
+       case CNL_DRAM_WIDTH_X8:
+       case CNL_DRAM_WIDTH_X16:
+       case CNL_DRAM_WIDTH_X32:
+               val = (val & CNL_DRAM_WIDTH_MASK) >> CNL_DRAM_WIDTH_SHIFT;
+               return 8 << val;
+       default:
+               MISSING_CASE(val);
+               return 0;
+       }
+ }
+ static int cnl_get_dimm_ranks(u16 val)
+ {
+       if (cnl_get_dimm_size(val) == 0)
+               return 0;
+       val = (val & CNL_DRAM_RANK_MASK) >> CNL_DRAM_RANK_SHIFT;
+       return val + 1;
+ }
+ static bool
+ skl_is_16gb_dimm(const struct dram_dimm_info *dimm)
+ {
+       /* Convert total GB to Gb per DRAM device */
+       return 8 * dimm->size / (intel_dimm_num_devices(dimm) ?: 1) == 16;
+ }
+ static void
+ skl_dram_get_dimm_info(struct drm_i915_private *dev_priv,
+                      struct dram_dimm_info *dimm,
+                      int channel, char dimm_name, u16 val)
+ {
+       if (INTEL_GEN(dev_priv) >= 10) {
+               dimm->size = cnl_get_dimm_size(val);
+               dimm->width = cnl_get_dimm_width(val);
+               dimm->ranks = cnl_get_dimm_ranks(val);
+       } else {
+               dimm->size = skl_get_dimm_size(val);
+               dimm->width = skl_get_dimm_width(val);
+               dimm->ranks = skl_get_dimm_ranks(val);
+       }
+       DRM_DEBUG_KMS("CH%u DIMM %c size: %u GB, width: X%u, ranks: %u, 16Gb DIMMs: %s\n",
+                     channel, dimm_name, dimm->size, dimm->width, dimm->ranks,
+                     yesno(skl_is_16gb_dimm(dimm)));
+ }
+ static int
+ skl_dram_get_channel_info(struct drm_i915_private *dev_priv,
+                         struct dram_channel_info *ch,
+                         int channel, u32 val)
+ {
+       skl_dram_get_dimm_info(dev_priv, &ch->dimm_l,
+                              channel, 'L', val & 0xffff);
+       skl_dram_get_dimm_info(dev_priv, &ch->dimm_s,
+                              channel, 'S', val >> 16);
+       if (ch->dimm_l.size == 0 && ch->dimm_s.size == 0) {
+               DRM_DEBUG_KMS("CH%u not populated\n", channel);
                return -EINVAL;
+       }
  
-       ch->l_info.size = tmp_l;
-       ch->s_info.size = tmp_s;
-       tmp_l = (val & SKL_DRAM_WIDTH_MASK) >> SKL_DRAM_WIDTH_SHIFT;
-       tmp_s = (s_val & SKL_DRAM_WIDTH_MASK) >> SKL_DRAM_WIDTH_SHIFT;
-       ch->l_info.width = (1 << tmp_l) * 8;
-       ch->s_info.width = (1 << tmp_s) * 8;
-       tmp_l = val & SKL_DRAM_RANK_MASK;
-       tmp_s = s_val & SKL_DRAM_RANK_MASK;
-       ch->l_info.rank = skl_get_dimm_rank(ch->l_info.size, tmp_l);
-       ch->s_info.rank = skl_get_dimm_rank(ch->s_info.size, tmp_s);
-       if (ch->l_info.rank == I915_DRAM_RANK_DUAL ||
-           ch->s_info.rank == I915_DRAM_RANK_DUAL)
-               ch->rank = I915_DRAM_RANK_DUAL;
-       else if (ch->l_info.rank == I915_DRAM_RANK_SINGLE &&
-                ch->s_info.rank == I915_DRAM_RANK_SINGLE)
-               ch->rank = I915_DRAM_RANK_DUAL;
+       if (ch->dimm_l.ranks == 2 || ch->dimm_s.ranks == 2)
+               ch->ranks = 2;
+       else if (ch->dimm_l.ranks == 1 && ch->dimm_s.ranks == 1)
+               ch->ranks = 2;
        else
-               ch->rank = I915_DRAM_RANK_SINGLE;
+               ch->ranks = 1;
  
-       ch->is_16gb_dimm = skl_is_16gb_dimm(ch->l_info.rank, ch->l_info.size,
-                                           ch->l_info.width) ||
-                          skl_is_16gb_dimm(ch->s_info.rank, ch->s_info.size,
-                                           ch->s_info.width);
+       ch->is_16gb_dimm =
+               skl_is_16gb_dimm(&ch->dimm_l) ||
+               skl_is_16gb_dimm(&ch->dimm_s);
  
-       DRM_DEBUG_KMS("(size:width:rank) L(%dGB:X%d:%s) S(%dGB:X%d:%s)\n",
-                     ch->l_info.size, ch->l_info.width,
-                     ch->l_info.rank ? "dual" : "single",
-                     ch->s_info.size, ch->s_info.width,
-                     ch->s_info.rank ? "dual" : "single");
+       DRM_DEBUG_KMS("CH%u ranks: %u, 16Gb DIMMs: %s\n",
+                     channel, ch->ranks, yesno(ch->is_16gb_dimm));
  
        return 0;
  }
  
  static bool
- intel_is_dram_symmetric(u32 val_ch0, u32 val_ch1,
-                       struct dram_channel_info *ch0)
+ intel_is_dram_symmetric(const struct dram_channel_info *ch0,
+                       const struct dram_channel_info *ch1)
  {
-       return (val_ch0 == val_ch1 &&
-               (ch0->s_info.size == 0 ||
-                (ch0->l_info.size == ch0->s_info.size &&
-                 ch0->l_info.width == ch0->s_info.width &&
-                 ch0->l_info.rank == ch0->s_info.rank)));
+       return !memcmp(ch0, ch1, sizeof(*ch0)) &&
+               (ch0->dimm_s.size == 0 ||
+                !memcmp(&ch0->dimm_l, &ch0->dimm_s, sizeof(ch0->dimm_l)));
  }
  
  static int
  skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
  {
        struct dram_info *dram_info = &dev_priv->dram_info;
-       struct dram_channel_info ch0, ch1;
-       u32 val_ch0, val_ch1;
+       struct dram_channel_info ch0 = {}, ch1 = {};
+       u32 val;
        int ret;
  
-       val_ch0 = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
-       ret = skl_dram_get_channel_info(&ch0, val_ch0);
+       val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
+       ret = skl_dram_get_channel_info(dev_priv, &ch0, 0, val);
        if (ret == 0)
                dram_info->num_channels++;
  
-       val_ch1 = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
-       ret = skl_dram_get_channel_info(&ch1, val_ch1);
+       val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
+       ret = skl_dram_get_channel_info(dev_priv, &ch1, 1, val);
        if (ret == 0)
                dram_info->num_channels++;
  
         * will be same as if single rank memory, so consider single rank
         * memory.
         */
-       if (ch0.rank == I915_DRAM_RANK_SINGLE ||
-           ch1.rank == I915_DRAM_RANK_SINGLE)
-               dram_info->rank = I915_DRAM_RANK_SINGLE;
+       if (ch0.ranks == 1 || ch1.ranks == 1)
+               dram_info->ranks = 1;
        else
-               dram_info->rank = max(ch0.rank, ch1.rank);
+               dram_info->ranks = max(ch0.ranks, ch1.ranks);
  
-       if (dram_info->rank == I915_DRAM_RANK_INVALID) {
+       if (dram_info->ranks == 0) {
                DRM_INFO("couldn't get memory rank information\n");
                return -EINVAL;
        }
  
        dram_info->is_16gb_dimm = ch0.is_16gb_dimm || ch1.is_16gb_dimm;
  
-       dev_priv->dram_info.symmetric_memory = intel_is_dram_symmetric(val_ch0,
-                                                                      val_ch1,
-                                                                      &ch0);
+       dram_info->symmetric_memory = intel_is_dram_symmetric(&ch0, &ch1);
  
-       DRM_DEBUG_KMS("memory configuration is %sSymmetric memory\n",
-                     dev_priv->dram_info.symmetric_memory ? "" : "not ");
+       DRM_DEBUG_KMS("Memory configuration is symmetric? %s\n",
+                     yesno(dram_info->symmetric_memory));
        return 0;
  }
  
+ static enum intel_dram_type
+ skl_get_dram_type(struct drm_i915_private *dev_priv)
+ {
+       u32 val;
+       val = I915_READ(SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN);
+       switch (val & SKL_DRAM_DDR_TYPE_MASK) {
+       case SKL_DRAM_DDR_TYPE_DDR3:
+               return INTEL_DRAM_DDR3;
+       case SKL_DRAM_DDR_TYPE_DDR4:
+               return INTEL_DRAM_DDR4;
+       case SKL_DRAM_DDR_TYPE_LPDDR3:
+               return INTEL_DRAM_LPDDR3;
+       case SKL_DRAM_DDR_TYPE_LPDDR4:
+               return INTEL_DRAM_LPDDR4;
+       default:
+               MISSING_CASE(val);
+               return INTEL_DRAM_UNKNOWN;
+       }
+ }
  static int
  skl_get_dram_info(struct drm_i915_private *dev_priv)
  {
        u32 mem_freq_khz, val;
        int ret;
  
+       dram_info->type = skl_get_dram_type(dev_priv);
+       DRM_DEBUG_KMS("DRAM type: %s\n", intel_dram_type_str(dram_info->type));
        ret = skl_dram_get_channels_info(dev_priv);
        if (ret)
                return ret;
        return 0;
  }
  
+ /* Returns Gb per DRAM device */
+ static int bxt_get_dimm_size(u32 val)
+ {
+       switch (val & BXT_DRAM_SIZE_MASK) {
+       case BXT_DRAM_SIZE_4GBIT:
+               return 4;
+       case BXT_DRAM_SIZE_6GBIT:
+               return 6;
+       case BXT_DRAM_SIZE_8GBIT:
+               return 8;
+       case BXT_DRAM_SIZE_12GBIT:
+               return 12;
+       case BXT_DRAM_SIZE_16GBIT:
+               return 16;
+       default:
+               MISSING_CASE(val);
+               return 0;
+       }
+ }
+ static int bxt_get_dimm_width(u32 val)
+ {
+       if (!bxt_get_dimm_size(val))
+               return 0;
+       val = (val & BXT_DRAM_WIDTH_MASK) >> BXT_DRAM_WIDTH_SHIFT;
+       return 8 << val;
+ }
+ static int bxt_get_dimm_ranks(u32 val)
+ {
+       if (!bxt_get_dimm_size(val))
+               return 0;
+       switch (val & BXT_DRAM_RANK_MASK) {
+       case BXT_DRAM_RANK_SINGLE:
+               return 1;
+       case BXT_DRAM_RANK_DUAL:
+               return 2;
+       default:
+               MISSING_CASE(val);
+               return 0;
+       }
+ }
+ static enum intel_dram_type bxt_get_dimm_type(u32 val)
+ {
+       if (!bxt_get_dimm_size(val))
+               return INTEL_DRAM_UNKNOWN;
+       switch (val & BXT_DRAM_TYPE_MASK) {
+       case BXT_DRAM_TYPE_DDR3:
+               return INTEL_DRAM_DDR3;
+       case BXT_DRAM_TYPE_LPDDR3:
+               return INTEL_DRAM_LPDDR3;
+       case BXT_DRAM_TYPE_DDR4:
+               return INTEL_DRAM_DDR4;
+       case BXT_DRAM_TYPE_LPDDR4:
+               return INTEL_DRAM_LPDDR4;
+       default:
+               MISSING_CASE(val);
+               return INTEL_DRAM_UNKNOWN;
+       }
+ }
+ static void bxt_get_dimm_info(struct dram_dimm_info *dimm,
+                             u32 val)
+ {
+       dimm->width = bxt_get_dimm_width(val);
+       dimm->ranks = bxt_get_dimm_ranks(val);
+       /*
+        * Size in register is Gb per DRAM device. Convert to total
+        * GB to match the way we report this for non-LP platforms.
+        */
+       dimm->size = bxt_get_dimm_size(val) * intel_dimm_num_devices(dimm) / 8;
+ }
  static int
  bxt_get_dram_info(struct drm_i915_private *dev_priv)
  {
         * Now read each DUNIT8/9/10/11 to check the rank of each dimms.
         */
        for (i = BXT_D_CR_DRP0_DUNIT_START; i <= BXT_D_CR_DRP0_DUNIT_END; i++) {
-               u8 size, width;
-               enum dram_rank rank;
-               u32 tmp;
+               struct dram_dimm_info dimm;
+               enum intel_dram_type type;
  
                val = I915_READ(BXT_D_CR_DRP0_DUNIT(i));
                if (val == 0xFFFFFFFF)
                        continue;
  
                dram_info->num_channels++;
-               tmp = val & BXT_DRAM_RANK_MASK;
-               if (tmp == BXT_DRAM_RANK_SINGLE)
-                       rank = I915_DRAM_RANK_SINGLE;
-               else if (tmp == BXT_DRAM_RANK_DUAL)
-                       rank = I915_DRAM_RANK_DUAL;
-               else
-                       rank = I915_DRAM_RANK_INVALID;
-               tmp = val & BXT_DRAM_SIZE_MASK;
-               if (tmp == BXT_DRAM_SIZE_4GB)
-                       size = 4;
-               else if (tmp == BXT_DRAM_SIZE_6GB)
-                       size = 6;
-               else if (tmp == BXT_DRAM_SIZE_8GB)
-                       size = 8;
-               else if (tmp == BXT_DRAM_SIZE_12GB)
-                       size = 12;
-               else if (tmp == BXT_DRAM_SIZE_16GB)
-                       size = 16;
-               else
-                       size = 0;
-               tmp = (val & BXT_DRAM_WIDTH_MASK) >> BXT_DRAM_WIDTH_SHIFT;
-               width = (1 << tmp) * 8;
-               DRM_DEBUG_KMS("dram size:%dGB width:X%d rank:%s\n", size,
-                             width, rank == I915_DRAM_RANK_SINGLE ? "single" :
-                             rank == I915_DRAM_RANK_DUAL ? "dual" : "unknown");
+               bxt_get_dimm_info(&dimm, val);
+               type = bxt_get_dimm_type(val);
+               WARN_ON(type != INTEL_DRAM_UNKNOWN &&
+                       dram_info->type != INTEL_DRAM_UNKNOWN &&
+                       dram_info->type != type);
+               DRM_DEBUG_KMS("CH%u DIMM size: %u GB, width: X%u, ranks: %u, type: %s\n",
+                             i - BXT_D_CR_DRP0_DUNIT_START,
+                             dimm.size, dimm.width, dimm.ranks,
+                             intel_dram_type_str(type));
  
                /*
                 * If any of the channel is single rank channel,
                 * worst case output will be same as if single rank
                 * memory, so consider single rank memory.
                 */
-               if (dram_info->rank == I915_DRAM_RANK_INVALID)
-                       dram_info->rank = rank;
-               else if (rank == I915_DRAM_RANK_SINGLE)
-                       dram_info->rank = I915_DRAM_RANK_SINGLE;
+               if (dram_info->ranks == 0)
+                       dram_info->ranks = dimm.ranks;
+               else if (dimm.ranks == 1)
+                       dram_info->ranks = 1;
+               if (type != INTEL_DRAM_UNKNOWN)
+                       dram_info->type = type;
        }
  
-       if (dram_info->rank == I915_DRAM_RANK_INVALID) {
-               DRM_INFO("couldn't get memory rank information\n");
+       if (dram_info->type == INTEL_DRAM_UNKNOWN ||
+           dram_info->ranks == 0) {
+               DRM_INFO("couldn't get memory information\n");
                return -EINVAL;
        }
  
@@@ -1290,14 -1486,8 +1453,8 @@@ static voi
  intel_get_dram_info(struct drm_i915_private *dev_priv)
  {
        struct dram_info *dram_info = &dev_priv->dram_info;
-       char bandwidth_str[32];
        int ret;
  
-       dram_info->valid = false;
-       dram_info->rank = I915_DRAM_RANK_INVALID;
-       dram_info->bandwidth_kbps = 0;
-       dram_info->num_channels = 0;
        /*
         * Assume 16Gb DIMMs are present until proven otherwise.
         * This is only used for the level 0 watermark latency
         */
        dram_info->is_16gb_dimm = !IS_GEN9_LP(dev_priv);
  
-       if (INTEL_GEN(dev_priv) < 9 || IS_GEMINILAKE(dev_priv))
+       if (INTEL_GEN(dev_priv) < 9)
                return;
  
-       /* Need to calculate bandwidth only for Gen9 */
-       if (IS_BROXTON(dev_priv))
+       if (IS_GEN9_LP(dev_priv))
                ret = bxt_get_dram_info(dev_priv);
-       else if (IS_GEN(dev_priv, 9))
-               ret = skl_get_dram_info(dev_priv);
        else
-               ret = skl_dram_get_channels_info(dev_priv);
+               ret = skl_get_dram_info(dev_priv);
        if (ret)
                return;
  
-       if (dram_info->bandwidth_kbps)
-               sprintf(bandwidth_str, "%d KBps", dram_info->bandwidth_kbps);
-       else
-               sprintf(bandwidth_str, "unknown");
-       DRM_DEBUG_KMS("DRAM bandwidth:%s, total-channels: %u\n",
-                     bandwidth_str, dram_info->num_channels);
-       DRM_DEBUG_KMS("DRAM rank: %s rank 16GB-dimm:%s\n",
-                     (dram_info->rank == I915_DRAM_RANK_DUAL) ?
-                     "dual" : "single", yesno(dram_info->is_16gb_dimm));
+       DRM_DEBUG_KMS("DRAM bandwidth: %u kBps, channels: %u\n",
+                     dram_info->bandwidth_kbps,
+                     dram_info->num_channels);
+       DRM_DEBUG_KMS("DRAM ranks: %u, 16Gb DIMMs: %s\n",
+                     dram_info->ranks, yesno(dram_info->is_16gb_dimm));
  }
  
  /**
@@@ -1348,7 -1532,7 +1499,7 @@@ static int i915_driver_init_hw(struct d
  
        if (HAS_PPGTT(dev_priv)) {
                if (intel_vgpu_active(dev_priv) &&
-                   !intel_vgpu_has_full_48bit_ppgtt(dev_priv)) {
+                   !intel_vgpu_has_full_ppgtt(dev_priv)) {
                        i915_report_error(dev_priv,
                                          "incompatible vGPU found, support for isolated ppGTT required\n");
                        return -ENXIO;
                goto err_ggtt;
        }
  
 -      ret = i915_kick_out_vgacon(dev_priv);
 +      ret = vga_remove_vgacon(pdev);
        if (ret) {
                DRM_ERROR("failed to remove conflicting VGA console\n");
                goto err_ggtt;
@@@ -1753,8 -1937,7 +1904,7 @@@ void i915_driver_unload(struct drm_devi
        /* Flush any external code that still may be under the RCU lock */
        synchronize_rcu();
  
-       if (i915_gem_suspend(dev_priv))
-               DRM_ERROR("failed to idle hardware; continuing to unload!\n");
+       i915_gem_suspend(dev_priv);
  
        drm_atomic_helper_shutdown(dev);
  
@@@ -1862,7 -2045,6 +2012,6 @@@ static bool suspend_to_idle(struct drm_
  static int i915_drm_prepare(struct drm_device *dev)
  {
        struct drm_i915_private *i915 = to_i915(dev);
-       int err;
  
        /*
         * NB intel_display_suspend() may issue new requests after we've
         * split out that work and pull it forward so that after point,
         * the GPU is not woken again.
         */
-       err = i915_gem_suspend(i915);
-       if (err)
-               dev_err(&i915->drm.pdev->dev,
-                       "GEM idle failed, suspend/resume might fail\n");
+       i915_gem_suspend(i915);
  
-       return err;
+       return 0;
  }
  
  static int i915_drm_suspend(struct drm_device *dev)
index b745c49a5af620e61adbfe05585f2f8ad7b7ad03,084016200a1e2ff566c3636a371e69d37849365d..46a52da3db297bec061d874858b8fbb440dc4654
@@@ -5,7 -5,6 +5,7 @@@
   */
  
  #include <linux/irq.h>
 +#include <linux/pm_runtime.h>
  #include "i915_pmu.h"
  #include "intel_ringbuffer.h"
  #include "i915_drv.h"
@@@ -102,7 -101,7 +102,7 @@@ static bool pmu_needs_timer(struct drm_
         *
         * Use RCS as proxy for all engines.
         */
-       else if (intel_engine_supports_stats(i915->engine[RCS]))
+       else if (intel_engine_supports_stats(i915->engine[RCS0]))
                enable &= ~BIT(I915_SAMPLE_BUSY);
  
        /*
@@@ -149,14 -148,6 +149,6 @@@ void i915_pmu_gt_unparked(struct drm_i9
        spin_unlock_irq(&i915->pmu.lock);
  }
  
- static bool grab_forcewake(struct drm_i915_private *i915, bool fw)
- {
-       if (!fw)
-               intel_uncore_forcewake_get(i915, FORCEWAKE_ALL);
-       return true;
- }
  static void
  add_sample(struct i915_pmu_sample *sample, u32 val)
  {
@@@ -169,49 -160,48 +161,48 @@@ engines_sample(struct drm_i915_private 
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
        intel_wakeref_t wakeref;
-       bool fw = false;
+       unsigned long flags;
  
        if ((dev_priv->pmu.enable & ENGINE_SAMPLE_MASK) == 0)
                return;
  
-       if (!dev_priv->gt.awake)
-               return;
-       wakeref = intel_runtime_pm_get_if_in_use(dev_priv);
+       wakeref = 0;
+       if (READ_ONCE(dev_priv->gt.awake))
+               wakeref = intel_runtime_pm_get_if_in_use(dev_priv);
        if (!wakeref)
                return;
  
+       spin_lock_irqsave(&dev_priv->uncore.lock, flags);
        for_each_engine(engine, dev_priv, id) {
-               u32 current_seqno = intel_engine_get_seqno(engine);
-               u32 last_seqno = intel_engine_last_submit(engine);
+               struct intel_engine_pmu *pmu = &engine->pmu;
+               bool busy;
                u32 val;
  
-               val = !i915_seqno_passed(current_seqno, last_seqno);
-               if (val)
-                       add_sample(&engine->pmu.sample[I915_SAMPLE_BUSY],
-                                  period_ns);
-               if (val && (engine->pmu.enable &
-                   (BIT(I915_SAMPLE_WAIT) | BIT(I915_SAMPLE_SEMA)))) {
-                       fw = grab_forcewake(dev_priv, fw);
-                       val = I915_READ_FW(RING_CTL(engine->mmio_base));
-               } else {
-                       val = 0;
-               }
+               val = I915_READ_FW(RING_CTL(engine->mmio_base));
+               if (val == 0) /* powerwell off => engine idle */
+                       continue;
  
                if (val & RING_WAIT)
-                       add_sample(&engine->pmu.sample[I915_SAMPLE_WAIT],
-                                  period_ns);
+                       add_sample(&pmu->sample[I915_SAMPLE_WAIT], period_ns);
                if (val & RING_WAIT_SEMAPHORE)
-                       add_sample(&engine->pmu.sample[I915_SAMPLE_SEMA],
-                                  period_ns);
+                       add_sample(&pmu->sample[I915_SAMPLE_SEMA], period_ns);
+               /*
+                * While waiting on a semaphore or event, MI_MODE reports the
+                * ring as idle. However, previously using the seqno, and with
+                * execlists sampling, we account for the ring waiting as the
+                * engine being busy. Therefore, we record the sample as being
+                * busy if either waiting or !idle.
+                */
+               busy = val & (RING_WAIT_SEMAPHORE | RING_WAIT);
+               if (!busy) {
+                       val = I915_READ_FW(RING_MI_MODE(engine->mmio_base));
+                       busy = !(val & MODE_IDLE);
+               }
+               if (busy)
+                       add_sample(&pmu->sample[I915_SAMPLE_BUSY], period_ns);
        }
-       if (fw)
-               intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
  
        intel_runtime_pm_put(dev_priv, wakeref);
  }
@@@ -484,6 -474,7 +475,6 @@@ static u64 get_rc6(struct drm_i915_priv
                 * counter value.
                 */
                spin_lock_irqsave(&i915->pmu.lock, flags);
 -              spin_lock(&kdev->power.lock);
  
                /*
                 * After the above branch intel_runtime_pm_get_if_in_use failed
                 * suspended and if not we cannot do better than report the last
                 * known RC6 value.
                 */
 -              if (kdev->power.runtime_status == RPM_SUSPENDED) {
 -                      if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
 -                              i915->pmu.suspended_jiffies_last =
 -                                                kdev->power.suspended_jiffies;
 +              if (pm_runtime_status_suspended(kdev)) {
 +                      val = pm_runtime_suspended_time(kdev);
  
 -                      val = kdev->power.suspended_jiffies -
 -                            i915->pmu.suspended_jiffies_last;
 -                      val += jiffies - kdev->power.accounting_timestamp;
 +                      if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
 +                              i915->pmu.suspended_time_last = val;
  
 -                      val = jiffies_to_nsecs(val);
 +                      val -= i915->pmu.suspended_time_last;
                        val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
  
                        i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
                        val = i915->pmu.sample[__I915_SAMPLE_RC6].cur;
                }
  
 -              spin_unlock(&kdev->power.lock);
                spin_unlock_irqrestore(&i915->pmu.lock, flags);
        }
  
index 8352d0bd8813110787e89149325fbeb27ada30c0,66ed3ee5998aecbbac9add552e4e8a2ca2c54459..848dd9e728d83f9427241e70bb53d6258886fb3c
@@@ -88,6 -88,8 +88,8 @@@ void intel_connector_destroy(struct drm
  
        kfree(intel_connector->detect_edid);
  
+       intel_hdcp_cleanup(intel_connector);
        if (!IS_ERR_OR_NULL(intel_connector->edid))
                kfree(intel_connector->edid);
  
@@@ -265,11 -267,3 +267,11 @@@ intel_attach_aspect_ratio_property(stru
                        connector->dev->mode_config.aspect_ratio_property,
                        DRM_MODE_PICTURE_ASPECT_NONE);
  }
 +
 +void
 +intel_attach_colorspace_property(struct drm_connector *connector)
 +{
 +      if (!drm_mode_create_colorspace_property(connector))
 +              drm_object_attach_property(&connector->base,
 +                                         connector->colorspace_property, 0);
 +}
index 94496488641cb988809efb31003c281b1898faff,eadc639e99acd5bd1b0f95966b5dbde50cdf4ad5..8574c212b37c4a8b85f537e7511dfdb5af05932e
@@@ -595,7 -595,7 +595,7 @@@ i9xx_select_p2_div(const struct intel_l
                   const struct intel_crtc_state *crtc_state,
                   int target)
  {
-       struct drm_device *dev = crtc_state->base.crtc->dev;
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
  
        if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
                /*
                 * We haven't figured out how to reliably set up different
                 * single/dual channel state, if we even can.
                 */
-               if (intel_is_dual_link_lvds(dev))
+               if (intel_is_dual_link_lvds(dev_priv))
                        return limit->p2.p2_fast;
                else
                        return limit->p2.p2_slow;
@@@ -951,14 -951,15 +951,15 @@@ chv_find_best_dpll(const struct intel_l
        return found;
  }
  
- bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
+ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
                        struct dpll *best_clock)
  {
        int refclk = 100000;
        const struct intel_limit *limit = &intel_limits_bxt;
  
        return chv_find_best_dpll(limit, crtc_state,
-                                 target_clock, refclk, NULL, best_clock);
+                                 crtc_state->port_clock, refclk,
+                                 NULL, best_clock);
  }
  
  bool intel_crtc_active(struct intel_crtc *crtc)
@@@ -1441,19 -1442,6 +1442,6 @@@ static void chv_enable_pll(struct intel
        }
  }
  
- static int intel_num_dvo_pipes(struct drm_i915_private *dev_priv)
- {
-       struct intel_crtc *crtc;
-       int count = 0;
-       for_each_intel_crtc(&dev_priv->drm, crtc) {
-               count += crtc->base.state->active &&
-                       intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DVO);
-       }
-       return count;
- }
  static void i9xx_enable_pll(struct intel_crtc *crtc,
                            const struct intel_crtc_state *crtc_state)
  {
        if (IS_MOBILE(dev_priv) && !IS_I830(dev_priv))
                assert_panel_unlocked(dev_priv, crtc->pipe);
  
-       /* Enable DVO 2x clock on both PLLs if necessary */
-       if (IS_I830(dev_priv) && intel_num_dvo_pipes(dev_priv) > 0) {
-               /*
-                * It appears to be important that we don't enable this
-                * for the current pipe before otherwise configuring the
-                * PLL. No idea how this should be handled if multiple
-                * DVO outputs are enabled simultaneosly.
-                */
-               dpll |= DPLL_DVO_2X_MODE;
-               I915_WRITE(DPLL(!crtc->pipe),
-                          I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
-       }
        /*
         * Apparently we need to have VGA mode enabled prior to changing
         * the P1/P2 dividers. Otherwise the DPLL will keep using the old
         * dividers, even though the register value does change.
         */
-       I915_WRITE(reg, 0);
+       I915_WRITE(reg, dpll & ~DPLL_VGA_MODE_DIS);
        I915_WRITE(reg, dpll);
  
        /* Wait for the clocks to stabilize. */
@@@ -1520,16 -1494,6 +1494,6 @@@ static void i9xx_disable_pll(const stru
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum pipe pipe = crtc->pipe;
  
-       /* Disable DVO 2x clock on both PLLs if necessary */
-       if (IS_I830(dev_priv) &&
-           intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO) &&
-           !intel_num_dvo_pipes(dev_priv)) {
-               I915_WRITE(DPLL(PIPE_B),
-                          I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE);
-               I915_WRITE(DPLL(PIPE_A),
-                          I915_READ(DPLL(PIPE_A)) & ~DPLL_DVO_2X_MODE);
-       }
        /* Don't disable pipe or pipe PLLs if needed */
        if (IS_I830(dev_priv))
                return;
@@@ -1658,14 -1622,15 +1622,15 @@@ static void ironlake_enable_pch_transco
        }
  
        val &= ~TRANS_INTERLACE_MASK;
-       if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK)
+       if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) {
                if (HAS_PCH_IBX(dev_priv) &&
                    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
                        val |= TRANS_LEGACY_INTERLACED_ILK;
                else
                        val |= TRANS_INTERLACED;
-       else
+       } else {
                val |= TRANS_PROGRESSIVE;
+       }
  
        I915_WRITE(reg, val | TRANS_ENABLE);
        if (intel_wait_for_register(dev_priv,
@@@ -1830,6 -1795,8 +1795,8 @@@ static void intel_enable_pipe(const str
                /* FIXME: assert CPU port conditions for SNB+ */
        }
  
+       trace_intel_pipe_enable(dev_priv, pipe);
        reg = PIPECONF(cpu_transcoder);
        val = I915_READ(reg);
        if (val & PIPECONF_ENABLE) {
@@@ -1869,6 -1836,8 +1836,8 @@@ static void intel_disable_pipe(const st
         */
        assert_planes_disabled(crtc);
  
+       trace_intel_pipe_disable(dev_priv, pipe);
        reg = PIPECONF(cpu_transcoder);
        val = I915_READ(reg);
        if ((val & PIPECONF_ENABLE) == 0)
@@@ -2690,11 -2659,11 +2659,11 @@@ int skl_format_to_fourcc(int format, bo
        case PLANE_CTL_FORMAT_Y216:
                return DRM_FORMAT_Y216;
        case PLANE_CTL_FORMAT_Y410:
 -              return DRM_FORMAT_Y410;
 +              return DRM_FORMAT_XVYU2101010;
        case PLANE_CTL_FORMAT_Y412:
 -              return DRM_FORMAT_Y412;
 +              return DRM_FORMAT_XVYU12_16161616;
        case PLANE_CTL_FORMAT_Y416:
 -              return DRM_FORMAT_Y416;
 +              return DRM_FORMAT_XVYU16161616;
        default:
        case PLANE_CTL_FORMAT_XRGB_8888:
                if (rgb_order) {
@@@ -2855,8 -2824,7 +2824,7 @@@ static void intel_plane_disable_noatomi
        if (plane->id == PLANE_PRIMARY)
                intel_pre_disable_primary_noatomic(&crtc->base);
  
-       trace_intel_disable_plane(&plane->base, crtc);
-       plane->disable_plane(plane, crtc_state);
+       intel_disable_plane(plane, crtc_state);
  }
  
  static void
@@@ -3260,9 -3228,10 +3228,10 @@@ static u32 i9xx_plane_ctl_crtc(const st
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        u32 dspcntr = 0;
  
-       dspcntr |= DISPPLANE_GAMMA_ENABLE;
+       if (crtc_state->gamma_enable)
+               dspcntr |= DISPPLANE_GAMMA_ENABLE;
  
-       if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+       if (crtc_state->csc_enable)
                dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
  
        if (INTEL_GEN(dev_priv) < 5)
@@@ -3489,7 -3458,7 +3458,7 @@@ static void i9xx_disable_plane(struct i
         *
         * On pre-g4x there is no way to gamma correct the
         * pipe bottom color but we'll keep on doing this
-        * anyway.
+        * anyway so that the crtc state readout works correctly.
         */
        dspcntr = i9xx_plane_ctl_crtc(crtc_state);
  
@@@ -3648,11 -3617,11 +3617,11 @@@ static u32 skl_plane_ctl_format(u32 pix
                return PLANE_CTL_FORMAT_Y212;
        case DRM_FORMAT_Y216:
                return PLANE_CTL_FORMAT_Y216;
 -      case DRM_FORMAT_Y410:
 +      case DRM_FORMAT_XVYU2101010:
                return PLANE_CTL_FORMAT_Y410;
 -      case DRM_FORMAT_Y412:
 +      case DRM_FORMAT_XVYU12_16161616:
                return PLANE_CTL_FORMAT_Y412;
 -      case DRM_FORMAT_Y416:
 +      case DRM_FORMAT_XVYU16161616:
                return PLANE_CTL_FORMAT_Y416;
        default:
                MISSING_CASE(pixel_format);
@@@ -3764,8 -3733,11 +3733,11 @@@ u32 skl_plane_ctl_crtc(const struct int
        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
                return plane_ctl;
  
-       plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
-       plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
+       if (crtc_state->gamma_enable)
+               plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
+       if (crtc_state->csc_enable)
+               plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
  
        return plane_ctl;
  }
@@@ -3817,8 -3789,11 +3789,11 @@@ u32 glk_plane_color_ctl_crtc(const stru
        if (INTEL_GEN(dev_priv) >= 11)
                return plane_color_ctl;
  
-       plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
-       plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
+       if (crtc_state->gamma_enable)
+               plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
+       if (crtc_state->csc_enable)
+               plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
  
        return plane_color_ctl;
  }
@@@ -3977,9 -3952,6 +3952,6 @@@ void intel_finish_reset(struct drm_i915
                 * The display has been reset as well,
                 * so need a full re-initialization.
                 */
-               intel_runtime_pm_disable_interrupts(dev_priv);
-               intel_runtime_pm_enable_interrupts(dev_priv);
                intel_pps_unlock_regs_wa(dev_priv);
                intel_modeset_init_hw(dev);
                intel_init_clock_gating(dev_priv);
@@@ -4019,13 -3991,13 +3991,13 @@@ static void icl_set_pipe_chicken(struc
         * and rounding for per-pixel values 00 and 0xff
         */
        tmp |= PER_PIXEL_ALPHA_BYPASS_EN;
        /*
-        * W/A for underruns with linear/X-tiled with
-        * WM1+ disabled.
+        * Display WA # 1605353570: icl
+        * Set the pixel rounding bit to 1 for allowing
+        * passthrough of Frame buffer pixels unmodified
+        * across pipe
         */
-       tmp |= PM_FILL_MAINTAIN_DBUF_FULLNESS;
+       tmp |= PIXEL_ROUNDING_TRUNC_FB_PASSTHRU;
        I915_WRITE(PIPE_CHICKEN(pipe), tmp);
  }
  
@@@ -4064,16 -4036,6 +4036,6 @@@ static void intel_update_pipe_config(co
                        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);
        if (INTEL_GEN(dev_priv) >= 11)
                icl_set_pipe_chicken(crtc);
  }
@@@ -5101,10 -5063,10 +5063,10 @@@ skl_update_scaler(struct intel_crtc_sta
        /* 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_GEN(dev_priv, 11) &&
+           (INTEL_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_GEN(dev_priv, 11) &&
+           (INTEL_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 "
@@@ -5216,9 -5178,9 +5178,9 @@@ static int skl_update_scaler_plane(stru
        case DRM_FORMAT_Y210:
        case DRM_FORMAT_Y212:
        case DRM_FORMAT_Y216:
 -      case DRM_FORMAT_Y410:
 -      case DRM_FORMAT_Y412:
 -      case DRM_FORMAT_Y416:
 +      case DRM_FORMAT_XVYU2101010:
 +      case DRM_FORMAT_XVYU12_16161616:
 +      case DRM_FORMAT_XVYU16161616:
                break;
        default:
                DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n",
@@@ -5673,7 -5635,7 +5635,7 @@@ static void intel_crtc_disable_planes(s
                    !(update_mask & BIT(plane->id)))
                        continue;
  
-               plane->disable_plane(plane, new_crtc_state);
+               intel_disable_plane(plane, new_crtc_state);
  
                if (old_plane_state->base.visible)
                        fb_bits |= plane->frontbuffer_bit;
@@@ -5824,6 -5786,14 +5786,14 @@@ static void intel_encoders_update_pipe(
        }
  }
  
+ static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_state)
+ {
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct intel_plane *plane = to_intel_plane(crtc->base.primary);
+       plane->disable_plane(plane, crtc_state);
+ }
  static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
                                 struct drm_atomic_state *old_state)
  {
         */
        intel_color_load_luts(pipe_config);
        intel_color_commit(pipe_config);
+       /* update DSPCNTR to configure gamma for pipe bottom color */
+       intel_disable_primary_plane(pipe_config);
  
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state, pipe_config);
@@@ -6017,6 -5989,9 +5989,9 @@@ static void haswell_crtc_enable(struct 
         */
        intel_color_load_luts(pipe_config);
        intel_color_commit(pipe_config);
+       /* update DSPCNTR to configure gamma/csc for pipe bottom color */
+       if (INTEL_GEN(dev_priv) < 9)
+               intel_disable_primary_plane(pipe_config);
  
        if (INTEL_GEN(dev_priv) >= 11)
                icl_set_pipe_chicken(intel_crtc);
@@@ -6197,7 -6172,7 +6172,7 @@@ bool intel_port_is_combophy(struct drm_
        if (port == PORT_NONE)
                return false;
  
-       if (IS_ICELAKE(dev_priv))
+       if (INTEL_GEN(dev_priv) >= 11)
                return port <= PORT_B;
  
        return false;
  
  bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port)
  {
-       if (IS_ICELAKE(dev_priv))
+       if (INTEL_GEN(dev_priv) >= 11)
                return port >= PORT_C && port <= PORT_F;
  
        return false;
@@@ -6374,6 -6349,8 +6349,8 @@@ static void valleyview_crtc_enable(stru
  
        intel_color_load_luts(pipe_config);
        intel_color_commit(pipe_config);
+       /* update DSPCNTR to configure gamma for pipe bottom color */
+       intel_disable_primary_plane(pipe_config);
  
        dev_priv->display.initial_watermarks(old_intel_state,
                                             pipe_config);
@@@ -6431,6 -6408,8 +6408,8 @@@ static void i9xx_crtc_enable(struct int
  
        intel_color_load_luts(pipe_config);
        intel_color_commit(pipe_config);
+       /* update DSPCNTR to configure gamma for pipe bottom color */
+       intel_disable_primary_plane(pipe_config);
  
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state,
@@@ -6813,7 -6792,13 +6792,13 @@@ static bool hsw_compute_ips_config(stru
        if (!hsw_crtc_state_ips_capable(crtc_state))
                return false;
  
-       if (crtc_state->ips_force_disable)
+       /*
+        * When IPS gets enabled, the pipe CRC changes. Since IPS gets
+        * enabled and disabled dynamically based on package C states,
+        * user space can't make reliable use of the CRCs, so let's just
+        * completely disable it.
+        */
+       if (crtc_state->crc_enabled)
                return false;
  
        /* IPS should be fine as long as at least one plane is enabled. */
@@@ -6888,8 -6873,7 +6873,7 @@@ static void intel_crtc_compute_pixel_ra
  static int intel_crtc_compute_config(struct intel_crtc *crtc,
                                     struct intel_crtc_state *pipe_config)
  {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
        int clock_limit = dev_priv->max_dotclk_freq;
  
                }
  
                if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_LVDS) &&
-                   intel_is_dual_link_lvds(dev)) {
+                   intel_is_dual_link_lvds(dev_priv)) {
                        DRM_DEBUG_KMS("Odd pipe source width not supported with dual link LVDS\n");
                        return -EINVAL;
                }
@@@ -7556,7 -7540,19 +7540,19 @@@ static void i8xx_compute_dpll(struct in
                        dpll |= PLL_P2_DIVIDE_BY_4;
        }
  
-       if (!IS_I830(dev_priv) &&
+       /*
+        * Bspec:
+        * "[Almador Errata}: For the correct operation of the muxed DVO pins
+        *  (GDEVSELB/I2Cdata, GIRDBY/I2CClk) and (GFRAMEB/DVI_Data,
+        *  GTRDYB/DVI_Clk): Bit 31 (DPLL VCO Enable) and Bit 30 (2X Clock
+        *  Enable) must be set to “1” in both the DPLL A Control Register
+        *  (06014h-06017h) and DPLL B Control Register (06018h-0601Bh)."
+        *
+        * For simplicity We simply keep both bits always enabled in
+        * both DPLLS. The spec says we should disable the DVO 2X clock
+        * when not needed, but this seems to work fine in practice.
+        */
+       if (IS_I830(dev_priv) ||
            intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO))
                dpll |= DPLL_DVO_2X_MODE;
  
@@@ -7764,13 -7760,16 +7760,16 @@@ static void i9xx_set_pipeconf(const str
                        pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
                else
                        pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT;
-       } else
+       } else {
                pipeconf |= PIPECONF_PROGRESSIVE;
+       }
  
        if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
             crtc_state->limited_color_range)
                pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
  
+       pipeconf |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
        I915_WRITE(PIPECONF(crtc->pipe), pipeconf);
        POSTING_READ(PIPECONF(crtc->pipe));
  }
@@@ -7814,8 -7813,7 +7813,7 @@@ static int i8xx_crtc_compute_clock(stru
  static int g4x_crtc_compute_clock(struct intel_crtc *crtc,
                                  struct intel_crtc_state *crtc_state)
  {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        const struct intel_limit *limit;
        int refclk = 96000;
  
                        DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
                }
  
-               if (intel_is_dual_link_lvds(dev))
+               if (intel_is_dual_link_lvds(dev_priv))
                        limit = &intel_limits_g4x_dual_channel_lvds;
                else
                        limit = &intel_limits_g4x_single_channel_lvds;
@@@ -8178,6 -8176,24 +8176,24 @@@ static void intel_get_crtc_ycbcr_config
        pipe_config->output_format = output;
  }
  
+ static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state)
+ {
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct intel_plane *plane = to_intel_plane(crtc->base.primary);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
+       u32 tmp;
+       tmp = I915_READ(DSPCNTR(i9xx_plane));
+       if (tmp & DISPPLANE_GAMMA_ENABLE)
+               crtc_state->gamma_enable = true;
+       if (!HAS_GMCH(dev_priv) &&
+           tmp & DISPPLANE_PIPE_CSC_ENABLE)
+               crtc_state->csc_enable = true;
+ }
  static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
                                 struct intel_crtc_state *pipe_config)
  {
            (tmp & PIPECONF_COLOR_RANGE_SELECT))
                pipe_config->limited_color_range = true;
  
+       pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_I9XX) >>
+               PIPECONF_GAMMA_MODE_SHIFT;
+       if (IS_CHERRYVIEW(dev_priv))
+               pipe_config->cgm_mode = I915_READ(CGM_PIPE_MODE(crtc->pipe));
+       i9xx_get_pipe_color_config(pipe_config);
        if (INTEL_GEN(dev_priv) < 4)
                pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
  
        }
        pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(crtc->pipe));
        if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
-               /*
-                * DPLL_DVO_2X_MODE must be enabled for both DPLLs
-                * on 830. Filter it out here so that we don't
-                * report errors due to that.
-                */
-               if (IS_I830(dev_priv))
-                       pipe_config->dpll_hw_state.dpll &= ~DPLL_DVO_2X_MODE;
                pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(crtc->pipe));
                pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(crtc->pipe));
        } else {
@@@ -8762,6 -8778,8 +8778,8 @@@ static void ironlake_set_pipeconf(cons
        if (crtc_state->limited_color_range)
                val |= PIPECONF_COLOR_RANGE_SELECT;
  
+       val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
        I915_WRITE(PIPECONF(pipe), val);
        POSTING_READ(PIPECONF(pipe));
  }
@@@ -8842,13 -8860,11 +8860,11 @@@ static bool ironlake_needs_fb_cb_tune(s
        return i9xx_dpll_compute_m(dpll) < factor * dpll->n;
  }
  
- static void ironlake_compute_dpll(struct intel_crtc *intel_crtc,
+ static void ironlake_compute_dpll(struct intel_crtc *crtc,
                                  struct intel_crtc_state *crtc_state,
                                  struct dpll *reduced_clock)
  {
-       struct drm_crtc *crtc = &intel_crtc->base;
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        u32 dpll, fp, fp2;
        int factor;
  
        if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
                if ((intel_panel_use_ssc(dev_priv) &&
                     dev_priv->vbt.lvds_ssc_freq == 100000) ||
-                   (HAS_PCH_IBX(dev_priv) && intel_is_dual_link_lvds(dev)))
+                   (HAS_PCH_IBX(dev_priv) &&
+                    intel_is_dual_link_lvds(dev_priv)))
                        factor = 25;
-       } else if (crtc_state->sdvo_tv_clock)
+       } else if (crtc_state->sdvo_tv_clock) {
                factor = 20;
+       }
  
        fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
  
  static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
                                       struct intel_crtc_state *crtc_state)
  {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        const struct intel_limit *limit;
        int refclk = 120000;
  
                        refclk = dev_priv->vbt.lvds_ssc_freq;
                }
  
-               if (intel_is_dual_link_lvds(dev)) {
+               if (intel_is_dual_link_lvds(dev_priv)) {
                        if (refclk == 100000)
                                limit = &intel_limits_ironlake_dual_lvds_100m;
                        else
  
        ironlake_compute_dpll(crtc, crtc_state, NULL);
  
-       if (!intel_get_shared_dpll(crtc, crtc_state, NULL)) {
+       if (!intel_get_shared_dpll(crtc_state, NULL)) {
                DRM_DEBUG_KMS("failed to find PLL for pipe %c\n",
                              pipe_name(crtc->pipe));
                return -EINVAL;
@@@ -9296,6 -9313,13 +9313,13 @@@ static bool ironlake_get_pipe_config(st
        if (tmp & PIPECONF_COLOR_RANGE_SELECT)
                pipe_config->limited_color_range = true;
  
+       pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_ILK) >>
+               PIPECONF_GAMMA_MODE_SHIFT;
+       pipe_config->csc_mode = I915_READ(PIPE_CSC_MODE(crtc->pipe));
+       i9xx_get_pipe_color_config(pipe_config);
        if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
                struct intel_shared_dpll *pll;
                enum intel_dpll_id pll_id;
@@@ -9580,11 -9604,11 +9604,11 @@@ static int haswell_crtc_compute_clock(s
                to_intel_atomic_state(crtc_state->base.state);
  
        if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
-           IS_ICELAKE(dev_priv)) {
+           INTEL_GEN(dev_priv) >= 11) {
                struct intel_encoder *encoder =
                        intel_get_crtc_new_encoder(state, crtc_state);
  
-               if (!intel_get_shared_dpll(crtc, crtc_state, encoder)) {
+               if (!intel_get_shared_dpll(crtc_state, encoder)) {
                        DRM_DEBUG_KMS("failed to find PLL for pipe %c\n",
                                      pipe_name(crtc->pipe));
                        return -EINVAL;
@@@ -9622,9 -9646,6 +9646,6 @@@ static void icelake_get_ddi_pll(struct 
                temp = I915_READ(DPCLKA_CFGCR0_ICL) &
                       DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
                id = temp >> DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port);
-               if (WARN_ON(!intel_dpll_is_combophy(id)))
-                       return;
        } else if (intel_port_is_tc(dev_priv, port)) {
                id = icl_tc_port_to_pll_id(intel_port_to_tc(dev_priv, port));
        } else {
@@@ -9718,15 -9739,18 +9739,18 @@@ static bool hsw_get_transcoder_state(st
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        enum intel_display_power_domain power_domain;
-       unsigned long panel_transcoder_mask = BIT(TRANSCODER_EDP);
+       unsigned long panel_transcoder_mask = 0;
        unsigned long enabled_panel_transcoders = 0;
        enum transcoder panel_transcoder;
        u32 tmp;
  
-       if (IS_ICELAKE(dev_priv))
+       if (INTEL_GEN(dev_priv) >= 11)
                panel_transcoder_mask |=
                        BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1);
  
+       if (HAS_TRANSCODER_EDP(dev_priv))
+               panel_transcoder_mask |= BIT(TRANSCODER_EDP);
        /*
         * The pipe->transcoder mapping is fixed with the exception of the eDP
         * and DSI transcoders handled below.
@@@ -9856,7 -9880,7 +9880,7 @@@ static void haswell_get_ddi_port_state(
  
        port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
  
-       if (IS_ICELAKE(dev_priv))
+       if (INTEL_GEN(dev_priv) >= 11)
                icelake_get_ddi_pll(dev_priv, port, pipe_config);
        else if (IS_CANNONLAKE(dev_priv))
                cannonlake_get_ddi_pll(dev_priv, port, pipe_config);
@@@ -9919,7 -9943,7 +9943,7 @@@ static bool haswell_get_pipe_config(str
                goto out;
  
        if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
-           IS_ICELAKE(dev_priv)) {
+           INTEL_GEN(dev_priv) >= 11) {
                haswell_get_ddi_port_state(crtc, pipe_config);
                intel_get_pipe_timings(crtc, pipe_config);
        }
        intel_get_pipe_src_size(crtc, pipe_config);
        intel_get_crtc_ycbcr_config(crtc, pipe_config);
  
-       pipe_config->gamma_mode =
-               I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
+       pipe_config->gamma_mode = I915_READ(GAMMA_MODE(crtc->pipe));
+       pipe_config->csc_mode = I915_READ(PIPE_CSC_MODE(crtc->pipe));
+       if (INTEL_GEN(dev_priv) >= 9) {
+               u32 tmp = I915_READ(SKL_BOTTOM_COLOR(crtc->pipe));
+               if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
+                       pipe_config->gamma_enable = true;
+               if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
+                       pipe_config->csc_enable = true;
+       } else {
+               i9xx_get_pipe_color_config(pipe_config);
+       }
  
        power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
        if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
@@@ -10100,7 -10137,12 +10137,12 @@@ i845_cursor_max_stride(struct intel_pla
  
  static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
  {
-       return CURSOR_GAMMA_ENABLE;
+       u32 cntl = 0;
+       if (crtc_state->gamma_enable)
+               cntl |= CURSOR_GAMMA_ENABLE;
+       return cntl;
  }
  
  static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
@@@ -10254,9 -10296,10 +10296,10 @@@ static u32 i9xx_cursor_ctl_crtc(const s
        if (INTEL_GEN(dev_priv) >= 11)
                return cntl;
  
-       cntl |= MCURSOR_GAMMA_ENABLE;
+       if (crtc_state->gamma_enable)
+               cntl = MCURSOR_GAMMA_ENABLE;
  
-       if (HAS_DDI(dev_priv))
+       if (crtc_state->csc_enable)
                cntl |= MCURSOR_PIPE_CSC_ENABLE;
  
        if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
@@@ -11245,16 -11288,11 +11288,11 @@@ static int intel_crtc_atomic_check(stru
                        return ret;
        }
  
-       if (mode_changed || crtc_state->color_mgmt_changed) {
+       if (mode_changed || pipe_config->update_pipe ||
+           crtc_state->color_mgmt_changed) {
                ret = intel_color_check(pipe_config);
                if (ret)
                        return ret;
-               /*
-                * Changing color management on Intel hardware is
-                * handled as part of planes update.
-                */
-               crtc_state->planes_changed = true;
        }
  
        ret = 0;
@@@ -11425,6 -11463,16 +11463,16 @@@ intel_dump_m_n_config(struct intel_crtc
                      m_n->link_m, m_n->link_n, m_n->tu);
  }
  
+ static void
+ intel_dump_infoframe(struct drm_i915_private *dev_priv,
+                    const union hdmi_infoframe *frame)
+ {
+       if ((drm_debug & DRM_UT_KMS) == 0)
+               return;
+       hdmi_infoframe_log(KERN_DEBUG, dev_priv->drm.dev, frame);
+ }
  #define OUTPUT_TYPE(x) [INTEL_OUTPUT_ ## x] = #x
  
  static const char * const output_type_str[] = {
@@@ -11528,6 -11576,22 +11576,22 @@@ static void intel_dump_pipe_config(stru
        DRM_DEBUG_KMS("audio: %i, infoframes: %i\n",
                      pipe_config->has_audio, pipe_config->has_infoframe);
  
+       DRM_DEBUG_KMS("infoframes enabled: 0x%x\n",
+                     pipe_config->infoframes.enable);
+       if (pipe_config->infoframes.enable &
+           intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL))
+               DRM_DEBUG_KMS("GCP: 0x%x\n", pipe_config->infoframes.gcp);
+       if (pipe_config->infoframes.enable &
+           intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI))
+               intel_dump_infoframe(dev_priv, &pipe_config->infoframes.avi);
+       if (pipe_config->infoframes.enable &
+           intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD))
+               intel_dump_infoframe(dev_priv, &pipe_config->infoframes.spd);
+       if (pipe_config->infoframes.enable &
+           intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_VENDOR))
+               intel_dump_infoframe(dev_priv, &pipe_config->infoframes.hdmi);
        DRM_DEBUG_KMS("requested mode:\n");
        drm_mode_debug_printmodeline(&pipe_config->base.mode);
        DRM_DEBUG_KMS("adjusted mode:\n");
@@@ -11676,7 -11740,7 +11740,7 @@@ clear_intel_crtc_state(struct intel_crt
        saved_state->shared_dpll = crtc_state->shared_dpll;
        saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
        saved_state->pch_pfit.force_thru = crtc_state->pch_pfit.force_thru;
-       saved_state->ips_force_disable = crtc_state->ips_force_disable;
+       saved_state->crc_enabled = crtc_state->crc_enabled;
        if (IS_G4X(dev_priv) ||
            IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                saved_state->wm = crtc_state->wm;
@@@ -11895,6 -11959,37 +11959,37 @@@ intel_compare_link_m_n(const struct int
        return false;
  }
  
+ static bool
+ intel_compare_infoframe(const union hdmi_infoframe *a,
+                       const union hdmi_infoframe *b)
+ {
+       return memcmp(a, b, sizeof(*a)) == 0;
+ }
+ static void
+ pipe_config_infoframe_err(struct drm_i915_private *dev_priv,
+                         bool adjust, const char *name,
+                         const union hdmi_infoframe *a,
+                         const union hdmi_infoframe *b)
+ {
+       if (adjust) {
+               if ((drm_debug & DRM_UT_KMS) == 0)
+                       return;
+               drm_dbg(DRM_UT_KMS, "mismatch in %s infoframe", name);
+               drm_dbg(DRM_UT_KMS, "expected:");
+               hdmi_infoframe_log(KERN_DEBUG, dev_priv->drm.dev, a);
+               drm_dbg(DRM_UT_KMS, "found");
+               hdmi_infoframe_log(KERN_DEBUG, dev_priv->drm.dev, b);
+       } else {
+               drm_err("mismatch in %s infoframe", name);
+               drm_err("expected:");
+               hdmi_infoframe_log(KERN_ERR, dev_priv->drm.dev, a);
+               drm_err("found");
+               hdmi_infoframe_log(KERN_ERR, dev_priv->drm.dev, b);
+       }
+ }
  static void __printf(3, 4)
  pipe_config_err(bool adjust, const char *name, const char *format, ...)
  {
@@@ -12078,7 -12173,17 +12173,17 @@@ intel_pipe_config_compare(struct drm_i9
        } \
  } while (0)
  
- #define PIPE_CONF_QUIRK(quirk)        \
+ #define PIPE_CONF_CHECK_INFOFRAME(name) do { \
+       if (!intel_compare_infoframe(&current_config->infoframes.name, \
+                                    &pipe_config->infoframes.name)) { \
+               pipe_config_infoframe_err(dev_priv, adjust, __stringify(name), \
+                                         &current_config->infoframes.name, \
+                                         &pipe_config->infoframes.name); \
+               ret = false; \
+       } \
+ } while (0)
+ #define PIPE_CONF_QUIRK(quirk) \
        ((current_config->quirks | pipe_config->quirks) & (quirk))
  
        PIPE_CONF_CHECK_I(cpu_transcoder);
  
                PIPE_CONF_CHECK_I(scaler_state.scaler_id);
                PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
+               PIPE_CONF_CHECK_X(gamma_mode);
+               if (IS_CHERRYVIEW(dev_priv))
+                       PIPE_CONF_CHECK_X(cgm_mode);
+               else
+                       PIPE_CONF_CHECK_X(csc_mode);
+               PIPE_CONF_CHECK_BOOL(gamma_enable);
+               PIPE_CONF_CHECK_BOOL(csc_enable);
        }
  
        PIPE_CONF_CHECK_BOOL(double_wide);
  
        PIPE_CONF_CHECK_I(min_voltage_level);
  
+       PIPE_CONF_CHECK_X(infoframes.enable);
+       PIPE_CONF_CHECK_X(infoframes.gcp);
+       PIPE_CONF_CHECK_INFOFRAME(avi);
+       PIPE_CONF_CHECK_INFOFRAME(spd);
+       PIPE_CONF_CHECK_INFOFRAME(hdmi);
  #undef PIPE_CONF_CHECK_X
  #undef PIPE_CONF_CHECK_I
  #undef PIPE_CONF_CHECK_BOOL
@@@ -12241,12 -12360,15 +12360,15 @@@ static void verify_wm_state(struct drm_
                            struct drm_crtc_state *new_state)
  {
        struct drm_i915_private *dev_priv = to_i915(crtc->dev);
-       struct skl_ddb_allocation hw_ddb, *sw_ddb;
-       struct skl_pipe_wm hw_wm, *sw_wm;
-       struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
+       struct skl_hw_state {
+               struct skl_ddb_entry ddb_y[I915_MAX_PLANES];
+               struct skl_ddb_entry ddb_uv[I915_MAX_PLANES];
+               struct skl_ddb_allocation ddb;
+               struct skl_pipe_wm wm;
+       } *hw;
+       struct skl_ddb_allocation *sw_ddb;
+       struct skl_pipe_wm *sw_wm;
        struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
-       struct skl_ddb_entry hw_ddb_y[I915_MAX_PLANES];
-       struct skl_ddb_entry hw_ddb_uv[I915_MAX_PLANES];
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        const enum pipe pipe = intel_crtc->pipe;
        int plane, level, max_level = ilk_wm_max_level(dev_priv);
        if (INTEL_GEN(dev_priv) < 9 || !new_state->active)
                return;
  
-       skl_pipe_wm_get_hw_state(intel_crtc, &hw_wm);
+       hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+       if (!hw)
+               return;
+       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);
+       skl_pipe_ddb_get_hw_state(intel_crtc, hw->ddb_y, hw->ddb_uv);
  
-       skl_ddb_get_hw_state(dev_priv, &hw_ddb);
+       skl_ddb_get_hw_state(dev_priv, &hw->ddb);
        sw_ddb = &dev_priv->wm.skl_hw.ddb;
  
-       if (INTEL_GEN(dev_priv) >= 11)
-               if (hw_ddb.enabled_slices != sw_ddb->enabled_slices)
-                       DRM_ERROR("mismatch in DBUF Slices (expected %u, got %u)\n",
-                                 sw_ddb->enabled_slices,
-                                 hw_ddb.enabled_slices);
+       if (INTEL_GEN(dev_priv) >= 11 &&
+           hw->ddb.enabled_slices != sw_ddb->enabled_slices)
+               DRM_ERROR("mismatch in DBUF Slices (expected %u, got %u)\n",
+                         sw_ddb->enabled_slices,
+                         hw->ddb.enabled_slices);
        /* planes */
        for_each_universal_plane(dev_priv, pipe, plane) {
-               hw_plane_wm = &hw_wm.planes[plane];
+               struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
+               hw_plane_wm = &hw->wm.planes[plane];
                sw_plane_wm = &sw_wm->planes[plane];
  
                /* Watermarks */
                }
  
                /* DDB */
-               hw_ddb_entry = &hw_ddb_y[plane];
+               hw_ddb_entry = &hw->ddb_y[plane];
                sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[plane];
  
                if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
         * once the plane becomes visible, we can skip this check
         */
        if (1) {
-               hw_plane_wm = &hw_wm.planes[PLANE_CURSOR];
+               struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
+               hw_plane_wm = &hw->wm.planes[PLANE_CURSOR];
                sw_plane_wm = &sw_wm->planes[PLANE_CURSOR];
  
                /* Watermarks */
                }
  
                /* DDB */
-               hw_ddb_entry = &hw_ddb_y[PLANE_CURSOR];
+               hw_ddb_entry = &hw->ddb_y[PLANE_CURSOR];
                sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[PLANE_CURSOR];
  
                if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
                                  hw_ddb_entry->start, hw_ddb_entry->end);
                }
        }
+       kfree(hw);
  }
  
  static void
@@@ -12517,7 -12650,8 +12650,8 @@@ intel_verify_planes(struct intel_atomic
  
        for_each_new_intel_plane_in_state(state, plane,
                                          plane_state, i)
-               assert_plane(plane, plane_state->base.visible);
+               assert_plane(plane, plane_state->slave ||
+                            plane_state->base.visible);
  }
  
  static void
@@@ -13576,7 -13710,7 +13710,7 @@@ static int do_rps_boost(struct wait_que
         * vblank without our intervention, so leave RPS alone.
         */
        if (!i915_request_started(rq))
-               gen6_rps_boost(rq, NULL);
+               gen6_rps_boost(rq);
        i915_request_put(rq);
  
        drm_crtc_vblank_put(wait->crtc);
@@@ -14109,14 -14243,11 +14243,11 @@@ intel_legacy_cursor_update(struct drm_p
         */
        crtc_state->active_planes = new_crtc_state->active_planes;
  
-       if (plane->state->visible) {
-               trace_intel_update_plane(plane, to_intel_crtc(crtc));
-               intel_plane->update_plane(intel_plane, crtc_state,
-                                         to_intel_plane_state(plane->state));
-       } else {
-               trace_intel_disable_plane(plane, to_intel_crtc(crtc));
-               intel_plane->disable_plane(intel_plane, crtc_state);
-       }
+       if (plane->state->visible)
+               intel_update_plane(intel_plane, crtc_state,
+                                  to_intel_plane_state(plane->state));
+       else
+               intel_disable_plane(intel_plane, crtc_state);
  
        intel_plane_unpin_fb(to_intel_plane_state(old_plane_state));
  
@@@ -14566,7 -14697,7 +14697,7 @@@ static void intel_setup_outputs(struct 
        if (!HAS_DISPLAY(dev_priv))
                return;
  
-       if (IS_ICELAKE(dev_priv)) {
+       if (INTEL_GEN(dev_priv) >= 11) {
                intel_ddi_init(dev_priv, PORT_A);
                intel_ddi_init(dev_priv, PORT_B);
                intel_ddi_init(dev_priv, PORT_C);
@@@ -15467,6 -15598,8 +15598,8 @@@ int intel_modeset_init(struct drm_devic
        intel_update_czclk(dev_priv);
        intel_modeset_init_hw(dev);
  
+       intel_hdcp_component_init(dev_priv);
        if (dev_priv->max_cdclk_freq == 0)
                intel_update_max_cdclk(dev_priv);
  
@@@ -15542,7 -15675,7 +15675,7 @@@ void i830_enable_pipe(struct drm_i915_p
                      pipe_name(pipe), clock.vco, clock.dot);
  
        fp = i9xx_dpll_compute_fp(&clock);
-       dpll = (I915_READ(DPLL(pipe)) & DPLL_DVO_2X_MODE) |
+       dpll = DPLL_DVO_2X_MODE |
                DPLL_VGA_MODE_DIS |
                ((clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT) |
                PLL_P2_DIVIDE_BY_4 |
@@@ -16328,6 -16461,8 +16461,8 @@@ void intel_modeset_cleanup(struct drm_d
        /* flush any delayed tasks or pending work */
        flush_scheduled_work();
  
+       intel_hdcp_component_fini(dev_priv);
        drm_mode_config_cleanup(dev);
  
        intel_overlay_cleanup(dev_priv);
@@@ -16374,8 -16509,6 +16509,6 @@@ struct intel_display_error_state 
  
        u32 power_well_driver;
  
-       int num_transcoders;
        struct intel_cursor_error_state {
                u32 control;
                u32 position;
        } plane[I915_MAX_PIPES];
  
        struct intel_transcoder_error_state {
+               bool available;
                bool power_domain_on;
                enum transcoder cpu_transcoder;
  
@@@ -16426,6 -16560,8 +16560,8 @@@ intel_display_capture_error_state(struc
        };
        int i;
  
+       BUILD_BUG_ON(ARRAY_SIZE(transcoders) != ARRAY_SIZE(error->transcoder));
        if (!HAS_DISPLAY(dev_priv))
                return NULL;
  
                        error->pipe[i].stat = I915_READ(PIPESTAT(i));
        }
  
-       /* Note: this does not include DSI transcoders. */
-       error->num_transcoders = INTEL_INFO(dev_priv)->num_pipes;
-       if (HAS_DDI(dev_priv))
-               error->num_transcoders++; /* Account for eDP. */
-       for (i = 0; i < error->num_transcoders; i++) {
+       for (i = 0; i < ARRAY_SIZE(error->transcoder); i++) {
                enum transcoder cpu_transcoder = transcoders[i];
  
+               if (!INTEL_INFO(dev_priv)->trans_offsets[cpu_transcoder])
+                       continue;
+               error->transcoder[i].available = true;
                error->transcoder[i].power_domain_on =
                        __intel_display_power_is_enabled(dev_priv,
                                POWER_DOMAIN_TRANSCODER(cpu_transcoder));
@@@ -16537,7 -16672,10 +16672,10 @@@ intel_display_print_error_state(struct 
                err_printf(m, "  BASE: %08x\n", error->cursor[i].base);
        }
  
-       for (i = 0; i < error->num_transcoders; i++) {
+       for (i = 0; i < ARRAY_SIZE(error->transcoder); i++) {
+               if (!error->transcoder[i].available)
+                       continue;
                err_printf(m, "CPU transcoder: %s\n",
                           transcoder_name(error->transcoder[i].cpu_transcoder));
                err_printf(m, "  Power: %s\n",
index 375f51d14dda344d9256429249c1bbb601bb5fd3,0ffa083a7af7e7a84e87da30f2b9419c053fbdd1..4d7ae579fc92d2dfd3e32ec1ab065ed69a1e6943
@@@ -41,6 -41,7 +41,7 @@@
  #include <drm/drm_rect.h>
  #include <drm/drm_vblank.h>
  #include <drm/drm_atomic.h>
+ #include <drm/i915_mei_hdcp_interface.h>
  #include <media/cec-notifier.h>
  
  struct drm_printer;
@@@ -323,6 -324,13 +324,13 @@@ struct intel_panel 
  
  struct intel_digital_port;
  
+ enum check_link_response {
+       HDCP_LINK_PROTECTED     = 0,
+       HDCP_TOPOLOGY_CHANGE,
+       HDCP_LINK_INTEGRITY_FAILURE,
+       HDCP_REAUTH_REQUEST
+ };
  /*
   * This structure serves as a translation layer between the generic HDCP code
   * and the bus-specific code. What that means is that HDCP over HDMI differs
@@@ -395,6 -403,32 +403,32 @@@ struct intel_hdcp_shim 
        /* Detects panel's hdcp capability. This is optional for HDMI. */
        int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
                            bool *hdcp_capable);
+       /* HDCP adaptation(DP/HDMI) required on the port */
+       enum hdcp_wired_protocol protocol;
+       /* Detects whether sink is HDCP2.2 capable */
+       int (*hdcp_2_2_capable)(struct intel_digital_port *intel_dig_port,
+                               bool *capable);
+       /* Write HDCP2.2 messages */
+       int (*write_2_2_msg)(struct intel_digital_port *intel_dig_port,
+                            void *buf, size_t size);
+       /* Read HDCP2.2 messages */
+       int (*read_2_2_msg)(struct intel_digital_port *intel_dig_port,
+                           u8 msg_id, void *buf, size_t size);
+       /*
+        * Implementation of DP HDCP2.2 Errata for the communication of stream
+        * type to Receivers. In DP HDCP2.2 Stream type is one of the input to
+        * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI.
+        */
+       int (*config_stream_type)(struct intel_digital_port *intel_dig_port,
+                                 bool is_repeater, u8 type);
+       /* HDCP2.2 Link Integrity Check */
+       int (*check_2_2_link)(struct intel_digital_port *intel_dig_port);
  };
  
  struct intel_hdcp {
        u64 value;
        struct delayed_work check_work;
        struct work_struct prop_work;
+       /* HDCP1.4 Encryption status */
+       bool hdcp_encrypted;
+       /* HDCP2.2 related definitions */
+       /* Flag indicates whether this connector supports HDCP2.2 or not. */
+       bool hdcp2_supported;
+       /* HDCP2.2 Encryption status */
+       bool hdcp2_encrypted;
+       /*
+        * Content Stream Type defined by content owner. TYPE0(0x0) content can
+        * flow in the link protected by HDCP2.2 or HDCP1.4, where as TYPE1(0x1)
+        * content can flow only through a link protected by HDCP2.2.
+        */
+       u8 content_type;
+       struct hdcp_port_data port_data;
+       bool is_paired;
+       bool is_repeater;
+       /*
+        * Count of ReceiverID_List received. Initialized to 0 at AKE_INIT.
+        * Incremented after processing the RepeaterAuth_Send_ReceiverID_List.
+        * When it rolls over re-auth has to be triggered.
+        */
+       u32 seq_num_v;
+       /*
+        * Count of RepeaterAuth_Stream_Manage msg propagated.
+        * Initialized to 0 on AKE_INIT. Incremented after every successful
+        * transmission of RepeaterAuth_Stream_Manage message. When it rolls
+        * over re-Auth has to be triggered.
+        */
+       u32 seq_num_m;
+       /*
+        * Work queue to signal the CP_IRQ. Used for the waiters to read the
+        * available information from HDCP DP sink.
+        */
+       wait_queue_head_t cp_irq_queue;
+       atomic_t cp_irq_count;
+       int cp_irq_count_cached;
  };
  
  struct intel_connector {
@@@ -921,7 -999,8 +999,8 @@@ struct intel_crtc_state 
        struct intel_link_m_n fdi_m_n;
  
        bool ips_enabled;
-       bool ips_force_disable;
+       bool crc_enabled;
  
        bool enable_fbc;
  
        /* Gamma mode programmed on the pipe */
        u32 gamma_mode;
  
+       union {
+               /* CSC mode programmed on the pipe */
+               u32 csc_mode;
+               /* CHV CGM mode */
+               u32 cgm_mode;
+       };
        /* bitmask of visible planes (enum plane_id) */
        u8 active_planes;
        u8 nv12_planes;
+       u8 c8_planes;
  
        /* bitmask of planes that will be updated during the commit */
        u8 update_planes;
  
+       struct {
+               u32 enable;
+               u32 gcp;
+               union hdmi_infoframe avi;
+               union hdmi_infoframe spd;
+               union hdmi_infoframe hdmi;
+       } infoframes;
        /* HDMI scrambling status */
        bool hdmi_scrambling;
  
        /* Output down scaling is done in LSPCON device */
        bool lspcon_downsampling;
  
+       /* enable pipe gamma? */
+       bool gamma_enable;
+       /* enable pipe csc? */
+       bool csc_enable;
        /* Display Stream compression state */
        struct {
                bool compression_enable;
@@@ -989,9 -1091,6 +1091,6 @@@ struct intel_crtc 
  
        struct intel_crtc_state *config;
  
-       /* global reset count when the last flip was submitted */
-       unsigned int reset_count;
        /* Access to these should be protected by dev_priv->irq_lock. */
        bool cpu_fifo_underrun_disabled;
        bool pch_fifo_underrun_disabled;
@@@ -1260,11 -1359,15 +1359,15 @@@ struct intel_digital_port 
                                const struct intel_crtc_state *crtc_state,
                                unsigned int type,
                                const void *frame, ssize_t len);
+       void (*read_infoframe)(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *crtc_state,
+                              unsigned int type,
+                              void *frame, ssize_t len);
        void (*set_infoframes)(struct intel_encoder *encoder,
                               bool enable,
                               const struct intel_crtc_state *crtc_state,
                               const struct drm_connector_state *conn_state);
-       bool (*infoframe_enabled)(struct intel_encoder *encoder,
+       u32 (*infoframes_enabled)(struct intel_encoder *encoder,
                                  const struct intel_crtc_state *pipe_config);
  };
  
@@@ -1738,7 -1841,7 +1841,7 @@@ void intel_dp_get_m_n(struct intel_crt
  void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state,
                      enum link_m_n_set m_n);
  int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
- bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
+ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
                        struct dpll *best_clock);
  int chv_calc_dpll_params(int refclk, struct dpll *pll_clock);
  
@@@ -1796,7 -1899,6 +1899,7 @@@ int intel_ddc_get_modes(struct drm_conn
  void intel_attach_force_audio_property(struct drm_connector *connector);
  void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
  void intel_attach_aspect_ratio_property(struct drm_connector *connector);
 +void intel_attach_colorspace_property(struct drm_connector *connector);
  
  /* intel_csr.c */
  void intel_csr_ucode_init(struct drm_i915_private *);
@@@ -2000,13 -2102,22 +2103,22 @@@ bool intel_hdmi_handle_sink_scrambling(
                                       bool scrambling);
  void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
  void intel_infoframe_init(struct intel_digital_port *intel_dig_port);
+ u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
+                                 const struct intel_crtc_state *crtc_state);
+ u32 intel_hdmi_infoframe_enable(unsigned int type);
+ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
+                                  struct intel_crtc_state *crtc_state);
+ void intel_read_infoframe(struct intel_encoder *encoder,
+                         const struct intel_crtc_state *crtc_state,
+                         enum hdmi_infoframe_type type,
+                         union hdmi_infoframe *frame);
  
  /* intel_lvds.c */
  bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv,
                             i915_reg_t lvds_reg, enum pipe *pipe);
  void intel_lvds_init(struct drm_i915_private *dev_priv);
- struct intel_encoder *intel_get_lvds_encoder(struct drm_device *dev);
- bool intel_is_dual_link_lvds(struct drm_device *dev);
+ struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *dev_priv);
+ bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv);
  
  /* intel_overlay.c */
  void intel_overlay_setup(struct drm_i915_private *dev_priv);
@@@ -2068,9 -2179,12 +2180,12 @@@ int intel_hdcp_init(struct intel_connec
                    const struct intel_hdcp_shim *hdcp_shim);
  int intel_hdcp_enable(struct intel_connector *connector);
  int intel_hdcp_disable(struct intel_connector *connector);
- int intel_hdcp_check_link(struct intel_connector *connector);
  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
  bool intel_hdcp_capable(struct intel_connector *connector);
+ void intel_hdcp_component_init(struct drm_i915_private *dev_priv);
+ void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
+ void intel_hdcp_cleanup(struct intel_connector *connector);
+ void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
  
  /* intel_psr.c */
  #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
@@@ -2079,9 -2193,9 +2194,9 @@@ void intel_psr_enable(struct intel_dp *
                      const struct intel_crtc_state *crtc_state);
  void intel_psr_disable(struct intel_dp *intel_dp,
                      const struct intel_crtc_state *old_crtc_state);
int intel_psr_set_debugfs_mode(struct drm_i915_private *dev_priv,
-                              struct drm_modeset_acquire_ctx *ctx,
                             u64 value);
void intel_psr_update(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state);
int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value);
  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
                          unsigned frontbuffer_bits,
                          enum fb_op_origin origin);
@@@ -2261,7 -2375,7 +2376,7 @@@ void intel_suspend_gt_powersave(struct 
  void gen6_rps_busy(struct drm_i915_private *dev_priv);
  void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
  void gen6_rps_idle(struct drm_i915_private *dev_priv);
- void gen6_rps_boost(struct i915_request *rq, struct intel_rps_client *rps);
+ void gen6_rps_boost(struct i915_request *rq);
  void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv);
  void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv);
  void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv);
@@@ -2375,6 -2489,14 +2490,14 @@@ int intel_atomic_setup_scalers(struct d
                               struct intel_crtc_state *crtc_state);
  
  /* intel_atomic_plane.c */
+ void intel_update_plane(struct intel_plane *plane,
+                       const struct intel_crtc_state *crtc_state,
+                       const struct intel_plane_state *plane_state);
+ void intel_update_slave(struct intel_plane *plane,
+                       const struct intel_crtc_state *crtc_state,
+                       const struct intel_plane_state *plane_state);
+ void intel_disable_plane(struct intel_plane *plane,
+                        const struct intel_crtc_state *crtc_state);
  struct intel_plane *intel_plane_alloc(void);
  void intel_plane_free(struct intel_plane *plane);
  struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
@@@ -2404,11 -2526,15 +2527,15 @@@ void lspcon_write_infoframe(struct inte
                            const struct intel_crtc_state *crtc_state,
                            unsigned int type,
                            const void *buf, ssize_t len);
+ void lspcon_read_infoframe(struct intel_encoder *encoder,
+                          const struct intel_crtc_state *crtc_state,
+                          unsigned int type,
+                          void *frame, ssize_t len);
  void lspcon_set_infoframes(struct intel_encoder *encoder,
                           bool enable,
                           const struct intel_crtc_state *crtc_state,
                           const struct drm_connector_state *conn_state);
bool lspcon_infoframe_enabled(struct intel_encoder *encoder,
u32 lspcon_infoframes_enabled(struct intel_encoder *encoder,
                              const struct intel_crtc_state *pipe_config);
  void lspcon_ycbcr420_config(struct drm_connector *connector,
                            struct intel_crtc_state *crtc_state);
index 765718b606d857a9993a91bfff92365452599f1e,07893ad2ad1f93c0c56e07a1bf69def94adfc349..26767785f14aa2d9120e53641f5f03752c90731a
@@@ -82,6 -82,8 +82,8 @@@ static struct intel_hdmi *intel_attache
  static u32 g4x_infoframe_index(unsigned int type)
  {
        switch (type) {
+       case HDMI_PACKET_TYPE_GAMUT_METADATA:
+               return VIDEO_DIP_SELECT_GAMUT;
        case HDMI_INFOFRAME_TYPE_AVI:
                return VIDEO_DIP_SELECT_AVI;
        case HDMI_INFOFRAME_TYPE_SPD:
  static u32 g4x_infoframe_enable(unsigned int type)
  {
        switch (type) {
+       case HDMI_PACKET_TYPE_GENERAL_CONTROL:
+               return VIDEO_DIP_ENABLE_GCP;
+       case HDMI_PACKET_TYPE_GAMUT_METADATA:
+               return VIDEO_DIP_ENABLE_GAMUT;
+       case DP_SDP_VSC:
+               return 0;
        case HDMI_INFOFRAME_TYPE_AVI:
                return VIDEO_DIP_ENABLE_AVI;
        case HDMI_INFOFRAME_TYPE_SPD:
  static u32 hsw_infoframe_enable(unsigned int type)
  {
        switch (type) {
+       case HDMI_PACKET_TYPE_GENERAL_CONTROL:
+               return VIDEO_DIP_ENABLE_GCP_HSW;
+       case HDMI_PACKET_TYPE_GAMUT_METADATA:
+               return VIDEO_DIP_ENABLE_GMP_HSW;
        case DP_SDP_VSC:
                return VIDEO_DIP_ENABLE_VSC_HSW;
        case DP_SDP_PPS:
@@@ -135,6 -147,8 +147,8 @@@ hsw_dip_data_reg(struct drm_i915_privat
                 int i)
  {
        switch (type) {
+       case HDMI_PACKET_TYPE_GAMUT_METADATA:
+               return HSW_TVIDEO_DIP_GMP_DATA(cpu_transcoder, i);
        case DP_SDP_VSC:
                return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i);
        case DP_SDP_PPS:
@@@ -200,17 -214,37 +214,37 @@@ static void g4x_write_infoframe(struct 
        POSTING_READ(VIDEO_DIP_CTL);
  }
  
- static bool g4x_infoframe_enabled(struct intel_encoder *encoder,
+ static void g4x_read_infoframe(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *crtc_state,
+                              unsigned int type,
+                              void *frame, ssize_t len)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       u32 val, *data = frame;
+       int i;
+       val = I915_READ(VIDEO_DIP_CTL);
+       val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+       val |= g4x_infoframe_index(type);
+       I915_WRITE(VIDEO_DIP_CTL, val);
+       for (i = 0; i < len; i += 4)
+               *data++ = I915_READ(VIDEO_DIP_DATA);
+ }
+ static u32 g4x_infoframes_enabled(struct intel_encoder *encoder,
                                  const struct intel_crtc_state *pipe_config)
  {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 val = I915_READ(VIDEO_DIP_CTL);
  
        if ((val & VIDEO_DIP_ENABLE) == 0)
-               return false;
+               return 0;
  
        if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(encoder->port))
-               return false;
+               return 0;
  
        return val & (VIDEO_DIP_ENABLE_AVI |
                      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_SPD);
@@@ -255,7 -289,28 +289,28 @@@ static void ibx_write_infoframe(struct 
        POSTING_READ(reg);
  }
  
- static bool ibx_infoframe_enabled(struct intel_encoder *encoder,
+ static void ibx_read_infoframe(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *crtc_state,
+                              unsigned int type,
+                              void *frame, ssize_t len)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       u32 val, *data = frame;
+       int i;
+       val = I915_READ(TVIDEO_DIP_CTL(crtc->pipe));
+       val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+       val |= g4x_infoframe_index(type);
+       I915_WRITE(TVIDEO_DIP_CTL(crtc->pipe), val);
+       for (i = 0; i < len; i += 4)
+               *data++ = I915_READ(TVIDEO_DIP_DATA(crtc->pipe));
+ }
+ static u32 ibx_infoframes_enabled(struct intel_encoder *encoder,
                                  const struct intel_crtc_state *pipe_config)
  {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 val = I915_READ(reg);
  
        if ((val & VIDEO_DIP_ENABLE) == 0)
-               return false;
+               return 0;
  
        if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(encoder->port))
-               return false;
+               return 0;
  
        return val & (VIDEO_DIP_ENABLE_AVI |
                      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
@@@ -316,7 -371,28 +371,28 @@@ static void cpt_write_infoframe(struct 
        POSTING_READ(reg);
  }
  
- static bool cpt_infoframe_enabled(struct intel_encoder *encoder,
+ static void cpt_read_infoframe(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *crtc_state,
+                              unsigned int type,
+                              void *frame, ssize_t len)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       u32 val, *data = frame;
+       int i;
+       val = I915_READ(TVIDEO_DIP_CTL(crtc->pipe));
+       val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+       val |= g4x_infoframe_index(type);
+       I915_WRITE(TVIDEO_DIP_CTL(crtc->pipe), val);
+       for (i = 0; i < len; i += 4)
+               *data++ = I915_READ(TVIDEO_DIP_DATA(crtc->pipe));
+ }
+ static u32 cpt_infoframes_enabled(struct intel_encoder *encoder,
                                  const struct intel_crtc_state *pipe_config)
  {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 val = I915_READ(TVIDEO_DIP_CTL(pipe));
  
        if ((val & VIDEO_DIP_ENABLE) == 0)
-               return false;
+               return 0;
  
        return val & (VIDEO_DIP_ENABLE_AVI |
                      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
@@@ -370,7 -446,28 +446,28 @@@ static void vlv_write_infoframe(struct 
        POSTING_READ(reg);
  }
  
- static bool vlv_infoframe_enabled(struct intel_encoder *encoder,
+ static void vlv_read_infoframe(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *crtc_state,
+                              unsigned int type,
+                              void *frame, ssize_t len)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       u32 val, *data = frame;
+       int i;
+       val = I915_READ(VLV_TVIDEO_DIP_CTL(crtc->pipe));
+       val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
+       val |= g4x_infoframe_index(type);
+       I915_WRITE(VLV_TVIDEO_DIP_CTL(crtc->pipe), val);
+       for (i = 0; i < len; i += 4)
+               *data++ = I915_READ(VLV_TVIDEO_DIP_DATA(crtc->pipe));
+ }
+ static u32 vlv_infoframes_enabled(struct intel_encoder *encoder,
                                  const struct intel_crtc_state *pipe_config)
  {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 val = I915_READ(VLV_TVIDEO_DIP_CTL(pipe));
  
        if ((val & VIDEO_DIP_ENABLE) == 0)
-               return false;
+               return 0;
  
        if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(encoder->port))
-               return false;
+               return 0;
  
        return val & (VIDEO_DIP_ENABLE_AVI |
                      VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
@@@ -423,7 -520,24 +520,24 @@@ static void hsw_write_infoframe(struct 
        POSTING_READ(ctl_reg);
  }
  
- static bool hsw_infoframe_enabled(struct intel_encoder *encoder,
+ static void hsw_read_infoframe(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *crtc_state,
+                              unsigned int type,
+                              void *frame, ssize_t len)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+       u32 val, *data = frame;
+       int i;
+       val = I915_READ(HSW_TVIDEO_DIP_CTL(cpu_transcoder));
+       for (i = 0; i < len; i += 4)
+               *data++ = I915_READ(hsw_dip_data_reg(dev_priv, cpu_transcoder,
+                                                    type, i >> 2));
+ }
+ static u32 hsw_infoframes_enabled(struct intel_encoder *encoder,
                                  const struct intel_crtc_state *pipe_config)
  {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
                      VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW);
  }
  
+ static const u8 infoframe_type_to_idx[] = {
+       HDMI_PACKET_TYPE_GENERAL_CONTROL,
+       HDMI_PACKET_TYPE_GAMUT_METADATA,
+       DP_SDP_VSC,
+       HDMI_INFOFRAME_TYPE_AVI,
+       HDMI_INFOFRAME_TYPE_SPD,
+       HDMI_INFOFRAME_TYPE_VENDOR,
+ };
+ u32 intel_hdmi_infoframe_enable(unsigned int type)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(infoframe_type_to_idx); i++) {
+               if (infoframe_type_to_idx[i] == type)
+                       return BIT(i);
+       }
+       return 0;
+ }
+ u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
+                                 const struct intel_crtc_state *crtc_state)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
+       u32 val, ret = 0;
+       int i;
+       val = dig_port->infoframes_enabled(encoder, crtc_state);
+       /* map from hardware bits to dip idx */
+       for (i = 0; i < ARRAY_SIZE(infoframe_type_to_idx); i++) {
+               unsigned int type = infoframe_type_to_idx[i];
+               if (HAS_DDI(dev_priv)) {
+                       if (val & hsw_infoframe_enable(type))
+                               ret |= BIT(i);
+               } else {
+                       if (val & g4x_infoframe_enable(type))
+                               ret |= BIT(i);
+               }
+       }
+       return ret;
+ }
  /*
   * The data we write to the DIP data buffer registers is 1 byte bigger than the
   * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting
   */
  static void intel_write_infoframe(struct intel_encoder *encoder,
                                  const struct intel_crtc_state *crtc_state,
-                                 union hdmi_infoframe *frame)
+                                 enum hdmi_infoframe_type type,
+                                 const union hdmi_infoframe *frame)
  {
        struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base);
        u8 buffer[VIDEO_DIP_DATA_SIZE];
        ssize_t len;
  
+       if ((crtc_state->infoframes.enable &
+            intel_hdmi_infoframe_enable(type)) == 0)
+               return;
+       if (WARN_ON(frame->any.type != type))
+               return;
        /* see comment above for the reason for this offset */
-       len = hdmi_infoframe_pack(frame, buffer + 1, sizeof(buffer) - 1);
-       if (len < 0)
+       len = hdmi_infoframe_pack_only(frame, buffer + 1, sizeof(buffer) - 1);
+       if (WARN_ON(len < 0))
                return;
  
        /* Insert the 'hole' (see big comment above) at position 3 */
        buffer[3] = 0;
        len++;
  
-       intel_dig_port->write_infoframe(encoder,
-                                       crtc_state,
-                                       frame->any.type, buffer, len);
+       intel_dig_port->write_infoframe(encoder, crtc_state, type, buffer, len);
  }
  
- static void intel_hdmi_set_avi_infoframe(struct intel_encoder *encoder,
-                                        const struct intel_crtc_state *crtc_state,
-                                        const struct drm_connector_state *conn_state)
+ void intel_read_infoframe(struct intel_encoder *encoder,
+                         const struct intel_crtc_state *crtc_state,
+                         enum hdmi_infoframe_type type,
+                         union hdmi_infoframe *frame)
  {
+       struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base);
+       u8 buffer[VIDEO_DIP_DATA_SIZE];
+       int ret;
+       if ((crtc_state->infoframes.enable &
+            intel_hdmi_infoframe_enable(type)) == 0)
+               return;
+       intel_dig_port->read_infoframe(encoder, crtc_state,
+                                      type, buffer, sizeof(buffer));
+       /* Fill the 'hole' (see big comment above) at position 3 */
+       memmove(&buffer[1], &buffer[0], 3);
+       /* see comment above for the reason for this offset */
+       ret = hdmi_infoframe_unpack(frame, buffer + 1, sizeof(buffer) - 1);
+       if (ret) {
+               DRM_DEBUG_KMS("Failed to unpack infoframe type 0x%02x\n", type);
+               return;
+       }
+       if (frame->any.type != type)
+               DRM_DEBUG_KMS("Found the wrong infoframe type 0x%x (expected 0x%02x)\n",
+                             frame->any.type, type);
+ }
+ static bool
+ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
+                                struct intel_crtc_state *crtc_state,
+                                struct drm_connector_state *conn_state)
+ {
+       struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->base.adjusted_mode;
-       union hdmi_infoframe frame;
+       struct drm_connector *connector = conn_state->connector;
        int ret;
  
-       ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
-                                                      conn_state->connector,
+       if (!crtc_state->has_infoframe)
+               return true;
+       crtc_state->infoframes.enable |=
+               intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI);
+       ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector,
                                                       adjusted_mode);
-       if (ret < 0) {
-               DRM_ERROR("couldn't fill AVI infoframe\n");
-               return;
-       }
+       if (ret)
+               return false;
  
        if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
-               frame.avi.colorspace = HDMI_COLORSPACE_YUV420;
+               frame->colorspace = HDMI_COLORSPACE_YUV420;
        else if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444)
-               frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
+               frame->colorspace = HDMI_COLORSPACE_YUV444;
        else
-               frame.avi.colorspace = HDMI_COLORSPACE_RGB;
+               frame->colorspace = HDMI_COLORSPACE_RGB;
  
-       drm_hdmi_avi_infoframe_colorspace(&frame.avi, conn_state);
++      drm_hdmi_avi_infoframe_colorspace(frame, conn_state);
 +
-       drm_hdmi_avi_infoframe_quant_range(&frame.avi,
-                                          conn_state->connector,
+       drm_hdmi_avi_infoframe_quant_range(frame, connector,
                                           adjusted_mode,
                                           crtc_state->limited_color_range ?
                                           HDMI_QUANTIZATION_RANGE_LIMITED :
                                           HDMI_QUANTIZATION_RANGE_FULL);
  
-       drm_hdmi_avi_infoframe_content_type(&frame.avi,
-                                           conn_state);
+       drm_hdmi_avi_infoframe_content_type(frame, conn_state);
  
        /* TODO: handle pixel repetition for YCBCR420 outputs */
-       intel_write_infoframe(encoder, crtc_state,
-                             &frame);
+       ret = hdmi_avi_infoframe_check(frame);
+       if (WARN_ON(ret))
+               return false;
+       return true;
  }
  
- static void intel_hdmi_set_spd_infoframe(struct intel_encoder *encoder,
-                                        const struct intel_crtc_state *crtc_state)
+ static bool
+ intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,
+                                struct intel_crtc_state *crtc_state,
+                                struct drm_connector_state *conn_state)
  {
-       union hdmi_infoframe frame;
+       struct hdmi_spd_infoframe *frame = &crtc_state->infoframes.spd.spd;
        int ret;
  
-       ret = hdmi_spd_infoframe_init(&frame.spd, "Intel", "Integrated gfx");
-       if (ret < 0) {
-               DRM_ERROR("couldn't fill SPD infoframe\n");
-               return;
-       }
+       if (!crtc_state->has_infoframe)
+               return true;
  
-       frame.spd.sdi = HDMI_SPD_SDI_PC;
+       crtc_state->infoframes.enable |=
+               intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD);
  
-       intel_write_infoframe(encoder, crtc_state,
-                             &frame);
+       ret = hdmi_spd_infoframe_init(frame, "Intel", "Integrated gfx");
+       if (WARN_ON(ret))
+               return false;
+       frame->sdi = HDMI_SPD_SDI_PC;
+       ret = hdmi_spd_infoframe_check(frame);
+       if (WARN_ON(ret))
+               return false;
+       return true;
  }
  
- static void
- intel_hdmi_set_hdmi_infoframe(struct intel_encoder *encoder,
-                             const struct intel_crtc_state *crtc_state,
-                             const struct drm_connector_state *conn_state)
- {
-       union hdmi_infoframe frame;
+ static bool
+ intel_hdmi_compute_hdmi_infoframe(struct intel_encoder *encoder,
+                                 struct intel_crtc_state *crtc_state,
+                                 struct drm_connector_state *conn_state)
+ {
+       struct hdmi_vendor_infoframe *frame =
+               &crtc_state->infoframes.hdmi.vendor.hdmi;
+       const struct drm_display_info *info =
+               &conn_state->connector->display_info;
        int ret;
  
-       ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
+       if (!crtc_state->has_infoframe || !info->has_hdmi_infoframe)
+               return true;
+       crtc_state->infoframes.enable |=
+               intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_VENDOR);
+       ret = drm_hdmi_vendor_infoframe_from_display_mode(frame,
                                                          conn_state->connector,
                                                          &crtc_state->base.adjusted_mode);
-       if (ret < 0)
-               return;
+       if (WARN_ON(ret))
+               return false;
  
-       intel_write_infoframe(encoder, crtc_state,
-                             &frame);
+       ret = hdmi_vendor_infoframe_check(frame);
+       if (WARN_ON(ret))
+               return false;
+       return true;
  }
  
  static void g4x_set_infoframes(struct intel_encoder *encoder,
        I915_WRITE(reg, val);
        POSTING_READ(reg);
  
-       intel_hdmi_set_avi_infoframe(encoder, crtc_state, conn_state);
-       intel_hdmi_set_spd_infoframe(encoder, crtc_state);
-       intel_hdmi_set_hdmi_infoframe(encoder, crtc_state, conn_state);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_AVI,
+                             &crtc_state->infoframes.avi);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_SPD,
+                             &crtc_state->infoframes.spd);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_VENDOR,
+                             &crtc_state->infoframes.hdmi);
  }
  
  static bool hdmi_sink_is_deep_color(const struct drm_connector_state *conn_state)
@@@ -676,7 -906,10 +908,10 @@@ static bool intel_hdmi_set_gcp_infofram
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
        i915_reg_t reg;
-       u32 val = 0;
+       if ((crtc_state->infoframes.enable &
+            intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL)) == 0)
+               return false;
  
        if (HAS_DDI(dev_priv))
                reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
        else
                return false;
  
+       I915_WRITE(reg, crtc_state->infoframes.gcp);
+       return true;
+ }
+ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
+                                  struct intel_crtc_state *crtc_state)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       i915_reg_t reg;
+       if ((crtc_state->infoframes.enable &
+            intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL)) == 0)
+               return;
+       if (HAS_DDI(dev_priv))
+               reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
+       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
+       else if (HAS_PCH_SPLIT(dev_priv))
+               reg = TVIDEO_DIP_GCP(crtc->pipe);
+       else
+               return;
+       crtc_state->infoframes.gcp = I915_READ(reg);
+ }
+ static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder,
+                                            struct intel_crtc_state *crtc_state,
+                                            struct drm_connector_state *conn_state)
+ {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       if (IS_G4X(dev_priv) || !crtc_state->has_infoframe)
+               return;
+       crtc_state->infoframes.enable |=
+               intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL);
        /* Indicate color depth whenever the sink supports deep color */
        if (hdmi_sink_is_deep_color(conn_state))
-               val |= GCP_COLOR_INDICATION;
+               crtc_state->infoframes.gcp |= GCP_COLOR_INDICATION;
  
        /* Enable default_phase whenever the display mode is suitably aligned */
        if (gcp_default_phase_possible(crtc_state->pipe_bpp,
                                       &crtc_state->base.adjusted_mode))
-               val |= GCP_DEFAULT_PHASE_ENABLE;
-       I915_WRITE(reg, val);
-       return val != 0;
+               crtc_state->infoframes.gcp |= GCP_DEFAULT_PHASE_ENABLE;
  }
  
  static void ibx_set_infoframes(struct intel_encoder *encoder,
        I915_WRITE(reg, val);
        POSTING_READ(reg);
  
-       intel_hdmi_set_avi_infoframe(encoder, crtc_state, conn_state);
-       intel_hdmi_set_spd_infoframe(encoder, crtc_state);
-       intel_hdmi_set_hdmi_infoframe(encoder, crtc_state, conn_state);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_AVI,
+                             &crtc_state->infoframes.avi);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_SPD,
+                             &crtc_state->infoframes.spd);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_VENDOR,
+                             &crtc_state->infoframes.hdmi);
  }
  
  static void cpt_set_infoframes(struct intel_encoder *encoder,
        I915_WRITE(reg, val);
        POSTING_READ(reg);
  
-       intel_hdmi_set_avi_infoframe(encoder, crtc_state, conn_state);
-       intel_hdmi_set_spd_infoframe(encoder, crtc_state);
-       intel_hdmi_set_hdmi_infoframe(encoder, crtc_state, conn_state);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_AVI,
+                             &crtc_state->infoframes.avi);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_SPD,
+                             &crtc_state->infoframes.spd);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_VENDOR,
+                             &crtc_state->infoframes.hdmi);
  }
  
  static void vlv_set_infoframes(struct intel_encoder *encoder,
        I915_WRITE(reg, val);
        POSTING_READ(reg);
  
-       intel_hdmi_set_avi_infoframe(encoder, crtc_state, conn_state);
-       intel_hdmi_set_spd_infoframe(encoder, crtc_state);
-       intel_hdmi_set_hdmi_infoframe(encoder, crtc_state, conn_state);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_AVI,
+                             &crtc_state->infoframes.avi);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_SPD,
+                             &crtc_state->infoframes.spd);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_VENDOR,
+                             &crtc_state->infoframes.hdmi);
  }
  
  static void hsw_set_infoframes(struct intel_encoder *encoder,
        I915_WRITE(reg, val);
        POSTING_READ(reg);
  
-       intel_hdmi_set_avi_infoframe(encoder, crtc_state, conn_state);
-       intel_hdmi_set_spd_infoframe(encoder, crtc_state);
-       intel_hdmi_set_hdmi_infoframe(encoder, crtc_state, conn_state);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_AVI,
+                             &crtc_state->infoframes.avi);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_SPD,
+                             &crtc_state->infoframes.spd);
+       intel_write_infoframe(encoder, crtc_state,
+                             HDMI_INFOFRAME_TYPE_VENDOR,
+                             &crtc_state->infoframes.hdmi);
  }
  
  void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
@@@ -1085,10 -1378,44 +1380,44 @@@ int intel_hdmi_hdcp_read_v_prime_part(s
        return ret;
  }
  
+ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
+ {
+       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+       struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+       struct drm_crtc *crtc = connector->base.state->crtc;
+       struct intel_crtc *intel_crtc = container_of(crtc,
+                                                    struct intel_crtc, base);
+       u32 scanline;
+       int ret;
+       for (;;) {
+               scanline = I915_READ(PIPEDSL(intel_crtc->pipe));
+               if (scanline > 100 && scanline < 200)
+                       break;
+               usleep_range(25, 50);
+       }
+       ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, false);
+       if (ret) {
+               DRM_ERROR("Disable HDCP signalling failed (%d)\n", ret);
+               return ret;
+       }
+       ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, true);
+       if (ret) {
+               DRM_ERROR("Enable HDCP signalling failed (%d)\n", ret);
+               return ret;
+       }
+       return 0;
+ }
  static
  int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
                                      bool enable)
  {
+       struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
+       struct intel_connector *connector = hdmi->attached_connector;
+       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
        int ret;
  
        if (!enable)
                          enable ? "Enable" : "Disable", ret);
                return ret;
        }
+       /*
+        * WA: To fix incorrect positioning of the window of
+        * opportunity and enc_en signalling in KABYLAKE.
+        */
+       if (IS_KABYLAKE(dev_priv) && enable)
+               return kbl_repositioning_enc_en_signal(connector);
        return 0;
  }
  
@@@ -1131,6 -1466,190 +1468,190 @@@ bool intel_hdmi_hdcp_check_link(struct 
        return true;
  }
  
+ static struct hdcp2_hdmi_msg_data {
+       u8 msg_id;
+       u32 timeout;
+       u32 timeout2;
+       } hdcp2_msg_data[] = {
+               {HDCP_2_2_AKE_INIT, 0, 0},
+               {HDCP_2_2_AKE_SEND_CERT, HDCP_2_2_CERT_TIMEOUT_MS, 0},
+               {HDCP_2_2_AKE_NO_STORED_KM, 0, 0},
+               {HDCP_2_2_AKE_STORED_KM, 0, 0},
+               {HDCP_2_2_AKE_SEND_HPRIME, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
+                               HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS},
+               {HDCP_2_2_AKE_SEND_PAIRING_INFO, HDCP_2_2_PAIRING_TIMEOUT_MS,
+                               0},
+               {HDCP_2_2_LC_INIT, 0, 0},
+               {HDCP_2_2_LC_SEND_LPRIME, HDCP_2_2_HDMI_LPRIME_TIMEOUT_MS, 0},
+               {HDCP_2_2_SKE_SEND_EKS, 0, 0},
+               {HDCP_2_2_REP_SEND_RECVID_LIST,
+                               HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0},
+               {HDCP_2_2_REP_SEND_ACK, 0, 0},
+               {HDCP_2_2_REP_STREAM_MANAGE, 0, 0},
+               {HDCP_2_2_REP_STREAM_READY, HDCP_2_2_STREAM_READY_TIMEOUT_MS,
+                               0},
+       };
+ static
+ int intel_hdmi_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
+                                   u8 *rx_status)
+ {
+       return intel_hdmi_hdcp_read(intel_dig_port,
+                                   HDCP_2_2_HDMI_REG_RXSTATUS_OFFSET,
+                                   rx_status,
+                                   HDCP_2_2_HDMI_RXSTATUS_LEN);
+ }
+ static int get_hdcp2_msg_timeout(u8 msg_id, bool is_paired)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(hdcp2_msg_data); i++)
+               if (hdcp2_msg_data[i].msg_id == msg_id &&
+                   (msg_id != HDCP_2_2_AKE_SEND_HPRIME || is_paired))
+                       return hdcp2_msg_data[i].timeout;
+               else if (hdcp2_msg_data[i].msg_id == msg_id)
+                       return hdcp2_msg_data[i].timeout2;
+       return -EINVAL;
+ }
+ static inline
+ int hdcp2_detect_msg_availability(struct intel_digital_port *intel_digital_port,
+                                 u8 msg_id, bool *msg_ready,
+                                 ssize_t *msg_sz)
+ {
+       u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN];
+       int ret;
+       ret = intel_hdmi_hdcp2_read_rx_status(intel_digital_port, rx_status);
+       if (ret < 0) {
+               DRM_DEBUG_KMS("rx_status read failed. Err %d\n", ret);
+               return ret;
+       }
+       *msg_sz = ((HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(rx_status[1]) << 8) |
+                 rx_status[0]);
+       if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST)
+               *msg_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1]) &&
+                            *msg_sz);
+       else
+               *msg_ready = *msg_sz;
+       return 0;
+ }
+ static ssize_t
+ intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
+                             u8 msg_id, bool paired)
+ {
+       bool msg_ready = false;
+       int timeout, ret;
+       ssize_t msg_sz = 0;
+       timeout = get_hdcp2_msg_timeout(msg_id, paired);
+       if (timeout < 0)
+               return timeout;
+       ret = __wait_for(ret = hdcp2_detect_msg_availability(intel_dig_port,
+                                                            msg_id, &msg_ready,
+                                                            &msg_sz),
+                        !ret && msg_ready && msg_sz, timeout * 1000,
+                        1000, 5 * 1000);
+       if (ret)
+               DRM_DEBUG_KMS("msg_id: %d, ret: %d, timeout: %d\n",
+                             msg_id, ret, timeout);
+       return ret ? ret : msg_sz;
+ }
+ static
+ int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
+                              void *buf, size_t size)
+ {
+       unsigned int offset;
+       offset = HDCP_2_2_HDMI_REG_WR_MSG_OFFSET;
+       return intel_hdmi_hdcp_write(intel_dig_port, offset, buf, size);
+ }
+ static
+ int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
+                             u8 msg_id, void *buf, size_t size)
+ {
+       struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
+       struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp;
+       unsigned int offset;
+       ssize_t ret;
+       ret = intel_hdmi_hdcp2_wait_for_msg(intel_dig_port, msg_id,
+                                           hdcp->is_paired);
+       if (ret < 0)
+               return ret;
+       /*
+        * Available msg size should be equal to or lesser than the
+        * available buffer.
+        */
+       if (ret > size) {
+               DRM_DEBUG_KMS("msg_sz(%zd) is more than exp size(%zu)\n",
+                             ret, size);
+               return -1;
+       }
+       offset = HDCP_2_2_HDMI_REG_RD_MSG_OFFSET;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, offset, buf, ret);
+       if (ret)
+               DRM_DEBUG_KMS("Failed to read msg_id: %d(%zd)\n", msg_id, ret);
+       return ret;
+ }
+ static
+ int intel_hdmi_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
+ {
+       u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN];
+       int ret;
+       ret = intel_hdmi_hdcp2_read_rx_status(intel_dig_port, rx_status);
+       if (ret)
+               return ret;
+       /*
+        * Re-auth request and Link Integrity Failures are represented by
+        * same bit. i.e reauth_req.
+        */
+       if (HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(rx_status[1]))
+               ret = HDCP_REAUTH_REQUEST;
+       else if (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1]))
+               ret = HDCP_TOPOLOGY_CHANGE;
+       return ret;
+ }
+ static
+ int intel_hdmi_hdcp2_capable(struct intel_digital_port *intel_dig_port,
+                            bool *capable)
+ {
+       u8 hdcp2_version;
+       int ret;
+       *capable = false;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, HDCP_2_2_HDMI_REG_VER_OFFSET,
+                                  &hdcp2_version, sizeof(hdcp2_version));
+       if (!ret && hdcp2_version & HDCP_2_2_HDMI_SUPPORT_MASK)
+               *capable = true;
+       return ret;
+ }
+ static inline
+ enum hdcp_wired_protocol intel_hdmi_hdcp2_protocol(void)
+ {
+       return HDCP_PROTOCOL_HDMI;
+ }
  static const struct intel_hdcp_shim intel_hdmi_hdcp_shim = {
        .write_an_aksv = intel_hdmi_hdcp_write_an_aksv,
        .read_bksv = intel_hdmi_hdcp_read_bksv,
        .read_v_prime_part = intel_hdmi_hdcp_read_v_prime_part,
        .toggle_signalling = intel_hdmi_hdcp_toggle_signalling,
        .check_link = intel_hdmi_hdcp_check_link,
+       .write_2_2_msg = intel_hdmi_hdcp2_write_msg,
+       .read_2_2_msg = intel_hdmi_hdcp2_read_msg,
+       .check_2_2_link = intel_hdmi_hdcp2_check_link,
+       .hdcp_2_2_capable = intel_hdmi_hdcp2_capable,
+       .protocol = HDCP_PROTOCOL_HDMI,
  };
  
  static void intel_hdmi_prepare(struct intel_encoder *encoder,
@@@ -1207,7 -1731,6 +1733,6 @@@ static void intel_hdmi_get_config(struc
                                  struct intel_crtc_state *pipe_config)
  {
        struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
-       struct intel_digital_port *intel_dig_port = hdmi_to_dig_port(intel_hdmi);
        struct drm_device *dev = encoder->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        u32 tmp, flags = 0;
        if (tmp & HDMI_MODE_SELECT_HDMI)
                pipe_config->has_hdmi_sink = true;
  
-       if (intel_dig_port->infoframe_enabled(encoder, pipe_config))
+       pipe_config->infoframes.enable |=
+               intel_hdmi_infoframes_enabled(encoder, pipe_config);
+       if (pipe_config->infoframes.enable)
                pipe_config->has_infoframe = true;
  
        if (tmp & SDVO_AUDIO_ENABLE)
        pipe_config->base.adjusted_mode.crtc_clock = dotclock;
  
        pipe_config->lane_count = 4;
+       intel_hdmi_read_gcp_infoframe(encoder, pipe_config);
+       intel_read_infoframe(encoder, pipe_config,
+                            HDMI_INFOFRAME_TYPE_AVI,
+                            &pipe_config->infoframes.avi);
+       intel_read_infoframe(encoder, pipe_config,
+                            HDMI_INFOFRAME_TYPE_SPD,
+                            &pipe_config->infoframes.spd);
+       intel_read_infoframe(encoder, pipe_config,
+                            HDMI_INFOFRAME_TYPE_VENDOR,
+                            &pipe_config->infoframes.hdmi);
  }
  
  static void intel_enable_hdmi_audio(struct intel_encoder *encoder,
@@@ -1666,7 -2204,7 +2206,7 @@@ static bool hdmi_deep_color_possible(co
  
        /* Display Wa_1405510057:icl */
        if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
-           bpc == 10 && IS_ICELAKE(dev_priv) &&
+           bpc == 10 && INTEL_GEN(dev_priv) >= 11 &&
            (adjusted_mode->crtc_hblank_end -
             adjusted_mode->crtc_hblank_start) % 8 == 2)
                return false;
@@@ -1824,6 -2362,23 +2364,23 @@@ int intel_hdmi_compute_config(struct in
                }
        }
  
+       intel_hdmi_compute_gcp_infoframe(encoder, pipe_config, conn_state);
+       if (!intel_hdmi_compute_avi_infoframe(encoder, pipe_config, conn_state)) {
+               DRM_DEBUG_KMS("bad AVI infoframe\n");
+               return -EINVAL;
+       }
+       if (!intel_hdmi_compute_spd_infoframe(encoder, pipe_config, conn_state)) {
+               DRM_DEBUG_KMS("bad SPD infoframe\n");
+               return -EINVAL;
+       }
+       if (!intel_hdmi_compute_hdmi_infoframe(encoder, pipe_config, conn_state)) {
+               DRM_DEBUG_KMS("bad HDMI infoframe\n");
+               return -EINVAL;
+       }
        return 0;
  }
  
@@@ -1943,7 -2498,7 +2500,7 @@@ intel_hdmi_detect(struct drm_connector 
  
        wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
  
-       if (IS_ICELAKE(dev_priv) &&
+       if (INTEL_GEN(dev_priv) >= 11 &&
            !intel_digital_port_connected(encoder))
                goto out;
  
@@@ -2145,21 -2700,10 +2702,21 @@@ static voi
  intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
  {
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
 +      struct intel_digital_port *intel_dig_port =
 +                              hdmi_to_dig_port(intel_hdmi);
  
        intel_attach_force_audio_property(connector);
        intel_attach_broadcast_rgb_property(connector);
        intel_attach_aspect_ratio_property(connector);
 +
 +      /*
 +       * Attach Colorspace property for Non LSPCON based device
 +       * ToDo: This needs to be extended for LSPCON implementation
 +       * as well. Will be implemented separately.
 +       */
 +      if (!intel_dig_port->lspcon.active)
 +              intel_attach_colorspace_property(connector);
 +
        drm_connector_attach_content_type_property(connector);
        connector->state->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
  
@@@ -2344,14 -2888,14 +2901,14 @@@ static u8 intel_hdmi_ddc_pin(struct drm
                return info->alternate_ddc_pin;
        }
  
-       if (IS_CHERRYVIEW(dev_priv))
-               ddc_pin = chv_port_to_ddc_pin(dev_priv, port);
-       else if (IS_GEN9_LP(dev_priv))
-               ddc_pin = bxt_port_to_ddc_pin(dev_priv, port);
+       if (HAS_PCH_ICP(dev_priv))
+               ddc_pin = icl_port_to_ddc_pin(dev_priv, port);
        else if (HAS_PCH_CNP(dev_priv))
                ddc_pin = cnp_port_to_ddc_pin(dev_priv, port);
-       else if (HAS_PCH_ICP(dev_priv))
-               ddc_pin = icl_port_to_ddc_pin(dev_priv, port);
+       else if (IS_GEN9_LP(dev_priv))
+               ddc_pin = bxt_port_to_ddc_pin(dev_priv, port);
+       else if (IS_CHERRYVIEW(dev_priv))
+               ddc_pin = chv_port_to_ddc_pin(dev_priv, port);
        else
                ddc_pin = g4x_port_to_ddc_pin(dev_priv, port);
  
@@@ -2368,33 -2912,36 +2925,36 @@@ void intel_infoframe_init(struct intel_
  
        if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                intel_dig_port->write_infoframe = vlv_write_infoframe;
+               intel_dig_port->read_infoframe = vlv_read_infoframe;
                intel_dig_port->set_infoframes = vlv_set_infoframes;
-               intel_dig_port->infoframe_enabled = vlv_infoframe_enabled;
+               intel_dig_port->infoframes_enabled = vlv_infoframes_enabled;
        } else if (IS_G4X(dev_priv)) {
                intel_dig_port->write_infoframe = g4x_write_infoframe;
+               intel_dig_port->read_infoframe = g4x_read_infoframe;
                intel_dig_port->set_infoframes = g4x_set_infoframes;
-               intel_dig_port->infoframe_enabled = g4x_infoframe_enabled;
+               intel_dig_port->infoframes_enabled = g4x_infoframes_enabled;
        } else if (HAS_DDI(dev_priv)) {
                if (intel_dig_port->lspcon.active) {
-                       intel_dig_port->write_infoframe =
-                                       lspcon_write_infoframe;
+                       intel_dig_port->write_infoframe = lspcon_write_infoframe;
+                       intel_dig_port->read_infoframe = lspcon_read_infoframe;
                        intel_dig_port->set_infoframes = lspcon_set_infoframes;
-                       intel_dig_port->infoframe_enabled =
-                                               lspcon_infoframe_enabled;
+                       intel_dig_port->infoframes_enabled = lspcon_infoframes_enabled;
                } else {
-                       intel_dig_port->set_infoframes = hsw_set_infoframes;
-                       intel_dig_port->infoframe_enabled =
-                                               hsw_infoframe_enabled;
                        intel_dig_port->write_infoframe = hsw_write_infoframe;
+                       intel_dig_port->read_infoframe = hsw_read_infoframe;
+                       intel_dig_port->set_infoframes = hsw_set_infoframes;
+                       intel_dig_port->infoframes_enabled = hsw_infoframes_enabled;
                }
        } else if (HAS_PCH_IBX(dev_priv)) {
                intel_dig_port->write_infoframe = ibx_write_infoframe;
+               intel_dig_port->read_infoframe = ibx_read_infoframe;
                intel_dig_port->set_infoframes = ibx_set_infoframes;
-               intel_dig_port->infoframe_enabled = ibx_infoframe_enabled;
+               intel_dig_port->infoframes_enabled = ibx_infoframes_enabled;
        } else {
                intel_dig_port->write_infoframe = cpt_write_infoframe;
+               intel_dig_port->read_infoframe = cpt_read_infoframe;
                intel_dig_port->set_infoframes = cpt_set_infoframes;
-               intel_dig_port->infoframe_enabled = cpt_infoframe_enabled;
+               intel_dig_port->infoframes_enabled = cpt_infoframes_enabled;
        }
  }
  
@@@ -2440,6 -2987,9 +3000,9 @@@ void intel_hdmi_init_connector(struct i
  
        intel_hdmi_add_properties(intel_hdmi, connector);
  
+       intel_connector_attach_encoder(intel_connector, intel_encoder);
+       intel_hdmi->attached_connector = intel_connector;
        if (is_hdcp_supported(dev_priv, port)) {
                int ret = intel_hdcp_init(intel_connector,
                                          &intel_hdmi_hdcp_shim);
                        DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
        }
  
-       intel_connector_attach_encoder(intel_connector, intel_encoder);
-       intel_hdmi->attached_connector = intel_connector;
        /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
         * 0xd.  Failure to do so will result in spurious interrupts being
         * generated on the port when a cable is not attached.
index 53174d5795741947b609d9c269ba03ed29e675a0,aee4defcb88dbade75c4480cd455270c2b7d4bdf..3f2055f70d05123313e769b7e328ed4615973047
@@@ -622,6 -622,9 +622,9 @@@ skl_disable_plane(struct intel_plane *p
  
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  
+       if (icl_is_hdr_plane(dev_priv, plane_id))
+               I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0);
        skl_write_plane_wm(plane, crtc_state);
  
        I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
@@@ -754,7 -757,12 +757,12 @@@ vlv_update_clrc(const struct intel_plan
  
  static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
  {
-       return SP_GAMMA_ENABLE;
+       u32 sprctl = 0;
+       if (crtc_state->gamma_enable)
+               sprctl |= SP_GAMMA_ENABLE;
+       return sprctl;
  }
  
  static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
@@@ -929,12 -937,12 +937,12 @@@ vlv_plane_get_hw_state(struct intel_pla
  
  static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
  {
-       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
        u32 sprctl = 0;
  
-       sprctl |= SPRITE_GAMMA_ENABLE;
+       if (crtc_state->gamma_enable)
+               sprctl |= SPRITE_GAMMA_ENABLE;
  
-       if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+       if (crtc_state->csc_enable)
                sprctl |= SPRITE_PIPE_CSC_ENABLE;
  
        return sprctl;
@@@ -1120,7 -1128,15 +1128,15 @@@ g4x_sprite_max_stride(struct intel_plan
  
  static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
  {
-       return DVS_GAMMA_ENABLE;
+       u32 dvscntr = 0;
+       if (crtc_state->gamma_enable)
+               dvscntr |= DVS_GAMMA_ENABLE;
+       if (crtc_state->csc_enable)
+               dvscntr |= DVS_PIPE_CSC_ENABLE;
+       return dvscntr;
  }
  
  static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
@@@ -1805,7 -1821,7 +1821,7 @@@ static const u32 skl_plane_formats[] = 
        DRM_FORMAT_VYUY,
  };
  
- static const uint32_t icl_plane_formats[] = {
+ static const u32 icl_plane_formats[] = {
        DRM_FORMAT_C8,
        DRM_FORMAT_RGB565,
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_Y210,
        DRM_FORMAT_Y212,
        DRM_FORMAT_Y216,
 -      DRM_FORMAT_Y410,
 -      DRM_FORMAT_Y412,
 -      DRM_FORMAT_Y416,
 +      DRM_FORMAT_XVYU2101010,
 +      DRM_FORMAT_XVYU12_16161616,
 +      DRM_FORMAT_XVYU16161616,
  };
  
- static const uint32_t icl_hdr_plane_formats[] = {
+ static const u32 icl_hdr_plane_formats[] = {
        DRM_FORMAT_C8,
        DRM_FORMAT_RGB565,
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_Y210,
        DRM_FORMAT_Y212,
        DRM_FORMAT_Y216,
 -      DRM_FORMAT_Y410,
 -      DRM_FORMAT_Y412,
 -      DRM_FORMAT_Y416,
 +      DRM_FORMAT_XVYU2101010,
 +      DRM_FORMAT_XVYU12_16161616,
 +      DRM_FORMAT_XVYU16161616,
  };
  
  static const u32 skl_planar_formats[] = {
        DRM_FORMAT_NV12,
  };
  
- static const uint32_t glk_planar_formats[] = {
+ static const u32 glk_planar_formats[] = {
        DRM_FORMAT_C8,
        DRM_FORMAT_RGB565,
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_P016,
  };
  
- static const uint32_t icl_planar_formats[] = {
+ static const u32 icl_planar_formats[] = {
        DRM_FORMAT_C8,
        DRM_FORMAT_RGB565,
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_Y210,
        DRM_FORMAT_Y212,
        DRM_FORMAT_Y216,
 -      DRM_FORMAT_Y410,
 -      DRM_FORMAT_Y412,
 -      DRM_FORMAT_Y416,
 +      DRM_FORMAT_XVYU2101010,
 +      DRM_FORMAT_XVYU12_16161616,
 +      DRM_FORMAT_XVYU16161616,
  };
  
- static const uint32_t icl_hdr_planar_formats[] = {
+ static const u32 icl_hdr_planar_formats[] = {
        DRM_FORMAT_C8,
        DRM_FORMAT_RGB565,
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_Y210,
        DRM_FORMAT_Y212,
        DRM_FORMAT_Y216,
 -      DRM_FORMAT_Y410,
 -      DRM_FORMAT_Y412,
 -      DRM_FORMAT_Y416,
 +      DRM_FORMAT_XVYU2101010,
 +      DRM_FORMAT_XVYU12_16161616,
 +      DRM_FORMAT_XVYU16161616,
  };
  
  static const u64 skl_plane_format_modifiers_noccs[] = {
@@@ -2085,9 -2101,9 +2101,9 @@@ static bool skl_plane_format_mod_suppor
        case DRM_FORMAT_Y210:
        case DRM_FORMAT_Y212:
        case DRM_FORMAT_Y216:
 -      case DRM_FORMAT_Y410:
 -      case DRM_FORMAT_Y412:
 -      case DRM_FORMAT_Y416:
 +      case DRM_FORMAT_XVYU2101010:
 +      case DRM_FORMAT_XVYU12_16161616:
 +      case DRM_FORMAT_XVYU16161616:
                if (modifier == I915_FORMAT_MOD_Yf_TILED)
                        return true;
                /* fall through */
diff --combined include/sound/hdaudio.h
index 45f944d57982800cc176ed782aedbf9b1d30f1fe,a438ec8e535b4beeedd895f88f486029231ae091..06f504c10b80ec84136a159d7156876006c44985
@@@ -367,7 -367,7 +367,7 @@@ struct hdac_bus 
        /* DRM component interface */
        struct drm_audio_component *audio_component;
        long display_power_status;
-       bool display_power_active;
+       unsigned long display_power_active;
  
        /* parameters required for enhanced capabilities */
        int num_streams;
@@@ -539,9 -539,6 +539,9 @@@ void snd_hdac_stream_sync(struct hdac_s
                          unsigned int streams);
  void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
                                      unsigned int streams);
 +int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
 +                              struct snd_pcm_substream *substream);
 +
  /*
   * macros for easy use
   */
This page took 0.206002 seconds and 4 git commands to generate.