[Intel-gfx] [PATCH 1/4] drm/i915: Extending HDCP for HSW, BDW and BXT+
Ramalingam C
ramalingam.c at intel.com
Thu Jan 18 05:48:05 UTC 2018
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 at intel.com>
---
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
More information about the Intel-gfx
mailing list