All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ramalingam C <ramalingam.c@intel.com>
To: intel-gfx@lists.freedesktop.org, daniel@ffwll.ch,
	tomas.winkler@intel.com, alexander.usyskin@intel.com
Subject: [RFC 3/3] drm/i915: Initialize HDCP2.2 and its MEI interface
Date: Wed, 11 Jul 2018 19:41:28 +0530	[thread overview]
Message-ID: <1531318288-23380-4-git-send-email-ramalingam.c@intel.com> (raw)
In-Reply-To: <1531318288-23380-1-git-send-email-ramalingam.c@intel.com>

Initialize HDCP2.2 support. This includes the mei interface
initialization along with required component registration.

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]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c   |  3 +-
 drivers/gpu/drm/i915/intel_drv.h  |  5 ++-
 drivers/gpu/drm/i915/intel_hdcp.c | 78 ++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_hdmi.c |  2 +-
 include/drm/i915_component.h      | 60 ++++++++++++++++++++++++++++++
 5 files changed, 144 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5be07e1d816d..12eb5bd33b7e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -6406,7 +6406,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 5799788c8f5d..c8b363772958 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1963,11 +1963,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);
+int intel_hdcp_component_init(struct drm_i915_private *dev_priv);
+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 65bbe5874eee..39fece04bbee 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -8,13 +8,19 @@
 
 #include <drm/drmP.h>
 #include <drm/drm_hdcp.h>
+#include <drm/i915_component.h>
 #include <linux/i2c.h>
 #include <linux/random.h>
+#include <linux/component.h>
 
 #include "intel_drv.h"
 #include "i915_reg.h"
 
 #define KEY_LOAD_TRIES	5
+#define GET_MEI_DDI_INDEX(port)		(((port) == PORT_A) ? DDI_A : \
+					 (enum hdcp_physical_port)(port))
+
+static int intel_hdcp2_init(struct intel_connector *connector);
 
 static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,
 				    const struct intel_hdcp_shim *shim)
@@ -743,11 +749,15 @@ bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
 }
 
 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)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret;
 
+	if (!hdcp_shim)
+		return -EINVAL;
+
 	ret = drm_connector_attach_content_protection_property(
 			&connector->base);
 	if (ret)
@@ -757,6 +767,10 @@ int intel_hdcp_init(struct intel_connector *connector,
 	mutex_init(&hdcp->hdcp_mutex);
 	INIT_DELAYED_WORK(&hdcp->hdcp_check_work, intel_hdcp_check_work);
 	INIT_WORK(&hdcp->hdcp_prop_work, intel_hdcp_prop_work);
+
+	if (hdcp2_supported)
+		intel_hdcp2_init(connector);
+
 	return 0;
 }
 
@@ -896,3 +910,65 @@ int intel_hdcp_check_link(struct intel_connector *connector)
 	mutex_unlock(&hdcp->hdcp_mutex);
 	return ret;
 }
+
+
+static int i915_hdcp_component_match(struct device *dev, void *data)
+{
+	return !strcmp(dev->driver->name, "mei_hdcp");
+}
+
+static int initialize_mei_hdcp_data(struct intel_connector *connector)
+{
+	struct intel_hdcp *hdcp = &connector->hdcp;
+	struct mei_hdcp_data *data = &hdcp->mei_data;
+	enum port port;
+
+	if (connector->encoder) {
+		port = connector->encoder->port;
+		data->port = GET_MEI_DDI_INDEX(port);
+	}
+
+	data->port_type = INTEGRATED;
+	data->protocol = hdcp->hdcp_shim->hdcp_protocol();
+
+	data->k = 1;
+	if (!data->streams)
+		data->streams = kcalloc(data->k,
+					sizeof(struct hdcp2_streamid_type),
+					GFP_KERNEL);
+	if (!data->streams) {
+		DRM_ERROR("Out of Memory\n");
+		return -ENOMEM;
+	}
+
+	data->streams[0].stream_id = 0;
+	data->streams[0].stream_type = hdcp->content_type;
+
+	return 0;
+}
+
+bool is_hdcp2_supported(struct drm_i915_private *dev_priv)
+{
+	return ((INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
+		IS_KABYLAKE(dev_priv)) && IS_ENABLED(CONFIG_INTEL_MEI_HDCP));
+}
+
+static int intel_hdcp2_init(struct intel_connector *connector)
+{
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_hdcp *hdcp = &connector->hdcp;
+	int ret;
+
+	WARN_ON(!is_hdcp2_supported(dev_priv));
+	ret = initialize_mei_hdcp_data(connector);
+	if (ret)
+		goto exit;
+
+	component_match_add(dev_priv->drm.dev, &dev_priv->master_match,
+			    i915_hdcp_component_match, dev_priv);
+
+	hdcp->hdcp2_supported = true;
+
+exit:
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 8363fbd18ee8..7988f958d835 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2366,7 +2366,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 
 	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");
 	}
diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index 52313bc227b2..f208a83ea2c9 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -24,6 +24,10 @@
 #ifndef _I915_COMPONENT_H_
 #define _I915_COMPONENT_H_
 
+#include <linux/mei_cl_bus.h>
+#include <linux/mei_hdcp.h>
+#include <drm/drm_hdcp.h>
+
 /* MAX_PORT is the number of port
  * It must be sync with I915_MAX_PORTS defined i915_drv.h
  */
@@ -121,6 +125,54 @@ struct i915_audio_component {
 	const struct i915_audio_component_audio_ops *audio_ops;
 };
 
+struct i915_hdcp_component_ops {
+	/**
+	 * @owner: mei_hdcp module
+	 */
+	struct module *owner;
+	int (*initiate_hdcp2_session)(struct mei_cl_device *cldev,
+				      struct mei_hdcp_data *data,
+				      struct hdcp2_ake_init *ake_data);
+	int
+	(*verify_receiver_cert_prepare_km)(struct mei_cl_device *cldev,
+					   struct mei_hdcp_data *data,
+					   struct hdcp2_ake_send_cert *rx_cert,
+					   bool *km_stored,
+					   struct hdcp2_ake_no_stored_km
+								*ek_pub_km,
+					   size_t *msg_sz);
+	int (*verify_hprime)(struct mei_cl_device *cldev,
+			     struct mei_hdcp_data *data,
+			     struct hdcp2_ake_send_hprime *rx_hprime);
+	int (*store_pairing_info)(struct mei_cl_device *cldev,
+				  struct mei_hdcp_data *data,
+				  struct hdcp2_ake_send_pairing_info
+								*pairing_info);
+	int (*initiate_locality_check)(struct mei_cl_device *cldev,
+				       struct mei_hdcp_data *data,
+				       struct hdcp2_lc_init *lc_init_data);
+	int (*verify_lprime)(struct mei_cl_device *cldev,
+			     struct mei_hdcp_data *data,
+			     struct hdcp2_lc_send_lprime *rx_lprime);
+	int (*get_session_key)(struct mei_cl_device *cldev,
+			       struct mei_hdcp_data *data,
+			       struct hdcp2_ske_send_eks *ske_data);
+	int
+	(*repeater_check_flow_prepare_ack)(struct mei_cl_device *cldev,
+					   struct mei_hdcp_data *data,
+					   struct hdcp2_rep_send_receiverid_list
+								*rep_topology,
+					   struct hdcp2_rep_send_ack
+								*rep_send_ack);
+	int (*verify_mprime)(struct mei_cl_device *cldev,
+			     struct mei_hdcp_data *data,
+			     struct hdcp2_rep_stream_ready *stream_ready);
+	int (*enable_hdcp_authentication)(struct mei_cl_device *cldev,
+					  struct mei_hdcp_data *data);
+	int (*close_hdcp_session)(struct mei_cl_device *cldev,
+				  struct mei_hdcp_data *data);
+};
+
 /**
  * struct i915_component_master - Used for communication between i915
  * and any other drivers for the services of different feature.
@@ -131,6 +183,14 @@ struct i915_component_master {
 	 * removing the reference to mei_cldev.
 	 */
 	struct device *i915_kdev;
+	/**
+	 * @mei_cldev: mei client device, used as parameter for ops
+	 */
+	struct mei_cl_device *mei_cldev;
+	/**
+	 * @ops: Ops implemented by mei_hdcp driver, used by i915 driver.
+	 */
+	const struct i915_hdcp_component_ops *hdcp_ops;
 
 	/*
 	 * Add here the interface details between I915 and interested modules.
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2018-07-11 14:11 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-11 14:11 [RFC 0/3] I915 component master Ramalingam C
2018-07-11 14:11 ` [RFC 1/3] component: alloc component_match without any comp to match Ramalingam C
2018-07-12  8:21   ` Daniel Vetter
2018-07-12  8:53     ` Ramalingam C
2018-07-11 14:11 ` [RFC 2/3] drm/i915: component master at i915 driver load Ramalingam C
2018-07-12  8:26   ` Daniel Vetter
2018-07-12  9:00     ` Ramalingam C
2018-07-11 14:11 ` Ramalingam C [this message]
2018-07-11 14:21 ` ✗ Fi.CI.BAT: failure for I915 component master Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1531318288-23380-4-git-send-email-ramalingam.c@intel.com \
    --to=ramalingam.c@intel.com \
    --cc=alexander.usyskin@intel.com \
    --cc=daniel@ffwll.ch \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=tomas.winkler@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.