Message ID | 1548917996-28081-6-git-send-email-ramalingam.c@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: Implement HDCP2.2 | expand |
>-----Original Message----- >From: C, Ramalingam >Sent: Thursday, January 31, 2019 12:29 PM >To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org; >daniel.vetter@ffwll.ch; Winkler, Tomas <tomas.winkler@intel.com>; Shankar, >Uma <uma.shankar@intel.com> >Cc: C, Ramalingam <ramalingam.c@intel.com> >Subject: [PATCH v10 05/40] 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. > >Signed-off-by: Ramalingam C <ramalingam.c@intel.com> >Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Looks ok to me. Reviewed-by: Uma Shankar <uma.shankar@intel.com> >--- > drivers/gpu/drm/i915/intel_dp.c | 3 ++- > drivers/gpu/drm/i915/intel_drv.h | 15 ++++++++++++++- >drivers/gpu/drm/i915/intel_hdcp.c | 33 ++++++++++++++++++++++++++++++--- >drivers/gpu/drm/i915/intel_hdmi.c | 8 ++++---- > 4 files changed, 50 insertions(+), 9 deletions(-) > >diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c >index 681e88405ada..815ee68efa2f 100644 >--- a/drivers/gpu/drm/i915/intel_dp.c >+++ b/drivers/gpu/drm/i915/intel_dp.c >@@ -6950,7 +6950,8 @@ intel_dp_init_connector(struct intel_digital_port >*intel_dig_port, > 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); >+ int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim, >+ false); > 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 90ba5436370e..0ac870feb5e9 100644 >--- a/drivers/gpu/drm/i915/intel_drv.h >+++ b/drivers/gpu/drm/i915/intel_drv.h >@@ -394,6 +394,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 { >@@ -2053,12 +2064,14 @@ 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); >+ const struct intel_hdcp_shim *hdcp_shim, >+ bool hdcp2_supported); > int intel_hdcp_enable(struct intel_connector *connector); int >intel_hdcp_disable(struct intel_connector *connector); int >intel_hdcp_check_link(struct intel_connector *connector); bool >is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port); bool >intel_hdcp_capable(struct intel_connector *connector); >+bool is_hdcp2_supported(struct drm_i915_private *dev_priv); > > /* 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 8cb85b07cfde..1a85dc46692d 100644 >--- a/drivers/gpu/drm/i915/intel_hdcp.c >+++ b/drivers/gpu/drm/i915/intel_hdcp.c >@@ -832,14 +832,37 @@ bool is_hdcp_supported(struct drm_i915_private >*dev_priv, enum port port) > return INTEL_GEN(dev_priv) >= 9 && port < PORT_E; } > >+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 drm_i915_private *dev_priv = to_i915(connector->base.dev); >+ struct intel_hdcp *hdcp = &connector->hdcp; >+ >+ WARN_ON(!is_hdcp2_supported(dev_priv)); >+ >+ /* 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) >+ const struct intel_hdcp_shim *shim, >+ bool hdcp2_supported) > { > 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 +870,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 (hdcp2_supported) >+ 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 97a98e1bea56..ab376a31cdab 100644 >--- a/drivers/gpu/drm/i915/intel_hdmi.c >+++ b/drivers/gpu/drm/i915/intel_hdmi.c >@@ -2427,16 +2427,16 @@ 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); >+ &intel_hdmi_hdcp_shim, false); > if (ret) > 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. >-- >2.7.4
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 681e88405ada..815ee68efa2f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6950,7 +6950,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, 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); + int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim, + false); 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 90ba5436370e..0ac870feb5e9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -394,6 +394,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 { @@ -2053,12 +2064,14 @@ 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); + const struct intel_hdcp_shim *hdcp_shim, + bool hdcp2_supported); int intel_hdcp_enable(struct intel_connector *connector); int intel_hdcp_disable(struct intel_connector *connector); int intel_hdcp_check_link(struct intel_connector *connector); bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port); bool intel_hdcp_capable(struct intel_connector *connector); +bool is_hdcp2_supported(struct drm_i915_private *dev_priv); /* 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 8cb85b07cfde..1a85dc46692d 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -832,14 +832,37 @@ bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port) return INTEL_GEN(dev_priv) >= 9 && port < PORT_E; } +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 drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_hdcp *hdcp = &connector->hdcp; + + WARN_ON(!is_hdcp2_supported(dev_priv)); + + /* 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) + const struct intel_hdcp_shim *shim, + bool hdcp2_supported) { 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 +870,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 (hdcp2_supported) + 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 97a98e1bea56..ab376a31cdab 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2427,16 +2427,16 @@ 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); + &intel_hdmi_hdcp_shim, false); if (ret) 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.