From patchwork Mon May 21 12:53:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10415215 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9FAE26053B for ; Mon, 21 May 2018 13:05:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8FAD4288AA for ; Mon, 21 May 2018 13:05:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 84521288B4; Mon, 21 May 2018 13:05:47 +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 D5CEB288AA for ; Mon, 21 May 2018 13:05:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B8F4D6F0EB; Mon, 21 May 2018 13:04:03 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id F07986F0E8; Mon, 21 May 2018 13:04:00 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 May 2018 06:04:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,426,1520924400"; d="scan'208";a="40968624" Received: from mint-dev.iind.intel.com ([10.223.25.164]) by fmsmga007.fm.intel.com with ESMTP; 21 May 2018 06:03:56 -0700 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Date: Mon, 21 May 2018 18:23:46 +0530 Message-Id: <1526907240-17639-28-git-send-email-ramalingam.c@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1526907240-17639-1-git-send-email-ramalingam.c@intel.com> References: <1526907240-17639-1-git-send-email-ramalingam.c@intel.com> Subject: [Intel-gfx] [PATCH v4 27/41] drm/i915: Implement HDCP2.2 link integrity check X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alexander.usyskin@intel.com, tomas.winkler@intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP 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: No Changes. v4: enum check_link_response is used check the link status [Uma] Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/intel_hdcp.c | 82 ++++++++++++++++++++++++++++++++++++++- include/drm/drm_hdcp.h | 8 ++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index ede5bf38ca12..a0f97a980606 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -23,6 +23,8 @@ static int _intel_hdcp2_enable(struct intel_connector *connector); static int _intel_hdcp2_disable(struct intel_connector *connector); +static void intel_hdcp2_check_work(struct work_struct *work); +static int intel_hdcp2_check_link(struct intel_connector *connector); static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port, const struct intel_hdcp_shim *shim) @@ -1526,6 +1528,84 @@ static int _intel_hdcp2_enable(struct intel_connector *connector) hdcp->hdcp_value = DRM_MODE_CONTENT_PROTECTION_ENABLED; schedule_work(&hdcp->hdcp_prop_work); - + schedule_delayed_work(&hdcp->hdcp2_check_work, + DRM_HDCP2_CHECK_PERIOD_MS); return 0; } + +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; + + if (!hdcp->hdcp_shim) + return -ENOENT; + + mutex_lock(&hdcp->hdcp_mutex); + + if (hdcp->hdcp_value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) + goto out; + + if (!(I915_READ(HDCP2_STATUS_DDI(port)) & LINK_ENCRYPTION_STATUS)) { + DRM_ERROR("HDCP check failed: link is not encrypted, %x\n", + I915_READ(HDCP2_STATUS_DDI(port))); + ret = -ENXIO; + hdcp->hdcp_value = DRM_MODE_CONTENT_PROTECTION_DESIRED; + schedule_work(&hdcp->hdcp_prop_work); + goto out; + } + + ret = hdcp->hdcp_shim->check_2_2_link(intel_dig_port); + if (ret == DRM_HDCP_LINK_PROTECTED) { + if (hdcp->hdcp_value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { + hdcp->hdcp_value = DRM_MODE_CONTENT_PROTECTION_ENABLED; + schedule_work(&hdcp->hdcp_prop_work); + } + goto out; + } + + DRM_INFO("[%s:%d] HDCP2.2 link failed, retrying authentication\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->hdcp_value = DRM_MODE_CONTENT_PROTECTION_DESIRED; + schedule_work(&hdcp->hdcp_prop_work); + goto out; + } + + ret = _intel_hdcp2_enable(connector); + if (ret) { + DRM_ERROR("[%s:%d] Failed to enable hdcp2.2 (%d)\n", + connector->base.name, connector->base.base.id, ret); + + hdcp->hdcp_value = DRM_MODE_CONTENT_PROTECTION_DESIRED; + schedule_work(&hdcp->hdcp_prop_work); + goto out; + } + +out: + mutex_unlock(&hdcp->hdcp_mutex); + + return ret; +} + +static void intel_hdcp2_check_work(struct work_struct *work) +{ + struct intel_hdcp *hdcp = container_of(to_delayed_work(work), + struct intel_hdcp, + hdcp2_check_work); + struct intel_connector *connector = container_of(hdcp, + struct intel_connector, + hdcp); + + if (!intel_hdcp2_check_link(connector)) + schedule_delayed_work(&hdcp->hdcp2_check_work, + DRM_HDCP2_CHECK_PERIOD_MS); +} diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index 6ce9f9d432dc..dcf719f356d8 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -11,6 +11,14 @@ /* 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 + +enum check_link_response { + DRM_HDCP_LINK_PROTECTED = 0, + DRM_HDCP_TOPOLOGY_CHANGE, + DRM_HDCP_LINK_INTEGRITY_FAILURE, + DRM_HDCP_REAUTH_REQUEST +}; /* Shared lengths/masks between HDMI/DVI/DisplayPort */ #define DRM_HDCP_AN_LEN 8