Message ID | 1549487071-15343-8-git-send-email-ramalingam.c@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: Implement HDCP2.2 | expand |
> 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 <ramalingam.c@intel.com> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> > Reviewed-by: Uma Shankar <uma.shankar@intel.com> > --- > drivers/gpu/drm/i915/intel_drv.h | 11 +++++++++++ > drivers/gpu/drm/i915/intel_hdcp.c | 28 ++++++++++++++++++++++++++-- > drivers/gpu/drm/i915/intel_hdmi.c | 6 +++--- > 3 files changed, 40 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_drv.h > b/drivers/gpu/drm/i915/intel_drv.h > index 90ba5436370e..030d962697dd 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 { > 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; Is this enough, you can have SKU where this is not enabled, and you can detect that only during runtime. > + > + 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); Won't this depend on the driver load order? Thanks Tomas
On 2/7/2019 8:43 PM, Winkler, Tomas wrote: >> 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 <ramalingam.c@intel.com> >> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> >> Reviewed-by: Uma Shankar <uma.shankar@intel.com> >> --- >> drivers/gpu/drm/i915/intel_drv.h | 11 +++++++++++ >> drivers/gpu/drm/i915/intel_hdcp.c | 28 ++++++++++++++++++++++++++-- >> drivers/gpu/drm/i915/intel_hdmi.c | 6 +++--- >> 3 files changed, 40 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/intel_drv.h >> b/drivers/gpu/drm/i915/intel_drv.h >> index 90ba5436370e..030d962697dd 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 { >> 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; > Is this enough, you can have SKU where this is not enabled, and you can detect that only during runtime. Best approach will be failing the HDCP2.2 support for such SKUs. But at present I am not aware of any. If there is any we can always add here. In the absence of the details about SKU with no HDCP support, even though init will assume the HDCP2.2 support based on the MEI_HDCP config variable, mei_dev with UUID wont be available hence driver-device bind wont occur hence I915-MEI interface will never be complete and/or HDCP2_CMDs passed from mei_hdcp to MEI_FW will fail. Hence HDCP2.2 will not attempted/succeed from I915. Basically nothing will blow up here. >> + >> + 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); > Won't this depend on the driver load order? With Component usage for this interface, this interface can go down and come up any point in time. Its handled with appropriate locks. Irrespective of the load order between i915 and mei_hdcp, when both drivers are up only then interface will be complete between them. -Ram > Thanks > Tomas >
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 90ba5436370e..030d962697dd 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 { 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.