Merge tag 'topic/hdcp-2018-02-13' of git://anongit.freedesktop.org/drm/drm-misc into...
authorDave Airlie <airlied@redhat.com>
Thu, 15 Feb 2018 23:36:04 +0000 (09:36 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 15 Feb 2018 23:36:04 +0000 (09:36 +1000)
Add HDCP support to i915 drm driver.

* tag 'topic/hdcp-2018-02-13' of git://anongit.freedesktop.org/drm/drm-misc: (26 commits)
  drm/i915: fix misalignment in HDCP register def
  drm/i915: Reauthenticate HDCP on failure
  drm/i915: Detect panel's hdcp capability
  drm/i915: Optimize HDCP key load
  drm/i915: Retry HDCP bksv read
  drm/i915: Connector info in HDCP debug msgs
  drm/i915: Stop encryption for repeater with no sink
  drm/i915: Handle failure from 2nd stage HDCP auth
  drm/i915: Downgrade hdcp logs from INFO to DEBUG_KMS
  drm/i915: Restore HDCP DRM_INFO when with no downstream
  drm/i915: Check for downstream topology errors
  drm/i915: Start repeater auth on READY/CP_IRQ
  drm/i915: II stage HDCP auth for repeater only
  drm/i915: Extending HDCP for HSW, BDW and BXT+
  drm/i915/dp: Fix compilation of intel_dp_hdcp_check_link
  drm/i915: Only disable HDCP when it's active
  drm/i915: Don't allow HDCP on PORT E/F
  drm/i915: Implement HDCP for DisplayPort
  drm/i915: Implement HDCP for HDMI
  drm/i915: Add function to output Aksv over GMBUS
  ...

14 files changed:
1  2 
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_uncore.c
include/drm/drm_dp_helper.h
include/uapi/drm/drm_mode.h

index 7d9ad20040a18480c71a03a906b9ed9b2bd472bd,69ff763a834e5d2bc2fb9335cbc6fd6cea88da3d..46733d534587bc15be02b225f7e092f16af1d645
@@@ -390,7 -390,7 +390,7 @@@ int drm_atomic_set_mode_prop_for_crtc(s
  
        if (blob) {
                if (blob->length != sizeof(struct drm_mode_modeinfo) ||
 -                  drm_mode_convert_umode(&state->mode,
 +                  drm_mode_convert_umode(state->crtc->dev, &state->mode,
                                           (const struct drm_mode_modeinfo *)
                                            blob->data))
                        return -EINVAL;
@@@ -863,10 -863,10 +863,10 @@@ static int drm_atomic_plane_check(struc
        int ret;
  
        /* either *both* CRTC and FB must be set, or neither */
 -      if (WARN_ON(state->crtc && !state->fb)) {
 +      if (state->crtc && !state->fb) {
                DRM_DEBUG_ATOMIC("CRTC set but no FB\n");
                return -EINVAL;
 -      } else if (WARN_ON(state->fb && !state->crtc)) {
 +      } else if (state->fb && !state->crtc) {
                DRM_DEBUG_ATOMIC("FB set but no CRTC\n");
                return -EINVAL;
        }
@@@ -1224,6 -1224,12 +1224,12 @@@ static int drm_atomic_connector_set_pro
                state->picture_aspect_ratio = val;
        } else if (property == connector->scaling_mode_property) {
                state->scaling_mode = val;
+       } else if (property == connector->content_protection_property) {
+               if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+                       DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
+                       return -EINVAL;
+               }
+               state->content_protection = val;
        } else if (connector->funcs->atomic_set_property) {
                return connector->funcs->atomic_set_property(connector,
                                state, property, val);
@@@ -1303,6 -1309,8 +1309,8 @@@ drm_atomic_connector_get_property(struc
                *val = state->picture_aspect_ratio;
        } else if (property == connector->scaling_mode_property) {
                *val = state->scaling_mode;
+       } else if (property == connector->content_protection_property) {
+               *val = state->content_protection;
        } else if (connector->funcs->atomic_get_property) {
                return connector->funcs->atomic_get_property(connector,
                                state, property, val);
index d6a7eba087a0a98faa2cc25f0e0cf6357b5542cc,b85a7749709d35c60def0aa24c1af7e0d9993846..16b9c3810af22c9920bfea381618cb04fe9d2227
@@@ -205,14 -205,9 +205,14 @@@ int drm_connector_init(struct drm_devic
        connector->dev = dev;
        connector->funcs = funcs;
  
 -      ret = ida_simple_get(&config->connector_ida, 0, 0, GFP_KERNEL);
 -      if (ret < 0)
 +      /* connector index is used with 32bit bitmasks */
 +      ret = ida_simple_get(&config->connector_ida, 0, 32, GFP_KERNEL);
 +      if (ret < 0) {
 +              DRM_DEBUG_KMS("Failed to allocate %s connector index: %d\n",
 +                            drm_connector_enum_list[connector_type].name,
 +                            ret);
                goto out_put;
 +      }
        connector->index = ret;
        ret = 0;
  
@@@ -761,6 -756,13 +761,13 @@@ static const struct drm_prop_enum_list 
  DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
                 drm_tv_subconnector_enum_list)
  
+ static struct drm_prop_enum_list drm_cp_enum_list[] = {
+       { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
+       { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
+       { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
+ };
+ DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
  /**
   * DOC: standard connector properties
   *
   *    should update this value using drm_mode_connector_set_tile_property().
   *    Userspace cannot change this property.
   * link-status:
-  *      Connector link-status property to indicate the status of link. The default
-  *      value of link-status is "GOOD". If something fails during or after modeset,
-  *      the kernel driver may set this to "BAD" and issue a hotplug uevent. Drivers
-  *      should update this value using drm_mode_connector_set_link_status_property().
+  *      Connector link-status property to indicate the status of link. The
+  *      default value of link-status is "GOOD". If something fails during or
+  *      after modeset, the kernel driver may set this to "BAD" and issue a
+  *      hotplug uevent. Drivers should update this value using
+  *      drm_mode_connector_set_link_status_property().
   * non_desktop:
   *    Indicates the output should be ignored for purposes of displaying a
   *    standard desktop environment or console. This is most likely because
   *    the output device is not rectilinear.
+  * Content Protection:
+  *    This property is used by userspace to request the kernel protect future
+  *    content communicated over the link. When requested, kernel will apply
+  *    the appropriate means of protection (most often HDCP), and use the
+  *    property to tell userspace the protection is active.
+  *
+  *    Drivers can set this up by calling
+  *    drm_connector_attach_content_protection_property() on initialization.
+  *
+  *    The value of this property can be one of the following:
+  *
+  *    - DRM_MODE_CONTENT_PROTECTION_UNDESIRED = 0
+  *            The link is not protected, content is transmitted in the clear.
+  *    - DRM_MODE_CONTENT_PROTECTION_DESIRED = 1
+  *            Userspace has requested content protection, but the link is not
+  *            currently protected. When in this state, kernel should enable
+  *            Content Protection as soon as possible.
+  *    - DRM_MODE_CONTENT_PROTECTION_ENABLED = 2
+  *            Userspace has requested content protection, and the link is
+  *            protected. Only the driver can set the property to this value.
+  *            If userspace attempts to set to ENABLED, kernel will return
+  *            -EINVAL.
+  *
+  *    A few guidelines:
+  *
+  *    - DESIRED state should be preserved until userspace de-asserts it by
+  *      setting the property to UNDESIRED. This means ENABLED should only
+  *      transition to UNDESIRED when the user explicitly requests it.
+  *    - If the state is DESIRED, kernel should attempt to re-authenticate the
+  *      link whenever possible. This includes across disable/enable, dpms,
+  *      hotplug, downstream device changes, link status failures, etc..
+  *    - Userspace is responsible for polling the property to determine when
+  *      the value transitions from ENABLED to DESIRED. This signifies the link
+  *      is no longer protected and userspace should take appropriate action
+  *      (whatever that might be).
   *
   * Connectors also have one standardized atomic property:
   *
@@@ -1130,6 -1168,42 +1173,42 @@@ int drm_connector_attach_scaling_mode_p
  }
  EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
  
+ /**
+  * drm_connector_attach_content_protection_property - attach content protection
+  * property
+  *
+  * @connector: connector to attach CP property on.
+  *
+  * This is used to add support for content protection on select connectors.
+  * Content Protection is intentionally vague to allow for different underlying
+  * technologies, however it is most implemented by HDCP.
+  *
+  * The content protection will be set to &drm_connector_state.content_protection
+  *
+  * Returns:
+  * Zero on success, negative errno on failure.
+  */
+ int drm_connector_attach_content_protection_property(
+               struct drm_connector *connector)
+ {
+       struct drm_device *dev = connector->dev;
+       struct drm_property *prop;
+       prop = drm_property_create_enum(dev, 0, "Content Protection",
+                                       drm_cp_enum_list,
+                                       ARRAY_SIZE(drm_cp_enum_list));
+       if (!prop)
+               return -ENOMEM;
+       drm_object_attach_property(&connector->base, prop,
+                                  DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
+       connector->content_protection_property = prop;
+       return 0;
+ }
+ EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
  /**
   * drm_mode_create_aspect_ratio_property - create aspect ratio property
   * @dev: DRM device
index 4d9e2f855e9d8f3e2a729db3e0ab93c704546a1f,7de05dc80f13a18a1e5e7fa889326c06f303f40d..3bddd8a068066d2ef23c2e1c7de11514c1bf93c1
@@@ -83,7 -83,6 +83,7 @@@ i915-y += i915_cmd_parser.o 
  i915-y += intel_uc.o \
          intel_uc_fw.o \
          intel_guc.o \
 +        intel_guc_ads.o \
          intel_guc_ct.o \
          intel_guc_fw.o \
          intel_guc_log.o \
@@@ -109,6 -108,7 +109,7 @@@ i915-y += intel_audio.o 
          intel_fbc.o \
          intel_fifo_underrun.o \
          intel_frontbuffer.o \
+         intel_hdcp.o \
          intel_hotplug.o \
          intel_modes.o \
          intel_overlay.o \
index 60079a69c2f9658f9ff13ad68853585219241032,a689396d0ff6d7cea5ae4c544c2ad7908f26a5eb..ad1fc845cd1b2bbf076f38101c2c19c109e09420
@@@ -83,8 -83,8 +83,8 @@@
  
  #define DRIVER_NAME           "i915"
  #define DRIVER_DESC           "Intel Graphics"
 -#define DRIVER_DATE           "20171222"
 -#define DRIVER_TIMESTAMP      1513971710
 +#define DRIVER_DATE           "20180207"
 +#define DRIVER_TIMESTAMP      1517988364
  
  /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
   * WARN_ON()) for hw state sanity checks to check for unexpected conditions
  #define I915_STATE_WARN_ON(x)                                         \
        I915_STATE_WARN((x), "%s", "WARN_ON(" __stringify(x) ")")
  
 +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
  bool __i915_inject_load_failure(const char *func, int line);
  #define i915_inject_load_failure() \
        __i915_inject_load_failure(__func__, __LINE__)
 +#else
 +#define i915_inject_load_failure() false
 +#endif
  
  typedef struct {
        uint32_t val;
@@@ -457,9 -453,9 +457,9 @@@ struct intel_display_error_state
  
  struct i915_gpu_state {
        struct kref ref;
 -      struct timeval time;
 -      struct timeval boottime;
 -      struct timeval uptime;
 +      ktime_t time;
 +      ktime_t boottime;
 +      ktime_t uptime;
  
        struct drm_i915_private *i915;
  
                        int ban_score;
                        int active;
                        int guilty;
 +                      bool bannable;
                } context;
  
                struct drm_i915_error_object {
@@@ -759,6 -754,7 +759,6 @@@ struct i915_drrs 
  struct i915_psr {
        struct mutex lock;
        bool sink_support;
 -      bool source_ok;
        struct intel_dp *enabled;
        bool active;
        struct delayed_work work;
@@@ -787,7 -783,6 +787,7 @@@ enum intel_pch 
        PCH_SPT,        /* Sunrisepoint PCH */
        PCH_KBP,        /* Kaby Lake PCH */
        PCH_CNP,        /* Cannon Lake PCH */
 +      PCH_ICP,        /* Ice Lake PCH */
        PCH_NOP,
  };
  
@@@ -1260,7 -1255,6 +1260,7 @@@ enum modeset_restore 
  #define DP_AUX_B 0x10
  #define DP_AUX_C 0x20
  #define DP_AUX_D 0x30
 +#define DP_AUX_F 0x60
  
  #define DDC_PIN_B  0x05
  #define DDC_PIN_C  0x04
@@@ -1287,7 -1281,6 +1287,7 @@@ struct ddi_vbt_port_info 
  
        uint8_t dp_boost_level;
        uint8_t hdmi_boost_level;
 +      int dp_max_link_rate;           /* 0 for not limited by VBT */
  };
  
  enum psr_lines_to_wait {
@@@ -1467,7 -1460,6 +1467,7 @@@ struct skl_wm_params 
        uint_fixed_16_16_t plane_blocks_per_line;
        uint_fixed_16_16_t y_tile_minimum;
        uint32_t linetime_us;
 +      uint32_t dbuf_block_size;
  };
  
  /*
@@@ -1800,7 -1792,7 +1800,7 @@@ struct i915_oa_ops 
  };
  
  struct intel_cdclk_state {
 -      unsigned int cdclk, vco, ref;
 +      unsigned int cdclk, vco, ref, bypass;
        u8 voltage_level;
  };
  
@@@ -2320,12 -2312,6 +2320,12 @@@ struct drm_i915_private 
                 */
                bool awake;
  
 +              /**
 +               * The number of times we have woken up.
 +               */
 +              unsigned int epoch;
 +#define I915_EPOCH_INVALID 0
 +
                /**
                 * We leave the user IRQ off as much as possible,
                 * but this means that requests will finish and never
@@@ -2418,11 -2404,16 +2418,11 @@@ enum hdmi_force_audio 
   *
   * We have one bit per pipe and per scanout plane type.
   */
 -#define INTEL_MAX_SPRITE_BITS_PER_PIPE 5
  #define INTEL_FRONTBUFFER_BITS_PER_PIPE 8
 -#define INTEL_FRONTBUFFER_PRIMARY(pipe) \
 -      (1 << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
 -#define INTEL_FRONTBUFFER_CURSOR(pipe) \
 -      (1 << (1 + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
 -#define INTEL_FRONTBUFFER_SPRITE(pipe, plane) \
 -      (1 << (2 + plane + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
 +#define INTEL_FRONTBUFFER(pipe, plane_id) \
 +      (1 << ((plane_id) + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
  #define INTEL_FRONTBUFFER_OVERLAY(pipe) \
 -      (1 << (2 + INTEL_MAX_SPRITE_BITS_PER_PIPE + (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
 +      (1 << (INTEL_FRONTBUFFER_BITS_PER_PIPE - 1 + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
  #define INTEL_FRONTBUFFER_ALL_MASK(pipe) \
        (0xff << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
  
@@@ -2604,7 -2595,6 +2604,7 @@@ intel_info(const struct drm_i915_privat
  #define IS_GEMINILAKE(dev_priv)       IS_PLATFORM(dev_priv, INTEL_GEMINILAKE)
  #define IS_COFFEELAKE(dev_priv)       IS_PLATFORM(dev_priv, INTEL_COFFEELAKE)
  #define IS_CANNONLAKE(dev_priv)       IS_PLATFORM(dev_priv, INTEL_CANNONLAKE)
 +#define IS_ICELAKE(dev_priv)  IS_PLATFORM(dev_priv, INTEL_ICELAKE)
  #define IS_MOBILE(dev_priv)   ((dev_priv)->info.is_mobile)
  #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \
                                    (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00)
                                 (dev_priv)->info.gt == 2)
  #define IS_CFL_GT3(dev_priv)  (IS_COFFEELAKE(dev_priv) && \
                                 (dev_priv)->info.gt == 3)
 +#define IS_CNL_WITH_PORT_F(dev_priv)   (IS_CANNONLAKE(dev_priv) && \
 +                                      (INTEL_DEVID(dev_priv) & 0x0004) == 0x0004)
  
  #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support)
  
  #define IS_GEN8(dev_priv)     (!!((dev_priv)->info.gen_mask & BIT(7)))
  #define IS_GEN9(dev_priv)     (!!((dev_priv)->info.gen_mask & BIT(8)))
  #define IS_GEN10(dev_priv)    (!!((dev_priv)->info.gen_mask & BIT(9)))
 +#define IS_GEN11(dev_priv)    (!!((dev_priv)->info.gen_mask & BIT(10)))
  
  #define IS_LP(dev_priv)       (INTEL_INFO(dev_priv)->is_lp)
  #define IS_GEN9_LP(dev_priv)  (IS_GEN9(dev_priv) && IS_LP(dev_priv))
  #define INTEL_PCH_KBP_DEVICE_ID_TYPE          0xA280
  #define INTEL_PCH_CNP_DEVICE_ID_TYPE          0xA300
  #define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE               0x9D80
 +#define INTEL_PCH_ICP_DEVICE_ID_TYPE          0x3480
  #define INTEL_PCH_P2X_DEVICE_ID_TYPE          0x7100
  #define INTEL_PCH_P3X_DEVICE_ID_TYPE          0x7000
  #define INTEL_PCH_QEMU_DEVICE_ID_TYPE         0x2900 /* qemu q35 has 2918 */
  
  #define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type)
 +#define HAS_PCH_ICP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ICP)
  #define HAS_PCH_CNP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CNP)
  #define HAS_PCH_CNP_LP(dev_priv) \
        ((dev_priv)->pch_id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE)
@@@ -2965,10 -2950,8 +2965,10 @@@ void intel_hpd_irq_handler(struct drm_i
  void intel_hpd_init(struct drm_i915_private *dev_priv);
  void intel_hpd_init_work(struct drm_i915_private *dev_priv);
  void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
 -enum port intel_hpd_pin_to_port(enum hpd_pin pin);
 -enum hpd_pin intel_hpd_pin(enum port port);
 +enum port intel_hpd_pin_to_port(struct drm_i915_private *dev_priv,
 +                              enum hpd_pin pin);
 +enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
 +                                 enum port port);
  bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
  void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
  
@@@ -3661,6 -3644,7 +3661,7 @@@ extern int intel_setup_gmbus(struct drm
  extern void intel_teardown_gmbus(struct drm_i915_private *dev_priv);
  extern bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
                                     unsigned int pin);
+ extern int intel_gmbus_output_aksv(struct i2c_adapter *adapter);
  
  extern struct i2c_adapter *
  intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin);
@@@ -3734,12 -3718,7 +3735,12 @@@ extern void intel_display_print_error_s
                                            struct intel_display_error_state *error);
  
  int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
 -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
 +int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, u32 mbox,
 +                                  u32 val, int fast_timeout_us,
 +                                  int slow_timeout_ms);
 +#define sandybridge_pcode_write(dev_priv, mbox, val)  \
 +      sandybridge_pcode_write_timeout(dev_priv, mbox, val, 500, 0)
 +
  int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
                      u32 reply_mask, u32 reply, int timeout_base_ms);
  
index 1489dd3b3ec2b15f47d0d99bca355e708f774e45,800ef0c9f317a7e7de92663250aa9f33003541e2..e9c79b5608237c226ee979338343ecdd9d175115
@@@ -1304,7 -1304,6 +1304,7 @@@ enum i915_power_well_id 
        SKL_DISP_PW_DDI_B,
        SKL_DISP_PW_DDI_C,
        SKL_DISP_PW_DDI_D,
 +      CNL_DISP_PW_DDI_F = 6,
  
        GLK_DISP_PW_AUX_A = 8,
        GLK_DISP_PW_AUX_B,
        CNL_DISP_PW_AUX_B = GLK_DISP_PW_AUX_B,
        CNL_DISP_PW_AUX_C = GLK_DISP_PW_AUX_C,
        CNL_DISP_PW_AUX_D,
 +      CNL_DISP_PW_AUX_F,
  
        SKL_DISP_PW_1 = 14,
        SKL_DISP_PW_2,
  #define _CNL_PORT_TX_DW2_LN0_B                0x162648
  #define _CNL_PORT_TX_DW2_LN0_C                0x162C48
  #define _CNL_PORT_TX_DW2_LN0_D                0x162E48
 -#define _CNL_PORT_TX_DW2_LN0_F                0x162A48
 +#define _CNL_PORT_TX_DW2_LN0_F                0x162848
  #define CNL_PORT_TX_DW2_GRP(port)     _MMIO_PORT6(port, \
                                                    _CNL_PORT_TX_DW2_GRP_AE, \
                                                    _CNL_PORT_TX_DW2_GRP_B, \
  
  #define GEN8_FAULT_TLB_DATA0          _MMIO(0x4b10)
  #define GEN8_FAULT_TLB_DATA1          _MMIO(0x4b14)
 +#define   FAULT_VA_HIGH_BITS          (0xf << 0)
 +#define   FAULT_GTT_SEL                       (1 << 4)
  
  #define FPGA_DBG              _MMIO(0x42300)
  #define   FPGA_DBG_RM_NOCLAIM (1<<31)
  #define   GFX_FORWARD_VBLANK_ALWAYS   (1<<5)
  #define   GFX_FORWARD_VBLANK_COND     (2<<5)
  
 +#define   GEN11_GFX_DISABLE_LEGACY_MODE       (1<<3)
 +
  #define VLV_DISPLAY_BASE 0x180000
  #define VLV_MIPI_BASE VLV_DISPLAY_BASE
  #define BXT_MIPI_BASE 0x60000
  #define LM_FIFO_WATERMARK   0x0000001F
  #define MI_ARB_STATE  _MMIO(0x20e4) /* 915+ only */
  
 +#define MBUS_ABOX_CTL                 _MMIO(0x45038)
 +#define MBUS_ABOX_BW_CREDIT_MASK      (3 << 20)
 +#define MBUS_ABOX_BW_CREDIT(x)                ((x) << 20)
 +#define MBUS_ABOX_B_CREDIT_MASK               (0xF << 16)
 +#define MBUS_ABOX_B_CREDIT(x)         ((x) << 16)
 +#define MBUS_ABOX_BT_CREDIT_POOL2_MASK        (0x1F << 8)
 +#define MBUS_ABOX_BT_CREDIT_POOL2(x)  ((x) << 8)
 +#define MBUS_ABOX_BT_CREDIT_POOL1_MASK        (0x1F << 0)
 +#define MBUS_ABOX_BT_CREDIT_POOL1(x)  ((x) << 0)
 +
 +#define _PIPEA_MBUS_DBOX_CTL          0x7003C
 +#define _PIPEB_MBUS_DBOX_CTL          0x7103C
 +#define PIPE_MBUS_DBOX_CTL(pipe)      _MMIO_PIPE(pipe, _PIPEA_MBUS_DBOX_CTL, \
 +                                                 _PIPEB_MBUS_DBOX_CTL)
 +#define MBUS_DBOX_BW_CREDIT_MASK      (3 << 14)
 +#define MBUS_DBOX_BW_CREDIT(x)                ((x) << 14)
 +#define MBUS_DBOX_B_CREDIT_MASK               (0x1F << 8)
 +#define MBUS_DBOX_B_CREDIT(x)         ((x) << 8)
 +#define MBUS_DBOX_A_CREDIT_MASK               (0xF << 0)
 +#define MBUS_DBOX_A_CREDIT(x)         ((x) << 0)
 +
 +#define MBUS_UBOX_CTL                 _MMIO(0x4503C)
 +#define MBUS_BBOX_CTL_S1              _MMIO(0x45040)
 +#define MBUS_BBOX_CTL_S2              _MMIO(0x45044)
 +
  /* Make render/texture TLB fetches lower priorty than associated data
   *   fetches. This is not turned on by default
   */
  # define GPIO_DATA_PULLUP_DISABLE     (1 << 13)
  
  #define GMBUS0                        _MMIO(dev_priv->gpio_mmio_base + 0x5100) /* clock/port select */
+ #define   GMBUS_AKSV_SELECT   (1<<11)
  #define   GMBUS_RATE_100KHZ   (0<<8)
  #define   GMBUS_RATE_50KHZ    (1<<8)
  #define   GMBUS_RATE_400KHZ   (2<<8) /* reserved on Pineview */
  #define   GMBUS_PIN_2_BXT     2
  #define   GMBUS_PIN_3_BXT     3
  #define   GMBUS_PIN_4_CNP     4
 -#define   GMBUS_NUM_PINS      7 /* including 0 */
 +#define   GMBUS_PIN_9_TC1_ICP 9
 +#define   GMBUS_PIN_10_TC2_ICP        10
 +#define   GMBUS_PIN_11_TC3_ICP        11
 +#define   GMBUS_PIN_12_TC4_ICP        12
 +
 +#define   GMBUS_NUM_PINS      13 /* including 0 */
  #define GMBUS1                        _MMIO(dev_priv->gpio_mmio_base + 0x5104) /* command/status */
  #define   GMBUS_SW_CLR_INT    (1<<31)
  #define   GMBUS_SW_RDY                (1<<30)
@@@ -4100,7 -4065,7 +4101,7 @@@ enum 
  #define EDP_PSR_AUX_CTL                               _MMIO(dev_priv->psr_mmio_base + 0x10)
  #define EDP_PSR_AUX_DATA(i)                   _MMIO(dev_priv->psr_mmio_base + 0x14 + (i) * 4) /* 5 registers */
  
 -#define EDP_PSR_STATUS_CTL                    _MMIO(dev_priv->psr_mmio_base + 0x40)
 +#define EDP_PSR_STATUS                                _MMIO(dev_priv->psr_mmio_base + 0x40)
  #define   EDP_PSR_STATUS_STATE_MASK           (7<<29)
  #define   EDP_PSR_STATUS_STATE_IDLE           (0<<29)
  #define   EDP_PSR_STATUS_STATE_SRDONACK               (1<<29)
  #define EDP_PSR_PERF_CNT              _MMIO(dev_priv->psr_mmio_base + 0x44)
  #define   EDP_PSR_PERF_CNT_MASK               0xffffff
  
 -#define EDP_PSR_DEBUG_CTL             _MMIO(dev_priv->psr_mmio_base + 0x60)
 +#define EDP_PSR_DEBUG                         _MMIO(dev_priv->psr_mmio_base + 0x60)
  #define   EDP_PSR_DEBUG_MASK_MAX_SLEEP         (1<<28)
  #define   EDP_PSR_DEBUG_MASK_LPSP              (1<<27)
  #define   EDP_PSR_DEBUG_MASK_MEMUP             (1<<26)
  #define   EDP_PSR2_IDLE_MASK          0xf
  #define   EDP_PSR2_FRAME_BEFORE_SU(a) ((a)<<4)
  
 -#define EDP_PSR2_STATUS_CTL            _MMIO(0x6f940)
 +#define EDP_PSR2_STATUS                       _MMIO(0x6f940)
  #define EDP_PSR2_STATUS_STATE_MASK     (0xf<<28)
  #define EDP_PSR2_STATUS_STATE_SHIFT    28
  
  #define _DPD_AUX_CH_DATA4     (dev_priv->info.display_mmio_offset + 0x64320)
  #define _DPD_AUX_CH_DATA5     (dev_priv->info.display_mmio_offset + 0x64324)
  
 +#define _DPF_AUX_CH_CTL               (dev_priv->info.display_mmio_offset + 0x64510)
 +#define _DPF_AUX_CH_DATA1     (dev_priv->info.display_mmio_offset + 0x64514)
 +#define _DPF_AUX_CH_DATA2     (dev_priv->info.display_mmio_offset + 0x64518)
 +#define _DPF_AUX_CH_DATA3     (dev_priv->info.display_mmio_offset + 0x6451c)
 +#define _DPF_AUX_CH_DATA4     (dev_priv->info.display_mmio_offset + 0x64520)
 +#define _DPF_AUX_CH_DATA5     (dev_priv->info.display_mmio_offset + 0x64524)
 +
  #define DP_AUX_CH_CTL(port)   _MMIO_PORT(port, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL)
  #define DP_AUX_CH_DATA(port, i)       _MMIO(_PORT(port, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
  
  #define _PLANE_CTL_3_A                                0x70380
  #define   PLANE_CTL_ENABLE                    (1 << 31)
  #define   PLANE_CTL_PIPE_GAMMA_ENABLE         (1 << 30)   /* Pre-GLK */
 +/*
 + * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition
 + * expanded to include bit 23 as well. However, the shift-24 based values
 + * correctly map to the same formats in ICL, as long as bit 23 is set to 0
 + */
  #define   PLANE_CTL_FORMAT_MASK                       (0xf << 24)
  #define   PLANE_CTL_FORMAT_YUV422             (  0 << 24)
  #define   PLANE_CTL_FORMAT_NV12                       (  1 << 24)
  #define   PLANE_CTL_FORMAT_AYUV                       (  8 << 24)
  #define   PLANE_CTL_FORMAT_INDEXED            ( 12 << 24)
  #define   PLANE_CTL_FORMAT_RGB_565            ( 14 << 24)
 +#define   ICL_PLANE_CTL_FORMAT_MASK           (0x1f << 23)
  #define   PLANE_CTL_PIPE_CSC_ENABLE           (1 << 23) /* Pre-GLK */
  #define   PLANE_CTL_KEY_ENABLE_MASK           (0x3 << 21)
  #define   PLANE_CTL_KEY_ENABLE_SOURCE         (  1 << 21)
  #define GEN8_DE_PORT_IMR _MMIO(0x44444)
  #define GEN8_DE_PORT_IIR _MMIO(0x44448)
  #define GEN8_DE_PORT_IER _MMIO(0x4444c)
 +#define  CNL_AUX_CHANNEL_F            (1 << 28)
  #define  GEN9_AUX_CHANNEL_D           (1 << 27)
  #define  GEN9_AUX_CHANNEL_C           (1 << 26)
  #define  GEN9_AUX_CHANNEL_B           (1 << 25)
  #define GEN8_PCU_IIR _MMIO(0x444e8)
  #define GEN8_PCU_IER _MMIO(0x444ec)
  
 +#define GEN11_GFX_MSTR_IRQ            _MMIO(0x190010)
 +#define  GEN11_MASTER_IRQ             (1 << 31)
 +#define  GEN11_PCU_IRQ                        (1 << 30)
 +#define  GEN11_DISPLAY_IRQ            (1 << 16)
 +#define  GEN11_GT_DW_IRQ(x)           (1 << (x))
 +#define  GEN11_GT_DW1_IRQ             (1 << 1)
 +#define  GEN11_GT_DW0_IRQ             (1 << 0)
 +
 +#define GEN11_DISPLAY_INT_CTL         _MMIO(0x44200)
 +#define  GEN11_DISPLAY_IRQ_ENABLE     (1 << 31)
 +#define  GEN11_AUDIO_CODEC_IRQ                (1 << 24)
 +#define  GEN11_DE_PCH_IRQ             (1 << 23)
 +#define  GEN11_DE_MISC_IRQ            (1 << 22)
 +#define  GEN11_DE_PORT_IRQ            (1 << 20)
 +#define  GEN11_DE_PIPE_C              (1 << 18)
 +#define  GEN11_DE_PIPE_B              (1 << 17)
 +#define  GEN11_DE_PIPE_A              (1 << 16)
 +
 +#define GEN11_GT_INTR_DW0             _MMIO(0x190018)
 +#define  GEN11_CSME                   (31)
 +#define  GEN11_GUNIT                  (28)
 +#define  GEN11_GUC                    (25)
 +#define  GEN11_WDPERF                 (20)
 +#define  GEN11_KCR                    (19)
 +#define  GEN11_GTPM                   (16)
 +#define  GEN11_BCS                    (15)
 +#define  GEN11_RCS0                   (0)
 +
 +#define GEN11_GT_INTR_DW1             _MMIO(0x19001c)
 +#define  GEN11_VECS(x)                        (31 - (x))
 +#define  GEN11_VCS(x)                 (x)
 +
 +#define GEN11_GT_INTR_DW(x)           _MMIO(0x190018 + (x * 4))
 +
 +#define GEN11_INTR_IDENTITY_REG0      _MMIO(0x190060)
 +#define GEN11_INTR_IDENTITY_REG1      _MMIO(0x190064)
 +#define  GEN11_INTR_DATA_VALID                (1 << 31)
 +#define  GEN11_INTR_ENGINE_MASK               (0xffff)
 +
 +#define GEN11_INTR_IDENTITY_REG(x)    _MMIO(0x190060 + (x * 4))
 +
 +#define GEN11_IIR_REG0_SELECTOR               _MMIO(0x190070)
 +#define GEN11_IIR_REG1_SELECTOR               _MMIO(0x190074)
 +
 +#define GEN11_IIR_REG_SELECTOR(x)     _MMIO(0x190070 + (x * 4))
 +
 +#define GEN11_RENDER_COPY_INTR_ENABLE _MMIO(0x190030)
 +#define GEN11_VCS_VECS_INTR_ENABLE    _MMIO(0x190034)
 +#define GEN11_GUC_SG_INTR_ENABLE      _MMIO(0x190038)
 +#define GEN11_GPM_WGBOXPERF_INTR_ENABLE       _MMIO(0x19003c)
 +#define GEN11_CRYPTO_RSVD_INTR_ENABLE _MMIO(0x190040)
 +#define GEN11_GUNIT_CSME_INTR_ENABLE  _MMIO(0x190044)
 +
 +#define GEN11_RCS0_RSVD_INTR_MASK     _MMIO(0x190090)
 +#define GEN11_BCS_RSVD_INTR_MASK      _MMIO(0x1900a0)
 +#define GEN11_VCS0_VCS1_INTR_MASK     _MMIO(0x1900a8)
 +#define GEN11_VCS2_VCS3_INTR_MASK     _MMIO(0x1900ac)
 +#define GEN11_VECS0_VECS1_INTR_MASK   _MMIO(0x1900d0)
 +#define GEN11_GUC_SG_INTR_MASK                _MMIO(0x1900e8)
 +#define GEN11_GPM_WGBOXPERF_INTR_MASK _MMIO(0x1900ec)
 +#define GEN11_CRYPTO_RSVD_INTR_MASK   _MMIO(0x1900f0)
 +#define GEN11_GUNIT_CSME_INTR_MASK    _MMIO(0x1900f4)
 +
  #define ILK_DISPLAY_CHICKEN2  _MMIO(0x42004)
  /* Required on all Ironlake and Sandybridge according to the B-Spec. */
  #define  ILK_ELPIN_409_SELECT (1 << 25)
  #define CHICKEN_TRANS_A         0x420c0
  #define CHICKEN_TRANS_B         0x420c4
  #define CHICKEN_TRANS(trans) _MMIO_TRANS(trans, CHICKEN_TRANS_A, CHICKEN_TRANS_B)
 -#define PSR2_VSC_ENABLE_PROG_HEADER    (1<<12)
 -#define PSR2_ADD_VERTICAL_LINE_COUNT   (1<<15)
 +#define  DDI_TRAINING_OVERRIDE_ENABLE (1<<19)
 +#define  DDI_TRAINING_OVERRIDE_VALUE  (1<<18)
 +#define  DDIE_TRAINING_OVERRIDE_ENABLE        (1<<17) /* CHICKEN_TRANS_A only */
 +#define  DDIE_TRAINING_OVERRIDE_VALUE (1<<16) /* CHICKEN_TRANS_A only */
 +#define  PSR2_ADD_VERTICAL_LINE_COUNT   (1<<15)
 +#define  PSR2_VSC_ENABLE_PROG_HEADER    (1<<12)
  
  #define DISP_ARB_CTL  _MMIO(0x45000)
  #define  DISP_FBC_MEMORY_WAKE         (1<<31)
  #define  RESET_PCH_HANDSHAKE_ENABLE   (1<<4)
  
  #define GEN8_CHICKEN_DCPR_1           _MMIO(0x46430)
 +#define   SKL_SELECT_ALTERNATE_DC_EXIT        (1<<30)
  #define   MASK_WAKEMEM                        (1<<13)
  
  #define SKL_DFSM                      _MMIO(0x51000)
  #define GEN9_SLICE_COMMON_ECO_CHICKEN0                _MMIO(0x7308)
  #define  DISABLE_PIXEL_MASK_CAMMING           (1<<14)
  
 +#define GEN9_SLICE_COMMON_ECO_CHICKEN1                _MMIO(0x731c)
 +
  #define GEN7_L3SQCREG1                                _MMIO(0xB010)
  #define  VLV_B0_WA_L3SQCREG1_VALUE            0x00D30000
  
  #define  CNP_RAWCLK_DIV(div)  ((div) << 16)
  #define  CNP_RAWCLK_FRAC_MASK (0xf << 26)
  #define  CNP_RAWCLK_FRAC(frac)        ((frac) << 26)
 +#define  ICP_RAWCLK_DEN(den)  ((den) << 26)
 +#define  ICP_RAWCLK_NUM(num)  ((num) << 11)
  
  #define PCH_DPLL_TMR_CFG        _MMIO(0xc6208)
  
  #define     GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT  8
  #define     GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT  16
  #define     GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT  24
+ #define   SKL_PCODE_LOAD_HDCP_KEYS            0x5
  #define   SKL_PCODE_CDCLK_CONTROL             0x7
  #define     SKL_CDCLK_PREPARE_FOR_CHANGE      0x3
  #define     SKL_CDCLK_READY_FOR_CHANGE                0x1
@@@ -8467,19 -8347,89 +8469,101 @@@ enum skl_power_gate 
  #define  SKL_PW_TO_PG(pw)                     ((pw) - SKL_DISP_PW_1 + SKL_PG1)
  #define  SKL_FUSE_PG_DIST_STATUS(pg)          (1 << (27 - (pg)))
  
 +#define _CNL_AUX_REG_IDX(pw)          ((pw) - 9)
 +#define _CNL_AUX_ANAOVRD1_B           0x162250
 +#define _CNL_AUX_ANAOVRD1_C           0x162210
 +#define _CNL_AUX_ANAOVRD1_D           0x1622D0
 +#define _CNL_AUX_ANAOVRD1_F           0x162A90
 +#define CNL_AUX_ANAOVRD1(pw)          _MMIO(_PICK(_CNL_AUX_REG_IDX(pw), \
 +                                                  _CNL_AUX_ANAOVRD1_B, \
 +                                                  _CNL_AUX_ANAOVRD1_C, \
 +                                                  _CNL_AUX_ANAOVRD1_D, \
 +                                                  _CNL_AUX_ANAOVRD1_F))
 +#define   CNL_AUX_ANAOVRD1_ENABLE     (1<<16)
 +#define   CNL_AUX_ANAOVRD1_LDO_BYPASS (1<<23)
  
+ /* HDCP Key Registers */
+ #define HDCP_KEY_CONF                 _MMIO(0x66c00)
+ #define  HDCP_AKSV_SEND_TRIGGER               BIT(31)
+ #define  HDCP_CLEAR_KEYS_TRIGGER      BIT(30)
+ #define  HDCP_KEY_LOAD_TRIGGER                BIT(8)
+ #define HDCP_KEY_STATUS                       _MMIO(0x66c04)
+ #define  HDCP_FUSE_IN_PROGRESS                BIT(7)
+ #define  HDCP_FUSE_ERROR              BIT(6)
+ #define  HDCP_FUSE_DONE                       BIT(5)
+ #define  HDCP_KEY_LOAD_STATUS         BIT(1)
+ #define  HDCP_KEY_LOAD_DONE           BIT(0)
+ #define HDCP_AKSV_LO                  _MMIO(0x66c10)
+ #define HDCP_AKSV_HI                  _MMIO(0x66c14)
+ /* HDCP Repeater Registers */
+ #define HDCP_REP_CTL                  _MMIO(0x66d00)
+ #define  HDCP_DDIB_REP_PRESENT                BIT(30)
+ #define  HDCP_DDIA_REP_PRESENT                BIT(29)
+ #define  HDCP_DDIC_REP_PRESENT                BIT(28)
+ #define  HDCP_DDID_REP_PRESENT                BIT(27)
+ #define  HDCP_DDIF_REP_PRESENT                BIT(26)
+ #define  HDCP_DDIE_REP_PRESENT                BIT(25)
+ #define  HDCP_DDIB_SHA1_M0            (1 << 20)
+ #define  HDCP_DDIA_SHA1_M0            (2 << 20)
+ #define  HDCP_DDIC_SHA1_M0            (3 << 20)
+ #define  HDCP_DDID_SHA1_M0            (4 << 20)
+ #define  HDCP_DDIF_SHA1_M0            (5 << 20)
+ #define  HDCP_DDIE_SHA1_M0            (6 << 20) /* Bspec says 5? */
+ #define  HDCP_SHA1_BUSY                       BIT(16)
+ #define  HDCP_SHA1_READY              BIT(17)
+ #define  HDCP_SHA1_COMPLETE           BIT(18)
+ #define  HDCP_SHA1_V_MATCH            BIT(19)
+ #define  HDCP_SHA1_TEXT_32            (1 << 1)
+ #define  HDCP_SHA1_COMPLETE_HASH      (2 << 1)
+ #define  HDCP_SHA1_TEXT_24            (4 << 1)
+ #define  HDCP_SHA1_TEXT_16            (5 << 1)
+ #define  HDCP_SHA1_TEXT_8             (6 << 1)
+ #define  HDCP_SHA1_TEXT_0             (7 << 1)
+ #define HDCP_SHA_V_PRIME_H0           _MMIO(0x66d04)
+ #define HDCP_SHA_V_PRIME_H1           _MMIO(0x66d08)
+ #define HDCP_SHA_V_PRIME_H2           _MMIO(0x66d0C)
+ #define HDCP_SHA_V_PRIME_H3           _MMIO(0x66d10)
+ #define HDCP_SHA_V_PRIME_H4           _MMIO(0x66d14)
+ #define HDCP_SHA_V_PRIME(h)           _MMIO((0x66d04 + h * 4))
+ #define HDCP_SHA_TEXT                 _MMIO(0x66d18)
+ /* HDCP Auth Registers */
+ #define _PORTA_HDCP_AUTHENC           0x66800
+ #define _PORTB_HDCP_AUTHENC           0x66500
+ #define _PORTC_HDCP_AUTHENC           0x66600
+ #define _PORTD_HDCP_AUTHENC           0x66700
+ #define _PORTE_HDCP_AUTHENC           0x66A00
+ #define _PORTF_HDCP_AUTHENC           0x66900
+ #define _PORT_HDCP_AUTHENC(port, x)   _MMIO(_PICK(port, \
+                                         _PORTA_HDCP_AUTHENC, \
+                                         _PORTB_HDCP_AUTHENC, \
+                                         _PORTC_HDCP_AUTHENC, \
+                                         _PORTD_HDCP_AUTHENC, \
+                                         _PORTE_HDCP_AUTHENC, \
+                                         _PORTF_HDCP_AUTHENC) + x)
+ #define PORT_HDCP_CONF(port)          _PORT_HDCP_AUTHENC(port, 0x0)
+ #define  HDCP_CONF_CAPTURE_AN         BIT(0)
+ #define  HDCP_CONF_AUTH_AND_ENC               (BIT(1) | BIT(0))
+ #define PORT_HDCP_ANINIT(port)                _PORT_HDCP_AUTHENC(port, 0x4)
+ #define PORT_HDCP_ANLO(port)          _PORT_HDCP_AUTHENC(port, 0x8)
+ #define PORT_HDCP_ANHI(port)          _PORT_HDCP_AUTHENC(port, 0xC)
+ #define PORT_HDCP_BKSVLO(port)                _PORT_HDCP_AUTHENC(port, 0x10)
+ #define PORT_HDCP_BKSVHI(port)                _PORT_HDCP_AUTHENC(port, 0x14)
+ #define PORT_HDCP_RPRIME(port)                _PORT_HDCP_AUTHENC(port, 0x18)
+ #define PORT_HDCP_STATUS(port)                _PORT_HDCP_AUTHENC(port, 0x1C)
+ #define  HDCP_STATUS_STREAM_A_ENC     BIT(31)
+ #define  HDCP_STATUS_STREAM_B_ENC     BIT(30)
+ #define  HDCP_STATUS_STREAM_C_ENC     BIT(29)
+ #define  HDCP_STATUS_STREAM_D_ENC     BIT(28)
+ #define  HDCP_STATUS_AUTH             BIT(21)
+ #define  HDCP_STATUS_ENC              BIT(20)
+ #define  HDCP_STATUS_RI_MATCH         BIT(19)
+ #define  HDCP_STATUS_R0_READY         BIT(18)
+ #define  HDCP_STATUS_AN_READY         BIT(17)
+ #define  HDCP_STATUS_CIPHER           BIT(16)
+ #define  HDCP_STATUS_FRAME_CNT(x)     ((x >> 8) & 0xff)
  /* Per-pipe DDI Function Control */
  #define _TRANS_DDI_FUNC_CTL_A         0x60400
  #define _TRANS_DDI_FUNC_CTL_B         0x61400
  #define  TRANS_DDI_EDP_INPUT_A_ONOFF  (4<<12)
  #define  TRANS_DDI_EDP_INPUT_B_ONOFF  (5<<12)
  #define  TRANS_DDI_EDP_INPUT_C_ONOFF  (6<<12)
+ #define  TRANS_DDI_HDCP_SIGNALLING    (1<<9)
  #define  TRANS_DDI_DP_VC_PAYLOAD_ALLOC        (1<<8)
  #define  TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE (1<<7)
  #define  TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ (1<<6)
  #define  BXT_CDCLK_CD2X_DIV_SEL_2     (2<<22)
  #define  BXT_CDCLK_CD2X_DIV_SEL_4     (3<<22)
  #define  BXT_CDCLK_CD2X_PIPE(pipe)    ((pipe)<<20)
 +#define  CDCLK_DIVMUX_CD_OVERRIDE     (1<<19)
  #define  BXT_CDCLK_CD2X_PIPE_NONE     BXT_CDCLK_CD2X_PIPE(3)
  #define  BXT_CDCLK_SSA_PRECHARGE_ENABLE       (1<<16)
  #define  CDCLK_FREQ_DECIMAL_MASK      (0x7ff)
   * CNL Clocks
   */
  #define DPCLKA_CFGCR0                         _MMIO(0x6C200)
 -#define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)      (1 << ((port)+10))
 -#define  DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port) (3 << ((port)*2))
 -#define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port)        ((port)*2)
 -#define  DPCLKA_CFGCR0_DDI_CLK_SEL(pll, port) ((pll) << ((port)*2))
 +#define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)      (1 << ((port) ==  PORT_F ? 23 : \
 +                                                    (port)+10))
 +#define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port)        ((port) == PORT_F ? 21 : \
 +                                              (port)*2)
 +#define  DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port) (3 << DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port))
 +#define  DPCLKA_CFGCR0_DDI_CLK_SEL(pll, port) ((pll) << DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port))
  
  /* CNL PLL */
  #define DPLL0_ENABLE          0x46010
  #define  SFUSE_STRAP_RAW_FREQUENCY    (1<<8)
  #define  SFUSE_STRAP_DISPLAY_DISABLED (1<<7)
  #define  SFUSE_STRAP_CRT_DISABLED     (1<<6)
 +#define  SFUSE_STRAP_DDIF_DETECTED    (1<<3)
  #define  SFUSE_STRAP_DDIB_DETECTED    (1<<2)
  #define  SFUSE_STRAP_DDIC_DETECTED    (1<<1)
  #define  SFUSE_STRAP_DDID_DETECTED    (1<<0)
index d9b52fe82932c4bfdc94f9a77249fd26f0214813,6260a882fbe44615e680815dd81b2e965825a32b..cfcd9cb37d5d138665e504e691959b84c00811b8
@@@ -1615,6 -1615,35 +1615,35 @@@ void intel_ddi_disable_transcoder_func(
        I915_WRITE(reg, val);
  }
  
+ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
+                                    bool enable)
+ {
+       struct drm_device *dev = intel_encoder->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       enum pipe pipe = 0;
+       int ret = 0;
+       uint32_t tmp;
+       if (WARN_ON(!intel_display_power_get_if_enabled(dev_priv,
+                                               intel_encoder->power_domain)))
+               return -ENXIO;
+       if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
+               ret = -EIO;
+               goto out;
+       }
+       tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
+       if (enable)
+               tmp |= TRANS_DDI_HDCP_SIGNALLING;
+       else
+               tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
+       I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
+ out:
+       intel_display_power_put(dev_priv, intel_encoder->power_domain);
+       return ret;
+ }
  bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
  {
        struct drm_device *dev = intel_connector->base.dev;
@@@ -2404,48 -2433,6 +2433,48 @@@ static void intel_enable_ddi_hdmi(struc
                                          crtc_state->hdmi_high_tmds_clock_ratio,
                                          crtc_state->hdmi_scrambling);
  
 +      /* Display WA #1143: skl,kbl,cfl */
 +      if (IS_GEN9_BC(dev_priv)) {
 +              /*
 +               * For some reason these chicken bits have been
 +               * stuffed into a transcoder register, event though
 +               * the bits affect a specific DDI port rather than
 +               * a specific transcoder.
 +               */
 +              static const enum transcoder port_to_transcoder[] = {
 +                      [PORT_A] = TRANSCODER_EDP,
 +                      [PORT_B] = TRANSCODER_A,
 +                      [PORT_C] = TRANSCODER_B,
 +                      [PORT_D] = TRANSCODER_C,
 +                      [PORT_E] = TRANSCODER_A,
 +              };
 +              enum transcoder transcoder = port_to_transcoder[port];
 +              u32 val;
 +
 +              val = I915_READ(CHICKEN_TRANS(transcoder));
 +
 +              if (port == PORT_E)
 +                      val |= DDIE_TRAINING_OVERRIDE_ENABLE |
 +                              DDIE_TRAINING_OVERRIDE_VALUE;
 +              else
 +                      val |= DDI_TRAINING_OVERRIDE_ENABLE |
 +                              DDI_TRAINING_OVERRIDE_VALUE;
 +
 +              I915_WRITE(CHICKEN_TRANS(transcoder), val);
 +              POSTING_READ(CHICKEN_TRANS(transcoder));
 +
 +              udelay(1);
 +
 +              if (port == PORT_E)
 +                      val &= ~(DDIE_TRAINING_OVERRIDE_ENABLE |
 +                               DDIE_TRAINING_OVERRIDE_VALUE);
 +              else
 +                      val &= ~(DDI_TRAINING_OVERRIDE_ENABLE |
 +                               DDI_TRAINING_OVERRIDE_VALUE);
 +
 +              I915_WRITE(CHICKEN_TRANS(transcoder), val);
 +      }
 +
        /* In HDMI/DVI mode, the port width, and swing/emphasis values
         * are ignored so nothing special needs to be done besides
         * enabling the port.
@@@ -2465,6 -2452,11 +2494,11 @@@ static void intel_enable_ddi(struct int
                intel_enable_ddi_hdmi(encoder, crtc_state, conn_state);
        else
                intel_enable_ddi_dp(encoder, crtc_state, conn_state);
+       /* Enable hdcp if it's desired */
+       if (conn_state->content_protection ==
+           DRM_MODE_CONTENT_PROTECTION_DESIRED)
+               intel_hdcp_enable(to_intel_connector(conn_state->connector));
  }
  
  static void intel_disable_ddi_dp(struct intel_encoder *encoder,
@@@ -2499,6 -2491,8 +2533,8 @@@ static void intel_disable_ddi(struct in
                              const struct intel_crtc_state *old_crtc_state,
                              const struct drm_connector_state *old_conn_state)
  {
+       intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
        if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
                intel_disable_ddi_hdmi(encoder, old_crtc_state, old_conn_state);
        else
@@@ -2910,10 -2904,6 +2946,10 @@@ void intel_ddi_init(struct drm_i915_pri
                intel_dig_port->ddi_io_power_domain =
                        POWER_DOMAIN_PORT_DDI_E_IO;
                break;
 +      case PORT_F:
 +              intel_dig_port->ddi_io_power_domain =
 +                      POWER_DOMAIN_PORT_DDI_F_IO;
 +              break;
        default:
                MISSING_CASE(port);
        }
index 15523f0e3b448a37bb51cca37b9e2397bcb47297,02bf31d935b4552e27114439f67f3988cf111cb1..60ba5bb3f34cfa9ce7fe6351076d58148757e7af
@@@ -2387,20 -2387,6 +2387,20 @@@ static unsigned int intel_fb_modifier_t
        }
  }
  
 +/*
 + * From the Sky Lake PRM:
 + * "The Color Control Surface (CCS) contains the compression status of
 + *  the cache-line pairs. The compression state of the cache-line pair
 + *  is specified by 2 bits in the CCS. Each CCS cache-line represents
 + *  an area on the main surface of 16 x16 sets of 128 byte Y-tiled
 + *  cache-line-pairs. CCS is always Y tiled."
 + *
 + * Since cache line pairs refers to horizontally adjacent cache lines,
 + * each cache line in the CCS corresponds to an area of 32x16 cache
 + * lines on the main surface. Since each pixel is 4 bytes, this gives
 + * us a ratio of one byte in the CCS for each 8x16 pixels in the
 + * main surface.
 + */
  static const struct drm_format_info ccs_formats[] = {
        { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
        { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
@@@ -2931,19 -2917,14 +2931,19 @@@ static bool skl_check_main_ccs_coordina
        return true;
  }
  
 -static int skl_check_main_surface(struct intel_plane_state *plane_state)
 +static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
 +                                struct intel_plane_state *plane_state)
  {
 +      struct drm_i915_private *dev_priv =
 +              to_i915(plane_state->base.plane->dev);
        const struct drm_framebuffer *fb = plane_state->base.fb;
        unsigned int rotation = plane_state->base.rotation;
        int x = plane_state->base.src.x1 >> 16;
        int y = plane_state->base.src.y1 >> 16;
        int w = drm_rect_width(&plane_state->base.src) >> 16;
        int h = drm_rect_height(&plane_state->base.src) >> 16;
 +      int dst_x = plane_state->base.dst.x1;
 +      int pipe_src_w = crtc_state->pipe_src_w;
        int max_width = skl_max_plane_width(fb, 0, rotation);
        int max_height = 4096;
        u32 alignment, offset, aux_offset = plane_state->aux.offset;
                return -EINVAL;
        }
  
 +      /*
 +       * Display WA #1175: cnl,glk
 +       * Planes other than the cursor may cause FIFO underflow and display
 +       * corruption if starting less than 4 pixels from the right edge of
 +       * the screen.
 +       * Besides the above WA fix the similar problem, where planes other
 +       * than the cursor ending less than 4 pixels from the left edge of the
 +       * screen may cause FIFO underflow and display corruption.
 +       */
 +      if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
 +          (dst_x + w < 4 || dst_x > pipe_src_w - 4)) {
 +              DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
 +                            dst_x + w < 4 ? "end" : "start",
 +                            dst_x + w < 4 ? dst_x + w : dst_x,
 +                            4, pipe_src_w - 4);
 +              return -ERANGE;
 +      }
 +
        intel_add_fb_offsets(&x, &y, plane_state, 0);
        offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
        alignment = intel_surf_alignment(fb, 0);
@@@ -3064,7 -3027,6 +3064,7 @@@ static int skl_check_nv12_aux_surface(s
  static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
  {
        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 +      struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc);
        const struct drm_framebuffer *fb = plane_state->base.fb;
        int src_x = plane_state->base.src.x1 >> 16;
        int y = src_y / vsub;
        u32 offset;
  
 -      switch (plane->id) {
 -      case PLANE_PRIMARY:
 -      case PLANE_SPRITE0:
 -              break;
 -      default:
 -              DRM_DEBUG_KMS("RC support only on plane 1 and 2\n");
 -              return -EINVAL;
 -      }
 -
 -      if (crtc->pipe == PIPE_C) {
 -              DRM_DEBUG_KMS("No RC support on pipe C\n");
 +      if (!skl_plane_has_ccs(dev_priv, crtc->pipe, plane->id)) {
 +              DRM_DEBUG_KMS("No RC support on %s\n", plane->base.name);
                return -EINVAL;
        }
  
        return 0;
  }
  
 -int skl_check_plane_surface(struct intel_plane_state *plane_state)
 +int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
 +                          struct intel_plane_state *plane_state)
  {
        const struct drm_framebuffer *fb = plane_state->base.fb;
        unsigned int rotation = plane_state->base.rotation;
                plane_state->aux.y = 0;
        }
  
 -      ret = skl_check_main_surface(plane_state);
 +      ret = skl_check_main_surface(crtc_state, plane_state);
        if (ret)
                return ret;
  
@@@ -4787,7 -4757,7 +4787,7 @@@ static int skl_update_scaler_plane(stru
                return ret;
  
        /* check colorkey */
 -      if (plane_state->ckey.flags != I915_SET_COLORKEY_NONE) {
 +      if (plane_state->ckey.flags) {
                DRM_DEBUG_KMS("[PLANE:%d:%s] scaling with color key not allowed",
                              intel_plane->base.base.id,
                              intel_plane->base.name);
@@@ -5671,8 -5641,6 +5671,8 @@@ enum intel_display_power_domain intel_p
                return POWER_DOMAIN_PORT_DDI_D_LANES;
        case PORT_E:
                return POWER_DOMAIN_PORT_DDI_E_LANES;
 +      case PORT_F:
 +              return POWER_DOMAIN_PORT_DDI_F_LANES;
        default:
                MISSING_CASE(port);
                return POWER_DOMAIN_PORT_OTHER;
@@@ -5693,8 -5661,8 +5693,8 @@@ static u64 get_crtc_power_domains(struc
        if (!crtc_state->base.active)
                return 0;
  
 -      mask = BIT(POWER_DOMAIN_PIPE(pipe));
 -      mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
 +      mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe));
 +      mask |= BIT_ULL(POWER_DOMAIN_TRANSCODER(transcoder));
        if (crtc_state->pch_pfit.enabled ||
            crtc_state->pch_pfit.force_thru)
                mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
        }
  
        if (HAS_DDI(dev_priv) && crtc_state->has_audio)
 -              mask |= BIT(POWER_DOMAIN_AUDIO);
 +              mask |= BIT_ULL(POWER_DOMAIN_AUDIO);
  
        if (crtc_state->shared_dpll)
                mask |= BIT_ULL(POWER_DOMAIN_PLLS);
@@@ -6404,18 -6372,9 +6404,18 @@@ static int intel_crtc_compute_config(st
         * - LVDS dual channel mode
         * - Double wide pipe
         */
 -      if ((intel_crtc_has_type(pipe_config, INTEL_OUTPUT_LVDS) &&
 -           intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
 -              pipe_config->pipe_src_w &= ~1;
 +      if (pipe_config->pipe_src_w & 1) {
 +              if (pipe_config->double_wide) {
 +                      DRM_DEBUG_KMS("Odd pipe source width not supported with double wide pipe\n");
 +                      return -EINVAL;
 +              }
 +
 +              if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_LVDS) &&
 +                  intel_is_dual_link_lvds(dev)) {
 +                      DRM_DEBUG_KMS("Odd pipe source width not supported with dual link LVDS\n");
 +                      return -EINVAL;
 +              }
 +      }
  
        /* Cantiga+ cannot handle modes with a hsync front porch of 0.
         * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
@@@ -8536,10 -8495,7 +8536,10 @@@ skylake_get_initial_plane_config(struc
  
        val = I915_READ(PLANE_CTL(pipe, plane_id));
  
 -      pixel_format = val & PLANE_CTL_FORMAT_MASK;
 +      if (INTEL_GEN(dev_priv) >= 11)
 +              pixel_format = val & ICL_PLANE_CTL_FORMAT_MASK;
 +      else
 +              pixel_format = val & PLANE_CTL_FORMAT_MASK;
  
        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
                alpha = I915_READ(PLANE_COLOR_CTL(pipe, plane_id));
@@@ -9352,18 -9308,13 +9352,18 @@@ static int intel_check_cursor(struct in
                              struct intel_plane_state *plane_state)
  {
        const struct drm_framebuffer *fb = plane_state->base.fb;
 +      struct drm_rect clip = {};
        int src_x, src_y;
        u32 offset;
        int ret;
  
 +      if (crtc_state->base.enable)
 +              drm_mode_get_hv_timing(&crtc_state->base.mode,
 +                                     &clip.x2, &clip.y2);
 +
        ret = drm_atomic_helper_check_plane_state(&plane_state->base,
                                                  &crtc_state->base,
 -                                                &plane_state->clip,
 +                                                &clip,
                                                  DRM_PLANE_HELPER_NO_SCALING,
                                                  DRM_PLANE_HELPER_NO_SCALING,
                                                  true, true);
@@@ -12568,13 -12519,7 +12568,13 @@@ static int do_rps_boost(struct wait_que
        struct wait_rps_boost *wait = container_of(_wait, typeof(*wait), wait);
        struct drm_i915_gem_request *rq = wait->request;
  
 -      gen6_rps_boost(rq, NULL);
 +      /*
 +       * If we missed the vblank, but the request is already running it
 +       * is reasonable to assume that it will complete before the next
 +       * vblank without our intervention, so leave RPS alone.
 +       */
 +      if (!i915_gem_request_started(rq))
 +              gen6_rps_boost(rq, NULL);
        i915_gem_request_put(rq);
  
        drm_crtc_vblank_put(wait->crtc);
@@@ -12798,25 -12743,20 +12798,25 @@@ intel_check_primary_plane(struct intel_
        int min_scale = DRM_PLANE_HELPER_NO_SCALING;
        int max_scale = DRM_PLANE_HELPER_NO_SCALING;
        bool can_position = false;
 +      struct drm_rect clip = {};
        int ret;
  
        if (INTEL_GEN(dev_priv) >= 9) {
                /* use scaler when colorkey is not required */
 -              if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
 +              if (!state->ckey.flags) {
                        min_scale = 1;
                        max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
                }
                can_position = true;
        }
  
 +      if (crtc_state->base.enable)
 +              drm_mode_get_hv_timing(&crtc_state->base.mode,
 +                                     &clip.x2, &clip.y2);
 +
        ret = drm_atomic_helper_check_plane_state(&state->base,
                                                  &crtc_state->base,
 -                                                &state->clip,
 +                                                &clip,
                                                  min_scale, max_scale,
                                                  can_position, true);
        if (ret)
                return 0;
  
        if (INTEL_GEN(dev_priv) >= 9) {
 -              ret = skl_check_plane_surface(state);
 +              ret = skl_check_plane_surface(crtc_state, state);
                if (ret)
                        return ret;
  
@@@ -13004,6 -12944,8 +13004,6 @@@ static bool intel_primary_plane_format_
                return i965_mod_supported(format, modifier);
        else
                return i8xx_mod_supported(format, modifier);
 -
 -      unreachable();
  }
  
  static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane,
@@@ -13211,14 -13153,21 +13211,14 @@@ intel_primary_plane_create(struct drm_i
        else
                primary->i9xx_plane = (enum i9xx_plane_id) pipe;
        primary->id = PLANE_PRIMARY;
 -      primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
 +      primary->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, primary->id);
        primary->check_plane = intel_check_primary_plane;
  
 -      if (INTEL_GEN(dev_priv) >= 10) {
 +      if (INTEL_GEN(dev_priv) >= 9) {
                intel_primary_formats = skl_primary_formats;
                num_formats = ARRAY_SIZE(skl_primary_formats);
 -              modifiers = skl_format_modifiers_ccs;
  
 -              primary->update_plane = skl_update_plane;
 -              primary->disable_plane = skl_disable_plane;
 -              primary->get_hw_state = skl_plane_get_hw_state;
 -      } else if (INTEL_GEN(dev_priv) >= 9) {
 -              intel_primary_formats = skl_primary_formats;
 -              num_formats = ARRAY_SIZE(skl_primary_formats);
 -              if (pipe < PIPE_C)
 +              if (skl_plane_has_ccs(dev_priv, pipe, PLANE_PRIMARY))
                        modifiers = skl_format_modifiers_ccs;
                else
                        modifiers = skl_format_modifiers_noccs;
@@@ -13332,7 -13281,7 +13332,7 @@@ intel_cursor_plane_create(struct drm_i9
        cursor->pipe = pipe;
        cursor->i9xx_plane = (enum i9xx_plane_id) pipe;
        cursor->id = PLANE_CURSOR;
 -      cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
 +      cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id);
  
        if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
                cursor->update_plane = i845_update_cursor;
@@@ -13648,7 -13597,7 +13648,7 @@@ static void intel_setup_outputs(struct 
                if (found || IS_GEN9_BC(dev_priv))
                        intel_ddi_init(dev_priv, PORT_A);
  
 -              /* DDI B, C and D detection is indicated by the SFUSE_STRAP
 +              /* DDI B, C, D, and F detection is indicated by the SFUSE_STRAP
                 * register */
                found = I915_READ(SFUSE_STRAP);
  
                        intel_ddi_init(dev_priv, PORT_C);
                if (found & SFUSE_STRAP_DDID_DETECTED)
                        intel_ddi_init(dev_priv, PORT_D);
 +              if (found & SFUSE_STRAP_DDIF_DETECTED)
 +                      intel_ddi_init(dev_priv, PORT_F);
                /*
                 * On SKL we don't have a way to detect DDI-E so we rely on VBT.
                 */
@@@ -14116,37 -14063,10 +14116,37 @@@ static void intel_atomic_state_free(str
        kfree(state);
  }
  
 +static enum drm_mode_status
 +intel_mode_valid(struct drm_device *dev,
 +               const struct drm_display_mode *mode)
 +{
 +      if (mode->vscan > 1)
 +              return MODE_NO_VSCAN;
 +
 +      if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 +              return MODE_NO_DBLESCAN;
 +
 +      if (mode->flags & DRM_MODE_FLAG_HSKEW)
 +              return MODE_H_ILLEGAL;
 +
 +      if (mode->flags & (DRM_MODE_FLAG_CSYNC |
 +                         DRM_MODE_FLAG_NCSYNC |
 +                         DRM_MODE_FLAG_PCSYNC))
 +              return MODE_HSYNC;
 +
 +      if (mode->flags & (DRM_MODE_FLAG_BCAST |
 +                         DRM_MODE_FLAG_PIXMUX |
 +                         DRM_MODE_FLAG_CLKDIV2))
 +              return MODE_BAD;
 +
 +      return MODE_OK;
 +}
 +
  static const struct drm_mode_config_funcs intel_mode_funcs = {
        .fb_create = intel_user_framebuffer_create,
        .get_format_info = intel_get_format_info,
        .output_poll_changed = intel_fbdev_output_poll_changed,
 +      .mode_valid = intel_mode_valid,
        .atomic_check = intel_atomic_check,
        .atomic_commit = intel_atomic_commit,
        .atomic_state_alloc = intel_atomic_state_alloc,
@@@ -15297,6 -15217,10 +15297,10 @@@ static void intel_hpd_poll_fini(struct 
        for_each_intel_connector_iter(connector, &conn_iter) {
                if (connector->modeset_retry_work.func)
                        cancel_work_sync(&connector->modeset_retry_work);
+               if (connector->hdcp_shim) {
+                       cancel_delayed_work_sync(&connector->hdcp_check_work);
+                       cancel_work_sync(&connector->hdcp_prop_work);
+               }
        }
        drm_connector_list_iter_end(&conn_iter);
  }
index 8503d182921b4c4d29a097990436a767bc7ff3ba,59024c7ec2cd99c89f872521459a1b519437ebe7..f10a14330e7c9f196593bfea38f8c9e4d77a3e45
@@@ -36,7 -36,9 +36,9 @@@
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_crtc.h>
  #include <drm/drm_crtc_helper.h>
+ #include <drm/drm_dp_helper.h>
  #include <drm/drm_edid.h>
+ #include <drm/drm_hdcp.h>
  #include "intel_drv.h"
  #include <drm/i915_drm.h>
  #include "i915_drv.h"
@@@ -155,28 -157,6 +157,28 @@@ static void intel_dp_set_sink_rates(str
        intel_dp->num_sink_rates = i;
  }
  
 +/* Get length of rates array potentially limited by max_rate. */
 +static int intel_dp_rate_limit_len(const int *rates, int len, int max_rate)
 +{
 +      int i;
 +
 +      /* Limit results by potentially reduced max rate */
 +      for (i = 0; i < len; i++) {
 +              if (rates[len - i - 1] <= max_rate)
 +                      return len - i;
 +      }
 +
 +      return 0;
 +}
 +
 +/* Get length of common rates array potentially limited by max_rate. */
 +static int intel_dp_common_len_rate_limit(const struct intel_dp *intel_dp,
 +                                        int max_rate)
 +{
 +      return intel_dp_rate_limit_len(intel_dp->common_rates,
 +                                     intel_dp->num_common_rates, max_rate);
 +}
 +
  /* Theoretical max between source and sink */
  static int intel_dp_max_common_rate(struct intel_dp *intel_dp)
  {
@@@ -240,38 -220,15 +242,38 @@@ intel_dp_downstream_max_dotclock(struc
        return max_dotclk;
  }
  
 +static int cnl_max_source_rate(struct intel_dp *intel_dp)
 +{
 +      struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 +      struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
 +      enum port port = dig_port->base.port;
 +
 +      u32 voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
 +
 +      /* Low voltage SKUs are limited to max of 5.4G */
 +      if (voltage == VOLTAGE_INFO_0_85V)
 +              return 540000;
 +
 +      /* For this SKU 8.1G is supported in all ports */
 +      if (IS_CNL_WITH_PORT_F(dev_priv))
 +              return 810000;
 +
 +      /* For other SKUs, max rate on ports A and B is 5.4G */
 +      if (port == PORT_A || port == PORT_D)
 +              return 540000;
 +
 +      return 810000;
 +}
 +
  static void
  intel_dp_set_source_rates(struct intel_dp *intel_dp)
  {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
        struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
 -      enum port port = dig_port->base.port;
 +      const struct ddi_vbt_port_info *info =
 +              &dev_priv->vbt.ddi_port_info[dig_port->base.port];
        const int *source_rates;
 -      int size;
 -      u32 voltage;
 +      int size, max_rate = 0, vbt_max_rate = info->dp_max_link_rate;
  
        /* This should only be done once */
        WARN_ON(intel_dp->source_rates || intel_dp->num_source_rates);
        } else if (IS_CANNONLAKE(dev_priv)) {
                source_rates = cnl_rates;
                size = ARRAY_SIZE(cnl_rates);
 -              voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
 -              if (port == PORT_A || port == PORT_D ||
 -                  voltage == VOLTAGE_INFO_0_85V)
 -                      size -= 2;
 +              max_rate = cnl_max_source_rate(intel_dp);
        } else if (IS_GEN9_BC(dev_priv)) {
                source_rates = skl_rates;
                size = ARRAY_SIZE(skl_rates);
                size = ARRAY_SIZE(default_rates) - 1;
        }
  
 +      if (max_rate && vbt_max_rate)
 +              max_rate = min(max_rate, vbt_max_rate);
 +      else if (vbt_max_rate)
 +              max_rate = vbt_max_rate;
 +
 +      if (max_rate)
 +              size = intel_dp_rate_limit_len(source_rates, size, max_rate);
 +
        intel_dp->source_rates = source_rates;
        intel_dp->num_source_rates = size;
  }
@@@ -359,6 -311,22 +361,6 @@@ static void intel_dp_set_common_rates(s
        }
  }
  
 -/* get length of common rates potentially limited by max_rate */
 -static int intel_dp_common_len_rate_limit(struct intel_dp *intel_dp,
 -                                        int max_rate)
 -{
 -      const int *common_rates = intel_dp->common_rates;
 -      int i, common_len = intel_dp->num_common_rates;
 -
 -      /* Limit results by potentially reduced max rate */
 -      for (i = 0; i < common_len; i++) {
 -              if (common_rates[common_len - i - 1] <= max_rate)
 -                      return common_len - i;
 -      }
 -
 -      return 0;
 -}
 -
  static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
                                       uint8_t lane_count)
  {
@@@ -828,8 -796,7 +830,8 @@@ static void intel_pps_get_registers(str
        regs->pp_stat = PP_STATUS(pps_idx);
        regs->pp_on = PP_ON_DELAYS(pps_idx);
        regs->pp_off = PP_OFF_DELAYS(pps_idx);
 -      if (!IS_GEN9_LP(dev_priv) && !HAS_PCH_CNP(dev_priv))
 +      if (!IS_GEN9_LP(dev_priv) && !HAS_PCH_CNP(dev_priv) &&
 +          !HAS_PCH_ICP(dev_priv))
                regs->pp_div = PP_DIVISOR(pps_idx);
  }
  
@@@ -1060,10 -1027,29 +1062,29 @@@ static uint32_t skl_get_aux_send_ctl(st
               DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
  }
  
+ static uint32_t intel_dp_get_aux_send_ctl(struct intel_dp *intel_dp,
+                                         bool has_aux_irq,
+                                         int send_bytes,
+                                         uint32_t aux_clock_divider,
+                                         bool aksv_write)
+ {
+       uint32_t val = 0;
+       if (aksv_write) {
+               send_bytes += 5;
+               val |= DP_AUX_CH_CTL_AUX_AKSV_SELECT;
+       }
+       return val | intel_dp->get_aux_send_ctl(intel_dp,
+                                               has_aux_irq,
+                                               send_bytes,
+                                               aux_clock_divider);
+ }
  static int
  intel_dp_aux_ch(struct intel_dp *intel_dp,
                const uint8_t *send, int send_bytes,
-               uint8_t *recv, int recv_size)
+               uint8_t *recv, int recv_size, bool aksv_write)
  {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        struct drm_i915_private *dev_priv =
        }
  
        while ((aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, clock++))) {
-               u32 send_ctl = intel_dp->get_aux_send_ctl(intel_dp,
-                                                         has_aux_irq,
-                                                         send_bytes,
-                                                         aux_clock_divider);
+               u32 send_ctl = intel_dp_get_aux_send_ctl(intel_dp,
+                                                        has_aux_irq,
+                                                        send_bytes,
+                                                        aux_clock_divider,
+                                                        aksv_write);
  
                /* Must try at least 3 times according to DP spec */
                for (try = 0; try < 5; try++) {
@@@ -1263,7 -1250,8 +1285,8 @@@ intel_dp_aux_transfer(struct drm_dp_au
                if (msg->buffer)
                        memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size);
  
-               ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize);
+               ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize,
+                                     false);
                if (ret > 0) {
                        msg->reply = rxbuf[0] >> 4;
  
                if (WARN_ON(rxsize > 20))
                        return -E2BIG;
  
-               ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize);
+               ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize,
+                                     false);
                if (ret > 0) {
                        msg->reply = rxbuf[0] >> 4;
                        /*
@@@ -1333,9 -1322,6 +1357,9 @@@ static enum port intel_aux_port(struct 
        case DP_AUX_D:
                aux_port = PORT_D;
                break;
 +      case DP_AUX_F:
 +              aux_port = PORT_F;
 +              break;
        default:
                MISSING_CASE(info->alternate_aux_channel);
                aux_port = PORT_A;
@@@ -1416,7 -1402,6 +1440,7 @@@ static i915_reg_t skl_aux_ctl_reg(struc
        case PORT_B:
        case PORT_C:
        case PORT_D:
 +      case PORT_F:
                return DP_AUX_CH_CTL(port);
        default:
                MISSING_CASE(port);
@@@ -1432,7 -1417,6 +1456,7 @@@ static i915_reg_t skl_aux_data_reg(stru
        case PORT_B:
        case PORT_C:
        case PORT_D:
 +      case PORT_F:
                return DP_AUX_CH_DATA(port, index);
        default:
                MISSING_CASE(port);
@@@ -4495,174 -4479,173 +4519,174 @@@ edp_detect(struct intel_dp *intel_dp
        return status;
  }
  
 -static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool ibx_digital_port_connected(struct intel_encoder *encoder)
  {
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 bit;
  
 -      switch (port->base.port) {
 -      case PORT_B:
 +      switch (encoder->hpd_pin) {
 +      case HPD_PORT_B:
                bit = SDE_PORTB_HOTPLUG;
                break;
 -      case PORT_C:
 +      case HPD_PORT_C:
                bit = SDE_PORTC_HOTPLUG;
                break;
 -      case PORT_D:
 +      case HPD_PORT_D:
                bit = SDE_PORTD_HOTPLUG;
                break;
        default:
 -              MISSING_CASE(port->base.port);
 +              MISSING_CASE(encoder->hpd_pin);
                return false;
        }
  
        return I915_READ(SDEISR) & bit;
  }
  
 -static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool cpt_digital_port_connected(struct intel_encoder *encoder)
  {
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 bit;
  
 -      switch (port->base.port) {
 -      case PORT_B:
 +      switch (encoder->hpd_pin) {
 +      case HPD_PORT_B:
                bit = SDE_PORTB_HOTPLUG_CPT;
                break;
 -      case PORT_C:
 +      case HPD_PORT_C:
                bit = SDE_PORTC_HOTPLUG_CPT;
                break;
 -      case PORT_D:
 +      case HPD_PORT_D:
                bit = SDE_PORTD_HOTPLUG_CPT;
                break;
        default:
 -              MISSING_CASE(port->base.port);
 +              MISSING_CASE(encoder->hpd_pin);
                return false;
        }
  
        return I915_READ(SDEISR) & bit;
  }
  
 -static bool spt_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool spt_digital_port_connected(struct intel_encoder *encoder)
  {
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 bit;
  
 -      switch (port->base.port) {
 -      case PORT_A:
 +      switch (encoder->hpd_pin) {
 +      case HPD_PORT_A:
                bit = SDE_PORTA_HOTPLUG_SPT;
                break;
 -      case PORT_E:
 +      case HPD_PORT_E:
                bit = SDE_PORTE_HOTPLUG_SPT;
                break;
        default:
 -              return cpt_digital_port_connected(dev_priv, port);
 +              return cpt_digital_port_connected(encoder);
        }
  
        return I915_READ(SDEISR) & bit;
  }
  
 -static bool g4x_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool g4x_digital_port_connected(struct intel_encoder *encoder)
  {
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 bit;
  
 -      switch (port->base.port) {
 -      case PORT_B:
 +      switch (encoder->hpd_pin) {
 +      case HPD_PORT_B:
                bit = PORTB_HOTPLUG_LIVE_STATUS_G4X;
                break;
 -      case PORT_C:
 +      case HPD_PORT_C:
                bit = PORTC_HOTPLUG_LIVE_STATUS_G4X;
                break;
 -      case PORT_D:
 +      case HPD_PORT_D:
                bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
                break;
        default:
 -              MISSING_CASE(port->base.port);
 +              MISSING_CASE(encoder->hpd_pin);
                return false;
        }
  
        return I915_READ(PORT_HOTPLUG_STAT) & bit;
  }
  
 -static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                      struct intel_digital_port *port)
 +static bool gm45_digital_port_connected(struct intel_encoder *encoder)
  {
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 bit;
  
 -      switch (port->base.port) {
 -      case PORT_B:
 +      switch (encoder->hpd_pin) {
 +      case HPD_PORT_B:
                bit = PORTB_HOTPLUG_LIVE_STATUS_GM45;
                break;
 -      case PORT_C:
 +      case HPD_PORT_C:
                bit = PORTC_HOTPLUG_LIVE_STATUS_GM45;
                break;
 -      case PORT_D:
 +      case HPD_PORT_D:
                bit = PORTD_HOTPLUG_LIVE_STATUS_GM45;
                break;
        default:
 -              MISSING_CASE(port->base.port);
 +              MISSING_CASE(encoder->hpd_pin);
                return false;
        }
  
        return I915_READ(PORT_HOTPLUG_STAT) & bit;
  }
  
 -static bool ilk_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool ilk_digital_port_connected(struct intel_encoder *encoder)
  {
 -      if (port->base.port == PORT_A)
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 +
 +      if (encoder->hpd_pin == HPD_PORT_A)
                return I915_READ(DEISR) & DE_DP_A_HOTPLUG;
        else
 -              return ibx_digital_port_connected(dev_priv, port);
 +              return ibx_digital_port_connected(encoder);
  }
  
 -static bool snb_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool snb_digital_port_connected(struct intel_encoder *encoder)
  {
 -      if (port->base.port == PORT_A)
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 +
 +      if (encoder->hpd_pin == HPD_PORT_A)
                return I915_READ(DEISR) & DE_DP_A_HOTPLUG;
        else
 -              return cpt_digital_port_connected(dev_priv, port);
 +              return cpt_digital_port_connected(encoder);
  }
  
 -static bool ivb_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool ivb_digital_port_connected(struct intel_encoder *encoder)
  {
 -      if (port->base.port == PORT_A)
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 +
 +      if (encoder->hpd_pin == HPD_PORT_A)
                return I915_READ(DEISR) & DE_DP_A_HOTPLUG_IVB;
        else
 -              return cpt_digital_port_connected(dev_priv, port);
 +              return cpt_digital_port_connected(encoder);
  }
  
 -static bool bdw_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *port)
 +static bool bdw_digital_port_connected(struct intel_encoder *encoder)
  {
 -      if (port->base.port == PORT_A)
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 +
 +      if (encoder->hpd_pin == HPD_PORT_A)
                return I915_READ(GEN8_DE_PORT_ISR) & GEN8_PORT_DP_A_HOTPLUG;
        else
 -              return cpt_digital_port_connected(dev_priv, port);
 +              return cpt_digital_port_connected(encoder);
  }
  
 -static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                     struct intel_digital_port *intel_dig_port)
 +static bool bxt_digital_port_connected(struct intel_encoder *encoder)
  {
 -      struct intel_encoder *intel_encoder = &intel_dig_port->base;
 -      enum port port;
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u32 bit;
  
 -      port = intel_hpd_pin_to_port(intel_encoder->hpd_pin);
 -      switch (port) {
 -      case PORT_A:
 +      switch (encoder->hpd_pin) {
 +      case HPD_PORT_A:
                bit = BXT_DE_PORT_HP_DDIA;
                break;
 -      case PORT_B:
 +      case HPD_PORT_B:
                bit = BXT_DE_PORT_HP_DDIB;
                break;
 -      case PORT_C:
 +      case HPD_PORT_C:
                bit = BXT_DE_PORT_HP_DDIC;
                break;
        default:
 -              MISSING_CASE(port);
 +              MISSING_CASE(encoder->hpd_pin);
                return false;
        }
  
  
  /*
   * intel_digital_port_connected - is the specified port connected?
 - * @dev_priv: i915 private structure
 - * @port: the port to test
 + * @encoder: intel_encoder
   *
 - * Return %true if @port is connected, %false otherwise.
 + * Return %true if port is connected, %false otherwise.
   */
 -bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                struct intel_digital_port *port)
 +bool intel_digital_port_connected(struct intel_encoder *encoder)
  {
 +      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 +
        if (HAS_GMCH_DISPLAY(dev_priv)) {
                if (IS_GM45(dev_priv))
 -                      return gm45_digital_port_connected(dev_priv, port);
 +                      return gm45_digital_port_connected(encoder);
                else
 -                      return g4x_digital_port_connected(dev_priv, port);
 +                      return g4x_digital_port_connected(encoder);
        }
  
        if (IS_GEN5(dev_priv))
 -              return ilk_digital_port_connected(dev_priv, port);
 +              return ilk_digital_port_connected(encoder);
        else if (IS_GEN6(dev_priv))
 -              return snb_digital_port_connected(dev_priv, port);
 +              return snb_digital_port_connected(encoder);
        else if (IS_GEN7(dev_priv))
 -              return ivb_digital_port_connected(dev_priv, port);
 +              return ivb_digital_port_connected(encoder);
        else if (IS_GEN8(dev_priv))
 -              return bdw_digital_port_connected(dev_priv, port);
 +              return bdw_digital_port_connected(encoder);
        else if (IS_GEN9_LP(dev_priv))
 -              return bxt_digital_port_connected(dev_priv, port);
 +              return bxt_digital_port_connected(encoder);
        else
 -              return spt_digital_port_connected(dev_priv, port);
 +              return spt_digital_port_connected(encoder);
  }
  
  static struct edid *
@@@ -4756,7 -4739,8 +4780,7 @@@ intel_dp_long_pulse(struct intel_connec
        /* Can't disconnect eDP, but you can close the lid... */
        if (intel_dp_is_edp(intel_dp))
                status = edp_detect(intel_dp);
 -      else if (intel_digital_port_connected(dev_priv,
 -                                            dp_to_dig_port(intel_dp)))
 +      else if (intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base))
                status = intel_dp_detect_dpcd(intel_dp);
        else
                status = connector_status_disconnected;
@@@ -5025,6 -5009,236 +5049,236 @@@ void intel_dp_encoder_suspend(struct in
        pps_unlock(intel_dp);
  }
  
+ static
+ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
+                               u8 *an)
+ {
+       struct intel_dp *intel_dp = enc_to_intel_dp(&intel_dig_port->base.base);
+       uint8_t txbuf[4], rxbuf[2], reply = 0;
+       ssize_t dpcd_ret;
+       int ret;
+       /* Output An first, that's easy */
+       dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
+                                    an, DRM_HDCP_AN_LEN);
+       if (dpcd_ret != DRM_HDCP_AN_LEN) {
+               DRM_ERROR("Failed to write An over DP/AUX (%zd)\n", dpcd_ret);
+               return dpcd_ret >= 0 ? -EIO : dpcd_ret;
+       }
+       /*
+        * Since Aksv is Oh-So-Secret, we can't access it in software. So in
+        * order to get it on the wire, we need to create the AUX header as if
+        * we were writing the data, and then tickle the hardware to output the
+        * data once the header is sent out.
+        */
+       txbuf[0] = (DP_AUX_NATIVE_WRITE << 4) |
+                  ((DP_AUX_HDCP_AKSV >> 16) & 0xf);
+       txbuf[1] = (DP_AUX_HDCP_AKSV >> 8) & 0xff;
+       txbuf[2] = DP_AUX_HDCP_AKSV & 0xff;
+       txbuf[3] = DRM_HDCP_KSV_LEN - 1;
+       ret = intel_dp_aux_ch(intel_dp, txbuf, sizeof(txbuf), rxbuf,
+                             sizeof(rxbuf), true);
+       if (ret < 0) {
+               DRM_ERROR("Write Aksv over DP/AUX failed (%d)\n", ret);
+               return ret;
+       } else if (ret == 0) {
+               DRM_ERROR("Aksv write over DP/AUX was empty\n");
+               return -EIO;
+       }
+       reply = (rxbuf[0] >> 4) & DP_AUX_NATIVE_REPLY_MASK;
+       return reply == DP_AUX_NATIVE_REPLY_ACK ? 0 : -EIO;
+ }
+ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
+                                  u8 *bksv)
+ {
+       ssize_t ret;
+       ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
+                              DRM_HDCP_KSV_LEN);
+       if (ret != DRM_HDCP_KSV_LEN) {
+               DRM_ERROR("Read Bksv from DP/AUX failed (%zd)\n", ret);
+               return ret >= 0 ? -EIO : ret;
+       }
+       return 0;
+ }
+ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+                                     u8 *bstatus)
+ {
+       ssize_t ret;
+       /*
+        * For some reason the HDMI and DP HDCP specs call this register
+        * definition by different names. In the HDMI spec, it's called BSTATUS,
+        * but in DP it's called BINFO.
+        */
+       ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO,
+                              bstatus, DRM_HDCP_BSTATUS_LEN);
+       if (ret != DRM_HDCP_BSTATUS_LEN) {
+               DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret);
+               return ret >= 0 ? -EIO : ret;
+       }
+       return 0;
+ }
+ static
+ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
+                            u8 *bcaps)
+ {
+       ssize_t ret;
+       ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
+                              bcaps, 1);
+       if (ret != 1) {
+               DRM_ERROR("Read bcaps from DP/AUX failed (%zd)\n", ret);
+               return ret >= 0 ? -EIO : ret;
+       }
+       return 0;
+ }
+ static
+ int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
+                                  bool *repeater_present)
+ {
+       ssize_t ret;
+       u8 bcaps;
+       ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+       if (ret)
+               return ret;
+       *repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
+       return 0;
+ }
+ static
+ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
+                               u8 *ri_prime)
+ {
+       ssize_t ret;
+       ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
+                              ri_prime, DRM_HDCP_RI_LEN);
+       if (ret != DRM_HDCP_RI_LEN) {
+               DRM_ERROR("Read Ri' from DP/AUX failed (%zd)\n", ret);
+               return ret >= 0 ? -EIO : ret;
+       }
+       return 0;
+ }
+ static
+ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
+                                bool *ksv_ready)
+ {
+       ssize_t ret;
+       u8 bstatus;
+       ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
+                              &bstatus, 1);
+       if (ret != 1) {
+               DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret);
+               return ret >= 0 ? -EIO : ret;
+       }
+       *ksv_ready = bstatus & DP_BSTATUS_READY;
+       return 0;
+ }
+ static
+ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
+                               int num_downstream, u8 *ksv_fifo)
+ {
+       ssize_t ret;
+       int i;
+       /* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
+       for (i = 0; i < num_downstream; i += 3) {
+               size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
+               ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+                                      DP_AUX_HDCP_KSV_FIFO,
+                                      ksv_fifo + i * DRM_HDCP_KSV_LEN,
+                                      len);
+               if (ret != len) {
+                       DRM_ERROR("Read ksv[%d] from DP/AUX failed (%zd)\n", i,
+                                 ret);
+                       return ret >= 0 ? -EIO : ret;
+               }
+       }
+       return 0;
+ }
+ static
+ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
+                                   int i, u32 *part)
+ {
+       ssize_t ret;
+       if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
+               return -EINVAL;
+       ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+                              DP_AUX_HDCP_V_PRIME(i), part,
+                              DRM_HDCP_V_PRIME_PART_LEN);
+       if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
+               DRM_ERROR("Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
+               return ret >= 0 ? -EIO : ret;
+       }
+       return 0;
+ }
+ static
+ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+                                   bool enable)
+ {
+       /* Not used for single stream DisplayPort setups */
+       return 0;
+ }
+ static
+ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+ {
+       ssize_t ret;
+       u8 bstatus;
+       ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
+                              &bstatus, 1);
+       if (ret != 1) {
+               DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret);
+               return false;
+       }
+       return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
+ }
+ static
+ int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
+                         bool *hdcp_capable)
+ {
+       ssize_t ret;
+       u8 bcaps;
+       ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+       if (ret)
+               return ret;
+       *hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
+       return 0;
+ }
+ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
+       .write_an_aksv = intel_dp_hdcp_write_an_aksv,
+       .read_bksv = intel_dp_hdcp_read_bksv,
+       .read_bstatus = intel_dp_hdcp_read_bstatus,
+       .repeater_present = intel_dp_hdcp_repeater_present,
+       .read_ri_prime = intel_dp_hdcp_read_ri_prime,
+       .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
+       .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
+       .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
+       .toggle_signalling = intel_dp_hdcp_toggle_signalling,
+       .check_link = intel_dp_hdcp_check_link,
+       .hdcp_capable = intel_dp_hdcp_capable,
+ };
  static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
  {
        struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
@@@ -5190,6 -5404,9 +5444,9 @@@ err
                drm_modeset_acquire_fini(&ctx);
                WARN(iret, "Acquiring modeset locks failed with %i\n", iret);
  
+               /* Short pulse can signify loss of hdcp authentication */
+               intel_hdcp_check_link(intel_dp->attached_connector);
                if (!handled) {
                        intel_dp->detect_done = false;
                        goto put_power;
@@@ -5267,8 -5484,7 +5524,8 @@@ intel_pps_readout_hw_state(struct intel
  
        pp_on = I915_READ(regs.pp_on);
        pp_off = I915_READ(regs.pp_off);
 -      if (!IS_GEN9_LP(dev_priv) && !HAS_PCH_CNP(dev_priv)) {
 +      if (!IS_GEN9_LP(dev_priv) && !HAS_PCH_CNP(dev_priv) &&
 +          !HAS_PCH_ICP(dev_priv)) {
                I915_WRITE(regs.pp_ctrl, pp_ctl);
                pp_div = I915_READ(regs.pp_div);
        }
        seq->t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
                   PANEL_POWER_DOWN_DELAY_SHIFT;
  
 -      if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) {
 +      if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv) ||
 +          HAS_PCH_ICP(dev_priv)) {
                seq->t11_t12 = ((pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >>
                                BXT_POWER_CYCLE_DELAY_SHIFT) * 1000;
        } else {
@@@ -5458,8 -5673,7 +5715,8 @@@ intel_dp_init_panel_power_sequencer_reg
                 (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT);
        /* Compute the divisor for the pp clock, simply match the Bspec
         * formula. */
 -      if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) {
 +      if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv) ||
 +          HAS_PCH_ICP(dev_priv)) {
                pp_div = I915_READ(regs.pp_ctrl);
                pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK;
                pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)
  
        I915_WRITE(regs.pp_on, pp_on);
        I915_WRITE(regs.pp_off, pp_off);
 -      if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv))
 +      if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv) ||
 +          HAS_PCH_ICP(dev_priv))
                I915_WRITE(regs.pp_ctrl, pp_div);
        else
                I915_WRITE(regs.pp_div, pp_div);
        DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n",
                      I915_READ(regs.pp_on),
                      I915_READ(regs.pp_off),
 -                    (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) ?
 +                    (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)  ||
 +                     HAS_PCH_ICP(dev_priv)) ?
                      (I915_READ(regs.pp_ctrl) & BXT_POWER_CYCLE_DELAY_MASK) :
                      I915_READ(regs.pp_div));
  }
