This patch extends the Key load process and hdcp initialization for few more capable intel platforms i.e. HSW, BDW and BXT+. Signed-off-by: Ramalingam C <ramalingam.c@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_hdcp.c | 42 ++++++++++++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_hdmi.c | 3 +-- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c0a4fc356145..7b54041a62f4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8357,6 +8357,7 @@ enum skl_power_gate { #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) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 68229f53d5b8..fb2e339405b5 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6352,7 +6352,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, intel_dp_add_properties(intel_dp, connector); - if (INTEL_GEN(dev_priv) >= 9 && !intel_dp_is_edp(intel_dp)) { + 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"); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5c8e260ca2bc..2de02f50e5fd 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1848,6 +1848,7 @@ int intel_hdcp_init(struct intel_connector *connector, 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) diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 827cab22f191..6ce6559897a6 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -49,13 +49,32 @@ static int intel_hdcp_load_keys(struct drm_i915_private *dev_priv) int ret; u32 val; - /* Initiate loading the HDCP key from fuses */ - mutex_lock(&dev_priv->pcu_lock); - ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_LOAD_HDCP_KEYS, 1); - mutex_unlock(&dev_priv->pcu_lock); - if (ret) { - DRM_ERROR("Failed to initiate HDCP key load (%d)\n", ret); - return ret; + /* + * On HSW and BDW HW loads the HDCP1.4 Key when Display comes + * out of reset. So if Key is not already loaded, its an error state. + */ + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + if (!(I915_READ(HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE)) + return -ENXIO; + + /* + * Initiate loading the HDCP key from fuses. + * + * BXT+ platforms, HDCP key needs to be loaded by SW. Only SKL and KBL + * differ in the key load trigger process from other platforms. + */ + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { + mutex_lock(&dev_priv->pcu_lock); + ret = sandybridge_pcode_write(dev_priv, + SKL_PCODE_LOAD_HDCP_KEYS, 1); + mutex_unlock(&dev_priv->pcu_lock); + if (ret) { + DRM_ERROR("Failed to initiate HDCP key load (%d)\n", + ret); + return ret; + } + } else { + I915_WRITE(HDCP_KEY_CONF, HDCP_KEY_LOAD_TRIGGER); } /* Wait for the keys to load (500us) */ @@ -575,6 +594,15 @@ static void intel_hdcp_prop_work(struct work_struct *work) drm_modeset_unlock(&dev->mode_config.connection_mutex); } +bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port) +{ + + /* PORT E doesn't have HDCP, and PORT F is disabled */ + return ((INTEL_GEN(dev_priv) >= 8 || IS_HASWELL(dev_priv)) && + !IS_CHERRYVIEW(dev_priv) && + port < PORT_E); +} + int intel_hdcp_init(struct intel_connector *connector, const struct intel_hdcp_shim *hdcp_shim) { diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 691f15b59124..5de1f966c926 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2304,8 +2304,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi_add_properties(intel_hdmi, connector); - /* PORT E doesn't have HDCP, and PORT F is disabled */ - if (INTEL_GEN(dev_priv) >= 9 && port < PORT_E) { + if (is_hdcp_supported(dev_priv, port)) { int ret = intel_hdcp_init(intel_connector, &intel_hdmi_hdcp_shim); if (ret) -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx