From patchwork Mon Feb 26 17:12:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 10242857 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 72F00602A0 for ; Mon, 26 Feb 2018 17:18:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A8112A1F8 for ; Mon, 26 Feb 2018 17:18:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5F9112A1FD; Mon, 26 Feb 2018 17:18:56 +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=-4.2 required=2.0 tests=BAYES_00, 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 20CAB2A1F8 for ; Mon, 26 Feb 2018 17:18:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 99EF16E507; Mon, 26 Feb 2018 17:18:48 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTPS id 753356E501; Mon, 26 Feb 2018 17:18:45 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Feb 2018 09:18:45 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,397,1515484800"; d="scan'208";a="203873730" Received: from mint-dev.iind.intel.com ([10.223.25.164]) by orsmga005.jf.intel.com with ESMTP; 26 Feb 2018 09:18:43 -0800 From: Ramalingam C To: intel-gfx@lists.freedesktop.org, seanpaul@chromium.org, dri-devel@lists.freedesktop.org Date: Mon, 26 Feb 2018 22:42:38 +0530 Message-Id: <1519665159-28639-5-git-send-email-ramalingam.c@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519665159-28639-1-git-send-email-ramalingam.c@intel.com> References: <1519665159-28639-1-git-send-email-ramalingam.c@intel.com> Subject: [Intel-gfx] [PATCH 4/5] drm/i915: Poll hdcp register on sudden NACK 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP In a connected state, If a HDMI HDCP sink is responded with NACK for HDCP I2C register access, then HDMI HDCP spec mandates the polling of any HDCP space registers for accessibility, minimum once in 2Secs atleast for 4Secs. Just to make it simple, this is generically implemented for both HDMI and DP. But we dont expect that this scanario will occur for DP. HDMI HDCP CTS Tests: 1A-04 and 1A-07A. Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/intel_hdcp.c | 74 +++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 95081aaa832a..14be14a45e5a 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -16,6 +16,47 @@ #define KEY_LOAD_TRIES 5 +static +struct intel_digital_port *conn_to_dig_port(struct intel_connector *connector) +{ + return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base); +} + +static inline bool hdcp_port_accessible(struct intel_connector *connector) +{ + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); + int ret = -ENXIO; + u8 bksv[DRM_HDCP_KSV_LEN]; + + ret = connector->hdcp_shim->read_bksv(intel_dig_port, bksv); + if (!ret) + return true; + return false; +} + +static bool wait_for_hdcp_port(struct intel_connector *connector) +{ + int i, tries = 10; + + for (i = 0; i < tries; i++) { + if (connector->base.status != connector_status_connected || + connector->base.state->content_protection == + DRM_MODE_CONTENT_PROTECTION_UNDESIRED || + connector->hdcp_value == + DRM_MODE_CONTENT_PROTECTION_UNDESIRED) + return false; + + if (hdcp_port_accessible(connector)) + break; + + msleep_interruptible(500); + } + + if (i == tries) + return false; + return true; +} + static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port, const struct intel_hdcp_shim *shim) { @@ -584,12 +625,6 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, return 0; } -static -struct intel_digital_port *conn_to_dig_port(struct intel_connector *connector) -{ - return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base); -} - static int _intel_hdcp_disable(struct intel_connector *connector) { struct drm_i915_private *dev_priv = connector->base.dev->dev_private; @@ -719,14 +754,26 @@ int intel_hdcp_init(struct intel_connector *connector, int intel_hdcp_enable(struct intel_connector *connector) { - int ret; + int ret, tries = 2; if (!connector->hdcp_shim) return -ENOENT; mutex_lock(&connector->hdcp_mutex); +enable_hdcp: ret = _intel_hdcp_enable(connector); + + /* + * Suddenly if sink is NACK-ed for the access of HDCP + * registers, but display is still connected, poll for hdcp + * port accessibility. One of the HDCP spec requirement. + */ + if ((ret == -EIO || ret == -ENXIO) && + connector->base.status == connector_status_connected && + !hdcp_port_accessible(connector)) + if (wait_for_hdcp_port(connector) && --tries) + goto enable_hdcp; if (ret) goto out; @@ -838,6 +885,19 @@ int intel_hdcp_check_link(struct intel_connector *connector) goto out; } + /* + * Suddenly if sink is NACK-ed for the access of HDCP + * registers, but display is still connected, poll for hdcp + * port accessibility. One of the HDCP spec requirement. + */ + if (connector->base.status == connector_status_connected && + !hdcp_port_accessible(connector)) { + mutex_unlock(&connector->hdcp_mutex); + if (!wait_for_hdcp_port(connector)) + return ret; + mutex_lock(&connector->hdcp_mutex); + } + ret = _intel_hdcp_enable(connector); if (ret) { DRM_ERROR("Failed to enable hdcp (%d)\n", ret);