@@@ -6015,10 -6227,8 +6272,10 @@@ intel_dp_init_connector_port_info(struc
  {
        struct intel_encoder *encoder = &intel_dig_port->base;
        struct intel_dp *intel_dp = &intel_dig_port->dp;
 +      struct intel_encoder *intel_encoder = &intel_dig_port->base;
 +      struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
  
 -      encoder->hpd_pin = intel_hpd_pin(encoder->port);
 +      encoder->hpd_pin = intel_hpd_pin_default(dev_priv, encoder->port);
  
        switch (encoder->port) {
        case PORT_A:
                /* FIXME: Check VBT for actual wiring of PORT E */
                intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D;
                break;
 +      case PORT_F:
 +              intel_dp->aux_power_domain = POWER_DOMAIN_AUX_F;
 +              break;
        default:
                MISSING_CASE(encoder->port);
        }
@@@ -6166,8 -6373,7 +6423,8 @@@ intel_dp_init_connector(struct intel_di
  
        /* init MST on ports that can support it */
        if (HAS_DP_MST(dev_priv) && !intel_dp_is_edp(intel_dp) &&
 -          (port == PORT_B || port == PORT_C || port == PORT_D))
 +          (port == PORT_B || port == PORT_C ||
 +           port == PORT_D || port == PORT_F))
                intel_dp_mst_encoder_init(intel_dig_port,
                                          intel_connector->base.base.id);
  
        }
  
        intel_dp_add_properties(intel_dp, connector);
+       if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) {
+               int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+               if (ret)
+                       DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
+       }
  
        /* 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
index cdcbeb595bb133b36de61894d7ad50769cba5993,c902be85e456ecb4fee2df2b05d65bea7d98741f..468ec1e90e16dab6bb451636719a95a22d8d6cf5
  #include <drm/drm_atomic.h>
  
  /**
-  * _wait_for - magic (register) wait macro
+  * __wait_for - magic wait macro
   *
-  * Does the right thing for modeset paths when run under kdgb or similar atomic
-  * contexts. Note that it's important that we check the condition again after
-  * having timed out, since the timeout could be due to preemption or similar and
-  * we've never had a chance to check the condition before the timeout.
+  * Macro to help avoid open coding check/wait/timeout patterns. Note that it's
+  * important that we check the condition again after having timed out, since the
+  * timeout could be due to preemption or similar and we've never had a chance to
+  * check the condition before the timeout.
   */
