]> Git Repo - linux.git/commitdiff
Merge drm/drm-next into drm-intel-next-queued
authorJoonas Lahtinen <[email protected]>
Wed, 27 Mar 2019 16:23:53 +0000 (18:23 +0200)
committerJoonas Lahtinen <[email protected]>
Wed, 27 Mar 2019 16:23:53 +0000 (18:23 +0200)
This is needed to get the fourcc code merged without conflicts.

Signed-off-by: Joonas Lahtinen <[email protected]>
1  2 
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_utils.h
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 a9fcb32f4989c8aa59341f0d4f6276b73ef0cfc9,9df65d386d11b40349df879fec224f0990a40b62..bbe1a5d56480b52a396a7b3160e91cac332e2016
@@@ -188,11 -188,6 +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));
@@@ -224,20 -219,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);
@@@ -335,16 -330,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);
@@@ -719,7 -714,8 +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);
@@@ -761,39 -757,6 +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)
  {
        /*
@@@ -910,7 -873,6 +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);
@@@ -968,6 -930,46 +935,6 @@@ static void i915_driver_cleanup_early(s
        i915_engines_cleanup(dev_priv);
  }
  
 -static int i915_mmio_setup(struct drm_i915_private *dev_priv)
 -{
 -      struct pci_dev *pdev = dev_priv->drm.pdev;
 -      int mmio_bar;
 -      int mmio_size;
 -
 -      mmio_bar = IS_GEN(dev_priv, 2) ? 1 : 0;
 -      /*
 -       * Before gen4, the registers and the GTT are behind different BARs.
 -       * However, from gen4 onwards, the registers and the GTT are shared
 -       * in the same BAR, so we want to restrict this ioremap from
 -       * clobbering the GTT which we want ioremap_wc instead. Fortunately,
 -       * the register BAR remains the same size for all the earlier
 -       * generations up to Ironlake.
 -       */
 -      if (INTEL_GEN(dev_priv) < 5)
 -              mmio_size = 512 * 1024;
 -      else
 -              mmio_size = 2 * 1024 * 1024;
 -      dev_priv->regs = pci_iomap(pdev, mmio_bar, mmio_size);
 -      if (dev_priv->regs == NULL) {
 -              DRM_ERROR("failed to map registers\n");
 -
 -              return -EIO;
 -      }
 -
 -      /* Try to make sure MCHBAR is enabled before poking at it */
 -      intel_setup_mchbar(dev_priv);
 -
 -      return 0;
 -}
 -
 -static void i915_mmio_cleanup(struct drm_i915_private *dev_priv)
 -{
 -      struct pci_dev *pdev = dev_priv->drm.pdev;
 -
 -      intel_teardown_mchbar(dev_priv);
 -      pci_iounmap(pdev, dev_priv->regs);
 -}
 -
  /**
   * i915_driver_init_mmio - setup device MMIO
   * @dev_priv: device private
@@@ -987,16 -989,15 +954,16 @@@ static int i915_driver_init_mmio(struc
        if (i915_get_bridge_dev(dev_priv))
                return -EIO;
  
 -      ret = i915_mmio_setup(dev_priv);
 +      ret = intel_uncore_init(&dev_priv->uncore);
        if (ret < 0)
                goto err_bridge;
  
 -      intel_uncore_init(dev_priv);
 +      /* Try to make sure MCHBAR is enabled before poking at it */
 +      intel_setup_mchbar(dev_priv);
  
        intel_device_info_init_mmio(dev_priv);
  
 -      intel_uncore_prune(dev_priv);
 +      intel_uncore_prune(&dev_priv->uncore);
  
        intel_uc_init_mmio(dev_priv);
  
        return 0;
  
  err_uncore:
 -      intel_uncore_fini(dev_priv);
 -      i915_mmio_cleanup(dev_priv);
 +      intel_teardown_mchbar(dev_priv);
 +      intel_uncore_fini(&dev_priv->uncore);
  err_bridge:
        pci_dev_put(dev_priv->bridge_dev);
  
   */
  static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv)
  {
 -      intel_uncore_fini(dev_priv);
 -      i915_mmio_cleanup(dev_priv);
 +      intel_teardown_mchbar(dev_priv);
 +      intel_uncore_fini(&dev_priv->uncore);
        pci_dev_put(dev_priv->bridge_dev);
  }
  
