* [PATCH v14 00/33] drm/i915: Implement HDCP2.2
@ 2019-02-16 17:36 Ramalingam C
2019-02-16 17:36 ` [PATCH v14 01/33] drm/i915: Gathering the HDCP1.4 routines together Ramalingam C
` (36 more replies)
0 siblings, 37 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
This series enables the HDCP2.2 Type 0 for I915. The sequence for
HDCP2.2 authentication and encryption is implemented as a generic flow
between HDMI and DP. Encoder specific implementations are moved
into hdcp_shim.
Intel HWs supports HDCP2.2 through ME FW. Hence this series
introduces a client driver for mei bus, so that for HDCP2.2
authentication, HDCP2.2 stack in I915 can avail the services from
ME FW. To enable this client driver set the config variable
CONFIG_INTEL_MEI_HDCP.
Userspace interface remains unchanged as version agnostic. When
userspace request for HDCP enable, Kernel will detect the HDCP source
and sink's HDCP version(1.4/2.2)capability and enable the best capable
version for that combination.
This series enables the HDCP2.2 for Type0 content streams.
Test-with: <1549566452-30175-1-git-send-email-ramalingam.c@intel.com>
So that CP will be tested on BAT machine too.
Not incrementing the series version from 14 to 15 as the delta is just a
addition of minor patch.
Major changes in v14
- enum port is moved into the drm/i915_drm.h
- Small fixes for mei_hdcp Kernel-Doc
- ICL device ID patch is already merged. So dropped it.
- Couple of patches are merged already. So dropped them.
- New patch for declaration of strict device in drm/audio header.
To ease the review process, series is hosted at
https://github.com/ramalingampc2008/drm-tip.git hdcp2_2_v14_rebased
Ramalingam C (31):
drm/i915: Gathering the HDCP1.4 routines together
drm/audio: declaration of struct device
drm/i915: Initialize HDCP2.2
drm/i915: MEI interface implementation
drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking
drm/i915: Enable and Disable of HDCP2.2
drm/i915: Implement HDCP2.2 receiver authentication
drm/i915: Implement HDCP2.2 repeater authentication
drm: HDCP2.2 link check period
drm/i915: Implement HDCP2.2 link integrity check
drm/i915: Handle HDCP2.2 downstream topology change
drm: removing the DP Errata msg and its msg id
drm/i915: Implement the HDCP2.2 support for DP
drm/i915: Implement the HDCP2.2 support for HDMI
drm/i915: CP_IRQ handling for DP HDCP2.2 msgs
drm/i915: Fix KBL HDCP2.2 encrypt status signalling
misc/mei/hdcp: Client driver for HDCP application
misc/mei/hdcp: Define ME FW interface for HDCP2.2
misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session
misc/mei/hdcp: Verify Receiver Cert and prepare km
misc/mei/hdcp: Verify H_prime
misc/mei/hdcp: Store the HDCP Pairing info
misc/mei/hdcp: Initiate Locality check
misc/mei/hdcp: Verify L_prime
misc/mei/hdcp: Prepare Session Key
misc/mei/hdcp: Repeater topology verification and ack
misc/mei/hdcp: Verify M_prime
misc/mei/hdcp: Enabling the HDCP authentication
misc/mei/hdcp: Closing wired HDCP2.2 Tx Session
misc/mei/hdcp: Component framework for I915 Interface
FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915
Tomas Winkler (2):
mei: bus: whitelist hdcp client
mei: bus: export to_mei_cl_device for mei client device drivers
drivers/gpu/drm/i915/i915_drv.c | 1 +
drivers/gpu/drm/i915/i915_drv.h | 7 +
drivers/gpu/drm/i915/intel_connector.c | 2 +
drivers/gpu/drm/i915/intel_display.c | 4 +
drivers/gpu/drm/i915/intel_dp.c | 350 ++++++++-
drivers/gpu/drm/i915/intel_drv.h | 83 ++-
drivers/gpu/drm/i915/intel_hdcp.c | 1242 +++++++++++++++++++++++++++++---
drivers/gpu/drm/i915/intel_hdmi.c | 237 +++++-
drivers/misc/mei/Kconfig | 8 +
drivers/misc/mei/Makefile | 2 +
drivers/misc/mei/bus-fixup.c | 16 +
drivers/misc/mei/bus.c | 1 -
drivers/misc/mei/hdcp/Makefile | 7 +
drivers/misc/mei/hdcp/mei_hdcp.c | 847 ++++++++++++++++++++++
drivers/misc/mei/hdcp/mei_hdcp.h | 377 ++++++++++
include/drm/drm_audio_component.h | 1 +
include/drm/drm_hdcp.h | 7 +-
include/linux/mei_cl_bus.h | 2 +
18 files changed, 3069 insertions(+), 125 deletions(-)
create mode 100644 drivers/misc/mei/hdcp/Makefile
create mode 100644 drivers/misc/mei/hdcp/mei_hdcp.c
create mode 100644 drivers/misc/mei/hdcp/mei_hdcp.h
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH v14 01/33] drm/i915: Gathering the HDCP1.4 routines together
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:36 ` [PATCH v14 02/33] drm/audio: declaration of struct device Ramalingam C
` (35 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
All HDCP1.4 routines are gathered together, followed by the generic
functions those can be extended for HDCP2.2 too.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/gpu/drm/i915/intel_hdcp.c | 118 +++++++++++++++++++-------------------
1 file changed, 59 insertions(+), 59 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index ce7ba3a9c000..8cb85b07cfde 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -730,6 +730,65 @@ struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
return container_of(hdcp, struct intel_connector, hdcp);
}
+/* Implements Part 3 of the HDCP authorization procedure */
+int intel_hdcp_check_link(struct intel_connector *connector)
+{
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ struct drm_i915_private *dev_priv = connector->base.dev->dev_private;
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ enum port port = intel_dig_port->base.port;
+ int ret = 0;
+
+ if (!hdcp->shim)
+ return -ENOENT;
+
+ mutex_lock(&hdcp->mutex);
+
+ if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+ goto out;
+
+ if (!(I915_READ(PORT_HDCP_STATUS(port)) & HDCP_STATUS_ENC)) {
+ DRM_ERROR("%s:%d HDCP check failed: link is not encrypted,%x\n",
+ connector->base.name, connector->base.base.id,
+ I915_READ(PORT_HDCP_STATUS(port)));
+ ret = -ENXIO;
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdcp->prop_work);
+ goto out;
+ }
+
+ if (hdcp->shim->check_link(intel_dig_port)) {
+ if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+ schedule_work(&hdcp->prop_work);
+ }
+ goto out;
+ }
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP link failed, retrying authentication\n",
+ connector->base.name, connector->base.base.id);
+
+ ret = _intel_hdcp_disable(connector);
+ if (ret) {
+ DRM_ERROR("Failed to disable hdcp (%d)\n", ret);
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdcp->prop_work);
+ goto out;
+ }
+
+ ret = _intel_hdcp_enable(connector);
+ if (ret) {
+ DRM_ERROR("Failed to enable hdcp (%d)\n", ret);
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdcp->prop_work);
+ goto out;
+ }
+
+out:
+ mutex_unlock(&hdcp->mutex);
+ return ret;
+}
+
static void intel_hdcp_check_work(struct work_struct *work)
{
struct intel_hdcp *hdcp = container_of(to_delayed_work(work),
@@ -866,62 +925,3 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
new_state->crtc);
crtc_state->mode_changed = true;
}
-
-/* Implements Part 3 of the HDCP authorization procedure */
-int intel_hdcp_check_link(struct intel_connector *connector)
-{
- struct intel_hdcp *hdcp = &connector->hdcp;
- struct drm_i915_private *dev_priv = connector->base.dev->dev_private;
- struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
- enum port port = intel_dig_port->base.port;
- int ret = 0;
-
- if (!hdcp->shim)
- return -ENOENT;
-
- mutex_lock(&hdcp->mutex);
-
- if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
- goto out;
-
- if (!(I915_READ(PORT_HDCP_STATUS(port)) & HDCP_STATUS_ENC)) {
- DRM_ERROR("%s:%d HDCP check failed: link is not encrypted,%x\n",
- connector->base.name, connector->base.base.id,
- I915_READ(PORT_HDCP_STATUS(port)));
- ret = -ENXIO;
- hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
- schedule_work(&hdcp->prop_work);
- goto out;
- }
-
- if (hdcp->shim->check_link(intel_dig_port)) {
- if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
- hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
- schedule_work(&hdcp->prop_work);
- }
- goto out;
- }
-
- DRM_DEBUG_KMS("[%s:%d] HDCP link failed, retrying authentication\n",
- connector->base.name, connector->base.base.id);
-
- ret = _intel_hdcp_disable(connector);
- if (ret) {
- DRM_ERROR("Failed to disable hdcp (%d)\n", ret);
- hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
- schedule_work(&hdcp->prop_work);
- goto out;
- }
-
- ret = _intel_hdcp_enable(connector);
- if (ret) {
- DRM_DEBUG_KMS("Failed to enable hdcp (%d)\n", ret);
- hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
- schedule_work(&hdcp->prop_work);
- goto out;
- }
-
-out:
- mutex_unlock(&hdcp->mutex);
- return ret;
-}
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 02/33] drm/audio: declaration of struct device
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
2019-02-16 17:36 ` [PATCH v14 01/33] drm/i915: Gathering the HDCP1.4 routines together Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:36 ` [PATCH v14 03/33] drm/i915: Initialize HDCP2.2 Ramalingam C via dri-devel
` (34 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Header has used the references to struct device without it definition
or declaration. Hence resulting in compilation warning such as
"'struct device' declared inside parameter list..."
This changes adds a declaration to struct device in the header to avoid
any such warnings.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
include/drm/drm_audio_component.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/drm/drm_audio_component.h b/include/drm/drm_audio_component.h
index d0c7444319f5..a45f93487039 100644
--- a/include/drm/drm_audio_component.h
+++ b/include/drm/drm_audio_component.h
@@ -5,6 +5,7 @@
#define _DRM_AUDIO_COMPONENT_H_
struct drm_audio_component;
+struct device;
/**
* struct drm_audio_component_ops - Ops implemented by DRM driver, called by hda driver
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 03/33] drm/i915: Initialize HDCP2.2
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
2019-02-16 17:36 ` [PATCH v14 01/33] drm/i915: Gathering the HDCP1.4 routines together Ramalingam C
2019-02-16 17:36 ` [PATCH v14 02/33] drm/audio: declaration of struct device Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C via dri-devel
2019-02-16 17:36 ` [PATCH v14 04/33] drm/i915: MEI interface implementation Ramalingam C via dri-devel
` (33 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
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 <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 3398b28c053b..11c696025085 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.
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 04/33] drm/i915: MEI interface implementation
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (2 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 03/33] drm/i915: Initialize HDCP2.2 Ramalingam C via dri-devel
@ 2019-02-16 17:36 ` Ramalingam C via dri-devel
2019-02-20 19:39 ` Daniel Vetter
2019-02-16 17:36 ` [PATCH v14 05/33] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking Ramalingam C
` (32 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Defining the mei-i915 interface functions and initialization of
the interface.
v2:
Adjust to the new interface changes. [Tomas]
Added further debug logs for the failures at MEI i/f.
port in hdcp_port data is equipped to handle -ve values.
v3:
mei comp is matched for global i915 comp master. [Daniel]
In hdcp_shim hdcp_protocol() is replaced with const variable. [Daniel]
mei wrappers are adjusted as per the i/f change [Daniel]
v4:
port initialization is done only at hdcp2_init only [Danvet]
v5:
I915 registers a subcomponent to be matched with mei_hdcp [Daniel]
v6:
HDCP_disable for all connectors incase of comp_unbind.
Tear down HDCP comp interface at i915_unload [Daniel]
v7:
Component init and fini are moved out of connector ops [Daniel]
hdcp_disable is not called from unbind. [Daniel]
v8:
subcomponent name is dropped as it is already merged.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> [v11]
---
drivers/gpu/drm/i915/i915_drv.c | 1 +
drivers/gpu/drm/i915/i915_drv.h | 7 +
drivers/gpu/drm/i915/intel_connector.c | 2 +
drivers/gpu/drm/i915/intel_display.c | 4 +
drivers/gpu/drm/i915/intel_drv.h | 8 +
drivers/gpu/drm/i915/intel_hdcp.c | 398 ++++++++++++++++++++++++++++++++-
6 files changed, 419 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6630212f2faf..c6354f6cdbdb 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -906,6 +906,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv)
mutex_init(&dev_priv->av_mutex);
mutex_init(&dev_priv->wm.wm_mutex);
mutex_init(&dev_priv->pps_mutex);
+ mutex_init(&dev_priv->hdcp_comp_mutex);
i915_memcpy_init_early(dev_priv);
intel_runtime_pm_init_early(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5c8d0489a1cd..d375d1cf86f5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -55,6 +55,7 @@
#include <drm/drm_util.h>
#include <drm/drm_dsc.h>
#include <drm/drm_connector.h>
+#include <drm/i915_mei_hdcp_interface.h>
#include "i915_fixed.h"
#include "i915_params.h"
@@ -2052,6 +2053,12 @@ struct drm_i915_private {
struct i915_pmu pmu;
+ struct i915_hdcp_comp_master *hdcp_master;
+ bool hdcp_comp_added;
+
+ /* Mutex to protect the above hdcp component related values. */
+ struct mutex hdcp_comp_mutex;
+
/*
* NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
* will be rejected. Instead look for a better place.
diff --git a/drivers/gpu/drm/i915/intel_connector.c b/drivers/gpu/drm/i915/intel_connector.c
index ee16758747c5..66ed3ee5998a 100644
--- a/drivers/gpu/drm/i915/intel_connector.c
+++ b/drivers/gpu/drm/i915/intel_connector.c
@@ -88,6 +88,8 @@ void intel_connector_destroy(struct drm_connector *connector)
kfree(intel_connector->detect_edid);
+ intel_hdcp_cleanup(intel_connector);
+
if (!IS_ERR_OR_NULL(intel_connector->edid))
kfree(intel_connector->edid);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 73a107b6eb9a..acb993ce7eaa 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -15453,6 +15453,8 @@ int intel_modeset_init(struct drm_device *dev)
intel_update_czclk(dev_priv);
intel_modeset_init_hw(dev);
+ intel_hdcp_component_init(dev_priv);
+
if (dev_priv->max_cdclk_freq == 0)
intel_update_max_cdclk(dev_priv);
@@ -16314,6 +16316,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
/* flush any delayed tasks or pending work */
flush_scheduled_work();
+ intel_hdcp_component_fini(dev_priv);
+
drm_mode_config_cleanup(dev);
intel_overlay_cleanup(dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 11c696025085..f8e8482573c8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -41,6 +41,7 @@
#include <drm/drm_rect.h>
#include <drm/drm_vblank.h>
#include <drm/drm_atomic.h>
+#include <drm/i915_mei_hdcp_interface.h>
#include <media/cec-notifier.h>
struct drm_printer;
@@ -395,6 +396,9 @@ struct intel_hdcp_shim {
/* Detects panel's hdcp capability. This is optional for HDMI. */
int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
bool *hdcp_capable);
+
+ /* HDCP adaptation(DP/HDMI) required on the port */
+ enum hdcp_wired_protocol protocol;
};
struct intel_hdcp {
@@ -415,6 +419,7 @@ struct intel_hdcp {
* content can flow only through a link protected by HDCP2.2.
*/
u8 content_type;
+ struct hdcp_port_data port_data;
};
struct intel_connector {
@@ -2088,6 +2093,9 @@ 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);
+void intel_hdcp_component_init(struct drm_i915_private *dev_priv);
+void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
+void intel_hdcp_cleanup(struct intel_connector *connector);
/* 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 7b1097d79fb8..d06bef9d1ab2 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -7,8 +7,10 @@
*/
#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"
@@ -832,6 +834,347 @@ bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
return INTEL_GEN(dev_priv) >= 9 && port < PORT_E;
}
+static __attribute__((unused)) int
+hdcp2_prepare_ake_init(struct intel_connector *connector,
+ struct hdcp2_ake_init *ake_data)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->initiate_hdcp2_session(comp->mei_dev, data, ake_data);
+ if (ret)
+ DRM_DEBUG_KMS("Prepare_ake_init failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused)) int
+hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
+ struct hdcp2_ake_send_cert *rx_cert,
+ bool *paired,
+ struct hdcp2_ake_no_stored_km *ek_pub_km,
+ size_t *msg_sz)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->verify_receiver_cert_prepare_km(comp->mei_dev, data,
+ rx_cert, paired,
+ ek_pub_km, msg_sz);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Verify rx_cert failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused)) int
+hdcp2_verify_hprime(struct intel_connector *connector,
+ struct hdcp2_ake_send_hprime *rx_hprime)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->verify_hprime(comp->mei_dev, data, rx_hprime);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Verify hprime failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused)) int
+hdcp2_store_pairing_info(struct intel_connector *connector,
+ struct hdcp2_ake_send_pairing_info *pairing_info)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->store_pairing_info(comp->mei_dev, data, pairing_info);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Store pairing info failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused)) int
+hdcp2_prepare_lc_init(struct intel_connector *connector,
+ struct hdcp2_lc_init *lc_init)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->initiate_locality_check(comp->mei_dev, data, lc_init);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Prepare lc_init failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused)) int
+hdcp2_verify_lprime(struct intel_connector *connector,
+ struct hdcp2_lc_send_lprime *rx_lprime)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->verify_lprime(comp->mei_dev, data, rx_lprime);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Verify L_Prime failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused))
+int hdcp2_prepare_skey(struct intel_connector *connector,
+ struct hdcp2_ske_send_eks *ske_data)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->get_session_key(comp->mei_dev, data, ske_data);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Get session key failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused)) int
+hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
+ struct hdcp2_rep_send_receiverid_list
+ *rep_topology,
+ struct hdcp2_rep_send_ack *rep_send_ack)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->repeater_check_flow_prepare_ack(comp->mei_dev, data,
+ rep_topology,
+ rep_send_ack);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Verify rep topology failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused)) int
+hdcp2_verify_mprime(struct intel_connector *connector,
+ struct hdcp2_rep_stream_ready *stream_ready)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->verify_mprime(comp->mei_dev, data, stream_ready);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Verify mprime failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused))
+int hdcp2_authenticate_port(struct intel_connector *connector)
+{
+ struct hdcp_port_data *data = &connector->hdcp.port_data;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->enable_hdcp_authentication(comp->mei_dev, data);
+ if (ret < 0)
+ DRM_DEBUG_KMS("Enable hdcp auth failed. %d\n", ret);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused))
+int hdcp2_close_mei_session(struct intel_connector *connector)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct i915_hdcp_comp_master *comp;
+ int ret;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ comp = dev_priv->hdcp_master;
+
+ if (!comp || !comp->ops) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->close_hdcp_session(comp->mei_dev,
+ &connector->hdcp.port_data);
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return ret;
+}
+
+static __attribute__((unused))
+int hdcp2_deauthenticate_port(struct intel_connector *connector)
+{
+ return hdcp2_close_mei_session(connector);
+}
+
+static int i915_hdcp_component_bind(struct device *i915_kdev,
+ struct device *mei_kdev, void *data)
+{
+ struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
+
+ DRM_DEBUG("I915 HDCP comp bind\n");
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ dev_priv->hdcp_master = (struct i915_hdcp_comp_master *)data;
+ dev_priv->hdcp_master->mei_dev = mei_kdev;
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ return 0;
+}
+
+static void i915_hdcp_component_unbind(struct device *i915_kdev,
+ struct device *mei_kdev, void *data)
+{
+ struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
+
+ DRM_DEBUG("I915 HDCP comp unbind\n");
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ dev_priv->hdcp_master = NULL;
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+}
+
+static const struct component_ops i915_hdcp_component_ops = {
+ .bind = i915_hdcp_component_bind,
+ .unbind = i915_hdcp_component_unbind,
+};
+
+static inline int initialize_hdcp_port_data(struct intel_connector *connector)
+{
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ struct hdcp_port_data *data = &hdcp->port_data;
+
+ data->port = connector->encoder->port;
+ data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
+ data->protocol = (u8)hdcp->shim->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;
+}
+
static bool is_hdcp2_supported(struct drm_i915_private *dev_priv)
{
if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
@@ -841,11 +1184,40 @@ static bool is_hdcp2_supported(struct drm_i915_private *dev_priv)
IS_KABYLAKE(dev_priv));
}
+void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
+{
+ int ret;
+
+ if (!is_hdcp2_supported(dev_priv))
+ return;
+
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ WARN_ON(dev_priv->hdcp_comp_added);
+
+ dev_priv->hdcp_comp_added = true;
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ ret = component_add_typed(dev_priv->drm.dev, &i915_hdcp_component_ops,
+ I915_COMPONENT_HDCP);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("Failed at component add(%d)\n", ret);
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ dev_priv->hdcp_comp_added = false;
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return;
+ }
+}
+
static void intel_hdcp2_init(struct intel_connector *connector)
{
struct intel_hdcp *hdcp = &connector->hdcp;
+ int ret;
+
+ ret = initialize_hdcp_port_data(connector);
+ if (ret) {
+ DRM_DEBUG_KMS("Mei hdcp data init failed\n");
+ return;
+ }
- /* TODO: MEI interface needs to be initialized here */
hdcp->hdcp2_supported = true;
}
@@ -917,6 +1289,30 @@ int intel_hdcp_disable(struct intel_connector *connector)
return ret;
}
+void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
+{
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ if (!dev_priv->hdcp_comp_added) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return;
+ }
+
+ dev_priv->hdcp_comp_added = false;
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ component_del(dev_priv->drm.dev, &i915_hdcp_component_ops);
+}
+
+void intel_hdcp_cleanup(struct intel_connector *connector)
+{
+ if (!connector->hdcp.shim)
+ return;
+
+ mutex_lock(&connector->hdcp.mutex);
+ kfree(connector->hdcp.port_data.streams);
+ mutex_unlock(&connector->hdcp.mutex);
+}
+
void intel_hdcp_atomic_check(struct drm_connector *connector,
struct drm_connector_state *old_state,
struct drm_connector_state *new_state)
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 05/33] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (3 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 04/33] drm/i915: MEI interface implementation Ramalingam C via dri-devel
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:36 ` [PATCH v14 06/33] drm/i915: Enable and Disable of HDCP2.2 Ramalingam C
` (31 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
"hdcp_encrypted" flag is defined to denote the HDCP1.4 encryption status.
This SW tracking is used to determine the need for real hdcp1.4 disable
and hdcp_check_link upon CP_IRQ.
On CP_IRQ we filter the CP_IRQ related to the states like Link failure
and reauthentication req etc and handle them in hdcp_check_link.
CP_IRQ corresponding to the authentication msg availability are ignored.
WARN_ON is added for the abrupt stop of HDCP encryption of a port.
v2:
bool is used in struct for the cleaner coding. [Daniel]
check_link work_fn is scheduled for cp_irq handling [Daniel]
v3:
rebased.
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_dp.c | 2 +-
drivers/gpu/drm/i915/intel_drv.h | 5 ++-
drivers/gpu/drm/i915/intel_hdcp.c | 73 ++++++++++++++++++++++++++++-----------
3 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index cf709835fb9a..9f73a4239574 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4780,7 +4780,7 @@ static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
intel_dp_handle_test_request(intel_dp);
if (val & DP_CP_IRQ)
- intel_hdcp_check_link(intel_dp->attached_connector);
+ intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
if (val & DP_SINK_SPECIFIC_IRQ)
DRM_DEBUG_DRIVER("Sink specific irq unhandled\n");
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f8e8482573c8..df2c88877480 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -409,6 +409,9 @@ struct intel_hdcp {
struct delayed_work check_work;
struct work_struct prop_work;
+ /* HDCP1.4 Encryption status */
+ bool hdcp_encrypted;
+
/* HDCP2.2 related definitions */
/* Flag indicates whether this connector supports HDCP2.2 or not. */
bool hdcp2_supported;
@@ -2090,12 +2093,12 @@ int intel_hdcp_init(struct intel_connector *connector,
const struct intel_hdcp_shim *hdcp_shim);
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);
void intel_hdcp_component_init(struct drm_i915_private *dev_priv);
void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
void intel_hdcp_cleanup(struct intel_connector *connector);
+void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
/* 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 d06bef9d1ab2..66e3850a57a0 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -74,6 +74,16 @@ bool intel_hdcp_capable(struct intel_connector *connector)
return capable;
}
+static inline bool intel_hdcp_in_use(struct intel_connector *connector)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ enum port port = connector->encoder->port;
+ u32 reg;
+
+ reg = I915_READ(PORT_HDCP_STATUS(port));
+ return reg & HDCP_STATUS_ENC;
+}
+
static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,
const struct intel_hdcp_shim *shim)
{
@@ -668,6 +678,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
connector->base.name, connector->base.base.id);
+ hdcp->hdcp_encrypted = false;
I915_WRITE(PORT_HDCP_CONF(port), 0);
if (intel_wait_for_register(dev_priv, PORT_HDCP_STATUS(port), ~0, 0,
ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
@@ -713,8 +724,10 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
/* Incase of authentication failures, HDCP spec expects reauth. */
for (i = 0; i < tries; i++) {
ret = intel_hdcp_auth(conn_to_dig_port(connector), hdcp->shim);
- if (!ret)
+ if (!ret) {
+ hdcp->hdcp_encrypted = true;
return 0;
+ }
DRM_DEBUG_KMS("HDCP Auth failure (%d)\n", ret);
@@ -741,16 +754,17 @@ int intel_hdcp_check_link(struct intel_connector *connector)
enum port port = intel_dig_port->base.port;
int ret = 0;
- if (!hdcp->shim)
- return -ENOENT;
-
mutex_lock(&hdcp->mutex);
- if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+ /* Check_link valid only when HDCP1.4 is enabled */
+ if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED ||
+ !hdcp->hdcp_encrypted) {
+ ret = -EINVAL;
goto out;
+ }
- if (!(I915_READ(PORT_HDCP_STATUS(port)) & HDCP_STATUS_ENC)) {
- DRM_ERROR("%s:%d HDCP check failed: link is not encrypted,%x\n",
+ if (WARN_ON(!intel_hdcp_in_use(connector))) {
+ DRM_ERROR("%s:%d HDCP link stopped encryption,%x\n",
connector->base.name, connector->base.base.id,
I915_READ(PORT_HDCP_STATUS(port)));
ret = -ENXIO;
@@ -791,18 +805,6 @@ int intel_hdcp_check_link(struct intel_connector *connector)
return ret;
}
-static void intel_hdcp_check_work(struct work_struct *work)
-{
- struct intel_hdcp *hdcp = container_of(to_delayed_work(work),
- struct intel_hdcp,
- check_work);
- struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
-
- if (!intel_hdcp_check_link(connector))
- schedule_delayed_work(&hdcp->check_work,
- DRM_HDCP_CHECK_PERIOD_MS);
-}
-
static void intel_hdcp_prop_work(struct work_struct *work)
{
struct intel_hdcp *hdcp = container_of(work, struct intel_hdcp,
@@ -1120,6 +1122,18 @@ int hdcp2_deauthenticate_port(struct intel_connector *connector)
return hdcp2_close_mei_session(connector);
}
+static void intel_hdcp_check_work(struct work_struct *work)
+{
+ struct intel_hdcp *hdcp = container_of(to_delayed_work(work),
+ struct intel_hdcp,
+ check_work);
+ struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
+
+ if (!intel_hdcp_check_link(connector))
+ schedule_delayed_work(&hdcp->check_work,
+ DRM_HDCP_CHECK_PERIOD_MS);
+}
+
static int i915_hdcp_component_bind(struct device *i915_kdev,
struct device *mei_kdev, void *data)
{
@@ -1281,7 +1295,8 @@ int intel_hdcp_disable(struct intel_connector *connector)
if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
hdcp->value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
- ret = _intel_hdcp_disable(connector);
+ if (hdcp->hdcp_encrypted)
+ ret = _intel_hdcp_disable(connector);
}
mutex_unlock(&hdcp->mutex);
@@ -1345,3 +1360,21 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
new_state->crtc);
crtc_state->mode_changed = true;
}
+
+/* Handles the CP_IRQ raised from the DP HDCP sink */
+void intel_hdcp_handle_cp_irq(struct intel_connector *connector)
+{
+ struct intel_hdcp *hdcp = &connector->hdcp;
+
+ if (!hdcp->shim)
+ return;
+
+ /*
+ * CP_IRQ could be triggered due to 1. HDCP2.2 auth msgs availability,
+ * 2. link failure and 3. repeater reauth request. At present we dont
+ * handle the CP_IRQ for the HDCP2.2 auth msg availability for read.
+ * To handle other two causes for CP_IRQ we have the work_fn which is
+ * scheduled here.
+ */
+ schedule_delayed_work(&hdcp->check_work, 0);
+}
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 06/33] drm/i915: Enable and Disable of HDCP2.2
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (4 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 05/33] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:36 ` [PATCH v14 07/33] drm/i915: Implement HDCP2.2 receiver authentication Ramalingam C
` (30 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Considering that HDCP2.2 is more secure than HDCP1.4, When a setup
supports HDCP2.2 and HDCP1.4, HDCP2.2 will be enabled.
When HDCP2.2 enabling fails and HDCP1.4 is supported, HDCP1.4 is
enabled.
This change implements a sequence of enabling and disabling of
HDCP2.2 authentication and HDCP2.2 port encryption.
v2:
Included few optimization suggestions [Chris Wilson]
Commit message is updated as per the rebased version.
intel_wait_for_register is used instead of wait_for. [Chris Wilson]
v3:
Extra comment added and Style issue fixed [Uma]
v4:
Rebased as part of patch reordering.
HDCP2 encryption status is tracked.
HW state check is moved into WARN_ON [Daniel]
v5:
Redefined the mei service functions as per comp redesign.
Merged patches related to hdcp2.2 enabling and disabling [Sean Paul].
Required shim functionality is defined [Sean Paul]
v6:
Return values are handles [Uma]
Realigned the code.
Check for comp_master is removed.
v7:
HDCP2.2 is attempted only if mei interface is up.
Adjust to the new interface
Avoid bool usage in struct [Tomas]
v8:
mei_binded status check is removed.
%s/hdcp2_in_use/hdcp2_encrypted
v9:
bool is used in struct intel_hdcp. [Daniel]
v10:
panel is replaced with sink [Uma]
Mei interface decided the hdcp2_capability.
WARN_ON if hdcp_enable is called when hdcp state is ENABLED.
Reviewed-by Uma.
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 | 7 ++
drivers/gpu/drm/i915/intel_hdcp.c | 212 +++++++++++++++++++++++++++++++++++---
2 files changed, 205 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index df2c88877480..2c99f88b71a7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -399,6 +399,10 @@ struct intel_hdcp_shim {
/* HDCP adaptation(DP/HDMI) required on the port */
enum hdcp_wired_protocol protocol;
+
+ /* Detects whether sink is HDCP2.2 capable */
+ int (*hdcp_2_2_capable)(struct intel_digital_port *intel_dig_port,
+ bool *capable);
};
struct intel_hdcp {
@@ -416,6 +420,9 @@ struct intel_hdcp {
/* Flag indicates whether this connector supports HDCP2.2 or not. */
bool hdcp2_supported;
+ /* HDCP2.2 Encryption status */
+ bool hdcp2_encrypted;
+
/*
* 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)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 66e3850a57a0..0b6ccb3d24fe 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -74,6 +74,32 @@ bool intel_hdcp_capable(struct intel_connector *connector)
return capable;
}
+/* Is HDCP2.2 capable on Platform and Sink */
+static bool intel_hdcp2_capable(struct intel_connector *connector)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ bool capable = false;
+
+ /* I915 support for HDCP2.2 */
+ if (!hdcp->hdcp2_supported)
+ return false;
+
+ /* MEI interface is solid */
+ mutex_lock(&dev_priv->hdcp_comp_mutex);
+ if (!dev_priv->hdcp_comp_added || !dev_priv->hdcp_master) {
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+ return false;
+ }
+ mutex_unlock(&dev_priv->hdcp_comp_mutex);
+
+ /* Sink's capability for HDCP2.2 */
+ hdcp->shim->hdcp_2_2_capable(intel_dig_port, &capable);
+
+ return capable;
+}
+
static inline bool intel_hdcp_in_use(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1094,8 +1120,7 @@ int hdcp2_authenticate_port(struct intel_connector *connector)
return ret;
}
-static __attribute__((unused))
-int hdcp2_close_mei_session(struct intel_connector *connector)
+static int hdcp2_close_mei_session(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct i915_hdcp_comp_master *comp;
@@ -1116,12 +1141,157 @@ int hdcp2_close_mei_session(struct intel_connector *connector)
return ret;
}
-static __attribute__((unused))
-int hdcp2_deauthenticate_port(struct intel_connector *connector)
+static int hdcp2_deauthenticate_port(struct intel_connector *connector)
{
return hdcp2_close_mei_session(connector);
}
+static int hdcp2_authenticate_sink(struct intel_connector *connector)
+{
+ DRM_ERROR("Sink authentication is done in subsequent patches\n");
+
+ return -EINVAL;
+}
+
+static int hdcp2_enable_encryption(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ enum port port = connector->encoder->port;
+ int ret;
+
+ WARN_ON(I915_READ(HDCP2_STATUS_DDI(port)) & LINK_ENCRYPTION_STATUS);
+
+ if (hdcp->shim->toggle_signalling) {
+ ret = hdcp->shim->toggle_signalling(intel_dig_port, true);
+ if (ret) {
+ DRM_ERROR("Failed to enable HDCP signalling. %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ if (I915_READ(HDCP2_STATUS_DDI(port)) & LINK_AUTH_STATUS) {
+ /* Link is Authenticated. Now set for Encryption */
+ I915_WRITE(HDCP2_CTL_DDI(port),
+ I915_READ(HDCP2_CTL_DDI(port)) |
+ CTL_LINK_ENCRYPTION_REQ);
+ }
+
+ ret = intel_wait_for_register(dev_priv, HDCP2_STATUS_DDI(port),
+ LINK_ENCRYPTION_STATUS,
+ LINK_ENCRYPTION_STATUS,
+ ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
+
+ return ret;
+}
+
+static int hdcp2_disable_encryption(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ enum port port = connector->encoder->port;
+ int ret;
+
+ WARN_ON(!(I915_READ(HDCP2_STATUS_DDI(port)) & LINK_ENCRYPTION_STATUS));
+
+ I915_WRITE(HDCP2_CTL_DDI(port),
+ I915_READ(HDCP2_CTL_DDI(port)) & ~CTL_LINK_ENCRYPTION_REQ);
+
+ ret = intel_wait_for_register(dev_priv, HDCP2_STATUS_DDI(port),
+ LINK_ENCRYPTION_STATUS, 0x0,
+ ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
+ if (ret == -ETIMEDOUT)
+ DRM_DEBUG_KMS("Disable Encryption Timedout");
+
+ if (hdcp->shim->toggle_signalling) {
+ ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
+ if (ret) {
+ DRM_ERROR("Failed to disable HDCP signalling. %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector)
+{
+ int ret, i, tries = 3;
+
+ for (i = 0; i < tries; i++) {
+ ret = hdcp2_authenticate_sink(connector);
+ if (!ret)
+ break;
+
+ /* Clearing the mei hdcp session */
+ DRM_DEBUG_KMS("HDCP2.2 Auth %d of %d Failed.(%d)\n",
+ i + 1, tries, ret);
+ if (hdcp2_deauthenticate_port(connector) < 0)
+ DRM_DEBUG_KMS("Port deauth failed.\n");
+ }
+
+ if (i != tries) {
+ /*
+ * Ensuring the required 200mSec min time interval between
+ * Session Key Exchange and encryption.
+ */
+ msleep(HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN);
+ ret = hdcp2_enable_encryption(connector);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("Encryption Enable Failed.(%d)\n", ret);
+ if (hdcp2_deauthenticate_port(connector) < 0)
+ DRM_DEBUG_KMS("Port deauth failed.\n");
+ }
+ }
+
+ return ret;
+}
+
+static int _intel_hdcp2_enable(struct intel_connector *connector)
+{
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ int ret;
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being enabled. Type: %d\n",
+ connector->base.name, connector->base.base.id,
+ hdcp->content_type);
+
+ ret = hdcp2_authenticate_and_encrypt(connector);
+ if (ret) {
+ DRM_DEBUG_KMS("HDCP2 Type%d Enabling Failed. (%d)\n",
+ hdcp->content_type, ret);
+ return ret;
+ }
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is enabled. Type %d\n",
+ connector->base.name, connector->base.base.id,
+ hdcp->content_type);
+
+ hdcp->hdcp2_encrypted = true;
+ return 0;
+}
+
+static int _intel_hdcp2_disable(struct intel_connector *connector)
+{
+ int ret;
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being Disabled\n",
+ connector->base.name, connector->base.base.id);
+
+ ret = hdcp2_disable_encryption(connector);
+
+ if (hdcp2_deauthenticate_port(connector) < 0)
+ DRM_DEBUG_KMS("Port deauth failed.\n");
+
+ connector->hdcp.hdcp2_encrypted = false;
+
+ return ret;
+}
+
static void intel_hdcp_check_work(struct work_struct *work)
{
struct intel_hdcp *hdcp = container_of(to_delayed_work(work),
@@ -1263,22 +1433,34 @@ int intel_hdcp_init(struct intel_connector *connector,
int intel_hdcp_enable(struct intel_connector *connector)
{
struct intel_hdcp *hdcp = &connector->hdcp;
- int ret;
+ int ret = -EINVAL;
if (!hdcp->shim)
return -ENOENT;
mutex_lock(&hdcp->mutex);
+ WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
- ret = _intel_hdcp_enable(connector);
- if (ret)
- goto out;
+ /*
+ * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
+ * is capable of HDCP2.2, it is preferred to use HDCP2.2.
+ */
+ if (intel_hdcp2_capable(connector))
+ ret = _intel_hdcp2_enable(connector);
+
+ /* When HDCP2.2 fails, HDCP1.4 will be attempted */
+ if (ret && intel_hdcp_capable(connector)) {
+ ret = _intel_hdcp_enable(connector);
+ if (!ret)
+ schedule_delayed_work(&hdcp->check_work,
+ DRM_HDCP_CHECK_PERIOD_MS);
+ }
+
+ if (!ret) {
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+ schedule_work(&hdcp->prop_work);
+ }
- hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
- schedule_work(&hdcp->prop_work);
- schedule_delayed_work(&hdcp->check_work,
- DRM_HDCP_CHECK_PERIOD_MS);
-out:
mutex_unlock(&hdcp->mutex);
return ret;
}
@@ -1295,7 +1477,9 @@ int intel_hdcp_disable(struct intel_connector *connector)
if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
hdcp->value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
- if (hdcp->hdcp_encrypted)
+ if (hdcp->hdcp2_encrypted)
+ ret = _intel_hdcp2_disable(connector);
+ else if (hdcp->hdcp_encrypted)
ret = _intel_hdcp_disable(connector);
}
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 07/33] drm/i915: Implement HDCP2.2 receiver authentication
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (5 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 06/33] drm/i915: Enable and Disable of HDCP2.2 Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:36 ` [PATCH v14 08/33] drm/i915: Implement HDCP2.2 repeater authentication Ramalingam C via dri-devel
` (29 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Implements HDCP2.2 authentication for hdcp2.2 receivers, with
following steps:
Authentication and Key exchange (AKE).
Locality Check (LC).
Session Key Exchange(SKE).
DP Errata for stream type configuration for receivers.
At AKE, the HDCP Receiver’s public key certificate is verified by the
HDCP Transmitter. A Master Key k m is exchanged.
At LC, the HDCP Transmitter enforces locality on the content by
requiring that the Round Trip Time (RTT) between a pair of messages
is not more than 20 ms.
At SKE, The HDCP Transmitter exchanges Session Key ks with
the HDCP Receiver.
In DP HDCP2.2 encryption and decryption logics use the stream type as
one of the parameter. So Before enabling the Encryption DP HDCP2.2
receiver needs to be communicated with stream type. This is added to
spec as ERRATA.
This generic implementation is complete only with the hdcp2 specific
functions defined at hdcp_shim.
v2: Rebased.
v3:
%s/PARING/PAIRING
Coding style fixing [Uma]
v4:
Rebased as part of patch reordering.
Defined the functions for mei services. [Daniel]
v5:
Redefined the mei service functions as per comp redesign.
Required intel_hdcp members are defined [Sean Paul]
v6:
Typo of cipher is Fixed [Uma]
%s/uintxx_t/uxx
Check for comp_master is removed.
v7:
Adjust to the new interface.
Avoid using bool structure members. [Tomas]
v8: Rebased.
v9:
bool is used in struct intel_hdcp [Daniel]
config_stream_type is redesigned [Daniel]
Reviewed-by Uma.
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 | 34 +++++++
drivers/gpu/drm/i915/intel_hdcp.c | 197 +++++++++++++++++++++++++++++++++++---
2 files changed, 216 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2c99f88b71a7..5797ee0078f2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -403,6 +403,22 @@ struct intel_hdcp_shim {
/* Detects whether sink is HDCP2.2 capable */
int (*hdcp_2_2_capable)(struct intel_digital_port *intel_dig_port,
bool *capable);
+
+ /* Write HDCP2.2 messages */
+ int (*write_2_2_msg)(struct intel_digital_port *intel_dig_port,
+ void *buf, size_t size);
+
+ /* Read HDCP2.2 messages */
+ int (*read_2_2_msg)(struct intel_digital_port *intel_dig_port,
+ u8 msg_id, void *buf, size_t size);
+
+ /*
+ * Implementation of DP HDCP2.2 Errata for the communication of stream
+ * type to Receivers. In DP HDCP2.2 Stream type is one of the input to
+ * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI.
+ */
+ int (*config_stream_type)(struct intel_digital_port *intel_dig_port,
+ bool is_repeater, u8 type);
};
struct intel_hdcp {
@@ -430,6 +446,24 @@ struct intel_hdcp {
*/
u8 content_type;
struct hdcp_port_data port_data;
+
+ bool is_paired;
+ bool is_repeater;
+
+ /*
+ * Count of ReceiverID_List received. Initialized to 0 at AKE_INIT.
+ * Incremented after processing the RepeaterAuth_Send_ReceiverID_List.
+ * When it rolls over re-auth has to be triggered.
+ */
+ u32 seq_num_v;
+
+ /*
+ * Count of RepeaterAuth_Stream_Manage msg propagated.
+ * Initialized to 0 on AKE_INIT. Incremented after every successful
+ * transmission of RepeaterAuth_Stream_Manage message. When it rolls
+ * over re-Auth has to be triggered.
+ */
+ u32 seq_num_m;
};
struct intel_connector {
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 0b6ccb3d24fe..d63f620581ad 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -17,6 +17,7 @@
#define KEY_LOAD_TRIES 5
#define ENCRYPT_STATUS_CHANGE_TIMEOUT_MS 50
+#define HDCP2_LC_RETRY_CNT 3
static
bool intel_hdcp_is_ksv_valid(u8 *ksv)
@@ -862,7 +863,7 @@ bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
return INTEL_GEN(dev_priv) >= 9 && port < PORT_E;
}
-static __attribute__((unused)) int
+static int
hdcp2_prepare_ake_init(struct intel_connector *connector,
struct hdcp2_ake_init *ake_data)
{
@@ -887,7 +888,7 @@ hdcp2_prepare_ake_init(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused)) int
+static int
hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
struct hdcp2_ake_send_cert *rx_cert,
bool *paired,
@@ -917,9 +918,8 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused)) int
-hdcp2_verify_hprime(struct intel_connector *connector,
- struct hdcp2_ake_send_hprime *rx_hprime)
+static int hdcp2_verify_hprime(struct intel_connector *connector,
+ struct hdcp2_ake_send_hprime *rx_hprime)
{
struct hdcp_port_data *data = &connector->hdcp.port_data;
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -942,7 +942,7 @@ hdcp2_verify_hprime(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused)) int
+static int
hdcp2_store_pairing_info(struct intel_connector *connector,
struct hdcp2_ake_send_pairing_info *pairing_info)
{
@@ -967,7 +967,7 @@ hdcp2_store_pairing_info(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused)) int
+static int
hdcp2_prepare_lc_init(struct intel_connector *connector,
struct hdcp2_lc_init *lc_init)
{
@@ -992,7 +992,7 @@ hdcp2_prepare_lc_init(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused)) int
+static int
hdcp2_verify_lprime(struct intel_connector *connector,
struct hdcp2_lc_send_lprime *rx_lprime)
{
@@ -1017,9 +1017,8 @@ hdcp2_verify_lprime(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused))
-int hdcp2_prepare_skey(struct intel_connector *connector,
- struct hdcp2_ske_send_eks *ske_data)
+static int hdcp2_prepare_skey(struct intel_connector *connector,
+ struct hdcp2_ske_send_eks *ske_data)
{
struct hdcp_port_data *data = &connector->hdcp.port_data;
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1096,8 +1095,7 @@ hdcp2_verify_mprime(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused))
-int hdcp2_authenticate_port(struct intel_connector *connector)
+static int hdcp2_authenticate_port(struct intel_connector *connector)
{
struct hdcp_port_data *data = &connector->hdcp.port_data;
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1146,11 +1144,180 @@ static int hdcp2_deauthenticate_port(struct intel_connector *connector)
return hdcp2_close_mei_session(connector);
}
+/* Authentication flow starts from here */
+static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ union {
+ struct hdcp2_ake_init ake_init;
+ struct hdcp2_ake_send_cert send_cert;
+ struct hdcp2_ake_no_stored_km no_stored_km;
+ struct hdcp2_ake_send_hprime send_hprime;
+ struct hdcp2_ake_send_pairing_info pairing_info;
+ } msgs;
+ const struct intel_hdcp_shim *shim = hdcp->shim;
+ size_t size;
+ int ret;
+
+ /* Init for seq_num */
+ hdcp->seq_num_v = 0;
+ hdcp->seq_num_m = 0;
+
+ ret = hdcp2_prepare_ake_init(connector, &msgs.ake_init);
+ if (ret < 0)
+ return ret;
+
+ ret = shim->write_2_2_msg(intel_dig_port, &msgs.ake_init,
+ sizeof(msgs.ake_init));
+ if (ret < 0)
+ return ret;
+
+ ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_AKE_SEND_CERT,
+ &msgs.send_cert, sizeof(msgs.send_cert));
+ if (ret < 0)
+ return ret;
+
+ if (msgs.send_cert.rx_caps[0] != HDCP_2_2_RX_CAPS_VERSION_VAL)
+ return -EINVAL;
+
+ hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]);
+
+ /*
+ * Here msgs.no_stored_km will hold msgs corresponding to the km
+ * stored also.
+ */
+ ret = hdcp2_verify_rx_cert_prepare_km(connector, &msgs.send_cert,
+ &hdcp->is_paired,
+ &msgs.no_stored_km, &size);
+ if (ret < 0)
+ return ret;
+
+ ret = shim->write_2_2_msg(intel_dig_port, &msgs.no_stored_km, size);
+ if (ret < 0)
+ return ret;
+
+ ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_AKE_SEND_HPRIME,
+ &msgs.send_hprime, sizeof(msgs.send_hprime));
+ if (ret < 0)
+ return ret;
+
+ ret = hdcp2_verify_hprime(connector, &msgs.send_hprime);
+ if (ret < 0)
+ return ret;
+
+ if (!hdcp->is_paired) {
+ /* Pairing is required */
+ ret = shim->read_2_2_msg(intel_dig_port,
+ HDCP_2_2_AKE_SEND_PAIRING_INFO,
+ &msgs.pairing_info,
+ sizeof(msgs.pairing_info));
+ if (ret < 0)
+ return ret;
+
+ ret = hdcp2_store_pairing_info(connector, &msgs.pairing_info);
+ if (ret < 0)
+ return ret;
+ hdcp->is_paired = true;
+ }
+
+ return 0;
+}
+
+static int hdcp2_locality_check(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ union {
+ struct hdcp2_lc_init lc_init;
+ struct hdcp2_lc_send_lprime send_lprime;
+ } msgs;
+ const struct intel_hdcp_shim *shim = hdcp->shim;
+ int tries = HDCP2_LC_RETRY_CNT, ret, i;
+
+ for (i = 0; i < tries; i++) {
+ ret = hdcp2_prepare_lc_init(connector, &msgs.lc_init);
+ if (ret < 0)
+ continue;
+
+ ret = shim->write_2_2_msg(intel_dig_port, &msgs.lc_init,
+ sizeof(msgs.lc_init));
+ if (ret < 0)
+ continue;
+
+ ret = shim->read_2_2_msg(intel_dig_port,
+ HDCP_2_2_LC_SEND_LPRIME,
+ &msgs.send_lprime,
+ sizeof(msgs.send_lprime));
+ if (ret < 0)
+ continue;
+
+ ret = hdcp2_verify_lprime(connector, &msgs.send_lprime);
+ if (!ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int hdcp2_session_key_exchange(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ struct hdcp2_ske_send_eks send_eks;
+ int ret;
+
+ ret = hdcp2_prepare_skey(connector, &send_eks);
+ if (ret < 0)
+ return ret;
+
+ ret = hdcp->shim->write_2_2_msg(intel_dig_port, &send_eks,
+ sizeof(send_eks));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int hdcp2_authenticate_sink(struct intel_connector *connector)
{
- DRM_ERROR("Sink authentication is done in subsequent patches\n");
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ const struct intel_hdcp_shim *shim = hdcp->shim;
+ int ret;
- return -EINVAL;
+ ret = hdcp2_authentication_key_exchange(connector);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("AKE Failed. Err : %d\n", ret);
+ return ret;
+ }
+
+ ret = hdcp2_locality_check(connector);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("Locality Check failed. Err : %d\n", ret);
+ return ret;
+ }
+
+ ret = hdcp2_session_key_exchange(connector);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("SKE Failed. Err : %d\n", ret);
+ return ret;
+ }
+
+ if (shim->config_stream_type) {
+ ret = shim->config_stream_type(intel_dig_port,
+ hdcp->is_repeater,
+ hdcp->content_type);
+ if (ret < 0)
+ return ret;
+ }
+
+ hdcp->port_data.streams[0].stream_type = hdcp->content_type;
+ ret = hdcp2_authenticate_port(connector);
+ if (ret < 0)
+ return ret;
+
+ return ret;
}
static int hdcp2_enable_encryption(struct intel_connector *connector)
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 08/33] drm/i915: Implement HDCP2.2 repeater authentication
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (6 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 07/33] drm/i915: Implement HDCP2.2 receiver authentication Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C via dri-devel
2019-02-16 17:36 ` [PATCH v14 09/33] drm: HDCP2.2 link check period Ramalingam C
` (28 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Implements the HDCP2.2 repeaters authentication steps such as verifying
the downstream topology and sending stream management information.
v2: Rebased.
v3:
-EINVAL is returned for topology error and rollover scenario.
Endianness conversion func from drm_hdcp.h is used [Uma]
v4:
Rebased as part of patches reordering.
Defined the mei service functions [Daniel]
v5:
Redefined the mei service functions as per comp redesign.
v6:
%s/uintxx_t/uxx
Check for comp_master is removed.
v7:
Adjust to the new mei interface.
style issue fixed.
v8:
drm_hdcp.h change is moved into separate patch [Daniel]
v9:
%s/__swab16/cpu_to_be16. [Tomas]
Reviewed-by Uma.
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_hdcp.c | 125 +++++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index d63f620581ad..24051120d3bb 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1041,7 +1041,7 @@ static int hdcp2_prepare_skey(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused)) int
+static int
hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
struct hdcp2_rep_send_receiverid_list
*rep_topology,
@@ -1070,7 +1070,7 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
return ret;
}
-static __attribute__((unused)) int
+static int
hdcp2_verify_mprime(struct intel_connector *connector,
struct hdcp2_rep_stream_ready *stream_ready)
{
@@ -1279,6 +1279,119 @@ static int hdcp2_session_key_exchange(struct intel_connector *connector)
return 0;
}
+static
+int hdcp2_propagate_stream_management_info(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ union {
+ struct hdcp2_rep_stream_manage stream_manage;
+ struct hdcp2_rep_stream_ready stream_ready;
+ } msgs;
+ const struct intel_hdcp_shim *shim = hdcp->shim;
+ int ret;
+
+ /* Prepare RepeaterAuth_Stream_Manage msg */
+ msgs.stream_manage.msg_id = HDCP_2_2_REP_STREAM_MANAGE;
+ drm_hdcp2_u32_to_seq_num(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
+
+ /* K no of streams is fixed as 1. Stored as big-endian. */
+ msgs.stream_manage.k = cpu_to_be16(1);
+
+ /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */
+ msgs.stream_manage.streams[0].stream_id = 0;
+ msgs.stream_manage.streams[0].stream_type = hdcp->content_type;
+
+ /* Send it to Repeater */
+ ret = shim->write_2_2_msg(intel_dig_port, &msgs.stream_manage,
+ sizeof(msgs.stream_manage));
+ if (ret < 0)
+ return ret;
+
+ ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_STREAM_READY,
+ &msgs.stream_ready, sizeof(msgs.stream_ready));
+ if (ret < 0)
+ return ret;
+
+ hdcp->port_data.seq_num_m = hdcp->seq_num_m;
+ hdcp->port_data.streams[0].stream_type = hdcp->content_type;
+
+ ret = hdcp2_verify_mprime(connector, &msgs.stream_ready);
+ if (ret < 0)
+ return ret;
+
+ hdcp->seq_num_m++;
+
+ if (hdcp->seq_num_m > HDCP_2_2_SEQ_NUM_MAX) {
+ DRM_DEBUG_KMS("seq_num_m roll over.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static
+int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ union {
+ struct hdcp2_rep_send_receiverid_list recvid_list;
+ struct hdcp2_rep_send_ack rep_ack;
+ } msgs;
+ const struct intel_hdcp_shim *shim = hdcp->shim;
+ u8 *rx_info;
+ u32 seq_num_v;
+ int ret;
+
+ ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_SEND_RECVID_LIST,
+ &msgs.recvid_list, sizeof(msgs.recvid_list));
+ if (ret < 0)
+ return ret;
+
+ rx_info = msgs.recvid_list.rx_info;
+
+ if (HDCP_2_2_MAX_CASCADE_EXCEEDED(rx_info[1]) ||
+ HDCP_2_2_MAX_DEVS_EXCEEDED(rx_info[1])) {
+ DRM_DEBUG_KMS("Topology Max Size Exceeded\n");
+ return -EINVAL;
+ }
+
+ /* Converting and Storing the seq_num_v to local variable as DWORD */
+ seq_num_v = drm_hdcp2_seq_num_to_u32(msgs.recvid_list.seq_num_v);
+
+ if (seq_num_v < hdcp->seq_num_v) {
+ /* Roll over of the seq_num_v from repeater. Reauthenticate. */
+ DRM_DEBUG_KMS("Seq_num_v roll over.\n");
+ return -EINVAL;
+ }
+
+ ret = hdcp2_verify_rep_topology_prepare_ack(connector,
+ &msgs.recvid_list,
+ &msgs.rep_ack);
+ if (ret < 0)
+ return ret;
+
+ hdcp->seq_num_v = seq_num_v;
+ ret = shim->write_2_2_msg(intel_dig_port, &msgs.rep_ack,
+ sizeof(msgs.rep_ack));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int hdcp2_authenticate_repeater(struct intel_connector *connector)
+{
+ int ret;
+
+ ret = hdcp2_authenticate_repeater_topology(connector);
+ if (ret < 0)
+ return ret;
+
+ return hdcp2_propagate_stream_management_info(connector);
+}
+
static int hdcp2_authenticate_sink(struct intel_connector *connector)
{
struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
@@ -1312,6 +1425,14 @@ static int hdcp2_authenticate_sink(struct intel_connector *connector)
return ret;
}
+ if (hdcp->is_repeater) {
+ ret = hdcp2_authenticate_repeater(connector);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("Repeater Auth Failed. Err: %d\n", ret);
+ return ret;
+ }
+ }
+
hdcp->port_data.streams[0].stream_type = hdcp->content_type;
ret = hdcp2_authenticate_port(connector);
if (ret < 0)
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 09/33] drm: HDCP2.2 link check period
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (7 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 08/33] drm/i915: Implement HDCP2.2 repeater authentication Ramalingam C via dri-devel
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:36 ` [PATCH v14 10/33] drm/i915: Implement HDCP2.2 link integrity check Ramalingam C
` (27 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Time period for HDCP2.2 link check.
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>
---
include/drm/drm_hdcp.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 7260b31af276..d4e98b11b4aa 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -13,6 +13,7 @@
/* Period of hdcp checks (to ensure we're still authenticated) */
#define DRM_HDCP_CHECK_PERIOD_MS (128 * 16)
+#define DRM_HDCP2_CHECK_PERIOD_MS 500
/* Shared lengths/masks between HDMI/DVI/DisplayPort */
#define DRM_HDCP_AN_LEN 8
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 10/33] drm/i915: Implement HDCP2.2 link integrity check
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (8 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 09/33] drm: HDCP2.2 link check period Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:36 ` [PATCH v14 11/33] drm/i915: Handle HDCP2.2 downstream topology change Ramalingam C via dri-devel
` (26 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Implements the link integrity check once in 500mSec.
Once encryption is enabled, an ongoing Link Integrity Check is
performed by the HDCP Receiver to check that cipher synchronization
is maintained between the HDCP Transmitter and the HDCP Receiver.
On the detection of synchronization lost, the HDCP Receiver must assert
the corresponding bits of the RxStatus register. The Transmitter polls
the RxStatus register and it may initiate re-authentication.
v2:
Rebased.
v3:
enum check_link_response is used check the link status [Uma]
v4:
Rebased as part of patch reordering.
v5:
Required members of intel_hdcp is defined [Sean Paul]
v6:
hdcp2_check_link is cancelled at required places.
v7:
Rebased for the component i/f changes.
Errors due to the sinks are reported as DEBUG logs.
v8:
hdcp_check_work is used for both hdcp1 and hdcp2 check_link [Daniel]
hdcp2.2 encryption status check is put under WARN_ON [Daniel]
drm_hdcp.h changes are moved into separate patch [Daniel]
v9:
enum check_link_status is defined at intel_drv.h [Daniel]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/intel_drv.h | 10 +++++
drivers/gpu/drm/i915/intel_hdcp.c | 88 ++++++++++++++++++++++++++++++++++++---
2 files changed, 93 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5797ee0078f2..dfedcc2b076c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -324,6 +324,13 @@ struct intel_panel {
struct intel_digital_port;
+enum check_link_response {
+ HDCP_LINK_PROTECTED = 0,
+ HDCP_TOPOLOGY_CHANGE,
+ HDCP_LINK_INTEGRITY_FAILURE,
+ HDCP_REAUTH_REQUEST
+};
+
/*
* This structure serves as a translation layer between the generic HDCP code
* and the bus-specific code. What that means is that HDCP over HDMI differs
@@ -419,6 +426,9 @@ struct intel_hdcp_shim {
*/
int (*config_stream_type)(struct intel_digital_port *intel_dig_port,
bool is_repeater, u8 type);
+
+ /* HDCP2.2 Link Integrity Check */
+ int (*check_2_2_link)(struct intel_digital_port *intel_dig_port);
};
struct intel_hdcp {
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 24051120d3bb..00fae3963caf 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -111,6 +111,16 @@ static inline bool intel_hdcp_in_use(struct intel_connector *connector)
return reg & HDCP_STATUS_ENC;
}
+static inline bool intel_hdcp2_in_use(struct intel_connector *connector)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ enum port port = connector->encoder->port;
+ u32 reg;
+
+ reg = I915_READ(HDCP2_STATUS_DDI(port));
+ return reg & LINK_ENCRYPTION_STATUS;
+}
+
static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,
const struct intel_hdcp_shim *shim)
{
@@ -1580,6 +1590,69 @@ static int _intel_hdcp2_disable(struct intel_connector *connector)
return ret;
}
+/* Implements the Link Integrity Check for HDCP2.2 */
+static int intel_hdcp2_check_link(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ enum port port = connector->encoder->port;
+ int ret = 0;
+
+ mutex_lock(&hdcp->mutex);
+
+ /* hdcp2_check_link is expected only when HDCP2.2 is Enabled */
+ if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED ||
+ !hdcp->hdcp2_encrypted) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (WARN_ON(!intel_hdcp2_in_use(connector))) {
+ DRM_ERROR("HDCP2.2 link stopped the encryption, %x\n",
+ I915_READ(HDCP2_STATUS_DDI(port)));
+ ret = -ENXIO;
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdcp->prop_work);
+ goto out;
+ }
+
+ ret = hdcp->shim->check_2_2_link(intel_dig_port);
+ if (ret == HDCP_LINK_PROTECTED) {
+ if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+ schedule_work(&hdcp->prop_work);
+ }
+ goto out;
+ }
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 link failed, retrying auth\n",
+ connector->base.name, connector->base.base.id);
+
+ ret = _intel_hdcp2_disable(connector);
+ if (ret) {
+ DRM_ERROR("[%s:%d] Failed to disable hdcp2.2 (%d)\n",
+ connector->base.name, connector->base.base.id, ret);
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdcp->prop_work);
+ goto out;
+ }
+
+ ret = _intel_hdcp2_enable(connector);
+ if (ret) {
+ DRM_DEBUG_KMS("[%s:%d] Failed to enable hdcp2.2 (%d)\n",
+ connector->base.name, connector->base.base.id,
+ ret);
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+ schedule_work(&hdcp->prop_work);
+ goto out;
+ }
+
+out:
+ mutex_unlock(&hdcp->mutex);
+ return ret;
+}
+
static void intel_hdcp_check_work(struct work_struct *work)
{
struct intel_hdcp *hdcp = container_of(to_delayed_work(work),
@@ -1587,7 +1660,10 @@ static void intel_hdcp_check_work(struct work_struct *work)
check_work);
struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
- if (!intel_hdcp_check_link(connector))
+ if (!intel_hdcp2_check_link(connector))
+ schedule_delayed_work(&hdcp->check_work,
+ DRM_HDCP2_CHECK_PERIOD_MS);
+ else if (!intel_hdcp_check_link(connector))
schedule_delayed_work(&hdcp->check_work,
DRM_HDCP_CHECK_PERIOD_MS);
}
@@ -1721,6 +1797,7 @@ int intel_hdcp_init(struct intel_connector *connector,
int intel_hdcp_enable(struct intel_connector *connector)
{
struct intel_hdcp *hdcp = &connector->hdcp;
+ unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
int ret = -EINVAL;
if (!hdcp->shim)
@@ -1733,18 +1810,19 @@ int intel_hdcp_enable(struct intel_connector *connector)
* Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
* is capable of HDCP2.2, it is preferred to use HDCP2.2.
*/
- if (intel_hdcp2_capable(connector))
+ if (intel_hdcp2_capable(connector)) {
ret = _intel_hdcp2_enable(connector);
+ if (!ret)
+ check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS;
+ }
/* When HDCP2.2 fails, HDCP1.4 will be attempted */
if (ret && intel_hdcp_capable(connector)) {
ret = _intel_hdcp_enable(connector);
- if (!ret)
- schedule_delayed_work(&hdcp->check_work,
- DRM_HDCP_CHECK_PERIOD_MS);
}
if (!ret) {
+ schedule_delayed_work(&hdcp->check_work, check_link_interval);
hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
schedule_work(&hdcp->prop_work);
}
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 11/33] drm/i915: Handle HDCP2.2 downstream topology change
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (9 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 10/33] drm/i915: Implement HDCP2.2 link integrity check Ramalingam C
@ 2019-02-16 17:36 ` Ramalingam C via dri-devel
2019-02-16 17:36 ` [PATCH v14 12/33] drm: removing the DP Errata msg and its msg id Ramalingam C
` (25 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
When repeater notifies a downstream topology change, this patch
reauthenticate the repeater alone without disabling the hdcp
encryption. If that fails then complete reauthentication is executed.
v2:
Rebased.
v3:
Typo in commit msg is fixed [Uma]
v4:
Rebased as part of patch reordering.
Minor style fixes.
v5:
Rebased.
v6:
Rebased.
v7:
Errors due to sinks are reported as DEBUG logs.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/intel_hdcp.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 00fae3963caf..fe0445c0eaac 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1626,8 +1626,24 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
goto out;
}
- DRM_DEBUG_KMS("[%s:%d] HDCP2.2 link failed, retrying auth\n",
- connector->base.name, connector->base.base.id);
+ if (ret == HDCP_TOPOLOGY_CHANGE) {
+ if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+ goto out;
+
+ DRM_DEBUG_KMS("HDCP2.2 Downstream topology change\n");
+ ret = hdcp2_authenticate_repeater_topology(connector);
+ if (!ret) {
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+ schedule_work(&hdcp->prop_work);
+ goto out;
+ }
+ DRM_DEBUG_KMS("[%s:%d] Repeater topology auth failed.(%d)\n",
+ connector->base.name, connector->base.base.id,
+ ret);
+ } else {
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 link failed, retrying auth\n",
+ connector->base.name, connector->base.base.id);
+ }
ret = _intel_hdcp2_disable(connector);
if (ret) {
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 12/33] drm: removing the DP Errata msg and its msg id
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (10 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 11/33] drm/i915: Handle HDCP2.2 downstream topology change Ramalingam C via dri-devel
@ 2019-02-16 17:36 ` Ramalingam C
2019-02-16 17:37 ` [PATCH v14 13/33] drm/i915: Implement the HDCP2.2 support for DP Ramalingam C
` (24 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:36 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Since DP ERRATA message is not defined at spec, those structure
definition is removed from drm_hdcp.h
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
include/drm/drm_hdcp.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index d4e98b11b4aa..f243408ecf26 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -69,7 +69,6 @@
#define HDCP_2_2_REP_SEND_ACK 15
#define HDCP_2_2_REP_STREAM_MANAGE 16
#define HDCP_2_2_REP_STREAM_READY 17
-#define HDCP_2_2_ERRATA_DP_STREAM_TYPE 50
#define HDCP_2_2_RTX_LEN 8
#define HDCP_2_2_RRX_LEN 8
@@ -220,11 +219,6 @@ struct hdcp2_rep_stream_ready {
u8 m_prime[HDCP_2_2_MPRIME_LEN];
} __packed;
-struct hdcp2_dp_errata_stream_type {
- u8 msg_id;
- u8 stream_type;
-} __packed;
-
/* HDCP2.2 TIMEOUTs in mSec */
#define HDCP_2_2_CERT_TIMEOUT_MS 100
#define HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS 1000
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 13/33] drm/i915: Implement the HDCP2.2 support for DP
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (11 preceding siblings ...)
2019-02-16 17:36 ` [PATCH v14 12/33] drm: removing the DP Errata msg and its msg id Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-08-15 8:43 ` Jani Nikula
2019-02-16 17:37 ` [PATCH v14 14/33] drm/i915: Implement the HDCP2.2 support for HDMI Ramalingam C
` (23 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Implements the DP adaptation specific HDCP2.2 functions.
These functions perform the DPCD read and write for communicating the
HDCP2.2 auth message back and forth.
v2:
wait for cp_irq is merged with this patch. Rebased.
v3:
wait_queue is used for wait for cp_irq [Chris Wilson]
v4:
Style fixed.
%s/PARING/PAIRING
Few style fixes [Uma]
v5:
Lookup table for DP HDCP2.2 msg details [Daniel].
Extra lines are removed.
v6: Rebased.
v7:
Fixed some regression introduced at v5. [Ankit]
Macro HDCP_2_2_RX_CAPS_VERSION_VAL is reused [Uma]
Converted a function to inline [Uma]
%s/uintxx_t/uxx
v8:
Error due to the sinks are reported as DEBUG logs.
Adjust to the new mei interface.
v9:
ARRAY_SIZE for no of array members [Jon & Daniel]
return of the wait_for_cp_irq is made as void [Daniel]
Wait for HDCP2.2 msg is done based on polling the reg bit than
CP_IRQ based. [Daniel]
hdcp adaptation is added as a const in the hdcp_shim [Daniel]
v10:
config_stream_type is redefined [Daniel]
DP Errata specific defines are moved into intel_dp.c.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Ankit K Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/intel_dp.c | 333 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 333 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 9f73a4239574..e9fe25f21200 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5847,6 +5847,333 @@ int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
return 0;
}
+struct hdcp2_dp_errata_stream_type {
+ u8 msg_id;
+ u8 stream_type;
+} __packed;
+
+static struct hdcp2_dp_msg_data {
+ u8 msg_id;
+ u32 offset;
+ bool msg_detectable;
+ u32 timeout;
+ u32 timeout2; /* Added for non_paired situation */
+ } hdcp2_msg_data[] = {
+ {HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0},
+ {HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
+ false, HDCP_2_2_CERT_TIMEOUT_MS, 0},
+ {HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
+ false, 0, 0},
+ {HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
+ false, 0, 0},
+ {HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
+ true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
+ HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS},
+ {HDCP_2_2_AKE_SEND_PAIRING_INFO,
+ DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
+ HDCP_2_2_PAIRING_TIMEOUT_MS, 0},
+ {HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0},
+ {HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
+ false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0},
+ {HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
+ 0, 0},
+ {HDCP_2_2_REP_SEND_RECVID_LIST,
+ DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
+ HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0},
+ {HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
+ 0, 0},
+ {HDCP_2_2_REP_STREAM_MANAGE,
+ DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
+ 0, 0},
+ {HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
+ false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0},
+/* local define to shovel this through the write_2_2 interface */
+#define HDCP_2_2_ERRATA_DP_STREAM_TYPE 50
+ {HDCP_2_2_ERRATA_DP_STREAM_TYPE,
+ DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
+ 0, 0},
+ };
+
+static inline
+int intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
+ u8 *rx_status)
+{
+ ssize_t ret;
+
+ ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+ DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
+ HDCP_2_2_DP_RXSTATUS_LEN);
+ if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
+ DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret);
+ return ret >= 0 ? -EIO : ret;
+ }
+
+ return 0;
+}
+
+static
+int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
+ u8 msg_id, bool *msg_ready)
+{
+ u8 rx_status;
+ int ret;
+
+ *msg_ready = false;
+ ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
+ if (ret < 0)
+ return ret;
+
+ switch (msg_id) {
+ case HDCP_2_2_AKE_SEND_HPRIME:
+ if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
+ *msg_ready = true;
+ break;
+ case HDCP_2_2_AKE_SEND_PAIRING_INFO:
+ if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
+ *msg_ready = true;
+ break;
+ case HDCP_2_2_REP_SEND_RECVID_LIST:
+ if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
+ *msg_ready = true;
+ break;
+ default:
+ DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static ssize_t
+intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
+ struct hdcp2_dp_msg_data *hdcp2_msg_data)
+{
+ struct intel_dp *dp = &intel_dig_port->dp;
+ struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
+ u8 msg_id = hdcp2_msg_data->msg_id;
+ int ret, timeout;
+ bool msg_ready = false;
+
+ if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
+ timeout = hdcp2_msg_data->timeout2;
+ else
+ timeout = hdcp2_msg_data->timeout;
+
+ /*
+ * There is no way to detect the CERT, LPRIME and STREAM_READY
+ * availability. So Wait for timeout and read the msg.
+ */
+ if (!hdcp2_msg_data->msg_detectable) {
+ mdelay(timeout);
+ ret = 0;
+ } else {
+ /* TODO: In case if you need to wait on CP_IRQ, do it here */
+ ret = __wait_for(ret =
+ hdcp2_detect_msg_availability(intel_dig_port,
+ msg_id,
+ &msg_ready),
+ !ret && msg_ready, timeout * 1000,
+ 1000, 5 * 1000);
+
+ if (!msg_ready)
+ ret = -ETIMEDOUT;
+ }
+
+ if (ret)
+ DRM_DEBUG_KMS("msg_id %d, ret %d, timeout(mSec): %d\n",
+ hdcp2_msg_data->msg_id, ret, timeout);
+
+ return ret;
+}
+
+static struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hdcp2_msg_data); i++)
+ if (hdcp2_msg_data[i].msg_id == msg_id)
+ return &hdcp2_msg_data[i];
+
+ return NULL;
+}
+
+static
+int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
+ void *buf, size_t size)
+{
+ unsigned int offset;
+ u8 *byte = buf;
+ ssize_t ret, bytes_to_write, len;
+ struct hdcp2_dp_msg_data *hdcp2_msg_data;
+
+ hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
+ if (!hdcp2_msg_data)
+ return -EINVAL;
+
+ offset = hdcp2_msg_data->offset;
+
+ /* No msg_id in DP HDCP2.2 msgs */
+ bytes_to_write = size - 1;
+ byte++;
+
+ while (bytes_to_write) {
+ len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
+ DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
+
+ ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
+ offset, (void *)byte, len);
+ if (ret < 0)
+ return ret;
+
+ bytes_to_write -= ret;
+ byte += ret;
+ offset += ret;
+ }
+
+ return size;
+}
+
+static
+ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port)
+{
+ u8 rx_info[HDCP_2_2_RXINFO_LEN];
+ u32 dev_cnt;
+ ssize_t ret;
+
+ ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+ DP_HDCP_2_2_REG_RXINFO_OFFSET,
+ (void *)rx_info, HDCP_2_2_RXINFO_LEN);
+ if (ret != HDCP_2_2_RXINFO_LEN)
+ return ret >= 0 ? -EIO : ret;
+
+ dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
+ HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
+
+ if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
+ dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
+
+ ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
+ HDCP_2_2_RECEIVER_IDS_MAX_LEN +
+ (dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
+
+ return ret;
+}
+
+static
+int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
+ u8 msg_id, void *buf, size_t size)
+{
+ unsigned int offset;
+ u8 *byte = buf;
+ ssize_t ret, bytes_to_recv, len;
+ struct hdcp2_dp_msg_data *hdcp2_msg_data;
+
+ hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
+ if (!hdcp2_msg_data)
+ return -EINVAL;
+ offset = hdcp2_msg_data->offset;
+
+ ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
+ if (ret < 0)
+ return ret;
+
+ if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
+ ret = get_receiver_id_list_size(intel_dig_port);
+ if (ret < 0)
+ return ret;
+
+ size = ret;
+ }
+ bytes_to_recv = size - 1;
+
+ /* DP adaptation msgs has no msg_id */
+ byte++;
+
+ while (bytes_to_recv) {
+ len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
+ DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
+
+ ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
+ (void *)byte, len);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("msg_id %d, ret %zd\n", msg_id, ret);
+ return ret;
+ }
+
+ bytes_to_recv -= ret;
+ byte += ret;
+ offset += ret;
+ }
+ byte = buf;
+ *byte = msg_id;
+
+ return size;
+}
+
+static
+int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
+ bool is_repeater, u8 content_type)
+{
+ struct hdcp2_dp_errata_stream_type stream_type_msg;
+
+ if (is_repeater)
+ return 0;
+
+ /*
+ * Errata for DP: As Stream type is used for encryption, Receiver
+ * should be communicated with stream type for the decryption of the
+ * content.
+ * Repeater will be communicated with stream type as a part of it's
+ * auth later in time.
+ */
+ stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
+ stream_type_msg.stream_type = content_type;
+
+ return intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
+ sizeof(stream_type_msg));
+}
+
+static
+int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
+{
+ u8 rx_status;
+ int ret;
+
+ ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
+ if (ret)
+ return ret;
+
+ if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
+ ret = HDCP_REAUTH_REQUEST;
+ else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
+ ret = HDCP_LINK_INTEGRITY_FAILURE;
+ else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
+ ret = HDCP_TOPOLOGY_CHANGE;
+
+ return ret;
+}
+
+static
+int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
+ bool *capable)
+{
+ u8 rx_caps[3];
+ int ret;
+
+ *capable = false;
+ ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+ DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
+ rx_caps, HDCP_2_2_RXCAPS_LEN);
+ if (ret != HDCP_2_2_RXCAPS_LEN)
+ return ret >= 0 ? -EIO : ret;
+
+ if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
+ HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
+ *capable = true;
+
+ return 0;
+}
+
static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
.write_an_aksv = intel_dp_hdcp_write_an_aksv,
.read_bksv = intel_dp_hdcp_read_bksv,
@@ -5859,6 +6186,12 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
.toggle_signalling = intel_dp_hdcp_toggle_signalling,
.check_link = intel_dp_hdcp_check_link,
.hdcp_capable = intel_dp_hdcp_capable,
+ .write_2_2_msg = intel_dp_hdcp2_write_msg,
+ .read_2_2_msg = intel_dp_hdcp2_read_msg,
+ .config_stream_type = intel_dp_hdcp2_config_stream_type,
+ .check_2_2_link = intel_dp_hdcp2_check_link,
+ .hdcp_2_2_capable = intel_dp_hdcp2_capable,
+ .protocol = HDCP_PROTOCOL_DP,
};
static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 14/33] drm/i915: Implement the HDCP2.2 support for HDMI
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (12 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 13/33] drm/i915: Implement the HDCP2.2 support for DP Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-16 17:37 ` [PATCH v14 15/33] drm/i915: CP_IRQ handling for DP HDCP2.2 msgs Ramalingam C via dri-devel
` (22 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Implements the HDMI adaptation specific HDCP2.2 operations.
Basically these are DDC read and write for authenticating through
HDCP2.2 messages.
v2: Rebased.
v3:
No more special handling of Gmbus burst read for AKE_SEND_CERT.
Style fixed with few naming. [Uma]
%s/PARING/PAIRING
v4:
msg_sz is initialized at definition.
Lookup table is defined for HDMI HDCP2.2 msgs [Daniel].
v5: Rebased.
v6:
Make a function as inline [Uma]
%s/uintxx_t/uxx
v7:
Errors due to sinks are reported as DEBUG logs.
Adjust to the new mei interface.
v8:
ARRAY_SIZE for the # of array members [Jon & Daniel].
hdcp adaptation is added as a const in the hdcp_shim [Daniel]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/intel_hdmi.c | 189 ++++++++++++++++++++++++++++++++++++++
1 file changed, 189 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index faeedf76db99..6a3e400f54d7 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1129,6 +1129,190 @@ bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
return true;
}
+static struct hdcp2_hdmi_msg_data {
+ u8 msg_id;
+ u32 timeout;
+ u32 timeout2;
+ } hdcp2_msg_data[] = {
+ {HDCP_2_2_AKE_INIT, 0, 0},
+ {HDCP_2_2_AKE_SEND_CERT, HDCP_2_2_CERT_TIMEOUT_MS, 0},
+ {HDCP_2_2_AKE_NO_STORED_KM, 0, 0},
+ {HDCP_2_2_AKE_STORED_KM, 0, 0},
+ {HDCP_2_2_AKE_SEND_HPRIME, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
+ HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS},
+ {HDCP_2_2_AKE_SEND_PAIRING_INFO, HDCP_2_2_PAIRING_TIMEOUT_MS,
+ 0},
+ {HDCP_2_2_LC_INIT, 0, 0},
+ {HDCP_2_2_LC_SEND_LPRIME, HDCP_2_2_HDMI_LPRIME_TIMEOUT_MS, 0},
+ {HDCP_2_2_SKE_SEND_EKS, 0, 0},
+ {HDCP_2_2_REP_SEND_RECVID_LIST,
+ HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0},
+ {HDCP_2_2_REP_SEND_ACK, 0, 0},
+ {HDCP_2_2_REP_STREAM_MANAGE, 0, 0},
+ {HDCP_2_2_REP_STREAM_READY, HDCP_2_2_STREAM_READY_TIMEOUT_MS,
+ 0},
+ };
+
+static
+int intel_hdmi_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
+ uint8_t *rx_status)
+{
+ return intel_hdmi_hdcp_read(intel_dig_port,
+ HDCP_2_2_HDMI_REG_RXSTATUS_OFFSET,
+ rx_status,
+ HDCP_2_2_HDMI_RXSTATUS_LEN);
+}
+
+static int get_hdcp2_msg_timeout(u8 msg_id, bool is_paired)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hdcp2_msg_data); i++)
+ if (hdcp2_msg_data[i].msg_id == msg_id &&
+ (msg_id != HDCP_2_2_AKE_SEND_HPRIME || is_paired))
+ return hdcp2_msg_data[i].timeout;
+ else if (hdcp2_msg_data[i].msg_id == msg_id)
+ return hdcp2_msg_data[i].timeout2;
+
+ return -EINVAL;
+}
+
+static inline
+int hdcp2_detect_msg_availability(struct intel_digital_port *intel_digital_port,
+ u8 msg_id, bool *msg_ready,
+ ssize_t *msg_sz)
+{
+ u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN];
+ int ret;
+
+ ret = intel_hdmi_hdcp2_read_rx_status(intel_digital_port, rx_status);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("rx_status read failed. Err %d\n", ret);
+ return ret;
+ }
+
+ *msg_sz = ((HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(rx_status[1]) << 8) |
+ rx_status[0]);
+
+ if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST)
+ *msg_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1]) &&
+ *msg_sz);
+ else
+ *msg_ready = *msg_sz;
+
+ return 0;
+}
+
+static ssize_t
+intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
+ u8 msg_id, bool paired)
+{
+ bool msg_ready = false;
+ int timeout, ret;
+ ssize_t msg_sz = 0;
+
+ timeout = get_hdcp2_msg_timeout(msg_id, paired);
+ if (timeout < 0)
+ return timeout;
+
+ ret = __wait_for(ret = hdcp2_detect_msg_availability(intel_dig_port,
+ msg_id, &msg_ready,
+ &msg_sz),
+ !ret && msg_ready && msg_sz, timeout * 1000,
+ 1000, 5 * 1000);
+ if (ret)
+ DRM_DEBUG_KMS("msg_id: %d, ret: %d, timeout: %d\n",
+ msg_id, ret, timeout);
+
+ return ret ? ret : msg_sz;
+}
+
+static
+int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
+ void *buf, size_t size)
+{
+ unsigned int offset;
+
+ offset = HDCP_2_2_HDMI_REG_WR_MSG_OFFSET;
+ return intel_hdmi_hdcp_write(intel_dig_port, offset, buf, size);
+}
+
+static
+int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
+ u8 msg_id, void *buf, size_t size)
+{
+ struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
+ struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp;
+ unsigned int offset;
+ ssize_t ret;
+
+ ret = intel_hdmi_hdcp2_wait_for_msg(intel_dig_port, msg_id,
+ hdcp->is_paired);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Available msg size should be equal to or lesser than the
+ * available buffer.
+ */
+ if (ret > size) {
+ DRM_DEBUG_KMS("msg_sz(%zd) is more than exp size(%zu)\n",
+ ret, size);
+ return -1;
+ }
+
+ offset = HDCP_2_2_HDMI_REG_RD_MSG_OFFSET;
+ ret = intel_hdmi_hdcp_read(intel_dig_port, offset, buf, ret);
+ if (ret)
+ DRM_DEBUG_KMS("Failed to read msg_id: %d(%zd)\n", msg_id, ret);
+
+ return ret;
+}
+
+static
+int intel_hdmi_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
+{
+ u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN];
+ int ret;
+
+ ret = intel_hdmi_hdcp2_read_rx_status(intel_dig_port, rx_status);
+ if (ret)
+ return ret;
+
+ /*
+ * Re-auth request and Link Integrity Failures are represented by
+ * same bit. i.e reauth_req.
+ */
+ if (HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(rx_status[1]))
+ ret = HDCP_REAUTH_REQUEST;
+ else if (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1]))
+ ret = HDCP_TOPOLOGY_CHANGE;
+
+ return ret;
+}
+
+static
+int intel_hdmi_hdcp2_capable(struct intel_digital_port *intel_dig_port,
+ bool *capable)
+{
+ u8 hdcp2_version;
+ int ret;
+
+ *capable = false;
+ ret = intel_hdmi_hdcp_read(intel_dig_port, HDCP_2_2_HDMI_REG_VER_OFFSET,
+ &hdcp2_version, sizeof(hdcp2_version));
+ if (!ret && hdcp2_version & HDCP_2_2_HDMI_SUPPORT_MASK)
+ *capable = true;
+
+ return ret;
+}
+
+static inline
+enum hdcp_wired_protocol intel_hdmi_hdcp2_protocol(void)
+{
+ return HDCP_PROTOCOL_HDMI;
+}
+
static const struct intel_hdcp_shim intel_hdmi_hdcp_shim = {
.write_an_aksv = intel_hdmi_hdcp_write_an_aksv,
.read_bksv = intel_hdmi_hdcp_read_bksv,
@@ -1140,6 +1324,11 @@ static const struct intel_hdcp_shim intel_hdmi_hdcp_shim = {
.read_v_prime_part = intel_hdmi_hdcp_read_v_prime_part,
.toggle_signalling = intel_hdmi_hdcp_toggle_signalling,
.check_link = intel_hdmi_hdcp_check_link,
+ .write_2_2_msg = intel_hdmi_hdcp2_write_msg,
+ .read_2_2_msg = intel_hdmi_hdcp2_read_msg,
+ .check_2_2_link = intel_hdmi_hdcp2_check_link,
+ .hdcp_2_2_capable = intel_hdmi_hdcp2_capable,
+ .protocol = HDCP_PROTOCOL_HDMI,
};
static void intel_hdmi_prepare(struct intel_encoder *encoder,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 15/33] drm/i915: CP_IRQ handling for DP HDCP2.2 msgs
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (13 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 14/33] drm/i915: Implement the HDCP2.2 support for HDMI Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C via dri-devel
2019-02-16 17:37 ` [PATCH v14 16/33] drm/i915: Fix KBL HDCP2.2 encrypt status signalling Ramalingam C
` (21 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Implements the
Waitqueue is created to wait for CP_IRQ
Signaling the CP_IRQ arrival through atomic variable.
For applicable DP HDCP2.2 msgs read wait for CP_IRQ.
As per HDCP2.2 spec "HDCP Transmitters must process CP_IRQ interrupts
when they are received from HDCP Receivers"
Without CP_IRQ processing, DP HDCP2.2 H_Prime msg was getting corrupted
while reading it based on corresponding status bit. This creates the
random failures in reading the DP HDCP2.2 msgs.
v2:
CP_IRQ arrival is tracked based on the atomic val inc [daniel]
Recording the reviewed-by Daniel from IRC.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_dp.c | 31 +++++++++++++++++++++++--------
drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++
drivers/gpu/drm/i915/intel_hdcp.c | 11 ++++-------
3 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e9fe25f21200..e1a051c0fbfe 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5623,6 +5623,18 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
edp_panel_vdd_off_sync(intel_dp);
}
+static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
+{
+ long ret;
+
+#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
+ ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
+ msecs_to_jiffies(timeout));
+
+ if (!ret)
+ DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
+}
+
static
int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
u8 *an)
@@ -5967,14 +5979,13 @@ intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
mdelay(timeout);
ret = 0;
} else {
- /* TODO: In case if you need to wait on CP_IRQ, do it here */
- ret = __wait_for(ret =
- hdcp2_detect_msg_availability(intel_dig_port,
- msg_id,
- &msg_ready),
- !ret && msg_ready, timeout * 1000,
- 1000, 5 * 1000);
-
+ /*
+ * As we want to check the msg availability at timeout, Ignoring
+ * the timeout at wait for CP_IRQ.
+ */
+ intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
+ ret = hdcp2_detect_msg_availability(intel_dig_port,
+ msg_id, &msg_ready);
if (!msg_ready)
ret = -ETIMEDOUT;
}
@@ -6001,6 +6012,8 @@ static
int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
void *buf, size_t size)
{
+ struct intel_dp *dp = &intel_dig_port->dp;
+ struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
unsigned int offset;
u8 *byte = buf;
ssize_t ret, bytes_to_write, len;
@@ -6016,6 +6029,8 @@ int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
bytes_to_write = size - 1;
byte++;
+ hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
+
while (bytes_to_write) {
len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index dfedcc2b076c..1d1ef7f04f93 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -474,6 +474,14 @@ struct intel_hdcp {
* over re-Auth has to be triggered.
*/
u32 seq_num_m;
+
+ /*
+ * Work queue to signal the CP_IRQ. Used for the waiters to read the
+ * available information from HDCP DP sink.
+ */
+ wait_queue_head_t cp_irq_queue;
+ atomic_t cp_irq_count;
+ int cp_irq_count_cached;
};
struct intel_connector {
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index fe0445c0eaac..6178fe93f398 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1806,6 +1806,7 @@ int intel_hdcp_init(struct intel_connector *connector,
if (is_hdcp2_supported(dev_priv))
intel_hdcp2_init(connector);
+ init_waitqueue_head(&hdcp->cp_irq_queue);
return 0;
}
@@ -1935,12 +1936,8 @@ void intel_hdcp_handle_cp_irq(struct intel_connector *connector)
if (!hdcp->shim)
return;
- /*
- * CP_IRQ could be triggered due to 1. HDCP2.2 auth msgs availability,
- * 2. link failure and 3. repeater reauth request. At present we dont
- * handle the CP_IRQ for the HDCP2.2 auth msg availability for read.
- * To handle other two causes for CP_IRQ we have the work_fn which is
- * scheduled here.
- */
+ atomic_inc(&connector->hdcp.cp_irq_count);
+ wake_up_all(&connector->hdcp.cp_irq_queue);
+
schedule_delayed_work(&hdcp->check_work, 0);
}
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 16/33] drm/i915: Fix KBL HDCP2.2 encrypt status signalling
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (14 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 15/33] drm/i915: CP_IRQ handling for DP HDCP2.2 msgs Ramalingam C via dri-devel
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-20 19:49 ` Daniel Vetter
2019-02-16 17:37 ` [PATCH v14 17/33] mei: bus: whitelist hdcp client Ramalingam C
` (20 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
HDCP transmitter is supposed to indicate the HDCP encryption status of
the link through enc_en signals in a window of time called "window of
opportunity" defined by HDCP HDMI spec.
But on KBL this timing of signalling has an issue. To fix the issue this
WA of resetting the signalling is required.
v2:
WA is moved into the toggle_signalling [Daniel]
v3:
Commit msg is rewritten with more information
v4:
Reviewed-by Daniel.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_hdmi.c | 42 +++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 6a3e400f54d7..c2c91e6645a5 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1083,10 +1083,44 @@ int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
return ret;
}
+static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct drm_crtc *crtc = connector->base.state->crtc;
+ struct intel_crtc *intel_crtc = container_of(crtc,
+ struct intel_crtc, base);
+ u32 scanline;
+ int ret;
+
+ for (;;) {
+ scanline = I915_READ(PIPEDSL(intel_crtc->pipe));
+ if (scanline > 100 && scanline < 200)
+ break;
+ usleep_range(25, 50);
+ }
+
+ ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, false);
+ if (ret) {
+ DRM_ERROR("Disable HDCP signalling failed (%d)\n", ret);
+ return ret;
+ }
+ ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, true);
+ if (ret) {
+ DRM_ERROR("Enable HDCP signalling failed (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
static
int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
bool enable)
{
+ struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
+ struct intel_connector *connector = hdmi->attached_connector;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
int ret;
if (!enable)
@@ -1098,6 +1132,14 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
enable ? "Enable" : "Disable", ret);
return ret;
}
+
+ /*
+ * WA: To fix incorrect positioning of the window of
+ * opportunity and enc_en signalling in KABYLAKE.
+ */
+ if (IS_KABYLAKE(dev_priv) && enable)
+ return kbl_repositioning_enc_en_signal(connector);
+
return 0;
}
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 17/33] mei: bus: whitelist hdcp client
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (15 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 16/33] drm/i915: Fix KBL HDCP2.2 encrypt status signalling Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-16 17:37 ` [PATCH v14 18/33] mei: bus: export to_mei_cl_device for mei client device drivers Ramalingam C
` (19 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
From: Tomas Winkler <tomas.winkler@intel.com>
Whitelist HDCP client for in kernel drm use
v2:
Rebased.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
drivers/misc/mei/bus-fixup.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
index 80215c312f0e..5fcac02233af 100644
--- a/drivers/misc/mei/bus-fixup.c
+++ b/drivers/misc/mei/bus-fixup.c
@@ -40,6 +40,9 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
#define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \
0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb)
+#define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \
+ 0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04)
+
#define MEI_UUID_ANY NULL_UUID_LE
/**
@@ -71,6 +74,18 @@ static void blacklist(struct mei_cl_device *cldev)
cldev->do_match = 0;
}
+/**
+ * whitelist - forcefully whitelist client
+ *
+ * @cldev: me clients device
+ */
+static void whitelist(struct mei_cl_device *cldev)
+{
+ dev_dbg(&cldev->dev, "running hook %s\n", __func__);
+
+ cldev->do_match = 1;
+}
+
#define OSTYPE_LINUX 2
struct mei_os_ver {
__le16 build;
@@ -472,6 +487,7 @@ static struct mei_fixup {
MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
MEI_FIXUP(MEI_UUID_WD, mei_wd),
MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix),
+ MEI_FIXUP(MEI_UUID_HDCP, whitelist),
};
/**
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 18/33] mei: bus: export to_mei_cl_device for mei client device drivers
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (16 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 17/33] mei: bus: whitelist hdcp client Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-16 17:37 ` [PATCH v14 19/33] misc/mei/hdcp: Client driver for HDCP application Ramalingam C
` (18 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
From: Tomas Winkler <tomas.winkler@intel.com>
Export to_mei_cl_device macro, it is needed also in mei client drivers.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
drivers/misc/mei/bus.c | 1 -
include/linux/mei_cl_bus.h | 2 ++
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index fc3872fe7b25..e5456faf00e6 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -28,7 +28,6 @@
#include "client.h"
#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver)
-#define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)
/**
* __mei_cl_send - internal client send (write)
diff --git a/include/linux/mei_cl_bus.h b/include/linux/mei_cl_bus.h
index 7fde40e17c8b..03b6ba2a63f8 100644
--- a/include/linux/mei_cl_bus.h
+++ b/include/linux/mei_cl_bus.h
@@ -55,6 +55,8 @@ struct mei_cl_device {
void *priv_data;
};
+#define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev)
+
struct mei_cl_driver {
struct device_driver driver;
const char *name;
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 19/33] misc/mei/hdcp: Client driver for HDCP application
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (17 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 18/33] mei: bus: export to_mei_cl_device for mei client device drivers Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 13:55 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 20/33] misc/mei/hdcp: Define ME FW interface for HDCP2.2 Ramalingam C via dri-devel
` (17 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
ME FW contributes a vital role in HDCP2.2 authentication.
HDCP2.2 driver needs to communicate to ME FW for each step of the
HDCP2.2 authentication.
ME FW prepare and HDCP2.2 authentication parameters and encrypt them
as per spec. With such parameter Driver prepares HDCP2.2 auth messages
and communicate with HDCP2.2 sink.
Similarly HDCP2.2 sink's response is shared with ME FW for decrypt and
verification.
Once All the steps of HDCP2.2 authentications are complete on driver's
request ME FW will configure the port as authenticated and supply the
HDCP keys to the Gen HW for encryption.
Only after this stage HDCP2.2 driver can start the HDCP2.2 encryption
for a port.
ME FW is interfaced to kernel through MEI Bus Driver. To obtain the
HDCP2.2 services from the ME FW through MEI Bus driver MEI Client
Driver is developed.
v2:
hdcp files are moved to drivers/misc/mei/hdcp/ [Tomas]
v3:
Squashed the Kbuild support [Tomas]
UUID renamed and Module License is modified [Tomas]
drv_data is set to null at remove [Tomas]
v4:
Module name is changed to "MEI HDCP"
I915 Selects the MEI_HDCP
v5:
Remove redundant text from the License header
Fix malformed licence
Removed the drv_data resetting.
v6:
K-Doc addition. [Tomas]
v7:
%s/UUID_LE/GUID_INIT [Tomas]
GPL Ver is 2.0 than 2.0+ [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/Kconfig | 7 +++++
drivers/misc/mei/Makefile | 2 ++
drivers/misc/mei/hdcp/Makefile | 7 +++++
drivers/misc/mei/hdcp/mei_hdcp.c | 64 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 80 insertions(+)
create mode 100644 drivers/misc/mei/hdcp/Makefile
create mode 100644 drivers/misc/mei/hdcp/mei_hdcp.c
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index c49e1d2269af..64a7b3483895 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -43,3 +43,10 @@ config INTEL_MEI_TXE
Supported SoCs:
Intel Bay Trail
+
+config INTEL_MEI_HDCP
+ tristate "Intel HDCP2.2 services of ME Interface"
+ select INTEL_MEI_ME
+ depends on DRM_I915
+ help
+ MEI Support for HDCP2.2 Services on Intel platforms.
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index d9215fc4e499..8c2d9565a4cb 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -24,3 +24,5 @@ mei-txe-objs += hw-txe.o
mei-$(CONFIG_EVENT_TRACING) += mei-trace.o
CFLAGS_mei-trace.o = -I$(src)
+
+obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
diff --git a/drivers/misc/mei/hdcp/Makefile b/drivers/misc/mei/hdcp/Makefile
new file mode 100644
index 000000000000..e27d10754dbf
--- /dev/null
+++ b/drivers/misc/mei/hdcp/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2017-2018, Intel Corporation.
+#
+# Makefile - HDCP client driver for Intel MEI Bus Driver.
+
+obj-$(CONFIG_INTEL_MEI_HDCP) += mei_hdcp.o
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
new file mode 100644
index 000000000000..8df069c1b0cc
--- /dev/null
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0)
+/*
+ * Copyright © 2017-2018 Intel Corporation
+ *
+ * Mei_hdcp.c: HDCP client driver for mei bus
+ *
+ * Author:
+ * Ramalingam C <ramalingam.c@intel.com>
+ */
+
+/**
+ * DOC: MEI_HDCP Client Driver
+ *
+ * This is a client driver to the mei_bus to make the HDCP2.2 services of
+ * ME FW available for the interested consumers like I915.
+ *
+ * This module will act as a translation layer between HDCP protocol
+ * implementor(I915) and ME FW by translating HDCP2.2 authentication
+ * messages to ME FW command payloads and vice versa.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uuid.h>
+#include <linux/mei_cl_bus.h>
+
+static int mei_hdcp_probe(struct mei_cl_device *cldev,
+ const struct mei_cl_device_id *id)
+{
+ int ret;
+
+ ret = mei_cldev_enable(cldev);
+ if (ret < 0)
+ dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+
+ return ret;
+}
+
+static int mei_hdcp_remove(struct mei_cl_device *cldev)
+{
+ return mei_cldev_disable(cldev);
+}
+
+#define MEI_UUID_HDCP GUID_INIT(0xB638AB7E, 0x94E2, 0x4EA2, 0xA5, \
+ 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04)
+
+static struct mei_cl_device_id mei_hdcp_tbl[] = {
+ { .uuid = MEI_UUID_HDCP, .version = MEI_CL_VERSION_ANY },
+ { }
+};
+MODULE_DEVICE_TABLE(mei, mei_hdcp_tbl);
+
+static struct mei_cl_driver mei_hdcp_driver = {
+ .id_table = mei_hdcp_tbl,
+ .name = KBUILD_MODNAME,
+ .probe = mei_hdcp_probe,
+ .remove = mei_hdcp_remove,
+};
+
+module_mei_cl_driver(mei_hdcp_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MEI HDCP");
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 20/33] misc/mei/hdcp: Define ME FW interface for HDCP2.2
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (18 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 19/33] misc/mei/hdcp: Client driver for HDCP application Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C via dri-devel
2019-02-21 12:42 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 21/33] misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session Ramalingam C
` (16 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Defines the HDCP specific ME FW interfaces such as Request CMDs,
payload structure for CMDs and their response status codes.
This patch defines payload size(Excluding the Header)for each WIRED
HDCP2.2 CMDs.
v2: Rebased.
v3:
Extra comments are removed.
v4:
%s/\/\*\*/\/\*
v5:
Extra lines are removed.
v6:
Remove redundant text from the License header
%s/LPRIME_HALF/V_PRIME_HALF
%s/uintxx_t/uxx
v7:
Extra taps removed.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Acked-by Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.h | 366 +++++++++++++++++++++++++++++++++++++++
1 file changed, 366 insertions(+)
create mode 100644 drivers/misc/mei/hdcp/mei_hdcp.h
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.h b/drivers/misc/mei/hdcp/mei_hdcp.h
new file mode 100644
index 000000000000..582a7e27ae29
--- /dev/null
+++ b/drivers/misc/mei/hdcp/mei_hdcp.h
@@ -0,0 +1,366 @@
+/* SPDX-License-Identifier: (GPL-2.0+) */
+/*
+ * Copyright © 2017-2018 Intel Corporation
+ *
+ * Authors:
+ * Ramalingam C <ramalingam.c@intel.com>
+ */
+
+#ifndef __MEI_HDCP_H__
+#define __MEI_HDCP_H__
+
+#include <drm/drm_hdcp.h>
+
+/* me_hdcp_status: Enumeration of all HDCP Status Codes */
+enum me_hdcp_status {
+ ME_HDCP_STATUS_SUCCESS = 0x0000,
+
+ /* WiDi Generic Status Codes */
+ ME_HDCP_STATUS_INTERNAL_ERROR = 0x1000,
+ ME_HDCP_STATUS_UNKNOWN_ERROR = 0x1001,
+ ME_HDCP_STATUS_INCORRECT_API_VERSION = 0x1002,
+ ME_HDCP_STATUS_INVALID_FUNCTION = 0x1003,
+ ME_HDCP_STATUS_INVALID_BUFFER_LENGTH = 0x1004,
+ ME_HDCP_STATUS_INVALID_PARAMS = 0x1005,
+ ME_HDCP_STATUS_AUTHENTICATION_FAILED = 0x1006,
+
+ /* WiDi Status Codes */
+ ME_HDCP_INVALID_SESSION_STATE = 0x6000,
+ ME_HDCP_SRM_FRAGMENT_UNEXPECTED = 0x6001,
+ ME_HDCP_SRM_INVALID_LENGTH = 0x6002,
+ ME_HDCP_SRM_FRAGMENT_OFFSET_INVALID = 0x6003,
+ ME_HDCP_SRM_VERIFICATION_FAILED = 0x6004,
+ ME_HDCP_SRM_VERSION_TOO_OLD = 0x6005,
+ ME_HDCP_RX_CERT_VERIFICATION_FAILED = 0x6006,
+ ME_HDCP_RX_REVOKED = 0x6007,
+ ME_HDCP_H_VERIFICATION_FAILED = 0x6008,
+ ME_HDCP_REPEATER_CHECK_UNEXPECTED = 0x6009,
+ ME_HDCP_TOPOLOGY_MAX_EXCEEDED = 0x600A,
+ ME_HDCP_V_VERIFICATION_FAILED = 0x600B,
+ ME_HDCP_L_VERIFICATION_FAILED = 0x600C,
+ ME_HDCP_STREAM_KEY_ALLOC_FAILED = 0x600D,
+ ME_HDCP_BASE_KEY_RESET_FAILED = 0x600E,
+ ME_HDCP_NONCE_GENERATION_FAILED = 0x600F,
+ ME_HDCP_STATUS_INVALID_E_KEY_STATE = 0x6010,
+ ME_HDCP_STATUS_INVALID_CS_ICV = 0x6011,
+ ME_HDCP_STATUS_INVALID_KB_KEY_STATE = 0x6012,
+ ME_HDCP_STATUS_INVALID_PAVP_MODE_ICV = 0x6013,
+ ME_HDCP_STATUS_INVALID_PAVP_MODE = 0x6014,
+ ME_HDCP_STATUS_LC_MAX_ATTEMPTS = 0x6015,
+
+ /* New status for HDCP 2.1 */
+ ME_HDCP_STATUS_MISMATCH_IN_M = 0x6016,
+
+ /* New status code for HDCP 2.2 Rx */
+ ME_HDCP_STATUS_RX_PROV_NOT_ALLOWED = 0x6017,
+ ME_HDCP_STATUS_RX_PROV_WRONG_SUBJECT = 0x6018,
+ ME_HDCP_RX_NEEDS_PROVISIONING = 0x6019,
+ ME_HDCP_BKSV_ICV_AUTH_FAILED = 0x6020,
+ ME_HDCP_STATUS_INVALID_STREAM_ID = 0x6021,
+ ME_HDCP_STATUS_CHAIN_NOT_INITIALIZED = 0x6022,
+ ME_HDCP_FAIL_NOT_EXPECTED = 0x6023,
+ ME_HDCP_FAIL_HDCP_OFF = 0x6024,
+ ME_HDCP_FAIL_INVALID_PAVP_MEMORY_MODE = 0x6025,
+ ME_HDCP_FAIL_AES_ECB_FAILURE = 0x6026,
+ ME_HDCP_FEATURE_NOT_SUPPORTED = 0x6027,
+ ME_HDCP_DMA_READ_ERROR = 0x6028,
+ ME_HDCP_DMA_WRITE_ERROR = 0x6029,
+ ME_HDCP_FAIL_INVALID_PACKET_SIZE = 0x6030,
+ ME_HDCP_H264_PARSING_ERROR = 0x6031,
+ ME_HDCP_HDCP2_ERRATA_VIDEO_VIOLATION = 0x6032,
+ ME_HDCP_HDCP2_ERRATA_AUDIO_VIOLATION = 0x6033,
+ ME_HDCP_TX_ACTIVE_ERROR = 0x6034,
+ ME_HDCP_MODE_CHANGE_ERROR = 0x6035,
+ ME_HDCP_STREAM_TYPE_ERROR = 0x6036,
+ ME_HDCP_STREAM_MANAGE_NOT_POSSIBLE = 0x6037,
+
+ ME_HDCP_STATUS_PORT_INVALID_COMMAND = 0x6038,
+ ME_HDCP_STATUS_UNSUPPORTED_PROTOCOL = 0x6039,
+ ME_HDCP_STATUS_INVALID_PORT_INDEX = 0x603a,
+ ME_HDCP_STATUS_TX_AUTH_NEEDED = 0x603b,
+ ME_HDCP_STATUS_NOT_INTEGRATED_PORT = 0x603c,
+ ME_HDCP_STATUS_SESSION_MAX_REACHED = 0x603d,
+
+ /* hdcp capable bit is not set in rx_caps(error is unique to DP) */
+ ME_HDCP_STATUS_NOT_HDCP_CAPABLE = 0x6041,
+
+ ME_HDCP_STATUS_INVALID_STREAM_COUNT = 0x6042,
+};
+
+#define HDCP_API_VERSION 0x00010000
+
+#define HDCP_M_LEN 16
+#define HDCP_KH_LEN 16
+
+/* Payload Buffer size(Excluding Header) for CMDs and corresponding response */
+/* Wired_Tx_AKE */
+#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN (4 + 1)
+#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_OUT (4 + 8 + 3)
+
+#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN (4 + 522 + 8 + 3)
+#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MIN_OUT (4 + 1 + 3 + 16 + 16)
+#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MAX_OUT (4 + 1 + 3 + 128)
+
+#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN (4 + 32)
+#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_OUT (4)
+
+#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN (4 + 16)
+#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_OUT (4)
+
+#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN (4)
+#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_OUT (4)
+
+/* Wired_Tx_LC */
+#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN (4)
+#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_OUT (4 + 8)
+
+#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN (4 + 32)
+#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_OUT (4)
+
+/* Wired_Tx_SKE */
+#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN (4)
+#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_OUT (4 + 16 + 8)
+
+/* Wired_Tx_SKE */
+#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN (4 + 1)
+#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_OUT (4)
+
+/* Wired_Tx_Repeater */
+#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN (4 + 2 + 3 + 16 + 155)
+#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_OUT (4 + 1 + 16)
+
+#define WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN (4 + 3 + \
+ 32 + 2 + 2)
+
+#define WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_OUT (4)
+
+/* hdcp_command_id: Enumeration of all WIRED HDCP Command IDs */
+enum hdcp_command_id {
+ _WIDI_COMMAND_BASE = 0x00030000,
+ WIDI_INITIATE_HDCP2_SESSION = _WIDI_COMMAND_BASE,
+ HDCP_GET_SRM_STATUS,
+ HDCP_SEND_SRM_FRAGMENT,
+
+ /* The wired HDCP Tx commands */
+ _WIRED_COMMAND_BASE = 0x00031000,
+ WIRED_INITIATE_HDCP2_SESSION = _WIRED_COMMAND_BASE,
+ WIRED_VERIFY_RECEIVER_CERT,
+ WIRED_AKE_SEND_HPRIME,
+ WIRED_AKE_SEND_PAIRING_INFO,
+ WIRED_INIT_LOCALITY_CHECK,
+ WIRED_VALIDATE_LOCALITY,
+ WIRED_GET_SESSION_KEY,
+ WIRED_ENABLE_AUTH,
+ WIRED_VERIFY_REPEATER,
+ WIRED_REPEATER_AUTH_STREAM_REQ,
+ WIRED_CLOSE_SESSION,
+
+ _WIRED_COMMANDS_COUNT,
+};
+
+union encrypted_buff {
+ u8 e_kpub_km[HDCP_2_2_E_KPUB_KM_LEN];
+ u8 e_kh_km_m[HDCP_2_2_E_KH_KM_M_LEN];
+ struct {
+ u8 e_kh_km[HDCP_KH_LEN];
+ u8 m[HDCP_M_LEN];
+ } __packed;
+};
+
+/* HDCP HECI message header. All header values are little endian. */
+struct hdcp_cmd_header {
+ u32 api_version;
+ u32 command_id;
+ enum me_hdcp_status status;
+ /* Length of the HECI message (excluding the header) */
+ u32 buffer_len;
+} __packed;
+
+/* Empty command request or response. No data follows the header. */
+struct hdcp_cmd_no_data {
+ struct hdcp_cmd_header header;
+} __packed;
+
+/* Uniquely identifies the hdcp port being addressed for a given command. */
+struct hdcp_port_id {
+ u8 integrated_port_type;
+ u8 physical_port;
+ u16 reserved;
+} __packed;
+
+/*
+ * Data structures for integrated wired HDCP2 Tx in
+ * support of the AKE protocol
+ */
+/* HECI struct for integrated wired HDCP Tx session initiation. */
+struct wired_cmd_initiate_hdcp2_session_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 protocol; /* for HDMI vs DP */
+} __packed;
+
+struct wired_cmd_initiate_hdcp2_session_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 r_tx[HDCP_2_2_RTX_LEN];
+ struct hdcp2_tx_caps tx_caps;
+} __packed;
+
+/* HECI struct for ending an integrated wired HDCP Tx session. */
+struct wired_cmd_close_session_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+struct wired_cmd_close_session_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+/* HECI struct for integrated wired HDCP Tx Rx Cert verification. */
+struct wired_cmd_verify_receiver_cert_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ struct hdcp2_cert_rx cert_rx;
+ u8 r_rx[HDCP_2_2_RRX_LEN];
+ u8 rx_caps[HDCP_2_2_RXCAPS_LEN];
+} __packed;
+
+struct wired_cmd_verify_receiver_cert_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 km_stored;
+ u8 reserved[3];
+ union encrypted_buff ekm_buff;
+} __packed;
+
+/* HECI struct for verification of Rx's Hprime in a HDCP Tx session */
+struct wired_cmd_ake_send_hprime_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 h_prime[HDCP_2_2_H_PRIME_LEN];
+} __packed;
+
+struct wired_cmd_ake_send_hprime_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+/*
+ * HECI struct for sending in AKE pairing data generated by the Rx in an
+ * integrated wired HDCP Tx session.
+ */
+struct wired_cmd_ake_send_pairing_info_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 e_kh_km[HDCP_2_2_E_KH_KM_LEN];
+} __packed;
+
+struct wired_cmd_ake_send_pairing_info_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+/* Data structures for integrated wired HDCP2 Tx in support of the LC protocol*/
+/*
+ * HECI struct for initiating locality check with an
+ * integrated wired HDCP Tx session.
+ */
+struct wired_cmd_init_locality_check_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+struct wired_cmd_init_locality_check_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 r_n[HDCP_2_2_RN_LEN];
+} __packed;
+
+/*
+ * HECI struct for validating an Rx's LPrime value in an
+ * integrated wired HDCP Tx session.
+ */
+struct wired_cmd_validate_locality_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 l_prime[HDCP_2_2_L_PRIME_LEN];
+} __packed;
+
+struct wired_cmd_validate_locality_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+/*
+ * Data structures for integrated wired HDCP2 Tx in support of the
+ * SKE protocol
+ */
+/* HECI struct for creating session key */
+struct wired_cmd_get_session_key_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+struct wired_cmd_get_session_key_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 e_dkey_ks[HDCP_2_2_E_DKEY_KS_LEN];
+ u8 r_iv[HDCP_2_2_RIV_LEN];
+} __packed;
+
+/* HECI struct for the Tx enable authentication command */
+struct wired_cmd_enable_auth_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 stream_type;
+} __packed;
+
+struct wired_cmd_enable_auth_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+/*
+ * Data structures for integrated wired HDCP2 Tx in support of
+ * the repeater protocols
+ */
+/*
+ * HECI struct for verifying the downstream repeater's HDCP topology in an
+ * integrated wired HDCP Tx session.
+ */
+struct wired_cmd_verify_repeater_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 rx_info[HDCP_2_2_RXINFO_LEN];
+ u8 seq_num_v[HDCP_2_2_SEQ_NUM_LEN];
+ u8 v_prime[HDCP_2_2_V_PRIME_HALF_LEN];
+ u8 receiver_ids[HDCP_2_2_RECEIVER_IDS_MAX_LEN];
+} __packed;
+
+struct wired_cmd_verify_repeater_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 content_type_supported;
+ u8 v[HDCP_2_2_V_PRIME_HALF_LEN];
+} __packed;
+
+/*
+ * HECI struct in support of stream management in an
+ * integrated wired HDCP Tx session.
+ */
+struct wired_cmd_repeater_auth_stream_req_in {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+ u8 seq_num_m[HDCP_2_2_SEQ_NUM_LEN];
+ u8 m_prime[HDCP_2_2_MPRIME_LEN];
+ u16 k;
+ struct hdcp2_streamid_type streams[1];
+} __packed;
+
+struct wired_cmd_repeater_auth_stream_req_out {
+ struct hdcp_cmd_header header;
+ struct hdcp_port_id port;
+} __packed;
+
+#endif /* __MEI_HDCP_H__ */
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 21/33] misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (19 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 20/33] misc/mei/hdcp: Define ME FW interface for HDCP2.2 Ramalingam C via dri-devel
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 13:30 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 22/33] misc/mei/hdcp: Verify Receiver Cert and prepare km Ramalingam C
` (15 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Request ME FW to start the HDCP2.2 session for an intel port.
Prepares payloads for command WIRED_INITIATE_HDCP2_SESSION and sends
to ME FW.
On Success, ME FW will start a HDCP2.2 session for the port and
provides the content for HDCP2.2 AKE_Init message.
v2: Rebased.
v3:
cldev is add as a separate parameter [Tomas]
Redundant comment and typecast are removed [Tomas]
v4:
%zd is used for size [Alexander]
%s/return -1/return -EIO [Alexander]
Spellings in commit msg is fixed [Uma]
v5: Rebased.
v6:
Collected the rb-ed by.
Realigning the patches in the series.
v7:
Adjust to the new mei interface.
Fix for kdoc.
v8:
K-Doc Addition.
memcpy for const length.
v9:
s/mei_hdcp_ddi/mei_fw_ddi
s/i915_port/mei_i915_port [Tomas]
renamed func as mei_hdcp_* [Tomas]
Instead of macro, inline func for ddi index is used. [Tomas]
v10:
Switch case for the coversion between i915_port to mei_ddi [Tomas]
Kernel doc fix.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 94 ++++++++++++++++++++++++++++++++++++++++
drivers/misc/mei/hdcp/mei_hdcp.h | 11 +++++
2 files changed, 105 insertions(+)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 8df069c1b0cc..952bae79dd02 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -23,6 +23,100 @@
#include <linux/slab.h>
#include <linux/uuid.h>
#include <linux/mei_cl_bus.h>
+#include <drm/drm_connector.h>
+#include <drm/i915_component.h>
+#include <drm/i915_mei_hdcp_interface.h>
+
+#include "mei_hdcp.h"
+
+static inline u8 mei_get_ddi_index(enum port port)
+{
+ switch (port) {
+ case PORT_A:
+ return MEI_DDI_A;
+ case PORT_B ... PORT_F:
+ return (u8)port;
+ default:
+ return MEI_DDI_INVALID_PORT;
+ }
+}
+
+/**
+ * mei_hdcp_initiate_session() - Initiate a Wired HDCP2.2 Tx Session in ME FW
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @ake_data: AKE_Init msg output.
+ *
+ * Return: 0 on Success, <0 on Failure.
+ */
+static int
+mei_hdcp_initiate_session(struct device *dev, struct hdcp_port_data *data,
+ struct hdcp2_ake_init *ake_data)
+{
+ struct wired_cmd_initiate_hdcp2_session_in session_init_in = { { 0 } };
+ struct wired_cmd_initiate_hdcp2_session_out
+ session_init_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !ake_data)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ session_init_in.header.api_version = HDCP_API_VERSION;
+ session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION;
+ session_init_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ session_init_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN;
+
+ session_init_in.port.integrated_port_type = data->port_type;
+ session_init_in.port.physical_port = mei_get_ddi_index(data->port);
+ session_init_in.protocol = data->protocol;
+
+ byte = mei_cldev_send(cldev, (u8 *)&session_init_in,
+ sizeof(session_init_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&session_init_out,
+ sizeof(session_init_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (session_init_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
+ WIRED_INITIATE_HDCP2_SESSION,
+ session_init_out.header.status);
+ return -EIO;
+ }
+
+ ake_data->msg_id = HDCP_2_2_AKE_INIT;
+ ake_data->tx_caps = session_init_out.tx_caps;
+ memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN);
+
+ return 0;
+}
+
+static __attribute__((unused))
+struct i915_hdcp_component_ops mei_hdcp_ops = {
+ .owner = THIS_MODULE,
+ .initiate_hdcp2_session = mei_hdcp_initiate_session,
+ .verify_receiver_cert_prepare_km = NULL,
+ .verify_hprime = NULL,
+ .store_pairing_info = NULL,
+ .initiate_locality_check = NULL,
+ .verify_lprime = NULL,
+ .get_session_key = NULL,
+ .repeater_check_flow_prepare_ack = NULL,
+ .verify_mprime = NULL,
+ .enable_hdcp_authentication = NULL,
+ .close_hdcp_session = NULL,
+};
static int mei_hdcp_probe(struct mei_cl_device *cldev,
const struct mei_cl_device_id *id)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.h b/drivers/misc/mei/hdcp/mei_hdcp.h
index 582a7e27ae29..1eca72a9c1c2 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.h
+++ b/drivers/misc/mei/hdcp/mei_hdcp.h
@@ -363,4 +363,15 @@ struct wired_cmd_repeater_auth_stream_req_out {
struct hdcp_port_id port;
} __packed;
+enum mei_fw_ddi {
+ MEI_DDI_INVALID_PORT = 0x0,
+
+ MEI_DDI_B = 1,
+ MEI_DDI_C,
+ MEI_DDI_D,
+ MEI_DDI_E,
+ MEI_DDI_F,
+ MEI_DDI_A = 7,
+ MEI_DDI_RANGE_END = MEI_DDI_A,
+};
#endif /* __MEI_HDCP_H__ */
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 22/33] misc/mei/hdcp: Verify Receiver Cert and prepare km
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (20 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 21/33] misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 13:39 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime Ramalingam C
` (14 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Requests for verification for receiver certification and also the
preparation for next AKE auth message with km.
On Success ME FW validate the HDCP2.2 receivers certificate and do the
revocation check on the receiver ID. AKE_Stored_Km will be prepared if
the receiver is already paired, else AKE_No_Stored_Km will be prepared.
Here AKE_Stored_Km and AKE_No_Stored_Km are HDCP2.2 protocol msgs.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd is used for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc Addition. [Tomas]
memcpy for const length.
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
Fixed the conversion of u8 to bool [Tomas]
K-Doc fix [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 83 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 82 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 952bae79dd02..922c6a76bb9f 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -102,11 +102,92 @@ mei_hdcp_initiate_session(struct device *dev, struct hdcp_port_data *data,
return 0;
}
+/**
+ * mei_hdcp_verify_receiver_cert_prepare_km() - Verify the Receiver Certificate
+ * AKE_Send_Cert and prepare AKE_Stored_Km/AKE_No_Stored_Km
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @rx_cert: AKE_Send_Cert for verification
+ * @km_stored: Pairing status flag output
+ * @ek_pub_km: AKE_Stored_Km/AKE_No_Stored_Km output msg
+ * @msg_sz : size of AKE_XXXXX_Km output msg
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_verify_receiver_cert_prepare_km(struct device *dev,
+ struct hdcp_port_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)
+{
+ struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = { { 0 } };
+ struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ verify_rxcert_in.header.api_version = HDCP_API_VERSION;
+ verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT;
+ verify_rxcert_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ verify_rxcert_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN;
+
+ verify_rxcert_in.port.integrated_port_type = data->port_type;
+ verify_rxcert_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ verify_rxcert_in.cert_rx = rx_cert->cert_rx;
+ memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN);
+ memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN);
+
+ byte = mei_cldev_send(cldev, (u8 *)&verify_rxcert_in,
+ sizeof(verify_rxcert_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed: %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&verify_rxcert_out,
+ sizeof(verify_rxcert_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed: %zd\n", byte);
+ return byte;
+ }
+
+ if (verify_rxcert_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
+ WIRED_VERIFY_RECEIVER_CERT,
+ verify_rxcert_out.header.status);
+ return -EIO;
+ }
+
+ *km_stored = !!verify_rxcert_out.km_stored;
+ if (verify_rxcert_out.km_stored) {
+ ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM;
+ *msg_sz = sizeof(struct hdcp2_ake_stored_km);
+ } else {
+ ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM;
+ *msg_sz = sizeof(struct hdcp2_ake_no_stored_km);
+ }
+
+ memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff,
+ sizeof(verify_rxcert_out.ekm_buff));
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
.initiate_hdcp2_session = mei_hdcp_initiate_session,
- .verify_receiver_cert_prepare_km = NULL,
+ .verify_receiver_cert_prepare_km =
+ mei_hdcp_verify_receiver_cert_prepare_km,
.verify_hprime = NULL,
.store_pairing_info = NULL,
.initiate_locality_check = NULL,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (21 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 22/33] misc/mei/hdcp: Verify Receiver Cert and prepare km Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 13:32 ` Winkler, Tomas
2019-02-21 13:33 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 24/33] misc/mei/hdcp: Store the HDCP Pairing info Ramalingam C
` (13 subsequent siblings)
36 siblings, 2 replies; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Requests for the verification of AKE_Send_H_prime.
ME will calculate the H and comparing it with received H_Prime.
The result will be returned as status.
Here AKE_Send_H_prime is a HDCP2.2 Authentication msg.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Styles and typos fixed [Uma]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc Addition [Tomas]
memcpy for const length.
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 58 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 922c6a76bb9f..0a4087a2efd5 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -182,13 +182,69 @@ mei_hdcp_verify_receiver_cert_prepare_km(struct device *dev,
return 0;
}
+/**
+ * mei_hdcp_verify_hprime() - Verify AKE_Send_H_prime at ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @rx_hprime: AKE_Send_H_prime msg for ME FW verification
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_verify_hprime(struct device *dev, struct hdcp_port_data *data,
+ struct hdcp2_ake_send_hprime *rx_hprime)
+{
+ struct wired_cmd_ake_send_hprime_in send_hprime_in = { { 0 } };
+ struct wired_cmd_ake_send_hprime_out send_hprime_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !rx_hprime)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ send_hprime_in.header.api_version = HDCP_API_VERSION;
+ send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME;
+ send_hprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ send_hprime_in.header.buffer_len = WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN;
+
+ send_hprime_in.port.integrated_port_type = data->port_type;
+ send_hprime_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ memcpy(send_hprime_in.h_prime, rx_hprime->h_prime,
+ HDCP_2_2_H_PRIME_LEN);
+
+ byte = mei_cldev_send(cldev, (u8 *)&send_hprime_in,
+ sizeof(send_hprime_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&send_hprime_out,
+ sizeof(send_hprime_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (send_hprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
+ WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
.initiate_hdcp2_session = mei_hdcp_initiate_session,
.verify_receiver_cert_prepare_km =
mei_hdcp_verify_receiver_cert_prepare_km,
- .verify_hprime = NULL,
+ .verify_hprime = mei_hdcp_verify_hprime,
.store_pairing_info = NULL,
.initiate_locality_check = NULL,
.verify_lprime = NULL,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 24/33] misc/mei/hdcp: Store the HDCP Pairing info
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (22 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 13:46 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 25/33] misc/mei/hdcp: Initiate Locality check Ramalingam C
` (12 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Provides Pairing info to ME to store.
Pairing is a process to fast track the subsequent authentication
with the same HDCP sink.
On Success, received HDCP pairing info is stored in non-volatile
memory of ME.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Style fixed [Uma]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition. [Tomas]
memcpy for const length.
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 60 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 0a4087a2efd5..1f5514244716 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -238,6 +238,64 @@ mei_hdcp_verify_hprime(struct device *dev, struct hdcp_port_data *data,
return 0;
}
+/**
+ * mei_hdcp_store_pairing_info() - Store pairing info received at ME FW
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @pairing_info: AKE_Send_Pairing_Info msg input to ME FW
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_store_pairing_info(struct device *dev, struct hdcp_port_data *data,
+ struct hdcp2_ake_send_pairing_info *pairing_info)
+{
+ struct wired_cmd_ake_send_pairing_info_in pairing_info_in = { { 0 } };
+ struct wired_cmd_ake_send_pairing_info_out pairing_info_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !pairing_info)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ pairing_info_in.header.api_version = HDCP_API_VERSION;
+ pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO;
+ pairing_info_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ pairing_info_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN;
+
+ pairing_info_in.port.integrated_port_type = data->port_type;
+ pairing_info_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km,
+ HDCP_2_2_E_KH_KM_LEN);
+
+ byte = mei_cldev_send(cldev, (u8 *)&pairing_info_in,
+ sizeof(pairing_info_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&pairing_info_out,
+ sizeof(pairing_info_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (pairing_info_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X failed. Status: 0x%X\n",
+ WIRED_AKE_SEND_PAIRING_INFO,
+ pairing_info_out.header.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -245,7 +303,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
.verify_receiver_cert_prepare_km =
mei_hdcp_verify_receiver_cert_prepare_km,
.verify_hprime = mei_hdcp_verify_hprime,
- .store_pairing_info = NULL,
+ .store_pairing_info = mei_hdcp_store_pairing_info,
.initiate_locality_check = NULL,
.verify_lprime = NULL,
.get_session_key = NULL,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 25/33] misc/mei/hdcp: Initiate Locality check
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (23 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 24/33] misc/mei/hdcp: Store the HDCP Pairing info Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 13:40 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 26/33] misc/mei/hdcp: Verify L_prime Ramalingam C
` (11 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Requests ME to start the second stage of HDCP2.2 authentication,
called Locality Check.
On Success, ME FW will provide LC_Init message to send to hdcp sink.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd used for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Style fixed [Uma]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition. [Tomas]
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 57 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 1f5514244716..29ef61fd21d2 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -296,6 +296,61 @@ mei_hdcp_store_pairing_info(struct device *dev, struct hdcp_port_data *data,
return 0;
}
+/**
+ * mei_hdcp_initiate_locality_check() - Prepare LC_Init
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @lc_init_data: LC_Init msg output
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_initiate_locality_check(struct device *dev,
+ struct hdcp_port_data *data,
+ struct hdcp2_lc_init *lc_init_data)
+{
+ struct wired_cmd_init_locality_check_in lc_init_in = { { 0 } };
+ struct wired_cmd_init_locality_check_out lc_init_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !lc_init_data)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ lc_init_in.header.api_version = HDCP_API_VERSION;
+ lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK;
+ lc_init_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ lc_init_in.header.buffer_len = WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN;
+
+ lc_init_in.port.integrated_port_type = data->port_type;
+ lc_init_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ byte = mei_cldev_send(cldev, (u8 *)&lc_init_in, sizeof(lc_init_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&lc_init_out, sizeof(lc_init_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (lc_init_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X Failed. status: 0x%X\n",
+ WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status);
+ return -EIO;
+ }
+
+ lc_init_data->msg_id = HDCP_2_2_LC_INIT;
+ memcpy(lc_init_data->r_n, lc_init_out.r_n, HDCP_2_2_RN_LEN);
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -304,7 +359,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
mei_hdcp_verify_receiver_cert_prepare_km,
.verify_hprime = mei_hdcp_verify_hprime,
.store_pairing_info = mei_hdcp_store_pairing_info,
- .initiate_locality_check = NULL,
+ .initiate_locality_check = mei_hdcp_initiate_locality_check,
.verify_lprime = NULL,
.get_session_key = NULL,
.repeater_check_flow_prepare_ack = NULL,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 26/33] misc/mei/hdcp: Verify L_prime
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (24 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 25/33] misc/mei/hdcp: Initiate Locality check Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 13:42 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 27/33] misc/mei/hdcp: Prepare Session Key Ramalingam C
` (10 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Request to ME to verify the LPrime received from HDCP sink.
On Success, ME FW will verify the received Lprime by calculating and
comparing with L.
This represents the completion of Locality Check.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Style fixed [Uma]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition. [Tomas]
memcpy for const length.
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 60 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 29ef61fd21d2..869a6f22f68d 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -351,6 +351,64 @@ mei_hdcp_initiate_locality_check(struct device *dev,
return 0;
}
+/**
+ * mei_hdcp_verify_lprime() - Verify lprime.
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @rx_lprime: LC_Send_L_prime msg for ME FW verification
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_verify_lprime(struct device *dev, struct hdcp_port_data *data,
+ struct hdcp2_lc_send_lprime *rx_lprime)
+{
+ struct wired_cmd_validate_locality_in verify_lprime_in = { { 0 } };
+ struct wired_cmd_validate_locality_out verify_lprime_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !rx_lprime)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ verify_lprime_in.header.api_version = HDCP_API_VERSION;
+ verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY;
+ verify_lprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ verify_lprime_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN;
+
+ verify_lprime_in.port.integrated_port_type = data->port_type;
+ verify_lprime_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime,
+ HDCP_2_2_L_PRIME_LEN);
+
+ byte = mei_cldev_send(cldev, (u8 *)&verify_lprime_in,
+ sizeof(verify_lprime_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&verify_lprime_out,
+ sizeof(verify_lprime_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (verify_lprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+ WIRED_VALIDATE_LOCALITY,
+ verify_lprime_out.header.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -360,7 +418,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
.verify_hprime = mei_hdcp_verify_hprime,
.store_pairing_info = mei_hdcp_store_pairing_info,
.initiate_locality_check = mei_hdcp_initiate_locality_check,
- .verify_lprime = NULL,
+ .verify_lprime = mei_hdcp_verify_lprime,
.get_session_key = NULL,
.repeater_check_flow_prepare_ack = NULL,
.verify_mprime = NULL,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 27/33] misc/mei/hdcp: Prepare Session Key
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (25 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 26/33] misc/mei/hdcp: Verify L_prime Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 14:24 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 28/33] misc/mei/hdcp: Repeater topology verification and ack Ramalingam C via dri-devel
` (9 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Request to ME to prepare the encrypted session key.
On Success, ME provides Encrypted session key. Function populates
the HDCP2.2 authentication msg SKE_Send_Eks.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Style fixed [Uma]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition. [Tomas]
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 59 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 869a6f22f68d..fe5070f901e8 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -409,6 +409,63 @@ mei_hdcp_verify_lprime(struct device *dev, struct hdcp_port_data *data,
return 0;
}
+/**
+ * mei_hdcp_get_session_key() - Prepare SKE_Send_Eks.
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @ske_data: SKE_Send_Eks msg output from ME FW.
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int mei_hdcp_get_session_key(struct device *dev,
+ struct hdcp_port_data *data,
+ struct hdcp2_ske_send_eks *ske_data)
+{
+ struct wired_cmd_get_session_key_in get_skey_in = { { 0 } };
+ struct wired_cmd_get_session_key_out get_skey_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !ske_data)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ get_skey_in.header.api_version = HDCP_API_VERSION;
+ get_skey_in.header.command_id = WIRED_GET_SESSION_KEY;
+ get_skey_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ get_skey_in.header.buffer_len = WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN;
+
+ get_skey_in.port.integrated_port_type = data->port_type;
+ get_skey_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ byte = mei_cldev_send(cldev, (u8 *)&get_skey_in, sizeof(get_skey_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&get_skey_out, sizeof(get_skey_out));
+
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (get_skey_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+ WIRED_GET_SESSION_KEY, get_skey_out.header.status);
+ return -EIO;
+ }
+
+ ske_data->msg_id = HDCP_2_2_SKE_SEND_EKS;
+ memcpy(ske_data->e_dkey_ks, get_skey_out.e_dkey_ks,
+ HDCP_2_2_E_DKEY_KS_LEN);
+ memcpy(ske_data->riv, get_skey_out.r_iv, HDCP_2_2_RIV_LEN);
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -419,7 +476,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
.store_pairing_info = mei_hdcp_store_pairing_info,
.initiate_locality_check = mei_hdcp_initiate_locality_check,
.verify_lprime = mei_hdcp_verify_lprime,
- .get_session_key = NULL,
+ .get_session_key = mei_hdcp_get_session_key,
.repeater_check_flow_prepare_ack = NULL,
.verify_mprime = NULL,
.enable_hdcp_authentication = NULL,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 28/33] misc/mei/hdcp: Repeater topology verification and ack
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (26 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 27/33] misc/mei/hdcp: Prepare Session Key Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C via dri-devel
2019-02-21 14:16 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 29/33] misc/mei/hdcp: Verify M_prime Ramalingam C via dri-devel
` (8 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Request ME to verify the downstream topology information received.
ME FW will validate the Repeaters receiver id list and
downstream topology.
On Success ME FW will provide the Least Significant
128bits of VPrime, which forms the repeater ack.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Style and typos fixed [Uma]
v5: Rebased.
v6: Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition. [Tomas]
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 77 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 76 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index fe5070f901e8..c06a9805ac85 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -466,6 +466,80 @@ static int mei_hdcp_get_session_key(struct device *dev,
return 0;
}
+/**
+ * mei_hdcp_repeater_check_flow_prepare_ack() - Validate the Downstream topology
+ * and prepare rep_ack.
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @rep_topology: Receiver ID List to be validated
+ * @rep_send_ack : repeater ack from ME FW.
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_repeater_check_flow_prepare_ack(struct device *dev,
+ struct hdcp_port_data *data,
+ struct hdcp2_rep_send_receiverid_list
+ *rep_topology,
+ struct hdcp2_rep_send_ack
+ *rep_send_ack)
+{
+ struct wired_cmd_verify_repeater_in verify_repeater_in = { { 0 } };
+ struct wired_cmd_verify_repeater_out verify_repeater_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !rep_topology || !rep_send_ack || !data)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ verify_repeater_in.header.api_version = HDCP_API_VERSION;
+ verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER;
+ verify_repeater_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ verify_repeater_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN;
+
+ verify_repeater_in.port.integrated_port_type = data->port_type;
+ verify_repeater_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ memcpy(verify_repeater_in.rx_info, rep_topology->rx_info,
+ HDCP_2_2_RXINFO_LEN);
+ memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v,
+ HDCP_2_2_SEQ_NUM_LEN);
+ memcpy(verify_repeater_in.v_prime, rep_topology->v_prime,
+ HDCP_2_2_V_PRIME_HALF_LEN);
+ memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids,
+ HDCP_2_2_RECEIVER_IDS_MAX_LEN);
+
+ byte = mei_cldev_send(cldev, (u8 *)&verify_repeater_in,
+ sizeof(verify_repeater_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&verify_repeater_out,
+ sizeof(verify_repeater_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (verify_repeater_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+ WIRED_VERIFY_REPEATER,
+ verify_repeater_out.header.status);
+ return -EIO;
+ }
+
+ memcpy(rep_send_ack->v, verify_repeater_out.v,
+ HDCP_2_2_V_PRIME_HALF_LEN);
+ rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK;
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -477,7 +551,8 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
.initiate_locality_check = mei_hdcp_initiate_locality_check,
.verify_lprime = mei_hdcp_verify_lprime,
.get_session_key = mei_hdcp_get_session_key,
- .repeater_check_flow_prepare_ack = NULL,
+ .repeater_check_flow_prepare_ack =
+ mei_hdcp_repeater_check_flow_prepare_ack,
.verify_mprime = NULL,
.enable_hdcp_authentication = NULL,
.close_hdcp_session = NULL,
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 29/33] misc/mei/hdcp: Verify M_prime
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (27 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 28/33] misc/mei/hdcp: Repeater topology verification and ack Ramalingam C via dri-devel
@ 2019-02-16 17:37 ` Ramalingam C via dri-devel
2019-02-21 13:44 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 30/33] misc/mei/hdcp: Enabling the HDCP authentication Ramalingam C
` (7 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Request to ME to verify the M_Prime received from the HDCP sink.
ME FW will calculate the M and compare with M_prime received
as part of RepeaterAuth_Stream_Ready, which is HDCP2.2 protocol msg.
On successful completion of this stage, downstream propagation of
the stream management info is completed.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
endianness conversion func is moved to drm_hdcp.h [Uma]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebasing.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition. [Tomas]
drm_hdcp2_u32_to_seq_num() is used for u32 to seq_num.
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 67 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index c06a9805ac85..721376fc9bf1 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -540,6 +540,71 @@ mei_hdcp_repeater_check_flow_prepare_ack(struct device *dev,
return 0;
}
+/**
+ * mei_hdcp_verify_mprime() - Verify mprime.
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @stream_ready: RepeaterAuth_Stream_Ready msg for ME FW verification.
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int mei_hdcp_verify_mprime(struct device *dev,
+ struct hdcp_port_data *data,
+ struct hdcp2_rep_stream_ready *stream_ready)
+{
+ struct wired_cmd_repeater_auth_stream_req_in
+ verify_mprime_in = { { 0 } };
+ struct wired_cmd_repeater_auth_stream_req_out
+ verify_mprime_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !stream_ready || !data)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ verify_mprime_in.header.api_version = HDCP_API_VERSION;
+ verify_mprime_in.header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ;
+ verify_mprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ verify_mprime_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN;
+
+ verify_mprime_in.port.integrated_port_type = data->port_type;
+ verify_mprime_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,
+ HDCP_2_2_MPRIME_LEN);
+ drm_hdcp2_u32_to_seq_num(verify_mprime_in.seq_num_m, data->seq_num_m);
+ memcpy(verify_mprime_in.streams, data->streams,
+ (data->k * sizeof(struct hdcp2_streamid_type)));
+
+ verify_mprime_in.k = __swab16(data->k);
+
+ byte = mei_cldev_send(cldev, (u8 *)&verify_mprime_in,
+ sizeof(verify_mprime_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&verify_mprime_out,
+ sizeof(verify_mprime_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (verify_mprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+ WIRED_REPEATER_AUTH_STREAM_REQ,
+ verify_mprime_out.header.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -553,7 +618,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
.get_session_key = mei_hdcp_get_session_key,
.repeater_check_flow_prepare_ack =
mei_hdcp_repeater_check_flow_prepare_ack,
- .verify_mprime = NULL,
+ .verify_mprime = mei_hdcp_verify_mprime,
.enable_hdcp_authentication = NULL,
.close_hdcp_session = NULL,
};
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 30/33] misc/mei/hdcp: Enabling the HDCP authentication
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (28 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 29/33] misc/mei/hdcp: Verify M_prime Ramalingam C via dri-devel
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 14:25 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 31/33] misc/mei/hdcp: Closing wired HDCP2.2 Tx Session Ramalingam C
` (6 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Request to ME to configure a port as authenticated.
On Success, ME FW will mark the port as authenticated and provides
HDCP cipher with the encryption keys.
Enabling the Authentication can be requested once all stages of
HDCP2.2 authentication is completed by interacting with ME FW.
Only after this stage, driver can enable the HDCP encryption for
the port, through HW registers.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Style and typos fixed [Uma]
v5: Rebased.
v6:
Collected the Rb-ed by.
Rebased.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition. [Tomas]
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 55 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 721376fc9bf1..d8e04e0621a1 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -605,6 +605,59 @@ static int mei_hdcp_verify_mprime(struct device *dev,
return 0;
}
+/**
+ * mei_hdcp_enable_authentication() - Mark a port as authenticated
+ * through ME FW
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int mei_hdcp_enable_authentication(struct device *dev,
+ struct hdcp_port_data *data)
+{
+ struct wired_cmd_enable_auth_in enable_auth_in = { { 0 } };
+ struct wired_cmd_enable_auth_out enable_auth_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ enable_auth_in.header.api_version = HDCP_API_VERSION;
+ enable_auth_in.header.command_id = WIRED_ENABLE_AUTH;
+ enable_auth_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ enable_auth_in.header.buffer_len = WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN;
+
+ enable_auth_in.port.integrated_port_type = data->port_type;
+ enable_auth_in.port.physical_port = mei_get_ddi_index(data->port);
+ enable_auth_in.stream_type = data->streams[0].stream_type;
+
+ byte = mei_cldev_send(cldev, (u8 *)&enable_auth_in,
+ sizeof(enable_auth_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&enable_auth_out,
+ sizeof(enable_auth_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (enable_auth_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+ WIRED_ENABLE_AUTH, enable_auth_out.header.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -619,7 +672,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
.repeater_check_flow_prepare_ack =
mei_hdcp_repeater_check_flow_prepare_ack,
.verify_mprime = mei_hdcp_verify_mprime,
- .enable_hdcp_authentication = NULL,
+ .enable_hdcp_authentication = mei_hdcp_enable_authentication,
.close_hdcp_session = NULL,
};
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 31/33] misc/mei/hdcp: Closing wired HDCP2.2 Tx Session
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (29 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 30/33] misc/mei/hdcp: Enabling the HDCP authentication Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 14:25 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 32/33] misc/mei/hdcp: Component framework for I915 Interface Ramalingam C
` (5 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Request the ME to terminate the HDCP2.2 session for a port.
On Success, ME FW will mark the intel port as Deauthenticated and
terminate the wired HDCP2.2 Tx session started due to the cmd
WIRED_INITIATE_HDCP2_SESSION.
v2: Rebased.
v3:
cldev is passed as first parameter [Tomas]
Redundant comments and cast are removed [Tomas]
v4:
%zd for ssize_t [Alexander]
%s/return -1/return -EIO [Alexander]
Style and typos fixed [Uma]
v5:
Extra line is removed.
v6:
Collected the Rb-ed by.
Rebased.
v7:
Adjust to the new mei interface.
Fix for Kdoc.
v8:
K-Doc addition.[Tomas]
v9:
renamed func as mei_hdcp_* [Tomas]
Inline function is defined for DDI index [Tomas]
v10:
K-Doc fix. [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 55 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index d8e04e0621a1..2afc7d31dacc 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -658,6 +658,59 @@ static int mei_hdcp_enable_authentication(struct device *dev,
return 0;
}
+/**
+ * mei_hdcp_close_session() - Close the Wired HDCP Tx session of ME FW per port.
+ * This also disables the authenticated state of the port.
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_close_session(struct device *dev, struct hdcp_port_data *data)
+{
+ struct wired_cmd_close_session_in session_close_in = { { 0 } };
+ struct wired_cmd_close_session_out session_close_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ session_close_in.header.api_version = HDCP_API_VERSION;
+ session_close_in.header.command_id = WIRED_CLOSE_SESSION;
+ session_close_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ session_close_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN;
+
+ session_close_in.port.integrated_port_type = data->port_type;
+ session_close_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ byte = mei_cldev_send(cldev, (u8 *)&session_close_in,
+ sizeof(session_close_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&session_close_out,
+ sizeof(session_close_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+ return byte;
+ }
+
+ if (session_close_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "Session Close Failed. status: 0x%X\n",
+ session_close_out.header.status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
static __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
@@ -673,7 +726,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
mei_hdcp_repeater_check_flow_prepare_ack,
.verify_mprime = mei_hdcp_verify_mprime,
.enable_hdcp_authentication = mei_hdcp_enable_authentication,
- .close_hdcp_session = NULL,
+ .close_hdcp_session = mei_hdcp_close_session,
};
static int mei_hdcp_probe(struct mei_cl_device *cldev,
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 32/33] misc/mei/hdcp: Component framework for I915 Interface
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (30 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 31/33] misc/mei/hdcp: Closing wired HDCP2.2 Tx Session Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C
2019-02-21 12:15 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 33/33] FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915 Ramalingam C via dri-devel
` (4 subsequent siblings)
36 siblings, 1 reply; 58+ messages in thread
From: Ramalingam C @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
Mei hdcp driver is designed as component slave for the I915 component
master.
v2: Rebased.
v3:
Notifier chain is adopted for cldev state update [Tomas]
v4:
Made static dummy functions as inline in mei_hdcp.h
API for polling client device status
IS_ENABLED used in header, for config status for mei_hdcp.
v5:
Replacing the notifier with component framework. [Daniel]
v6:
Rebased on the I915 comp master redesign.
v7:
mei_hdcp_component_registered is made static [Uma]
Need for global static variable mei_cldev is removed.
v8:
master comp is added to be matched with i915 subcomponent [daniel]
v9:
only comp_master is set and retrieved as driver_data [Daniel]
Reviewed-by Daniel.
v10:
small corrections at probe [Tomas]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/misc/mei/hdcp/mei_hdcp.c | 82 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 80 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 2afc7d31dacc..ad55b41550d6 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <linux/uuid.h>
#include <linux/mei_cl_bus.h>
+#include <linux/component.h>
#include <drm/drm_connector.h>
#include <drm/i915_component.h>
#include <drm/i915_mei_hdcp_interface.h>
@@ -711,8 +712,7 @@ mei_hdcp_close_session(struct device *dev, struct hdcp_port_data *data)
return 0;
}
-static __attribute__((unused))
-struct i915_hdcp_component_ops mei_hdcp_ops = {
+static struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
.initiate_hdcp2_session = mei_hdcp_initiate_session,
.verify_receiver_cert_prepare_km =
@@ -729,20 +729,98 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
.close_hdcp_session = mei_hdcp_close_session,
};
+static int mei_component_master_bind(struct device *dev)
+{
+ struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct i915_hdcp_comp_master *comp_master =
+ mei_cldev_get_drvdata(cldev);
+ int ret;
+
+ dev_info(dev, "%s\n", __func__);
+ comp_master->ops = &mei_hdcp_ops;
+ comp_master->mei_dev = dev;
+ ret = component_bind_all(dev, comp_master);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void mei_component_master_unbind(struct device *dev)
+{
+ struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct i915_hdcp_comp_master *comp_master =
+ mei_cldev_get_drvdata(cldev);
+
+ dev_info(dev, "%s\n", __func__);
+ component_unbind_all(dev, comp_master);
+}
+
+static const struct component_master_ops mei_component_master_ops = {
+ .bind = mei_component_master_bind,
+ .unbind = mei_component_master_unbind,
+};
+
+static int mei_hdcp_component_match(struct device *dev, int subcomponent,
+ void *data)
+{
+ return !strcmp(dev->driver->name, "i915") &&
+ subcomponent == I915_COMPONENT_HDCP;
+}
+
static int mei_hdcp_probe(struct mei_cl_device *cldev,
const struct mei_cl_device_id *id)
{
+ struct i915_hdcp_comp_master *comp_master;
+ struct component_match *master_match;
int ret;
ret = mei_cldev_enable(cldev);
if (ret < 0)
dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+ comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
+ if (!comp_master) {
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ master_match = NULL;
+ component_match_add_typed(&cldev->dev, &master_match,
+ mei_hdcp_component_match, comp_master);
+ if (IS_ERR_OR_NULL(master_match)) {
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ mei_cldev_set_drvdata(cldev, comp_master);
+ ret = component_master_add_with_match(&cldev->dev,
+ &mei_component_master_ops,
+ master_match);
+ if (ret < 0) {
+ dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
+ goto err_exit;
+ }
+
+ return 0;
+
+err_exit:
+ mei_cldev_set_drvdata(cldev, NULL);
+ kfree(comp_master);
+ mei_cldev_disable(cldev);
+
return ret;
}
static int mei_hdcp_remove(struct mei_cl_device *cldev)
{
+ struct i915_hdcp_comp_master *comp_master =
+ mei_cldev_get_drvdata(cldev);
+
+ component_master_del(&cldev->dev, &mei_component_master_ops);
+ kfree(comp_master);
+ mei_cldev_set_drvdata(cldev, NULL);
+
return mei_cldev_disable(cldev);
}
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 58+ messages in thread
* [PATCH v14 33/33] FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (31 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 32/33] misc/mei/hdcp: Component framework for I915 Interface Ramalingam C
@ 2019-02-16 17:37 ` Ramalingam C via dri-devel
2019-02-16 18:18 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Implement HDCP2.2 Patchwork
` (3 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C via dri-devel @ 2019-02-16 17:37 UTC (permalink / raw)
To: intel-gfx, dri-devel, daniel.vetter, tomas.winkler, uma.shankar
FOR TESTING PURPOSE ONLY.
By default INTEL_MEI_HDCP is set to y. This patch is created to
test the interface between I915 and MEI_HDCP.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
drivers/misc/mei/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index 64a7b3483895..e5defb2e1557 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -48,5 +48,6 @@ config INTEL_MEI_HDCP
tristate "Intel HDCP2.2 services of ME Interface"
select INTEL_MEI_ME
depends on DRM_I915
+ default y
help
MEI Support for HDCP2.2 Services on Intel platforms.
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 58+ messages in thread
* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Implement HDCP2.2
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (32 preceding siblings ...)
2019-02-16 17:37 ` [PATCH v14 33/33] FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915 Ramalingam C via dri-devel
@ 2019-02-16 18:18 ` Patchwork
2019-02-16 18:28 ` ✗ Fi.CI.SPARSE: " Patchwork
` (2 subsequent siblings)
36 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2019-02-16 18:18 UTC (permalink / raw)
To: intel-gfx
== Series Details ==
Series: drm/i915: Implement HDCP2.2
URL : https://patchwork.freedesktop.org/series/56794/
State : warning
== Summary ==
$ dim checkpatch origin/drm-tip
648bcac402ba drm/i915: Gathering the HDCP1.4 routines together
207737e7931f drm/audio: declaration of struct device
62caa86cc392 drm/i915: Initialize HDCP2.2
dbc970a8d63f drm/i915: MEI interface implementation
b17268a8a0ea drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking
6a7027b73b0a drm/i915: Enable and Disable of HDCP2.2
dbf489637139 drm/i915: Implement HDCP2.2 receiver authentication
ca6f1d300452 drm/i915: Implement HDCP2.2 repeater authentication
6d779e197150 drm: HDCP2.2 link check period
e4ad7b658917 drm/i915: Implement HDCP2.2 link integrity check
ef34221a5887 drm/i915: Handle HDCP2.2 downstream topology change
d61925db1422 drm: removing the DP Errata msg and its msg id
c76117d4868c drm/i915: Implement the HDCP2.2 support for DP
31ff42f161ac drm/i915: Implement the HDCP2.2 support for HDMI
80bb5c7b3470 drm/i915: CP_IRQ handling for DP HDCP2.2 msgs
287023fc9e54 drm/i915: Fix KBL HDCP2.2 encrypt status signalling
ddc5da855976 mei: bus: whitelist hdcp client
13ce0dff2ec4 mei: bus: export to_mei_cl_device for mei client device drivers
60500497dc7b misc/mei/hdcp: Client driver for HDCP application
-:77: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#77:
new file mode 100644
total: 0 errors, 1 warnings, 0 checks, 86 lines checked
1bfdacf04fe3 misc/mei/hdcp: Define ME FW interface for HDCP2.2
-:30: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#30:
new file mode 100644
total: 0 errors, 1 warnings, 0 checks, 366 lines checked
d703928aea87 misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session
922d4ec99a23 misc/mei/hdcp: Verify Receiver Cert and prepare km
5294bbbc7ee8 misc/mei/hdcp: Verify H_prime
7bd202557218 misc/mei/hdcp: Store the HDCP Pairing info
243d05121c55 misc/mei/hdcp: Initiate Locality check
50fd28040aa6 misc/mei/hdcp: Verify L_prime
afcdf5e7fbbb misc/mei/hdcp: Prepare Session Key
29a099742f0d misc/mei/hdcp: Repeater topology verification and ack
10b823d80ce8 misc/mei/hdcp: Verify M_prime
7213d21c344b misc/mei/hdcp: Enabling the HDCP authentication
eca7ff1c4449 misc/mei/hdcp: Closing wired HDCP2.2 Tx Session
274b0fae6f45 misc/mei/hdcp: Component framework for I915 Interface
eb2f8047a83c FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* ✗ Fi.CI.SPARSE: warning for drm/i915: Implement HDCP2.2
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (33 preceding siblings ...)
2019-02-16 18:18 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Implement HDCP2.2 Patchwork
@ 2019-02-16 18:28 ` Patchwork
2019-02-16 18:45 ` ✓ Fi.CI.BAT: success " Patchwork
2019-02-16 20:49 ` ✓ Fi.CI.IGT: " Patchwork
36 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2019-02-16 18:28 UTC (permalink / raw)
To: intel-gfx
== Series Details ==
Series: drm/i915: Implement HDCP2.2
URL : https://patchwork.freedesktop.org/series/56794/
State : warning
== Summary ==
$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Gathering the HDCP1.4 routines together
Okay!
Commit: drm/audio: declaration of struct device
Okay!
Commit: drm/i915: Initialize HDCP2.2
Okay!
Commit: drm/i915: MEI interface implementation
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3567:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3574:16: warning: expression using sizeof(void)
+./include/linux/slab.h:664:13: error: not a function <noident>
Commit: drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking
+drivers/gpu/drm/i915/intel_hdcp.c:749:5: warning: symbol 'intel_hdcp_check_link' was not declared. Should it be static?
Commit: drm/i915: Enable and Disable of HDCP2.2
Okay!
Commit: drm/i915: Implement HDCP2.2 receiver authentication
Okay!
Commit: drm/i915: Implement HDCP2.2 repeater authentication
Okay!
Commit: drm: HDCP2.2 link check period
Okay!
Commit: drm/i915: Implement HDCP2.2 link integrity check
Okay!
Commit: drm/i915: Handle HDCP2.2 downstream topology change
Okay!
Commit: drm: removing the DP Errata msg and its msg id
Okay!
Commit: drm/i915: Implement the HDCP2.2 support for DP
Okay!
Commit: drm/i915: Implement the HDCP2.2 support for HDMI
Okay!
Commit: drm/i915: CP_IRQ handling for DP HDCP2.2 msgs
Okay!
Commit: drm/i915: Fix KBL HDCP2.2 encrypt status signalling
Okay!
Commit: mei: bus: whitelist hdcp client
Okay!
Commit: mei: bus: export to_mei_cl_device for mei client device drivers
Okay!
Commit: misc/mei/hdcp: Client driver for HDCP application
+Error in reading or end of file.
Commit: misc/mei/hdcp: Define ME FW interface for HDCP2.2
Okay!
Commit: misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session
Okay!
Commit: misc/mei/hdcp: Verify Receiver Cert and prepare km
Okay!
Commit: misc/mei/hdcp: Verify H_prime
Okay!
Commit: misc/mei/hdcp: Store the HDCP Pairing info
Okay!
Commit: misc/mei/hdcp: Initiate Locality check
Okay!
Commit: misc/mei/hdcp: Verify L_prime
Okay!
Commit: misc/mei/hdcp: Prepare Session Key
Okay!
Commit: misc/mei/hdcp: Repeater topology verification and ack
Okay!
Commit: misc/mei/hdcp: Verify M_prime
Okay!
Commit: misc/mei/hdcp: Enabling the HDCP authentication
Okay!
Commit: misc/mei/hdcp: Closing wired HDCP2.2 Tx Session
Okay!
Commit: misc/mei/hdcp: Component framework for I915 Interface
Okay!
Commit: FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915
Okay!
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* ✓ Fi.CI.BAT: success for drm/i915: Implement HDCP2.2
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (34 preceding siblings ...)
2019-02-16 18:28 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-02-16 18:45 ` Patchwork
2019-02-16 20:49 ` ✓ Fi.CI.IGT: " Patchwork
36 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2019-02-16 18:45 UTC (permalink / raw)
To: intel-gfx
== Series Details ==
Series: drm/i915: Implement HDCP2.2
URL : https://patchwork.freedesktop.org/series/56794/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_5615 -> Patchwork_12237
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://patchwork.freedesktop.org/api/1.0/series/56794/revisions/1/mbox/
Known issues
------------
Here are the changes found in Patchwork_12237 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@kms_chamelium@hdmi-hpd-fast:
- fi-kbl-7500u: PASS -> FAIL [fdo#109485]
* igt@kms_content_protection@atomic:
- fi-skl-gvtdvm: NOTRUN -> FAIL [fdo#108597] +1
- fi-apl-guc: NOTRUN -> FAIL [fdo#108597] / [fdo#108739] +1
* igt@kms_content_protection@legacy:
- fi-cfl-8109u: NOTRUN -> FAIL [fdo#108739] +1
* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
- fi-byt-clapper: PASS -> FAIL [fdo#103191] / [fdo#107362] +1
* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
- fi-blb-e6850: NOTRUN -> INCOMPLETE [fdo#107718]
* igt@pm_rpm@basic-rte:
- fi-byt-j1900: PASS -> FAIL [fdo#108800]
* igt@pm_rpm@module-reload:
- fi-skl-6770hq: PASS -> DMESG-WARN [fdo#105541]
#### Possible fixes ####
* igt@gem_exec_suspend@basic-s3:
- fi-blb-e6850: INCOMPLETE [fdo#107718] -> PASS
* igt@kms_pipe_crc_basic@hang-read-crc-pipe-b:
- fi-byt-clapper: FAIL [fdo#103191] / [fdo#107362] -> PASS
* igt@kms_pipe_crc_basic@read-crc-pipe-a:
- fi-byt-clapper: FAIL [fdo#107362] -> PASS
* igt@pm_rpm@module-reload:
- {fi-icl-y}: INCOMPLETE [fdo#108840] -> PASS
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#103191]: https://bugs.freedesktop.org/show_bug.cgi?id=103191
[fdo#105541]: https://bugs.freedesktop.org/show_bug.cgi?id=105541
[fdo#107362]: https://bugs.freedesktop.org/show_bug.cgi?id=107362
[fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
[fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569
[fdo#108597]: https://bugs.freedesktop.org/show_bug.cgi?id=108597
[fdo#108739]: https://bugs.freedesktop.org/show_bug.cgi?id=108739
[fdo#108800]: https://bugs.freedesktop.org/show_bug.cgi?id=108800
[fdo#108840]: https://bugs.freedesktop.org/show_bug.cgi?id=108840
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
[fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
[fdo#109485]: https://bugs.freedesktop.org/show_bug.cgi?id=109485
[fdo#109527]: https://bugs.freedesktop.org/show_bug.cgi?id=109527
Participating hosts (43 -> 40)
------------------------------
Missing (3): fi-kbl-soraka fi-byt-squawks fi-bsw-cyan
Build changes
-------------
* IGT: IGT_4833 -> IGTPW_2356
* Linux: CI_DRM_5615 -> Patchwork_12237
CI_DRM_5615: a6e4cbf00557faf0c2d68fdff81b1afb9242aa4d @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_2356: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2356/
IGT_4833: 7802324e86ddf947cba847e910f75b1a8affe8d7 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_12237: eb2f8047a83c7bcdffb4976a08994ba2392947ed @ git://anongit.freedesktop.org/gfx-ci/linux
== Linux commits ==
eb2f8047a83c FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915
274b0fae6f45 misc/mei/hdcp: Component framework for I915 Interface
eca7ff1c4449 misc/mei/hdcp: Closing wired HDCP2.2 Tx Session
7213d21c344b misc/mei/hdcp: Enabling the HDCP authentication
10b823d80ce8 misc/mei/hdcp: Verify M_prime
29a099742f0d misc/mei/hdcp: Repeater topology verification and ack
afcdf5e7fbbb misc/mei/hdcp: Prepare Session Key
50fd28040aa6 misc/mei/hdcp: Verify L_prime
243d05121c55 misc/mei/hdcp: Initiate Locality check
7bd202557218 misc/mei/hdcp: Store the HDCP Pairing info
5294bbbc7ee8 misc/mei/hdcp: Verify H_prime
922d4ec99a23 misc/mei/hdcp: Verify Receiver Cert and prepare km
d703928aea87 misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session
1bfdacf04fe3 misc/mei/hdcp: Define ME FW interface for HDCP2.2
60500497dc7b misc/mei/hdcp: Client driver for HDCP application
13ce0dff2ec4 mei: bus: export to_mei_cl_device for mei client device drivers
ddc5da855976 mei: bus: whitelist hdcp client
287023fc9e54 drm/i915: Fix KBL HDCP2.2 encrypt status signalling
80bb5c7b3470 drm/i915: CP_IRQ handling for DP HDCP2.2 msgs
31ff42f161ac drm/i915: Implement the HDCP2.2 support for HDMI
c76117d4868c drm/i915: Implement the HDCP2.2 support for DP
d61925db1422 drm: removing the DP Errata msg and its msg id
ef34221a5887 drm/i915: Handle HDCP2.2 downstream topology change
e4ad7b658917 drm/i915: Implement HDCP2.2 link integrity check
6d779e197150 drm: HDCP2.2 link check period
ca6f1d300452 drm/i915: Implement HDCP2.2 repeater authentication
dbf489637139 drm/i915: Implement HDCP2.2 receiver authentication
6a7027b73b0a drm/i915: Enable and Disable of HDCP2.2
b17268a8a0ea drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking
dbc970a8d63f drm/i915: MEI interface implementation
62caa86cc392 drm/i915: Initialize HDCP2.2
207737e7931f drm/audio: declaration of struct device
648bcac402ba drm/i915: Gathering the HDCP1.4 routines together
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12237/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* ✓ Fi.CI.IGT: success for drm/i915: Implement HDCP2.2
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
` (35 preceding siblings ...)
2019-02-16 18:45 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-02-16 20:49 ` Patchwork
36 siblings, 0 replies; 58+ messages in thread
From: Patchwork @ 2019-02-16 20:49 UTC (permalink / raw)
To: intel-gfx
== Series Details ==
Series: drm/i915: Implement HDCP2.2
URL : https://patchwork.freedesktop.org/series/56794/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_5615_full -> Patchwork_12237_full
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in Patchwork_12237_full:
### IGT changes ###
#### Suppressed ####
The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.
* {igt@gem_media_vme}:
- shard-glk: PASS -> FAIL
Known issues
------------
Here are the changes found in Patchwork_12237_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@i915_suspend@shrink:
- shard-apl: NOTRUN -> DMESG-WARN [fdo#107886] / [fdo#109244]
- shard-snb: NOTRUN -> DMESG-WARN [fdo#109244]
- shard-hsw: NOTRUN -> DMESG-WARN [fdo#109244]
- shard-iclb: NOTRUN -> DMESG-WARN [fdo#107886] / [fdo#109244]
- shard-glk: NOTRUN -> DMESG-WARN [fdo#109244]
* igt@kms_busy@extended-modeset-hang-newfb-render-a:
- shard-iclb: NOTRUN -> DMESG-WARN [fdo#107956] +1
* igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-c:
- shard-glk: PASS -> DMESG-WARN [fdo#107956]
* igt@kms_ccs@pipe-a-crc-primary-rotation-180:
- shard-iclb: NOTRUN -> FAIL [fdo#107725]
* igt@kms_color@pipe-b-ctm-0-25:
- shard-iclb: NOTRUN -> DMESG-WARN [fdo#109624] +3
* igt@kms_color@pipe-b-legacy-gamma:
- shard-iclb: NOTRUN -> FAIL [fdo#104782] +1
* igt@kms_color@pipe-c-degamma:
- shard-iclb: NOTRUN -> DMESG-FAIL [fdo#109624]
* igt@kms_cursor_crc@cursor-256x256-dpms:
- shard-apl: PASS -> FAIL [fdo#103232] +1
* igt@kms_cursor_crc@cursor-64x21-random:
- shard-iclb: NOTRUN -> FAIL [fdo#103232] +2
* igt@kms_cursor_crc@cursor-size-change:
- shard-kbl: PASS -> FAIL [fdo#103232]
* igt@kms_cursor_legacy@2x-long-flip-vs-cursor-atomic:
- shard-glk: PASS -> FAIL [fdo#104873]
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt:
- shard-glk: PASS -> FAIL [fdo#103167] +7
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-wc:
- shard-iclb: NOTRUN -> FAIL [fdo#103167]
* igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-fullscreen:
- shard-iclb: PASS -> FAIL [fdo#103167] +2
* igt@kms_plane@pixel-format-pipe-a-planes:
- shard-iclb: NOTRUN -> FAIL [fdo#103166] +1
* igt@kms_plane@pixel-format-pipe-a-planes-source-clamping:
- shard-glk: PASS -> FAIL [fdo#108948]
* igt@kms_plane@plane-position-covered-pipe-a-planes:
- shard-iclb: PASS -> FAIL [fdo#103166]
* igt@kms_plane_multiple@atomic-pipe-b-tiling-none:
- shard-glk: PASS -> FAIL [fdo#103166] +4
* igt@kms_setmode@basic:
- shard-apl: PASS -> FAIL [fdo#99912]
- shard-iclb: NOTRUN -> FAIL [fdo#99912]
- shard-hsw: PASS -> FAIL [fdo#99912]
* igt@kms_sysfs_edid_timing:
- shard-iclb: PASS -> FAIL [fdo#100047]
* igt@pm_rpm@cursor:
- shard-apl: PASS -> INCOMPLETE [fdo#103927]
* igt@pm_rpm@pm-tiling:
- shard-iclb: PASS -> DMESG-WARN [fdo#107724] +1
#### Possible fixes ####
* igt@gem_eio@unwedge-stress:
- shard-snb: FAIL -> PASS
* igt@gem_linear_blits@normal:
- shard-snb: INCOMPLETE [fdo#105411] -> PASS
* igt@i915_selftest@live_execlists:
- shard-iclb: INCOMPLETE [fdo#109567] -> PASS
* igt@i915_selftest@live_workarounds:
- shard-iclb: DMESG-FAIL [fdo#108954] -> PASS
* igt@kms_atomic_transition@1x-modeset-transitions-nonblocking-fencing:
- shard-apl: FAIL -> PASS
* igt@kms_color@pipe-a-ctm-max:
- shard-apl: FAIL [fdo#108147] -> PASS
* igt@kms_cursor_crc@cursor-128x128-random:
- shard-apl: FAIL [fdo#103232] -> PASS +6
* igt@kms_cursor_crc@cursor-128x128-suspend:
- shard-apl: FAIL [fdo#103191] / [fdo#103232] -> PASS +1
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt:
- shard-apl: FAIL [fdo#103167] -> PASS +5
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move:
- shard-iclb: FAIL [fdo#103167] -> PASS +1
* igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-cpu:
- shard-glk: FAIL [fdo#103167] -> PASS +4
* igt@kms_plane@plane-position-covered-pipe-b-planes:
- shard-glk: FAIL [fdo#103166] -> PASS +1
* igt@kms_plane_multiple@atomic-pipe-a-tiling-x:
- shard-kbl: FAIL [fdo#103166] -> PASS
* igt@kms_plane_multiple@atomic-pipe-b-tiling-y:
- shard-iclb: FAIL [fdo#103166] -> PASS +1
* igt@kms_plane_multiple@atomic-pipe-c-tiling-yf:
- shard-apl: FAIL [fdo#103166] -> PASS +5
* igt@pm_rpm@legacy-planes-dpms:
- shard-iclb: DMESG-WARN [fdo#107724] -> PASS +1
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#100047]: https://bugs.freedesktop.org/show_bug.cgi?id=100047
[fdo#103166]: https://bugs.freedesktop.org/show_bug.cgi?id=103166
[fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
[fdo#103191]: https://bugs.freedesktop.org/show_bug.cgi?id=103191
[fdo#103232]: https://bugs.freedesktop.org/show_bug.cgi?id=103232
[fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
[fdo#104782]: https://bugs.freedesktop.org/show_bug.cgi?id=104782
[fdo#104873]: https://bugs.freedesktop.org/show_bug.cgi?id=104873
[fdo#105411]: https://bugs.freedesktop.org/show_bug.cgi?id=105411
[fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
[fdo#107725]: https://bugs.freedesktop.org/show_bug.cgi?id=107725
[fdo#107886]: https://bugs.freedesktop.org/show_bug.cgi?id=107886
[fdo#107956]: https://bugs.freedesktop.org/show_bug.cgi?id=107956
[fdo#108147]: https://bugs.freedesktop.org/show_bug.cgi?id=108147
[fdo#108948]: https://bugs.freedesktop.org/show_bug.cgi?id=108948
[fdo#108954]: https://bugs.freedesktop.org/show_bug.cgi?id=108954
[fdo#109244]: https://bugs.freedesktop.org/show_bug.cgi?id=109244
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
[fdo#109275]: https://bugs.freedesktop.org/show_bug.cgi?id=109275
[fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
[fdo#109277]: https://bugs.freedesktop.org/show_bug.cgi?id=109277
[fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
[fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
[fdo#109281]: https://bugs.freedesktop.org/show_bug.cgi?id=109281
[fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
[fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
[fdo#109287]: https://bugs.freedesktop.org/show_bug.cgi?id=109287
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109290]: https://bugs.freedesktop.org/show_bug.cgi?id=109290
[fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
[fdo#109292]: https://bugs.freedesktop.org/show_bug.cgi?id=109292
[fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
[fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
[fdo#109502]: https://bugs.freedesktop.org/show_bug.cgi?id=109502
[fdo#109506]: https://bugs.freedesktop.org/show_bug.cgi?id=109506
[fdo#109567]: https://bugs.freedesktop.org/show_bug.cgi?id=109567
[fdo#109624]: https://bugs.freedesktop.org/show_bug.cgi?id=109624
[fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912
Participating hosts (7 -> 6)
------------------------------
Missing (1): shard-skl
Build changes
-------------
* IGT: IGT_4833 -> IGTPW_2356
* Linux: CI_DRM_5615 -> Patchwork_12237
CI_DRM_5615: a6e4cbf00557faf0c2d68fdff81b1afb9242aa4d @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_2356: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2356/
IGT_4833: 7802324e86ddf947cba847e910f75b1a8affe8d7 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_12237: eb2f8047a83c7bcdffb4976a08994ba2392947ed @ git://anongit.freedesktop.org/gfx-ci/linux
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12237/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 04/33] drm/i915: MEI interface implementation
2019-02-16 17:36 ` [PATCH v14 04/33] drm/i915: MEI interface implementation Ramalingam C via dri-devel
@ 2019-02-20 19:39 ` Daniel Vetter
2019-02-21 4:07 ` C, Ramalingam
0 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2019-02-20 19:39 UTC (permalink / raw)
To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, tomas.winkler, dri-devel
On Sat, Feb 16, 2019 at 11:06:51PM +0530, Ramalingam C wrote:
> Defining the mei-i915 interface functions and initialization of
> the interface.
>
> v2:
> Adjust to the new interface changes. [Tomas]
> Added further debug logs for the failures at MEI i/f.
> port in hdcp_port data is equipped to handle -ve values.
> v3:
> mei comp is matched for global i915 comp master. [Daniel]
> In hdcp_shim hdcp_protocol() is replaced with const variable. [Daniel]
> mei wrappers are adjusted as per the i/f change [Daniel]
> v4:
> port initialization is done only at hdcp2_init only [Danvet]
> v5:
> I915 registers a subcomponent to be matched with mei_hdcp [Daniel]
> v6:
> HDCP_disable for all connectors incase of comp_unbind.
> Tear down HDCP comp interface at i915_unload [Daniel]
> v7:
> Component init and fini are moved out of connector ops [Daniel]
> hdcp_disable is not called from unbind. [Daniel]
> v8:
> subcomponent name is dropped as it is already merged.
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> [v11]
I think that r-b was for v7, not v8, and v11 of this patch doesn't even
exist. Series itself is as v14. Anyways, merged, thanks for all your work!
-Daniel
> ---
> drivers/gpu/drm/i915/i915_drv.c | 1 +
> drivers/gpu/drm/i915/i915_drv.h | 7 +
> drivers/gpu/drm/i915/intel_connector.c | 2 +
> drivers/gpu/drm/i915/intel_display.c | 4 +
> drivers/gpu/drm/i915/intel_drv.h | 8 +
> drivers/gpu/drm/i915/intel_hdcp.c | 398 ++++++++++++++++++++++++++++++++-
> 6 files changed, 419 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 6630212f2faf..c6354f6cdbdb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -906,6 +906,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv)
> mutex_init(&dev_priv->av_mutex);
> mutex_init(&dev_priv->wm.wm_mutex);
> mutex_init(&dev_priv->pps_mutex);
> + mutex_init(&dev_priv->hdcp_comp_mutex);
>
> i915_memcpy_init_early(dev_priv);
> intel_runtime_pm_init_early(dev_priv);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 5c8d0489a1cd..d375d1cf86f5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -55,6 +55,7 @@
> #include <drm/drm_util.h>
> #include <drm/drm_dsc.h>
> #include <drm/drm_connector.h>
> +#include <drm/i915_mei_hdcp_interface.h>
>
> #include "i915_fixed.h"
> #include "i915_params.h"
> @@ -2052,6 +2053,12 @@ struct drm_i915_private {
>
> struct i915_pmu pmu;
>
> + struct i915_hdcp_comp_master *hdcp_master;
> + bool hdcp_comp_added;
> +
> + /* Mutex to protect the above hdcp component related values. */
> + struct mutex hdcp_comp_mutex;
> +
> /*
> * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> * will be rejected. Instead look for a better place.
> diff --git a/drivers/gpu/drm/i915/intel_connector.c b/drivers/gpu/drm/i915/intel_connector.c
> index ee16758747c5..66ed3ee5998a 100644
> --- a/drivers/gpu/drm/i915/intel_connector.c
> +++ b/drivers/gpu/drm/i915/intel_connector.c
> @@ -88,6 +88,8 @@ void intel_connector_destroy(struct drm_connector *connector)
>
> kfree(intel_connector->detect_edid);
>
> + intel_hdcp_cleanup(intel_connector);
> +
> if (!IS_ERR_OR_NULL(intel_connector->edid))
> kfree(intel_connector->edid);
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 73a107b6eb9a..acb993ce7eaa 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -15453,6 +15453,8 @@ int intel_modeset_init(struct drm_device *dev)
> intel_update_czclk(dev_priv);
> intel_modeset_init_hw(dev);
>
> + intel_hdcp_component_init(dev_priv);
> +
> if (dev_priv->max_cdclk_freq == 0)
> intel_update_max_cdclk(dev_priv);
>
> @@ -16314,6 +16316,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
> /* flush any delayed tasks or pending work */
> flush_scheduled_work();
>
> + intel_hdcp_component_fini(dev_priv);
> +
> drm_mode_config_cleanup(dev);
>
> intel_overlay_cleanup(dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 11c696025085..f8e8482573c8 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -41,6 +41,7 @@
> #include <drm/drm_rect.h>
> #include <drm/drm_vblank.h>
> #include <drm/drm_atomic.h>
> +#include <drm/i915_mei_hdcp_interface.h>
> #include <media/cec-notifier.h>
>
> struct drm_printer;
> @@ -395,6 +396,9 @@ struct intel_hdcp_shim {
> /* Detects panel's hdcp capability. This is optional for HDMI. */
> int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
> bool *hdcp_capable);
> +
> + /* HDCP adaptation(DP/HDMI) required on the port */
> + enum hdcp_wired_protocol protocol;
> };
>
> struct intel_hdcp {
> @@ -415,6 +419,7 @@ struct intel_hdcp {
> * content can flow only through a link protected by HDCP2.2.
> */
> u8 content_type;
> + struct hdcp_port_data port_data;
> };
>
> struct intel_connector {
> @@ -2088,6 +2093,9 @@ 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);
> +void intel_hdcp_component_init(struct drm_i915_private *dev_priv);
> +void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
> +void intel_hdcp_cleanup(struct intel_connector *connector);
>
> /* 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 7b1097d79fb8..d06bef9d1ab2 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -7,8 +7,10 @@
> */
>
> #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"
> @@ -832,6 +834,347 @@ bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
> return INTEL_GEN(dev_priv) >= 9 && port < PORT_E;
> }
>
> +static __attribute__((unused)) int
> +hdcp2_prepare_ake_init(struct intel_connector *connector,
> + struct hdcp2_ake_init *ake_data)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->initiate_hdcp2_session(comp->mei_dev, data, ake_data);
> + if (ret)
> + DRM_DEBUG_KMS("Prepare_ake_init failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused)) int
> +hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
> + struct hdcp2_ake_send_cert *rx_cert,
> + bool *paired,
> + struct hdcp2_ake_no_stored_km *ek_pub_km,
> + size_t *msg_sz)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->verify_receiver_cert_prepare_km(comp->mei_dev, data,
> + rx_cert, paired,
> + ek_pub_km, msg_sz);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Verify rx_cert failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused)) int
> +hdcp2_verify_hprime(struct intel_connector *connector,
> + struct hdcp2_ake_send_hprime *rx_hprime)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->verify_hprime(comp->mei_dev, data, rx_hprime);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Verify hprime failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused)) int
> +hdcp2_store_pairing_info(struct intel_connector *connector,
> + struct hdcp2_ake_send_pairing_info *pairing_info)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->store_pairing_info(comp->mei_dev, data, pairing_info);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Store pairing info failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused)) int
> +hdcp2_prepare_lc_init(struct intel_connector *connector,
> + struct hdcp2_lc_init *lc_init)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->initiate_locality_check(comp->mei_dev, data, lc_init);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Prepare lc_init failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused)) int
> +hdcp2_verify_lprime(struct intel_connector *connector,
> + struct hdcp2_lc_send_lprime *rx_lprime)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->verify_lprime(comp->mei_dev, data, rx_lprime);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Verify L_Prime failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused))
> +int hdcp2_prepare_skey(struct intel_connector *connector,
> + struct hdcp2_ske_send_eks *ske_data)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->get_session_key(comp->mei_dev, data, ske_data);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Get session key failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused)) int
> +hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
> + struct hdcp2_rep_send_receiverid_list
> + *rep_topology,
> + struct hdcp2_rep_send_ack *rep_send_ack)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->repeater_check_flow_prepare_ack(comp->mei_dev, data,
> + rep_topology,
> + rep_send_ack);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Verify rep topology failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused)) int
> +hdcp2_verify_mprime(struct intel_connector *connector,
> + struct hdcp2_rep_stream_ready *stream_ready)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->verify_mprime(comp->mei_dev, data, stream_ready);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Verify mprime failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused))
> +int hdcp2_authenticate_port(struct intel_connector *connector)
> +{
> + struct hdcp_port_data *data = &connector->hdcp.port_data;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->enable_hdcp_authentication(comp->mei_dev, data);
> + if (ret < 0)
> + DRM_DEBUG_KMS("Enable hdcp auth failed. %d\n", ret);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused))
> +int hdcp2_close_mei_session(struct intel_connector *connector)
> +{
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct i915_hdcp_comp_master *comp;
> + int ret;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + comp = dev_priv->hdcp_master;
> +
> + if (!comp || !comp->ops) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return -EINVAL;
> + }
> +
> + ret = comp->ops->close_hdcp_session(comp->mei_dev,
> + &connector->hdcp.port_data);
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return ret;
> +}
> +
> +static __attribute__((unused))
> +int hdcp2_deauthenticate_port(struct intel_connector *connector)
> +{
> + return hdcp2_close_mei_session(connector);
> +}
> +
> +static int i915_hdcp_component_bind(struct device *i915_kdev,
> + struct device *mei_kdev, void *data)
> +{
> + struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
> +
> + DRM_DEBUG("I915 HDCP comp bind\n");
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + dev_priv->hdcp_master = (struct i915_hdcp_comp_master *)data;
> + dev_priv->hdcp_master->mei_dev = mei_kdev;
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + return 0;
> +}
> +
> +static void i915_hdcp_component_unbind(struct device *i915_kdev,
> + struct device *mei_kdev, void *data)
> +{
> + struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
> +
> + DRM_DEBUG("I915 HDCP comp unbind\n");
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + dev_priv->hdcp_master = NULL;
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +}
> +
> +static const struct component_ops i915_hdcp_component_ops = {
> + .bind = i915_hdcp_component_bind,
> + .unbind = i915_hdcp_component_unbind,
> +};
> +
> +static inline int initialize_hdcp_port_data(struct intel_connector *connector)
> +{
> + struct intel_hdcp *hdcp = &connector->hdcp;
> + struct hdcp_port_data *data = &hdcp->port_data;
> +
> + data->port = connector->encoder->port;
> + data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
> + data->protocol = (u8)hdcp->shim->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;
> +}
> +
> static bool is_hdcp2_supported(struct drm_i915_private *dev_priv)
> {
> if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
> @@ -841,11 +1184,40 @@ static bool is_hdcp2_supported(struct drm_i915_private *dev_priv)
> IS_KABYLAKE(dev_priv));
> }
>
> +void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
> +{
> + int ret;
> +
> + if (!is_hdcp2_supported(dev_priv))
> + return;
> +
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + WARN_ON(dev_priv->hdcp_comp_added);
> +
> + dev_priv->hdcp_comp_added = true;
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + ret = component_add_typed(dev_priv->drm.dev, &i915_hdcp_component_ops,
> + I915_COMPONENT_HDCP);
> + if (ret < 0) {
> + DRM_DEBUG_KMS("Failed at component add(%d)\n", ret);
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + dev_priv->hdcp_comp_added = false;
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return;
> + }
> +}
> +
> static void intel_hdcp2_init(struct intel_connector *connector)
> {
> struct intel_hdcp *hdcp = &connector->hdcp;
> + int ret;
> +
> + ret = initialize_hdcp_port_data(connector);
> + if (ret) {
> + DRM_DEBUG_KMS("Mei hdcp data init failed\n");
> + return;
> + }
>
> - /* TODO: MEI interface needs to be initialized here */
> hdcp->hdcp2_supported = true;
> }
>
> @@ -917,6 +1289,30 @@ int intel_hdcp_disable(struct intel_connector *connector)
> return ret;
> }
>
> +void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
> +{
> + mutex_lock(&dev_priv->hdcp_comp_mutex);
> + if (!dev_priv->hdcp_comp_added) {
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> + return;
> + }
> +
> + dev_priv->hdcp_comp_added = false;
> + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> +
> + component_del(dev_priv->drm.dev, &i915_hdcp_component_ops);
> +}
> +
> +void intel_hdcp_cleanup(struct intel_connector *connector)
> +{
> + if (!connector->hdcp.shim)
> + return;
> +
> + mutex_lock(&connector->hdcp.mutex);
> + kfree(connector->hdcp.port_data.streams);
> + mutex_unlock(&connector->hdcp.mutex);
> +}
> +
> void intel_hdcp_atomic_check(struct drm_connector *connector,
> struct drm_connector_state *old_state,
> struct drm_connector_state *new_state)
> --
> 2.7.4
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 16/33] drm/i915: Fix KBL HDCP2.2 encrypt status signalling
2019-02-16 17:37 ` [PATCH v14 16/33] drm/i915: Fix KBL HDCP2.2 encrypt status signalling Ramalingam C
@ 2019-02-20 19:49 ` Daniel Vetter
0 siblings, 0 replies; 58+ messages in thread
From: Daniel Vetter @ 2019-02-20 19:49 UTC (permalink / raw)
To: Ramalingam C
Cc: daniel.vetter, intel-gfx, uma.shankar, tomas.winkler, dri-devel
On Sat, Feb 16, 2019 at 11:07:03PM +0530, Ramalingam C wrote:
> HDCP transmitter is supposed to indicate the HDCP encryption status of
> the link through enc_en signals in a window of time called "window of
> opportunity" defined by HDCP HDMI spec.
>
> But on KBL this timing of signalling has an issue. To fix the issue this
> WA of resetting the signalling is required.
>
> v2:
> WA is moved into the toggle_signalling [Daniel]
> v3:
> Commit msg is rewritten with more information
> v4:
> Reviewed-by Daniel.
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Merged all the i915 patches to dinq for 5.2.
Thanks, Daniel
> ---
> drivers/gpu/drm/i915/intel_hdmi.c | 42 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 6a3e400f54d7..c2c91e6645a5 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1083,10 +1083,44 @@ int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
> return ret;
> }
>
> +static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
> +{
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
> + struct drm_crtc *crtc = connector->base.state->crtc;
> + struct intel_crtc *intel_crtc = container_of(crtc,
> + struct intel_crtc, base);
> + u32 scanline;
> + int ret;
> +
> + for (;;) {
> + scanline = I915_READ(PIPEDSL(intel_crtc->pipe));
> + if (scanline > 100 && scanline < 200)
> + break;
> + usleep_range(25, 50);
> + }
> +
> + ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, false);
> + if (ret) {
> + DRM_ERROR("Disable HDCP signalling failed (%d)\n", ret);
> + return ret;
> + }
> + ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, true);
> + if (ret) {
> + DRM_ERROR("Enable HDCP signalling failed (%d)\n", ret);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> static
> int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> bool enable)
> {
> + struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
> + struct intel_connector *connector = hdmi->attached_connector;
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> int ret;
>
> if (!enable)
> @@ -1098,6 +1132,14 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> enable ? "Enable" : "Disable", ret);
> return ret;
> }
> +
> + /*
> + * WA: To fix incorrect positioning of the window of
> + * opportunity and enc_en signalling in KABYLAKE.
> + */
> + if (IS_KABYLAKE(dev_priv) && enable)
> + return kbl_repositioning_enc_en_signal(connector);
> +
> return 0;
> }
>
> --
> 2.7.4
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 04/33] drm/i915: MEI interface implementation
2019-02-20 19:39 ` Daniel Vetter
@ 2019-02-21 4:07 ` C, Ramalingam
0 siblings, 0 replies; 58+ messages in thread
From: C, Ramalingam @ 2019-02-21 4:07 UTC (permalink / raw)
To: Daniel Vetter
Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org,
Winkler, Tomas, dri-devel@lists.freedesktop.org
> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Thursday, February 21, 2019 1:10 AM
> To: C, Ramalingam <ramalingam.c@intel.com>
> Cc: 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>
> Subject: Re: [PATCH v14 04/33] drm/i915: MEI interface implementation
>
> On Sat, Feb 16, 2019 at 11:06:51PM +0530, Ramalingam C wrote:
> > Defining the mei-i915 interface functions and initialization of the
> > interface.
> >
> > v2:
> > Adjust to the new interface changes. [Tomas]
> > Added further debug logs for the failures at MEI i/f.
> > port in hdcp_port data is equipped to handle -ve values.
> > v3:
> > mei comp is matched for global i915 comp master. [Daniel]
> > In hdcp_shim hdcp_protocol() is replaced with const variable. [Daniel]
> > mei wrappers are adjusted as per the i/f change [Daniel]
> > v4:
> > port initialization is done only at hdcp2_init only [Danvet]
> > v5:
> > I915 registers a subcomponent to be matched with mei_hdcp [Daniel]
> > v6:
> > HDCP_disable for all connectors incase of comp_unbind.
> > Tear down HDCP comp interface at i915_unload [Daniel]
> > v7:
> > Component init and fini are moved out of connector ops [Daniel]
> > hdcp_disable is not called from unbind. [Daniel]
> > v8:
> > subcomponent name is dropped as it is already merged.
> >
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> [v11]
>
> I think that r-b was for v7, not v8, and v11 of this patch doesn't even exist. Series
> itself is as v14. Anyways, merged, thanks for all your work!
Thanks Daniel. Series version at which R-b was received for the original patch was captured here.
But yes. Should have captured the patch version instead.
-Ram
> -Daniel
>
> > ---
> > drivers/gpu/drm/i915/i915_drv.c | 1 +
> > drivers/gpu/drm/i915/i915_drv.h | 7 +
> > drivers/gpu/drm/i915/intel_connector.c | 2 +
> > drivers/gpu/drm/i915/intel_display.c | 4 +
> > drivers/gpu/drm/i915/intel_drv.h | 8 +
> > drivers/gpu/drm/i915/intel_hdcp.c | 398
> ++++++++++++++++++++++++++++++++-
> > 6 files changed, 419 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.c
> > b/drivers/gpu/drm/i915/i915_drv.c index 6630212f2faf..c6354f6cdbdb
> > 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.c
> > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > @@ -906,6 +906,7 @@ static int i915_driver_init_early(struct
> drm_i915_private *dev_priv)
> > mutex_init(&dev_priv->av_mutex);
> > mutex_init(&dev_priv->wm.wm_mutex);
> > mutex_init(&dev_priv->pps_mutex);
> > + mutex_init(&dev_priv->hdcp_comp_mutex);
> >
> > i915_memcpy_init_early(dev_priv);
> > intel_runtime_pm_init_early(dev_priv);
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h index 5c8d0489a1cd..d375d1cf86f5
> > 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -55,6 +55,7 @@
> > #include <drm/drm_util.h>
> > #include <drm/drm_dsc.h>
> > #include <drm/drm_connector.h>
> > +#include <drm/i915_mei_hdcp_interface.h>
> >
> > #include "i915_fixed.h"
> > #include "i915_params.h"
> > @@ -2052,6 +2053,12 @@ struct drm_i915_private {
> >
> > struct i915_pmu pmu;
> >
> > + struct i915_hdcp_comp_master *hdcp_master;
> > + bool hdcp_comp_added;
> > +
> > + /* Mutex to protect the above hdcp component related values. */
> > + struct mutex hdcp_comp_mutex;
> > +
> > /*
> > * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > * will be rejected. Instead look for a better place.
> > diff --git a/drivers/gpu/drm/i915/intel_connector.c
> > b/drivers/gpu/drm/i915/intel_connector.c
> > index ee16758747c5..66ed3ee5998a 100644
> > --- a/drivers/gpu/drm/i915/intel_connector.c
> > +++ b/drivers/gpu/drm/i915/intel_connector.c
> > @@ -88,6 +88,8 @@ void intel_connector_destroy(struct drm_connector
> > *connector)
> >
> > kfree(intel_connector->detect_edid);
> >
> > + intel_hdcp_cleanup(intel_connector);
> > +
> > if (!IS_ERR_OR_NULL(intel_connector->edid))
> > kfree(intel_connector->edid);
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 73a107b6eb9a..acb993ce7eaa 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -15453,6 +15453,8 @@ int intel_modeset_init(struct drm_device *dev)
> > intel_update_czclk(dev_priv);
> > intel_modeset_init_hw(dev);
> >
> > + intel_hdcp_component_init(dev_priv);
> > +
> > if (dev_priv->max_cdclk_freq == 0)
> > intel_update_max_cdclk(dev_priv);
> >
> > @@ -16314,6 +16316,8 @@ void intel_modeset_cleanup(struct drm_device
> *dev)
> > /* flush any delayed tasks or pending work */
> > flush_scheduled_work();
> >
> > + intel_hdcp_component_fini(dev_priv);
> > +
> > drm_mode_config_cleanup(dev);
> >
> > intel_overlay_cleanup(dev_priv);
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 11c696025085..f8e8482573c8 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -41,6 +41,7 @@
> > #include <drm/drm_rect.h>
> > #include <drm/drm_vblank.h>
> > #include <drm/drm_atomic.h>
> > +#include <drm/i915_mei_hdcp_interface.h>
> > #include <media/cec-notifier.h>
> >
> > struct drm_printer;
> > @@ -395,6 +396,9 @@ struct intel_hdcp_shim {
> > /* Detects panel's hdcp capability. This is optional for HDMI. */
> > int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
> > bool *hdcp_capable);
> > +
> > + /* HDCP adaptation(DP/HDMI) required on the port */
> > + enum hdcp_wired_protocol protocol;
> > };
> >
> > struct intel_hdcp {
> > @@ -415,6 +419,7 @@ struct intel_hdcp {
> > * content can flow only through a link protected by HDCP2.2.
> > */
> > u8 content_type;
> > + struct hdcp_port_data port_data;
> > };
> >
> > struct intel_connector {
> > @@ -2088,6 +2093,9 @@ 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);
> > +void intel_hdcp_component_init(struct drm_i915_private *dev_priv);
> > +void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
> > +void intel_hdcp_cleanup(struct intel_connector *connector);
> >
> > /* 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 7b1097d79fb8..d06bef9d1ab2 100644
> > --- a/drivers/gpu/drm/i915/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> > @@ -7,8 +7,10 @@
> > */
> >
> > #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"
> > @@ -832,6 +834,347 @@ bool is_hdcp_supported(struct drm_i915_private
> *dev_priv, enum port port)
> > return INTEL_GEN(dev_priv) >= 9 && port < PORT_E; }
> >
> > +static __attribute__((unused)) int
> > +hdcp2_prepare_ake_init(struct intel_connector *connector,
> > + struct hdcp2_ake_init *ake_data) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->initiate_hdcp2_session(comp->mei_dev, data,
> ake_data);
> > + if (ret)
> > + DRM_DEBUG_KMS("Prepare_ake_init failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused)) int
> > +hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
> > + struct hdcp2_ake_send_cert *rx_cert,
> > + bool *paired,
> > + struct hdcp2_ake_no_stored_km *ek_pub_km,
> > + size_t *msg_sz)
> > +{
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->verify_receiver_cert_prepare_km(comp->mei_dev,
> data,
> > + rx_cert, paired,
> > + ek_pub_km, msg_sz);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Verify rx_cert failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused)) int
> > +hdcp2_verify_hprime(struct intel_connector *connector,
> > + struct hdcp2_ake_send_hprime *rx_hprime) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->verify_hprime(comp->mei_dev, data, rx_hprime);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Verify hprime failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused)) int
> > +hdcp2_store_pairing_info(struct intel_connector *connector,
> > + struct hdcp2_ake_send_pairing_info *pairing_info) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->store_pairing_info(comp->mei_dev, data,
> pairing_info);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Store pairing info failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused)) int
> > +hdcp2_prepare_lc_init(struct intel_connector *connector,
> > + struct hdcp2_lc_init *lc_init) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->initiate_locality_check(comp->mei_dev, data, lc_init);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Prepare lc_init failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused)) int
> > +hdcp2_verify_lprime(struct intel_connector *connector,
> > + struct hdcp2_lc_send_lprime *rx_lprime) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->verify_lprime(comp->mei_dev, data, rx_lprime);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Verify L_Prime failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused))
> > +int hdcp2_prepare_skey(struct intel_connector *connector,
> > + struct hdcp2_ske_send_eks *ske_data) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->get_session_key(comp->mei_dev, data, ske_data);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Get session key failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused)) int
> > +hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
> > + struct hdcp2_rep_send_receiverid_list
> > +
> *rep_topology,
> > + struct hdcp2_rep_send_ack *rep_send_ack)
> {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->repeater_check_flow_prepare_ack(comp->mei_dev,
> data,
> > + rep_topology,
> > + rep_send_ack);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Verify rep topology failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused)) int
> > +hdcp2_verify_mprime(struct intel_connector *connector,
> > + struct hdcp2_rep_stream_ready *stream_ready) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->verify_mprime(comp->mei_dev, data, stream_ready);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Verify mprime failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused))
> > +int hdcp2_authenticate_port(struct intel_connector *connector) {
> > + struct hdcp_port_data *data = &connector->hdcp.port_data;
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->enable_hdcp_authentication(comp->mei_dev, data);
> > + if (ret < 0)
> > + DRM_DEBUG_KMS("Enable hdcp auth failed. %d\n", ret);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused))
> > +int hdcp2_close_mei_session(struct intel_connector *connector) {
> > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > + struct i915_hdcp_comp_master *comp;
> > + int ret;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + comp = dev_priv->hdcp_master;
> > +
> > + if (!comp || !comp->ops) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return -EINVAL;
> > + }
> > +
> > + ret = comp->ops->close_hdcp_session(comp->mei_dev,
> > + &connector->hdcp.port_data);
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return ret;
> > +}
> > +
> > +static __attribute__((unused))
> > +int hdcp2_deauthenticate_port(struct intel_connector *connector) {
> > + return hdcp2_close_mei_session(connector);
> > +}
> > +
> > +static int i915_hdcp_component_bind(struct device *i915_kdev,
> > + struct device *mei_kdev, void *data) {
> > + struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
> > +
> > + DRM_DEBUG("I915 HDCP comp bind\n");
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + dev_priv->hdcp_master = (struct i915_hdcp_comp_master *)data;
> > + dev_priv->hdcp_master->mei_dev = mei_kdev;
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + return 0;
> > +}
> > +
> > +static void i915_hdcp_component_unbind(struct device *i915_kdev,
> > + struct device *mei_kdev, void *data) {
> > + struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
> > +
> > + DRM_DEBUG("I915 HDCP comp unbind\n");
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + dev_priv->hdcp_master = NULL;
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +}
> > +
> > +static const struct component_ops i915_hdcp_component_ops = {
> > + .bind = i915_hdcp_component_bind,
> > + .unbind = i915_hdcp_component_unbind, };
> > +
> > +static inline int initialize_hdcp_port_data(struct intel_connector
> > +*connector) {
> > + struct intel_hdcp *hdcp = &connector->hdcp;
> > + struct hdcp_port_data *data = &hdcp->port_data;
> > +
> > + data->port = connector->encoder->port;
> > + data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
> > + data->protocol = (u8)hdcp->shim->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;
> > +}
> > +
> > static bool is_hdcp2_supported(struct drm_i915_private *dev_priv) {
> > if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
> > @@ -841,11 +1184,40 @@ static bool is_hdcp2_supported(struct
> drm_i915_private *dev_priv)
> > IS_KABYLAKE(dev_priv));
> > }
> >
> > +void intel_hdcp_component_init(struct drm_i915_private *dev_priv) {
> > + int ret;
> > +
> > + if (!is_hdcp2_supported(dev_priv))
> > + return;
> > +
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + WARN_ON(dev_priv->hdcp_comp_added);
> > +
> > + dev_priv->hdcp_comp_added = true;
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + ret = component_add_typed(dev_priv->drm.dev,
> &i915_hdcp_component_ops,
> > + I915_COMPONENT_HDCP);
> > + if (ret < 0) {
> > + DRM_DEBUG_KMS("Failed at component add(%d)\n", ret);
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + dev_priv->hdcp_comp_added = false;
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return;
> > + }
> > +}
> > +
> > static void intel_hdcp2_init(struct intel_connector *connector) {
> > struct intel_hdcp *hdcp = &connector->hdcp;
> > + int ret;
> > +
> > + ret = initialize_hdcp_port_data(connector);
> > + if (ret) {
> > + DRM_DEBUG_KMS("Mei hdcp data init failed\n");
> > + return;
> > + }
> >
> > - /* TODO: MEI interface needs to be initialized here */
> > hdcp->hdcp2_supported = true;
> > }
> >
> > @@ -917,6 +1289,30 @@ int intel_hdcp_disable(struct intel_connector
> *connector)
> > return ret;
> > }
> >
> > +void intel_hdcp_component_fini(struct drm_i915_private *dev_priv) {
> > + mutex_lock(&dev_priv->hdcp_comp_mutex);
> > + if (!dev_priv->hdcp_comp_added) {
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > + return;
> > + }
> > +
> > + dev_priv->hdcp_comp_added = false;
> > + mutex_unlock(&dev_priv->hdcp_comp_mutex);
> > +
> > + component_del(dev_priv->drm.dev, &i915_hdcp_component_ops); }
> > +
> > +void intel_hdcp_cleanup(struct intel_connector *connector) {
> > + if (!connector->hdcp.shim)
> > + return;
> > +
> > + mutex_lock(&connector->hdcp.mutex);
> > + kfree(connector->hdcp.port_data.streams);
> > + mutex_unlock(&connector->hdcp.mutex);
> > +}
> > +
> > void intel_hdcp_atomic_check(struct drm_connector *connector,
> > struct drm_connector_state *old_state,
> > struct drm_connector_state *new_state)
> > --
> > 2.7.4
> >
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 32/33] misc/mei/hdcp: Component framework for I915 Interface
2019-02-16 17:37 ` [PATCH v14 32/33] misc/mei/hdcp: Component framework for I915 Interface Ramalingam C
@ 2019-02-21 12:15 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 12:15 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> Mei hdcp driver is designed as component slave for the I915 component
> master.
>
> v2: Rebased.
> v3:
> Notifier chain is adopted for cldev state update [Tomas]
> v4:
> Made static dummy functions as inline in mei_hdcp.h
> API for polling client device status
> IS_ENABLED used in header, for config status for mei_hdcp.
> v5:
> Replacing the notifier with component framework. [Daniel]
> v6:
> Rebased on the I915 comp master redesign.
> v7:
> mei_hdcp_component_registered is made static [Uma]
> Need for global static variable mei_cldev is removed.
> v8:
> master comp is added to be matched with i915 subcomponent [daniel]
> v9:
> only comp_master is set and retrieved as driver_data [Daniel]
> Reviewed-by Daniel.
> v10:
> small corrections at probe [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 82
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 80 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 2afc7d31dacc..ad55b41550d6 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -23,6 +23,7 @@
> #include <linux/slab.h>
> #include <linux/uuid.h>
> #include <linux/mei_cl_bus.h>
> +#include <linux/component.h>
> #include <drm/drm_connector.h>
> #include <drm/i915_component.h>
> #include <drm/i915_mei_hdcp_interface.h> @@ -711,8 +712,7 @@
> mei_hdcp_close_session(struct device *dev, struct hdcp_port_data *data)
> return 0;
> }
>
> -static __attribute__((unused))
> -struct i915_hdcp_component_ops mei_hdcp_ops = {
> +static struct i915_hdcp_component_ops mei_hdcp_ops = {
Should be 'const' too.
> .owner = THIS_MODULE,
> .initiate_hdcp2_session = mei_hdcp_initiate_session,
> .verify_receiver_cert_prepare_km =
> @@ -729,20 +729,98 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> .close_hdcp_session = mei_hdcp_close_session, };
>
> +static int mei_component_master_bind(struct device *dev) {
> + struct mei_cl_device *cldev = to_mei_cl_device(dev);
> + struct i915_hdcp_comp_master *comp_master =
> +
> mei_cldev_get_drvdata(cldev);
> + int ret;
> +
> + dev_info(dev, "%s\n", __func__);
Need change this to dev_dbg() it will pollute log
> + comp_master->ops = &mei_hdcp_ops;
> + comp_master->mei_dev = dev;
> + ret = component_bind_all(dev, comp_master);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static void mei_component_master_unbind(struct device *dev) {
> + struct mei_cl_device *cldev = to_mei_cl_device(dev);
> + struct i915_hdcp_comp_master *comp_master =
> +
> mei_cldev_get_drvdata(cldev);
> +
> + dev_info(dev, "%s\n", __func__);
> + component_unbind_all(dev, comp_master); }
> +
> +static const struct component_master_ops mei_component_master_ops = {
> + .bind = mei_component_master_bind,
> + .unbind = mei_component_master_unbind, };
> +
> +static int mei_hdcp_component_match(struct device *dev, int subcomponent,
> + void *data)
> +{
> + return !strcmp(dev->driver->name, "i915") &&
> + subcomponent == I915_COMPONENT_HDCP; }
> +
> static int mei_hdcp_probe(struct mei_cl_device *cldev,
> const struct mei_cl_device_id *id) {
> + struct i915_hdcp_comp_master *comp_master;
> + struct component_match *master_match;
> int ret;
>
> ret = mei_cldev_enable(cldev);
> if (ret < 0)
> dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
If this is not a fatal condition than should not print in dev_err()
>
> + comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
> + if (!comp_master) {
> + ret = -ENOMEM;
> + goto err_exit;
> + }
> +
> + master_match = NULL;
> + component_match_add_typed(&cldev->dev, &master_match,
> + mei_hdcp_component_match,
> comp_master);
> + if (IS_ERR_OR_NULL(master_match)) {
> + ret = -ENOMEM;
> + goto err_exit;
> + }
> +
> + mei_cldev_set_drvdata(cldev, comp_master);
> + ret = component_master_add_with_match(&cldev->dev,
> + &mei_component_master_ops,
> + master_match);
> + if (ret < 0) {
> + dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
> + goto err_exit;
> + }
> +
> + return 0;
> +
> +err_exit:
> + mei_cldev_set_drvdata(cldev, NULL);
> + kfree(comp_master);
> + mei_cldev_disable(cldev);
> +
> return ret;
> }
>
> static int mei_hdcp_remove(struct mei_cl_device *cldev) {
> + struct i915_hdcp_comp_master *comp_master =
> +
> mei_cldev_get_drvdata(cldev);
> +
> + component_master_del(&cldev->dev, &mei_component_master_ops);
> + kfree(comp_master);
> + mei_cldev_set_drvdata(cldev, NULL);
> +
> return mei_cldev_disable(cldev);
> }
>
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH v14 20/33] misc/mei/hdcp: Define ME FW interface for HDCP2.2
2019-02-16 17:37 ` [PATCH v14 20/33] misc/mei/hdcp: Define ME FW interface for HDCP2.2 Ramalingam C via dri-devel
@ 2019-02-21 12:42 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 12:42 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> Defines the HDCP specific ME FW interfaces such as Request CMDs, payload
> structure for CMDs and their response status codes.
>
> This patch defines payload size(Excluding the Header)for each WIRED
> HDCP2.2 CMDs.
>
> v2: Rebased.
> v3:
> Extra comments are removed.
> v4:
> %s/\/\*\*/\/\*
> v5:
> Extra lines are removed.
> v6:
> Remove redundant text from the License header
> %s/LPRIME_HALF/V_PRIME_HALF
> %s/uintxx_t/uxx
> v7:
> Extra taps removed.
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com> Acked-by Tomas
> Winkler <tomas.winkler@intel.com>
> ---
> drivers/misc/mei/hdcp/mei_hdcp.h | 366
> +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 366 insertions(+)
> create mode 100644 drivers/misc/mei/hdcp/mei_hdcp.h
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.h
> b/drivers/misc/mei/hdcp/mei_hdcp.h
> new file mode 100644
> index 000000000000..582a7e27ae29
> --- /dev/null
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.h
> @@ -0,0 +1,366 @@
> +/* SPDX-License-Identifier: (GPL-2.0+) */
> +/*
> + * Copyright © 2017-2018 Intel Corporation
2019
> + *
> + * Authors:
> + * Ramalingam C <ramalingam.c@intel.com> */
> +
> +#ifndef __MEI_HDCP_H__
> +#define __MEI_HDCP_H__
> +
> +#include <drm/drm_hdcp.h>
> +
> +/* me_hdcp_status: Enumeration of all HDCP Status Codes */ enum
> +me_hdcp_status {
> + ME_HDCP_STATUS_SUCCESS = 0x0000,
> +
> + /* WiDi Generic Status Codes */
> + ME_HDCP_STATUS_INTERNAL_ERROR = 0x1000,
> + ME_HDCP_STATUS_UNKNOWN_ERROR = 0x1001,
> + ME_HDCP_STATUS_INCORRECT_API_VERSION = 0x1002,
> + ME_HDCP_STATUS_INVALID_FUNCTION = 0x1003,
> + ME_HDCP_STATUS_INVALID_BUFFER_LENGTH = 0x1004,
> + ME_HDCP_STATUS_INVALID_PARAMS = 0x1005,
> + ME_HDCP_STATUS_AUTHENTICATION_FAILED = 0x1006,
> +
> + /* WiDi Status Codes */
> + ME_HDCP_INVALID_SESSION_STATE = 0x6000,
> + ME_HDCP_SRM_FRAGMENT_UNEXPECTED = 0x6001,
> + ME_HDCP_SRM_INVALID_LENGTH = 0x6002,
> + ME_HDCP_SRM_FRAGMENT_OFFSET_INVALID = 0x6003,
> + ME_HDCP_SRM_VERIFICATION_FAILED = 0x6004,
> + ME_HDCP_SRM_VERSION_TOO_OLD = 0x6005,
> + ME_HDCP_RX_CERT_VERIFICATION_FAILED = 0x6006,
> + ME_HDCP_RX_REVOKED = 0x6007,
> + ME_HDCP_H_VERIFICATION_FAILED = 0x6008,
> + ME_HDCP_REPEATER_CHECK_UNEXPECTED = 0x6009,
> + ME_HDCP_TOPOLOGY_MAX_EXCEEDED = 0x600A,
> + ME_HDCP_V_VERIFICATION_FAILED = 0x600B,
> + ME_HDCP_L_VERIFICATION_FAILED = 0x600C,
> + ME_HDCP_STREAM_KEY_ALLOC_FAILED = 0x600D,
> + ME_HDCP_BASE_KEY_RESET_FAILED = 0x600E,
> + ME_HDCP_NONCE_GENERATION_FAILED = 0x600F,
> + ME_HDCP_STATUS_INVALID_E_KEY_STATE = 0x6010,
> + ME_HDCP_STATUS_INVALID_CS_ICV = 0x6011,
> + ME_HDCP_STATUS_INVALID_KB_KEY_STATE = 0x6012,
> + ME_HDCP_STATUS_INVALID_PAVP_MODE_ICV = 0x6013,
> + ME_HDCP_STATUS_INVALID_PAVP_MODE = 0x6014,
> + ME_HDCP_STATUS_LC_MAX_ATTEMPTS = 0x6015,
> +
> + /* New status for HDCP 2.1 */
> + ME_HDCP_STATUS_MISMATCH_IN_M = 0x6016,
> +
> + /* New status code for HDCP 2.2 Rx */
> + ME_HDCP_STATUS_RX_PROV_NOT_ALLOWED = 0x6017,
> + ME_HDCP_STATUS_RX_PROV_WRONG_SUBJECT = 0x6018,
> + ME_HDCP_RX_NEEDS_PROVISIONING = 0x6019,
> + ME_HDCP_BKSV_ICV_AUTH_FAILED = 0x6020,
> + ME_HDCP_STATUS_INVALID_STREAM_ID = 0x6021,
> + ME_HDCP_STATUS_CHAIN_NOT_INITIALIZED = 0x6022,
> + ME_HDCP_FAIL_NOT_EXPECTED = 0x6023,
> + ME_HDCP_FAIL_HDCP_OFF = 0x6024,
> + ME_HDCP_FAIL_INVALID_PAVP_MEMORY_MODE = 0x6025,
> + ME_HDCP_FAIL_AES_ECB_FAILURE = 0x6026,
> + ME_HDCP_FEATURE_NOT_SUPPORTED = 0x6027,
> + ME_HDCP_DMA_READ_ERROR = 0x6028,
> + ME_HDCP_DMA_WRITE_ERROR = 0x6029,
> + ME_HDCP_FAIL_INVALID_PACKET_SIZE = 0x6030,
> + ME_HDCP_H264_PARSING_ERROR = 0x6031,
> + ME_HDCP_HDCP2_ERRATA_VIDEO_VIOLATION = 0x6032,
> + ME_HDCP_HDCP2_ERRATA_AUDIO_VIOLATION = 0x6033,
> + ME_HDCP_TX_ACTIVE_ERROR = 0x6034,
> + ME_HDCP_MODE_CHANGE_ERROR = 0x6035,
> + ME_HDCP_STREAM_TYPE_ERROR = 0x6036,
> + ME_HDCP_STREAM_MANAGE_NOT_POSSIBLE = 0x6037,
> +
> + ME_HDCP_STATUS_PORT_INVALID_COMMAND = 0x6038,
> + ME_HDCP_STATUS_UNSUPPORTED_PROTOCOL = 0x6039,
> + ME_HDCP_STATUS_INVALID_PORT_INDEX = 0x603a,
> + ME_HDCP_STATUS_TX_AUTH_NEEDED = 0x603b,
> + ME_HDCP_STATUS_NOT_INTEGRATED_PORT = 0x603c,
> + ME_HDCP_STATUS_SESSION_MAX_REACHED = 0x603d,
> +
> + /* hdcp capable bit is not set in rx_caps(error is unique to DP) */
> + ME_HDCP_STATUS_NOT_HDCP_CAPABLE = 0x6041,
> +
> + ME_HDCP_STATUS_INVALID_STREAM_COUNT = 0x6042,
> +};
> +
> +#define HDCP_API_VERSION 0x00010000
> +
> +#define HDCP_M_LEN 16
> +#define HDCP_KH_LEN 16
> +
> +/* Payload Buffer size(Excluding Header) for CMDs and corresponding
> +response */
> +/* Wired_Tx_AKE */
> +#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN (4 + 1)
> +#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_OUT (4 + 8
> + 3)
> +
> +#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN (4 +
> 522 + 8 + 3)
> +#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MIN_OUT
> (4 + 1 + 3 + 16 + 16)
> +#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MAX_OUT
> (4 + 1 + 3 + 128)
> +
> +#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN (4 +
> 32)
> +#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_OUT
> (4)
> +
> +#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN
> (4 + 16)
> +#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_OUT
> (4)
> +
> +#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN (4)
> +#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_OUT (4)
> +
> +/* Wired_Tx_LC */
> +#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN (4)
> +#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_OUT (4 + 8)
> +
> +#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN
> (4 + 32)
> +#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_OUT
> (4)
> +
> +/* Wired_Tx_SKE */
> +#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN (4)
> +#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_OUT
> (4 + 16 + 8)
> +
> +/* Wired_Tx_SKE */
> +#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN (4 + 1)
> +#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_OUT (4)
> +
> +/* Wired_Tx_Repeater */
> +#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN (4 + 2
> + 3 + 16 + 155)
> +#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_OUT
> (4 + 1 + 16)
> +
> +#define
> WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN
> (4 + 3 + \
> + 32 + 2 + 2)
> +
> +#define WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_OUT
> (4)
> +
> +/* hdcp_command_id: Enumeration of all WIRED HDCP Command IDs */
> enum
> +hdcp_command_id {
> + _WIDI_COMMAND_BASE = 0x00030000,
> + WIDI_INITIATE_HDCP2_SESSION = _WIDI_COMMAND_BASE,
> + HDCP_GET_SRM_STATUS,
> + HDCP_SEND_SRM_FRAGMENT,
> +
> + /* The wired HDCP Tx commands */
> + _WIRED_COMMAND_BASE = 0x00031000,
> + WIRED_INITIATE_HDCP2_SESSION = _WIRED_COMMAND_BASE,
> + WIRED_VERIFY_RECEIVER_CERT,
> + WIRED_AKE_SEND_HPRIME,
> + WIRED_AKE_SEND_PAIRING_INFO,
> + WIRED_INIT_LOCALITY_CHECK,
> + WIRED_VALIDATE_LOCALITY,
> + WIRED_GET_SESSION_KEY,
> + WIRED_ENABLE_AUTH,
> + WIRED_VERIFY_REPEATER,
> + WIRED_REPEATER_AUTH_STREAM_REQ,
> + WIRED_CLOSE_SESSION,
> +
> + _WIRED_COMMANDS_COUNT,
> +};
> +
> +union encrypted_buff {
> + u8 e_kpub_km[HDCP_2_2_E_KPUB_KM_LEN];
> + u8 e_kh_km_m[HDCP_2_2_E_KH_KM_M_LEN];
> + struct {
> + u8 e_kh_km[HDCP_KH_LEN];
> + u8 m[HDCP_M_LEN];
> + } __packed;
> +};
> +
> +/* HDCP HECI message header. All header values are little endian. */
> +struct hdcp_cmd_header {
> + u32 api_version;
> + u32 command_id;
> + enum me_hdcp_status status;
> + /* Length of the HECI message (excluding the header) */
> + u32 buffer_len;
> +} __packed;
> +
> +/* Empty command request or response. No data follows the header. */
> +struct hdcp_cmd_no_data {
> + struct hdcp_cmd_header header;
> +} __packed;
> +
> +/* Uniquely identifies the hdcp port being addressed for a given
> +command. */ struct hdcp_port_id {
> + u8 integrated_port_type;
> + u8 physical_port;
> + u16 reserved;
> +} __packed;
> +
> +/*
> + * Data structures for integrated wired HDCP2 Tx in
> + * support of the AKE protocol
> + */
> +/* HECI struct for integrated wired HDCP Tx session initiation. */
> +struct wired_cmd_initiate_hdcp2_session_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 protocol; /* for HDMI vs DP */
> +} __packed;
> +
> +struct wired_cmd_initiate_hdcp2_session_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 r_tx[HDCP_2_2_RTX_LEN];
> + struct hdcp2_tx_caps tx_caps;
> +} __packed;
> +
> +/* HECI struct for ending an integrated wired HDCP Tx session. */
> +struct wired_cmd_close_session_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +struct wired_cmd_close_session_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +/* HECI struct for integrated wired HDCP Tx Rx Cert verification. */
> +struct wired_cmd_verify_receiver_cert_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + struct hdcp2_cert_rx cert_rx;
> + u8 r_rx[HDCP_2_2_RRX_LEN];
> + u8 rx_caps[HDCP_2_2_RXCAPS_LEN];
> +} __packed;
> +
> +struct wired_cmd_verify_receiver_cert_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 km_stored;
> + u8 reserved[3];
> + union encrypted_buff ekm_buff;
> +} __packed;
> +
> +/* HECI struct for verification of Rx's Hprime in a HDCP Tx session */
> +struct wired_cmd_ake_send_hprime_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 h_prime[HDCP_2_2_H_PRIME_LEN];
> +} __packed;
> +
> +struct wired_cmd_ake_send_hprime_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +/*
> + * HECI struct for sending in AKE pairing data generated by the Rx in
> +an
> + * integrated wired HDCP Tx session.
> + */
> +struct wired_cmd_ake_send_pairing_info_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 e_kh_km[HDCP_2_2_E_KH_KM_LEN];
> +} __packed;
> +
> +struct wired_cmd_ake_send_pairing_info_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +/* Data structures for integrated wired HDCP2 Tx in support of the LC
> +protocol*/
> +/*
> + * HECI struct for initiating locality check with an
> + * integrated wired HDCP Tx session.
> + */
> +struct wired_cmd_init_locality_check_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +struct wired_cmd_init_locality_check_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 r_n[HDCP_2_2_RN_LEN];
> +} __packed;
> +
> +/*
> + * HECI struct for validating an Rx's LPrime value in an
> + * integrated wired HDCP Tx session.
> + */
> +struct wired_cmd_validate_locality_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 l_prime[HDCP_2_2_L_PRIME_LEN];
> +} __packed;
> +
> +struct wired_cmd_validate_locality_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +/*
> + * Data structures for integrated wired HDCP2 Tx in support of the
> + * SKE protocol
> + */
> +/* HECI struct for creating session key */ struct
> +wired_cmd_get_session_key_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +struct wired_cmd_get_session_key_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 e_dkey_ks[HDCP_2_2_E_DKEY_KS_LEN];
> + u8 r_iv[HDCP_2_2_RIV_LEN];
> +} __packed;
> +
> +/* HECI struct for the Tx enable authentication command */ struct
> +wired_cmd_enable_auth_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 stream_type;
> +} __packed;
> +
> +struct wired_cmd_enable_auth_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> +} __packed;
> +
> +/*
> + * Data structures for integrated wired HDCP2 Tx in support of
> + * the repeater protocols
> + */
> +/*
> + * HECI struct for verifying the downstream repeater's HDCP topology in
> +an
> + * integrated wired HDCP Tx session.
> + */
> +struct wired_cmd_verify_repeater_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 rx_info[HDCP_2_2_RXINFO_LEN];
> + u8 seq_num_v[HDCP_2_2_SEQ_NUM_LEN];
> + u8 v_prime[HDCP_2_2_V_PRIME_HALF_LEN];
> + u8
> receiver_ids[HDCP_2_2_RECEIVER_IDS_MAX_LEN];
> +} __packed;
> +
> +struct wired_cmd_verify_repeater_out {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8 content_type_supported;
> + u8 v[HDCP_2_2_V_PRIME_HALF_LEN];
> +} __packed;
> +
> +/*
> + * HECI struct in support of stream management in an
> + * integrated wired HDCP Tx session.
> + */
> +struct wired_cmd_repeater_auth_stream_req_in {
> + struct hdcp_cmd_header header;
> + struct hdcp_port_id port;
> + u8
> seq_num_m[HDCP_2_2_SEQ_NUM_LEN];
> + u8 m_prime[HDCP_2_2_MPRIME_LEN];
> + u16 k;
This is big endian
__be16 k;
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 21/33] misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session
2019-02-16 17:37 ` [PATCH v14 21/33] misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session Ramalingam C
@ 2019-02-21 13:30 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:30 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
> On Success, ME FW will start a HDCP2.2 session for the port and provides the
> content for HDCP2.2 AKE_Init message.
>
> v2: Rebased.
> v3:
> cldev is add as a separate parameter [Tomas]
> Redundant comment and typecast are removed [Tomas]
> v4:
> %zd is used for size [Alexander]
> %s/return -1/return -EIO [Alexander]
> Spellings in commit msg is fixed [Uma]
> v5: Rebased.
> v6:
> Collected the rb-ed by.
> Realigning the patches in the series.
> v7:
> Adjust to the new mei interface.
> Fix for kdoc.
> v8:
> K-Doc Addition.
> memcpy for const length.
> v9:
> s/mei_hdcp_ddi/mei_fw_ddi
> s/i915_port/mei_i915_port [Tomas]
> renamed func as mei_hdcp_* [Tomas]
> Instead of macro, inline func for ddi index is used. [Tomas]
> v10:
> Switch case for the coversion between i915_port to mei_ddi [Tomas]
> Kernel doc fix.
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 94
> ++++++++++++++++++++++++++++++++++++++++
> drivers/misc/mei/hdcp/mei_hdcp.h | 11 +++++
> 2 files changed, 105 insertions(+)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 8df069c1b0cc..952bae79dd02 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -23,6 +23,100 @@
> #include <linux/slab.h>
> #include <linux/uuid.h>
> #include <linux/mei_cl_bus.h>
> +#include <drm/drm_connector.h>
> +#include <drm/i915_component.h>
> +#include <drm/i915_mei_hdcp_interface.h>
> +
> +#include "mei_hdcp.h"
> +
> +static inline u8 mei_get_ddi_index(enum port port) {
> + switch (port) {
> + case PORT_A:
> + return MEI_DDI_A;
> + case PORT_B ... PORT_F:
> + return (u8)port;
> + default:
> + return MEI_DDI_INVALID_PORT;
> + }
> +}
> +
> +/**
> + * mei_hdcp_initiate_session() - Initiate a Wired HDCP2.2 Tx Session in
> +ME FW
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @ake_data: AKE_Init msg output.
> + *
> + * Return: 0 on Success, <0 on Failure.
> + */
> +static int
> +mei_hdcp_initiate_session(struct device *dev, struct hdcp_port_data *data,
> + struct hdcp2_ake_init *ake_data)
> +{
> + struct wired_cmd_initiate_hdcp2_session_in session_init_in = { { 0 } };
> + struct wired_cmd_initiate_hdcp2_session_out
> + session_init_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !ake_data)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + session_init_in.header.api_version = HDCP_API_VERSION;
> + session_init_in.header.command_id =
> WIRED_INITIATE_HDCP2_SESSION;
> + session_init_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + session_init_in.header.buffer_len =
> +
> WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN;
> +
> + session_init_in.port.integrated_port_type = data->port_type;
> + session_init_in.port.physical_port = mei_get_ddi_index(data->port);
> + session_init_in.protocol = data->protocol;
> +
> + byte = mei_cldev_send(cldev, (u8 *)&session_init_in,
> + sizeof(session_init_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&session_init_out,
> + sizeof(session_init_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (session_init_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
> + WIRED_INITIATE_HDCP2_SESSION,
> + session_init_out.header.status);
> + return -EIO;
> + }
> +
> + ake_data->msg_id = HDCP_2_2_AKE_INIT;
> + ake_data->tx_caps = session_init_out.tx_caps;
> + memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN);
> +
> + return 0;
> +}
> +
> +static __attribute__((unused))
> +struct i915_hdcp_component_ops mei_hdcp_ops = {
> + .owner = THIS_MODULE,
> + .initiate_hdcp2_session = mei_hdcp_initiate_session,
> + .verify_receiver_cert_prepare_km = NULL,
> + .verify_hprime = NULL,
> + .store_pairing_info = NULL,
> + .initiate_locality_check = NULL,
> + .verify_lprime = NULL,
> + .get_session_key = NULL,
> + .repeater_check_flow_prepare_ack = NULL,
> + .verify_mprime = NULL,
> + .enable_hdcp_authentication = NULL,
> + .close_hdcp_session = NULL,
> +};
>
> static int mei_hdcp_probe(struct mei_cl_device *cldev,
> const struct mei_cl_device_id *id) diff --git
> a/drivers/misc/mei/hdcp/mei_hdcp.h b/drivers/misc/mei/hdcp/mei_hdcp.h
> index 582a7e27ae29..1eca72a9c1c2 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.h
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.h
> @@ -363,4 +363,15 @@ struct wired_cmd_repeater_auth_stream_req_out {
> struct hdcp_port_id port;
> } __packed;
>
> +enum mei_fw_ddi {
> + MEI_DDI_INVALID_PORT = 0x0,
> +
> + MEI_DDI_B = 1,
> + MEI_DDI_C,
> + MEI_DDI_D,
> + MEI_DDI_E,
> + MEI_DDI_F,
> + MEI_DDI_A = 7,
> + MEI_DDI_RANGE_END = MEI_DDI_A,
> +};
> #endif /* __MEI_HDCP_H__ */
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime
2019-02-16 17:37 ` [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime Ramalingam C
@ 2019-02-21 13:32 ` Winkler, Tomas
2019-02-21 13:33 ` Winkler, Tomas
1 sibling, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:32 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> Requests for the verification of AKE_Send_H_prime.
>
> ME will calculate the H and comparing it with received H_Prime.
> The result will be returned as status.
>
> Here AKE_Send_H_prime is a HDCP2.2 Authentication msg.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Styles and typos fixed [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc Addition [Tomas]
> memcpy for const length.
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 58
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 57 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 922c6a76bb9f..0a4087a2efd5 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -182,13 +182,69 @@ mei_hdcp_verify_receiver_cert_prepare_km(struct
> device *dev,
> return 0;
> }
>
> +/**
> + * mei_hdcp_verify_hprime() - Verify AKE_Send_H_prime at ME FW.
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @rx_hprime: AKE_Send_H_prime msg for ME FW verification
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_verify_hprime(struct device *dev, struct hdcp_port_data *data,
> + struct hdcp2_ake_send_hprime *rx_hprime) {
> + struct wired_cmd_ake_send_hprime_in send_hprime_in = { { 0 } };
> + struct wired_cmd_ake_send_hprime_out send_hprime_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !rx_hprime)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + send_hprime_in.header.api_version = HDCP_API_VERSION;
> + send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME;
> + send_hprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + send_hprime_in.header.buffer_len =
> +WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN;
> +
> + send_hprime_in.port.integrated_port_type = data->port_type;
> + send_hprime_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + memcpy(send_hprime_in.h_prime, rx_hprime->h_prime,
> + HDCP_2_2_H_PRIME_LEN);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&send_hprime_in,
> + sizeof(send_hprime_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&send_hprime_out,
> + sizeof(send_hprime_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (send_hprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
> + WIRED_AKE_SEND_HPRIME,
> send_hprime_out.header.status);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> .initiate_hdcp2_session = mei_hdcp_initiate_session,
> .verify_receiver_cert_prepare_km =
> mei_hdcp_verify_receiver_cert_prepare_km,
> - .verify_hprime = NULL,
> + .verify_hprime = mei_hdcp_verify_hprime,
> .store_pairing_info = NULL,
> .initiate_locality_check = NULL,
> .verify_lprime = NULL,
> --
> 2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime
2019-02-16 17:37 ` [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime Ramalingam C
2019-02-21 13:32 ` Winkler, Tomas
@ 2019-02-21 13:33 ` Winkler, Tomas
1 sibling, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:33 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
> Requests for the verification of AKE_Send_H_prime.
>
> ME will calculate the H and comparing it with received H_Prime.
> The result will be returned as status.
>
> Here AKE_Send_H_prime is a HDCP2.2 Authentication msg.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Styles and typos fixed [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc Addition [Tomas]
> memcpy for const length.
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 58
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 57 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 922c6a76bb9f..0a4087a2efd5 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -182,13 +182,69 @@ mei_hdcp_verify_receiver_cert_prepare_km(struct
> device *dev,
> return 0;
> }
>
> +/**
> + * mei_hdcp_verify_hprime() - Verify AKE_Send_H_prime at ME FW.
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @rx_hprime: AKE_Send_H_prime msg for ME FW verification
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_verify_hprime(struct device *dev, struct hdcp_port_data *data,
> + struct hdcp2_ake_send_hprime *rx_hprime) {
> + struct wired_cmd_ake_send_hprime_in send_hprime_in = { { 0 } };
> + struct wired_cmd_ake_send_hprime_out send_hprime_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !rx_hprime)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + send_hprime_in.header.api_version = HDCP_API_VERSION;
> + send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME;
> + send_hprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + send_hprime_in.header.buffer_len =
> +WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN;
> +
> + send_hprime_in.port.integrated_port_type = data->port_type;
> + send_hprime_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + memcpy(send_hprime_in.h_prime, rx_hprime->h_prime,
> + HDCP_2_2_H_PRIME_LEN);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&send_hprime_in,
> + sizeof(send_hprime_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&send_hprime_out,
> + sizeof(send_hprime_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (send_hprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
> + WIRED_AKE_SEND_HPRIME,
> send_hprime_out.header.status);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> .initiate_hdcp2_session = mei_hdcp_initiate_session,
> .verify_receiver_cert_prepare_km =
> mei_hdcp_verify_receiver_cert_prepare_km,
> - .verify_hprime = NULL,
> + .verify_hprime = mei_hdcp_verify_hprime,
> .store_pairing_info = NULL,
> .initiate_locality_check = NULL,
> .verify_lprime = NULL,
> --
> 2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 22/33] misc/mei/hdcp: Verify Receiver Cert and prepare km
2019-02-16 17:37 ` [PATCH v14 22/33] misc/mei/hdcp: Verify Receiver Cert and prepare km Ramalingam C
@ 2019-02-21 13:39 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:39 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
> Requests for verification for receiver certification and also the preparation for
> next AKE auth message with km.
>
> On Success ME FW validate the HDCP2.2 receivers certificate and do the
> revocation check on the receiver ID. AKE_Stored_Km will be prepared if the
> receiver is already paired, else AKE_No_Stored_Km will be prepared.
>
> Here AKE_Stored_Km and AKE_No_Stored_Km are HDCP2.2 protocol msgs.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd is used for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc Addition. [Tomas]
> memcpy for const length.
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> Fixed the conversion of u8 to bool [Tomas]
> K-Doc fix [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 83
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 82 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 952bae79dd02..922c6a76bb9f 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -102,11 +102,92 @@ mei_hdcp_initiate_session(struct device *dev, struct
> hdcp_port_data *data,
> return 0;
> }
>
> +/**
> + * mei_hdcp_verify_receiver_cert_prepare_km() - Verify the Receiver
> +Certificate
> + * AKE_Send_Cert and prepare AKE_Stored_Km/AKE_No_Stored_Km
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @rx_cert: AKE_Send_Cert for verification
> + * @km_stored: Pairing status flag output
> + * @ek_pub_km: AKE_Stored_Km/AKE_No_Stored_Km output msg
> + * @msg_sz : size of AKE_XXXXX_Km output msg
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_verify_receiver_cert_prepare_km(struct device *dev,
> + struct hdcp_port_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)
> +{
> + struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = { { 0 } };
> + struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + verify_rxcert_in.header.api_version = HDCP_API_VERSION;
> + verify_rxcert_in.header.command_id =
> WIRED_VERIFY_RECEIVER_CERT;
> + verify_rxcert_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + verify_rxcert_in.header.buffer_len =
> +
> WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN;
> +
> + verify_rxcert_in.port.integrated_port_type = data->port_type;
> + verify_rxcert_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + verify_rxcert_in.cert_rx = rx_cert->cert_rx;
> + memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN);
> + memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps,
> +HDCP_2_2_RXCAPS_LEN);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&verify_rxcert_in,
> + sizeof(verify_rxcert_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed: %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&verify_rxcert_out,
> + sizeof(verify_rxcert_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed: %zd\n", byte);
> + return byte;
> + }
> +
> + if (verify_rxcert_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
> + WIRED_VERIFY_RECEIVER_CERT,
> + verify_rxcert_out.header.status);
> + return -EIO;
> + }
> +
> + *km_stored = !!verify_rxcert_out.km_stored;
> + if (verify_rxcert_out.km_stored) {
> + ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM;
> + *msg_sz = sizeof(struct hdcp2_ake_stored_km);
> + } else {
> + ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM;
> + *msg_sz = sizeof(struct hdcp2_ake_no_stored_km);
> + }
> +
> + memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff,
> + sizeof(verify_rxcert_out.ekm_buff));
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> .initiate_hdcp2_session = mei_hdcp_initiate_session,
> - .verify_receiver_cert_prepare_km = NULL,
> + .verify_receiver_cert_prepare_km =
> + mei_hdcp_verify_receiver_cert_prepare_km,
> .verify_hprime = NULL,
> .store_pairing_info = NULL,
> .initiate_locality_check = NULL,
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 25/33] misc/mei/hdcp: Initiate Locality check
2019-02-16 17:37 ` [PATCH v14 25/33] misc/mei/hdcp: Initiate Locality check Ramalingam C
@ 2019-02-21 13:40 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:40 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
> Requests ME to start the second stage of HDCP2.2 authentication, called
> Locality Check.
>
> On Success, ME FW will provide LC_Init message to send to hdcp sink.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd used for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Style fixed [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition. [Tomas]
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 57
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 56 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 1f5514244716..29ef61fd21d2 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -296,6 +296,61 @@ mei_hdcp_store_pairing_info(struct device *dev,
> struct hdcp_port_data *data,
> return 0;
> }
>
> +/**
> + * mei_hdcp_initiate_locality_check() - Prepare LC_Init
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @lc_init_data: LC_Init msg output
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_initiate_locality_check(struct device *dev,
> + struct hdcp_port_data *data,
> + struct hdcp2_lc_init *lc_init_data) {
> + struct wired_cmd_init_locality_check_in lc_init_in = { { 0 } };
> + struct wired_cmd_init_locality_check_out lc_init_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !lc_init_data)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + lc_init_in.header.api_version = HDCP_API_VERSION;
> + lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK;
> + lc_init_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + lc_init_in.header.buffer_len =
> +WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN;
> +
> + lc_init_in.port.integrated_port_type = data->port_type;
> + lc_init_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&lc_init_in, sizeof(lc_init_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&lc_init_out, sizeof(lc_init_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (lc_init_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X Failed. status: 0x%X\n",
> + WIRED_INIT_LOCALITY_CHECK,
> lc_init_out.header.status);
> + return -EIO;
> + }
> +
> + lc_init_data->msg_id = HDCP_2_2_LC_INIT;
> + memcpy(lc_init_data->r_n, lc_init_out.r_n, HDCP_2_2_RN_LEN);
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> @@ -304,7 +359,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> mei_hdcp_verify_receiver_cert_prepare_km,
> .verify_hprime = mei_hdcp_verify_hprime,
> .store_pairing_info = mei_hdcp_store_pairing_info,
> - .initiate_locality_check = NULL,
> + .initiate_locality_check = mei_hdcp_initiate_locality_check,
> .verify_lprime = NULL,
> .get_session_key = NULL,
> .repeater_check_flow_prepare_ack = NULL,
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH v14 26/33] misc/mei/hdcp: Verify L_prime
2019-02-16 17:37 ` [PATCH v14 26/33] misc/mei/hdcp: Verify L_prime Ramalingam C
@ 2019-02-21 13:42 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:42 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
> Request to ME to verify the LPrime received from HDCP sink.
>
> On Success, ME FW will verify the received Lprime by calculating and
> comparing with L.
>
> This represents the completion of Locality Check.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Style fixed [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition. [Tomas]
> memcpy for const length.
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 60
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 59 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 29ef61fd21d2..869a6f22f68d 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -351,6 +351,64 @@ mei_hdcp_initiate_locality_check(struct device *dev,
> return 0;
> }
>
> +/**
> + * mei_hdcp_verify_lprime() - Verify lprime.
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @rx_lprime: LC_Send_L_prime msg for ME FW verification
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_verify_lprime(struct device *dev, struct hdcp_port_data *data,
> + struct hdcp2_lc_send_lprime *rx_lprime) {
> + struct wired_cmd_validate_locality_in verify_lprime_in = { { 0 } };
> + struct wired_cmd_validate_locality_out verify_lprime_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !rx_lprime)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + verify_lprime_in.header.api_version = HDCP_API_VERSION;
> + verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY;
> + verify_lprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + verify_lprime_in.header.buffer_len =
> +
> WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN;
> +
> + verify_lprime_in.port.integrated_port_type = data->port_type;
> + verify_lprime_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime,
> + HDCP_2_2_L_PRIME_LEN);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&verify_lprime_in,
> + sizeof(verify_lprime_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&verify_lprime_out,
> + sizeof(verify_lprime_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (verify_lprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
> + WIRED_VALIDATE_LOCALITY,
> + verify_lprime_out.header.status);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> @@ -360,7 +418,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> .verify_hprime = mei_hdcp_verify_hprime,
> .store_pairing_info = mei_hdcp_store_pairing_info,
> .initiate_locality_check = mei_hdcp_initiate_locality_check,
> - .verify_lprime = NULL,
> + .verify_lprime = mei_hdcp_verify_lprime,
> .get_session_key = NULL,
> .repeater_check_flow_prepare_ack = NULL,
> .verify_mprime = NULL,
> --
> 2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 29/33] misc/mei/hdcp: Verify M_prime
2019-02-16 17:37 ` [PATCH v14 29/33] misc/mei/hdcp: Verify M_prime Ramalingam C via dri-devel
@ 2019-02-21 13:44 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:44 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> Request to ME to verify the M_Prime received from the HDCP sink.
>
> ME FW will calculate the M and compare with M_prime received as part of
> RepeaterAuth_Stream_Ready, which is HDCP2.2 protocol msg.
>
> On successful completion of this stage, downstream propagation of the stream
> management info is completed.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> endianness conversion func is moved to drm_hdcp.h [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition. [Tomas]
> drm_hdcp2_u32_to_seq_num() is used for u32 to seq_num.
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
> +
> + verify_mprime_in.k = __swab16(data->k);
> +
cpu_to_be16(data->k)
> + byte = mei_cldev_send(cldev, (u8 *)&verify_mprime_in,
> + sizeof(verify_mprime_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 24/33] misc/mei/hdcp: Store the HDCP Pairing info
2019-02-16 17:37 ` [PATCH v14 24/33] misc/mei/hdcp: Store the HDCP Pairing info Ramalingam C
@ 2019-02-21 13:46 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:46 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> Provides Pairing info to ME to store.
>
> Pairing is a process to fast track the subsequent authentication with the same
> HDCP sink.
>
> On Success, received HDCP pairing info is stored in non-volatile memory of ME.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Style fixed [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition. [Tomas]
> memcpy for const length.
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 60
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 59 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 0a4087a2efd5..1f5514244716 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -238,6 +238,64 @@ mei_hdcp_verify_hprime(struct device *dev, struct
> hdcp_port_data *data,
> return 0;
> }
>
> +/**
> + * mei_hdcp_store_pairing_info() - Store pairing info received at ME FW
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @pairing_info: AKE_Send_Pairing_Info msg input to ME FW
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_store_pairing_info(struct device *dev, struct hdcp_port_data
> *data,
> + struct hdcp2_ake_send_pairing_info *pairing_info) {
> + struct wired_cmd_ake_send_pairing_info_in pairing_info_in = { { 0 } };
> + struct wired_cmd_ake_send_pairing_info_out pairing_info_out = { { 0 }
> };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !pairing_info)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + pairing_info_in.header.api_version = HDCP_API_VERSION;
> + pairing_info_in.header.command_id =
> WIRED_AKE_SEND_PAIRING_INFO;
> + pairing_info_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + pairing_info_in.header.buffer_len =
> +
> WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN;
> +
> + pairing_info_in.port.integrated_port_type = data->port_type;
> + pairing_info_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km,
> + HDCP_2_2_E_KH_KM_LEN);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&pairing_info_in,
> + sizeof(pairing_info_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&pairing_info_out,
> + sizeof(pairing_info_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (pairing_info_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X failed. Status: 0x%X\n",
> + WIRED_AKE_SEND_PAIRING_INFO,
> + pairing_info_out.header.status);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> @@ -245,7 +303,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> .verify_receiver_cert_prepare_km =
> mei_hdcp_verify_receiver_cert_prepare_km,
> .verify_hprime = mei_hdcp_verify_hprime,
> - .store_pairing_info = NULL,
> + .store_pairing_info = mei_hdcp_store_pairing_info,
> .initiate_locality_check = NULL,
> .verify_lprime = NULL,
> .get_session_key = NULL,
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH v14 19/33] misc/mei/hdcp: Client driver for HDCP application
2019-02-16 17:37 ` [PATCH v14 19/33] misc/mei/hdcp: Client driver for HDCP application Ramalingam C
@ 2019-02-21 13:55 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 13:55 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> ME FW contributes a vital role in HDCP2.2 authentication.
> HDCP2.2 driver needs to communicate to ME FW for each step of the
> HDCP2.2 authentication.
>
> ME FW prepare and HDCP2.2 authentication parameters and encrypt them as
> per spec. With such parameter Driver prepares HDCP2.2 auth messages and
> communicate with HDCP2.2 sink.
>
> Similarly HDCP2.2 sink's response is shared with ME FW for decrypt and
> verification.
>
> Once All the steps of HDCP2.2 authentications are complete on driver's request
> ME FW will configure the port as authenticated and supply the HDCP keys to
> the Gen HW for encryption.
>
> Only after this stage HDCP2.2 driver can start the HDCP2.2 encryption for a
> port.
>
> ME FW is interfaced to kernel through MEI Bus Driver. To obtain the
> HDCP2.2 services from the ME FW through MEI Bus driver MEI Client Driver is
> developed.
>
> v2:
> hdcp files are moved to drivers/misc/mei/hdcp/ [Tomas]
> v3:
> Squashed the Kbuild support [Tomas]
> UUID renamed and Module License is modified [Tomas]
> drv_data is set to null at remove [Tomas]
> v4:
> Module name is changed to "MEI HDCP"
> I915 Selects the MEI_HDCP
> v5:
> Remove redundant text from the License header
> Fix malformed licence
> Removed the drv_data resetting.
> v6:
> K-Doc addition. [Tomas]
> v7:
> %s/UUID_LE/GUID_INIT [Tomas]
> GPL Ver is 2.0 than 2.0+ [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
> drivers/misc/mei/Kconfig | 7 +++++
> drivers/misc/mei/Makefile | 2 ++
> drivers/misc/mei/hdcp/Makefile | 7 +++++
> drivers/misc/mei/hdcp/mei_hdcp.c | 64
> ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 80 insertions(+)
> create mode 100644 drivers/misc/mei/hdcp/Makefile create mode 100644
> drivers/misc/mei/hdcp/mei_hdcp.c
>
> diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig index
> c49e1d2269af..64a7b3483895 100644
> --- a/drivers/misc/mei/Kconfig
> +++ b/drivers/misc/mei/Kconfig
> @@ -43,3 +43,10 @@ config INTEL_MEI_TXE
>
> Supported SoCs:
> Intel Bay Trail
> +
> +config INTEL_MEI_HDCP
> + tristate "Intel HDCP2.2 services of ME Interface"
> + select INTEL_MEI_ME
> + depends on DRM_I915
> + help
> + MEI Support for HDCP2.2 Services on Intel platforms.
Usually we need around 4 lines of doc,
When this should be selected?
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 28/33] misc/mei/hdcp: Repeater topology verification and ack
2019-02-16 17:37 ` [PATCH v14 28/33] misc/mei/hdcp: Repeater topology verification and ack Ramalingam C via dri-devel
@ 2019-02-21 14:16 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 14:16 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
> ack
>
> Request ME to verify the downstream topology information received.
>
> ME FW will validate the Repeaters receiver id list and downstream topology.
>
> On Success ME FW will provide the Least Significant 128bits of VPrime, which
> forms the repeater ack.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Style and typos fixed [Uma]
> v5: Rebased.
> v6: Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition. [Tomas]
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 77
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 76 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index fe5070f901e8..c06a9805ac85 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -466,6 +466,80 @@ static int mei_hdcp_get_session_key(struct device
> *dev,
> return 0;
> }
>
> +/**
> + * mei_hdcp_repeater_check_flow_prepare_ack() - Validate the Downstream
> +topology
> + * and prepare rep_ack.
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @rep_topology: Receiver ID List to be validated
> + * @rep_send_ack : repeater ack from ME FW.
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_repeater_check_flow_prepare_ack(struct device *dev,
> + struct hdcp_port_data *data,
> + struct hdcp2_rep_send_receiverid_list
> + *rep_topology,
> + struct hdcp2_rep_send_ack
> + *rep_send_ack)
> +{
> + struct wired_cmd_verify_repeater_in verify_repeater_in = { { 0 } };
> + struct wired_cmd_verify_repeater_out verify_repeater_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !rep_topology || !rep_send_ack || !data)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + verify_repeater_in.header.api_version = HDCP_API_VERSION;
> + verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER;
> + verify_repeater_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + verify_repeater_in.header.buffer_len =
> +
> WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN;
> +
> + verify_repeater_in.port.integrated_port_type = data->port_type;
> + verify_repeater_in.port.physical_port = mei_get_ddi_index(data-
> >port);
> +
> + memcpy(verify_repeater_in.rx_info, rep_topology->rx_info,
> + HDCP_2_2_RXINFO_LEN);
> + memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v,
> + HDCP_2_2_SEQ_NUM_LEN);
> + memcpy(verify_repeater_in.v_prime, rep_topology->v_prime,
> + HDCP_2_2_V_PRIME_HALF_LEN);
> + memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids,
> + HDCP_2_2_RECEIVER_IDS_MAX_LEN);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&verify_repeater_in,
> + sizeof(verify_repeater_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&verify_repeater_out,
> + sizeof(verify_repeater_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (verify_repeater_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
> + WIRED_VERIFY_REPEATER,
> + verify_repeater_out.header.status);
> + return -EIO;
> + }
> +
> + memcpy(rep_send_ack->v, verify_repeater_out.v,
> + HDCP_2_2_V_PRIME_HALF_LEN);
> + rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK;
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> @@ -477,7 +551,8 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> .initiate_locality_check = mei_hdcp_initiate_locality_check,
> .verify_lprime = mei_hdcp_verify_lprime,
> .get_session_key = mei_hdcp_get_session_key,
> - .repeater_check_flow_prepare_ack = NULL,
> + .repeater_check_flow_prepare_ack =
> + mei_hdcp_repeater_check_flow_prepare_ack,
> .verify_mprime = NULL,
> .enable_hdcp_authentication = NULL,
> .close_hdcp_session = NULL,
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 27/33] misc/mei/hdcp: Prepare Session Key
2019-02-16 17:37 ` [PATCH v14 27/33] misc/mei/hdcp: Prepare Session Key Ramalingam C
@ 2019-02-21 14:24 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 14:24 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> Request to ME to prepare the encrypted session key.
>
> On Success, ME provides Encrypted session key. Function populates the
> HDCP2.2 authentication msg SKE_Send_Eks.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Style fixed [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebasing.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition. [Tomas]
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 59
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 58 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 869a6f22f68d..fe5070f901e8 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -409,6 +409,63 @@ mei_hdcp_verify_lprime(struct device *dev, struct
> hdcp_port_data *data,
> return 0;
> }
>
> +/**
> + * mei_hdcp_get_session_key() - Prepare SKE_Send_Eks.
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + * @ske_data: SKE_Send_Eks msg output from ME FW.
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int mei_hdcp_get_session_key(struct device *dev,
> + struct hdcp_port_data *data,
> + struct hdcp2_ske_send_eks *ske_data) {
> + struct wired_cmd_get_session_key_in get_skey_in = { { 0 } };
> + struct wired_cmd_get_session_key_out get_skey_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data || !ske_data)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + get_skey_in.header.api_version = HDCP_API_VERSION;
> + get_skey_in.header.command_id = WIRED_GET_SESSION_KEY;
> + get_skey_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + get_skey_in.header.buffer_len =
> WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN;
> +
> + get_skey_in.port.integrated_port_type = data->port_type;
> + get_skey_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&get_skey_in, sizeof(get_skey_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&get_skey_out,
> +sizeof(get_skey_out));
> +
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (get_skey_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
> + WIRED_GET_SESSION_KEY,
> get_skey_out.header.status);
> + return -EIO;
> + }
> +
> + ske_data->msg_id = HDCP_2_2_SKE_SEND_EKS;
> + memcpy(ske_data->e_dkey_ks, get_skey_out.e_dkey_ks,
> + HDCP_2_2_E_DKEY_KS_LEN);
> + memcpy(ske_data->riv, get_skey_out.r_iv, HDCP_2_2_RIV_LEN);
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> @@ -419,7 +476,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> .store_pairing_info = mei_hdcp_store_pairing_info,
> .initiate_locality_check = mei_hdcp_initiate_locality_check,
> .verify_lprime = mei_hdcp_verify_lprime,
> - .get_session_key = NULL,
> + .get_session_key = mei_hdcp_get_session_key,
> .repeater_check_flow_prepare_ack = NULL,
> .verify_mprime = NULL,
> .enable_hdcp_authentication = NULL,
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 30/33] misc/mei/hdcp: Enabling the HDCP authentication
2019-02-16 17:37 ` [PATCH v14 30/33] misc/mei/hdcp: Enabling the HDCP authentication Ramalingam C
@ 2019-02-21 14:25 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 14:25 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
>
> Request to ME to configure a port as authenticated.
>
> On Success, ME FW will mark the port as authenticated and provides HDCP
> cipher with the encryption keys.
>
> Enabling the Authentication can be requested once all stages of
> HDCP2.2 authentication is completed by interacting with ME FW.
>
> Only after this stage, driver can enable the HDCP encryption for the port,
> through HW registers.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Style and typos fixed [Uma]
> v5: Rebased.
> v6:
> Collected the Rb-ed by.
> Rebased.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition. [Tomas]
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 55
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 54 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index 721376fc9bf1..d8e04e0621a1 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -605,6 +605,59 @@ static int mei_hdcp_verify_mprime(struct device
> *dev,
> return 0;
> }
>
> +/**
> + * mei_hdcp_enable_authentication() - Mark a port as authenticated
> + * through ME FW
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int mei_hdcp_enable_authentication(struct device *dev,
> + struct hdcp_port_data *data)
> +{
> + struct wired_cmd_enable_auth_in enable_auth_in = { { 0 } };
> + struct wired_cmd_enable_auth_out enable_auth_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + enable_auth_in.header.api_version = HDCP_API_VERSION;
> + enable_auth_in.header.command_id = WIRED_ENABLE_AUTH;
> + enable_auth_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + enable_auth_in.header.buffer_len =
> WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN;
> +
> + enable_auth_in.port.integrated_port_type = data->port_type;
> + enable_auth_in.port.physical_port = mei_get_ddi_index(data->port);
> + enable_auth_in.stream_type = data->streams[0].stream_type;
> +
> + byte = mei_cldev_send(cldev, (u8 *)&enable_auth_in,
> + sizeof(enable_auth_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&enable_auth_out,
> + sizeof(enable_auth_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (enable_auth_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
> + WIRED_ENABLE_AUTH,
> enable_auth_out.header.status);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> @@ -619,7 +672,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> .repeater_check_flow_prepare_ack =
> mei_hdcp_repeater_check_flow_prepare_ack,
> .verify_mprime = mei_hdcp_verify_mprime,
> - .enable_hdcp_authentication = NULL,
> + .enable_hdcp_authentication = mei_hdcp_enable_authentication,
> .close_hdcp_session = NULL,
> };
>
> --
> 2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH v14 31/33] misc/mei/hdcp: Closing wired HDCP2.2 Tx Session
2019-02-16 17:37 ` [PATCH v14 31/33] misc/mei/hdcp: Closing wired HDCP2.2 Tx Session Ramalingam C
@ 2019-02-21 14:25 ` Winkler, Tomas
0 siblings, 0 replies; 58+ messages in thread
From: Winkler, Tomas @ 2019-02-21 14:25 UTC (permalink / raw)
To: C, Ramalingam, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch,
Shankar, Uma
> Request the ME to terminate the HDCP2.2 session for a port.
>
> On Success, ME FW will mark the intel port as Deauthenticated and terminate
> the wired HDCP2.2 Tx session started due to the cmd
> WIRED_INITIATE_HDCP2_SESSION.
>
> v2: Rebased.
> v3:
> cldev is passed as first parameter [Tomas]
> Redundant comments and cast are removed [Tomas]
> v4:
> %zd for ssize_t [Alexander]
> %s/return -1/return -EIO [Alexander]
> Style and typos fixed [Uma]
> v5:
> Extra line is removed.
> v6:
> Collected the Rb-ed by.
> Rebased.
> v7:
> Adjust to the new mei interface.
> Fix for Kdoc.
> v8:
> K-Doc addition.[Tomas]
> v9:
> renamed func as mei_hdcp_* [Tomas]
> Inline function is defined for DDI index [Tomas]
> v10:
> K-Doc fix. [Tomas]
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
LGTM
> ---
> drivers/misc/mei/hdcp/mei_hdcp.c | 55
> +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 54 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index d8e04e0621a1..2afc7d31dacc 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -658,6 +658,59 @@ static int mei_hdcp_enable_authentication(struct
> device *dev,
> return 0;
> }
>
> +/**
> + * mei_hdcp_close_session() - Close the Wired HDCP Tx session of ME FW per
> port.
> + * This also disables the authenticated state of the port.
> + * @dev: device corresponding to the mei_cl_device
> + * @data: Intel HW specific hdcp data
> + *
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_hdcp_close_session(struct device *dev, struct hdcp_port_data *data)
> +{
> + struct wired_cmd_close_session_in session_close_in = { { 0 } };
> + struct wired_cmd_close_session_out session_close_out = { { 0 } };
> + struct mei_cl_device *cldev;
> + ssize_t byte;
> +
> + if (!dev || !data)
> + return -EINVAL;
> +
> + cldev = to_mei_cl_device(dev);
> +
> + session_close_in.header.api_version = HDCP_API_VERSION;
> + session_close_in.header.command_id = WIRED_CLOSE_SESSION;
> + session_close_in.header.status = ME_HDCP_STATUS_SUCCESS;
> + session_close_in.header.buffer_len =
> + WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN;
> +
> + session_close_in.port.integrated_port_type = data->port_type;
> + session_close_in.port.physical_port = mei_get_ddi_index(data->port);
> +
> + byte = mei_cldev_send(cldev, (u8 *)&session_close_in,
> + sizeof(session_close_in));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> + return byte;
> + }
> +
> + byte = mei_cldev_recv(cldev, (u8 *)&session_close_out,
> + sizeof(session_close_out));
> + if (byte < 0) {
> + dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> + return byte;
> + }
> +
> + if (session_close_out.header.status != ME_HDCP_STATUS_SUCCESS) {
> + dev_dbg(dev, "Session Close Failed. status: 0x%X\n",
> + session_close_out.header.status);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> static __attribute__((unused))
> struct i915_hdcp_component_ops mei_hdcp_ops = {
> .owner = THIS_MODULE,
> @@ -673,7 +726,7 @@ struct i915_hdcp_component_ops mei_hdcp_ops = {
> mei_hdcp_repeater_check_flow_prepare_ack,
> .verify_mprime = mei_hdcp_verify_mprime,
> .enable_hdcp_authentication = mei_hdcp_enable_authentication,
> - .close_hdcp_session = NULL,
> + .close_hdcp_session = mei_hdcp_close_session,
> };
>
> static int mei_hdcp_probe(struct mei_cl_device *cldev,
> --
> 2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 13/33] drm/i915: Implement the HDCP2.2 support for DP
2019-02-16 17:37 ` [PATCH v14 13/33] drm/i915: Implement the HDCP2.2 support for DP Ramalingam C
@ 2019-08-15 8:43 ` Jani Nikula
2019-08-19 15:06 ` Ramalingam C
0 siblings, 1 reply; 58+ messages in thread
From: Jani Nikula @ 2019-08-15 8:43 UTC (permalink / raw)
To: Ramalingam C, intel-gfx, dri-devel, daniel.vetter, tomas.winkler,
uma.shankar
On Sat, 16 Feb 2019, Ramalingam C via dri-devel <dri-devel@lists.freedesktop.org> wrote:
> Implements the DP adaptation specific HDCP2.2 functions.
>
> These functions perform the DPCD read and write for communicating the
> HDCP2.2 auth message back and forth.
>
> v2:
> wait for cp_irq is merged with this patch. Rebased.
> v3:
> wait_queue is used for wait for cp_irq [Chris Wilson]
> v4:
> Style fixed.
> %s/PARING/PAIRING
> Few style fixes [Uma]
> v5:
> Lookup table for DP HDCP2.2 msg details [Daniel].
> Extra lines are removed.
> v6: Rebased.
> v7:
> Fixed some regression introduced at v5. [Ankit]
> Macro HDCP_2_2_RX_CAPS_VERSION_VAL is reused [Uma]
> Converted a function to inline [Uma]
> %s/uintxx_t/uxx
> v8:
> Error due to the sinks are reported as DEBUG logs.
> Adjust to the new mei interface.
> v9:
> ARRAY_SIZE for no of array members [Jon & Daniel]
> return of the wait_for_cp_irq is made as void [Daniel]
> Wait for HDCP2.2 msg is done based on polling the reg bit than
> CP_IRQ based. [Daniel]
> hdcp adaptation is added as a const in the hdcp_shim [Daniel]
> v10:
> config_stream_type is redefined [Daniel]
> DP Errata specific defines are moved into intel_dp.c.
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Signed-off-by: Ankit K Nautiyal <ankit.k.nautiyal@intel.com>
> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> ---
> drivers/gpu/drm/i915/intel_dp.c | 333 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 333 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 9f73a4239574..e9fe25f21200 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -5847,6 +5847,333 @@ int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> return 0;
> }
>
> +struct hdcp2_dp_errata_stream_type {
> + u8 msg_id;
> + u8 stream_type;
> +} __packed;
> +
> +static struct hdcp2_dp_msg_data {
> + u8 msg_id;
> + u32 offset;
> + bool msg_detectable;
> + u32 timeout;
> + u32 timeout2; /* Added for non_paired situation */
> + } hdcp2_msg_data[] = {
> + {HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0},
> + {HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
> + false, HDCP_2_2_CERT_TIMEOUT_MS, 0},
> + {HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
> + false, 0, 0},
> + {HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
> + false, 0, 0},
> + {HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
> + true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
> + HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS},
> + {HDCP_2_2_AKE_SEND_PAIRING_INFO,
> + DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
> + HDCP_2_2_PAIRING_TIMEOUT_MS, 0},
> + {HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0},
> + {HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
> + false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0},
> + {HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
> + 0, 0},
> + {HDCP_2_2_REP_SEND_RECVID_LIST,
> + DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
> + HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0},
> + {HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
> + 0, 0},
> + {HDCP_2_2_REP_STREAM_MANAGE,
> + DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
> + 0, 0},
> + {HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
> + false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0},
> +/* local define to shovel this through the write_2_2 interface */
> +#define HDCP_2_2_ERRATA_DP_STREAM_TYPE 50
> + {HDCP_2_2_ERRATA_DP_STREAM_TYPE,
> + DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
> + 0, 0},
> + };
Hate to bring this up so far after this has been merged, but
hdcp2_msg_data[] must be moved out of driver static data.
BR,
Jani.
> +
> +static inline
> +int intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
> + u8 *rx_status)
> +{
> + ssize_t ret;
> +
> + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> + DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
> + HDCP_2_2_DP_RXSTATUS_LEN);
> + if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
> + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret);
> + return ret >= 0 ? -EIO : ret;
> + }
> +
> + return 0;
> +}
> +
> +static
> +int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
> + u8 msg_id, bool *msg_ready)
> +{
> + u8 rx_status;
> + int ret;
> +
> + *msg_ready = false;
> + ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> + if (ret < 0)
> + return ret;
> +
> + switch (msg_id) {
> + case HDCP_2_2_AKE_SEND_HPRIME:
> + if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
> + *msg_ready = true;
> + break;
> + case HDCP_2_2_AKE_SEND_PAIRING_INFO:
> + if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
> + *msg_ready = true;
> + break;
> + case HDCP_2_2_REP_SEND_RECVID_LIST:
> + if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> + *msg_ready = true;
> + break;
> + default:
> + DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static ssize_t
> +intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
> + struct hdcp2_dp_msg_data *hdcp2_msg_data)
> +{
> + struct intel_dp *dp = &intel_dig_port->dp;
> + struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> + u8 msg_id = hdcp2_msg_data->msg_id;
> + int ret, timeout;
> + bool msg_ready = false;
> +
> + if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
> + timeout = hdcp2_msg_data->timeout2;
> + else
> + timeout = hdcp2_msg_data->timeout;
> +
> + /*
> + * There is no way to detect the CERT, LPRIME and STREAM_READY
> + * availability. So Wait for timeout and read the msg.
> + */
> + if (!hdcp2_msg_data->msg_detectable) {
> + mdelay(timeout);
> + ret = 0;
> + } else {
> + /* TODO: In case if you need to wait on CP_IRQ, do it here */
> + ret = __wait_for(ret =
> + hdcp2_detect_msg_availability(intel_dig_port,
> + msg_id,
> + &msg_ready),
> + !ret && msg_ready, timeout * 1000,
> + 1000, 5 * 1000);
> +
> + if (!msg_ready)
> + ret = -ETIMEDOUT;
> + }
> +
> + if (ret)
> + DRM_DEBUG_KMS("msg_id %d, ret %d, timeout(mSec): %d\n",
> + hdcp2_msg_data->msg_id, ret, timeout);
> +
> + return ret;
> +}
> +
> +static struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(hdcp2_msg_data); i++)
> + if (hdcp2_msg_data[i].msg_id == msg_id)
> + return &hdcp2_msg_data[i];
> +
> + return NULL;
> +}
> +
> +static
> +int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
> + void *buf, size_t size)
> +{
> + unsigned int offset;
> + u8 *byte = buf;
> + ssize_t ret, bytes_to_write, len;
> + struct hdcp2_dp_msg_data *hdcp2_msg_data;
> +
> + hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
> + if (!hdcp2_msg_data)
> + return -EINVAL;
> +
> + offset = hdcp2_msg_data->offset;
> +
> + /* No msg_id in DP HDCP2.2 msgs */
> + bytes_to_write = size - 1;
> + byte++;
> +
> + while (bytes_to_write) {
> + len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
> + DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
> +
> + ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> + offset, (void *)byte, len);
> + if (ret < 0)
> + return ret;
> +
> + bytes_to_write -= ret;
> + byte += ret;
> + offset += ret;
> + }
> +
> + return size;
> +}
> +
> +static
> +ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port)
> +{
> + u8 rx_info[HDCP_2_2_RXINFO_LEN];
> + u32 dev_cnt;
> + ssize_t ret;
> +
> + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> + DP_HDCP_2_2_REG_RXINFO_OFFSET,
> + (void *)rx_info, HDCP_2_2_RXINFO_LEN);
> + if (ret != HDCP_2_2_RXINFO_LEN)
> + return ret >= 0 ? -EIO : ret;
> +
> + dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
> + HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
> +
> + if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
> + dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
> +
> + ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
> + HDCP_2_2_RECEIVER_IDS_MAX_LEN +
> + (dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
> +
> + return ret;
> +}
> +
> +static
> +int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
> + u8 msg_id, void *buf, size_t size)
> +{
> + unsigned int offset;
> + u8 *byte = buf;
> + ssize_t ret, bytes_to_recv, len;
> + struct hdcp2_dp_msg_data *hdcp2_msg_data;
> +
> + hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
> + if (!hdcp2_msg_data)
> + return -EINVAL;
> + offset = hdcp2_msg_data->offset;
> +
> + ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
> + if (ret < 0)
> + return ret;
> +
> + if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
> + ret = get_receiver_id_list_size(intel_dig_port);
> + if (ret < 0)
> + return ret;
> +
> + size = ret;
> + }
> + bytes_to_recv = size - 1;
> +
> + /* DP adaptation msgs has no msg_id */
> + byte++;
> +
> + while (bytes_to_recv) {
> + len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
> + DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
> +
> + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
> + (void *)byte, len);
> + if (ret < 0) {
> + DRM_DEBUG_KMS("msg_id %d, ret %zd\n", msg_id, ret);
> + return ret;
> + }
> +
> + bytes_to_recv -= ret;
> + byte += ret;
> + offset += ret;
> + }
> + byte = buf;
> + *byte = msg_id;
> +
> + return size;
> +}
> +
> +static
> +int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
> + bool is_repeater, u8 content_type)
> +{
> + struct hdcp2_dp_errata_stream_type stream_type_msg;
> +
> + if (is_repeater)
> + return 0;
> +
> + /*
> + * Errata for DP: As Stream type is used for encryption, Receiver
> + * should be communicated with stream type for the decryption of the
> + * content.
> + * Repeater will be communicated with stream type as a part of it's
> + * auth later in time.
> + */
> + stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
> + stream_type_msg.stream_type = content_type;
> +
> + return intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
> + sizeof(stream_type_msg));
> +}
> +
> +static
> +int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
> +{
> + u8 rx_status;
> + int ret;
> +
> + ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> + if (ret)
> + return ret;
> +
> + if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
> + ret = HDCP_REAUTH_REQUEST;
> + else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
> + ret = HDCP_LINK_INTEGRITY_FAILURE;
> + else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> + ret = HDCP_TOPOLOGY_CHANGE;
> +
> + return ret;
> +}
> +
> +static
> +int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
> + bool *capable)
> +{
> + u8 rx_caps[3];
> + int ret;
> +
> + *capable = false;
> + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> + DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
> + rx_caps, HDCP_2_2_RXCAPS_LEN);
> + if (ret != HDCP_2_2_RXCAPS_LEN)
> + return ret >= 0 ? -EIO : ret;
> +
> + if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
> + HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
> + *capable = true;
> +
> + return 0;
> +}
> +
> static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> .read_bksv = intel_dp_hdcp_read_bksv,
> @@ -5859,6 +6186,12 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> .toggle_signalling = intel_dp_hdcp_toggle_signalling,
> .check_link = intel_dp_hdcp_check_link,
> .hdcp_capable = intel_dp_hdcp_capable,
> + .write_2_2_msg = intel_dp_hdcp2_write_msg,
> + .read_2_2_msg = intel_dp_hdcp2_read_msg,
> + .config_stream_type = intel_dp_hdcp2_config_stream_type,
> + .check_2_2_link = intel_dp_hdcp2_check_link,
> + .hdcp_2_2_capable = intel_dp_hdcp2_capable,
> + .protocol = HDCP_PROTOCOL_DP,
> };
>
> static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
--
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH v14 13/33] drm/i915: Implement the HDCP2.2 support for DP
2019-08-15 8:43 ` Jani Nikula
@ 2019-08-19 15:06 ` Ramalingam C
0 siblings, 0 replies; 58+ messages in thread
From: Ramalingam C @ 2019-08-19 15:06 UTC (permalink / raw)
To: Jani Nikula
Cc: daniel.vetter, intel-gfx, uma.shankar, tomas.winkler, dri-devel
On 2019-08-15 at 11:43:54 +0300, Jani Nikula wrote:
> On Sat, 16 Feb 2019, Ramalingam C via dri-devel <dri-devel@lists.freedesktop.org> wrote:
> > Implements the DP adaptation specific HDCP2.2 functions.
> >
> > These functions perform the DPCD read and write for communicating the
> > HDCP2.2 auth message back and forth.
> >
> > v2:
> > wait for cp_irq is merged with this patch. Rebased.
> > v3:
> > wait_queue is used for wait for cp_irq [Chris Wilson]
> > v4:
> > Style fixed.
> > %s/PARING/PAIRING
> > Few style fixes [Uma]
> > v5:
> > Lookup table for DP HDCP2.2 msg details [Daniel].
> > Extra lines are removed.
> > v6: Rebased.
> > v7:
> > Fixed some regression introduced at v5. [Ankit]
> > Macro HDCP_2_2_RX_CAPS_VERSION_VAL is reused [Uma]
> > Converted a function to inline [Uma]
> > %s/uintxx_t/uxx
> > v8:
> > Error due to the sinks are reported as DEBUG logs.
> > Adjust to the new mei interface.
> > v9:
> > ARRAY_SIZE for no of array members [Jon & Daniel]
> > return of the wait_for_cp_irq is made as void [Daniel]
> > Wait for HDCP2.2 msg is done based on polling the reg bit than
> > CP_IRQ based. [Daniel]
> > hdcp adaptation is added as a const in the hdcp_shim [Daniel]
> > v10:
> > config_stream_type is redefined [Daniel]
> > DP Errata specific defines are moved into intel_dp.c.
> >
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Signed-off-by: Ankit K Nautiyal <ankit.k.nautiyal@intel.com>
> > Reviewed-by: Uma Shankar <uma.shankar@intel.com>
> > ---
> > drivers/gpu/drm/i915/intel_dp.c | 333 ++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 333 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 9f73a4239574..e9fe25f21200 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -5847,6 +5847,333 @@ int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> > return 0;
> > }
> >
> > +struct hdcp2_dp_errata_stream_type {
> > + u8 msg_id;
> > + u8 stream_type;
> > +} __packed;
> > +
> > +static struct hdcp2_dp_msg_data {
> > + u8 msg_id;
> > + u32 offset;
> > + bool msg_detectable;
> > + u32 timeout;
> > + u32 timeout2; /* Added for non_paired situation */
> > + } hdcp2_msg_data[] = {
> > + {HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0},
> > + {HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
> > + false, HDCP_2_2_CERT_TIMEOUT_MS, 0},
> > + {HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
> > + false, 0, 0},
> > + {HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
> > + false, 0, 0},
> > + {HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
> > + true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
> > + HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS},
> > + {HDCP_2_2_AKE_SEND_PAIRING_INFO,
> > + DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
> > + HDCP_2_2_PAIRING_TIMEOUT_MS, 0},
> > + {HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0},
> > + {HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
> > + false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0},
> > + {HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
> > + 0, 0},
> > + {HDCP_2_2_REP_SEND_RECVID_LIST,
> > + DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
> > + HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0},
> > + {HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
> > + 0, 0},
> > + {HDCP_2_2_REP_STREAM_MANAGE,
> > + DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
> > + 0, 0},
> > + {HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
> > + false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0},
> > +/* local define to shovel this through the write_2_2 interface */
> > +#define HDCP_2_2_ERRATA_DP_STREAM_TYPE 50
> > + {HDCP_2_2_ERRATA_DP_STREAM_TYPE,
> > + DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
> > + 0, 0},
> > + };
>
> Hate to bring this up so far after this has been merged, but
> hdcp2_msg_data[] must be moved out of driver static data.
Jani,
Could you please explain why we dont like it?
Alternate i could think immediately is populate the messages in the
runtime based on the msg_id using the functions and use them.
-Ram
>
> BR,
> Jani.
>
>
> > +
> > +static inline
> > +int intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
> > + u8 *rx_status)
> > +{
> > + ssize_t ret;
> > +
> > + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> > + DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
> > + HDCP_2_2_DP_RXSTATUS_LEN);
> > + if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
> > + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret);
> > + return ret >= 0 ? -EIO : ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static
> > +int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
> > + u8 msg_id, bool *msg_ready)
> > +{
> > + u8 rx_status;
> > + int ret;
> > +
> > + *msg_ready = false;
> > + ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> > + if (ret < 0)
> > + return ret;
> > +
> > + switch (msg_id) {
> > + case HDCP_2_2_AKE_SEND_HPRIME:
> > + if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
> > + *msg_ready = true;
> > + break;
> > + case HDCP_2_2_AKE_SEND_PAIRING_INFO:
> > + if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
> > + *msg_ready = true;
> > + break;
> > + case HDCP_2_2_REP_SEND_RECVID_LIST:
> > + if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> > + *msg_ready = true;
> > + break;
> > + default:
> > + DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
> > + return -EINVAL;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static ssize_t
> > +intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
> > + struct hdcp2_dp_msg_data *hdcp2_msg_data)
> > +{
> > + struct intel_dp *dp = &intel_dig_port->dp;
> > + struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> > + u8 msg_id = hdcp2_msg_data->msg_id;
> > + int ret, timeout;
> > + bool msg_ready = false;
> > +
> > + if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
> > + timeout = hdcp2_msg_data->timeout2;
> > + else
> > + timeout = hdcp2_msg_data->timeout;
> > +
> > + /*
> > + * There is no way to detect the CERT, LPRIME and STREAM_READY
> > + * availability. So Wait for timeout and read the msg.
> > + */
> > + if (!hdcp2_msg_data->msg_detectable) {
> > + mdelay(timeout);
> > + ret = 0;
> > + } else {
> > + /* TODO: In case if you need to wait on CP_IRQ, do it here */
> > + ret = __wait_for(ret =
> > + hdcp2_detect_msg_availability(intel_dig_port,
> > + msg_id,
> > + &msg_ready),
> > + !ret && msg_ready, timeout * 1000,
> > + 1000, 5 * 1000);
> > +
> > + if (!msg_ready)
> > + ret = -ETIMEDOUT;
> > + }
> > +
> > + if (ret)
> > + DRM_DEBUG_KMS("msg_id %d, ret %d, timeout(mSec): %d\n",
> > + hdcp2_msg_data->msg_id, ret, timeout);
> > +
> > + return ret;
> > +}
> > +
> > +static struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(hdcp2_msg_data); i++)
> > + if (hdcp2_msg_data[i].msg_id == msg_id)
> > + return &hdcp2_msg_data[i];
> > +
> > + return NULL;
> > +}
> > +
> > +static
> > +int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
> > + void *buf, size_t size)
> > +{
> > + unsigned int offset;
> > + u8 *byte = buf;
> > + ssize_t ret, bytes_to_write, len;
> > + struct hdcp2_dp_msg_data *hdcp2_msg_data;
> > +
> > + hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
> > + if (!hdcp2_msg_data)
> > + return -EINVAL;
> > +
> > + offset = hdcp2_msg_data->offset;
> > +
> > + /* No msg_id in DP HDCP2.2 msgs */
> > + bytes_to_write = size - 1;
> > + byte++;
> > +
> > + while (bytes_to_write) {
> > + len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
> > + DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
> > +
> > + ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> > + offset, (void *)byte, len);
> > + if (ret < 0)
> > + return ret;
> > +
> > + bytes_to_write -= ret;
> > + byte += ret;
> > + offset += ret;
> > + }
> > +
> > + return size;
> > +}
> > +
> > +static
> > +ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port)
> > +{
> > + u8 rx_info[HDCP_2_2_RXINFO_LEN];
> > + u32 dev_cnt;
> > + ssize_t ret;
> > +
> > + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> > + DP_HDCP_2_2_REG_RXINFO_OFFSET,
> > + (void *)rx_info, HDCP_2_2_RXINFO_LEN);
> > + if (ret != HDCP_2_2_RXINFO_LEN)
> > + return ret >= 0 ? -EIO : ret;
> > +
> > + dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
> > + HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
> > +
> > + if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
> > + dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
> > +
> > + ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
> > + HDCP_2_2_RECEIVER_IDS_MAX_LEN +
> > + (dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
> > +
> > + return ret;
> > +}
> > +
> > +static
> > +int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
> > + u8 msg_id, void *buf, size_t size)
> > +{
> > + unsigned int offset;
> > + u8 *byte = buf;
> > + ssize_t ret, bytes_to_recv, len;
> > + struct hdcp2_dp_msg_data *hdcp2_msg_data;
> > +
> > + hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
> > + if (!hdcp2_msg_data)
> > + return -EINVAL;
> > + offset = hdcp2_msg_data->offset;
> > +
> > + ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
> > + if (ret < 0)
> > + return ret;
> > +
> > + if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
> > + ret = get_receiver_id_list_size(intel_dig_port);
> > + if (ret < 0)
> > + return ret;
> > +
> > + size = ret;
> > + }
> > + bytes_to_recv = size - 1;
> > +
> > + /* DP adaptation msgs has no msg_id */
> > + byte++;
> > +
> > + while (bytes_to_recv) {
> > + len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
> > + DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
> > +
> > + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
> > + (void *)byte, len);
> > + if (ret < 0) {
> > + DRM_DEBUG_KMS("msg_id %d, ret %zd\n", msg_id, ret);
> > + return ret;
> > + }
> > +
> > + bytes_to_recv -= ret;
> > + byte += ret;
> > + offset += ret;
> > + }
> > + byte = buf;
> > + *byte = msg_id;
> > +
> > + return size;
> > +}
> > +
> > +static
> > +int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
> > + bool is_repeater, u8 content_type)
> > +{
> > + struct hdcp2_dp_errata_stream_type stream_type_msg;
> > +
> > + if (is_repeater)
> > + return 0;
> > +
> > + /*
> > + * Errata for DP: As Stream type is used for encryption, Receiver
> > + * should be communicated with stream type for the decryption of the
> > + * content.
> > + * Repeater will be communicated with stream type as a part of it's
> > + * auth later in time.
> > + */
> > + stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
> > + stream_type_msg.stream_type = content_type;
> > +
> > + return intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
> > + sizeof(stream_type_msg));
> > +}
> > +
> > +static
> > +int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
> > +{
> > + u8 rx_status;
> > + int ret;
> > +
> > + ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> > + if (ret)
> > + return ret;
> > +
> > + if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
> > + ret = HDCP_REAUTH_REQUEST;
> > + else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
> > + ret = HDCP_LINK_INTEGRITY_FAILURE;
> > + else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> > + ret = HDCP_TOPOLOGY_CHANGE;
> > +
> > + return ret;
> > +}
> > +
> > +static
> > +int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
> > + bool *capable)
> > +{
> > + u8 rx_caps[3];
> > + int ret;
> > +
> > + *capable = false;
> > + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> > + DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
> > + rx_caps, HDCP_2_2_RXCAPS_LEN);
> > + if (ret != HDCP_2_2_RXCAPS_LEN)
> > + return ret >= 0 ? -EIO : ret;
> > +
> > + if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
> > + HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
> > + *capable = true;
> > +
> > + return 0;
> > +}
> > +
> > static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> > .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > .read_bksv = intel_dp_hdcp_read_bksv,
> > @@ -5859,6 +6186,12 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> > .toggle_signalling = intel_dp_hdcp_toggle_signalling,
> > .check_link = intel_dp_hdcp_check_link,
> > .hdcp_capable = intel_dp_hdcp_capable,
> > + .write_2_2_msg = intel_dp_hdcp2_write_msg,
> > + .read_2_2_msg = intel_dp_hdcp2_read_msg,
> > + .config_stream_type = intel_dp_hdcp2_config_stream_type,
> > + .check_2_2_link = intel_dp_hdcp2_check_link,
> > + .hdcp_2_2_capable = intel_dp_hdcp2_capable,
> > + .protocol = HDCP_PROTOCOL_DP,
> > };
> >
> > static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
>
> --
> Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 58+ messages in thread
end of thread, other threads:[~2019-08-19 15:06 UTC | newest]
Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-16 17:36 [PATCH v14 00/33] drm/i915: Implement HDCP2.2 Ramalingam C
2019-02-16 17:36 ` [PATCH v14 01/33] drm/i915: Gathering the HDCP1.4 routines together Ramalingam C
2019-02-16 17:36 ` [PATCH v14 02/33] drm/audio: declaration of struct device Ramalingam C
2019-02-16 17:36 ` [PATCH v14 03/33] drm/i915: Initialize HDCP2.2 Ramalingam C via dri-devel
2019-02-16 17:36 ` [PATCH v14 04/33] drm/i915: MEI interface implementation Ramalingam C via dri-devel
2019-02-20 19:39 ` Daniel Vetter
2019-02-21 4:07 ` C, Ramalingam
2019-02-16 17:36 ` [PATCH v14 05/33] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking Ramalingam C
2019-02-16 17:36 ` [PATCH v14 06/33] drm/i915: Enable and Disable of HDCP2.2 Ramalingam C
2019-02-16 17:36 ` [PATCH v14 07/33] drm/i915: Implement HDCP2.2 receiver authentication Ramalingam C
2019-02-16 17:36 ` [PATCH v14 08/33] drm/i915: Implement HDCP2.2 repeater authentication Ramalingam C via dri-devel
2019-02-16 17:36 ` [PATCH v14 09/33] drm: HDCP2.2 link check period Ramalingam C
2019-02-16 17:36 ` [PATCH v14 10/33] drm/i915: Implement HDCP2.2 link integrity check Ramalingam C
2019-02-16 17:36 ` [PATCH v14 11/33] drm/i915: Handle HDCP2.2 downstream topology change Ramalingam C via dri-devel
2019-02-16 17:36 ` [PATCH v14 12/33] drm: removing the DP Errata msg and its msg id Ramalingam C
2019-02-16 17:37 ` [PATCH v14 13/33] drm/i915: Implement the HDCP2.2 support for DP Ramalingam C
2019-08-15 8:43 ` Jani Nikula
2019-08-19 15:06 ` Ramalingam C
2019-02-16 17:37 ` [PATCH v14 14/33] drm/i915: Implement the HDCP2.2 support for HDMI Ramalingam C
2019-02-16 17:37 ` [PATCH v14 15/33] drm/i915: CP_IRQ handling for DP HDCP2.2 msgs Ramalingam C via dri-devel
2019-02-16 17:37 ` [PATCH v14 16/33] drm/i915: Fix KBL HDCP2.2 encrypt status signalling Ramalingam C
2019-02-20 19:49 ` Daniel Vetter
2019-02-16 17:37 ` [PATCH v14 17/33] mei: bus: whitelist hdcp client Ramalingam C
2019-02-16 17:37 ` [PATCH v14 18/33] mei: bus: export to_mei_cl_device for mei client device drivers Ramalingam C
2019-02-16 17:37 ` [PATCH v14 19/33] misc/mei/hdcp: Client driver for HDCP application Ramalingam C
2019-02-21 13:55 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 20/33] misc/mei/hdcp: Define ME FW interface for HDCP2.2 Ramalingam C via dri-devel
2019-02-21 12:42 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 21/33] misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session Ramalingam C
2019-02-21 13:30 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 22/33] misc/mei/hdcp: Verify Receiver Cert and prepare km Ramalingam C
2019-02-21 13:39 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 23/33] misc/mei/hdcp: Verify H_prime Ramalingam C
2019-02-21 13:32 ` Winkler, Tomas
2019-02-21 13:33 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 24/33] misc/mei/hdcp: Store the HDCP Pairing info Ramalingam C
2019-02-21 13:46 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 25/33] misc/mei/hdcp: Initiate Locality check Ramalingam C
2019-02-21 13:40 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 26/33] misc/mei/hdcp: Verify L_prime Ramalingam C
2019-02-21 13:42 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 27/33] misc/mei/hdcp: Prepare Session Key Ramalingam C
2019-02-21 14:24 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 28/33] misc/mei/hdcp: Repeater topology verification and ack Ramalingam C via dri-devel
2019-02-21 14:16 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 29/33] misc/mei/hdcp: Verify M_prime Ramalingam C via dri-devel
2019-02-21 13:44 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 30/33] misc/mei/hdcp: Enabling the HDCP authentication Ramalingam C
2019-02-21 14:25 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 31/33] misc/mei/hdcp: Closing wired HDCP2.2 Tx Session Ramalingam C
2019-02-21 14:25 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 32/33] misc/mei/hdcp: Component framework for I915 Interface Ramalingam C
2019-02-21 12:15 ` Winkler, Tomas
2019-02-16 17:37 ` [PATCH v14 33/33] FOR_TEST_ONLY: i915/Kconfig: Select mei_hdcp by I915 Ramalingam C via dri-devel
2019-02-16 18:18 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Implement HDCP2.2 Patchwork
2019-02-16 18:28 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-02-16 18:45 ` ✓ Fi.CI.BAT: success " Patchwork
2019-02-16 20:49 ` ✓ Fi.CI.IGT: " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox