From: Ramalingam C Date: Sat, 16 Feb 2019 17:36:50 +0000 (+0530) Subject: drm/i915: Initialize HDCP2.2 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=04707f97163637e21a8f3db103252bd7e26b214c;p=openwrt%2Fstaging%2Fblogic.git drm/i915: Initialize HDCP2.2 Add the HDCP2.2 initialization to the existing HDCP1.4 stack. v2: mei interface handle is protected with mutex. [Chris Wilson] v3: Notifiers are used for the mei interface state. v4: Poll for mei client device state Error msg for out of mem [Uma] Inline req for init function removed [Uma] v5: Rebase as Part of reordering. Component is used for the I915 and MEI_HDCP interface [Daniel] v6: HDCP2.2 uses the I915 component master to communicate with mei_hdcp - [Daniel] Required HDCP2.2 variables defined [Sean Paul] v7: intel_hdcp2.2_init returns void [Uma] Realigning the codes. v8: Avoid using bool structure members. MEI interface related changes are moved into separate patch. Commit msg is updated accordingly. intel_hdcp_exit is defined and used from i915_unload v9: Movement of the hdcp_check_link is moved to new patch [Daniel] intel_hdcp2_exit is removed as mei_comp will be unbind in i915_unload. v10: bool is used in struct to make coding simpler. [Daniel] hdmi hdcp init is placed correctly after encoder attachment. v11: hdcp2_capability check is moved into hdcp.c [Tomas] Signed-off-by: Ramalingam C Reviewed-by: Daniel Vetter Reviewed-by: Uma Shankar Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1550338640-17470-4-git-send-email-ramalingam.c@intel.com --- diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index eec4ed93c335..56918161435d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -404,6 +404,17 @@ struct intel_hdcp { u64 value; struct delayed_work check_work; struct work_struct prop_work; + + /* HDCP2.2 related definitions */ + /* Flag indicates whether this connector supports HDCP2.2 or not. */ + bool hdcp2_supported; + + /* + * Content Stream Type defined by content owner. TYPE0(0x0) content can + * flow in the link protected by HDCP2.2 or HDCP1.4, where as TYPE1(0x1) + * content can flow only through a link protected by HDCP2.2. + */ + u8 content_type; }; struct intel_connector { diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 8cb85b07cfde..7b1097d79fb8 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -832,14 +832,34 @@ bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port) return INTEL_GEN(dev_priv) >= 9 && port < PORT_E; } +static bool is_hdcp2_supported(struct drm_i915_private *dev_priv) +{ + if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP)) + return false; + + return (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) || + IS_KABYLAKE(dev_priv)); +} + +static void intel_hdcp2_init(struct intel_connector *connector) +{ + struct intel_hdcp *hdcp = &connector->hdcp; + + /* TODO: MEI interface needs to be initialized here */ + hdcp->hdcp2_supported = true; +} + int intel_hdcp_init(struct intel_connector *connector, const struct intel_hdcp_shim *shim) { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; int ret; - ret = drm_connector_attach_content_protection_property( - &connector->base); + if (!shim) + return -EINVAL; + + ret = drm_connector_attach_content_protection_property(&connector->base); if (ret) return ret; @@ -847,6 +867,10 @@ int intel_hdcp_init(struct intel_connector *connector, mutex_init(&hdcp->mutex); INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work); INIT_WORK(&hdcp->prop_work, intel_hdcp_prop_work); + + if (is_hdcp2_supported(dev_priv)) + intel_hdcp2_init(connector); + return 0; } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f125a62eba8c..faeedf76db99 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2427,6 +2427,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi_add_properties(intel_hdmi, connector); + intel_connector_attach_encoder(intel_connector, intel_encoder); + intel_hdmi->attached_connector = intel_connector; + if (is_hdcp_supported(dev_priv, port)) { int ret = intel_hdcp_init(intel_connector, &intel_hdmi_hdcp_shim); @@ -2434,9 +2437,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, DRM_DEBUG_KMS("HDCP init failed, skipping.\n"); } - intel_connector_attach_encoder(intel_connector, intel_encoder); - intel_hdmi->attached_connector = intel_connector; - /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being * generated on the port when a cable is not attached.