From patchwork Tue Dec 3 17:36:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 11271779 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 E021A139A for ; Tue, 3 Dec 2019 17:37:34 +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 C5C3E20803 for ; Tue, 3 Dec 2019 17:37:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C5C3E20803 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=poorly.run Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D817B6EA4A; Tue, 3 Dec 2019 17:37:32 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@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 D4F246EA47 for ; Tue, 3 Dec 2019 17:37:30 +0000 (UTC) Received: by mail-yb1-xb44.google.com with SMTP id q7so1862486ybk.4 for ; Tue, 03 Dec 2019 09:37:30 -0800 (PST) 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=Km82VcRkTZuSw6qGN0kn4itOohtD+O7wdXp8OYBw050=; b=jXunNyiEUlqXbnP4DILujysM7odCgBzhr+1og7c3Teou2rZIS8RMHd7ArEXUeUa3+V DoDnchvLX6Wfx1dtW3oryCkdxnaCB0AdpCxLHlRTEG767YOrUgXIOnKKIZTMy5dqX0kp KNx76MjOsfe/URTu+6C8ma8LwW7CzOfwBYOGzlyW7IjbKPhjWhmIs5VcellI1rb3dp2F rGQBA2l7WpHDf9oB+yQrpiuOXDFQSX8RZ0Snf+nicKEqbnW+zHiOO9nswQlVkCAf1sUl U91tMVz1ss+ouDY3/cALndQRak32lm1KVEzxGBg4TqfnVckPjG42BhL58YpscgiAa3sD CIqQ== X-Gm-Message-State: APjAAAXtgzT80eMnpZX/OOLx4PVCh4mhz2LoGEVthcKIKdGEsDuo1IPX XIohdv0vDV3Fq5z1mFcra1QGCg== X-Google-Smtp-Source: APXvYqz8xSQ7FEL3txDfFc9JPXjfO9mHCYMS6nNLBPvKfRL5AiTGaM3naoaBIVRQGTjA39BZw7XaHg== X-Received: by 2002:a25:b090:: with SMTP id f16mr5433670ybj.437.1575394649890; Tue, 03 Dec 2019 09:37:29 -0800 (PST) Received: from rosewood.cam.corp.google.com ([2620:0:1013:11:89c6:2139:5435:371d]) by smtp.gmail.com with ESMTPSA id g190sm1729426ywf.41.2019.12.03.09.37.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Dec 2019 09:37:29 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, ramalingm.c@intel.com Date: Tue, 3 Dec 2019 12:36:30 -0500 Message-Id: <20191203173638.94919-8-sean@poorly.run> X-Mailer: git-send-email 2.24.0.393.g34dc348eaf-goog In-Reply-To: <20191203173638.94919-1-sean@poorly.run> References: <20191203173638.94919-1-sean@poorly.run> MIME-Version: 1.0 X-Mailman-Original-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=Km82VcRkTZuSw6qGN0kn4itOohtD+O7wdXp8OYBw050=; b=I4JYMUkd0vXwZQRB6JAog8eIW4nnp9K74RxN6q6Has4Es9uMZbuWvFedZ9UhZ8xrbw qn57pyoZIe2ZPgcXYnGz3zSyWiOBlzEqD9ef/oJqytzcb1n9PGVypRRltio2M3gNUeoP pH2VuDV7asTEF2Ut7NnurXt0ScIgLv5Q0qZNACHpTSqLuDcRu/1IvSzwWrSX/1QEIhlE 2jdZtsvTpR2aLym86RXaOHC3RwV76QayWFW/dSnADmT2IkdrjDnTC629SJlY9bvelEg8 x20eyhsDJ9e7YYDQUYmrZ3Ji4A03YZhatWajxGeymZ/vRyNi635r0FtQMjsWyF0/uxxe I9Sw== Subject: [Intel-gfx] [PATCH 07/11] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Airlie , Sean Paul Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" 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. Signed-off-by: Sean Paul --- 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 | 49 ++++++++++++++++--- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 + 5 files changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ca28913a4c9f..a55bc7109045 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4717,6 +4717,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) intel_encoder = &intel_dig_port->base; encoder = &intel_encoder->base; + mutex_init(&intel_dig_port->hdcp_mutex); + intel_dig_port->num_hdcp_streams = 0; + drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index bbd44772b9b0..489e1d00928b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1309,6 +1309,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 e26fb26b1909..fc5a7dc6ab9b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7535,6 +7535,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 f34763fa5b42..cd246f501738 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -849,6 +849,7 @@ struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp) static void intel_hdcp_update_value(struct intel_connector *connector, u64 value, bool update_property) { + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; WARN_ON(!mutex_is_locked(&hdcp->mutex)); @@ -856,6 +857,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) schedule_work(&hdcp->prop_work); @@ -872,6 +882,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 */ @@ -923,6 +935,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; } @@ -1994,6 +2007,7 @@ int intel_hdcp_init(struct intel_connector *connector, int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) { + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; int ret = -EINVAL; @@ -2002,6 +2016,7 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) 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; @@ -2031,12 +2046,14 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) true); } + mutex_unlock(&intel_dig_port->hdcp_mutex); mutex_unlock(&hdcp->mutex); return ret; } int intel_hdcp_disable(struct intel_connector *connector) { + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; int ret = 0; @@ -2044,17 +2061,33 @@ 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 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(connector, false); + if (ret) + DRM_DEBUG_KMS("Failed to disable HDCP signalling\n"); + goto out; } + 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 6a1e711c4f7a..c230d37c4276 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -3243,6 +3243,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));