- #define _wait_for(COND, US, Wmin, Wmax) ({ \
+ #define __wait_for(OP, COND, US, Wmin, Wmax) ({ \
        unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1;   \
        long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \
        int ret__;                                                      \
        might_sleep();                                                  \
        for (;;) {                                                      \
                bool expired__ = time_after(jiffies, timeout__);        \
+               OP;                                                     \
                if (COND) {                                             \
                        ret__ = 0;                                      \
                        break;                                          \
@@@ -70,7 -71,9 +71,9 @@@
        ret__;                                                          \
  })
  
- #define wait_for(COND, MS)    _wait_for((COND), (MS) * 1000, 10, 1000)
+ #define _wait_for(COND, US, Wmin, Wmax)       __wait_for(, (COND), (US), (Wmin), \
+                                                  (Wmax))
+ #define wait_for(COND, MS)            _wait_for((COND), (MS) * 1000, 10, 1000)
  
  /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */
  #if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT)
@@@ -298,6 -301,80 +301,80 @@@ struct intel_panel 
        } backlight;
  };
  
+ /*
+  * 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
+  * from HDCP over DP, so to account for these differences, we need to
+  * communicate with the receiver through this shim.
+  *
+  * For completeness, the 2 buses differ in the following ways:
+  *    - DP AUX vs. DDC
+  *            HDCP registers on the receiver are set via DP AUX for DP, and
+  *            they are set via DDC for HDMI.
+  *    - Receiver register offsets
+  *            The offsets of the registers are different for DP vs. HDMI
+  *    - Receiver register masks/offsets
+  *            For instance, the ready bit for the KSV fifo is in a different
+  *            place on DP vs HDMI
+  *    - Receiver register names
+  *            Seriously. In the DP spec, the 16-bit register containing
+  *            downstream information is called BINFO, on HDMI it's called
+  *            BSTATUS. To confuse matters further, DP has a BSTATUS register
+  *            with a completely different definition.
+  *    - KSV FIFO
+  *            On HDMI, the ksv fifo is read all at once, whereas on DP it must
+  *            be read 3 keys at a time
+  *    - Aksv output
+  *            Since Aksv is hidden in hardware, there's different procedures
+  *            to send it over DP AUX vs DDC
+  */
+ struct intel_hdcp_shim {
+       /* Outputs the transmitter's An and Aksv values to the receiver. */
+       int (*write_an_aksv)(struct intel_digital_port *intel_dig_port, u8 *an);
+       /* Reads the receiver's key selection vector */
+       int (*read_bksv)(struct intel_digital_port *intel_dig_port, u8 *bksv);
+       /*
+        * Reads BINFO from DP receivers and BSTATUS from HDMI receivers. The
+        * definitions are the same in the respective specs, but the names are
+        * different. Call it BSTATUS since that's the name the HDMI spec
+        * uses and it was there first.
+        */
+       int (*read_bstatus)(struct intel_digital_port *intel_dig_port,
+                           u8 *bstatus);
+       /* Determines whether a repeater is present downstream */
+       int (*repeater_present)(struct intel_digital_port *intel_dig_port,
+                               bool *repeater_present);
+       /* Reads the receiver's Ri' value */
+       int (*read_ri_prime)(struct intel_digital_port *intel_dig_port, u8 *ri);
+       /* Determines if the receiver's KSV FIFO is ready for consumption */
+       int (*read_ksv_ready)(struct intel_digital_port *intel_dig_port,
+                             bool *ksv_ready);
+       /* Reads the ksv fifo for num_downstream devices */
+       int (*read_ksv_fifo)(struct intel_digital_port *intel_dig_port,
+                            int num_downstream, u8 *ksv_fifo);
+       /* Reads a 32-bit part of V' from the receiver */
+       int (*read_v_prime_part)(struct intel_digital_port *intel_dig_port,
+                                int i, u32 *part);
+       /* Enables HDCP signalling on the port */
+       int (*toggle_signalling)(struct intel_digital_port *intel_dig_port,
+                                bool enable);
+       /* Ensures the link is still protected */
+       bool (*check_link)(struct intel_digital_port *intel_dig_port);
+       /* Detects panel's hdcp capability. This is optional for HDMI. */
+       int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
+                           bool *hdcp_capable);
+ };
  struct intel_connector {
        struct drm_connector base;
        /*
  
        /* Work struct to schedule a uevent on link train failure */
        struct work_struct modeset_retry_work;
+       const struct intel_hdcp_shim *hdcp_shim;
+       struct mutex hdcp_mutex;
+       uint64_t hdcp_value; /* protected by hdcp_mutex */
+       struct delayed_work hdcp_check_work;
+       struct work_struct hdcp_prop_work;
  };
  
  struct intel_digital_connector_state {
@@@ -406,6 -489,7 +489,6 @@@ struct intel_atomic_state 
  
  struct intel_plane_state {
        struct drm_plane_state base;
 -      struct drm_rect clip;
        struct i915_vma *vma;
  
        struct {
@@@ -1297,6 -1381,8 +1380,8 @@@ void intel_ddi_compute_min_voltage_leve
  u32 bxt_signal_levels(struct intel_dp *intel_dp);
  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
  u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
+ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
+                                    bool enable);
  
  unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
                                   int plane, unsigned int height);
@@@ -1506,8 -1592,7 +1591,8 @@@ u32 skl_plane_ctl(const struct intel_cr
                  const struct intel_plane_state *plane_state);
  u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
                     unsigned int rotation);
 -int skl_check_plane_surface(struct intel_plane_state *plane_state);
 +int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
 +                          struct intel_plane_state *plane_state);
  int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
  
  /* intel_csr.c */
@@@ -1590,7 -1675,8 +1675,7 @@@ static inline unsigned int intel_dp_unu
  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
  int intel_dp_link_required(int pixel_clock, int bpp);
  int intel_dp_max_data_rate(int max_link_clock, int max_lanes);
 -bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 -                                struct intel_digital_port *port);
 +bool intel_digital_port_connected(struct intel_encoder *encoder);
  
  /* intel_dp_aux_backlight.c */
  int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector);
@@@ -1757,9 -1843,18 +1842,19 @@@ static inline void intel_backlight_devi
  }
  #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
  
+ /* intel_hdcp.c */
+ void intel_hdcp_atomic_check(struct drm_connector *connector,
+                            struct drm_connector_state *old_state,
+                            struct drm_connector_state *new_state);
+ int intel_hdcp_init(struct intel_connector *connector,
+                   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);
  
  /* intel_psr.c */
 +#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
  void intel_psr_enable(struct intel_dp *intel_dp,
                      const struct intel_crtc_state *crtc_state);
  void intel_psr_disable(struct intel_dp *intel_dp,
@@@ -1932,8 -2027,6 +2027,8 @@@ void skl_update_plane(struct intel_plan
                      const struct intel_plane_state *plane_state);
  void skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc);
  bool skl_plane_get_hw_state(struct intel_plane *plane);
 +bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
 +                     enum pipe pipe, enum plane_id plane_id);
  
  /* intel_tv.c */
  void intel_tv_init(struct drm_i915_private *dev_priv);
