From patchwork Tue Sep 18 04:52:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Sripada, Radhakrishna" X-Patchwork-Id: 10603725 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3E1A413AD for ; Tue, 18 Sep 2018 04:50:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D4BB2A351 for ; Tue, 18 Sep 2018 04:50:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1F6FF2A3D2; Tue, 18 Sep 2018 04:50:49 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable 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 A07A72A351 for ; Tue, 18 Sep 2018 04:50:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 235916E0A6; Tue, 18 Sep 2018 04:50:44 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5C0586E092; Tue, 18 Sep 2018 04:50:42 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Sep 2018 21:50:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,388,1531810800"; d="scan'208";a="90995308" Received: from invictus.jf.intel.com ([10.54.75.152]) by fmsmga001.fm.intel.com with ESMTP; 17 Sep 2018 21:50:41 -0700 From: Radhakrishna Sripada To: intel-gfx@lists.freedesktop.org Date: Mon, 17 Sep 2018 21:52:08 -0700 Message-Id: <20180918045209.525-1-radhakrishna.sripada@intel.com> X-Mailer: git-send-email 2.9.3 MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v6 1/2] drm: Add connector property to limit max bpc 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: Daniel Vetter , Kishore Kadiyala , dri-devel@lists.freedesktop.org, Rodrigo Vivi Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP At times 12bpc HDMI cannot be driven due to faulty cables, dongles level shifters etc. To workaround them we may need to drive the output at a lower bpc. Currently the user space does not have a way to limit the bpc. The default bpc to be programmed is decided by the driver and is run against connector limitations. Creating a new connector property "max bpc" in order to limit the bpc. xrandr can make use of this connector property to make sure that bpc does not exceed the configured value. This property can be used by userspace to set the bpc. V2: Initialize max_bpc to satisfy kms_properties V3: Move the property to drm_connector V4: Split drm and i915 components(Ville) V5: Make the property per connector(Ville) V6: Compare the requested bpc to connector bpc(Daniel) Move the attach_property function to core(Ville) Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Kishore Kadiyala Cc: Rodrigo Vivi Cc: Manasi Navare Cc: Stanislav Lisovskiy Signed-off-by: Radhakrishna Sripada --- drivers/gpu/drm/drm_atomic.c | 24 ++++++++++++++++++++++++ drivers/gpu/drm/drm_atomic_helper.c | 4 ++++ drivers/gpu/drm/drm_atomic_uapi.c | 4 ++++ drivers/gpu/drm/drm_connector.c | 34 ++++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 20 ++++++++++++++++++++ 5 files changed, 86 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 7ada75919756..fa9996deb132 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -390,6 +390,7 @@ static int drm_atomic_connector_check(struct drm_connector *connector, { struct drm_crtc_state *crtc_state; struct drm_writeback_job *writeback_job = state->writeback_job; + struct drm_display_info *info = &connector->display_info; if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job) return 0; @@ -400,6 +401,29 @@ static int drm_atomic_connector_check(struct drm_connector *connector, return -EINVAL; } + if (connector->max_bpc_property) { + if (info->bpc != 0 && info->bpc < state->max_requested_bpc) { + /* Don't use an invalid EDID bpc value */ + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] Clamping requested" + " display bpp (was %d) to EDID reported" + "max of %d\n", connector->base.id, + connector->name, + state->max_requested_bpc, info->bpc); + state->max_bpc = info->bpc; + } else if (info->bpc != 0) { + state->max_bpc = state->max_requested_bpc; + } else { + /* Clamp bpc to 8 on screens witout EDID 1.4 */ + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] Clamping requested" + " display bpp (was %d) to default limit" + " of 24\n", connector->base.id, + connector->name, state->max_requested_bpc); + state->max_bpc = 8; + } + } else { + state->max_bpc = info->bpc ? info->bpc : 8; + } + if (state->crtc) crtc_state = drm_atomic_get_existing_crtc_state(state->state, state->crtc); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 3cf1aa132778..d9ce8077fb6a 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -639,6 +639,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, if (old_connector_state->link_status != new_connector_state->link_status) new_crtc_state->connectors_changed = true; + + if (old_connector_state->max_requested_bpc != + new_connector_state->max_requested_bpc) + new_crtc_state->connectors_changed = true; } if (funcs->atomic_check) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index d5b7f315098c..86ac33922b09 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -740,6 +740,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, return set_out_fence_for_connector(state->state, connector, fence_ptr); + } else if (property == connector->max_bpc_property) { + state->max_requested_bpc = val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -804,6 +806,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = 0; } else if (property == config->writeback_out_fence_ptr_property) { *val = 0; + } else if (property == connector->max_bpc_property) { + *val = state->max_requested_bpc; } 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 1e40e5decbe9..06ad59222e03 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1583,6 +1583,40 @@ void drm_connector_set_link_status_property(struct drm_connector *connector, EXPORT_SYMBOL(drm_connector_set_link_status_property); /** + * drm_connector_attach_max_bpc_property - attach "max bpc" property + * @connector: connector to attach max bpc property on. + * @min: The minimum bit depth supported by the connector. + * @max: The maximum bit depth supported by the connector. + * + * This is used to add support for limiting the bit depth on a connector. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_max_bpc_property(struct drm_connector *connector, int + min, int max) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + prop = connector->max_bpc_property; + if (prop == NULL) { + prop = drm_property_create_range(dev, 0, "max bpc", min, max); + if (!prop) + return -ENOMEM; + + connector->max_bpc_property = prop; + } + + drm_object_attach_property(&connector->base, prop, max); + connector->state->max_requested_bpc = max; + + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_max_bpc_property); + +/** * drm_connector_init_panel_orientation_property - * initialize the connecters panel_orientation property * @connector: connector for which to init the panel-orientation property. diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 91a877fa00cb..d9c60fde5372 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -461,6 +461,18 @@ struct drm_connector_state { * drm_writeback_signal_completion() */ struct drm_writeback_job *writeback_job; + + /** + * @max_requested_bpc: Connector property to limit the maximum bit + * depth of the pixels. + */ + unsigned int max_requested_bpc; + + /** + * @max_bpc: Connector max_bpc based on the requested max_bpc property + * and the connector bpc limitations obtained from edid. + */ + unsigned int max_bpc; }; /** @@ -924,6 +936,12 @@ struct drm_connector { */ struct drm_property_blob *path_blob_ptr; + /** + * @max_bpc_property: Default connector property for the max bpc to be + * driven out of the connector. + */ + struct drm_property *max_bpc_property; + #define DRM_CONNECTOR_POLL_HPD (1 << 0) #define DRM_CONNECTOR_POLL_CONNECT (1 << 1) #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) @@ -1201,6 +1219,8 @@ void drm_connector_set_link_status_property(struct drm_connector *connector, uint64_t link_status); int drm_connector_init_panel_orientation_property( struct drm_connector *connector, int width, int height); +int drm_connector_attach_max_bpc_property(struct drm_connector *connector, + int min, int max); /** * struct drm_tile_group - Tile group metadata