On Tue, Dec 05, 2017 at 12:15:07AM -0500, Sean Paul wrote:
> This patch adds HDCP support for HDMI connectors by implementing
> the intel_hdcp_shim.
>
> Nothing too special, just a bunch of DDC reads/writes.
>
> Changes in v2:
> - Rebased on drm-intel-next
> Changes in v3:
> - Initialize new worker
>
> Signed-off-by: Sean Paul
> ---
> drivers/gpu/drm/i915/i915_reg.h | 1 +
> drivers/gpu/drm/i915/intel_ddi.c | 50
> drivers/gpu/drm/i915/intel_drv.h | 2 +
> drivers/gpu/drm/i915/intel_hdmi.c | 257
> ++
> 4 files changed, 310 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 107e16392710..79944ab4218a 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8450,6 +8450,7 @@ enum skl_power_gate {
> #define TRANS_DDI_EDP_INPUT_A_ONOFF (4<<12)
> #define TRANS_DDI_EDP_INPUT_B_ONOFF (5<<12)
> #define TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12)
> +#define TRANS_DDI_HDCP_SIGNALLING (1<<9)
> #define TRANS_DDI_DP_VC_PAYLOAD_ALLOC (1<<8)
> #define TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE (1<<7)
> #define TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ (1<<6)
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index eff3b51872eb..a179fd9968a5 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1615,6 +1615,56 @@ void intel_ddi_disable_transcoder_func(struct
> drm_i915_private *dev_priv,
> I915_WRITE(reg, val);
> }
>
> +int intel_ddi_disable_hdcp_signalling(struct intel_encoder *intel_encoder)
> +{
> + struct drm_device *dev = intel_encoder->base.dev;
> + struct drm_i915_private *dev_priv = to_i915(dev);
> + enum pipe pipe = 0;
> + int ret = 0;
> + uint32_t tmp;
> +
> + if (!intel_display_power_get_if_enabled(dev_priv,
> + intel_encoder->power_domain))
> + return -ENXIO;
> +
> + if (!intel_encoder->get_hw_state(intel_encoder, )) {
> + ret = -EIO;
> + goto out;
> + }
Hm, do we really need these checks here? With the new worker design I
think they'd indicate a synchronization bug (misplaced
cancel_delayed_work_sync probably).
If you want to keep them for safetey please wrap in a WARN_ON. Same for
the one below.
Otherwise looks all good to me.
> +
> + tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
> + tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
> + I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
> +out:
> + intel_display_power_put(dev_priv, intel_encoder->power_domain);
> + return ret;
> +}
> +
> +int intel_ddi_enable_hdcp_signalling(struct intel_encoder *intel_encoder)
> +{
> + struct drm_device *dev = intel_encoder->base.dev;
> + struct drm_i915_private *dev_priv = to_i915(dev);
> + enum pipe pipe = 0;
> + int ret = 0;
> + uint32_t tmp;
> +
> + if (!intel_display_power_get_if_enabled(dev_priv,
> + intel_encoder->power_domain))
> + return -ENXIO;
> +
> + if (!intel_encoder->get_hw_state(intel_encoder, )) {
> + ret = -EIO;
> + goto out;
> + }
> +
> + tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
> + tmp |= TRANS_DDI_HDCP_SIGNALLING;
> + I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
> +out:
> + intel_display_power_put(dev_priv, intel_encoder->power_domain);
> + return ret;
> +}
> +
> bool intel_ddi_connector_get_hw_state(struct intel_connector
> *intel_connector)
> {
> struct drm_device *dev = intel_connector->base.dev;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 6f47a4227f5f..0b4405f3e988 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1379,6 +1379,8 @@ void intel_ddi_compute_min_voltage_level(struct
> drm_i915_private *dev_priv,
> u32 bxt_signal_levels(struct intel_dp *intel_dp);
> uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
> u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
> +int intel_ddi_enable_hdcp_signalling(struct intel_encoder *intel_encoder);
> +int intel_ddi_disable_hdcp_signalling(struct intel_encoder *intel_encoder);
>
> unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
> int plane, unsigned int height);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> b/drivers/gpu/drm/i915/intel_hdmi.c
> index 9d5e72728475..17a525b9fcf9 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -34,6 +34,7 @@
> #include
> #include
> #include
> +#include
> #include
> #include "intel_drv.h"
> #include
> @@ -873,6 +874,252 @@ void intel_dp_dual_mode_set_tmds_output(struct
> intel_hdmi *hdmi, bool enable)
>adapter, enable);
> }
>
> +static int