index 23150f598dfa77a6742a0ae410e1bba84cf7d444,b5a388208afa2b56d502446d97992f545f8a5060..f5d7bfb4300622088a00a41fd05972d93c0a5853
@@@ -34,6 -34,7 +34,7 @@@
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_crtc.h>
  #include <drm/drm_edid.h>
+ #include <drm/drm_hdcp.h>
  #include <drm/drm_scdc_helper.h>
  #include "intel_drv.h"
  #include <drm/i915_drm.h>
@@@ -876,6 -877,248 +877,248 @@@ void intel_dp_dual_mode_set_tmds_output
                                         adapter, enable);
  }
  
+ static int intel_hdmi_hdcp_read(struct intel_digital_port *intel_dig_port,
+                               unsigned int offset, void *buffer, size_t size)
+ {
+       struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
+       struct drm_i915_private *dev_priv =
+               intel_dig_port->base.base.dev->dev_private;
+       struct i2c_adapter *adapter = intel_gmbus_get_adapter(dev_priv,
+                                                             hdmi->ddc_bus);
+       int ret;
+       u8 start = offset & 0xff;
+       struct i2c_msg msgs[] = {
+               {
+                       .addr = DRM_HDCP_DDC_ADDR,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &start,
+               },
+               {
+                       .addr = DRM_HDCP_DDC_ADDR,
+                       .flags = I2C_M_RD,
+                       .len = size,
+                       .buf = buffer
+               }
+       };
+       ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
+       if (ret == ARRAY_SIZE(msgs))
+               return 0;
+       return ret >= 0 ? -EIO : ret;
+ }
+ static int intel_hdmi_hdcp_write(struct intel_digital_port *intel_dig_port,
+                                unsigned int offset, void *buffer, size_t size)
+ {
+       struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
+       struct drm_i915_private *dev_priv =
+               intel_dig_port->base.base.dev->dev_private;
+       struct i2c_adapter *adapter = intel_gmbus_get_adapter(dev_priv,
+                                                             hdmi->ddc_bus);
+       int ret;
+       u8 *write_buf;
+       struct i2c_msg msg;
+       write_buf = kzalloc(size + 1, GFP_KERNEL);
+       if (!write_buf)
+               return -ENOMEM;
+       write_buf[0] = offset & 0xff;
+       memcpy(&write_buf[1], buffer, size);
+       msg.addr = DRM_HDCP_DDC_ADDR;
+       msg.flags = 0,
+       msg.len = size + 1,
+       msg.buf = write_buf;
+       ret = i2c_transfer(adapter, &msg, 1);
+       if (ret == 1)
+               return 0;
+       return ret >= 0 ? -EIO : ret;
+ }
+ static
+ int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
+                                 u8 *an)
+ {
+       struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
+       struct drm_i915_private *dev_priv =
+               intel_dig_port->base.base.dev->dev_private;
+       struct i2c_adapter *adapter = intel_gmbus_get_adapter(dev_priv,
+                                                             hdmi->ddc_bus);
+       int ret;
+       ret = intel_hdmi_hdcp_write(intel_dig_port, DRM_HDCP_DDC_AN, an,
+                                   DRM_HDCP_AN_LEN);
+       if (ret) {
+               DRM_ERROR("Write An over DDC failed (%d)\n", ret);
+               return ret;
+       }
+       ret = intel_gmbus_output_aksv(adapter);
+       if (ret < 0) {
+               DRM_ERROR("Failed to output aksv (%d)\n", ret);
+               return ret;
+       }
+       return 0;
+ }
+ static int intel_hdmi_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
+                                    u8 *bksv)
+ {
+       int ret;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BKSV, bksv,
+                                  DRM_HDCP_KSV_LEN);
+       if (ret)
+               DRM_ERROR("Read Bksv over DDC failed (%d)\n", ret);
+       return ret;
+ }
+ static
+ int intel_hdmi_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+                                u8 *bstatus)
+ {
+       int ret;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BSTATUS,
+                                  bstatus, DRM_HDCP_BSTATUS_LEN);
+       if (ret)
+               DRM_ERROR("Read bstatus over DDC failed (%d)\n", ret);
+       return ret;
+ }
+ static
+ int intel_hdmi_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
+                                    bool *repeater_present)
+ {
+       int ret;
+       u8 val;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BCAPS, &val, 1);
+       if (ret) {
+               DRM_ERROR("Read bcaps over DDC failed (%d)\n", ret);
+               return ret;
+       }
+       *repeater_present = val & DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT;
+       return 0;
+ }
+ static
+ int intel_hdmi_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
+                                 u8 *ri_prime)
+ {
+       int ret;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_RI_PRIME,
+                                  ri_prime, DRM_HDCP_RI_LEN);
+       if (ret)
+               DRM_ERROR("Read Ri' over DDC failed (%d)\n", ret);
+       return ret;
+ }
+ static
+ int intel_hdmi_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
+                                  bool *ksv_ready)
+ {
+       int ret;
+       u8 val;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BCAPS, &val, 1);
+       if (ret) {
+               DRM_ERROR("Read bcaps over DDC failed (%d)\n", ret);
+               return ret;
+       }
+       *ksv_ready = val & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY;
+       return 0;
+ }
+ static
+ int intel_hdmi_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
+                                 int num_downstream, u8 *ksv_fifo)
+ {
+       int ret;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_KSV_FIFO,
+                                  ksv_fifo, num_downstream * DRM_HDCP_KSV_LEN);
+       if (ret) {
+               DRM_ERROR("Read ksv fifo over DDC failed (%d)\n", ret);
+               return ret;
+       }
+       return 0;
+ }
+ static
+ int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
+                                     int i, u32 *part)
+ {
+       int ret;
+       if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
+               return -EINVAL;
+       ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_V_PRIME(i),
+                                  part, DRM_HDCP_V_PRIME_PART_LEN);
+       if (ret)
+               DRM_ERROR("Read V'[%d] over DDC failed (%d)\n", i, ret);
+       return ret;
+ }
+ static
+ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+                                     bool enable)
+ {
+       int ret;
+       if (!enable)
+               usleep_range(6, 60); /* Bspec says >= 6us */
+       ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, enable);
+       if (ret) {
+               DRM_ERROR("%s HDCP signalling failed (%d)\n",
+                         enable ? "Enable" : "Disable", ret);
+               return ret;
+       }
+       return 0;
+ }
+ static
+ bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+ {
+       struct drm_i915_private *dev_priv =
+               intel_dig_port->base.base.dev->dev_private;
+       enum port port = intel_dig_port->base.port;
+       int ret;
+       union {
+               u32 reg;
+               u8 shim[DRM_HDCP_RI_LEN];
+       } ri;
+       ret = intel_hdmi_hdcp_read_ri_prime(intel_dig_port, ri.shim);
+       if (ret)
+               return false;
+       I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
+       /* Wait for Ri prime match */
+       if (wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
+                    (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
+               DRM_ERROR("Ri' mismatch detected, link check failed (%x)\n",
+                         I915_READ(PORT_HDCP_STATUS(port)));
+               return false;
+       }
+       return true;
+ }
+ 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_bstatus = intel_hdmi_hdcp_read_bstatus,
+       .repeater_present = intel_hdmi_hdcp_repeater_present,
+       .read_ri_prime = intel_hdmi_hdcp_read_ri_prime,
+       .read_ksv_ready = intel_hdmi_hdcp_read_ksv_ready,
+       .read_ksv_fifo = intel_hdmi_hdcp_read_ksv_fifo,
+       .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,
+ };
  static void intel_hdmi_prepare(struct intel_encoder *encoder,
                               const struct intel_crtc_state *crtc_state)
  {
@@@ -1314,6 -1557,9 +1557,6 @@@ intel_hdmi_mode_valid(struct drm_connec
        bool force_dvi =
                READ_ONCE(to_intel_digital_connector_state(connector->state)->force_audio) == HDMI_AUDIO_OFF_DVI;
  
 -      if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 -              return MODE_NO_DBLESCAN;
 -
        clock = mode->clock;
  
        if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
@@@ -1564,10 -1810,7 +1807,10 @@@ intel_hdmi_dp_dual_mode_detect(struct d
         * there's nothing connected to the port.
         */
        if (type == DRM_DP_DUAL_MODE_UNKNOWN) {
 -              if (has_edid &&
 +              /* An overridden EDID imply that we want this port for testing.
 +               * Make sure not to set limits for that port.
 +               */
 +              if (has_edid && !connector->override_edid &&
                    intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
                        DRM_DEBUG_KMS("Assuming DP dual mode adaptor presence based on VBT\n");
                        type = DRM_DP_DUAL_MODE_TYPE1_DVI;
@@@ -1595,20 -1838,12 +1838,20 @@@ intel_hdmi_set_edid(struct drm_connecto
        struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
        struct edid *edid;
        bool connected = false;
 +      struct i2c_adapter *i2c;
  
        intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
  
 -      edid = drm_get_edid(connector,
 -                          intel_gmbus_get_adapter(dev_priv,
 -                          intel_hdmi->ddc_bus));
 +      i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
 +
 +      edid = drm_get_edid(connector, i2c);
 +
 +      if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
 +              DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
 +              intel_gmbus_force_bit(i2c, true);
 +              edid = drm_get_edid(connector, i2c);
 +              intel_gmbus_force_bit(i2c, false);
 +      }
  
        intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
  
@@@ -1932,9 -2167,6 +2175,9 @@@ static u8 cnp_port_to_ddc_pin(struct dr
        case PORT_D:
                ddc_pin = GMBUS_PIN_4_CNP;
                break;
 +      case PORT_F:
 +              ddc_pin = GMBUS_PIN_3_BXT;
 +              break;
        default:
                MISSING_CASE(port);
                ddc_pin = GMBUS_PIN_1_BXT;
        return ddc_pin;
  }
  
 +static u8 icl_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
 +{
 +      u8 ddc_pin;
 +
 +      switch (port) {
 +      case PORT_A:
 +              ddc_pin = GMBUS_PIN_1_BXT;
 +              break;
 +      case PORT_B:
 +              ddc_pin = GMBUS_PIN_2_BXT;
 +              break;
 +      case PORT_C:
 +              ddc_pin = GMBUS_PIN_9_TC1_ICP;
 +              break;
 +      case PORT_D:
 +              ddc_pin = GMBUS_PIN_10_TC2_ICP;
 +              break;
 +      case PORT_E:
 +              ddc_pin = GMBUS_PIN_11_TC3_ICP;
 +              break;
 +      case PORT_F:
 +              ddc_pin = GMBUS_PIN_12_TC4_ICP;
 +              break;
 +      default:
 +              MISSING_CASE(port);
 +              ddc_pin = GMBUS_PIN_2_BXT;
 +              break;
 +      }
 +      return ddc_pin;
 +}
 +
  static u8 g4x_port_to_ddc_pin(struct drm_i915_private *dev_priv,
                              enum port port)
  {
@@@ -2016,8 -2217,6 +2259,8 @@@ static u8 intel_hdmi_ddc_pin(struct drm
                ddc_pin = bxt_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 (IS_ICELAKE(dev_priv))
 +              ddc_pin = icl_port_to_ddc_pin(dev_priv, port);
        else
                ddc_pin = g4x_port_to_ddc_pin(dev_priv, port);
  
@@@ -2088,7 -2287,7 +2331,7 @@@ void intel_hdmi_init_connector(struct i
  
        if (WARN_ON(port == PORT_A))
                return;
 -      intel_encoder->hpd_pin = intel_hpd_pin(port);
 +      intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
  
        if (HAS_DDI(dev_priv))
                intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
  
        intel_hdmi_add_properties(intel_hdmi, connector);
  
+       if (is_hdcp_supported(dev_priv, port)) {
+               int ret = intel_hdcp_init(intel_connector,
+                                         &intel_hdmi_hdcp_shim);
+               if (ret)
+                       DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
+       }
        intel_connector_attach_encoder(intel_connector, intel_encoder);
        intel_hdmi->attached_connector = intel_connector;
  
index ad1b1a345f2e1cae7ce513bf174747ed1a50f962,6f7ef4e225ee4b7360bb3e97c48793bb7e43ce90..e6875509bcd9cc53330a2e980d450b7e26a26e4e
@@@ -30,6 -30,7 +30,7 @@@
  #include <linux/i2c-algo-bit.h>
  #include <linux/export.h>
  #include <drm/drmP.h>
+ #include <drm/drm_hdcp.h>
  #include "intel_drv.h"
  #include <drm/i915_drm.h>
  #include "i915_drv.h"
@@@ -75,22 -76,11 +76,22 @@@ static const struct gmbus_pin gmbus_pin
        [GMBUS_PIN_4_CNP] = { "dpd", GPIOE },
  };
  
 +static const struct gmbus_pin gmbus_pins_icp[] = {
 +      [GMBUS_PIN_1_BXT] = { "dpa", GPIOA },
 +      [GMBUS_PIN_2_BXT] = { "dpb", GPIOB },
 +      [GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOC },
 +      [GMBUS_PIN_10_TC2_ICP] = { "tc2", GPIOD },
 +      [GMBUS_PIN_11_TC3_ICP] = { "tc3", GPIOE },
 +      [GMBUS_PIN_12_TC4_ICP] = { "tc4", GPIOF },
 +};
 +
  /* pin is expected to be valid */
  static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv,
                                             unsigned int pin)
  {
 -      if (HAS_PCH_CNP(dev_priv))
 +      if (HAS_PCH_ICP(dev_priv))
 +              return &gmbus_pins_icp[pin];
 +      else if (HAS_PCH_CNP(dev_priv))
                return &gmbus_pins_cnp[pin];
        else if (IS_GEN9_LP(dev_priv))
                return &gmbus_pins_bxt[pin];
@@@ -107,9 -97,7 +108,9 @@@ bool intel_gmbus_is_valid_pin(struct dr
  {
        unsigned int size;
  
 -      if (HAS_PCH_CNP(dev_priv))
 +      if (HAS_PCH_ICP(dev_priv))
 +              size = ARRAY_SIZE(gmbus_pins_icp);
 +      else if (HAS_PCH_CNP(dev_priv))
                size = ARRAY_SIZE(gmbus_pins_cnp);
        else if (IS_GEN9_LP(dev_priv))
                size = ARRAY_SIZE(gmbus_pins_bxt);
@@@ -415,7 -403,8 +416,8 @@@ gmbus_xfer_read(struct drm_i915_privat
  
  static int
  gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
-                      unsigned short addr, u8 *buf, unsigned int len)
+                      unsigned short addr, u8 *buf, unsigned int len,
+                      u32 gmbus1_index)
  {
        unsigned int chunk_size = len;
        u32 val, loop;
  
        I915_WRITE_FW(GMBUS3, val);
        I915_WRITE_FW(GMBUS1,
-                     GMBUS_CYCLE_WAIT |
+                     gmbus1_index | GMBUS_CYCLE_WAIT |
                      (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
                      (addr << GMBUS_SLAVE_ADDR_SHIFT) |
                      GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
  }
  
  static int
- gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
+ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
+                u32 gmbus1_index)
  {
        u8 *buf = msg->buf;
        unsigned int tx_size = msg->len;
        do {
                len = min(tx_size, GMBUS_BYTE_COUNT_MAX);
  
-               ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len);
+               ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len,
+                                            gmbus1_index);
                if (ret)
                        return ret;
  
  }
  
  /*
-  * The gmbus controller can combine a 1 or 2 byte write with a read that
-  * immediately follows it by using an "INDEX" cycle.
+  * The gmbus controller can combine a 1 or 2 byte write with another read/write
+  * that immediately follows it by using an "INDEX" cycle.
   */
  static bool
- gmbus_is_index_read(struct i2c_msg *msgs, int i, int num)
+ gmbus_is_index_xfer(struct i2c_msg *msgs, int i, int num)
  {
        return (i + 1 < num &&
                msgs[i].addr == msgs[i + 1].addr &&
                !(msgs[i].flags & I2C_M_RD) &&
                (msgs[i].len == 1 || msgs[i].len == 2) &&
-               (msgs[i + 1].flags & I2C_M_RD));
+               msgs[i + 1].len > 0);
  }
  
  static int
- gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
+ gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
  {
        u32 gmbus1_index = 0;
        u32 gmbus5 = 0;
        if (gmbus5)
                I915_WRITE_FW(GMBUS5, gmbus5);
  
-       ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
+       if (msgs[1].flags & I2C_M_RD)
+               ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
+       else
+               ret = gmbus_xfer_write(dev_priv, &msgs[1], gmbus1_index);
  
        /* Clear GMBUS5 after each index transfer */
        if (gmbus5)
  }
  
  static int
- do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
+             u32 gmbus0_source)
  {
        struct intel_gmbus *bus = container_of(adapter,
                                               struct intel_gmbus,
                pch_gmbus_clock_gating(dev_priv, false);
  
  retry:
-       I915_WRITE_FW(GMBUS0, bus->reg0);
+       I915_WRITE_FW(GMBUS0, gmbus0_source | bus->reg0);
  
        for (; i < num; i += inc) {
                inc = 1;
-               if (gmbus_is_index_read(msgs, i, num)) {
-                       ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
-                       inc = 2; /* an index read is two msgs */
+               if (gmbus_is_index_xfer(msgs, i, num)) {
+                       ret = gmbus_index_xfer(dev_priv, &msgs[i]);
+                       inc = 2; /* an index transmission is two msgs */
                } else if (msgs[i].flags & I2C_M_RD) {
                        ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
                } else {
-                       ret = gmbus_xfer_write(dev_priv, &msgs[i]);
+                       ret = gmbus_xfer_write(dev_priv, &msgs[i], 0);
                }
  
                if (!ret)
@@@ -656,7 -651,7 +664,7 @@@ gmbus_xfer(struct i2c_adapter *adapter
                if (ret < 0)
                        bus->force_bit &= ~GMBUS_FORCE_BIT_RETRY;
        } else {
-               ret = do_gmbus_xfer(adapter, msgs, num);
+               ret = do_gmbus_xfer(adapter, msgs, num, 0);
                if (ret == -EAGAIN)
                        bus->force_bit |= GMBUS_FORCE_BIT_RETRY;
        }
        return ret;
  }
  
+ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
+ {
+       struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
+                                              adapter);
+       struct drm_i915_private *dev_priv = bus->dev_priv;
+       int ret;
+       u8 cmd = DRM_HDCP_DDC_AKSV;
+       u8 buf[DRM_HDCP_KSV_LEN] = { 0 };
+       struct i2c_msg msgs[] = {
+               {
+                       .addr = DRM_HDCP_DDC_ADDR,
+                       .flags = 0,
+                       .len = sizeof(cmd),
+                       .buf = &cmd,
+               },
+               {
+                       .addr = DRM_HDCP_DDC_ADDR,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+       intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+       mutex_lock(&dev_priv->gmbus_mutex);
+       /*
+        * In order to output Aksv to the receiver, use an indexed write to
+        * pass the i2c command, and tell GMBUS to use the HW-provided value
+        * instead of sourcing GMBUS3 for the data.
+        */
+       ret = do_gmbus_xfer(adapter, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT);
+       mutex_unlock(&dev_priv->gmbus_mutex);
+       intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+       return ret;
+ }
  static u32 gmbus_func(struct i2c_adapter *adapter)
  {
        return i2c_bit_algo.functionality(adapter) &
index 4075010ac088f98eefeeae4eae989380c4e3e614,129c8ac77985a8f8d960c09dc196eb3476d4501b..164dbb8cfa3682385986447c853997301a4b9f02
@@@ -1452,7 -1452,7 +1452,7 @@@ static const struct reg_whitelist 
  } reg_read_whitelist[] = { {
        .offset_ldw = RING_TIMESTAMP(RENDER_RING_BASE),
        .offset_udw = RING_TIMESTAMP_UDW(RENDER_RING_BASE),
 -      .gen_mask = INTEL_GEN_MASK(4, 10),
 +      .gen_mask = INTEL_GEN_MASK(4, 11),
        .size = 8
  } };
  
@@@ -1767,12 -1767,14 +1767,14 @@@ int __intel_wait_for_register_fw(struc
  }
  
  /**
-  * intel_wait_for_register - wait until register matches expected state
+  * __intel_wait_for_register - wait until register matches expected state
   * @dev_priv: the i915 device
   * @reg: the register to read
   * @mask: mask to apply to register value
   * @value: expected value
-  * @timeout_ms: timeout in millisecond
+  * @fast_timeout_us: fast timeout in microsecond for atomic/tight wait
+  * @slow_timeout_ms: slow timeout in millisecond
+  * @out_value: optional placeholder to hold registry value
   *
   * This routine waits until the target register @reg contains the expected
   * @value after applying the @mask, i.e. it waits until ::
   *
   * Returns 0 if the register matches the desired condition, or -ETIMEOUT.
   */
- int intel_wait_for_register(struct drm_i915_private *dev_priv,
+ int __intel_wait_for_register(struct drm_i915_private *dev_priv,
                            i915_reg_t reg,
                            u32 mask,
                            u32 value,
-                           unsigned int timeout_ms)
+                           unsigned int fast_timeout_us,
+                           unsigned int slow_timeout_ms,
+                           u32 *out_value)
  {
        unsigned fw =
                intel_uncore_forcewake_for_reg(dev_priv, reg, FW_REG_READ);
+       u32 reg_value;
        int ret;
  
        might_sleep();
  
        ret = __intel_wait_for_register_fw(dev_priv,
                                           reg, mask, value,
-                                          2, 0, NULL);
+                                          fast_timeout_us, 0, &reg_value);
  
        intel_uncore_forcewake_put__locked(dev_priv, fw);
        spin_unlock_irq(&dev_priv->uncore.lock);
  
        if (ret)
-               ret = wait_for((I915_READ_NOTRACE(reg) & mask) == value,
-                              timeout_ms);
+               ret = __wait_for(reg_value = I915_READ_NOTRACE(reg),
+                                (reg_value & mask) == value,
+                                slow_timeout_ms * 1000, 10, 1000);
+       if (out_value)
+               *out_value = reg_value;
  
        return ret;
  }
@@@ -1936,7 -1945,8 +1945,7 @@@ int intel_reset_guc(struct drm_i915_pri
  {
        int ret;
  
 -      if (!HAS_GUC(dev_priv))
 -              return -EINVAL;
 +      GEM_BUG_ON(!HAS_GUC(dev_priv));
  
        intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
        ret = gen6_hw_domain_reset(dev_priv, GEN9_GRDOM_GUC);
index 768d9eda06cb9a1b60c1ce4f3b7fbaa8b5bc4779,9d3ce3b9b1215223b3ebec3497a105f4b84cff08..c239e6e24a1014504cb0a04d17a9b194782c6d41
@@@ -75,7 -75,6 +75,7 @@@
  #define DP_MAX_DOWNSPREAD                   0x003
  # define DP_MAX_DOWNSPREAD_0_5                    (1 << 0)
  # define DP_NO_AUX_HANDSHAKE_LINK_TRAINING  (1 << 6)
 +# define DP_TPS4_SUPPORTED                  (1 << 7)
  
  #define DP_NORP                             0x004
  
  # define DP_LINK_BW_1_62                  0x06
  # define DP_LINK_BW_2_7                           0x0a
  # define DP_LINK_BW_5_4                           0x14    /* 1.2 */
 +# define DP_LINK_BW_8_1                           0x1e    /* 1.4 */
  
  #define DP_LANE_COUNT_SET                 0x101
  # define DP_LANE_COUNT_MASK               0x0f
  # define DP_TRAINING_PATTERN_1                    1
  # define DP_TRAINING_PATTERN_2                    2
  # define DP_TRAINING_PATTERN_3                    3       /* 1.2 */
 +# define DP_TRAINING_PATTERN_4              7       /* 1.4 */
  # define DP_TRAINING_PATTERN_MASK         0x3
 +# define DP_TRAINING_PATTERN_MASK_1_4     0xf
  
  /* DPCD 1.1 only. For DPCD >= 1.2 see per-lane DP_LINK_QUAL_LANEn_SET */
  # define DP_LINK_QUAL_PATTERN_11_DISABLE    (0 << 2)
  #define DP_CEC_TX_MESSAGE_BUFFER               0x3020
  #define DP_CEC_MESSAGE_BUFFER_LENGTH             0x10
  
+ #define DP_AUX_HDCP_BKSV              0x68000
+ #define DP_AUX_HDCP_RI_PRIME          0x68005
+ #define DP_AUX_HDCP_AKSV              0x68007
+ #define DP_AUX_HDCP_AN                        0x6800C
+ #define DP_AUX_HDCP_V_PRIME(h)                (0x68014 + h * 4)
+ #define DP_AUX_HDCP_BCAPS             0x68028
+ # define DP_BCAPS_REPEATER_PRESENT    BIT(1)
+ # define DP_BCAPS_HDCP_CAPABLE                BIT(0)
+ #define DP_AUX_HDCP_BSTATUS           0x68029
+ # define DP_BSTATUS_REAUTH_REQ                BIT(3)
+ # define DP_BSTATUS_LINK_FAILURE      BIT(2)
+ # define DP_BSTATUS_R0_PRIME_READY    BIT(1)
+ # define DP_BSTATUS_READY             BIT(0)
+ #define DP_AUX_HDCP_BINFO             0x6802A
+ #define DP_AUX_HDCP_KSV_FIFO          0x6802C
+ #define DP_AUX_HDCP_AINFO             0x6803B
  /* DP 1.2 Sideband message defines */
  /* peer device type - DP 1.2a Table 2-92 */
  #define DP_PEER_DEVICE_NONE           0x0
@@@ -974,20 -987,6 +991,20 @@@ drm_dp_tps3_supported(const u8 dpcd[DP_
                dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED;
  }
  
 +static inline bool
 +drm_dp_tps4_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 +{
 +      return dpcd[DP_DPCD_REV] >= 0x14 &&
 +              dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED;
 +}
 +
 +static inline u8
 +drm_dp_training_pattern_mask(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 +{
 +      return (dpcd[DP_DPCD_REV] >= 0x14) ? DP_TRAINING_PATTERN_MASK_1_4 :
 +              DP_TRAINING_PATTERN_MASK;
 +}
 +
  static inline bool
  drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
  {
index eb9b68c7c21852f54317c6ba4d6dc6a6504502c1,d1a69ff24fe849252f9b04918f900f430948eed5..2c575794fb5275fc294fa05aacd6fc7c32a5ccac
@@@ -38,18 -38,14 +38,18 @@@ extern "C" 
  #define DRM_DISPLAY_MODE_LEN  32
  #define DRM_PROP_NAME_LEN     32
  
 -#define DRM_MODE_TYPE_BUILTIN (1<<0)
 -#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
 -#define DRM_MODE_TYPE_CRTC_C  ((1<<2) | DRM_MODE_TYPE_BUILTIN)
 +#define DRM_MODE_TYPE_BUILTIN (1<<0) /* deprecated */
 +#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
 +#define DRM_MODE_TYPE_CRTC_C  ((1<<2) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
  #define DRM_MODE_TYPE_PREFERRED       (1<<3)
 -#define DRM_MODE_TYPE_DEFAULT (1<<4)
 +#define DRM_MODE_TYPE_DEFAULT (1<<4) /* deprecated */
  #define DRM_MODE_TYPE_USERDEF (1<<5)
  #define DRM_MODE_TYPE_DRIVER  (1<<6)
  
 +#define DRM_MODE_TYPE_ALL     (DRM_MODE_TYPE_PREFERRED |      \
 +                               DRM_MODE_TYPE_USERDEF |        \
 +                               DRM_MODE_TYPE_DRIVER)
 +
  /* Video mode flags */
  /* bit compatible with the xrandr RR_ definitions (bits 0-13)
   *
@@@ -70,8 -66,8 +70,8 @@@
  #define DRM_MODE_FLAG_PCSYNC                  (1<<7)
  #define DRM_MODE_FLAG_NCSYNC                  (1<<8)
  #define DRM_MODE_FLAG_HSKEW                   (1<<9) /* hskew provided */
 -#define DRM_MODE_FLAG_BCAST                   (1<<10)
 -#define DRM_MODE_FLAG_PIXMUX                  (1<<11)
 +#define DRM_MODE_FLAG_BCAST                   (1<<10) /* deprecated */
 +#define DRM_MODE_FLAG_PIXMUX                  (1<<11) /* deprecated */
  #define DRM_MODE_FLAG_DBLCLK                  (1<<12)
  #define DRM_MODE_FLAG_CLKDIV2                 (1<<13)
   /*
  #define  DRM_MODE_FLAG_PIC_AR_16_9 \
                        (DRM_MODE_PICTURE_ASPECT_16_9<<19)
  
 +#define  DRM_MODE_FLAG_ALL    (DRM_MODE_FLAG_PHSYNC |         \
 +                               DRM_MODE_FLAG_NHSYNC |         \
 +                               DRM_MODE_FLAG_PVSYNC |         \
 +                               DRM_MODE_FLAG_NVSYNC |         \
 +                               DRM_MODE_FLAG_INTERLACE |      \
 +                               DRM_MODE_FLAG_DBLSCAN |        \
 +                               DRM_MODE_FLAG_CSYNC |          \
 +                               DRM_MODE_FLAG_PCSYNC |         \
 +                               DRM_MODE_FLAG_NCSYNC |         \
 +                               DRM_MODE_FLAG_HSKEW |          \
 +                               DRM_MODE_FLAG_DBLCLK |         \
 +                               DRM_MODE_FLAG_CLKDIV2 |        \
 +                               DRM_MODE_FLAG_3D_MASK)
 +
  /* DPMS flags */
  /* bit compatible with the xorg definitions. */
  #define DRM_MODE_DPMS_ON      0
                DRM_MODE_REFLECT_X | \
                DRM_MODE_REFLECT_Y)
  
+ /* Content Protection Flags */
+ #define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0
+ #define DRM_MODE_CONTENT_PROTECTION_DESIRED     1
+ #define DRM_MODE_CONTENT_PROTECTION_ENABLED     2
  
  struct drm_mode_modeinfo {
        __u32 clock;