From patchwork Fri Jan 17 19:30:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339651 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A151F92A for ; Fri, 17 Jan 2020 19:31:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7B6F02082F for ; Fri, 17 Jan 2020 19:31:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="WRgjs5pj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7B6F02082F Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B5BB86F8D7; Fri, 17 Jan 2020 19:31:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yb1-xb41.google.com (mail-yb1-xb41.google.com [IPv6:2607:f8b0:4864:20::b41]) by gabe.freedesktop.org (Postfix) with ESMTPS id BA9D56F8D7 for ; Fri, 17 Jan 2020 19:31:07 +0000 (UTC) Received: by mail-yb1-xb41.google.com with SMTP id w9so6086730ybs.3 for ; Fri, 17 Jan 2020 11:31:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xPTHjBNu4VtrBqVG645UC3saugAIeeYvWqQHdj1RQv8=; b=WRgjs5pj49zUBNIMSyXl9tVuSN+7o7BgdpC354+E4WQJ4t0c57InPhpTyGs+b328QZ Vg3jjzAf8GF+ofEYo98E2EIsEvyPvSWuI5YoaqR5beXC/RTRXLV6igIYxCSl62hul/z5 6u+w2DtPKhGpxmCAm9U5V3WLQNkL9A9qHNhDGEIWs8O1wwRM7+/OdMZC3I+B/zZXY1oW 8BdvohDH2uYzNlEdb0GVHKb/kpeGPrL7GMrqkFuOVU14VlYWx7ZJVWdGWLEJGFPDLXtR x4bTx6ayuZK0SBw6xjYAsN4WCHoOyuo8VhO7b9tGloc/Zjo78kFW4MyRjENWeWn1gSLa BGmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xPTHjBNu4VtrBqVG645UC3saugAIeeYvWqQHdj1RQv8=; b=PQhEtWnR1r5zCHPbcUbTzTtyp8r1k2ncPtSUL3GG4zbYHCT1uZ7jo/cQAi7Rr8o4ny 61Z4IE5r+meGm2Uw5XDH/wd3a3unBxSuXAjo8yEDc8t4iHmH+y4sT7O+HYnTx7DcsGah N8wVSo4wQb/HwikIkVr4z/+QhCyQFzKUmbCDiqeEBf1puGWJVZNxzfcyWBktzVx/lrRA HAGMM+o/9KJXmH6E+h34LAAaO7j3tS4w1NA5Opl0naDmqCvjSiGbwYaLHeqwl8y1S0i+ aubuWHn8gNdxOQAZhZZjBvSrLHu4Ut59F1b9faOdPUnVHf0LfvoCtxyHXlqRrF+ahpao 4QoQ== X-Gm-Message-State: APjAAAVY9fQm67xAYYfWq/n8l70zKdGhIhzRSpcjlLCdVpTxSKi9grTP fzIVK2ZcAGdKCA01RNRwzXPz0XhgxMicRQ== X-Google-Smtp-Source: APXvYqzRVcaz7/l6y+QVAuOboyL2N4672gbqDsMbqJqbM3Q9ACDCJQK4eEiJt8ttUqC0oI1W1+3omw== X-Received: by 2002:a25:a444:: with SMTP id f62mr26316922ybi.235.1579289466659; Fri, 17 Jan 2020 11:31:06 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id h193sm11418485ywc.88.2020.01.17.11.31.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:06 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 01/12] drm/i915: Fix sha_text population code Date: Fri, 17 Jan 2020 14:30:52 -0500 Message-Id: <20200117193103.156821-2-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul , stable@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul This patch fixes a few bugs: 1- We weren't taking into account sha_leftovers when adding multiple ksvs to sha_text. As such, we were or'ing the end of ksv[j - 1] with the beginning of ksv[j] 2- In the sha_leftovers == 2 and sha_leftovers == 3 case, bstatus was being placed on the wrong half of sha_text, overlapping the leftover ksv value 3- In the sha_leftovers == 2 case, we need to manually terminate the byte stream with 0x80 since the hardware doesn't have enough room to add it after writing M0 The upside is that all of the HDCP supported HDMI repeaters I could find on Amazon just strip HDCP anyways, so it turns out to be _really_ hard to hit any of these cases without an MST hub, which is not (yet) supported. Oh, and the sha_leftovers == 1 case works perfectly! Fixes: ee5e5e7a5e0f (drm/i915: Add HDCP framework + base implementation) Cc: Chris Wilson Cc: Ramalingam C Cc: Daniel Vetter Cc: Sean Paul Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: intel-gfx@lists.freedesktop.org Cc: # v4.17+ Reviewed-by: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-2-sean@poorly.run #v2 Changes in v2: -None Changes in v3: -None --- drivers/gpu/drm/i915/display/intel_hdcp.c | 25 +++++++++++++++++------ include/drm/drm_hdcp.h | 3 +++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 0fdbd39f6641..eaab9008feef 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -335,8 +335,10 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, /* Fill up the empty slots in sha_text and write it out */ sha_empty = sizeof(sha_text) - sha_leftovers; - for (j = 0; j < sha_empty; j++) - sha_text |= ksv[j] << ((sizeof(sha_text) - j - 1) * 8); + for (j = 0; j < sha_empty; j++) { + u8 off = ((sizeof(sha_text) - j - 1 - sha_leftovers) * 8); + sha_text |= ksv[j] << off; + } ret = intel_write_sha_text(dev_priv, sha_text); if (ret < 0) @@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, } else if (sha_leftovers == 2) { /* Write 32 bits of text */ I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); - sha_text |= bstatus[0] << 24 | bstatus[1] << 16; + sha_text |= bstatus[0] << 8 | bstatus[1]; ret = intel_write_sha_text(dev_priv, sha_text); if (ret < 0) return ret; @@ -440,16 +442,27 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, return ret; sha_idx += sizeof(sha_text); } + + /* + * Terminate the SHA-1 stream by hand. For the other leftover + * cases this is appended by the hardware. + */ + I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); + sha_text = DRM_HDCP_SHA1_TERMINATOR << 24; + ret = intel_write_sha_text(dev_priv, sha_text); + if (ret < 0) + return ret; + sha_idx += sizeof(sha_text); } else if (sha_leftovers == 3) { - /* Write 32 bits of text */ + /* Write 32 bits of text (filled from LSB) */ I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); - sha_text |= bstatus[0] << 24; + sha_text |= bstatus[0]; ret = intel_write_sha_text(dev_priv, sha_text); if (ret < 0) return ret; sha_idx += sizeof(sha_text); - /* Write 8 bits of text, 24 bits of M0 */ + /* Write 8 bits of text (filled from LSB), 24 bits of M0 */ I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8); ret = intel_write_sha_text(dev_priv, bstatus[1]); if (ret < 0) diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index 06a11202a097..20498c822204 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -29,6 +29,9 @@ /* Slave address for the HDCP registers in the receiver */ #define DRM_HDCP_DDC_ADDR 0x3A +/* Value to use at the end of the SHA-1 bytestream used for repeaters */ +#define DRM_HDCP_SHA1_TERMINATOR 0x80 + /* HDCP register offsets for HDMI/DVI devices */ #define DRM_HDCP_DDC_BKSV 0x00 #define DRM_HDCP_DDC_RI_PRIME 0x08 From patchwork Fri Jan 17 19:30:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339647 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3119992A for ; Fri, 17 Jan 2020 19:31:16 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 103342072B for ; Fri, 17 Jan 2020 19:31:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="WMXiEass" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 103342072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 115156F8D8; Fri, 17 Jan 2020 19:31:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc41.google.com (mail-yw1-xc41.google.com [IPv6:2607:f8b0:4864:20::c41]) by gabe.freedesktop.org (Postfix) with ESMTPS id C75EF6F8D4 for ; Fri, 17 Jan 2020 19:31:08 +0000 (UTC) Received: by mail-yw1-xc41.google.com with SMTP id l14so14845276ywj.9 for ; Fri, 17 Jan 2020 11:31:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cE4plDgeOaA1EdeFDIGVj5csFXNHOxdShFqwh4J/5Fc=; b=WMXiEassOBYE9KIMY/hA/5Xm4kX4pFBtFP7Z/WC/qytrK3VWYV6QLb6qPBt85nU6pQ 4aHo8J9IGB5Z9YW8ufzzu6RJ3j/NsQYm2ey9FWG6f1ynRtE9dbhQX3oUp7RAdSojRcyY f70uVgeKR/BJIzePGP8lT+0813UGeIqYy67Kj/EW49nA70AMFdwcCd4599UJrV65vr8m fA1b8luLcrRpZ6GvOF1x0ZswYtFRW0mPydDWrx42z2yij5f9NZvclMs2rDErAlsZj6zY ZusZHmQ+uzS1/Q1p/QlwBRRikMZCAwsG1auEnnd8p9+TqoTlodPrPQuhlICStQNIMtdn +1JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cE4plDgeOaA1EdeFDIGVj5csFXNHOxdShFqwh4J/5Fc=; b=lzG/0GBNI9UcqruHS6XVLslqkCqGIynXUXCE8+co+WQEUkamNRzJBNnijHKSjUsRgx 9W8hfgcqSCiZoC5I5hU8L/h3wF/7DsrsZ068bYcgxuVauju978zd52xKtfMgkFeM6h+k uoc3h+Kq3mO/RmSEPdZ7HM733virJpEjSZq+iRm2Occ6c7alb0QlpUYZ1NN15PeGf7Pb NWI4vOr3ZpmfYhQWaekTkLQTzvByRiC9LGb+aTOo2ZVfCnncwmyrPehgm4CWblD1T+MY cerZNvnu8pyR6Qqy5OsIQuPAgSdmpux5JVRq+7lBfCWywr5nJo/lhBCvy1YO79/yqKnf bMSg== X-Gm-Message-State: APjAAAXMz2baP84HKMOFO/vRv4f1fVFZx+MK+rKQdN8+NuGm5T0g6AOL Dw+WWdJkJyPCsqy+HqRqJMCsyE3ytGF2Tg== X-Google-Smtp-Source: APXvYqyckStytURl9B6tgOLARMKeyE9aLWO+1WYovvHBWnXcs94qq1uKa+LYIGFqlTUz76q5Qn6pxg== X-Received: by 2002:a81:7a43:: with SMTP id v64mr30586336ywc.95.1579289467846; Fri, 17 Jan 2020 11:31:07 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id m16sm11439344ywa.90.2020.01.17.11.31.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:07 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 02/12] drm/i915: Clear the repeater bit on HDCP disable Date: Fri, 17 Jan 2020 14:30:53 -0500 Message-Id: <20200117193103.156821-3-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul , stable@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul On HDCP disable, clear the repeater bit. This ensures if we connect a non-repeater sink after a repeater, the bit is in the state we expect. Fixes: ee5e5e7a5e0f (drm/i915: Add HDCP framework + base implementation) Cc: Chris Wilson Cc: Ramalingam C Cc: Daniel Vetter Cc: Sean Paul Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: intel-gfx@lists.freedesktop.org Cc: # v4.17+ Reviewed-by: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-3-sean@poorly.run #v2 Changes in v2: -Added to the set Changes in v3: -None I had previously agreed that clearing the rep_ctl bits on enable would also be a good idea. However when I committed that idea to code, it didn't look right. So let's rely on enables and disables being paired and everything outside of that will be considered a bug --- drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index eaab9008feef..c4394c8e10eb 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector) struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); enum port port = intel_dig_port->base.port; enum transcoder cpu_transcoder = hdcp->cpu_transcoder; + u32 repeater_ctl; int ret; DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n", @@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector) return -ETIMEDOUT; } + repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder, + port); + I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl); + ret = hdcp->shim->toggle_signalling(intel_dig_port, false); if (ret) { DRM_ERROR("Failed to disable HDCP signalling\n"); From patchwork Fri Jan 17 19:30:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339655 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C91F9921 for ; Fri, 17 Jan 2020 19:31:24 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A83342072B for ; Fri, 17 Jan 2020 19:31:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="YknXv6Cm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A83342072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 901BD6F8DB; Fri, 17 Jan 2020 19:31:11 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc41.google.com (mail-yw1-xc41.google.com [IPv6:2607:f8b0:4864:20::c41]) by gabe.freedesktop.org (Postfix) with ESMTPS id E8EAE6F8D7 for ; Fri, 17 Jan 2020 19:31:09 +0000 (UTC) Received: by mail-yw1-xc41.google.com with SMTP id v126so14828981ywc.10 for ; Fri, 17 Jan 2020 11:31:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vw0YZIzYilg4if3Ue4FJsV410z1mun8IqIxc6oGE2sI=; b=YknXv6CmaGJlLUkmJKe5oTsWYP5Id1i6aH7rpUWrV84LPkyuAfPKQiBFtNXGonUgzP NWDEdpFo1aBlBwrLIhwOAU7HBD7TwlQS86/ose80wQcGLBK7tjmzjRtnOKUIwZ3ebuwU coIxHDzV9MkrzdppMc1Uq1QTfO/3kNeOl14r9cKxrUbNRzTSM+69aMnaNo5kkJU9HUnO NP/+dsm7Pw3m94FubNMnuvWcLYleRgFB5awSmbp2S572iNiK83+eQjnxsrN7t0Y6mtjY 7L/+YMsbJKbLZmzSo80GuNu2B3+HgWDa1zwHcwpvfUU7Jr7a7lYapwyXyxKF0eewT3pL C48g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vw0YZIzYilg4if3Ue4FJsV410z1mun8IqIxc6oGE2sI=; b=Pz7/n6ny6rvvSaP5494HE6r1B8Q2VdupfQSFQElWh1VI24tO/WxEm4ZXCRT7ic8U8q rtJXs0ZIZwR4gHB+4Nv0zV6n+R7Yi4qcx5OQdbgiGDdLodUUHpDjm57tpL6fOJ+lOdb5 dEoZYzY1FO93lKF3ImqYQ+SKTJ24v9xTos/AzGSW/RlmbcLj+f1m16k6MraIRzbFTCbd vcCWlk552ZMdtl6xu5ySKJ0hXNDF1Ims9yHhVLqVuanwYwuRA2Z4HUIN7LwnvbaLq2sH +Z7jnNjkemwfsVIcVPw1HTtXMZDVHaTXsEMYO6OaLCvSRUHiJMDLcvUopgdBp098BFrf 2LLA== X-Gm-Message-State: APjAAAVxG0fqZ2TeaMtWSYBdH3SaNekZd+QmFv0+/XeiVOJwIPCHpMDt mjucDlBJf1XF55zhhwzRbS2/oyiTrAmtNg== X-Google-Smtp-Source: APXvYqxUFFMmX7Sk67neg7EQaixXOc9A/7Ol/EjOgbpqQiC3UynFaBufPQN+Ojysm8p3m41C5MXX7Q== X-Received: by 2002:a81:1d09:: with SMTP id d9mr31029497ywd.146.1579289469007; Fri, 17 Jan 2020 11:31:09 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id s3sm11710343ywf.22.2020.01.17.11.31.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:08 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 03/12] drm/i915: WARN if HDCP signalling is enabled upon disable Date: Fri, 17 Jan 2020 14:30:54 -0500 Message-Id: <20200117193103.156821-4-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul HDCP signalling should not be left on, WARN if it is Cc: Ville Syrjälä Cc: Daniel Vetter Reviewed-by: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-4-sean@poorly.run #v2 Changes in v2: - Added to the set in lieu of just clearing the bit Changes in v3: - None --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 32ea3c7e8b62..87b8b347f682 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1998,6 +1998,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); val &= ~TRANS_DDI_FUNC_ENABLE; + WARN_ON(val & TRANS_DDI_HDCP_SIGNALLING); + if (INTEL_GEN(dev_priv) >= 12) { if (!intel_dp_mst_is_master_trans(crtc_state)) val &= ~TGL_TRANS_DDI_PORT_MASK; From patchwork Fri Jan 17 19:30:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339661 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A05A4921 for ; Fri, 17 Jan 2020 19:31:28 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7F3132072B for ; Fri, 17 Jan 2020 19:31:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="WDo/jNCz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7F3132072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 27DC76F8E1; Fri, 17 Jan 2020 19:31:15 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc43.google.com (mail-yw1-xc43.google.com [IPv6:2607:f8b0:4864:20::c43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 671D36F8DA for ; Fri, 17 Jan 2020 19:31:11 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id b186so14850871ywc.1 for ; Fri, 17 Jan 2020 11:31:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SbNgaMiTiOnuP5x7gX1mRS5vhRHmZZDgtqKGI/95uUY=; b=WDo/jNCzpIjteT6slJO5OAxoOx1qm5KozHFnrFFef8CXsmZeQ8/NzzQzP86Pg8RQv3 nbpf8kRUsCOtku0xitylysA7Sgg6KsgbYSMQZaaBR7qHIxY9efXwUbARg8r3TtOLa0Zo EbMnl5QF2fXO7Z6NQNur03TXI71gkPIdOgeJrkwjNv2/7fKEqNYmg/MPtr4N+NlJJvw8 pFUeFQscDQ1kKj2+JbvKIsOgU8TukPPWPHHUzJSaT0Q6X6WHgtEd3U0v59nr3EQduyee L+yek8MCoZCIep8+ENfiRj9g0lPgMHV/EUoLTDPAs91RUgx4PTSRPystlCmWAwjcgoO0 aX9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SbNgaMiTiOnuP5x7gX1mRS5vhRHmZZDgtqKGI/95uUY=; b=d08Glb3nDcnIGK1XHBwhzCS8TehLuh0UDLu349SLZUTWdo4DUCIyJurnWB2TmA31Io Lg8spKJCaRRzgo8WJEkU8g9vNsWw3TTwe55WrKijgYNWsrKdMaoGjRJ4RF/8aqMjFcbm eslNWnqwUrWwKlkxRu5aGV2C91lhUpZKCYhuRfN7pIzicDtskS26toC2xDGdnUVA1au4 uxdl9nru8my9eHz809TF2520ZSP4sC1oisV87cQb50Rfn4cuhZLhKba2PfgU3l1YwFNu s8UxBMAmCmEeWfgRAE9PLu09lvL6ufNbBYd4MX81dBnTzpNwnXF5KvVArLXu3cd06MO7 QPDA== X-Gm-Message-State: APjAAAW8H7EEs/FtG+AHfr4c1WjRD8bgIIcc/iN6lFX4T9Bm0B8uKmwr yhToNd0nWeKxbjK6Ys1iCIExWC/kt1RjjA== X-Google-Smtp-Source: APXvYqz/yCMJFOzlADix9RzmgcLqjA4WjrMIrzaDFEcrlxiX+WzFCHmyro9a55/oNZRLKFaoya3slw== X-Received: by 2002:a81:6f07:: with SMTP id k7mr33628147ywc.395.1579289470209; Fri, 17 Jan 2020 11:31:10 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id y9sm11248970ywc.19.2020.01.17.11.31.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:09 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 04/12] drm/i915: Intercept Aksv writes in the aux hooks Date: Fri, 17 Jan 2020 14:30:55 -0500 Message-Id: <20200117193103.156821-5-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul Instead of hand rolling the transfer ourselves in the hdcp hook, inspect aux messages and add the aksv flag in the aux transfer hook. IIRC, this was the original implementation and folks wanted this hack to be isolated to the hdcp code, which makes sense. However in testing an LG monitor on my desk, I noticed it was passing back a DEFER reply. This wasn't handled in our hand-rolled code and HDCP auth was failing as a result. Instead of copy/pasting all of the retry logic and delays from drm dp helpers, let's just use the helpers and hide the aksv select as best as we can. Reviewed-by: Ville Syrjälä Reviewed-by: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-3-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-5-sean@poorly.run #v2 Changes in v2: -Remove 'generate' in intel_dp_aux_generate_xfer_flags, make arg const (Ville) -Bundle Aksv if statement together (Ville) -Rename 'txbuf' to 'aksv' (Ville) Changes in v3: -None --- drivers/gpu/drm/i915/display/intel_dp.c | 62 ++++++++++++------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4074d83b1a5f..0d59f62917ed 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1515,12 +1515,27 @@ intel_dp_aux_header(u8 txbuf[HEADER_SIZE], txbuf[3] = msg->size - 1; } +static u32 intel_dp_aux_xfer_flags(const struct drm_dp_aux_msg *msg) +{ + /* + * If we're trying to send the HDCP Aksv, we need to set a the Aksv + * select bit to inform the hardware to send the Aksv after our header + * since we can't access that data from software. + */ + if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE && + msg->address == DP_AUX_HDCP_AKSV) + return DP_AUX_CH_CTL_AUX_AKSV_SELECT; + + return 0; +} + static ssize_t intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux); u8 txbuf[20], rxbuf[20]; size_t txsize, rxsize; + u32 flags = intel_dp_aux_xfer_flags(msg); int ret; intel_dp_aux_header(txbuf, msg); @@ -1541,7 +1556,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size); ret = intel_dp_aux_xfer(intel_dp, txbuf, txsize, - rxbuf, rxsize, 0); + rxbuf, rxsize, flags); if (ret > 0) { msg->reply = rxbuf[0] >> 4; @@ -1564,7 +1579,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) return -E2BIG; ret = intel_dp_aux_xfer(intel_dp, txbuf, txsize, - rxbuf, rxsize, 0); + rxbuf, rxsize, flags); if (ret > 0) { msg->reply = rxbuf[0] >> 4; /* @@ -5904,17 +5919,9 @@ static int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port, u8 *an) { - struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(&intel_dig_port->base.base)); - static const struct drm_dp_aux_msg msg = { - .request = DP_AUX_NATIVE_WRITE, - .address = DP_AUX_HDCP_AKSV, - .size = DRM_HDCP_KSV_LEN, - }; - u8 txbuf[HEADER_SIZE + DRM_HDCP_KSV_LEN] = {}, rxbuf[2], reply = 0; + u8 aksv[DRM_HDCP_KSV_LEN] = {}; ssize_t dpcd_ret; - int ret; - /* Output An first, that's easy */ dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN, an, DRM_HDCP_AN_LEN); if (dpcd_ret != DRM_HDCP_AN_LEN) { @@ -5924,29 +5931,18 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port, } /* - * Since Aksv is Oh-So-Secret, we can't access it in software. So in - * order to get it on the wire, we need to create the AUX header as if - * we were writing the data, and then tickle the hardware to output the - * data once the header is sent out. + * Since Aksv is Oh-So-Secret, we can't access it in software. So we + * send an empty buffer of the correct length through the DP helpers. On + * the other side, in the transfer hook, we'll generate a flag based on + * the destination address which will tickle the hardware to output the + * Aksv on our behalf after the header is sent. */ - intel_dp_aux_header(txbuf, &msg); - - ret = intel_dp_aux_xfer(intel_dp, txbuf, HEADER_SIZE + msg.size, - rxbuf, sizeof(rxbuf), - DP_AUX_CH_CTL_AUX_AKSV_SELECT); - if (ret < 0) { - DRM_DEBUG_KMS("Write Aksv over DP/AUX failed (%d)\n", ret); - return ret; - } else if (ret == 0) { - DRM_DEBUG_KMS("Aksv write over DP/AUX was empty\n"); - return -EIO; - } - - reply = (rxbuf[0] >> 4) & DP_AUX_NATIVE_REPLY_MASK; - if (reply != DP_AUX_NATIVE_REPLY_ACK) { - DRM_DEBUG_KMS("Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n", - reply); - return -EIO; + dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV, + aksv, DRM_HDCP_KSV_LEN); + if (dpcd_ret != DRM_HDCP_KSV_LEN) { + DRM_DEBUG_KMS("Failed to write Aksv over DP/AUX (%zd)\n", + dpcd_ret); + return dpcd_ret >= 0 ? -EIO : dpcd_ret; } return 0; } From patchwork Fri Jan 17 19:30:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339663 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6D8B392A for ; Fri, 17 Jan 2020 19:31:30 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4C58E2072B for ; Fri, 17 Jan 2020 19:31:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="Wcyuvn+h" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4C58E2072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 972A16F8E2; Fri, 17 Jan 2020 19:31:15 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc42.google.com (mail-yw1-xc42.google.com [IPv6:2607:f8b0:4864:20::c42]) by gabe.freedesktop.org (Postfix) with ESMTPS id 87B7F6F8DF for ; Fri, 17 Jan 2020 19:31:12 +0000 (UTC) Received: by mail-yw1-xc42.google.com with SMTP id t141so14826530ywc.11 for ; Fri, 17 Jan 2020 11:31:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vCqhWZxKLkRGJQifIZv6y999wq0wVRJdEkxycq1q+QE=; b=Wcyuvn+hOoPdjp+jWdzMKQ9jIkhMix9O9mIx+Xxa5vBEAoWst8pWMRMQG8A43IuE4U n1UrBAFv4s1/a/heHvtKVc78owRuqrN9hXouHap8LIYPepqREe6RJPca1vfFWYZQesJh v3DAUWX11T7V+EmNiDWv+iEc8MMcNZyHKjAQ0TY3ket3+To3r7mSZr4fZOSdS1ezFiVq DHg1l7AXd10Bh505t3GzOwnC0AjzYrscv+B8Uwnwfohp/1Y/RhgpFtXbbeXM+S8GNSGB Op0B5IU4YnpQ/Ire1MzFIsNkrcUZdBg3oQ23ujTqNqfzYfW4NSehlNJrPi5DbThHkCSc Kj2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vCqhWZxKLkRGJQifIZv6y999wq0wVRJdEkxycq1q+QE=; b=ItldTqsirTTghThaSvNmIeRGH1Fj/AlQk8sDbIl51YPk+SHGMvS8EUu+jzYYjvInf4 lmstvGt6pJpuEez+c6gOcUq7Dsrn3R1vIAPWh2uuty6X7Bd9+SDM+ZOFXuD1xT0Z9cPE ex9Zx7KEZgZnJcIfXSbjti/q8NhzWjUyi6t5SeHVVExJ6hGvTN7dj1nWXItBFcUGTHr3 FULHmRumb2QoaMNr405ALPNiIXZmYCWN+CfSZDGrqwdiSepMcqdwblMIZEBXNp96uMOu qlvWRf99C2QSpPjTMY0sM3S63gPEv2qnYRdiXXUpyVQad2sjHGn6DzqiHSnrYOKwIKE6 Av6w== X-Gm-Message-State: APjAAAXlTjaUCpSl9sx/3ILk5bXhPHzeiW0i70pSrR+mqAzeAycxCzff 3yUkVG6JufQMko+tQLY0fSAHVTWh8OzRfw== X-Google-Smtp-Source: APXvYqydeEzxYslmq8WWftXx0mvzICqrPiOwFP22UZ5PLcyVkacm6wA4HeFVEADV/Rn8qKfWzuliiA== X-Received: by 2002:a81:924d:: with SMTP id j74mr32779575ywg.381.1579289471439; Fri, 17 Jan 2020 11:31:11 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id t15sm11984105ywg.67.2020.01.17.11.31.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:11 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 05/12] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling Date: Fri, 17 Jan 2020 14:30:56 -0500 Message-Id: <20200117193103.156821-6-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul Instead of using intel_dig_port's encoder pipe to determine which transcoder to toggle signalling on, use the cpu_transcoder field already stored in intel_hdmi. This is particularly important for MST. Suggested-by: Ville Syrjälä Reviewed-by: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-6-sean@poorly.run #v2 Changes in v2: - Added to the set Changes in v3: - s/hdcp/hdmi/ in commit msg (Ram) --- drivers/gpu/drm/i915/display/intel_ddi.c | 13 ++++--------- drivers/gpu/drm/i915/display/intel_ddi.h | 2 ++ .../gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 1 + drivers/gpu/drm/i915/display/intel_hdcp.c | 11 +++++++---- drivers/gpu/drm/i915/display/intel_hdmi.c | 16 +++++++++++----- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 87b8b347f682..a90ce672d2cf 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2017,12 +2017,12 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state } int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, + enum transcoder cpu_transcoder, bool enable) { struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); intel_wakeref_t wakeref; - enum pipe pipe = 0; int ret = 0; u32 tmp; @@ -2031,18 +2031,13 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, if (WARN_ON(!wakeref)) return -ENXIO; - if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) { - ret = -EIO; - goto out; - } - - tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe)); + tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); if (enable) tmp |= TRANS_DDI_HDCP_SIGNALLING; else tmp &= ~TRANS_DDI_HDCP_SIGNALLING; - I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp); -out: + I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), tmp); + intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h index 167c6579d972..5b22daf04060 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -18,6 +18,7 @@ struct intel_crtc_state; struct intel_dp; struct intel_dpll_hw_state; struct intel_encoder; +enum transcoder; void intel_ddi_fdi_post_disable(struct intel_encoder *intel_encoder, const struct intel_crtc_state *old_crtc_state, @@ -45,6 +46,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder); u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder, u8 voltage_swing); int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, + enum transcoder cpu_transcoder, bool enable); void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index fdd943a17de3..8a96fedefad3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -301,6 +301,7 @@ struct intel_hdcp_shim { /* Enables HDCP signalling on the port */ int (*toggle_signalling)(struct intel_digital_port *intel_dig_port, + enum transcoder cpu_transcoder, bool enable); /* Ensures the link is still protected */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0d59f62917ed..89501b7525a9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6083,6 +6083,7 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port, static int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, + enum transcoder cpu_transcoder, bool enable) { /* Not used for single stream DisplayPort setups */ diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index c4394c8e10eb..f8d56d3b2ddb 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -693,7 +693,7 @@ static int intel_hdcp_auth(struct intel_connector *connector) intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder, port)); - ret = shim->toggle_signalling(intel_dig_port, true); + ret = shim->toggle_signalling(intel_dig_port, cpu_transcoder, true); if (ret) return ret; @@ -792,7 +792,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector) port); I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl); - ret = hdcp->shim->toggle_signalling(intel_dig_port, false); + ret = hdcp->shim->toggle_signalling(intel_dig_port, cpu_transcoder, + false); if (ret) { DRM_ERROR("Failed to disable HDCP signalling\n"); return ret; @@ -1552,7 +1553,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector) WARN_ON(I915_READ(HDCP2_STATUS(dev_priv, cpu_transcoder, port)) & LINK_ENCRYPTION_STATUS); if (hdcp->shim->toggle_signalling) { - ret = hdcp->shim->toggle_signalling(intel_dig_port, true); + ret = hdcp->shim->toggle_signalling(intel_dig_port, + cpu_transcoder, true); if (ret) { DRM_ERROR("Failed to enable HDCP signalling. %d\n", ret); @@ -1603,7 +1605,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector) DRM_DEBUG_KMS("Disable Encryption Timedout"); if (hdcp->shim->toggle_signalling) { - ret = hdcp->shim->toggle_signalling(intel_dig_port, false); + ret = hdcp->shim->toggle_signalling(intel_dig_port, + cpu_transcoder, false); if (ret) { DRM_ERROR("Failed to disable HDCP signalling. %d\n", ret); diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 93ac0f296852..6b28c00d7289 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1444,7 +1444,8 @@ 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) +static int kbl_repositioning_enc_en_signal(struct intel_connector *connector, + enum transcoder cpu_transcoder) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); @@ -1461,12 +1462,14 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector) usleep_range(25, 50); } - ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, false); + ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, + cpu_transcoder, 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); + ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, + cpu_transcoder, true); if (ret) { DRM_ERROR("Enable HDCP signalling failed (%d)\n", ret); return ret; @@ -1477,6 +1480,7 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector) static int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, + enum transcoder cpu_transcoder, bool enable) { struct intel_hdmi *hdmi = &intel_dig_port->hdmi; @@ -1487,7 +1491,8 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, if (!enable) usleep_range(6, 60); /* Bspec says >= 6us */ - ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, enable); + ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, + cpu_transcoder, enable); if (ret) { DRM_ERROR("%s HDCP signalling failed (%d)\n", enable ? "Enable" : "Disable", ret); @@ -1499,7 +1504,8 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, * opportunity and enc_en signalling in KABYLAKE. */ if (IS_KABYLAKE(dev_priv) && enable) - return kbl_repositioning_enc_en_signal(connector); + return kbl_repositioning_enc_en_signal(connector, + cpu_transcoder); return 0; } From patchwork Fri Jan 17 19:30:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339665 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0BA7692A for ; Fri, 17 Jan 2020 19:31:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DE4FD2072B for ; Fri, 17 Jan 2020 19:31:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="baLlv6HB" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DE4FD2072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1BFAA6F8E3; Fri, 17 Jan 2020 19:31:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yb1-xb42.google.com (mail-yb1-xb42.google.com [IPv6:2607:f8b0:4864:20::b42]) by gabe.freedesktop.org (Postfix) with ESMTPS id 10EDA6F8E1 for ; Fri, 17 Jan 2020 19:31:14 +0000 (UTC) Received: by mail-yb1-xb42.google.com with SMTP id x18so6383635ybk.6 for ; Fri, 17 Jan 2020 11:31:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bKZcnT+TsVxfMWYRx4pqWKSy//If+wmK7L6G6Yxhy4U=; b=baLlv6HB70X15TtezlclweYvNUsdGJsQod8hMsS2IVZnP4SP2FODIE/7rTMegy+VDz mVzxNWZZbvfw4sKJJ78bkYt51exgeFqNq3ppa1X1x46mmKAQAxVwaGd9nov6TMzid8Tp 8LBmMHyVp6+5Rz2sj6kemx12kodeaKdwsft7f4+WzaOnyIRksqobJzkqJ120FIxVfZ34 k1FNxPUfeLQZBFMdvrp7aYEwSaF9m4MD/o/e7zaHiknAWc4Tg5oPzZzlVJ/hnqDdvi1v IU4WHNQ/Jbk2BD3DwB8K0usS8LG+wpoah8pquvFradzh474Es/oGzCRCh0gOw2U/jytr GBUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bKZcnT+TsVxfMWYRx4pqWKSy//If+wmK7L6G6Yxhy4U=; b=SydLYoepJuybDnsPHOMSqJsZS2ihBjnNrbuhojCrEj/rt8k+rCUY5CRTyOS7VFnzXW NO8l7iL9KWD1J82ATVWWLEUxnr37n+Rfc+SYDAfHCClnbQPVkBWHUiS6brS5BiG2CgI5 QBZe/ARGH+t4zEMhazRlFqL8FmnXF1TEg86p21mxm4IUb+Uw/4IFCCqqXM1e/O4YDKv5 M1zWQdt4bi44XF3hGjBKa1ZMC9/QAEXUeAJXkulMfkv+joEB//eC3Ht8eV68Yfp/RbZk JOs7+G8y69U6CpNK7Rhi3IY4MXYO/APS9XpEmu6vflKAl3mzN+O/u/r3TMbb+WCZXPgJ sRLg== X-Gm-Message-State: APjAAAVJay2fKkTCUufL/asA/0i+bQ9SOZVMAujJLbgeqW0YuyoIlEPX 4GdHWRoquBQ92rJkaLxAVsS6OlO6CPs2Dg== X-Google-Smtp-Source: APXvYqyEFN39EFp9biwYUfMLVVQx9Uf0Ji6ieoA86TzStUPLuGv4ViCXXX3ENkkj/0GExWeb75gGMQ== X-Received: by 2002:a25:1a55:: with SMTP id a82mr13788404yba.497.1579289472968; Fri, 17 Jan 2020 11:31:12 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id t5sm11907486ywc.3.2020.01.17.11.31.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:12 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 06/12] drm/i915: Factor out hdcp->value assignments Date: Fri, 17 Jan 2020 14:30:57 -0500 Message-Id: <20200117193103.156821-7-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul This is a bit of housecleaning for a future patch. Instead of sprinkling hdcp->value assignments and prop_work scheduling everywhere, introduce a function to do it for us. Reviewed-by: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-7-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-7-sean@poorly.run #v2 Changes in v2: -None Changes in v3: -None --- drivers/gpu/drm/i915/display/intel_hdcp.c | 67 ++++++++++++++++------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index f8d56d3b2ddb..798e7e1a19fc 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -852,6 +852,21 @@ struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp) return container_of(hdcp, struct intel_connector, hdcp); } +static void intel_hdcp_update_value(struct intel_connector *connector, + u64 value, bool update_property) +{ + struct intel_hdcp *hdcp = &connector->hdcp; + + WARN_ON(!mutex_is_locked(&hdcp->mutex)); + + if (hdcp->value == value) + return; + + hdcp->value = value; + if (update_property) + schedule_work(&hdcp->prop_work); +} + /* Implements Part 3 of the HDCP authorization procedure */ static int intel_hdcp_check_link(struct intel_connector *connector) { @@ -878,15 +893,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector) I915_READ(HDCP_STATUS(dev_priv, cpu_transcoder, port))); ret = -ENXIO; - hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; - schedule_work(&hdcp->prop_work); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_DESIRED, + true); 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); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_ENABLED, true); } goto out; } @@ -897,16 +913,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector) 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); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_DESIRED, + true); 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); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_DESIRED, + true); goto out; } @@ -1716,16 +1734,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) I915_READ(HDCP2_STATUS(dev_priv, cpu_transcoder, port))); ret = -ENXIO; - hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; - schedule_work(&hdcp->prop_work); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_DESIRED, + true); 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); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_ENABLED, + true); } goto out; } @@ -1737,8 +1757,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) 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); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_ENABLED, + true); goto out; } DRM_DEBUG_KMS("[%s:%d] Repeater topology auth failed.(%d)\n", @@ -1753,8 +1774,8 @@ static int intel_hdcp2_check_link(struct intel_connector *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); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_DESIRED, true); goto out; } @@ -1763,8 +1784,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) 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); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_DESIRED, + true); goto out; } @@ -2004,8 +2026,9 @@ int intel_hdcp_enable(struct intel_connector *connector, if (!ret) { schedule_delayed_work(&hdcp->check_work, check_link_interval); - hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED; - schedule_work(&hdcp->prop_work); + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_ENABLED, + true); } mutex_unlock(&hdcp->mutex); @@ -2023,7 +2046,9 @@ int intel_hdcp_disable(struct intel_connector *connector) mutex_lock(&hdcp->mutex); if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { - hdcp->value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED; + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_UNDESIRED, + false); if (hdcp->hdcp2_encrypted) ret = _intel_hdcp2_disable(connector); else if (hdcp->hdcp_encrypted) From patchwork Fri Jan 17 19:30:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339667 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A7E88921 for ; Fri, 17 Jan 2020 19:31:33 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 869B52072B for ; Fri, 17 Jan 2020 19:31:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="ODdIjfqS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 869B52072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1E5A16F8E4; Fri, 17 Jan 2020 19:31:17 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc42.google.com (mail-yw1-xc42.google.com [IPv6:2607:f8b0:4864:20::c42]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8846C6F8DF for ; Fri, 17 Jan 2020 19:31:15 +0000 (UTC) Received: by mail-yw1-xc42.google.com with SMTP id n184so14848173ywc.3 for ; Fri, 17 Jan 2020 11:31:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3ubir/m9xDSlAFBCmwMlfNBHlzcc7MKfRN+IGBaH8jo=; b=ODdIjfqS5LqerJVA5GdNL+kRYqk4I2IspEeFz93TdGLhiUTwgZ6WvHw4VVAlSIHrGI eIg4rPszArm5Uiem4TTRR0ZBSdHEPy0b9UUF1y+JYF/80cx60ghVHKAFnCqald1MPorD qxS8BlPxY+e7G0gzBZOZmUAgP5vHFVL1A65HMvXCFvH9rWEk9+o0ur1cGCMKe6erL3KW m2tjpwYNPUkoeTXOv3KMfYCU1LvRPUZRu9L5E33h7+l8Z6+OhN66QId4E9WR/K4RFCL5 3rT13cj1gWHdtTYxxvd1REayrewBp1QYedwy9Hg3llGlITKeoiBrDWhFttT6KO4QIRm4 KCZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3ubir/m9xDSlAFBCmwMlfNBHlzcc7MKfRN+IGBaH8jo=; b=gj6FCjS9Ryynn6kQEwhRq5r9WEauzZfpO2YKytK7NaqbtESpZQw7T4YT6eWKaKbK1T CHAxPWRQQOR4hhNE/sCKvhyhVBjbqhERRwMFBv1Ea3YYgNxBrsNW0YjCSeqqwZFaXnkM Rs33J5G8BLtk8asa2WNpHvL9n1qp/O23VEjUCNfYFmIJGWIlZzYBbuIk1Dy/AQRp/JzN yGeNT9FklrdmeaefSaQpHfG+TeKRtag6t2hEcxrSjsjwXKaE9ze2dPa3aXkDR2lwSfjz GMpgcJGBxfzH3QmCotyMdYF9Rl9tW9Hvx9Q7Ois1q6Ho3tPGWWU0UyvxWCwEcbP9Lo7Y Rw7w== X-Gm-Message-State: APjAAAUJm/C2bmEaQNBlU7TdhPYYf7ZyN2Q3BXrfsTnnCKr+MMNepWgj jgYJ7+T9J94h3OH7zZZYyV/AydW/ZJjm8g== X-Google-Smtp-Source: APXvYqxTRun/YYf6j5hDaVvmHdcIsWSTdXxI77ri4rxOqnjqidu4c9ZIGks0bbD6J7fzFd087Zzplg== X-Received: by 2002:a81:2746:: with SMTP id n67mr30798872ywn.182.1579289474183; Fri, 17 Jan 2020 11:31:14 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id p62sm11342850ywc.44.2020.01.17.11.31.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:13 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 07/12] drm/i915: Protect workers against disappearing connectors Date: Fri, 17 Jan 2020 14:30:58 -0500 Message-Id: <20200117193103.156821-8-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul This patch adds some protection against connectors being destroyed before the HDCP workers are finished. For check_work, we do a synchronous cancel after the connector is unregistered which will ensure that it is finished before destruction. In the case of prop_work, we can't do a synchronous wait since it needs to take connection_mutex which could cause deadlock. Instead, we'll take a reference on the connector when scheduling prop_work and give it up once we're done. Reviewed-by: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-8-sean@poorly.run #v2 Changes in v2: - Added to the set Changes in v3: - Change the WARN_ON condition in intel_hdcp_cleanup to allow for initializing connectors as well --- drivers/gpu/drm/i915/display/intel_hdcp.c | 43 ++++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 798e7e1a19fc..fabacfb1b644 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -863,8 +863,10 @@ static void intel_hdcp_update_value(struct intel_connector *connector, return; hdcp->value = value; - if (update_property) + if (update_property) { + drm_connector_get(&connector->base); schedule_work(&hdcp->prop_work); + } } /* Implements Part 3 of the HDCP authorization procedure */ @@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work) mutex_unlock(&hdcp->mutex); drm_modeset_unlock(&dev->mode_config.connection_mutex); + + drm_connector_put(&connector->base); } bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port) @@ -1802,6 +1806,9 @@ static void intel_hdcp_check_work(struct work_struct *work) check_work); struct intel_connector *connector = intel_hdcp_to_connector(hdcp); + if (drm_connector_is_unregistered(&connector->base)) + return; + if (!intel_hdcp2_check_link(connector)) schedule_delayed_work(&hdcp->check_work, DRM_HDCP2_CHECK_PERIOD_MS); @@ -2076,12 +2083,38 @@ void intel_hdcp_component_fini(struct drm_i915_private *dev_priv) void intel_hdcp_cleanup(struct intel_connector *connector) { - if (!connector->hdcp.shim) + struct intel_hdcp *hdcp = &connector->hdcp; + + if (!hdcp->shim) return; - mutex_lock(&connector->hdcp.mutex); - kfree(connector->hdcp.port_data.streams); - mutex_unlock(&connector->hdcp.mutex); + /* + * If the connector is registered, it's possible userspace could kick + * off another HDCP enable, which would re-spawn the workers. + */ + WARN_ON(connector->base.registration_state == DRM_CONNECTOR_REGISTERED); + + /* + * Now that the connector is not registered, check_work won't be run, + * but cancel any outstanding instances of it + */ + cancel_delayed_work_sync(&hdcp->check_work); + + /* + * We don't cancel prop_work in the same way as check_work since it + * requires connection_mutex which could be held while calling this + * function. Instead, we rely on the connector references grabbed before + * scheduling prop_work to ensure the connector is alive when prop_work + * is run. So if we're in the destroy path (which is where this + * function should be called), we're "guaranteed" that prop_work is not + * active (tl;dr This Should Never Happen). + */ + WARN_ON(work_pending(&hdcp->prop_work)); + + mutex_lock(&hdcp->mutex); + kfree(hdcp->port_data.streams); + hdcp->shim = NULL; + mutex_unlock(&hdcp->mutex); } void intel_hdcp_atomic_check(struct drm_connector *connector, From patchwork Fri Jan 17 19:30:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339669 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2C00892A for ; Fri, 17 Jan 2020 19:31:37 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 09E6D2072B for ; Fri, 17 Jan 2020 19:31:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="KNX6kbXg" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 09E6D2072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F0CAA6F8E8; Fri, 17 Jan 2020 19:31:19 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yb1-xb43.google.com (mail-yb1-xb43.google.com [IPv6:2607:f8b0:4864:20::b43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 896BC6F8E6 for ; Fri, 17 Jan 2020 19:31:16 +0000 (UTC) Received: by mail-yb1-xb43.google.com with SMTP id k15so6660110ybd.10 for ; Fri, 17 Jan 2020 11:31:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UrSO/k55VdhipLaQRmQtE0SXT4vzZi3TKz+iaXCu8hE=; b=KNX6kbXgdCciMNskRxCEH816RtpHWp5fkXPT0+wpkAG4gOVz0iJ9ilveECPLsHIxn9 KR86pznN262miJttjPT25cwE+QsfCeEat8KuTL5O918DiEXb51w5YszwTPp+1pKXMems Bu89t6z0fIRJQi0zAyPQJrOR42kBpZfKiMdViT0ahaLaf0A6hUEa8yqOsA77AxA8oWps RDB6nU1tubO/69dWg/dwp650y8AZFlkRuGk/F526BXf9+uUg3Fr24jYmCp2cQjPqSUMm mcKSiZmwRrTPZ3EtkWrFj4VHsQjwze/vkvDkr77TdJqOZibdNSHUBdb7KSKZfD0Z1bMR Q5Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UrSO/k55VdhipLaQRmQtE0SXT4vzZi3TKz+iaXCu8hE=; b=DhfqSzEEpWsEy/8hpiJJUrvvYtbTuNQVEPv7Svw0bvMKGyG56ec5rE9tjhBoxZUjQW zo3mr5xOydprcLkAQMhOlfhJpHpe9FsA/GR5oQ3YyUqCp+lZVOFFn8pQdoiJTDtBN9Me dLmCt/wQ4y22nuvw1bXfiuauQCobebPDEcLMtVLNGQjPb1xg8Wrugdxctzs+nw3dq21w T1sogop7lY+ekfTiYK3bRHzICUVpl1NOYXYCghxXWy8YLMhyH8KBCKZrsTjWxekAoSnZ Ghe6jwiwOAlnMvKG9kATMdgmIvane3ZaewvWzkTithU9f3vgbpOgVObadOs6S1ZpXz7F mAKA== X-Gm-Message-State: APjAAAUPiLnH91XexjPcfxt023wz9O5Qwc8lMs/t2OT0EUs5dxj7i6xU 7Xf7hfwADjG9yXT9EWrnym7lEPdEQlveWg== X-Google-Smtp-Source: APXvYqx6XFZvoT2aYrfDD87SYeb+dV2vjl/ivIGaP9z05+ZZQamQnExigN9n25MP/Dswl5qEqpp8LQ== X-Received: by 2002:a5b:611:: with SMTP id d17mr29460821ybq.87.1579289475404; Fri, 17 Jan 2020 11:31:15 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id e76sm11848968ywe.25.2020.01.17.11.31.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:15 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it Date: Fri, 17 Jan 2020 14:30:59 -0500 Message-Id: <20200117193103.156821-9-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul This patch is required for HDCP over MST. If a port is being used for multiple HDCP streams, we don't want to fully disable HDCP on a port if one of them is disabled. Instead, we just disable the HDCP signalling on that particular pipe and exit early. The last pipe to disable HDCP will also bring down HDCP on the port. In order to achieve this, we need to keep a refcount in intel_digital_port and protect it using a new hdcp_mutex. Cc: Ramalingam C Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-9-sean@poorly.run #v2 Changes in v2: - Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work Changes in v3: - None --- drivers/gpu/drm/i915/display/intel_ddi.c | 3 ++ .../drm/i915/display/intel_display_types.h | 5 ++ drivers/gpu/drm/i915/display/intel_dp.c | 2 + drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++++++++++++++---- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 + 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index a90ce672d2cf..4073dd96b83e 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4815,6 +4815,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) encoder = &intel_dig_port->base; + mutex_init(&intel_dig_port->hdcp_mutex); + intel_dig_port->num_hdcp_streams = 0; + drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 8a96fedefad3..b488e8b1478e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1355,6 +1355,11 @@ struct intel_digital_port { enum phy_fia tc_phy_fia; u8 tc_phy_fia_idx; + /* protects num_hdcp_streams reference count */ + struct mutex hdcp_mutex; + /* the number of pipes using HDCP signalling out of this port */ + unsigned int num_hdcp_streams; + void (*write_infoframe)(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, unsigned int type, diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 89501b7525a9..a91f65ba35a1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7583,6 +7583,8 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, intel_encoder = &intel_dig_port->base; encoder = &intel_encoder->base; + mutex_init(&intel_dig_port->hdcp_mutex); + if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base, &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS, "DP %c", port_name(port))) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index fabacfb1b644..dc83d81c6df0 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -779,6 +779,19 @@ 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); + /* + * If there are other connectors on this port using HDCP, don't disable + * it. Instead, toggle the HDCP signalling off on that particular + * connector/pipe and exit. + */ + if (intel_dig_port->num_hdcp_streams > 0) { + ret = hdcp->shim->toggle_signalling(intel_dig_port, + cpu_transcoder, false); + if (ret) + DRM_ERROR("Failed to disable HDCP signalling\n"); + return ret; + } + hdcp->hdcp_encrypted = false; I915_WRITE(HDCP_CONF(dev_priv, cpu_transcoder, port), 0); if (intel_de_wait_for_clear(dev_priv, @@ -855,6 +868,7 @@ struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp) static void intel_hdcp_update_value(struct intel_connector *connector, u64 value, bool update_property) { + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; WARN_ON(!mutex_is_locked(&hdcp->mutex)); @@ -862,6 +876,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector, if (hdcp->value == value) return; + WARN_ON(!mutex_is_locked(&intel_dig_port->hdcp_mutex)); + + if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) { + if (!WARN_ON(intel_dig_port->num_hdcp_streams == 0)) + intel_dig_port->num_hdcp_streams--; + } else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) { + intel_dig_port->num_hdcp_streams++; + } + hdcp->value = value; if (update_property) { drm_connector_get(&connector->base); @@ -880,6 +903,8 @@ static int intel_hdcp_check_link(struct intel_connector *connector) int ret = 0; mutex_lock(&hdcp->mutex); + mutex_lock(&intel_dig_port->hdcp_mutex); + cpu_transcoder = hdcp->cpu_transcoder; /* Check_link valid only when HDCP1.4 is enabled */ @@ -931,6 +956,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector) } out: + mutex_unlock(&intel_dig_port->hdcp_mutex); mutex_unlock(&hdcp->mutex); return ret; } @@ -1996,6 +2022,7 @@ int intel_hdcp_enable(struct intel_connector *connector, enum transcoder cpu_transcoder, u8 content_type) { 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; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; int ret = -EINVAL; @@ -2004,6 +2031,7 @@ int intel_hdcp_enable(struct intel_connector *connector, return -ENOENT; mutex_lock(&hdcp->mutex); + mutex_lock(&intel_dig_port->hdcp_mutex); WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED); hdcp->content_type = content_type; @@ -2038,12 +2066,14 @@ int intel_hdcp_enable(struct intel_connector *connector, true); } + mutex_unlock(&intel_dig_port->hdcp_mutex); mutex_unlock(&hdcp->mutex); return ret; } int intel_hdcp_disable(struct intel_connector *connector) { + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; int ret = 0; @@ -2051,17 +2081,21 @@ int intel_hdcp_disable(struct intel_connector *connector) return -ENOENT; mutex_lock(&hdcp->mutex); + mutex_lock(&intel_dig_port->hdcp_mutex); - if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { - intel_hdcp_update_value(connector, - DRM_MODE_CONTENT_PROTECTION_UNDESIRED, - false); - if (hdcp->hdcp2_encrypted) - ret = _intel_hdcp2_disable(connector); - else if (hdcp->hdcp_encrypted) - ret = _intel_hdcp_disable(connector); - } + if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) + goto out; + + intel_hdcp_update_value(connector, + DRM_MODE_CONTENT_PROTECTION_UNDESIRED, false); + if (hdcp->hdcp2_encrypted) + ret = _intel_hdcp2_disable(connector); + else if (hdcp->hdcp_encrypted) + ret = _intel_hdcp_disable(connector); + +out: + mutex_unlock(&intel_dig_port->hdcp_mutex); mutex_unlock(&hdcp->mutex); cancel_delayed_work_sync(&hdcp->check_work); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 6b28c00d7289..68b648ec6abb 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -3252,6 +3252,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv, intel_encoder = &intel_dig_port->base; + mutex_init(&intel_dig_port->hdcp_mutex); + drm_encoder_init(&dev_priv->drm, &intel_encoder->base, &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS, "HDMI %c", port_name(port)); From patchwork Fri Jan 17 19:31:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339671 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A40FD921 for ; Fri, 17 Jan 2020 19:31:38 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 82E4C2072B for ; Fri, 17 Jan 2020 19:31:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="V4rTLTFz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 82E4C2072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DF1396F8E7; Fri, 17 Jan 2020 19:31:19 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc41.google.com (mail-yw1-xc41.google.com [IPv6:2607:f8b0:4864:20::c41]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8E2176F8E7 for ; Fri, 17 Jan 2020 19:31:17 +0000 (UTC) Received: by mail-yw1-xc41.google.com with SMTP id 10so14828788ywv.5 for ; Fri, 17 Jan 2020 11:31:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=s3OkfGIoleUm6Rec1dUioh8HFNHKiCT+sLnujPKvY3w=; b=V4rTLTFz7oekQnIaAzZ0x/kQRqewFQHPankUsezx/D9KTFTM56/vb4ZvkCpRAhthYz ggtS6x8+w+gE6uedyfexbeqtv1gBh3pk9ykTsaR6T+GtctQ5M297NNZ4PZ3P3p5L+D+Z BbI5UVsPz8Z7efxNKSiE24Ewn/31h73b3NcI0MP43lWWy+T2BAXgw6S097wYSo2stQvM XMZC/XxJRenXJAbVTWVNIuvZpCQY6nG0OW4UtNTSNlrOuRzMa/FGTwaMdgPaGnhflgy1 7By0T/APf4wtXJgWggmFUDGjkIBY2H/vf5Qku3/sy+WfkvvXJCiHxRS8Hpb2K1v+QxWV cNnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=s3OkfGIoleUm6Rec1dUioh8HFNHKiCT+sLnujPKvY3w=; b=dtx55Xym9Umey+3r7fH7Ou8vqYrE6b1/JvH37PFxbFsAANSmE3xnF2gwkP2P2CfQcv x/9ibJNNtgsn3KMfuFgZ1hAEsox3T7tg4zB4Sk9JMrlZrlzQrxQBWIPYYHhWp834c5Kw IytmHctByDwNm06Jf66rouEntpn0yZglGZ+Uhd4PChpwK0zWvtPYO+VRJtVNHaHVnP2J FgpQR4J9ZitPuoCjqfnMbL+2aNYA448vJnGAx3CUDqc10JLSuIOUGQ74lpVF/FjZOZgx g0Fp2+PIv3yMQ5Vui5x4yr8CZfRwqnBbQw58I/YJUuiNhGDOlUaqv7fbkos8OsNW9aT9 Z/JQ== X-Gm-Message-State: APjAAAWRUhkmkVjub29tMaBk05lTpmNvnOjdA8TPZOPEATEVtSf2VY0K o96M+WaLYn+TUmRe6oNphkc1hgLmZX0jJg== X-Google-Smtp-Source: APXvYqxNTK9OOHmQjK67mkq0DyWDKlvmtO4zuL5OC2OlrkCBm06kYY/0ZM6EpUly6J7H0iaAPZCpcQ== X-Received: by 2002:a81:9a82:: with SMTP id r124mr29108959ywg.469.1579289476593; Fri, 17 Jan 2020 11:31:16 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id s5sm11732242ywb.34.2020.01.17.11.31.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:16 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 09/12] drm/i915: Support DP MST in enc_to_dig_port() function Date: Fri, 17 Jan 2020 14:31:00 -0500 Message-Id: <20200117193103.156821-10-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul Although DP_MST fake encoders are not subclassed from digital ports, they are associated with them. Support these encoders. Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-9-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-10-sean@poorly.run #v2 Changes in v2: -None Changes in v3: -None --- .../drm/i915/display/intel_display_types.h | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b488e8b1478e..d7f4897a1eb9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1460,6 +1460,18 @@ static inline bool intel_encoder_is_dig_port(struct intel_encoder *encoder) } } +static inline bool intel_encoder_is_mst(struct intel_encoder *encoder) +{ + return encoder->type == INTEL_OUTPUT_DP_MST; +} + +static inline struct intel_dp_mst_encoder * +enc_to_mst(struct intel_encoder *encoder) +{ + return container_of(&encoder->base, struct intel_dp_mst_encoder, + base.base); +} + static inline struct intel_digital_port * enc_to_dig_port(struct intel_encoder *encoder) { @@ -1468,6 +1480,8 @@ enc_to_dig_port(struct intel_encoder *encoder) if (intel_encoder_is_dig_port(intel_encoder)) return container_of(&encoder->base, struct intel_digital_port, base.base); + else if (intel_encoder_is_mst(intel_encoder)) + return enc_to_mst(encoder)->primary; else return NULL; } @@ -1478,13 +1492,6 @@ conn_to_dig_port(struct intel_connector *connector) return enc_to_dig_port(intel_attached_encoder(connector)); } -static inline struct intel_dp_mst_encoder * -enc_to_mst(struct intel_encoder *encoder) -{ - return container_of(&encoder->base, struct intel_dp_mst_encoder, - base.base); -} - static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder) { return &enc_to_dig_port(encoder)->dp; From patchwork Fri Jan 17 19:31:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339673 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2494E921 for ; Fri, 17 Jan 2020 19:31:40 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 036872072B for ; Fri, 17 Jan 2020 19:31:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="bTt0dwHn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 036872072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EEA476F8EB; Fri, 17 Jan 2020 19:31:20 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc43.google.com (mail-yw1-xc43.google.com [IPv6:2607:f8b0:4864:20::c43]) by gabe.freedesktop.org (Postfix) with ESMTPS id D27DE6F8E5 for ; Fri, 17 Jan 2020 19:31:18 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id l22so14845375ywc.8 for ; Fri, 17 Jan 2020 11:31:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CVp0iaVlF0nO///15Pnb5sk5f0/+/YTOeu8+lpIkcpI=; b=bTt0dwHnq7o+7un24uht4HBmTSL8cB4Eljm2zHFM6I8UtVkuHG5aFd+mkUwW/YTR5q JTQIKYicadJKsmqvht0GG83CfJ1+0vrtntQ5cYL0nDs6jFxWSCuepMmaSsPonwHfpFwk 6hzquhoAM+jy1n7X2zx6+JEKrJTDQtrrsXITBG+nspOWTpOqC9WJ3pkMEpR6J56wXFc5 MrQm5yemEwaqDm/oOMH5MqNGCe3IRpRyC/bCOQpmCWRWB8KAbezbPasU28RF1cmQ65hB +5nK33vbzeK8hBXe+x872WTrPRnsnNmbiviUWM0EH6O2eRLgWZTv80E3ldw7qvAgMlIq ttBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CVp0iaVlF0nO///15Pnb5sk5f0/+/YTOeu8+lpIkcpI=; b=VPBkMnFmdXL9dHt2Ag8Nlb8czpF7N8u151DgLZ4suVPy7HBYi27m0Xj3L5qM7R4ZUz jRSr0XWIKfJBliCr1RWhn9bL7InuFh/NsHT5GnLySkN/YvUUJDPh3+xxuzXym3ScDarp 8GXfnPKb9QH5hfxIqB7KioP/vaVUiqmyIxTqhaiy3MzLqvmVXCMZSZcZHzvfbE4NhBR0 9/G2y1m5S2F9JAYb2GmyM/W7KNecC6HkbV7vkYSV6xUy//kaPH9PQP5DBgDZ939PIr5Y dZ+I84DuByGGInOZF1+8GonTfxDHHysSyz79iOcOEIEennlp0uZrtoaDCD1Qj/avERrl GPAQ== X-Gm-Message-State: APjAAAU/Gr24I+3Yo9FNm0wADgUliabEEd3F27OPIwzDH1OMyqqWcocS aaJX+aIVhzNq0bWNPBwhzvu6SIvJwoss2A== X-Google-Smtp-Source: APXvYqwEOd+XBNax5JSbaTr1u1iU6k+SMgutvsRrwm53mQnASW/cZEpkCCV4zdmD77M4FtTW5WVrzQ== X-Received: by 2002:a81:ac47:: with SMTP id z7mr30597420ywj.42.1579289477811; Fri, 17 Jan 2020 11:31:17 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id e185sm12292661ywa.33.2020.01.17.11.31.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:17 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 10/12] drm/i915: Use ddi_update_pipe in intel_dp_mst Date: Fri, 17 Jan 2020 14:31:01 -0500 Message-Id: <20200117193103.156821-11-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul In order to act upon content_protection property changes, we'll need to implement the .update_pipe() hook. We can re-use intel_ddi_update_pipe for this Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-10-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-11-sean@poorly.run #v2 Changes in v2: -None Changes in v3: -None --- drivers/gpu/drm/i915/display/intel_ddi.c | 9 +++++---- drivers/gpu/drm/i915/display/intel_dp.h | 4 ++++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 4073dd96b83e..43e935d3d86c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4136,9 +4136,9 @@ 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, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +void intel_ddi_update_pipe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -4148,7 +4148,8 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder, conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED); - if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && + !intel_encoder_is_mst(encoder)) intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state); /* diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 3da166054788..0a028b58a8be 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -125,4 +125,8 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count) u32 intel_dp_mode_to_fec_clock(u32 mode_clock); +void intel_ddi_update_pipe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); + #endif /* __INTEL_DP_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index cba68c5a80fa..975d97989d3b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -774,6 +774,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum intel_encoder->compute_config = intel_dp_mst_compute_config; intel_encoder->disable = intel_mst_disable_dp; intel_encoder->post_disable = intel_mst_post_disable_dp; + intel_encoder->update_pipe = intel_ddi_update_pipe; intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp; intel_encoder->pre_enable = intel_mst_pre_enable_dp; intel_encoder->enable = intel_mst_enable_dp; From patchwork Fri Jan 17 19:31:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339689 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 76AA2921 for ; Fri, 17 Jan 2020 19:31:45 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 555792072B for ; Fri, 17 Jan 2020 19:31:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="CCBw5Qqk" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 555792072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 64E5C6F8E0; Fri, 17 Jan 2020 19:31:32 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yb1-xb44.google.com (mail-yb1-xb44.google.com [IPv6:2607:f8b0:4864:20::b44]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0C6E76F8EC for ; Fri, 17 Jan 2020 19:31:21 +0000 (UTC) Received: by mail-yb1-xb44.google.com with SMTP id x18so6383783ybk.6 for ; Fri, 17 Jan 2020 11:31:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xsH0fgLJFLymo170l1JlsicYN/gmCJ1EFNaQ/xUOkB4=; b=CCBw5Qqkf7eN67XvYd0ziojluKpLyD58ObvJ0pQZ+u/cbvbyOEmT6+qMN1fB/31T7E C05YP+KWg4ZDjun9xN+An9yiouAvp7dyKDYy6dliR77yHMxE+UZAGoX5Ay3BH8RxyNJp 71bWyy1plw8RlberwJa6vwW7xrflmbXjtMAY+5QBMTPlS38I7wSaQ47Yzlu4doDRrJvI Lz0nLKcReWHmWn9imD+5YEVyn7Df1fflCQt6hOgF1CFPmgthbP15Hp6l9YqTmjTCcqMA rzZhZyP9+tTw1/aeaRiZX6bGns3s3kML7K+7zwDVtmVZnMdJN0JgTja/pVKnEPd4OB3c etZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xsH0fgLJFLymo170l1JlsicYN/gmCJ1EFNaQ/xUOkB4=; b=PP+U1ZJroG8Df3AcIdDndDt9BE4ktnUa+M/RnA9WHjX57825vkWgxtQALJiuDex2AL wUS+ejdGYVzGN0RbWTc9ljnq3Uh8w53Qdt3tzGlQhUogik42EQi8NrI76rwKwUr66mEt t6ndrP4fxDoU/LqYMJuVnKLAc6g98iXerQAjEeqXRLtAUL24cix8/V2YG5/MidI9/Wul 8AuJwMSBwu0UJdkUT3HYD4OwrG5XXRO6ZNdPVDkwsAQ4vKEftd3QY4DhmFjHq/qBZB6D ap8C0MF+W6GYE6lfGl25OBYGnE+9Rdh+pUfEEOQuTpr4BeIcicXuB2b2mla6sho3KnEJ nPkw== X-Gm-Message-State: APjAAAX1O4fj4XZTxSRm7xbFxzLVnIi1DVb8FDplGUvqgUvhXTAOwPIA LKgIGQGovOhlB+3qYM/PQ+lB5z6Hg3Qumg== X-Google-Smtp-Source: APXvYqwnIlYMMlhuXac3FqmV65OgcxNJFoPbF24ygVwEebyxV2l5yzejMbGo4acTKeGwnHzc/89fVw== X-Received: by 2002:a25:ccc7:: with SMTP id l190mr7569745ybf.94.1579289479083; Fri, 17 Jan 2020 11:31:19 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id e76sm11849037ywe.25.2020.01.17.11.31.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:18 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 11/12] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst Date: Fri, 17 Jan 2020 14:31:02 -0500 Message-Id: <20200117193103.156821-12-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul These functions are all the same for dp and dp_mst, so move them into a dedicated file for both sst and mst to use. Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-12-sean@poorly.run #v2 Changes in v2: -None Changes in v3: -Created intel_dp_hdcp.c for the shared functions to live (Ville) --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 580 +----------------- drivers/gpu/drm/i915/display/intel_dp.h | 3 + drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 604 +++++++++++++++++++ 4 files changed, 612 insertions(+), 576 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_dp_hdcp.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 3c88d7d8c764..d4ce488f58e9 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -218,6 +218,7 @@ i915-y += \ display/intel_ddi.o \ display/intel_dp.o \ display/intel_dp_aux_backlight.o \ + display/intel_dp_hdcp.o \ display/intel_dp_link_training.o \ display/intel_dp_mst.o \ display/intel_dsi.o \ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a91f65ba35a1..6cc83af60604 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5903,576 +5903,6 @@ 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) -{ - u8 aksv[DRM_HDCP_KSV_LEN] = {}; - ssize_t dpcd_ret; - - dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN, - an, DRM_HDCP_AN_LEN); - if (dpcd_ret != DRM_HDCP_AN_LEN) { - DRM_DEBUG_KMS("Failed to write An over DP/AUX (%zd)\n", - dpcd_ret); - return dpcd_ret >= 0 ? -EIO : dpcd_ret; - } - - /* - * Since Aksv is Oh-So-Secret, we can't access it in software. So we - * send an empty buffer of the correct length through the DP helpers. On - * the other side, in the transfer hook, we'll generate a flag based on - * the destination address which will tickle the hardware to output the - * Aksv on our behalf after the header is sent. - */ - dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV, - aksv, DRM_HDCP_KSV_LEN); - if (dpcd_ret != DRM_HDCP_KSV_LEN) { - DRM_DEBUG_KMS("Failed to write Aksv over DP/AUX (%zd)\n", - dpcd_ret); - return dpcd_ret >= 0 ? -EIO : dpcd_ret; - } - return 0; -} - -static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, - u8 *bksv) -{ - ssize_t ret; - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv, - DRM_HDCP_KSV_LEN); - if (ret != DRM_HDCP_KSV_LEN) { - DRM_DEBUG_KMS("Read Bksv from DP/AUX failed (%zd)\n", ret); - return ret >= 0 ? -EIO : ret; - } - return 0; -} - -static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port, - u8 *bstatus) -{ - ssize_t ret; - /* - * For some reason the HDMI and DP HDCP specs call this register - * definition by different names. In the HDMI spec, it's called BSTATUS, - * but in DP it's called BINFO. - */ - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO, - bstatus, DRM_HDCP_BSTATUS_LEN); - if (ret != DRM_HDCP_BSTATUS_LEN) { - DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); - return ret >= 0 ? -EIO : ret; - } - return 0; -} - -static -int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port, - u8 *bcaps) -{ - ssize_t ret; - - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS, - bcaps, 1); - if (ret != 1) { - DRM_DEBUG_KMS("Read bcaps from DP/AUX failed (%zd)\n", ret); - return ret >= 0 ? -EIO : ret; - } - - return 0; -} - -static -int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port, - bool *repeater_present) -{ - ssize_t ret; - u8 bcaps; - - ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps); - if (ret) - return ret; - - *repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT; - return 0; -} - -static -int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port, - u8 *ri_prime) -{ - ssize_t ret; - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME, - ri_prime, DRM_HDCP_RI_LEN); - if (ret != DRM_HDCP_RI_LEN) { - DRM_DEBUG_KMS("Read Ri' from DP/AUX failed (%zd)\n", ret); - return ret >= 0 ? -EIO : ret; - } - return 0; -} - -static -int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port, - bool *ksv_ready) -{ - ssize_t ret; - u8 bstatus; - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS, - &bstatus, 1); - if (ret != 1) { - DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); - return ret >= 0 ? -EIO : ret; - } - *ksv_ready = bstatus & DP_BSTATUS_READY; - return 0; -} - -static -int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port, - int num_downstream, u8 *ksv_fifo) -{ - ssize_t ret; - int i; - - /* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */ - for (i = 0; i < num_downstream; i += 3) { - size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN; - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, - DP_AUX_HDCP_KSV_FIFO, - ksv_fifo + i * DRM_HDCP_KSV_LEN, - len); - if (ret != len) { - DRM_DEBUG_KMS("Read ksv[%d] from DP/AUX failed (%zd)\n", - i, ret); - return ret >= 0 ? -EIO : ret; - } - } - return 0; -} - -static -int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port, - int i, u32 *part) -{ - ssize_t ret; - - if (i >= DRM_HDCP_V_PRIME_NUM_PARTS) - return -EINVAL; - - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, - DP_AUX_HDCP_V_PRIME(i), part, - DRM_HDCP_V_PRIME_PART_LEN); - if (ret != DRM_HDCP_V_PRIME_PART_LEN) { - DRM_DEBUG_KMS("Read v'[%d] from DP/AUX failed (%zd)\n", i, ret); - return ret >= 0 ? -EIO : ret; - } - return 0; -} - -static -int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, - enum transcoder cpu_transcoder, - bool enable) -{ - /* Not used for single stream DisplayPort setups */ - return 0; -} - -static -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port) -{ - ssize_t ret; - u8 bstatus; - - ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS, - &bstatus, 1); - if (ret != 1) { - DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); - return false; - } - - return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ)); -} - -static -int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port, - bool *hdcp_capable) -{ - ssize_t ret; - u8 bcaps; - - ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps); - if (ret) - return ret; - - *hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE; - return 0; -} - -struct hdcp2_dp_errata_stream_type { - u8 msg_id; - u8 stream_type; -} __packed; - -struct hdcp2_dp_msg_data { - u8 msg_id; - u32 offset; - bool msg_detectable; - u32 timeout; - u32 timeout2; /* Added for non_paired situation */ -}; - -static const struct hdcp2_dp_msg_data hdcp2_dp_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, - const 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 { - /* - * 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; - } - - if (ret) - DRM_DEBUG_KMS("msg_id %d, ret %d, timeout(mSec): %d\n", - hdcp2_msg_data->msg_id, ret, timeout); - - return ret; -} - -static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++) - if (hdcp2_dp_msg_data[i].msg_id == msg_id) - return &hdcp2_dp_msg_data[i]; - - return NULL; -} - -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; - const 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++; - - 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; - - 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; - const 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, - .read_bstatus = intel_dp_hdcp_read_bstatus, - .repeater_present = intel_dp_hdcp_repeater_present, - .read_ri_prime = intel_dp_hdcp_read_ri_prime, - .read_ksv_ready = intel_dp_hdcp_read_ksv_ready, - .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo, - .read_v_prime_part = intel_dp_hdcp_read_v_prime_part, - .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) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -7453,7 +6883,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_encoder->port; enum phy phy = intel_port_to_phy(dev_priv, port); - int type; + int type, ret; /* Initialize the work for modeset in case of link train failure */ INIT_WORK(&intel_connector->modeset_retry_work, @@ -7540,11 +6970,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, intel_dp_add_properties(intel_dp, connector); - if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) { - int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim); - if (ret) - DRM_DEBUG_KMS("HDCP init failed, skipping.\n"); - } + ret = intel_dp_init_hdcp(intel_dig_port, intel_connector); + if (ret) + DRM_DEBUG_KMS("HDCP init failed, skipping.\n"); /* 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 diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 0a028b58a8be..cb96a40da032 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -129,4 +129,7 @@ void intel_ddi_update_pipe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); +int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector); + #endif /* __INTEL_DP_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c new file mode 100644 index 000000000000..0b6d90980e90 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -0,0 +1,604 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (C) 2020 Google, Inc. + * + * Authors: + * Sean Paul + */ + +#include +#include +#include + +#include "intel_display_types.h" +#include "intel_dp.h" +#include "intel_hdcp.h" + +struct hdcp2_dp_errata_stream_type { + u8 msg_id; + u8 stream_type; +} __packed; + +struct hdcp2_dp_msg_data { + u8 msg_id; + u32 offset; + bool msg_detectable; + u32 timeout; + u32 timeout2; /* Added for non_paired situation */ +}; + +static const struct hdcp2_dp_msg_data hdcp2_dp_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 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 const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++) + if (hdcp2_dp_msg_data[i].msg_id == msg_id) + return &hdcp2_dp_msg_data[i]; + + return NULL; +} + +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; + const 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++; + + 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; + + 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 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, + const 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 { + /* + * 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; + } + + if (ret) + DRM_DEBUG_KMS("msg_id %d, ret %d, timeout(mSec): %d\n", + hdcp2_msg_data->msg_id, ret, timeout); + + return ret; +} + +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; + const 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 +int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port, + u8 *an) +{ + u8 aksv[DRM_HDCP_KSV_LEN] = {}; + ssize_t dpcd_ret; + + dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN, + an, DRM_HDCP_AN_LEN); + if (dpcd_ret != DRM_HDCP_AN_LEN) { + DRM_DEBUG_KMS("Failed to write An over DP/AUX (%zd)\n", + dpcd_ret); + return dpcd_ret >= 0 ? -EIO : dpcd_ret; + } + + /* + * Since Aksv is Oh-So-Secret, we can't access it in software. So we + * send an empty buffer of the correct length through the DP helpers. On + * the other side, in the transfer hook, we'll generate a flag based on + * the destination address which will tickle the hardware to output the + * Aksv on our behalf after the header is sent. + */ + dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV, + aksv, DRM_HDCP_KSV_LEN); + if (dpcd_ret != DRM_HDCP_KSV_LEN) { + DRM_DEBUG_KMS("Failed to write Aksv over DP/AUX (%zd)\n", + dpcd_ret); + return dpcd_ret >= 0 ? -EIO : dpcd_ret; + } + return 0; +} + +static +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, u8 *bksv) +{ + ssize_t ret; + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv, + DRM_HDCP_KSV_LEN); + if (ret != DRM_HDCP_KSV_LEN) { + DRM_DEBUG_KMS("Read Bksv from DP/AUX failed (%zd)\n", ret); + return ret >= 0 ? -EIO : ret; + } + return 0; +} + +static +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port, + u8 *bstatus) +{ + ssize_t ret; + /* + * For some reason the HDMI and DP HDCP specs call this register + * definition by different names. In the HDMI spec, it's called BSTATUS, + * but in DP it's called BINFO. + */ + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO, + bstatus, DRM_HDCP_BSTATUS_LEN); + if (ret != DRM_HDCP_BSTATUS_LEN) { + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); + return ret >= 0 ? -EIO : ret; + } + return 0; +} + +static +int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port, + u8 *bcaps) +{ + ssize_t ret; + + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS, + bcaps, 1); + if (ret != 1) { + DRM_DEBUG_KMS("Read bcaps from DP/AUX failed (%zd)\n", ret); + return ret >= 0 ? -EIO : ret; + } + + return 0; +} + +static +int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port, + bool *repeater_present) +{ + ssize_t ret; + u8 bcaps; + + ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps); + if (ret) + return ret; + + *repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT; + return 0; +} + +static +int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port, + u8 *ri_prime) +{ + ssize_t ret; + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME, + ri_prime, DRM_HDCP_RI_LEN); + if (ret != DRM_HDCP_RI_LEN) { + DRM_DEBUG_KMS("Read Ri' from DP/AUX failed (%zd)\n", ret); + return ret >= 0 ? -EIO : ret; + } + return 0; +} + +static +int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port, + bool *ksv_ready) +{ + ssize_t ret; + u8 bstatus; + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS, + &bstatus, 1); + if (ret != 1) { + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); + return ret >= 0 ? -EIO : ret; + } + *ksv_ready = bstatus & DP_BSTATUS_READY; + return 0; +} + +static +int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port, + int num_downstream, u8 *ksv_fifo) +{ + ssize_t ret; + int i; + + /* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */ + for (i = 0; i < num_downstream; i += 3) { + size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN; + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, + DP_AUX_HDCP_KSV_FIFO, + ksv_fifo + i * DRM_HDCP_KSV_LEN, + len); + if (ret != len) { + DRM_DEBUG_KMS("Read ksv[%d] from DP/AUX failed (%zd)\n", + i, ret); + return ret >= 0 ? -EIO : ret; + } + } + return 0; +} + +static +int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port, + int i, u32 *part) +{ + ssize_t ret; + + if (i >= DRM_HDCP_V_PRIME_NUM_PARTS) + return -EINVAL; + + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, + DP_AUX_HDCP_V_PRIME(i), part, + DRM_HDCP_V_PRIME_PART_LEN); + if (ret != DRM_HDCP_V_PRIME_PART_LEN) { + DRM_DEBUG_KMS("Read v'[%d] from DP/AUX failed (%zd)\n", i, ret); + return ret >= 0 ? -EIO : ret; + } + return 0; +} + +static +int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, + enum transcoder cpu_transcoder, + bool enable) +{ + /* Not used for single stream DisplayPort setups */ + return 0; +} + +static +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port) +{ + ssize_t ret; + u8 bstatus; + + ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS, + &bstatus, 1); + if (ret != 1) { + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); + return false; + } + + return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ)); +} + +static +int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port, + bool *hdcp_capable) +{ + ssize_t ret; + u8 bcaps; + + ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps); + if (ret) + return ret; + + *hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE; + 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, + .read_bstatus = intel_dp_hdcp_read_bstatus, + .repeater_present = intel_dp_hdcp_repeater_present, + .read_ri_prime = intel_dp_hdcp_read_ri_prime, + .read_ksv_ready = intel_dp_hdcp_read_ksv_ready, + .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo, + .read_v_prime_part = intel_dp_hdcp_read_v_prime_part, + .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, +}; + +int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector) +{ + struct drm_device *dev = intel_connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_encoder *intel_encoder = &intel_dig_port->base; + enum port port = intel_encoder->port; + struct intel_dp *intel_dp = &intel_dig_port->dp; + + if (!is_hdcp_supported(dev_priv, port)) + return 0; + + if (!intel_dp_is_edp(intel_dp)) + return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim); + + return 0; +} From patchwork Fri Jan 17 19:31:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11339691 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B533E921 for ; Fri, 17 Jan 2020 19:31:46 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 93F142072B for ; Fri, 17 Jan 2020 19:31:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=poorly.run header.i=@poorly.run header.b="c4+lLtnK" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 93F142072B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6B5C56F8EC; Fri, 17 Jan 2020 19:31:32 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw1-xc43.google.com (mail-yw1-xc43.google.com [IPv6:2607:f8b0:4864:20::c43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 44EFE6F8EE for ; Fri, 17 Jan 2020 19:31:21 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id 192so14857146ywy.0 for ; Fri, 17 Jan 2020 11:31:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poorly.run; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EC0eVUirKQcmSVVw6pDzcfXPPPenb62+TYMFcLStUpE=; b=c4+lLtnKCyNtRyMBZH8U5GYJgmpwHO7ic5fYtmDvVwyq/nlVnQpv0/Lgv+WhSFFW3f hgKqJBJm/n17frXcxVVeyVlPKcVYdcdJ7qyBiXqfzASjAZX3Yq1HyBI7lDlUnZ80ugbn efMC4X9GCH3qbJ6OB4i6Ws4S/lEtkKEdjJW1xbf/rydk+/dHebEU1Oq2YCIeMphhU2Fy nbdZU20T2YdLkwoIc6mnbf9ctQ6Nys344IkjrHwDDI1LrM3UR4GXrAx4/sjIKrzPS1AP BQFvTKBOSTHyUi8bv8WgXb0oRr11K9W880AmypnRGBXQ45jMmr5HWr+RlEbYISTiv84x xc3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EC0eVUirKQcmSVVw6pDzcfXPPPenb62+TYMFcLStUpE=; b=jP17bLIYwjuDd7LY2h0DyTWYZmv2vT6JM2+sn7o2Alh8epDdRBLPqY2Se2Yeda542F KTO0dmZcYYSTPizCfNTiQxlSMvViyhf8yXoSNwrCqExkGC7KQBCLa+dihFrQ2HFVQHhI S18gYDxo30qz366EeQphHnmd+34EL3fRVidoIpJWCOwWCBTExXzVr9svonRm3Db0pCOg gfuk+Gte4P1yHjhOaQOLbpxMGWrA2T1ZPs7QGOsfK1LVSNxnaLqO/TCzBtstR3uOCzou Tw+4gYY49MsnU9Dalyy7sKLSURXpD5Ar/uT08FWr+y2rTpQTkQFT9xnDR/pgzZTvzMgv HtwQ== X-Gm-Message-State: APjAAAUGA6sUKsqbESTZQ54NLG2slZsmLDa1r41JTYxGVbl/5PAckl1D MHIrHS84DJ1qGBRyDhmi9mjANDtJ1pm6Ww== X-Google-Smtp-Source: APXvYqysN6pmIgToA9k6RmMx/UJkh6PsWR7/yF2ET0GbzV/ZBabBe9iLLfSG1HmwnpOq6Goirmo8uA== X-Received: by 2002:a81:9890:: with SMTP id p138mr32096229ywg.224.1579289480281; Fri, 17 Jan 2020 11:31:20 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id a23sm11971803ywa.32.2020.01.17.11.31.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 11:31:19 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v3 12/12] drm/i915: Add HDCP 1.4 support for MST connectors Date: Fri, 17 Jan 2020 14:31:03 -0500 Message-Id: <20200117193103.156821-13-sean@poorly.run> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog In-Reply-To: <20200117193103.156821-1-sean@poorly.run> References: <20200117193103.156821-1-sean@poorly.run> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, rodrigo.vivi@intel.com, Sean Paul Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul Now that all the groundwork has been laid, we can turn on HDCP 1.4 over MST. Everything except for toggling the HDCP signalling and HDCP 2.2 support is the same as the DP case, so we'll re-use those callbacks Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2 Changes in v2: - Toggle HDCP from encoder disable/enable - Don't disable HDCP on MST connector destroy, leave that for encoder disable, just ensure the check_work routine isn't running any longer Changes in v3: - Place the shim in the new intel_dp_hdcp.c file (Ville) --- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 78 +++++++++++++++++++- drivers/gpu/drm/i915/display/intel_dp_mst.c | 14 ++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index 0b6d90980e90..a93ad675e7bb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -11,6 +11,7 @@ #include #include "intel_display_types.h" +#include "intel_ddi.h" #include "intel_dp.h" #include "intel_hdcp.h" @@ -585,6 +586,78 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = { .protocol = HDCP_PROTOCOL_DP, }; +static int +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, + enum transcoder cpu_transcoder, + bool enable) +{ + int ret; + + ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, + cpu_transcoder, enable); + if (ret) + DRM_DEBUG_KMS("%s HDCP signalling failed (%d)\n", + enable ? "Enable" : "Disable", ret); + return ret; +} + +static +int intel_dp_mst_hdcp2_write_msg(struct intel_digital_port *intel_dig_port, + void *buf, size_t size) +{ + return -EOPNOTSUPP; +} + +static +int intel_dp_mst_hdcp2_read_msg(struct intel_digital_port *intel_dig_port, + u8 msg_id, void *buf, size_t size) +{ + return -EOPNOTSUPP; +} + +static int +intel_dp_mst_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port, + bool is_repeater, u8 content_type) +{ + return -EOPNOTSUPP; +} + +static +int intel_dp_mst_hdcp2_check_link(struct intel_digital_port *intel_dig_port) +{ + return -EOPNOTSUPP; +} + +static +int intel_dp_mst_hdcp2_capable(struct intel_digital_port *intel_dig_port, + bool *capable) +{ + *capable = false; + return 0; +} + +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = { + .write_an_aksv = intel_dp_hdcp_write_an_aksv, + .read_bksv = intel_dp_hdcp_read_bksv, + .read_bstatus = intel_dp_hdcp_read_bstatus, + .repeater_present = intel_dp_hdcp_repeater_present, + .read_ri_prime = intel_dp_hdcp_read_ri_prime, + .read_ksv_ready = intel_dp_hdcp_read_ksv_ready, + .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo, + .read_v_prime_part = intel_dp_hdcp_read_v_prime_part, + .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling, + .check_link = intel_dp_hdcp_check_link, + .hdcp_capable = intel_dp_hdcp_capable, + + .write_2_2_msg = intel_dp_mst_hdcp2_write_msg, + .read_2_2_msg = intel_dp_mst_hdcp2_read_msg, + .config_stream_type = intel_dp_mst_hdcp2_config_stream_type, + .check_2_2_link = intel_dp_mst_hdcp2_check_link, + .hdcp_2_2_capable = intel_dp_mst_hdcp2_capable, + + .protocol = HDCP_PROTOCOL_DP, +}; + int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port, struct intel_connector *intel_connector) { @@ -597,7 +670,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port, if (!is_hdcp_supported(dev_priv, port)) return 0; - if (!intel_dp_is_edp(intel_dp)) + if (!intel_encoder_is_mst(intel_encoder)) + return intel_hdcp_init(intel_connector, + &intel_dp_mst_hdcp_shim); + else if (!intel_dp_is_edp(intel_dp)) return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim); return 0; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 975d97989d3b..00c2032c71ed 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -36,6 +36,7 @@ #include "intel_dp.h" #include "intel_dp_mst.h" #include "intel_dpio_phy.h" +#include "intel_hdcp.h" static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, @@ -326,6 +327,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder, DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); + intel_hdcp_disable(intel_mst->connector); + drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port); ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr); @@ -497,6 +500,13 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder, drm_dp_update_payload_part2(&intel_dp->mst_mgr); if (pipe_config->has_audio) intel_audio_codec_enable(encoder, pipe_config, conn_state); + + /* 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), + pipe_config->cpu_transcoder, + (u8)conn_state->hdcp_content_type); } static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder, @@ -690,6 +700,10 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); + ret = intel_dp_init_hdcp(intel_dig_port, intel_connector); + if (ret) + DRM_DEBUG_KMS("HDCP init failed, skipping.\n"); + /* * Reuse the prop from the SST connector because we're * not allowed to create new props after device registration.