@@@ -1033,180 -1034,110 +1000,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 I915_DRAM_RANK_INVALID;
 +      return str[type];
  }
  
 -static bool
 -skl_is_16gb_dimm(enum dram_rank rank, u8 size, u8 width)
 +#undef DRAM_TYPE_STR
 +
 +static int intel_dimm_num_devices(const struct dram_dimm_info *dimm)
  {
 -      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 dimm->ranks * 64 / (dimm->width ?: 1);
 +}
  
 -      return false;
 +/* Returns total GB for the whole DIMM */
 +static int skl_get_dimm_size(u16 val)
 +{
 +      return val & SKL_DRAM_SIZE_MASK;
  }
  
 -static int
 -skl_dram_get_channel_info(struct dram_channel_info *ch, u32 val)
 +static int skl_get_dimm_width(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;
 +      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_get_dimm_ranks(u16 val)
 +{
 +      if (skl_get_dimm_size(val) == 0)
 +              return 0;
 +
 +      val = (val & SKL_DRAM_RANK_MASK) >> SKL_DRAM_RANK_SHIFT;
 +
 +      return val + 1;
 +}
 +
 +/* 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;
  
 -      tmp_l = val & SKL_DRAM_SIZE_MASK;
 -      tmp_s = s_val & SKL_DRAM_SIZE_MASK;
 +      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 (tmp_l == 0 && tmp_s == 0)
 +      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;
        }
  
@@@ -1447,8 -1290,14 +1414,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));
  }
  
  /**
@@@ -1493,7 -1348,7 +1460,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;
@@@ -1898,7 -1753,8 +1865,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);
  
@@@ -2006,6 -1862,7 +1973,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)
@@@ -2085,7 -1945,7 +2052,7 @@@ static int i915_drm_suspend_late(struc
  
        i915_gem_suspend_late(dev_priv);
  
 -      intel_uncore_suspend(dev_priv);
 +      intel_uncore_suspend(&dev_priv->uncore);
  
        intel_power_domains_suspend(dev_priv,
                                    get_suspend_mode(dev_priv, hibernation));
@@@ -2281,9 -2141,7 +2248,9 @@@ static int i915_drm_resume_early(struc
                DRM_ERROR("Resume prepare failed: %d, continuing anyway\n",
                          ret);
  
 -      intel_uncore_resume_early(dev_priv);
 +      intel_uncore_resume_early(&dev_priv->uncore);
 +
 +      i915_check_and_clear_faults(dev_priv);
  
        if (INTEL_GEN(dev_priv) >= 11 || IS_GEN9_LP(dev_priv)) {
                gen9_sanitize_dc_state(dev_priv);
@@@ -2687,7 -2545,7 +2654,7 @@@ int vlv_force_gfx_clock(struct drm_i915
        if (!force_on)
                return 0;
  
 -      err = intel_wait_for_register(dev_priv,
 +      err = intel_wait_for_register(&dev_priv->uncore,
                                      VLV_GTLC_SURVIVABILITY_REG,
                                      VLV_GFX_CLK_STATUS_BIT,
                                      VLV_GFX_CLK_STATUS_BIT,
@@@ -2853,7 -2711,7 +2820,7 @@@ static int intel_runtime_suspend(struc
  
        intel_runtime_pm_disable_interrupts(dev_priv);
  
 -      intel_uncore_suspend(dev_priv);
 +      intel_uncore_suspend(&dev_priv->uncore);
  
        ret = 0;
        if (INTEL_GEN(dev_priv) >= 11) {
  
        if (ret) {
                DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret);
 -              intel_uncore_runtime_resume(dev_priv);
 +              intel_uncore_runtime_resume(&dev_priv->uncore);
  
                intel_runtime_pm_enable_interrupts(dev_priv);
  
        enable_rpm_wakeref_asserts(dev_priv);
        intel_runtime_pm_cleanup(dev_priv);
  
 -      if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv))
 +      if (intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore))
                DRM_ERROR("Unclaimed access detected prior to suspending\n");
  
        dev_priv->runtime_pm.suspended = true;
                intel_opregion_notify_adapter(dev_priv, PCI_D1);
        }
  
 -      assert_forcewakes_inactive(dev_priv);
 +      assert_forcewakes_inactive(&dev_priv->uncore);
  
        if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
                intel_hpd_poll_init(dev_priv);
@@@ -2941,7 -2799,7 +2908,7 @@@ static int intel_runtime_resume(struct 
  
        intel_opregion_notify_adapter(dev_priv, PCI_D0);
        dev_priv->runtime_pm.suspended = false;
 -      if (intel_uncore_unclaimed_mmio(dev_priv))
 +      if (intel_uncore_unclaimed_mmio(&dev_priv->uncore))
                DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n");
  
        if (INTEL_GEN(dev_priv) >= 11) {
                ret = vlv_resume_prepare(dev_priv, true);
        }
  
 -      intel_uncore_runtime_resume(dev_priv);
 +      intel_uncore_runtime_resume(&dev_priv->uncore);
  
        intel_runtime_pm_enable_interrupts(dev_priv);
  
@@@ -3111,7 -2969,7 +3078,7 @@@ static const struct drm_ioctl_desc i915
        DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey_ioctl, DRM_MASTER),
        DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER),
        DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 -      DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
 +      DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE_EXT, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
index 084016200a1e2ff566c3636a371e69d37849365d,b745c49a5af620e61adbfe05585f2f8ad7b7ad03..46a52da3db297bec061d874858b8fbb440dc4654
@@@ -5,6 -5,7 +5,7 @@@
   */
  
  #include <linux/irq.h>
+ #include <linux/pm_runtime.h>
  #include "i915_pmu.h"
  #include "intel_ringbuffer.h"
  #include "i915_drv.h"
@@@ -101,7 -102,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);
  
        /*
@@@ -148,6 -149,14 +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)
  {
@@@ -160,48 -169,49 +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);
  }
@@@ -474,7 -484,6 +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 8baedcaddbba75084e68449368b7c0c5057763d0,540e20eb032c564d1c01d633c8564f8ccf2edca6..2dbe8933b50a1796b43446d81b4361f846316d69
        __T;                                                            \
  })
  
 +/*
 + * container_of_user: Extract the superclass from a pointer to a member.
 + *
 + * Exactly like container_of() with the exception that it plays nicely
 + * with sparse for __user @ptr.
 + */
 +#define container_of_user(ptr, type, member) ({                               \
 +      void __user *__mptr = (void __user *)(ptr);                     \
 +      BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&   \
 +                       !__same_type(*(ptr), void),                    \
 +                       "pointer type mismatch in container_of()");    \
 +      ((type __user *)(__mptr - offsetof(type, member))); })
 +
 +/*
 + * check_user_mbz: Check that a user value exists and is zero
 + *
 + * Frequently in our uABI we reserve space for future extensions, and
 + * two ensure that userspace is prepared we enforce that space must
 + * be zero. (Then any future extension can safely assume a default value
 + * of 0.)
 + *
 + * check_user_mbz() combines checking that the user pointer is accessible
 + * and that the contained value is zero.
 + *
 + * Returns: -EFAULT if not accessible, -EINVAL if !zero, or 0 on success.
 + */
 +#define check_user_mbz(U) ({                                          \
 +      typeof(*(U)) mbz__;                                             \
 +      get_user(mbz__, (U)) ? -EFAULT : mbz__ ? -EINVAL : 0;           \
 +})
 +
  static inline u64 ptr_to_u64(const void *ptr)
  {
        return (uintptr_t)ptr;
  
  #include <linux/list.h>
  
- static inline int list_is_first(const struct list_head *list,
-                               const struct list_head *head)
- {
-       return head->next == list;
- }
  static inline void __list_del_many(struct list_head *head,
                                   struct list_head *first)
  {
index 66ed3ee5998aecbbac9add552e4e8a2ca2c54459,8352d0bd8813110787e89149325fbeb27ada30c0..848dd9e728d83f9427241e70bb53d6258886fb3c
@@@ -88,8 -88,6 +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);
  
@@@ -267,3 -265,11 +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 3371bf96dabdd7c85a96a47a37be03b9ded66a02,94496488641cb988809efb31003c281b1898faff..8576a7f799f2e0e91230bfc43cf9b3c457956c78
@@@ -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,15 -951,14 +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)
@@@ -1040,7 -1039,7 +1040,7 @@@ intel_wait_for_pipe_off(const struct in
                i915_reg_t reg = PIPECONF(cpu_transcoder);
  
                /* Wait for the Pipe State to go off */
 -              if (intel_wait_for_register(dev_priv,
 +              if (intel_wait_for_register(&dev_priv->uncore,
                                            reg, I965_PIPECONF_ACTIVE, 0,
                                            100))
                        WARN(1, "pipe_off wait timed out\n");
@@@ -1346,7 -1345,7 +1346,7 @@@ static void _vlv_enable_pll(struct inte
        POSTING_READ(DPLL(pipe));
        udelay(150);
  
 -      if (intel_wait_for_register(dev_priv,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    DPLL(pipe),
                                    DPLL_LOCK_VLV,
                                    DPLL_LOCK_VLV,
@@@ -1399,7 -1398,7 +1399,7 @@@ static void _chv_enable_pll(struct inte
        I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll);
  
        /* Check PLL is locked */
 -      if (intel_wait_for_register(dev_priv,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    DPLL(pipe), DPLL_LOCK_VLV, DPLL_LOCK_VLV,
                                    1))
                DRM_ERROR("PLL %d failed to lock\n", pipe);
@@@ -1442,12 -1441,17 +1442,12 @@@ static void chv_enable_pll(struct intel
        }
  }
  
 -static int intel_num_dvo_pipes(struct drm_i915_private *dev_priv)
 +static bool i9xx_has_pps(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);
 -      }
 +      if (IS_I830(dev_priv))
 +              return false;
  
 -      return count;
 +      return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
  }
  
  static void i9xx_enable_pll(struct intel_crtc *crtc,
        assert_pipe_disabled(dev_priv, crtc->pipe);
  
        /* PLL is protected by panel, make sure we can write it */
 -      if (IS_MOBILE(dev_priv) && !IS_I830(dev_priv))
 +      if (i9xx_has_pps(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. */
@@@ -1502,6 -1520,16 +1502,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;
@@@ -1580,7 -1608,7 +1580,7 @@@ void vlv_wait_port_ready(struct drm_i91
                BUG();
        }
  
 -      if (intel_wait_for_register(dev_priv,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    dpll_reg, port_mask, expected_mask,
                                    1000))
                WARN(1, "timed out waiting for port %c ready: got 0x%x, expected 0x%x\n",
@@@ -1630,18 -1658,17 +1630,18 @@@ 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,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    reg, TRANS_STATE_ENABLE, TRANS_STATE_ENABLE,
                                    100))
                DRM_ERROR("failed to enable transcoder %c\n", pipe_name(pipe));
@@@ -1671,7 -1698,7 +1671,7 @@@ static void lpt_enable_pch_transcoder(s
                val |= TRANS_PROGRESSIVE;
  
        I915_WRITE(LPT_TRANSCONF, val);
 -      if (intel_wait_for_register(dev_priv,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    LPT_TRANSCONF,
                                    TRANS_STATE_ENABLE,
                                    TRANS_STATE_ENABLE,
@@@ -1697,7 -1724,7 +1697,7 @@@ static void ironlake_disable_pch_transc
        val &= ~TRANS_ENABLE;
        I915_WRITE(reg, val);
        /* wait for PCH transcoder off, transcoder state */
 -      if (intel_wait_for_register(dev_priv,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    reg, TRANS_STATE_ENABLE, 0,
                                    50))
                DRM_ERROR("failed to disable transcoder %c\n", pipe_name(pipe));
@@@ -1719,7 -1746,7 +1719,7 @@@ void lpt_disable_pch_transcoder(struct 
        val &= ~TRANS_ENABLE;
        I915_WRITE(LPT_TRANSCONF, val);
        /* wait for PCH transcoder off, transcoder state */
 -      if (intel_wait_for_register(dev_priv,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    LPT_TRANSCONF, TRANS_STATE_ENABLE, 0,
                                    50))
                DRM_ERROR("Failed to disable PCH transcoder\n");
@@@ -1803,8 -1830,6 +1803,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) {
@@@ -1844,8 -1869,6 +1844,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)
@@@ -2667,11 -2690,11 +2667,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) {
@@@ -2832,7 -2855,8 +2832,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
@@@ -3236,10 -3260,9 +3236,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)
@@@ -3466,7 -3489,7 +3466,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);
  
@@@ -3625,11 -3648,11 +3625,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);
@@@ -3741,11 -3764,8 +3741,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;
  }
@@@ -3797,11 -3817,8 +3797,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;
  }
@@@ -3960,6 -3977,9 +3960,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);
@@@ -3999,13 -4019,13 +3999,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);
  }
  
