From patchwork Sat Mar 9 04:04:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845733 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B87111669 for ; Sat, 9 Mar 2019 04:02:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A4934300D2 for ; Sat, 9 Mar 2019 04:02:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 98CE6300EE; Sat, 9 Mar 2019 04:02:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 55431300D2 for ; Sat, 9 Mar 2019 04:02:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4C7D26E39E; Sat, 9 Mar 2019 04:02:52 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id AE9376E36B; Sat, 9 Mar 2019 04:02:49 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:02:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618562" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:02:47 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 1/8] drm/i915: debugfs: HDCP2.2 capability read Date: Sat, 9 Mar 2019 09:34:45 +0530 Message-Id: <20190309040452.23699-2-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Adding the HDCP2.2 capability of HDCP src and sink info into debugfs entry "i915_hdcp_sink_capability" This helps the userspace tests to skip the HDCP2.2 test on non HDCP2.2 sinks. Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/i915_debugfs.c | 13 +++++++++++-- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_hdcp.c | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6a90558de213..8ef097c492d6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4755,6 +4755,7 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data) { struct drm_connector *connector = m->private; struct intel_connector *intel_connector = to_intel_connector(connector); + bool hdcp_cap, hdcp2_cap; if (connector->status != connector_status_connected) return -ENODEV; @@ -4765,8 +4766,16 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data) seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id); - seq_printf(m, "%s ", !intel_hdcp_capable(intel_connector) ? - "None" : "HDCP1.4"); + hdcp_cap = intel_hdcp_capable(intel_connector); + hdcp2_cap = intel_hdcp2_capable(intel_connector); + + if (hdcp_cap) + seq_puts(m, "HDCP1.4 "); + if (hdcp2_cap) + seq_puts(m, "HDCP2.2 "); + + if (!hdcp_cap && !hdcp2_cap) + seq_puts(m, "None"); seq_puts(m, "\n"); return 0; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 58483f8245aa..f143aaf57e55 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2176,6 +2176,7 @@ int intel_hdcp_enable(struct intel_connector *connector); int intel_hdcp_disable(struct intel_connector *connector); bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port); bool intel_hdcp_capable(struct intel_connector *connector); +bool intel_hdcp2_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); diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 9ce09f67776d..ff9497e5c591 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -76,7 +76,7 @@ bool intel_hdcp_capable(struct intel_connector *connector) } /* Is HDCP2.2 capable on Platform and Sink */ -static bool intel_hdcp2_capable(struct intel_connector *connector) +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); From patchwork Sat Mar 9 04:04:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845737 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A2EFF4B7E for ; Sat, 9 Mar 2019 04:03:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E1F3300D2 for ; Sat, 9 Mar 2019 04:03:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 82703300EE; Sat, 9 Mar 2019 04:03:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EFD1E300D2 for ; Sat, 9 Mar 2019 04:02:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BC1B36E423; Sat, 9 Mar 2019 04:02:52 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id B20DD6E39E; Sat, 9 Mar 2019 04:02:51 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:02:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618623" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:02:49 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 2/8] drm: Add Content protection type property Date: Sat, 9 Mar 2019 09:34:46 +0530 Message-Id: <20190309040452.23699-3-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a DRM ENUM property to the selected connectors. This property is used for mentioning the protected content's type from userspace to kernel HDCP authentication. Type of the stream is decided by the protected content providers. Type 0 content can be rendered on any HDCP protected display wires. But Type 1 content can be rendered only on HDCP2.2 protected paths. So when a userspace sets this property to Type 1 and starts the HDCP enable, kernel will honour it only if HDCP2.2 authentication is through for type 1. Else HDCP enable will be failed. v2: cp_content_type is replaced with content_protection_type [daniel] check at atomic_set_property is removed [Maarten] Signed-off-by: Ramalingam C --- drivers/gpu/drm/drm_atomic_uapi.c | 4 ++ drivers/gpu/drm/drm_connector.c | 63 +++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 15 ++++++++ include/uapi/drm/drm_mode.h | 4 ++ 4 files changed, 86 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 4eb81f10bc54..f383d4be5a92 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -746,6 +746,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, return -EINVAL; } state->content_protection = val; + } else if (property == connector->content_protection_type_property) { + state->content_protection_type = val; } else if (property == connector->colorspace_property) { state->colorspace = val; } else if (property == config->writeback_fb_id_property) { @@ -822,6 +824,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->scaling_mode; } else if (property == connector->content_protection_property) { *val = state->content_protection; + } else if (property == connector->content_protection_type_property) { + *val = state->content_protection_type; } else if (property == config->writeback_fb_id_property) { /* Writeback framebuffer is one-shot, write and forget */ *val = 0; diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 07d65a16c623..4ce0830e9fb4 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -853,6 +853,13 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = { { DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER, "DCI-P3_RGB_Theater" }, }; +static struct drm_prop_enum_list drm_content_protection_type_enum_list[] = { + { DRM_MODE_CONTENT_PROTECTION_TYPE0, "Type 0" }, + { DRM_MODE_CONTENT_PROTECTION_TYPE1, "Type 1" }, +}; +DRM_ENUM_NAME_FN(drm_get_content_protection_type_name, + drm_content_protection_type_enum_list) + /** * DOC: standard connector properties * @@ -958,6 +965,23 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = { * the value transitions from ENABLED to DESIRED. This signifies the link * is no longer protected and userspace should take appropriate action * (whatever that might be). + * Content_protection_type: + * This property is used by the userspace to configure the kernel with + * upcoming stream's content type. Content Type of a stream is decided by + * the owner of the stream, as Type 0 or Type 1. + * + * The value of the property can be one the below: + * - DRM_MODE_CONTENT_PROTECTION_TYPE0 = 0 + * Type 0 streams can be transmitted on a link which is encrypted + * with HDCP 1.4 or HDCP 2.2. + * - DRM_MODE_CONTENT_PROTECTION_TYPE1 = 1 + * Type 1 streams can be transmitted on a link which is encrypted + * only with HDCP2.2. + * + * Please note this content type is introduced at HDCP2.2 and used in its + * authentication process. If content type is changed when + * content_protection is not UNDESIRED, then kernel will disable the HDCP + * and re-enable with new type in the same atomic commit * * max bpc: * This range property is used by userspace to limit the bit depth. When @@ -1547,6 +1571,45 @@ int drm_connector_attach_content_protection_property( } EXPORT_SYMBOL(drm_connector_attach_content_protection_property); +/** + * drm_connector_attach_content_protection_type_property - attach content + * protection type property + * + * @connector: connector to attach content protection type property on. + * + * This is used to add support for sending the protected content's stream type + * from userspace to kernel on selected connectors. Protected content provider + * will decide their type of their content and declare the same to kernel. + * + * This information will be used during the HDCP2.2 authentication. + * + * Content type will be set to &drm_connector_state.content_protection_type. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int +drm_connector_attach_content_protection_type_property(struct drm_connector * + connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + prop = drm_property_create_enum(dev, 0, "Content_protection_type", + drm_content_protection_type_enum_list, + ARRAY_SIZE( + drm_content_protection_type_enum_list)); + if (!prop) + return -ENOMEM; + + drm_object_attach_property(&connector->base, prop, + DRM_MODE_CONTENT_PROTECTION_TYPE0); + connector->content_protection_type_property = prop; + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_content_protection_type_property); + /** * drm_mode_create_aspect_ratio_property - create aspect ratio property * @dev: DRM device diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index c8061992d6cb..2116732789ec 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -518,6 +518,12 @@ struct drm_connector_state { */ unsigned int content_type; + /** + * @content_protection_type: Connector property to pass the type of + * protected content. This is most commonly used for HDCP. + */ + unsigned int content_protection_type; + /** * @scaling_mode: Connector property to control the * upscaling, mostly used for built-in panels. @@ -1035,6 +1041,12 @@ struct drm_connector { */ struct drm_property *colorspace_property; + /** + * @content_protection_type_property: DRM ENUM property for type of + * Protected Content. + */ + struct drm_property *content_protection_type_property; + /** * @path_blob_ptr: * @@ -1294,6 +1306,7 @@ const char *drm_get_dvi_i_select_name(int val); const char *drm_get_tv_subconnector_name(int val); const char *drm_get_tv_select_name(int val); const char *drm_get_content_protection_name(int val); +const char *drm_get_content_protection_type_name(int val); int drm_mode_create_dvi_i_properties(struct drm_device *dev); int drm_mode_create_tv_margin_properties(struct drm_device *dev); @@ -1309,6 +1322,8 @@ int drm_connector_attach_vrr_capable_property( struct drm_connector *connector); int drm_connector_attach_content_protection_property( struct drm_connector *connector); +int drm_connector_attach_content_protection_type_property( + struct drm_connector *connector); int drm_mode_create_aspect_ratio_property(struct drm_device *dev); int drm_mode_create_colorspace_property(struct drm_connector *connector); int drm_mode_create_content_type_property(struct drm_device *dev); diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index a439c2e67896..65b4e4d8fdfb 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -210,6 +210,10 @@ extern "C" { #define DRM_MODE_CONTENT_PROTECTION_DESIRED 1 #define DRM_MODE_CONTENT_PROTECTION_ENABLED 2 +/* Content Type classification for HDCP2.2 vs others */ +#define DRM_MODE_CONTENT_PROTECTION_TYPE0 0 +#define DRM_MODE_CONTENT_PROTECTION_TYPE1 1 + struct drm_mode_modeinfo { __u32 clock; __u16 hdisplay; From patchwork Sat Mar 9 04:04:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845741 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD3F013B5 for ; Sat, 9 Mar 2019 04:03:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B2A6C300E5 for ; Sat, 9 Mar 2019 04:03:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A404E300F6; Sat, 9 Mar 2019 04:03:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 18FF0300E5 for ; Sat, 9 Mar 2019 04:03:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 269E16E432; Sat, 9 Mar 2019 04:02:56 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id B1FA96E42E; Sat, 9 Mar 2019 04:02:53 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:02:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618674" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:02:51 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 3/8] drm/i915: Attach content type property Date: Sat, 9 Mar 2019 09:34:47 +0530 Message-Id: <20190309040452.23699-4-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Attaches the content type property for HDCP2.2 capable connectors. Implements the update of content type from property and apply the restriction on HDCP version selection. v2: s/cp_content_type/content_protection_type [daniel] disable at hdcp_atomic_check to avoid check at atomic_set_property [Maarten] Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/intel_ddi.c | 21 +++++++++++++++------ drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_hdcp.c | 30 +++++++++++++++++++++++++----- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 7e3b4e8fdf3a..8702938ec376 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3499,7 +3499,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder, /* Enable hdcp if it's desired */ if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) - intel_hdcp_enable(to_intel_connector(conn_state->connector)); + intel_hdcp_enable(to_intel_connector(conn_state->connector), + (u8)conn_state->content_protection_type); } static void intel_disable_ddi_dp(struct intel_encoder *encoder, @@ -3562,21 +3563,29 @@ static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder, intel_panel_update_backlight(encoder, crtc_state, conn_state); } -static void intel_ddi_update_pipe(struct intel_encoder *encoder, +static void intel_ddi_update_hdcp(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state); - if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) - intel_hdcp_enable(to_intel_connector(conn_state->connector)); + intel_hdcp_enable(to_intel_connector(conn_state->connector), + (u8)conn_state->content_protection_type); else if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) intel_hdcp_disable(to_intel_connector(conn_state->connector)); } +static void intel_ddi_update_pipe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state); + + intel_ddi_update_hdcp(encoder, crtc_state, conn_state); +} + static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, enum port port) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f143aaf57e55..186fa035f491 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2172,7 +2172,7 @@ void intel_hdcp_atomic_check(struct drm_connector *connector, struct drm_connector_state *new_state); 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_enable(struct intel_connector *connector, u8 content_type); int intel_hdcp_disable(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); diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index ff9497e5c591..ff1bbbee2e52 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -1782,6 +1782,13 @@ static void intel_hdcp2_init(struct intel_connector *connector) return; } + ret = drm_connector_attach_content_protection_type_property( + &connector->base); + if (ret) { + kfree(hdcp->port_data.streams); + return; + } + hdcp->hdcp2_supported = true; } @@ -1811,7 +1818,7 @@ int intel_hdcp_init(struct intel_connector *connector, return 0; } -int intel_hdcp_enable(struct intel_connector *connector) +int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) { struct intel_hdcp *hdcp = &connector->hdcp; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; @@ -1822,6 +1829,7 @@ int intel_hdcp_enable(struct intel_connector *connector) mutex_lock(&hdcp->mutex); WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED); + hdcp->content_type = content_type; /* * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup @@ -1833,8 +1841,12 @@ int intel_hdcp_enable(struct intel_connector *connector) check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS; } - /* When HDCP2.2 fails, HDCP1.4 will be attempted */ - if (ret && intel_hdcp_capable(connector)) { + /* + * When HDCP2.2 fails and Content Type is not Type1, HDCP1.4 will + * be attempted. + */ + if (ret && intel_hdcp_capable(connector) && + hdcp->content_type != DRM_MODE_CONTENT_PROTECTION_TYPE1) { ret = _intel_hdcp_enable(connector); } @@ -1901,6 +1913,8 @@ void intel_hdcp_atomic_check(struct drm_connector *connector, { u64 old_cp = old_state->content_protection; u64 new_cp = new_state->content_protection; + u64 old_type = old_state->content_protection_type; + u64 new_type = new_state->content_protection_type; struct drm_crtc_state *crtc_state; if (!new_state->crtc) { @@ -1920,8 +1934,14 @@ void intel_hdcp_atomic_check(struct drm_connector *connector, */ if (old_cp == new_cp || (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED && - new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) - return; + new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) { + if (old_type == new_type) + return; + + new_state->content_protection = + DRM_MODE_CONTENT_PROTECTION_DESIRED; + intel_hdcp_disable(to_intel_connector(connector)); + } crtc_state = drm_atomic_get_new_crtc_state(new_state->state, new_state->crtc); From patchwork Sat Mar 9 04:04:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845749 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B9C0913B5 for ; Sat, 9 Mar 2019 04:03:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A12F2300D2 for ; Sat, 9 Mar 2019 04:03:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92DF6300E5; Sat, 9 Mar 2019 04:03:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A5229300F6 for ; Sat, 9 Mar 2019 04:03:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E30D56E435; Sat, 9 Mar 2019 04:02:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id BAA156E42E; Sat, 9 Mar 2019 04:02:55 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:02:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618742" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:02:53 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 4/8] drm/i915: HDCP SRM parsing and revocation check Date: Sat, 9 Mar 2019 09:34:48 +0530 Message-Id: <20190309040452.23699-5-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Implements the SRM table parsing for HDCP 1.4 and 2.2. And also revocation check is added at authentication of HDCP1.4 and 2.2 Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 6 + drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_hdcp.c | 308 ++++++++++++++++++++++++++++-- include/drm/drm_hdcp.h | 32 ++++ 5 files changed, 334 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0d743907e7bc..6c396ec0f552 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -873,6 +873,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv) mutex_init(&dev_priv->wm.wm_mutex); mutex_init(&dev_priv->pps_mutex); mutex_init(&dev_priv->hdcp_comp_mutex); + mutex_init(&dev_priv->srm_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 c4ffe19ec698..c6c7cb1ae1b4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2054,6 +2054,12 @@ struct drm_i915_private { /* Mutex to protect the above hdcp component related values. */ struct mutex hdcp_comp_mutex; + unsigned int revocated_ksv_cnt; + u8 *revocated_ksv_list; + + /* Mutex to protect the data about revocated ksvs */ + struct mutex srm_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_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 186fa035f491..7550f4ed5a98 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2181,6 +2181,8 @@ 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); +ssize_t intel_hdcp_srm_update(struct drm_i915_private *dev_priv, char *buf, + size_t count); /* 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 ff1bbbee2e52..b1fa81666490 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -273,6 +273,62 @@ u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port *intel_dig_port) return -EINVAL; } +static inline void intel_hdcp_print_ksv(u8 *ksv) +{ + DRM_DEBUG_KMS("\t%#04x, %#04x, %#04x, %#04x, %#04x\n", *ksv, + *(ksv + 1), *(ksv + 2), *(ksv + 3), *(ksv + 4)); +} + +static inline +struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp) +{ + return container_of(hdcp, struct intel_connector, hdcp); +} + +/* Check if any of the KSV is revocated by DCP LLC through SRM table */ +static inline +bool intel_hdcp_ksvs_revocated(struct intel_hdcp *hdcp, u8 *ksvs, u32 ksv_count) +{ + struct intel_connector *connector = intel_hdcp_to_connector(hdcp); + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); + struct drm_i915_private *dev_priv = + intel_dig_port->base.base.dev->dev_private; + u32 rev_ksv_cnt, cnt, i, j; + u8 *rev_ksv_list; + + mutex_lock(&dev_priv->srm_mutex); + rev_ksv_cnt = dev_priv->revocated_ksv_cnt; + rev_ksv_list = dev_priv->revocated_ksv_list; + + /* If the Revocated ksv list is empty */ + if (!rev_ksv_cnt || !rev_ksv_list) { + mutex_unlock(&dev_priv->srm_mutex); + return false; + } + + for (cnt = 0; cnt < ksv_count; cnt++) { + rev_ksv_list = dev_priv->revocated_ksv_list; + for (i = 0; i < rev_ksv_cnt; i++) { + for (j = 0; j < DRM_HDCP_KSV_LEN; j++) + if (*(ksvs + j) != *(rev_ksv_list + j)) { + break; + } else if (j == (DRM_HDCP_KSV_LEN - 1)) { + DRM_DEBUG_KMS("Revocated KSV is "); + intel_hdcp_print_ksv(ksvs); + mutex_unlock(&dev_priv->srm_mutex); + return true; + } + /* Move the offset to next KSV in the revocated list */ + rev_ksv_list += DRM_HDCP_KSV_LEN; + } + + /* Iterate to next ksv_offset */ + ksvs += DRM_HDCP_KSV_LEN; + } + mutex_unlock(&dev_priv->srm_mutex); + return false; +} + static int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port, const struct intel_hdcp_shim *shim, @@ -490,9 +546,10 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port, /* Implements Part 2 of the HDCP authorization procedure */ static -int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, - const struct intel_hdcp_shim *shim) +int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp, + struct intel_digital_port *intel_dig_port) { + const struct intel_hdcp_shim *shim = hdcp->shim; u8 bstatus[2], num_downstream, *ksv_fifo; int ret, i, tries = 3; @@ -531,6 +588,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, if (ret) goto err; + if (intel_hdcp_ksvs_revocated(hdcp, ksv_fifo, num_downstream)) { + DRM_ERROR("Revocated Ksv(s) in ksv_fifo\n"); + return -EPERM; + } + /* * When V prime mismatches, DP Spec mandates re-read of * V prime atleast twice. @@ -557,9 +619,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, } /* Implements Part 1 of the HDCP authorization procedure */ -static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, - const struct intel_hdcp_shim *shim) +static int intel_hdcp_auth(struct intel_connector *connector) { + 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; struct drm_i915_private *dev_priv; enum port port; unsigned long r0_prime_gen_start; @@ -625,6 +689,11 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, if (ret < 0) return ret; + if (intel_hdcp_ksvs_revocated(hdcp, bksv.shim, 1)) { + DRM_ERROR("BKSV is revocated\n"); + return -EPERM; + } + I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]); I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]); @@ -698,7 +767,7 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, */ if (repeater_present) - return intel_hdcp_auth_downstream(intel_dig_port, shim); + return intel_hdcp_auth_downstream(hdcp, intel_dig_port); DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n"); return 0; @@ -735,7 +804,6 @@ static int _intel_hdcp_disable(struct intel_connector *connector) static int _intel_hdcp_enable(struct intel_connector *connector) { - struct intel_hdcp *hdcp = &connector->hdcp; struct drm_i915_private *dev_priv = connector->base.dev->dev_private; int i, ret, tries = 3; @@ -760,9 +828,9 @@ 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); + ret = intel_hdcp_auth(connector); if (!ret) { - hdcp->hdcp_encrypted = true; + connector->hdcp.hdcp_encrypted = true; return 0; } @@ -776,12 +844,6 @@ static int _intel_hdcp_enable(struct intel_connector *connector) return ret; } -static inline -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 */ static int intel_hdcp_check_link(struct intel_connector *connector) { @@ -1193,6 +1255,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]); + if (intel_hdcp_ksvs_revocated(hdcp, + msgs.send_cert.cert_rx.receiver_id, 1)) { + DRM_ERROR("Receiver ID is revocated\n"); + return -EPERM; + } + /* * Here msgs.no_stored_km will hold msgs corresponding to the km * stored also. @@ -1351,7 +1419,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) } msgs; const struct intel_hdcp_shim *shim = hdcp->shim; u8 *rx_info; - u32 seq_num_v; + u32 seq_num_v, device_cnt; int ret; ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_SEND_RECVID_LIST, @@ -1376,6 +1444,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) return -EINVAL; } + device_cnt = HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 || + HDCP_2_2_DEV_COUNT_LO(rx_info[1]); + if (intel_hdcp_ksvs_revocated(hdcp, msgs.recvid_list.receiver_ids, + device_cnt)) { + DRM_ERROR("Revoked receiver ID(s) is in list\n"); + return -EPERM; + } + ret = hdcp2_verify_rep_topology_prepare_ack(connector, &msgs.recvid_list, &msgs.rep_ack); @@ -1818,6 +1894,208 @@ int intel_hdcp_init(struct intel_connector *connector, return 0; } +static u32 intel_hdcp_get_revocated_ksv_count(u8 *buf, u32 vrls_length) +{ + u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz; + + do { + vrl_ksv_cnt = *buf; + ksv_count += vrl_ksv_cnt; + + vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1; + buf += vrl_sz; + parsed_bytes += vrl_sz; + } while (parsed_bytes < vrls_length); + + return ksv_count; +} + +static u32 intel_hdcp_get_revocated_ksvs(u8 *ksv_list, const u8 *buf, + u32 vrls_length) +{ + u32 parsed_bytes = 0, ksv_count = 0; + u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0; + + do { + vrl_ksv_cnt = *buf; + vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN; + + buf++; + + DRM_DEBUG_KMS("vrl: %d, Revoked KSVs: %d\n", vrl_idx++, + vrl_ksv_cnt); + memcpy(ksv_list, buf, vrl_ksv_sz); + + ksv_count += vrl_ksv_cnt; + ksv_list += vrl_ksv_sz; + buf += vrl_ksv_sz; + + parsed_bytes += (vrl_ksv_sz + 1); + } while (parsed_bytes < vrls_length); + + return ksv_count; +} + +static int intel_hdcp_parse_srm(struct drm_i915_private *dev_priv, char *buf, + size_t count) +{ + struct hdcp_srm_header *header; + u32 vrl_length, ksv_count; + + if (count < (sizeof(struct hdcp_srm_header) + + DRM_HDCP_1_4_VRL_LENGTH_SIZE + DRM_HDCP_1_4_DCP_SIG_SIZE)) { + DRM_ERROR("Invalid blob length\n"); + return -EINVAL; + } + + header = (struct hdcp_srm_header *)buf; + mutex_lock(&dev_priv->srm_mutex); + DRM_DEBUG_KMS("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n", + header->spec_indicator.srm_id, + __swab16(header->srm_version), header->srm_gen_no); + + WARN_ON(header->spec_indicator.reserved_hi || + header->spec_indicator.reserved_lo); + + if (header->spec_indicator.srm_id != DRM_HDCP_1_4_SRM_ID) { + DRM_ERROR("Invalid srm_id\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -EINVAL; + } + + buf = buf + sizeof(*header); + vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2)); + if (count < (sizeof(struct hdcp_srm_header) + vrl_length) || + vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE + + DRM_HDCP_1_4_DCP_SIG_SIZE)) { + DRM_ERROR("Invalid blob length or vrl length\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -EINVAL; + } + + /* Length of the all vrls combined */ + vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE + + DRM_HDCP_1_4_DCP_SIG_SIZE); + + if (!vrl_length) { + DRM_DEBUG_KMS("No vrl found\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -EINVAL; + } + + buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE; + ksv_count = intel_hdcp_get_revocated_ksv_count(buf, vrl_length); + if (!ksv_count) { + DRM_DEBUG_KMS("Revocated KSV count is 0\n"); + mutex_unlock(&dev_priv->srm_mutex); + return count; + } + + kfree(dev_priv->revocated_ksv_list); + dev_priv->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN, + GFP_KERNEL); + if (!dev_priv->revocated_ksv_list) { + DRM_ERROR("Out of Memory\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -ENOMEM; + } + + if (intel_hdcp_get_revocated_ksvs(dev_priv->revocated_ksv_list, + buf, vrl_length) != ksv_count) { + dev_priv->revocated_ksv_cnt = 0; + kfree(dev_priv->revocated_ksv_list); + mutex_unlock(&dev_priv->srm_mutex); + return -EINVAL; + } + + dev_priv->revocated_ksv_cnt = ksv_count; + mutex_unlock(&dev_priv->srm_mutex); + return count; +} + +static int intel_hdcp2_parse_srm(struct drm_i915_private *dev_priv, char *buf, + size_t count) +{ + struct hdcp2_srm_header *header; + u32 vrl_length, ksv_count, ksv_sz; + + mutex_lock(&dev_priv->srm_mutex); + if (count < (sizeof(struct hdcp2_srm_header) + + DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) { + DRM_ERROR("Invalid blob length\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -EINVAL; + } + + header = (struct hdcp2_srm_header *)buf; + DRM_DEBUG_KMS("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n", + header->spec_indicator.srm_id, + __swab16(header->srm_version), header->srm_gen_no); + + WARN_ON(header->spec_indicator.reserved); + buf = buf + sizeof(*header); + vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2)); + + if (count < (sizeof(struct hdcp2_srm_header) + vrl_length) || + vrl_length < (DRM_HDCP_2_VRL_LENGTH_SIZE + + DRM_HDCP_2_DCP_SIG_SIZE)) { + DRM_ERROR("Invalid blob length or vrl length\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -EINVAL; + } + + /* Length of the all vrls combined */ + vrl_length -= (DRM_HDCP_2_VRL_LENGTH_SIZE + + DRM_HDCP_2_DCP_SIG_SIZE); + + if (!vrl_length) { + DRM_DEBUG_KMS("No vrl found\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -EINVAL; + } + + buf += DRM_HDCP_2_VRL_LENGTH_SIZE; + ksv_count = (*buf << 2) | DRM_HDCP_2_KSV_COUNT_2_LSBITS(*(buf + 1)); + if (!ksv_count) { + DRM_DEBUG_KMS("Revocated KSV count is 0\n"); + mutex_unlock(&dev_priv->srm_mutex); + return count; + } + + kfree(dev_priv->revocated_ksv_list); + dev_priv->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN, + GFP_KERNEL); + if (!dev_priv->revocated_ksv_list) { + DRM_ERROR("Out of Memory\n"); + mutex_unlock(&dev_priv->srm_mutex); + return -ENOMEM; + } + + ksv_sz = ksv_count * DRM_HDCP_KSV_LEN; + buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ; + + DRM_DEBUG_KMS("Revoked KSVs: %d\n", ksv_count); + memcpy(dev_priv->revocated_ksv_list, buf, ksv_sz); + + dev_priv->revocated_ksv_cnt = ksv_count; + mutex_unlock(&dev_priv->srm_mutex); + return count; +} + +ssize_t intel_hdcp_srm_update(struct drm_i915_private *dev_priv, char *buf, + size_t count) +{ + u8 srm_id; + + srm_id = *((u8 *)buf); + if (srm_id == 0x80) + return (ssize_t)intel_hdcp_parse_srm(dev_priv, buf, count); + else if (srm_id == 0x91) + return (ssize_t)intel_hdcp2_parse_srm(dev_priv, buf, count); + + return (ssize_t)-EINVAL; +} + int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) { struct intel_hdcp *hdcp = &connector->hdcp; diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index f243408ecf26..652aaf5d658e 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -265,4 +265,36 @@ void drm_hdcp2_u32_to_seq_num(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val) seq_num[2] = val; } +#define DRM_HDCP_1_4_SRM_ID 0x8 +#define DRM_HDCP_1_4_VRL_LENGTH_SIZE 3 +#define DRM_HDCP_1_4_DCP_SIG_SIZE 40 + +struct hdcp_srm_header { + struct { + u8 reserved_hi:4; + u8 srm_id:4; + u8 reserved_lo; + } spec_indicator; + u16 srm_version; + u8 srm_gen_no; +} __packed; + +#define DRM_HDCP_2_SRM_ID 0x9 +#define DRM_HDCP_2_INDICATOR 0x1 +#define DRM_HDCP_2_VRL_LENGTH_SIZE 3 +#define DRM_HDCP_2_DCP_SIG_SIZE 384 +#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ 4 + +#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte) (((byte) & 0xC) >> 6) + +struct hdcp2_srm_header { + struct { + u8 hdcp2_indicator:4; + u8 srm_id:4; + u8 reserved; + } spec_indicator; + u16 srm_version; + u8 srm_gen_no; +} __packed; + #endif From patchwork Sat Mar 9 04:04:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845751 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4EE121669 for ; Sat, 9 Mar 2019 04:03:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B207300D2 for ; Sat, 9 Mar 2019 04:03:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2F997300EE; Sat, 9 Mar 2019 04:03:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DFD2F300D2 for ; Sat, 9 Mar 2019 04:03:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 36E8B6E439; Sat, 9 Mar 2019 04:03:00 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id B97196E435; Sat, 9 Mar 2019 04:02:57 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:02:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618787" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:02:55 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 5/8] drm/i915/sysfs: Node for hdcp srm Date: Sat, 9 Mar 2019 09:34:49 +0530 Message-Id: <20190309040452.23699-6-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Binary Sysfs entry is created to pass the HDCP SRM table into kerel for the HDCP authentication purpose. Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/i915_sysfs.c | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 41313005af42..4621e944a24e 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -576,6 +576,36 @@ static void i915_setup_error_capture(struct device *kdev) {} static void i915_teardown_error_capture(struct device *kdev) {} #endif +static ssize_t +i915_srm_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t offset, size_t count) +{ + struct device *kdev = kobj_to_dev(kobj); + struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + + return intel_hdcp_srm_update(dev_priv, buf, count); +} + +static const struct bin_attribute srm_attrs = { + .attr = {.name = "hdcp_srm", .mode = S_IWUSR}, + .read = NULL, + .write = i915_srm_write, + .mmap = NULL, + .private = (void *)0 +}; + +static void i915_setup_hdcp_srm(struct device *kdev) +{ + if (sysfs_create_bin_file(&kdev->kobj, &srm_attrs)) + DRM_ERROR("error_state sysfs setup failed\n"); +} + +static void i915_teardown_hdcp_srm(struct device *kdev) +{ + sysfs_remove_bin_file(&kdev->kobj, &srm_attrs); +} + void i915_setup_sysfs(struct drm_i915_private *dev_priv) { struct device *kdev = dev_priv->drm.primary->kdev; @@ -623,12 +653,14 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv) DRM_ERROR("RPS sysfs setup failed\n"); i915_setup_error_capture(kdev); + i915_setup_hdcp_srm(kdev); } void i915_teardown_sysfs(struct drm_i915_private *dev_priv) { struct device *kdev = dev_priv->drm.primary->kdev; + i915_teardown_hdcp_srm(kdev); i915_teardown_error_capture(kdev); if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) From patchwork Sat Mar 9 04:04:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845757 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 111831669 for ; Sat, 9 Mar 2019 04:03:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0F53300D2 for ; Sat, 9 Mar 2019 04:03:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E59E1300EE; Sat, 9 Mar 2019 04:03:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6C96A300D2 for ; Sat, 9 Mar 2019 04:03:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2A68F6E43F; Sat, 9 Mar 2019 04:03:03 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id BC2766E438; Sat, 9 Mar 2019 04:02:59 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:02:59 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618847" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:02:57 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 6/8] drm: Add CP downstream_info property Date: Sat, 9 Mar 2019 09:34:50 +0530 Message-Id: <20190309040452.23699-7-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a optional CP downstream info blob property to the connectors. This enables the Userspace to read the information of HDCP authenticated downstream topology. Driver will updated this blob with all downstream information at the end of the authentication. In case userspace configures this platform as repeater, then this information is needed for the authentication with upstream HDCP transmitter. v2: %s/cp_downstream/content_protection_downstream [daniel] Signed-off-by: Ramalingam C --- drivers/gpu/drm/drm_atomic_uapi.c | 4 ++ drivers/gpu/drm/drm_connector.c | 89 +++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 12 +++++ include/uapi/drm/drm_mode.h | 27 ++++++++++ 4 files changed, 132 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index f383d4be5a92..51fa217f99f6 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -826,6 +826,10 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->content_protection; } else if (property == connector->content_protection_type_property) { *val = state->content_protection_type; + } else if (property == + connector->content_protection_downstream_property) { + *val = connector->content_protection_downstream_blob_ptr ? + connector->content_protection_downstream_blob_ptr->base.id : 0; } else if (property == config->writeback_fb_id_property) { /* Writeback framebuffer is one-shot, write and forget */ *val = 0; diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 4ce0830e9fb4..3a11624ca73c 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -245,6 +245,7 @@ int drm_connector_init(struct drm_device *dev, INIT_LIST_HEAD(&connector->modes); mutex_init(&connector->mutex); connector->edid_blob_ptr = NULL; + connector->content_protection_downstream_blob_ptr = NULL; connector->status = connector_status_unknown; connector->display_info.panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; @@ -982,6 +983,25 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_type_name, * authentication process. If content type is changed when * content_protection is not UNDESIRED, then kernel will disable the HDCP * and re-enable with new type in the same atomic commit + * Content_protection_downstream_info: + * This blob property is used to pass the HDCP downstream topology details + * of a HDCP encrypted connector, from kernel to userspace. + * This provides all required information to userspace, so that userspace + * can implement the HDCP repeater using the kernel as downstream ports of + * the repeater. as illustrated below: + * + * HDCP Repeaters + * +--------------------------------------------------------------+ + * | | + * | | | + * | Userspace HDCP Receiver +-----> KMD HDCP transmitters | + * | (Upstream Port) <------+ (Downstream Ports) | + * | | | + * | | + * +--------------------------------------------------------------+ + * + * Kernel will populate this blob only when the HDCP authentication is + * successful. * * max bpc: * This range property is used by userspace to limit the bit depth. When @@ -1610,6 +1630,75 @@ drm_connector_attach_content_protection_type_property(struct drm_connector * } EXPORT_SYMBOL(drm_connector_attach_content_protection_type_property); +/** + * drm_connector_attach_content_protection_downstream_property - attach content + * protection downstream property + * + * @connector: connector to attach content protection downstream property on. + * + * This is used to add support for content protection downstream info on + * select connectors. when Intel platform is configured as repeater, + * this downstream info is used by userspace, to complete the repeater + * authentication of HDCP specification with upstream HDCP transmitter. + * + * The content protection downstream will be set to + * &drm_connector_state.content_protection_downstream + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_content_protection_downstream_property( + struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + prop = drm_property_create(dev, DRM_MODE_PROP_BLOB | + DRM_MODE_PROP_IMMUTABLE, + "CP_downstream_info", 0); + if (!prop) + return -ENOMEM; + + drm_object_attach_property(&connector->base, prop, 0); + + connector->content_protection_downstream_property = prop; + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_content_protection_downstream_property); + +/** + * drm_connector_update_content_protection_downstream_property - update + * the content_protection_downstream property of a connector + * @connector: drm connector + * @content_protection_downstream_info: new value of the + * content_protection_downstream property + * + * This function creates a new blob modeset object and assigns its id to the + * connector's content_protection_downstream property. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_update_content_protection_downstream_property( + struct drm_connector *connector, + const struct content_protection_downstream_info *info) +{ + struct drm_device *dev = connector->dev; + int ret; + + if (!info) + return -EINVAL; + + ret = drm_property_replace_global_blob(dev, + &connector->content_protection_downstream_blob_ptr, + sizeof(struct content_protection_downstream_info), + info, &connector->base, + connector->content_protection_downstream_property); + return ret; +} +EXPORT_SYMBOL(drm_connector_update_content_protection_downstream_property); + /** * drm_mode_create_aspect_ratio_property - create aspect ratio property * @dev: DRM device diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 2116732789ec..247a9338be72 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1047,6 +1047,13 @@ struct drm_connector { */ struct drm_property *content_protection_type_property; + /** + * @content_protection_downstream_property: DRM BLOB property for + * content protection downstream information. + */ + struct drm_property *content_protection_downstream_property; + struct drm_property_blob *content_protection_downstream_blob_ptr; + /** * @path_blob_ptr: * @@ -1324,6 +1331,11 @@ int drm_connector_attach_content_protection_property( struct drm_connector *connector); int drm_connector_attach_content_protection_type_property( struct drm_connector *connector); +int drm_connector_attach_content_protection_downstream_property( + struct drm_connector *connector); +int drm_connector_update_content_protection_downstream_property( + struct drm_connector *connector, + const struct content_protection_downstream_info *info); int drm_mode_create_aspect_ratio_property(struct drm_device *dev); int drm_mode_create_colorspace_property(struct drm_connector *connector); int drm_mode_create_content_type_property(struct drm_device *dev); diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 65b4e4d8fdfb..629ed7fdc15a 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -214,6 +214,33 @@ extern "C" { #define DRM_MODE_CONTENT_PROTECTION_TYPE0 0 #define DRM_MODE_CONTENT_PROTECTION_TYPE1 1 +#define DRM_MODE_HDCP_KSV_LEN 5 +#define DRM_MODE_HDCP_MAX_DEVICE_CNT 127 + +struct content_protection_downstream_info { + /* KSV of immediate HDCP Sink. In Little-Endian Format. */ + char bksv[DRM_MODE_HDCP_KSV_LEN]; + + /* Whether Immediate HDCP sink is a repeater? */ + bool is_repeater; + + /* Depth received from immediate downstream repeater */ + __u8 depth; + + /* Device count received from immediate downstream repeater */ + __u32 device_count; + + /* + * Max buffer required to hold ksv list received from immediate + * repeater. In this array first device_count * DRM_MODE_HDCP_KSV_LEN + * will hold the valid ksv bytes. + * If authentication specification is + * HDCP1.4 - each KSV's Bytes will be in Little-Endian format. + * HDCP2.2 - each KSV's Bytes will be in Big-Endian format. + */ + char ksv_list[DRM_MODE_HDCP_KSV_LEN * DRM_MODE_HDCP_MAX_DEVICE_CNT]; +}; + struct drm_mode_modeinfo { __u32 clock; __u16 hdisplay; From patchwork Sat Mar 9 04:04:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845761 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D84DB13B5 for ; Sat, 9 Mar 2019 04:03:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C4555300D2 for ; Sat, 9 Mar 2019 04:03:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B8CB0300EE; Sat, 9 Mar 2019 04:03:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 61776300D2 for ; Sat, 9 Mar 2019 04:03:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DE2AC6E43B; Sat, 9 Mar 2019 04:03:04 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id BBD0C6E43C; Sat, 9 Mar 2019 04:03:01 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:03:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618915" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:02:59 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 7/8] drm/i915: Populate downstream info for HDCP1.4 Date: Sat, 9 Mar 2019 09:34:51 +0530 Message-Id: <20190309040452.23699-8-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Implements drm blob property content_protection_downstream_info property on HDCP capable connectors. Downstream topology info is gathered across authentication stages and stored in intel_hdcp. When HDCP authentication is complete, new blob with latest downstream topology information is updated to content_protection_downstream_info property. v2: %s/cp_downstream/content_protection_downstream [daniel] Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_hdcp.c | 35 ++++++++++++++++++++++++++++++- include/drm/drm_hdcp.h | 1 + include/uapi/drm/drm_mode.h | 5 +++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7550f4ed5a98..4e722702897a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -482,6 +482,8 @@ struct intel_hdcp { wait_queue_head_t cp_irq_queue; atomic_t cp_irq_count; int cp_irq_count_cached; + + struct content_protection_downstream_info *downstream_info; }; struct intel_connector { diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index b1fa81666490..777f40202a15 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -580,6 +580,9 @@ int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp, if (num_downstream == 0) return -EINVAL; + hdcp->downstream_info->device_count = num_downstream; + hdcp->downstream_info->depth = DRM_HDCP_DEPTH(bstatus[1]); + ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL); if (!ksv_fifo) return -ENOMEM; @@ -593,6 +596,8 @@ int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp, return -EPERM; } + memcpy(hdcp->downstream_info->ksv_list, ksv_fifo, + num_downstream * DRM_HDCP_KSV_LEN); /* * When V prime mismatches, DP Spec mandates re-read of * V prime atleast twice. @@ -694,15 +699,20 @@ static int intel_hdcp_auth(struct intel_connector *connector) return -EPERM; } + hdcp->downstream_info->ver_in_force = DRM_MODE_HDCP14_IN_FORCE; + memcpy(hdcp->downstream_info->bksv, bksv.shim, DRM_MODE_HDCP_KSV_LEN); + I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]); I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]); ret = shim->repeater_present(intel_dig_port, &repeater_present); if (ret) return ret; - if (repeater_present) + if (repeater_present) { I915_WRITE(HDCP_REP_CTL, intel_hdcp_get_repeater_ctl(intel_dig_port)); + hdcp->downstream_info->is_repeater = true; + } ret = shim->toggle_signalling(intel_dig_port, true); if (ret) @@ -798,6 +808,14 @@ static int _intel_hdcp_disable(struct intel_connector *connector) return ret; } + memset(hdcp->downstream_info, 0, + sizeof(struct content_protection_downstream_info)); + + if (drm_connector_update_content_protection_downstream_property( + &connector->base, + connector->hdcp.downstream_info)) + DRM_ERROR("Downstream_info update failed.\n"); + DRM_DEBUG_KMS("HDCP is disabled\n"); return 0; } @@ -831,6 +849,10 @@ static int _intel_hdcp_enable(struct intel_connector *connector) ret = intel_hdcp_auth(connector); if (!ret) { connector->hdcp.hdcp_encrypted = true; + if (drm_connector_update_content_protection_downstream_property( + &connector->base, + connector->hdcp.downstream_info)) + DRM_ERROR("Downstream_info update failed.\n"); return 0; } @@ -1882,6 +1904,17 @@ int intel_hdcp_init(struct intel_connector *connector, if (ret) return ret; + ret = drm_connector_attach_content_protection_downstream_property( + &connector->base); + if (ret) + return ret; + + hdcp->downstream_info = + kzalloc(sizeof(struct content_protection_downstream_info), + GFP_KERNEL); + if (!hdcp->downstream_info) + return -ENOMEM; + hdcp->shim = shim; mutex_init(&hdcp->mutex); INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work); diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index 652aaf5d658e..654a170f03eb 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -23,6 +23,7 @@ #define DRM_HDCP_V_PRIME_PART_LEN 4 #define DRM_HDCP_V_PRIME_NUM_PARTS 5 #define DRM_HDCP_NUM_DOWNSTREAM(x) (x & 0x7f) +#define DRM_HDCP_DEPTH(x) ((x) & 0x7) #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x) (x & BIT(3)) #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x) (x & BIT(7)) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 629ed7fdc15a..3973d35c3b57 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -216,8 +216,13 @@ extern "C" { #define DRM_MODE_HDCP_KSV_LEN 5 #define DRM_MODE_HDCP_MAX_DEVICE_CNT 127 +#define DRM_MODE_HDCP14_IN_FORCE (1 << 0) +#define DRM_MODE_HDCP22_IN_FORCE (1 << 1) struct content_protection_downstream_info { + /* Version of HDCP authenticated (1.4/2.2) */ + __u32 ver_in_force; + /* KSV of immediate HDCP Sink. In Little-Endian Format. */ char bksv[DRM_MODE_HDCP_KSV_LEN]; From patchwork Sat Mar 9 04:04:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10845765 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F9901823 for ; Sat, 9 Mar 2019 04:03:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8BA79300D2 for ; Sat, 9 Mar 2019 04:03:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 805D7300EE; Sat, 9 Mar 2019 04:03:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 36A16300D2 for ; Sat, 9 Mar 2019 04:03:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C800F6E442; Sat, 9 Mar 2019 04:03:07 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id BAAA06E441; Sat, 9 Mar 2019 04:03:03 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2019 20:03:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,458,1544515200"; d="scan'208";a="124618986" Received: from dut-ram.iind.intel.com ([10.223.34.157]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2019 20:03:01 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, daniel.vetter@ffwll.ch, maarten.lankhorst@linux.intel.com Subject: [PATCH v2 8/8] drm/i915: Populate downstream info for HDCP2.2 Date: Sat, 9 Mar 2019 09:34:52 +0530 Message-Id: <20190309040452.23699-9-ramalingam.c@intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190309040452.23699-1-ramalingam.c@intel.com> References: <20190309040452.23699-1-ramalingam.c@intel.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Populates the downstream info for HDCP2.2 encryption also. On success of encryption Blob is updated. Additional two variable are added to downstream info blob. Such as ver_in_force and content type. v2: s/cp_downstream/content_protection_downstream [daniel] Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/intel_hdcp.c | 30 +++++++++++++++++++++++++++++- include/uapi/drm/drm_mode.h | 3 +++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 777f40202a15..3350b37375db 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -1283,6 +1283,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) return -EPERM; } + hdcp->downstream_info->ver_in_force = DRM_MODE_HDCP22_IN_FORCE; + hdcp->downstream_info->content_type = hdcp->content_type; + memcpy(hdcp->downstream_info->bksv, msgs.send_cert.cert_rx.receiver_id, + HDCP_2_2_RECEIVER_ID_LEN); + hdcp->downstream_info->is_repeater = hdcp->is_repeater; + /* * Here msgs.no_stored_km will hold msgs corresponding to the km * stored also. @@ -1474,6 +1480,11 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) return -EPERM; } + hdcp->downstream_info->device_count = device_cnt; + hdcp->downstream_info->depth = HDCP_2_2_DEPTH(rx_info[0]); + memcpy(hdcp->downstream_info->ksv_list, msgs.recvid_list.receiver_ids, + device_cnt * HDCP_2_2_RECEIVER_ID_LEN); + ret = hdcp2_verify_rep_topology_prepare_ack(connector, &msgs.recvid_list, &msgs.rep_ack); @@ -1660,6 +1671,13 @@ static int _intel_hdcp2_enable(struct intel_connector *connector) if (ret) { DRM_DEBUG_KMS("HDCP2 Type%d Enabling Failed. (%d)\n", hdcp->content_type, ret); + + memset(hdcp->downstream_info, 0, + sizeof(struct content_protection_downstream_info)); + drm_connector_update_content_protection_downstream_property( + &connector->base, + hdcp->downstream_info); + return ret; } @@ -1667,12 +1685,17 @@ static int _intel_hdcp2_enable(struct intel_connector *connector) connector->base.name, connector->base.base.id, hdcp->content_type); + drm_connector_update_content_protection_downstream_property( + &connector->base, + hdcp->downstream_info); hdcp->hdcp2_encrypted = true; + return 0; } static int _intel_hdcp2_disable(struct intel_connector *connector) { + struct intel_hdcp *hdcp = &connector->hdcp; int ret; DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being Disabled\n", @@ -1683,8 +1706,13 @@ static int _intel_hdcp2_disable(struct intel_connector *connector) if (hdcp2_deauthenticate_port(connector) < 0) DRM_DEBUG_KMS("Port deauth failed.\n"); - connector->hdcp.hdcp2_encrypted = false; + hdcp->hdcp2_encrypted = false; + memset(hdcp->downstream_info, 0, + sizeof(struct content_protection_downstream_info)); + drm_connector_update_content_protection_downstream_property( + &connector->base, + hdcp->downstream_info); return ret; } diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 3973d35c3b57..dc81713d3a07 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -223,6 +223,9 @@ struct content_protection_downstream_info { /* Version of HDCP authenticated (1.4/2.2) */ __u32 ver_in_force; + /* Applicable only for HDCP2.2 */ + __u8 content_type; + /* KSV of immediate HDCP Sink. In Little-Endian Format. */ char bksv[DRM_MODE_HDCP_KSV_LEN];