From patchwork Thu Nov 30 03:08:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 10084129 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B63A660311 for ; Thu, 30 Nov 2017 03:09:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A8D9429D5C for ; Thu, 30 Nov 2017 03:09:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9BE1729D9D; Thu, 30 Nov 2017 03:09:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1197C29D5C for ; Thu, 30 Nov 2017 03:09:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E3A86EA19; Thu, 30 Nov 2017 03:09:46 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-yw0-x244.google.com (mail-yw0-x244.google.com [IPv6:2607:f8b0:4002:c05::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 20AE66EA19 for ; Thu, 30 Nov 2017 03:09:44 +0000 (UTC) Received: by mail-yw0-x244.google.com with SMTP id f1so2188957ywd.8 for ; Wed, 29 Nov 2017 19:09:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uEGyBrnqyLd23mwYBxHWweFYCp9bsiunG9qVd4iEUnA=; b=H7sXO3jjz2utxD6REIYw+zZToLtO8IqUZiwEsv2I5cjsaogsEbXGPUYSrnlzzUiBiG 57COyb84tpF/fohjVIG1fNXNKXJ0T5Zvo2LDYJI5DMUmXk1KS8ugDd7l8Q1TbXQ78enu wc55IE5ThvExzcoUbKnp7w5POAOe+yb21lLgw= 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; bh=uEGyBrnqyLd23mwYBxHWweFYCp9bsiunG9qVd4iEUnA=; b=SpP+GcnVe+bs7CI/ovHjx5mA+j0P1TgC3HyKMEg31s7lvBKFWODeIeYOdPjaTuA8/z MY4wiXXRPx00bBeYQwMUUytVnysjT2mYAHK+lZ9waZGNAY6wH3hlZ9nA3X/pZ2K0OxPF 2cWltPezeE3GvTzm/kKn7t6slgJpBJKsQeMZ1sx/UcpJIY6oDXZz0c9C+hNMoISmda9E VqbvMEixUei+46WUlJEm3sXhHWvHQugbp+kGFy1kRGWrkMpmeAqUrGF2MJWL3wMnNXq6 O3W0lmtNOieV6RAZiCgeaALbDYEYRFCu1JHYcStYA7rLYDa13xq1hwJMYi7/rhcv9P6t RvIg== X-Gm-Message-State: AJaThX4TIiDUrgo+U3Kq0N0COlGS42K6yG1yEj3ivp3VgpfdOVKKYfc0 cWMc4TGPawQXtqH6C5jgNcdfglRiMcg= X-Google-Smtp-Source: AGs4zMZEqAdmRdKA/XEf45LB7csg16pD5H34JKgiPf1i5jdN/7Pu2Ykn6rSmMzm8HIFHKml70qOlug== X-Received: by 10.129.166.193 with SMTP id d184mr639243ywh.241.1512011383918; Wed, 29 Nov 2017 19:09:43 -0800 (PST) Received: from rosewood.cam.corp.google.com ([2620:0:1013:11:d3af:69ac:1964:28e8]) by smtp.gmail.com with ESMTPSA id u24sm1460752ywh.84.2017.11.29.19.09.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Nov 2017 19:09:43 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Subject: [RFC PATCH 1/6] drm: Add Content Protection property Date: Wed, 29 Nov 2017 22:08:56 -0500 Message-Id: <20171130030907.26848-2-seanpaul@chromium.org> X-Mailer: git-send-email 2.15.0.531.g2ccb3012c9-goog In-Reply-To: <20171130030907.26848-1-seanpaul@chromium.org> References: <20171130030907.26848-1-seanpaul@chromium.org> Cc: David Airlie , linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Daniel Vetter , linux-arm-kernel@lists.infradead.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a new optional connector property to allow userspace to enable protection over the content it is displaying. This will typically be implemented by the driver using HDCP. The property is a tri-state with the following values: - OFF: Self explanatory, no content protection - DESIRED: Userspace requests that the driver enable protection - ENABLED: Once the driver has authenticated the link, it sets this value The driver is responsible for downgrading ENABLED to DESIRED if the link becomes unprotected. The driver should also maintain the desiredness of protection across hotplug/dpms/suspend. If this looks familiar, I posted [1] this 3 years ago. We have been using this in ChromeOS across exynos, mediatek, and rockchip over that time. Signed-off-by: Sean Paul [1] https://lists.freedesktop.org/archives/dri-devel/2014-December/073336.html --- drivers/gpu/drm/drm_atomic.c | 8 ++++++++ drivers/gpu/drm/drm_connector.c | 43 +++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_sysfs.c | 29 +++++++++++++++++++++++++++ include/drm/drm_connector.h | 16 +++++++++++++++ include/uapi/drm/drm_mode.h | 4 ++++ 5 files changed, 100 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 37445d50816a..2212793eefa6 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1185,6 +1185,12 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, state->picture_aspect_ratio = val; } else if (property == connector->scaling_mode_property) { state->scaling_mode = val; + } else if (property == connector->content_protection_property) { + if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) { + DRM_DEBUG_KMS("only drivers can set CP Enabled\n"); + return -EINVAL; + } + state->content_protection = val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -1264,6 +1270,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->picture_aspect_ratio; } else if (property == connector->scaling_mode_property) { *val = state->scaling_mode; + } else if (property == connector->content_protection_property) { + *val = state->content_protection; } else if (connector->funcs->atomic_get_property) { return connector->funcs->atomic_get_property(connector, state, property, val); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 704fc8934616..de2345a4a125 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -698,6 +698,13 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = { DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, drm_tv_subconnector_enum_list) +static struct drm_prop_enum_list drm_cp_enum_list[] = { + { DRM_MODE_CONTENT_PROTECTION_OFF, "Off" }, + { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" }, + { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" }, +}; +DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list) + /** * DOC: standard connector properties * @@ -1046,6 +1053,42 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, } EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property); +/** + * drm_connector_attach_content_protection_property - attach content protection + * property + * + * @connector: connector to attach CP property on. + * + * This is used to add support for content protection on select connectors. + * Content Protection is intentionally vague to allow for different underlying + * technologies, however it is most implemented by HDCP. + * + * The content protection will be set to &drm_connector_state.content_protection + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_content_protection_property( + struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + prop = drm_property_create_enum(dev, 0, "Content Protection", + drm_cp_enum_list, + ARRAY_SIZE(drm_cp_enum_list)); + if (!prop) + return -ENOMEM; + + drm_object_attach_property(&connector->base, prop, + DRM_MODE_CONTENT_PROTECTION_OFF); + + connector->content_protection_property = prop; + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_content_protection_property); + /** * drm_mode_create_aspect_ratio_property - create aspect ratio property * @dev: DRM device diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 1c5b5ce1fd7f..e8e15756dc59 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -21,6 +21,7 @@ #include #include #include "drm_internal.h" +#include "drm_crtc_internal.h" #define to_drm_minor(d) dev_get_drvdata(d) #define to_drm_connector(d) dev_get_drvdata(d) @@ -229,16 +230,44 @@ static ssize_t modes_show(struct device *device, return written; } +static ssize_t content_protection_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct drm_connector *connector = to_drm_connector(device); + struct drm_device *dev = connector->dev; + struct drm_property *prop; + uint64_t cp; + int ret; + + drm_modeset_lock_all(dev); + + prop = connector->content_protection_property; + if (!prop) { + drm_modeset_unlock_all(dev); + return 0; + } + + ret = drm_object_property_get_value(&connector->base, prop, &cp); + drm_modeset_unlock_all(dev); + if (ret) + return 0; + + return snprintf(buf, PAGE_SIZE, "%s\n", + drm_get_content_protection_name((int)cp)); +} + static DEVICE_ATTR_RW(status); static DEVICE_ATTR_RO(enabled); static DEVICE_ATTR_RO(dpms); static DEVICE_ATTR_RO(modes); +static DEVICE_ATTR_RO(content_protection); static struct attribute *connector_dev_attrs[] = { &dev_attr_status.attr, &dev_attr_enabled.attr, &dev_attr_dpms.attr, &dev_attr_modes.attr, + &dev_attr_content_protection.attr, NULL }; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 1543212b0449..ec6ea3953002 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -375,6 +375,12 @@ struct drm_connector_state { * upscaling, mostly used for built-in panels. */ unsigned int scaling_mode; + + /** + * @content_protection: Connector property to request content + * protection. This is most commonly used for HDCP. + */ + unsigned int content_protection; }; /** @@ -722,6 +728,7 @@ struct drm_cmdline_mode { * @tile_h_size: horizontal size of this tile. * @tile_v_size: vertical size of this tile. * @scaling_mode_property: Optional atomic property to control the upscaling. + * @content_protection_property: Optional property to control content protection * * Each connector may be connected to one or more CRTCs, or may be clonable by * another connector if they can share a CRTC. Each connector also has a specific @@ -812,6 +819,12 @@ struct drm_connector { struct drm_property *scaling_mode_property; + /** + * @content_protection_property: DRM ENUM property for content + * protection + */ + struct drm_property *content_protection_property; + /** * @path_blob_ptr: * @@ -1012,6 +1025,7 @@ const char *drm_get_dvi_i_subconnector_name(int val); const char *drm_get_dvi_i_select_name(int val); const char *drm_get_tv_subconnector_name(int val); const char *drm_get_tv_select_name(int val); +const char *drm_get_content_protection_name(int val); int drm_mode_create_dvi_i_properties(struct drm_device *dev); int drm_mode_create_tv_properties(struct drm_device *dev, @@ -1020,6 +1034,8 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int drm_mode_create_scaling_mode_property(struct drm_device *dev); int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); +int drm_connector_attach_content_protection_property( + struct drm_connector *connector); int drm_mode_create_aspect_ratio_property(struct drm_device *dev); int drm_mode_create_suggested_offset_properties(struct drm_device *dev); diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 5597a87154e5..03f4d22305c2 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -173,6 +173,10 @@ extern "C" { DRM_MODE_REFLECT_X | \ DRM_MODE_REFLECT_Y) +/* Content Protection Flags */ +#define DRM_MODE_CONTENT_PROTECTION_OFF 0 +#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1 +#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2 struct drm_mode_modeinfo { __u32 clock;