@@@ -4044,6 -4064,16 +4044,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);
  }
@@@ -5071,10 -5101,10 +5071,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 "
@@@ -5186,9 -5216,9 +5186,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",
@@@ -5299,7 -5329,7 +5299,7 @@@ void hsw_enable_ips(const struct intel_
                 * and don't wait for vblanks until the end of crtc_enable, then
                 * the HW state readout code will complain that the expected
                 * IPS_CTL value is not the one we read. */
 -              if (intel_wait_for_register(dev_priv,
 +              if (intel_wait_for_register(&dev_priv->uncore,
                                            IPS_CTL, IPS_ENABLE, IPS_ENABLE,
                                            50))
                        DRM_ERROR("Timed out waiting for IPS enable\n");
@@@ -5324,7 -5354,7 +5324,7 @@@ void hsw_disable_ips(const struct intel
                 * 42ms timeout value leads to occasional timeouts so use 100ms
                 * instead.
                 */
 -              if (intel_wait_for_register(dev_priv,
 +              if (intel_wait_for_register(&dev_priv->uncore,
                                            IPS_CTL, IPS_ENABLE, 0,
                                            100))
                        DRM_ERROR("Timed out waiting for IPS disable\n");
@@@ -5643,7 -5673,7 +5643,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;
@@@ -5794,14 -5824,6 +5794,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);
@@@ -5997,9 -6017,6 +5997,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);
@@@ -6180,7 -6197,7 +6180,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;
@@@ -6357,8 -6374,6 +6357,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);
@@@ -6416,8 -6431,6 +6416,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,
@@@ -6800,13 -6813,7 +6800,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. */
@@@ -6881,7 -6888,8 +6881,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;
                }
@@@ -7548,19 -7556,7 +7548,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;
  
@@@ -7768,16 -7764,13 +7768,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));
  }
