From patchwork Tue Feb 18 22:02:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389819 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 CD73017EF for ; Tue, 18 Feb 2020 22:03:42 +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 ABEFF207FD for ; Tue, 18 Feb 2020 22:03:42 +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="epgew5uQ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ABEFF207FD 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 B7C086EA9B; Tue, 18 Feb 2020 22:03:31 +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 94F8E6EA96 for ; Tue, 18 Feb 2020 22:03:30 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id t141so10129288ywc.11 for ; Tue, 18 Feb 2020 14:03:30 -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=cmEv6KYeIZ/itTi4Tb2yD0Ax+KLuuOVxjE5ac+Oou1Q=; b=epgew5uQNxLRoaIaCHs5pjx5HAoV2sUOXIVFAmZHlbT6lWtkSao4PFI7tch/wT6lKY nDCVDLFmL4b1oCjWmAfqrhY9KiAIafJPsITlDHhH5q5SeuRyiIjFij8sk6B4osXsrH8E UEOHj86nlOnNMS6Wg48FbPSO8iIxHSQzwz4p7XuyDhyJRvuduuvAKgYdHA3Cgsm04Q3s 1JUuS8P6By/j+Fo5is5rVw4AwtB7hXg72WZ5CwgeLLJ/lpOjN7oUrfFBh5iG2XUHFRnx x1BqCQz7Jw3fRBVa6U73cfUoGNpWy8WDxh/Kn+VkLei8JG5FBqMMIY2EnN1S3S3PetM+ bDcg== 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=cmEv6KYeIZ/itTi4Tb2yD0Ax+KLuuOVxjE5ac+Oou1Q=; b=RLazmgiDnJ/4BT9kqua+zDDb7X6DwQ46KFrKYMHP1KVBskcBIpO/7KoKaHeNfvC9Hk 1BXS4TPJFc6YtFA3rhCkPU3YiFB96uj5fpG2qerPShT+6Pnl1XJxGHnzAH45gFq8TXSh F3JBloWBm+EbnIG/NdXY7Ub7UWu5JApyjP+yrkhHQS59g4KBrWdr3GlIy+A48J81uC0g wMD4gd5L6iCtHof9zSO1x/JxrHAkRCNcHfKW7WRiiI+sU1mWOc5/DFlfWt4Qlrorocmm Ida/sCD+1Hm5VBYxKViI+AuJVwLfGUfpBLhj/pVcWWmY5g1GudTQSWjnqAd7LSpbv06T I+Gw== X-Gm-Message-State: APjAAAXqtIvkN3loAZiHs7fKFDPChKYLtHuFjTbAMdJB2xvgVHanJsA6 CvvPrc/XvM1h/jGA5L511+JQjB1kH6Q= X-Google-Smtp-Source: APXvYqwV1SVHQrglY5ZjNw0BIqPSTUVQoEHyY+37gVGqJ8yZPu7K2f0g7J89NYU7Zqf/RqVm/8q56A== X-Received: by 2002:a81:2550:: with SMTP id l77mr18000249ywl.347.1582063409523; Tue, 18 Feb 2020 14:03:29 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id a124sm8230ywc.104.2020.02.18.14.03.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:28 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 01/14] drm/i915: Fix sha_text population code Date: Tue, 18 Feb 2020 17:02:29 -0500 Message-Id: <20200218220242.107265-2-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com, 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-2-sean@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -Rebased on intel_de_write changes --- drivers/gpu/drm/i915/display/intel_hdcp.c | 26 +++++++++++++++++------ include/drm/drm_hdcp.h | 3 +++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 30e0a3aa9d574..de996f4f56997 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -337,8 +337,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) @@ -436,7 +438,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, /* Write 32 bits of text */ intel_de_write(dev_priv, 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; @@ -451,17 +453,29 @@ 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. + */ + intel_de_write(dev_priv, 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) */ intel_de_write(dev_priv, 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 */ intel_de_write(dev_priv, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8); ret = intel_write_sha_text(dev_priv, bstatus[1]); diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index 06a11202a0976..20498c8222046 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 Tue Feb 18 22:02:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389823 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 3AB7A1395 for ; Tue, 18 Feb 2020 22:03: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 18C98207FD for ; Tue, 18 Feb 2020 22:03: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="QdGz5jmS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 18C98207FD 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 0F6B66EA9D; Tue, 18 Feb 2020 22:03:34 +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 DBEA06EA9E for ; Tue, 18 Feb 2020 22:03:31 +0000 (UTC) Received: by mail-yb1-xb42.google.com with SMTP id l75so11328301ybf.6 for ; Tue, 18 Feb 2020 14:03:31 -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=IfpImic0Um1/+E93YU2yBYy/dmBtMwQl96DrDYQiErg=; b=QdGz5jmSSv0P5AQZi05BnWRF9EhmKDcGfOjeMdqInmj48MGazwSQSiPTk483TmEJA+ kQt3znS0mw0h9eQLnzCFXeyEolF7H3V4MLdKpAodmkkd0bg02+zuiNXca+8E5iYdxzV9 JsQZjZSvo7Mlbl6NACMRXk2mRtuDSm0IBG7OOJH4z4dGBg+hiTyuE041gqXgkC1Z81uL KSTQVQhw1dEHqn3hon3aObj1Vl3lMumYA6W9PjSGoHKTGwxsosrq+10FstTpGbpIySci DgqBthKAwo9n8lgd2/yrwkfeoQ2H7EK23tKsoK8a3+KdK2Fdltefq7D9FHfqmBHiFFq7 eoWw== 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=IfpImic0Um1/+E93YU2yBYy/dmBtMwQl96DrDYQiErg=; b=TJ/3BB/Nz+6nsiGOV1JWp1RVMpZUCNxzkGm9uqpvZbM4XjZhUtFn+QM6i115ewx7lQ Qpri00JHcTyluezcUJ0O5lT4yWBKQoRb4BIs09vPUshnPY1KHmQx2wSoe4nrFgkyrEvj bmCPwCZD85zZWpzsZoBEyUsSZ4Laba6ISGo1ML73dBdNtMQ+9oRab4xISVt2Bij0X8DD CcIGeIJ/S0BI1yjUJDxG+z++5wPfxGYQ8TskchXG0X2goyZIJovRPYuyrVoRoE+AQeSr OxVDFGG+KTCEs3ey5jn2iflPHmcFMXnn42TeoR7m3aSmhad0w5uHK3TUwzDq0jWB2kgw RRew== X-Gm-Message-State: APjAAAUVHbFuOMoZ/LGcfa76adf+zm2K3iqXixvS0bLedhQ/dMQ/QamC 3vweQo631MqCLkfqzRlWB4ETST0w32U= X-Google-Smtp-Source: APXvYqx2fAVGNlQKTOGmly5wlHfYcLk+3IYqdnsojURjw6fCbaf9yaVGbL3sNWz0CgG73hWXTNC//g== X-Received: by 2002:a05:6902:52e:: with SMTP id y14mr21161614ybs.133.1582063410899; Tue, 18 Feb 2020 14:03:30 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id z2sm32831ywb.13.2020.02.18.14.03.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:30 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 02/14] drm/i915: Clear the repeater bit on HDCP disable Date: Tue, 18 Feb 2020 17:02:30 -0500 Message-Id: <20200218220242.107265-3-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com, 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-3-sean@poorly.run #v3 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 Changes in v4: -s/I915_(READ|WRITE)/intel_de_(read|write)/ --- drivers/gpu/drm/i915/display/intel_hdcp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index de996f4f56997..f31a2f5d51a17 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -790,6 +790,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector) struct intel_hdcp *hdcp = &connector->hdcp; enum port port = intel_dig_port->base.port; enum transcoder cpu_transcoder = hdcp->cpu_transcoder; + u32 repeater_ctl; int ret; drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n", @@ -805,6 +806,11 @@ static int _intel_hdcp_disable(struct intel_connector *connector) return -ETIMEDOUT; } + repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder, + port); + intel_de_write(dev_priv, HDCP_REP_CTL, + intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl); + ret = hdcp->shim->toggle_signalling(intel_dig_port, false); if (ret) { drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n"); From patchwork Tue Feb 18 22:02:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389825 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 32D1717EF for ; Tue, 18 Feb 2020 22:03:49 +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 1170F207FD for ; Tue, 18 Feb 2020 22:03:49 +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="AYb70cRS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1170F207FD 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 CFFBC6EA9E; Tue, 18 Feb 2020 22:03:34 +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 590766E417 for ; Tue, 18 Feb 2020 22:03:33 +0000 (UTC) Received: by mail-yb1-xb44.google.com with SMTP id u26so7749960ybd.3 for ; Tue, 18 Feb 2020 14:03:33 -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=4qNH+oSfqFDiH2zka2uZ4hJzeTVR/EM2vBf7regMnHc=; b=AYb70cRSStT7hJ5LEFO8cXFXuepTztaeDvLCDtdB1J1uZgtv4i/w5wmnHk3fH+QFJt Vqax+mDv9dTqokLITrmqqCogu27IYV69h1bySWRhS8eqY6gRsZrm4P1tHCPqiF3fiylL AucQoMP2Nc22vyrsYPSex7q373EZDNXd2or1xBnI+zZiFoMVCb2irVMgDbvaWozHNyUJ cMEvUDuXKPQI6dW8MWK+NVVhb8pSfvfXqp6J4SVM0xLZQblKBmuLG6zgVlkkqv3DeI5L AoL1UgoRXAMhudEgbfMf0lkBtt9QXkSxD7HTePlMClPSdbHrorG74SAuyVK9/mtaCY8J nk+A== 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=4qNH+oSfqFDiH2zka2uZ4hJzeTVR/EM2vBf7regMnHc=; b=ZBWSsqrRU2e2vwop5Ao8+Vf3Rgs3AndGh04n0jXN4lLTph6Wyc19/BOAbgvxrRpPOM daBu1gpnorujr2ZN6RII1Q6tP3a2DDpj8tqpaJIn+1zCaAd5QsWVYmRuVbeluBAncofx odtPLnh7ApgrAkqfttnOxkVZb9T5sQGUr8aOycnqnHpNZ4X2z0buKzg7J0RBRIPgwcMZ IKW3ibokjrwNUypg47b7juvmOqSs/ItLilrodVCpAnay3JuFspfYftFjqgSaGYlIXNNx RV6UEzMKa2c+1Bt2W0V/h4OoxpztcBAB6EJqCyDnlZ8Ax+ngGv2VZSGWonBRLdUJnvYf ahoA== X-Gm-Message-State: APjAAAWXPd9hd+gn+DOQBNHffv60dh98IMP5yr4m5oholr/iWNXSlsPm ZSLp5Frc0PSynRJNyCAA5o+aQbxdhak= X-Google-Smtp-Source: APXvYqwQWZnE3drxBc2jf/95A7ugFTExO8dzBboEUUhM9PPH0bsgsFMSypa/pmU0+MRcN2VtIgMa5w== X-Received: by 2002:a25:5c07:: with SMTP id q7mr22814879ybb.376.1582063412369; Tue, 18 Feb 2020 14:03:32 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id v133sm11992ywb.86.2020.02.18.14.03.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:31 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 03/14] drm/i915: WARN if HDCP signalling is enabled upon disable Date: Tue, 18 Feb 2020 17:02:31 -0500 Message-Id: <20200218220242.107265-4-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-4-sean@poorly.run #v3 Changes in v2: -Added to the set in lieu of just clearing the bit Changes in v3: -None Changes in v4: -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 a1fd8fd67c855..fc84cd7c724fb 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2013,6 +2013,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state val = intel_de_read(dev_priv, 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 Tue Feb 18 22:02:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389835 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 F32B417EF for ; Tue, 18 Feb 2020 22:03:56 +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 D1E9D207FD for ; Tue, 18 Feb 2020 22:03:56 +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="ULFrCBCt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D1E9D207FD 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 680BC6EAA7; Tue, 18 Feb 2020 22:03:38 +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 C411E6EAA0 for ; Tue, 18 Feb 2020 22:03:34 +0000 (UTC) Received: by mail-yw1-xc41.google.com with SMTP id b186so10168413ywc.1 for ; Tue, 18 Feb 2020 14:03:34 -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=9MJ2h70I41VNPuqusx++lycc2Hn4DBe7ATQubiICxr8=; b=ULFrCBCtzBrPZfrCgzWhdjzZHEXJN6H7GA8cqVycVY92zemxWZH71/nLV5izUT5tzO ziAn3t7YQayTJaNt2WC4RNpUCX/bUjRxKT8Rie6bEsnbVCEs+1GGX7g935ZLviqFzyao U6s1K1VHiISPjF8BrOgR8KM8Ro9aAQGVUkjB5OUo9PhxQgbW8pWR3lsOmvOJ19KADsCF olKE34IFXcpLi1RxWesZl0GjXJfJNufRm808AgbdTPiObgJ6XKuT8s0a4jmxDPrm/kuX CtXVAr3xO/Tx0CiYE1uEZ5AJ6GwjfPt45BVck54Yl2r01e7T9PKVACU0KIyh5BkQ4hzV 10NA== 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=9MJ2h70I41VNPuqusx++lycc2Hn4DBe7ATQubiICxr8=; b=WBUq/xGrcgrMBgITOfUuM9tFAZvWJ+pdh/RpLMUjAhnI8V9iBBrT+oAWTnFLXOEMl4 05+lmow1C44vyLJGQp7Y1RD2yUzr+pWPTUYh8X7GO1oSiEBA6vbQ7OvnIMQAoAgSXilq QjehP7uec1ojUWFDfTzfho0H2Sfvoep9BiZEbuTGWBHfeu1nVDrRQY4NHOM2Q5hiqNs6 pvz5tAXID/pgrVu/Su41oAuojMVfuzTA1M/LgzclD0hktvrVK+9KS2EKQoHvzxXvdnXd nvnasMw4lIoCYi5sJGHObID75CFHKdWU7d0jDbSqkQ9bV0i3sBmLDc7Q/HQALLYQGWUo Cnzg== X-Gm-Message-State: APjAAAXRmA9nCRMCednr16YCkDcKxuhY2oxI7e5ZS2tlSj9BreEDJxHX F182RLX7j8VFX1qWvc6ad5IjmMVdL9U= X-Google-Smtp-Source: APXvYqyLvvxhSnIZ1r9nlZ+/JeW/y97JevTE8oTIlAEMuLlFlQw9pJlp3I+ODPl1LZlGRBMDALO2Gw== X-Received: by 2002:a81:38d6:: with SMTP id f205mr17237128ywa.387.1582063413682; Tue, 18 Feb 2020 14:03:33 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id y17sm29597ywd.23.2020.02.18.14.03.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:33 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 04/14] drm/i915: Intercept Aksv writes in the aux hooks Date: Tue, 18 Feb 2020 17:02:32 -0500 Message-Id: <20200218220242.107265-5-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-5-sean@poorly.run #v3 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 Changes in v4: -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 9541ab11624d8..1c947218bc300 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1523,12 +1523,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); @@ -1549,7 +1564,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; @@ -1572,7 +1587,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; /* @@ -5941,17 +5956,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) { @@ -5961,29 +5968,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 Tue Feb 18 22:02:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389833 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 354C917EF for ; Tue, 18 Feb 2020 22:03:55 +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 13B91207FD for ; Tue, 18 Feb 2020 22:03:55 +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="CuXAiJY2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 13B91207FD 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 2E7F66EAA5; Tue, 18 Feb 2020 22:03:37 +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 017E16EAA3 for ; Tue, 18 Feb 2020 22:03:35 +0000 (UTC) Received: by mail-yb1-xb43.google.com with SMTP id p123so11321430ybp.2 for ; Tue, 18 Feb 2020 14:03:35 -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=M/08RcrjbFUuhliiQlnwMmtmnKxsSPX8tGNDi2kpTHY=; b=CuXAiJY2z4tLWctm+uW1VbmD2ZLoYvfDnZKt1kfGl4hC9csXVJpcAqaB4x41LyIqjG tR2ACSCw3vrFcIAEUI3w6viXUtkqExGabcZu7tnAVYeHWLMAtkZh2rRRgcbI+BxxqerM X7d8i7s6dXPKxhVDvVSTdGMViP4GGexrpFN/wIEfOk6pYSqL/Os8dce0n8k0gBh1D+/O OcuCIHwleqbt1Mogvs2NF6+m+a1e00Q+OIhW1bauf+1U4B45PBtyfujFv07UORGdEsyN A9YM2tMFxCLOQm6mVsjoln5bJ/vtyI0+12PeZd7l1nCZPwpROS2u6H/scqRpU8Fl5TgA NfFg== 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=M/08RcrjbFUuhliiQlnwMmtmnKxsSPX8tGNDi2kpTHY=; b=qP2Sag7fYShWqp/KLBEH2vjBAx12lKNXvVUmUxWTeLHwJt/LGcYVRmV/IATMWZzwpY x3v3fwv9hg9npY5dSeNMPErWLNeRI4EI2ND3BkihqmkcbeNNZ1R7iWC+QYRaHA+Z76Jg j1V+rYx6L72pUVJJIHy/wTs9dRtIRUyTdmseTpgrfsDMcR40R2CFoVXXZDnbrMNs/RtY RGJqS2zPJkBxuBu0c4O4YQcWq5OGh7FhR1PdlUkDekb+WPkiOtIX+OMYOMI18a/MTLoL 851T5qttYf5Hmwonq+EZCD95g8AYDYTom7KUtXiWhbvp1IdCaulFcnPGimdXbL9xWvH4 jFvw== X-Gm-Message-State: APjAAAWVX7LnbIPdzlBM2NIbIO8Wei8s2NZtuPHeKHk3AAMxpKM9CDVk ftA5Z2iiL7C7+qtMgbZb+aVtVxiZ6m4= X-Google-Smtp-Source: APXvYqwwgh/P6zxChaZtMqe31b4VORLoK73hxGwNaL1VcgmAg+OIhhMU96vS79QM3OrxwO9hInfQpw== X-Received: by 2002:a25:9002:: with SMTP id s2mr21178435ybl.243.1582063414923; Tue, 18 Feb 2020 14:03:34 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id h203sm8438ywb.98.2020.02.18.14.03.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:34 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 05/14] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling Date: Tue, 18 Feb 2020 17:02:33 -0500 Message-Id: <20200218220242.107265-6-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-6-sean@poorly.run #v3 Changes in v2: -Added to the set Changes in v3: -s/hdcp/hdmi/ in commit msg (Ram) Changes in v4: -Rebased on intel_de_(read|write) change --- drivers/gpu/drm/i915/display/intel_ddi.c | 12 +++--------- 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, 25 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index fc84cd7c724fb..61984218961fa 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2034,12 +2034,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; @@ -2048,18 +2048,12 @@ 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 = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe)); + tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); if (enable) tmp |= TRANS_DDI_HDCP_SIGNALLING; else tmp &= ~TRANS_DDI_HDCP_SIGNALLING; - intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe), tmp); -out: + intel_de_write(dev_priv, 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 167c6579d972e..5b22daf04060f 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 283c622f8ba12..b9e4ba8071d29 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -306,6 +306,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 1c947218bc300..f601cdcd4c647 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6120,6 +6120,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 f31a2f5d51a17..680d88566d992 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -710,7 +710,7 @@ static int intel_hdcp_auth(struct intel_connector *connector) intel_de_write(dev_priv, HDCP_REP_CTL, 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; @@ -811,7 +811,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector) intel_de_write(dev_priv, HDCP_REP_CTL, intel_de_read(dev_priv, 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_err(&dev_priv->drm, "Failed to disable HDCP signalling\n"); return ret; @@ -1584,7 +1585,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector) WARN_ON(intel_de_read(dev_priv, 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_err(&dev_priv->drm, "Failed to enable HDCP signalling. %d\n", @@ -1634,7 +1636,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector) drm_dbg_kms(&dev_priv->drm, "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_err(&dev_priv->drm, "Failed to disable HDCP signalling. %d\n", diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 476ce1d9c557c..f1092066440f4 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1456,7 +1456,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 = intel_attached_dig_port(connector); @@ -1473,12 +1474,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; @@ -1489,6 +1492,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; @@ -1499,7 +1503,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); @@ -1511,7 +1516,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 Tue Feb 18 22:02:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389837 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 80B291395 for ; Tue, 18 Feb 2020 22:03:58 +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 5EF0C207FD for ; Tue, 18 Feb 2020 22:03:58 +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="HKR0B0av" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EF0C207FD 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 2D6756EAA0; Tue, 18 Feb 2020 22:03:39 +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 6DA626EAA8 for ; Tue, 18 Feb 2020 22:03:37 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id b186so10168468ywc.1 for ; Tue, 18 Feb 2020 14:03:37 -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=uwK0zioUNffzqb1aGtEapNZw0WWcKt69QujW42tpynI=; b=HKR0B0av1rVQnVCMGwmC4y+G4xOkAV8b7sA0dEhbDNI4Cw6Z6RujLV4FpJem+a1WAj FB2moymtFJllg1qMGuIPg9r6Dja7PH4v6GgUHGOHaAoGdfQ8S2W11sUHU6IJeMYFcmZX AMsC8Ann7eb4diwtiI3IOBJl3DQi6iW8DMw08Ok0nGxxt3jpohVOjGjbgQX6F0/h2oYo L5LHKVlvCZcnUK2JFBPalUKM33VQtqJTO0mGymGX9IPIp/AzEe/GQsm1X8OwTTbicieN Dk2HzqAU6eoowsR0+gfVnczGGSF9wcPluz/XJcBPlGVKP7ewRwcuQskuZYWR3J+mdv9i XdeA== 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=uwK0zioUNffzqb1aGtEapNZw0WWcKt69QujW42tpynI=; b=RsC7L8I9bD5UuD5LcmfWkP5EAbOvbn9085XCHGfBgTH29aFJN+YgjWKgY84oSQn6tu UqCepB8AwXFJnrHY0p/BkUAzQ2MOkWVxyV6ZqvdAJhDYexxzbImz2THJqeiIhI4F7osY /y2Ain+ibVZwg35wUvHDnjtjmuc0TQrEnwOsDVgHgxpmT7wErrxmG/4HZwF7Q2is7FCF t0YWBr+NBuUjb9CfF3Cb9B57Pujnow6jzMRqzBp5zqQZcHHskQqDCq+OWOVsrrb0bB0S ULCCWjbd6iB16MAbX+d4xPExiV5+dEC3k8Lc7Mkg84fsdgeKCo8/ZSSyAz45MvJxKdQB LTTA== X-Gm-Message-State: APjAAAXtQH76f0UD9+2ByUZbYkh4jBKLixZv4uT+idcE82CSXD4ixrgA U4l+MjOymg19O7UHFTCuuEF7FIO3ZpI= X-Google-Smtp-Source: APXvYqwqkvwjTTL4Bk+ckyQQeZRadAiESW2KWnMcTDQkkQs15FNzS7Jk2btZraCTaIWA9Ji8nEoF2Q== X-Received: by 2002:a81:138f:: with SMTP id 137mr19475297ywt.364.1582063416332; Tue, 18 Feb 2020 14:03:36 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id c84sm41614ywa.1.2020.02.18.14.03.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:35 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 06/14] drm/i915: Factor out hdcp->value assignments Date: Tue, 18 Feb 2020 17:02:34 -0500 Message-Id: <20200218220242.107265-7-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-7-sean@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -Rebased on top of drm_* logging changes --- 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 680d88566d992..c61ade8aa15e6 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -873,6 +873,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) { @@ -899,15 +914,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector) connector->base.name, connector->base.base.id, intel_de_read(dev_priv, 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; } @@ -919,16 +935,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector) ret = _intel_hdcp_disable(connector); if (ret) { drm_err(&dev_priv->drm, "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_err(&dev_priv->drm, "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; } @@ -1748,16 +1766,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) "HDCP2.2 link stopped the encryption, %x\n", intel_de_read(dev_priv, 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; } @@ -1770,8 +1790,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) "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_dbg_kms(&dev_priv->drm, @@ -1789,8 +1810,8 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) drm_err(&dev_priv->drm, "[%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; } @@ -1800,8 +1821,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) "[%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; } @@ -2042,8 +2064,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); @@ -2061,7 +2084,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 Tue Feb 18 22:02:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389843 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 53D8C1395 for ; Tue, 18 Feb 2020 22:04:01 +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 322E5207FD for ; Tue, 18 Feb 2020 22:04:01 +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="b6GjIqK+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 322E5207FD 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 483096EAAB; Tue, 18 Feb 2020 22:03:40 +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 0E6016EAA0 for ; Tue, 18 Feb 2020 22:03:39 +0000 (UTC) Received: by mail-yw1-xc42.google.com with SMTP id 10so10152827ywv.5 for ; Tue, 18 Feb 2020 14:03:39 -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=w+pyfuAZAh1veh329AWb5PnerCG5liLmEQyf2lHc9wk=; b=b6GjIqK+0pYuNCj8v1LERZvLllxBF1IyR0j0tjR+d3LlXPeFAnAAbZQPuOBMP3vgb5 FGOYzdQNgGC9xGMhH8dSI92TUW8zYwhh86IaFmDnCtpRZblFjlKN0/A5C/NX1LbLrFnf N2319DmZkzbEi6jO/Kw5Kx4Fluo45rorDBSZM7AJL8D5S0z9ZkMTPs1wgHGumYu0bb3P TdGwWsyfgi9glq7w8tqrby1BmQk2PVZwbm+voVfu71f0MQsluFEsqP8YqtxVYtIkGsqS 5sjafbpeEQHQ5ivOTpE16SnIG+DTnUH2oMDqXV+HqqrpG28zOq5t4UV3TsEpEnZBYT8n D5cw== 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=w+pyfuAZAh1veh329AWb5PnerCG5liLmEQyf2lHc9wk=; b=NnrootY2gv+GlDn2+en1l7Y04AGpzORLwkuZrztcecoHm8ExuiBX+OV896dwRce6jo zc5Xk8tWSUPAUyhWC2hTgeUMaI0S7fOg3+06E89oDjqimU4fc8nJdy/hYW5byvQjGxLo FIyxlr+jyGc8W+de2xhc/ZrO/cv9qR9veDdgSiFhKQ3bIalvAXOrpiXITUovlRLM0Z8D w2OmbpcGwUvTKrU1wrODL8AMAU8srcWc+x+o9fMcDLA1zEXjh+yhAa7kh9pK5UyWSkR/ Y08pX48tNg4JtOk7biVAiAQzwpb+bCV1s1jbnw75CIJyyyYIrqj85IEynpgwiQpfwXMh xH+Q== X-Gm-Message-State: APjAAAWKJF7o1sP6o+6/yP0ySYjPghgtbTk6hIwU5+X1BjIQ7PGO3+bp oN0FR3nuPjleGnVipgLcymiz2dok/T0= X-Google-Smtp-Source: APXvYqxpfdAASF1+BsNwANqir409ZFFa1UOIXtW2WiXcHvw0dGOXhxUCdN7nQ1Ss/UJxBMEpmF3EkQ== X-Received: by 2002:a0d:c245:: with SMTP id e66mr3360131ywd.32.1582063417553; Tue, 18 Feb 2020 14:03:37 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id s31sm31706ywa.30.2020.02.18.14.03.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:37 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 07/14] drm/i915: Protect workers against disappearing connectors Date: Tue, 18 Feb 2020 17:02:35 -0500 Message-Id: <20200218220242.107265-8-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-8-sean@poorly.run #v3 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 Changes in v4: -None --- 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 c61ade8aa15e6..161f4bcc5bda5 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -884,8 +884,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 */ @@ -976,6 +978,8 @@ static void intel_hdcp_prop_work(struct work_struct *work) mutex_unlock(&hdcp->mutex); drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex); + + drm_connector_put(&connector->base); } bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port) @@ -1839,6 +1843,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); @@ -2154,12 +2161,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 Tue Feb 18 22:02:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389845 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 D1C5417EF for ; Tue, 18 Feb 2020 22:04:02 +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 AFD2E207FD for ; Tue, 18 Feb 2020 22:04:02 +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="HjKFQ8zX" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AFD2E207FD 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 C2A2B6E417; Tue, 18 Feb 2020 22:03:42 +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 8E2696E417 for ; Tue, 18 Feb 2020 22:03:40 +0000 (UTC) Received: by mail-yb1-xb42.google.com with SMTP id n131so7953076ybg.13 for ; Tue, 18 Feb 2020 14:03:40 -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=1xFrPsR+pjvWrrTqLwAtnCgdK8XyTUkpgkcfWZE6OuQ=; b=HjKFQ8zX41XCdED2ya1dkpvNb3SVU+BGBlEMZwP5a1BltQjLzzmdBVdZL5tH8ywZYx xcl1xyM/3enpOnBYXmGdbE8V/VjA/A20MCLqkLNwQ0tEfW8QhGRBssvBfkhZ4z0Egjoa 6PUDJulcBMJoM3BOak2KAp1adi+W48aUpzaqq8uHLUnYihbHczDw7v2SNGZoX3HOOIvW mNjq9pI0PJizR1wT5ZG1mK9fuODm5NXfrM6peuBWLj0GMSw7d4RR2yhJOPF3irWp1fmT g1AzwvTW4Tav6FI1N/piGQmkt304iYXRKD7NEKbrIYOU4xH/sz3TSl5C/8rEWHPydtOQ pUUA== 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=1xFrPsR+pjvWrrTqLwAtnCgdK8XyTUkpgkcfWZE6OuQ=; b=QPqW1hodYJH/KZ3jXRWE51b5ZLT6pc/wh0i+bs7NVI+/lZE32+Il3Fm9lJdNNf2yvo HKzeSBdOnekpTwnq3HohUEQo3j6rM8Bxsuc/dLNYHHsf0F7kTR72OG39mA5SvV8Nrbrw 4h39q2+TnaZ+jyvReHXAM1DZd/7ady5RVJCZTI5pXQNPGQ7x0J4VoMl/H2NtSSCX0elM yWMNfy3fFi/BxFdODv6rrzIAfobekXpO/W/ckyqwMU4TOW335aEDhkHuTkAh8Goifbjb T9i8pX9tbEmKBkcTXkkb330L00ycPAHurkZrNWMbgRaGMAlLEDVKvHUd4Q4p6ZnYlN8N GE4g== X-Gm-Message-State: APjAAAXvx3IeQKBDA8meSr+krJtB1Ljiq7f0r2DvBDNnPS4yVw3b7OwF i8VN/p2DLcNVHJvBmuvUCP2v4HL3kgU= X-Google-Smtp-Source: APXvYqyGsQ6J+U59yjtBLbHezD8dCQLdAEDFQm+EWLUpyNlED8n3VxtbFDVM5EyyoqNv4H0wbAH7/g== X-Received: by 2002:a25:3454:: with SMTP id b81mr21953911yba.417.1582063419436; Tue, 18 Feb 2020 14:03:39 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id q130sm22610ywg.52.2020.02.18.14.03.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:38 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 08/14] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it Date: Tue, 18 Feb 2020 17:02:36 -0500 Message-Id: <20200218220242.107265-9-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-9-sean@poorly.run #v3 Changes in v2: -Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work Changes in v3: -None Changes in v4: -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 61984218961fa..e84315ce753cd 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4758,6 +4758,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); + mutex_init(&intel_dig_port->hdcp_mutex); + intel_dig_port->num_hdcp_streams = 0; + encoder->hotplug = intel_ddi_hotplug; encoder->compute_output_type = intel_ddi_compute_output_type; encoder->compute_config = intel_ddi_compute_config; diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b9e4ba8071d29..edbe8211078df 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1339,6 +1339,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 f601cdcd4c647..05d09161afa76 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7641,6 +7641,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 161f4bcc5bda5..970cdd793cbbe 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -796,6 +796,19 @@ static int _intel_hdcp_disable(struct intel_connector *connector) drm_dbg_kms(&dev_priv->drm, "[%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; intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0); if (intel_de_wait_for_clear(dev_priv, @@ -876,6 +889,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 = intel_attached_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; WARN_ON(!mutex_is_locked(&hdcp->mutex)); @@ -883,6 +897,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); @@ -901,6 +924,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 */ @@ -953,6 +978,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; } @@ -2034,6 +2060,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 = intel_attached_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; int ret = -EINVAL; @@ -2042,6 +2069,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; @@ -2076,12 +2104,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 = intel_attached_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; int ret = 0; @@ -2089,17 +2119,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 f1092066440f4..d569d0a1f1dcf 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -3264,6 +3264,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 Tue Feb 18 22:02:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389853 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 5128017EF for ; Tue, 18 Feb 2020 22:04:06 +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 2F4AC207FD for ; Tue, 18 Feb 2020 22:04:06 +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="XQ5lZbPi" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2F4AC207FD 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 596A36EAB7; Tue, 18 Feb 2020 22:03:46 +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 A79C36E417 for ; Tue, 18 Feb 2020 22:03:41 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id z141so10125818ywd.13 for ; Tue, 18 Feb 2020 14:03:41 -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=2EOch5Rw3WBJMp4XFKpC6cuq8lAKO8K/UQJcWa2z04E=; b=XQ5lZbPiQ5NRHZBckdqypesKO35A3U8OyigM0WIPQwaEwufKMEOCP8gl1QXVZpJgvH P0G/FaDUmP0t+9Qilt2K5BjU13FEvDjzs8jdNWcbyAbIxv4mLuMkU4nUFpWzZAnXxUwz Mf6m12ucOx20alpkEg2tIJBIod4RSW4Qajc+iMh97YD4yYPlwf/FeJG8x5QHAany5ZLK 1Xn2jPPpjhg92VyGTHvJoomV0bYbZ1S0dWL7BKFPn2r1fZG08BX48OR4sS1JhDImM+ud FkC497gHQ2UbIt7DcV0DtNSMIBchas1aor/rBb9cGE+yXjD3ausLtT32KYuO3ayF9e5W veYA== 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=2EOch5Rw3WBJMp4XFKpC6cuq8lAKO8K/UQJcWa2z04E=; b=ja+qUqFXuWYn8/x245eYmcwgOQmArG+CfdmVp6wedtvYbghYvrfveoSwr2FnnpCS2h DPuXrEJQlLmHo6fmw8uY3n8Fca44ZMYns9xzWl3mnlKYoSQf6KPgjdqkfEBCcEnhnkJU heDz4T1hRag4wrmfS9abBYczpGCQ48l0MT/KBLm1mLEynfH+8d/x7GsX8ZAU74/v1bZ/ iNqTDEVm/EQBHBzEoPUl51poPVpNyxdp9+VOuKudF+E7SyKIh2sgL/U5BXlUZRBshC/g YgAtUfdTh0QLtsA6kb5eUeIylgKtavvfrtCj8VDQNqoB+E9UP/Wxvi4QiQvgUyn60J7n OSvQ== X-Gm-Message-State: APjAAAV7ranfcZZIGpDj/te2wzcR+152EY2MERRCmuYPHCiDaJElrI+M vAHMFkeJYf51k0Jb2V/H9wjNotAP7cY= X-Google-Smtp-Source: APXvYqxFP7kqlT/z0xwWhddDnmLSUArX8hEVg8DxV7ZciVIngV+T5wN2mDmmjsenccm2xLHnFQ2kbw== X-Received: by 2002:a0d:cf85:: with SMTP id r127mr19028316ywd.514.1582063420703; Tue, 18 Feb 2020 14:03:40 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id d137sm21972ywe.36.2020.02.18.14.03.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:40 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 09/14] drm/i915: Support DP MST in enc_to_dig_port() function Date: Tue, 18 Feb 2020 17:02:37 -0500 Message-Id: <20200218220242.107265-10-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-10-sean@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -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 edbe8211078df..9fb25f80dc91d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1444,6 +1444,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) { @@ -1452,6 +1464,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; } @@ -1462,13 +1476,6 @@ intel_attached_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 Tue Feb 18 22:02:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389859 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 DCB1B1395 for ; Tue, 18 Feb 2020 22:04:09 +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 BB301207FD for ; Tue, 18 Feb 2020 22:04:09 +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="H/hdcSEh" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BB301207FD 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 21A4C6EAC0; Tue, 18 Feb 2020 22:03:47 +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 36A816EAAC for ; Tue, 18 Feb 2020 22:03:43 +0000 (UTC) Received: by mail-yb1-xb43.google.com with SMTP id b141so11313909ybg.10 for ; Tue, 18 Feb 2020 14:03:43 -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=+DAThCAeUYnhUzxPv8jDEX6JPd0YiZKig6k4tZl+QAo=; b=H/hdcSEhPuLDk3Brb7FVKiU+YB49NWMYkTD9i4WitX9qV8ODpNUq1twCWnJdYCUpCi zp43xF8ZJn5t5ltIhUpPhSP5msauzgyf3zA/WAaJ/E92kHtYlYAMbIZLOBthR4KPzLhq 929etzDgX2RQEqLoaT8jsi2f+BKCAI7FFcu4oEQ6ieGMYKSwjrQCAUl5RmlcZ1tQzrQn To3GAj1XpiVOnhNKB4VgbyAgpxcrcdHSgaK6oTouerbfLo99U10SJJ/Dp0UxBP6EO65f MrlDyqGetLEWbvoGv473ylsF6GfQH1p2NomK7Lqhh2BKW9B/gAVwb3uULwfmCzOqL3Hh DClw== 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=+DAThCAeUYnhUzxPv8jDEX6JPd0YiZKig6k4tZl+QAo=; b=YHUrXN1irIwi7ofb67MtRz7qJSFMBypGpFHDffATeyOU12fvvoy2d4K/i/wH+ifjYR btBFCHAUWi/VO6riejbIvDJVHO+sSn1Jmhj/nqshN/YW2wfuob6M9hA5pGs1dtVONpmS /hHIEqhysihGRZKfu0W5QaJCMH7+mdV8mwsn+Z7FkC7LRadPlakA86MEA9xU/5IpAwcZ Q+wOObD85dDVy/APHHjyExZKMcMvirvMN20jHHbJBSUVTzyAJh78b3WM26QeAN/UlumV 40L5LCsNP91kqiGRcUnuGgsL1SU7FXYY9LLvJtkymWpIU6kzCVu4tWd7dJ63EZptMc/u RqEw== X-Gm-Message-State: APjAAAW6HEVS8va6+zungwrdVUFTVdVlrwKQiPgpd1i2At5IR16f+56g Cp/MMvqHuQVECp51qhiJrlgHSHBp3P8= X-Google-Smtp-Source: APXvYqzEAuvkd+G4QQeFWKapMGJPdBAGnJl61HvAW85IbzILkmMKpuAUrrU49ELabwbfVlvckA6/9g== X-Received: by 2002:a25:e909:: with SMTP id n9mr21879196ybd.187.1582063422226; Tue, 18 Feb 2020 14:03:42 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id a12sm11440ywa.95.2020.02.18.14.03.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:41 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 10/14] drm/i915: Use ddi_update_pipe in intel_dp_mst Date: Tue, 18 Feb 2020 17:02:38 -0500 Message-Id: <20200218220242.107265-11-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-11-sean@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -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 e84315ce753cd..cd2eac53a3b06 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4108,12 +4108,13 @@ 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) { - 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); intel_hdcp_update_pipe(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 3da1660547888..0a028b58a8bed 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 d7bfa7c350e99..f44a58e14a736 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -787,6 +787,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 Tue Feb 18 22:02:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389863 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 01D1917EF for ; Tue, 18 Feb 2020 22:04:12 +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 D4BF0207FD for ; Tue, 18 Feb 2020 22:04:11 +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="IZ+TTlwz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D4BF0207FD 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 D62356EACE; Tue, 18 Feb 2020 22:03:48 +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 E9D4E6EAB2 for ; Tue, 18 Feb 2020 22:03:45 +0000 (UTC) Received: by mail-yw1-xc41.google.com with SMTP id b186so10168679ywc.1 for ; Tue, 18 Feb 2020 14:03:45 -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=MbKvISoVZtVNf2I9vZO9JjOTvDn1yOeU1D3TtLxoyCM=; b=IZ+TTlwzXNqUlpMdpB/QFUV9Ux4eIf37pVotp6mIqHB86kCLJ3IxK6V9FzQbg5TIPA yMsrWfbX6ck6MHAmE0yi7fgaX4cfh9KL0YrBROmmHkPbJslLtUaL93iJ50Si+0Tq2LV7 6aqWSY9VoQ8ochpNAGWfUBtfG2ypgB71yGDLFLMYmMVkmJRtTcmdj0Ll2KF7TM2/IpbZ pKt/x0yVjEAkFTo0El7ThzHQqsRKwCo0iWDYYc723eALFByCgzIm9IPyWoy5YpOXqwIV SS1lBh0HcQIxzS957txXsANFashhvQotnLed2/hdLYWwOVQvALWMJfsPaIectLbuhe4r QXGA== 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=MbKvISoVZtVNf2I9vZO9JjOTvDn1yOeU1D3TtLxoyCM=; b=kVfRid9abjGypm1M1T/krAlz7xVh1st33u3ltLMwn2bGhcfCbh5JXUGsGGr87mrV/K YD5ATprpLLxj4sWgW5S9UTIAeHcfAtdeMFqHgmTofL0Q7aJrQjm9tSqbXbZHVuOH+vKq D+SEvUSs/ih4AssNf+HBca9GJBAVhVREaQP9HntjQTQATMvJyDvYzFGwTyHKr5uTQccS T9BwV6dULVYAzNU3Z6m7QcQsJeCTR2Jh6t3KA2K0BStt9xmO8OX+XaOVhcf+1cSwbjuz 691+zUKvuWF/I5ArlV/jeXkE84mtOLxnAVJaZig+Q6YDI2QnG/MtY9/Js7uNwzJI0xoB xRtQ== X-Gm-Message-State: APjAAAVWDogpkBs16uPmobCNCbBlv82jkEHZ9E2qIXuMvB0nSv/Rix0V PcMG8/mhTZ+8CLjnBHYtyWmBrshHV7k= X-Google-Smtp-Source: APXvYqxTNCtJWg5kfckh4QTE0drvEBUz9esT1Vwv7ZyAQRx7a8wsA4wSWT12KzmVYA6lpEVlKRjbGw== X-Received: by 2002:a0d:d711:: with SMTP id z17mr5438084ywd.120.1582063423634; Tue, 18 Feb 2020 14:03:43 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id p6sm17647ywi.63.2020.02.18.14.03.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:43 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 11/14] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst Date: Tue, 18 Feb 2020 17:02:39 -0500 Message-Id: <20200218220242.107265-12-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-12-sean@poorly.run #v3 Changes in v2: -None Changes in v3: -Created intel_dp_hdcp.c for the shared functions to live (Ville) Changes in v4: -Rebased on new drm logging change --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 581 +----------------- drivers/gpu/drm/i915/display/intel_dp.h | 3 + drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 604 +++++++++++++++++++ 4 files changed, 612 insertions(+), 577 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 b314d44ded5eb..142feb8cf6aa5 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -222,6 +222,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 05d09161afa76..bdf0bbe8ac743 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5940,576 +5940,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); @@ -7508,7 +6938,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, @@ -7596,12 +7026,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_dbg_kms(&dev_priv->drm, - "HDCP init failed, skipping.\n"); - } + ret = intel_dp_init_hdcp(intel_dig_port, intel_connector); + if (ret) + drm_dbg_kms(&dev_priv->drm, "HDCP init failed (%d)\n", ret); /* 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 0a028b58a8bed..cb96a40da0323 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 0000000000000..0b6d90980e909 --- /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 Tue Feb 18 22:02:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389857 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 6374D17EF for ; Tue, 18 Feb 2020 22:04:08 +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 4166424672 for ; Tue, 18 Feb 2020 22:04:08 +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="PDAPDq8n" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4166424672 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 07E806EAB8; Tue, 18 Feb 2020 22:03:48 +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 198116EAB3 for ; Tue, 18 Feb 2020 22:03:46 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id z141so10125922ywd.13 for ; Tue, 18 Feb 2020 14:03:46 -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=oWhEkUIUWNx1G1JMKBT67kP0/td96SzJZ0ipMfdJ4XM=; b=PDAPDq8nxsFgxJh6lMj/D2ZRs3KyKJMSgNMx7TKF1nF21iaxc/VVnsI57rSwB/qSst 4WADVvMirzYd1piCFKw7B+5U5tn2sx8xKB+y57HQdOBoOzCxQ2j88jXDwjnb+rV1fBa3 2d4cwRlZT5Jahj29I/d7CR+TQWMhoWHwUYrWM0PQFFR0ej2/kl6d5G0JZ0keuJA2O5xV agmqT4AfnbDLPEFsvHifQ+u6mBnlIH/arheqclEaeyPb+hoUDYRD+yjESj3NT2ev7OCi mcA0HB6sLdKdtMgfvnmxlN0GO7znuUDy8M6Vh67wH8+BBXZ2eTk+TkVzUodQ5PgUoIqb q4vw== 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=oWhEkUIUWNx1G1JMKBT67kP0/td96SzJZ0ipMfdJ4XM=; b=Bs8q+vnPMQkSAfLlw6uWVSkCuKKVPb/ddaDClfunXQg5STMK12h49fs5wsCXGmj2Ah iUg/fuGF2YsBG5oPiBaUvjo+rzGhknQ/I0lwRF70jNcM3SLUS/ZQqHZ2yzo3AQSwOkfj Wjvo02tIllLPPRfm9S7s8cNvNlvTRYfYSiYQd/FcdRvTQYwaE6UaRC4RjXIYRtaUOhtu c1y83Ixpb0BRI/WefSCfo6Mbky6bYsGH/Mk0SkOOszxx5uyJ/MD0kgPnacF9NqNBaA4R UWVuEMUUGEzwCpcldW49XsZkBLd2ZeCQ2QE0GT4AhPetmXdbluehNSojEs7Pcywlrtte zeNQ== X-Gm-Message-State: APjAAAUEZJAXC5/SMdnLLFj8v3tpeEb+wF+6HWV53Qpne5fO1D/f3Cac gZaVPnRPyFfpY+T+YVVsLpQZ/nOyYKE= X-Google-Smtp-Source: APXvYqy1UJzNHSxFZpHj2nLK82S8hgrF/MlluSPF9iFCdbTyEue/1GdMZRR6bUMxwvsEswWuJ75Rew== X-Received: by 2002:a0d:d8c2:: with SMTP id a185mr17371288ywe.337.1582063424807; Tue, 18 Feb 2020 14:03:44 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id s130sm31449ywg.11.2020.02.18.14.03.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:44 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 12/14] drm/i915: Add connector to hdcp_shim->check_link() Date: Tue, 18 Feb 2020 17:02:40 -0500 Message-Id: <20200218220242.107265-13-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul Currently we derive the connector from digital port in check_link(). For MST, this isn't sufficient since the digital port passed into the function can have multiple connectors downstream. This patch adds connector to the check_link() arguments so we have it when we need it. Signed-off-by: Sean Paul Changes in v4: -Added to the set --- drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 3 ++- drivers/gpu/drm/i915/display/intel_hdcp.c | 2 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 5 ++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 9fb25f80dc91d..ce85f1bab2729 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -310,7 +310,8 @@ struct intel_hdcp_shim { bool enable); /* Ensures the link is still protected */ - bool (*check_link)(struct intel_digital_port *intel_dig_port); + bool (*check_link)(struct intel_digital_port *intel_dig_port, + struct intel_connector *connector); /* Detects panel's hdcp capability. This is optional for HDMI. */ int (*hdcp_capable)(struct intel_digital_port *intel_dig_port, diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index 0b6d90980e909..f1f4c2c793652 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -535,7 +535,8 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, } static -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port) +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port, + struct intel_connector *connector) { ssize_t ret; u8 bstatus; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 970cdd793cbbe..20952f6fb31eb 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -947,7 +947,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector) goto out; } - if (hdcp->shim->check_link(intel_dig_port)) { + if (hdcp->shim->check_link(intel_dig_port, connector)) { if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { intel_hdcp_update_value(connector, DRM_MODE_CONTENT_PROTECTION_ENABLED, true); diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index d569d0a1f1dcf..59b24ed603fa6 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1523,11 +1523,10 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port, } static -bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port) +bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port, + struct intel_connector *connector) { struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev); - struct intel_connector *connector = - intel_dig_port->hdmi.attached_connector; enum port port = intel_dig_port->base.port; enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder; int ret; From patchwork Tue Feb 18 22:02:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389871 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 2DA4317F0 for ; Tue, 18 Feb 2020 22:04: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 0C336207FD for ; Tue, 18 Feb 2020 22:04: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="BN/PyFTN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0C336207FD 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 A0E196EAAD; Tue, 18 Feb 2020 22:03:52 +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 8D1A86EACA for ; Tue, 18 Feb 2020 22:03:47 +0000 (UTC) Received: by mail-yw1-xc42.google.com with SMTP id h126so10147127ywc.6 for ; Tue, 18 Feb 2020 14:03:47 -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=Vs7KKiHvwBDYaNLVMRNzG/6a+DIoa5ExQfl3ktdNOFg=; b=BN/PyFTNAbhF2/DjUgMRrcE4OVJKfkNMIIqkAvysBm3DTVKZP8GjLMe8p4e+pLyIS4 7ph5c1nX3Z86iSwKTo3GXaOeXIRU/2+IoIzW+k72aCZNdZL1mMZqarnM/CnKGqq61VTc JdZYF/BPl9GGxRPL7yBcT9kx1W3SeWhk/tgocrTugSy0E2ZCwyt2oZOq8Sd+bFxjlVdp QuF/XrV7E29PFw+zqqg5LpPt5VdcSnnklDJL3pGimxbCUrHtm2fRj6j1PTZu0Wiyf+QA c8/nUQcZ6vF0P3DfB4QqEFg9kIZSXIzyPu4XmH5z8N0DYqqg9jBseXjBFpT6qR5OBsNX NeNg== 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=Vs7KKiHvwBDYaNLVMRNzG/6a+DIoa5ExQfl3ktdNOFg=; b=sO1Twf1pSgBXZ/MvLGmFZ6wVJkgigzNYfwGc951Q1NM5LxmmCLu24dkzBrWdXO3D/P Osf/eZiUI5DOkseCjevBYrY96Rp4wcv5gSLLvgX122TjnYm8r5++k1tGc1Gmr8EBelIT FUI2rB7dcQRkiW4PoQByuqu++FtPIxMUm6LfoVA0j2WKg1IlbYSmsS8limL9qIk7H0WJ YmdDWhKxjiHhirpNoFA4IiqUdC3xWyq8KzOf6SzIlETcyVqpGauu0It/aMhdf9qSKGZi R87EqvEzzA3pPZ1qfMC8OgeVUOnbK9gT3fHybhskUqhGvt3vIbR6we0q7ee4cMuutivH CkJg== X-Gm-Message-State: APjAAAVNdYhS/vSxjRGRZfEk13PwQShRuEonUspHp1tOzfsIu8JLt8XO 7mHyQhjA1eYeJQeDdDTCHE06h9IvOA0= X-Google-Smtp-Source: APXvYqxFnQ7/r7Eu0J55rFH6I3jdZHx3ltwRrwkv140Q6lyUrJHvJ3bTLFr/jF09OceMxQGDT0pAyQ== X-Received: by 2002:a0d:db47:: with SMTP id d68mr19517951ywe.338.1582063425961; Tue, 18 Feb 2020 14:03:45 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id d188sm25214ywe.50.2020.02.18.14.03.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:45 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 13/14] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message Date: Tue, 18 Feb 2020 17:02:41 -0500 Message-Id: <20200218220242.107265-14-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Sean Paul Used to query whether an MST stream is encrypted or not. Cc: Lyude Paul Signed-off-by: Sean Paul Changes in v4: -Added to the set --- drivers/gpu/drm/drm_dp_mst_topology.c | 117 ++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 3 + include/drm/drm_dp_mst_helper.h | 44 ++++++++++ 3 files changed, 164 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index a811247cecfef..30b6dc6ce54c2 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -418,6 +419,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req, memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes); idx += req->u.i2c_write.num_bytes; break; + case DP_QUERY_STREAM_ENC_STATUS: { + const struct drm_dp_query_stream_enc_status *msg; + + msg = &req->u.enc_status; + buf[idx] = msg->stream_id; + idx++; + memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id)); + idx += sizeof(msg->client_id); + buf[idx] = 0; + buf[idx] |= msg->stream_event & GENMASK(1, 0); + buf[idx] |= msg->valid_stream_event ? BIT(2) : 0; + buf[idx] |= (msg->stream_behavior & GENMASK(1, 0)) << 3; + buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0; + idx++; + } + break; } raw->cur_len = idx; } @@ -926,6 +943,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms return true; } +static bool +drm_dp_sideband_parse_query_stream_enc_status( + struct drm_dp_sideband_msg_rx *raw, + struct drm_dp_sideband_msg_reply_body *repmsg) +{ + struct drm_dp_query_stream_enc_status_ack_reply *reply; + + reply = &repmsg->u.enc_status; + + reply->stream_id = raw->msg[3]; + + reply->reply_signed = raw->msg[2] & BIT(0); + + reply->hdcp_1x_device_present = raw->msg[2] & BIT(3); + reply->hdcp_2x_device_present = raw->msg[2] & BIT(4); + + reply->query_capable_device_present = raw->msg[2] & BIT(5); + reply->legacy_device_present = raw->msg[2] & BIT(6); + reply->unauthorizable_device_present = raw->msg[2] & BIT(7); + + reply->auth_completed = !!(raw->msg[1] & BIT(3)); + reply->encryption_enabled = !!(raw->msg[1] & BIT(4)); + reply->repeater_present = !!(raw->msg[1] & BIT(5)); + reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6; + + return true; +} + static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw, struct drm_dp_sideband_msg_reply_body *msg) { @@ -960,6 +1005,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw, return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg); case DP_CLEAR_PAYLOAD_ID_TABLE: return true; /* since there's nothing to parse */ + case DP_QUERY_STREAM_ENC_STATUS: + return drm_dp_sideband_parse_query_stream_enc_status(raw, msg); default: DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type, drm_dp_mst_req_type_str(msg->req_type)); @@ -1113,6 +1160,25 @@ static int build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg, return 0; } +static int +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id, + u8 *q_id) +{ + struct drm_dp_sideband_msg_req_body req; + + req.req_type = DP_QUERY_STREAM_ENC_STATUS; + req.u.enc_status.stream_id = stream_id; + memcpy(req.u.enc_status.client_id, q_id, + sizeof(req.u.enc_status.client_id)); + req.u.enc_status.stream_event = 0; + req.u.enc_status.valid_stream_event = false; + req.u.enc_status.stream_behavior = 0; + req.u.enc_status.valid_stream_behavior = false; + + drm_dp_encode_sideband_req(&req, msg); + return 0; +} + static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_vcpi *vcpi) { @@ -3154,6 +3220,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, } EXPORT_SYMBOL(drm_dp_send_power_updown_phy); +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port, + struct drm_dp_query_stream_enc_status_ack_reply *status) +{ + struct drm_dp_sideband_msg_tx *txmsg; + u8 nonce[7]; + int len, ret; + + txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + if (!txmsg) + return -ENOMEM; + + port = drm_dp_mst_topology_get_port_validated(mgr, port); + if (!port) { + ret = -EINVAL; + goto out_get_port; + } + + get_random_bytes(nonce, sizeof(nonce)); + + /* + * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message + * transaction at the MST Branch device directly connected to the + * Source" + */ + txmsg->dst = mgr->mst_primary; + + len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce); + + drm_dp_queue_down_tx(mgr, txmsg); + + ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg); + if (ret < 0) { + goto out; + } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) { + DRM_DEBUG_KMS("query encryption status nak received\n"); + ret = -ENXIO; + goto out; + } + + ret = 0; + memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status)); + +out: + drm_dp_mst_topology_put_port(port); +out_get_port: + kfree(txmsg); + return ret; +} +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status); + static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr, int id, struct drm_dp_payload *payload) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index b8f6bac6341c1..11b2c49e4f0f4 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1099,6 +1099,9 @@ #define DP_POWER_DOWN_PHY 0x25 #define DP_SINK_EVENT_NOTIFY 0x30 #define DP_QUERY_STREAM_ENC_STATUS 0x38 +#define DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST 0 +#define DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE 1 +#define DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE 2 /* DP 1.2 MST sideband reply types */ #define DP_SIDEBAND_REPLY_ACK 0x00 diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 5483f888712ad..baf3405df44d8 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -305,6 +305,34 @@ struct drm_dp_remote_i2c_write_ack_reply { u8 port_number; }; +struct drm_dp_query_stream_enc_status_ack_reply { + /* Bit[23:16]- Stream Id */ + u8 stream_id; + + /* Bit[15]- Signed */ + bool reply_signed; + + /* Bit[10:8]- Stream Output Sink Type */ + bool unauthorizable_device_present; + bool legacy_device_present; + bool query_capable_device_present; + + /* Bit[12:11]- Stream Output CP Type */ + bool hdcp_1x_device_present; + bool hdcp_2x_device_present; + + /* Bit[4]- Stream Authentication */ + bool auth_completed; + + /* Bit[3]- Stream Encryption */ + bool encryption_enabled; + + /* Bit[2]- Stream Repeater Function Present */ + bool repeater_present; + + /* Bit[1:0]- Stream State */ + u8 state; +}; struct drm_dp_sideband_msg_rx { u8 chunk[48]; @@ -378,6 +406,15 @@ struct drm_dp_remote_i2c_write { u8 *bytes; }; +struct drm_dp_query_stream_enc_status { + u8 stream_id; + u8 client_id[7]; /* 56-bit nonce */ + u8 stream_event; + bool valid_stream_event; + u8 stream_behavior; + u8 valid_stream_behavior; +}; + /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */ struct drm_dp_port_number_req { u8 port_number; @@ -426,6 +463,8 @@ struct drm_dp_sideband_msg_req_body { struct drm_dp_remote_i2c_read i2c_read; struct drm_dp_remote_i2c_write i2c_write; + + struct drm_dp_query_stream_enc_status enc_status; } u; }; @@ -448,6 +487,8 @@ struct drm_dp_sideband_msg_reply_body { struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack; struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack; struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack; + + struct drm_dp_query_stream_enc_status_ack_reply enc_status; } u; }; @@ -804,6 +845,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, struct drm_dp_mst_port *port); int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, bool power_up); +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port, + struct drm_dp_query_stream_enc_status_ack_reply *status); int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state); void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port); From patchwork Tue Feb 18 22:02:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11389869 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 AC2CB1395 for ; Tue, 18 Feb 2020 22:04:14 +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 8AD38207FD for ; Tue, 18 Feb 2020 22:04:14 +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="d/hF5ZrW" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8AD38207FD 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 A92ED6EAA9; Tue, 18 Feb 2020 22:03:51 +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 64AC06EAC5 for ; Tue, 18 Feb 2020 22:03:48 +0000 (UTC) Received: by mail-yb1-xb42.google.com with SMTP id v12so11317968ybi.5 for ; Tue, 18 Feb 2020 14:03:48 -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=6FWDpPOp5SnUYvKqoDjlOAx23GmsnRjgCgyGIX4xGiA=; b=d/hF5ZrWj+a8BrePP8E1V/dOPL78r2bRG/UwoP8jph/hm8aAf5l6itqOXGlC/84/OR vY2lCJ6oXk/0njHM1M5GuAgn1qzI5qaQd6Gh28IYZ/qKtSCId2aHdT20ahzkN2UJydUx me1FFYXc6DAflYb5Ig/Eh6gCi4mUMpd1LfKDb3PnJhgUhSgtdTr/DF/XCaAjTCvQ8680 4Cr9LhUnWNC4YpLgSapXzSh2OSt6yG6/M5B86f7K65q8Zs4J3TUMW4mF9ceB/fi3co93 9BRVMpqBpemf8zM0Ya/0iHBMJAJBeQgVCH1JhqPmhYCia1Gi8ef3X2lcB4hrA2Sx4CH7 Zlgw== 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=6FWDpPOp5SnUYvKqoDjlOAx23GmsnRjgCgyGIX4xGiA=; b=tdMumeIMAeOL/XPoiJPq0r1lNSxTJH7ahPALQJVokrNarWh4wyJML9gh6nNjzkuyaB /Xsi8E3dsmRevLIhK03t/I9XLOIdkJp+1zOnSSPvWeQIhNwhGjpeig66P29fJ8vV2nI1 VAqC9Vo2p9/wsWQPLL0I3BpBTeGOxn+xTKvB7u33MompzmXvwgYfYBdvejPpZzGmEMTz yb9MX/98LGl6HcCB6sBp+Lxol4V80jaitRr2zuUq7Uw9ek9wG3KnqLlej6QkATWCncLG XuXfoiNNfKTRwpqL/nak3E0tmNgRY6KZhSUF4w001rUMQyYgPjUMd9mnQKqaraw1uOBt QXLA== X-Gm-Message-State: APjAAAWjGn8zVVz7FG5tJCcHuhLtDR7ABYtLuancvfJrOT4bw3uPIznO ZEVtIBeSfODuGkaN6Gy7PhV+5vWgqsg= X-Google-Smtp-Source: APXvYqygkdZFgNy7Hepc9WKd/Gpfe5p9nai99IukFZNT/QakshtwYwdLu6f6x+5fd29rfgUlK1lTXg== X-Received: by 2002:a25:4656:: with SMTP id t83mr318254yba.184.1582063427252; Tue, 18 Feb 2020 14:03:47 -0800 (PST) Received: from localhost ([2620:0:1013:11:1e1:4760:6ce4:fc64]) by smtp.gmail.com with ESMTPSA id d199sm14601ywh.83.2020.02.18.14.03.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Feb 2020 14:03:46 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [PATCH v4 14/14] drm/i915: Add HDCP 1.4 support for MST connectors Date: Tue, 18 Feb 2020 17:02:42 -0500 Message-Id: <20200218220242.107265-15-sean@poorly.run> X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog In-Reply-To: <20200218220242.107265-1-sean@poorly.run> References: <20200218220242.107265-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, Sean Paul , juston.li@intel.com, rodrigo.vivi@intel.com 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 Cc: Juston Li 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 Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3 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) Changes in v4: -Actually use the mst shim for mst connections (Juston) -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted --- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 102 ++++++++++++++++++- drivers/gpu/drm/i915/display/intel_dp_mst.c | 14 +++ 2 files changed, 115 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 f1f4c2c793652..e69ad428d10fb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -7,10 +7,12 @@ */ #include +#include #include #include #include "intel_display_types.h" +#include "intel_ddi.h" #include "intel_dp.h" #include "intel_hdcp.h" @@ -586,6 +588,101 @@ 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 +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port, + struct intel_connector *connector) +{ + struct intel_dp *intel_dp = &intel_dig_port->dp; + struct drm_dp_query_stream_enc_status_ack_reply reply; + int ret; + + if (!intel_dp_hdcp_check_link(intel_dig_port, connector)) + return false; + + ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr, + connector->port, &reply); + if (ret) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] failed QSES ret=%d\n", + connector->base.base.id, connector->base.name, + ret); + return false; + } + + return reply.auth_completed && reply.encryption_enabled; +} + +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_mst_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) { @@ -598,7 +695,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_connector->mst_port) + 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 f44a58e14a736..ac5dc17ad6d86 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); @@ -510,6 +513,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, @@ -703,6 +713,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.