@@@ -7821,7 -7814,8 +7821,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;
@@@ -7970,22 -7964,14 +7970,22 @@@ static int vlv_crtc_compute_clock(struc
        return 0;
  }
  
 +static bool i9xx_has_pfit(struct drm_i915_private *dev_priv)
 +{
 +      if (IS_I830(dev_priv))
 +              return false;
 +
 +      return INTEL_GEN(dev_priv) >= 4 ||
 +              IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
 +}
 +
  static void i9xx_get_pfit_config(struct intel_crtc *crtc,
                                 struct intel_crtc_state *pipe_config)
  {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        u32 tmp;
  
 -      if (INTEL_GEN(dev_priv) <= 3 &&
 -          (IS_I830(dev_priv) || !IS_MOBILE(dev_priv)))
 +      if (!i9xx_has_pfit(dev_priv))
                return;
  
        tmp = I915_READ(PFIT_CONTROL);
@@@ -8192,24 -8178,6 +8192,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 {
@@@ -8794,8 -8762,6 +8794,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));
  }
@@@ -8876,11 -8842,13 +8876,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;
@@@ -9329,13 -9296,6 +9329,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;
@@@ -9481,8 -9441,7 +9481,8 @@@ static void hsw_disable_lcpll(struct dr
        I915_WRITE(LCPLL_CTL, val);
        POSTING_READ(LCPLL_CTL);
  
 -      if (intel_wait_for_register(dev_priv, LCPLL_CTL, LCPLL_PLL_LOCK, 0, 1))
 +      if (intel_wait_for_register(&dev_priv->uncore,
 +                                  LCPLL_CTL, LCPLL_PLL_LOCK, 0, 1))
                DRM_ERROR("LCPLL still locked\n");
  
        val = hsw_read_dcomp(dev_priv);
@@@ -9520,7 -9479,7 +9520,7 @@@ static void hsw_restore_lcpll(struct dr
         * Make sure we're not on PC8 state before disabling PC8, otherwise
         * we'll hang the machine. To prevent PC8 state, just enable force_wake.
         */
 -      intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 +      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
  
        if (val & LCPLL_POWER_DOWN_ALLOW) {
                val &= ~LCPLL_POWER_DOWN_ALLOW;
        val &= ~LCPLL_PLL_DISABLE;
        I915_WRITE(LCPLL_CTL, val);
  
 -      if (intel_wait_for_register(dev_priv,
 +      if (intel_wait_for_register(&dev_priv->uncore,
                                    LCPLL_CTL, LCPLL_PLL_LOCK, LCPLL_PLL_LOCK,
                                    5))
                DRM_ERROR("LCPLL not locked yet\n");
                        DRM_ERROR("Switching back to LCPLL failed\n");
        }
  
 -      intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 +      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
  
        intel_update_cdclk(dev_priv);
        intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK");
@@@ -9621,11 -9580,11 +9621,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;
@@@ -9663,6 -9622,9 +9663,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 {
@@@ -9756,18 -9718,15 +9756,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.
@@@ -9897,7 -9856,7 +9897,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);
@@@ -9960,7 -9919,7 +9960,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)) {
@@@ -10154,12 -10100,7 +10154,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,
@@@ -10313,10 -10254,9 +10313,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))
@@@ -11305,11 -11245,16 +11305,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;
@@@ -11480,16 -11425,6 +11480,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[] = {
@@@ -11593,22 -11528,6 +11593,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");
@@@ -11757,7 -11676,7 +11757,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;
@@@ -11976,37 -11895,6 +11976,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, ...)
  {
@@@ -12190,17 -12078,7 +12190,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
@@@ -12377,15 -12241,12 +12377,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
@@@ -12667,8 -12517,7 +12667,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
@@@ -13534,7 -13383,7 +13534,7 @@@ static void intel_atomic_commit_tail(st
                 * so enable debugging for the next modeset - and hope we catch
                 * the culprit.
                 */
 -              intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
 +              intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore);
                intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref);
        }
  
@@@ -13727,7 -13576,7 +13727,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);
@@@ -14260,11 -14109,14 +14260,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));
  
@@@ -14714,12 -14566,7 +14714,12 @@@ static void intel_setup_outputs(struct 
        if (!HAS_DISPLAY(dev_priv))
                return;
  
 -      if (IS_ICELAKE(dev_priv)) {
 +      if (IS_ELKHARTLAKE(dev_priv)) {
 +              intel_ddi_init(dev_priv, PORT_A);
 +              intel_ddi_init(dev_priv, PORT_B);
 +              intel_ddi_init(dev_priv, PORT_C);
 +              icl_dsi_init(dev_priv);
 +      } else 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);
@@@ -15620,8 -15467,6 +15620,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);
  
@@@ -15697,7 -15542,7 +15697,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 |
@@@ -16483,8 -16328,6 +16483,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);
@@@ -16531,6 -16374,8 +16531,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;
  
@@@ -16582,8 -16426,6 +16582,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));
@@@ -16694,10 -16537,7 +16694,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 6aab82d8d9c5780f5d544eb2308c217d7bf6e0f8,375f51d14dda344d9256429249c1bbb601bb5fd3..f8c7b291fdc356a8b80eef5c28263de58901187c
@@@ -41,7 -41,6 +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;
@@@ -324,13 -323,6 +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
@@@ -403,32 -395,6 +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 {
@@@ -999,8 -921,7 +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;
@@@ -1091,6 -989,9 +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;
@@@ -1359,15 -1260,11 +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);
  };
  
@@@ -1659,7 -1556,7 +1659,7 @@@ int intel_ddi_toggle_hdcp_signalling(st
                                     bool enable);
  void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
  int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
 -                      enum intel_dpll_id pll_id);
 +                      struct intel_dpll_hw_state *state);
  
  unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
                                   int color_plane, unsigned int height);
@@@ -1841,7 -1738,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);
  
@@@ -1899,6 -1796,7 +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 *);
@@@ -1908,16 -1806,6 +1909,16 @@@ void intel_csr_ucode_suspend(struct drm
  void intel_csr_ucode_resume(struct drm_i915_private *);
  
  /* intel_dp.c */
 +struct link_config_limits {
 +      int min_clock, max_clock;
 +      int min_lane_count, max_lane_count;
 +      int min_bpp, max_bpp;
 +};
 +void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
 +                                     struct intel_crtc_state *pipe_config,
 +                                     struct link_config_limits *limits);
 +bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
 +                                const struct drm_connector_state *conn_state);
  bool intel_dp_port_enabled(struct drm_i915_private *dev_priv,
                           i915_reg_t dp_reg, enum port port,
                           enum pipe *pipe);
@@@ -2112,22 -2000,13 +2113,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);
@@@ -2163,13 -2042,10 +2164,13 @@@ void intel_panel_update_backlight(struc
                                  const struct intel_crtc_state *crtc_state,
                                  const struct drm_connector_state *conn_state);
  void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state);
 -extern struct drm_display_mode *intel_find_panel_downclock(
 -                              struct drm_i915_private *dev_priv,
 -                              struct drm_display_mode *fixed_mode,
 -                              struct drm_connector *connector);
 +struct drm_display_mode *
 +intel_panel_edid_downclock_mode(struct intel_connector *connector,
 +                              const struct drm_display_mode *fixed_mode);
 +struct drm_display_mode *
 +intel_panel_edid_fixed_mode(struct intel_connector *connector);
 +struct drm_display_mode *
 +intel_panel_vbt_fixed_mode(struct intel_connector *connector);
  
  #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
  int intel_backlight_device_register(struct intel_connector *connector);
@@@ -2192,12 -2068,9 +2193,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)
@@@ -2206,9 -2079,9 +2207,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);
@@@ -2279,26 -2152,20 +2280,26 @@@ void icl_dbuf_slices_update(struct drm_
                            u8 req_slices);
  
  static inline void
 -assert_rpm_device_not_suspended(struct drm_i915_private *i915)
 +assert_rpm_device_not_suspended(struct i915_runtime_pm *rpm)
  {
 -      WARN_ONCE(i915->runtime_pm.suspended,
 +      WARN_ONCE(rpm->suspended,
                  "Device suspended during HW access\n");
  }
  
  static inline void
 -assert_rpm_wakelock_held(struct drm_i915_private *i915)
 +__assert_rpm_wakelock_held(struct i915_runtime_pm *rpm)
  {
 -      assert_rpm_device_not_suspended(i915);
 -      WARN_ONCE(!atomic_read(&i915->runtime_pm.wakeref_count),
 +      assert_rpm_device_not_suspended(rpm);
 +      WARN_ONCE(!atomic_read(&rpm->wakeref_count),
                  "RPM wakelock ref not held during HW access");
  }
  
 +static inline void
 +assert_rpm_wakelock_held(struct drm_i915_private *i915)
 +{
 +      __assert_rpm_wakelock_held(&i915->runtime_pm);
 +}
 +
  /**
   * disable_rpm_wakeref_asserts - disable the RPM assert checks
   * @i915: i915 device instance
@@@ -2390,10 -2257,11 +2391,10 @@@ void intel_cleanup_gt_powersave(struct 
  void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv);
  void intel_enable_gt_powersave(struct drm_i915_private *dev_priv);
  void intel_disable_gt_powersave(struct drm_i915_private *dev_priv);
 -void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv);
  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);
@@@ -2507,14 -2375,6 +2508,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);
@@@ -2544,15 -2404,11 +2545,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 07893ad2ad1f93c0c56e07a1bf69def94adfc349,765718b606d857a9993a91bfff92365452599f1e..26767785f14aa2d9120e53641f5f03752c90731a
@@@ -82,8 -82,6 +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:
@@@ -147,8 -135,6 +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:
@@@ -214,37 -200,17 +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);
@@@ -289,28 -255,7 +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 |
@@@ -371,28 -316,7 +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 |
@@@ -446,28 -370,7 +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 |
@@@ -520,24 -423,7 +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)
@@@ -906,10 -676,7 +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)
@@@ -1378,44 -1085,10 +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;
  }
  
@@@ -1466,190 -1131,6 +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,
@@@ -1731,6 -1207,7 +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,
@@@ -2204,7 -1666,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;
@@@ -2362,23 -1824,6 +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;
  }
  
@@@ -2498,7 -1943,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;
  
@@@ -2700,10 -2145,21 +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;
  
@@@ -2888,14 -2344,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);
  
@@@ -2912,36 -2368,33 +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;
        }
  }
  
@@@ -2987,9 -2440,6 +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 aee4defcb88dbade75c4480cd455270c2b7d4bdf,53174d5795741947b609d9c269ba03ed29e675a0..3f2055f70d05123313e769b7e328ed4615973047
@@@ -622,9 -622,6 +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);
@@@ -757,12 -754,7 +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,
@@@ -937,12 -929,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;
@@@ -1128,15 -1120,7 +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,
@@@ -1821,7 -1805,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[] = {
@@@ -2101,9 -2085,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 a438ec8e535b4beeedd895f88f486029231ae091,45f944d57982800cc176ed782aedbf9b1d30f1fe..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,6 -539,9 +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.370161 seconds and 4 git commands to generate.