From patchwork Mon Sep 3 16:54:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586137 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 CFEDE175A for ; Mon, 3 Sep 2018 16:54:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE41528A73 for ; Mon, 3 Sep 2018 16:54:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B03B728ED8; Mon, 3 Sep 2018 16:54:51 +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=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 947C528A73 for ; Mon, 3 Sep 2018 16:54:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1B8816E29D; Mon, 3 Sep 2018 16:54:50 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x543.google.com (mail-ed1-x543.google.com [IPv6:2a00:1450:4864:20::543]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9322A6E298 for ; Mon, 3 Sep 2018 16:54:48 +0000 (UTC) Received: by mail-ed1-x543.google.com with SMTP id s10-v6so1221907edb.11 for ; Mon, 03 Sep 2018 09:54:48 -0700 (PDT) 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; bh=fd5ZyTNcUhVVLcMoBqZFpYcD97z9jtd6evAOzLwXV6M=; b=I6BXKE1umCnYpPri21dFVJTdSRX3LcQkrD433h9QGW+Bj97Tr7MYxv0OwqQKrv3QZA e69mrhPlnrAH9b90tszgoJvlLJc4bs3bqw3Kex40vTmadClAlufGG77GOa/s29KivPYU si7iTT5OIiDzFpVEcQOYyIsyIj9oAkTGMsLHr6PFnSvWg5mP/0YD9Zw6KhIjAoH4YJb6 YWfyNu6SxyoEBbiNAP795a/zTXenbzxoyjYn7WEwiPtbXz+iQTGWXp2OUMGpmuAdo07q 7c0Phq4UM4HTWPBhN/yPWjx9Dygy4pfnprq5C78EJf42SSV6BQs9bZsqzhfKrD+r59vu BH2Q== X-Gm-Message-State: APzg51DZ+e3bS1rZ6OCiYgJ32Ggo21IXei9iiEpWTgGa9LeHEXmpu9QL h63xxXDKC40qfv5KNsTxWKeF6A== X-Google-Smtp-Source: ANB0VdZvj58gyao+r0lZG0oJP7iqYAYXD4AG8ToqRhbTaxwm9JvYX/wGPUgCDuP69yw9Lqdfsmctmg== X-Received: by 2002:a50:ca83:: with SMTP id x3-v6mr3202415edh.287.1535993687266; Mon, 03 Sep 2018 09:54:47 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:46 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:26 +0200 Message-Id: <20180903165439.24845-1-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 Subject: [Intel-gfx] [PATCH 01/14] drm: Add drm/kernel.h header file 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 , Intel Graphics Development , Sean Paul MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP We have a bunch of neat little macros all over the place which should move to kernel.h. But some of them died in bikesheds on lkml, and we need a decent home for them. Start out by moving the for_each_if macro there. Cc: Sean Paul Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.h | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_connector.h | 2 ++ include/drm/drmP.h | 3 -- include/drm/drm_atomic.h | 1 + include/drm/drm_atomic_helper.h | 1 + include/drm/drm_connector.h | 1 + include/drm/drm_encoder.h | 1 + include/drm/drm_plane.h | 1 + include/drm/kernel.h | 32 +++++++++++++++++++++ 11 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 include/drm/kernel.h diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 14e562887307..63cd53067cc3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -52,6 +52,7 @@ #include #include #include +#include #include "i915_params.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h index e20e6a36a748..bb6e8d949ebb 100644 --- a/drivers/gpu/drm/i915/intel_display.h +++ b/drivers/gpu/drm/i915/intel_display.h @@ -25,6 +25,8 @@ #ifndef _INTEL_DISPLAY_H_ #define _INTEL_DISPLAY_H_ +#include + enum i915_gpio { GPIOA, GPIOB, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3f6920dd7880..c06ec8078313 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -2,6 +2,8 @@ #ifndef _INTEL_RINGBUFFER_H_ #define _INTEL_RINGBUFFER_H_ +#include + #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index dc7454e7f19a..fff89cb4a792 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -32,6 +32,8 @@ #include #include #include +#include + #include "nouveau_crtc.h" #include "nouveau_encoder.h" diff --git a/include/drm/drmP.h b/include/drm/drmP.h index f7a19c2a7a80..05350424a4d3 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -110,7 +110,4 @@ static inline bool drm_can_sleep(void) return true; } -/* helper for handling conditionals in various for_each macros */ -#define for_each_if(condition) if (!(condition)) {} else - #endif diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index da9d95a19580..07b4cb1c9603 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -29,6 +29,7 @@ #define DRM_ATOMIC_H_ #include +#include /** * struct drm_crtc_commit - track modeset commits on a CRTC diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index f4c7ed876c97..63e736eeb516 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -31,6 +31,7 @@ #include #include #include +#include struct drm_atomic_state; struct drm_private_obj; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 97ea41dc678f..95be147ee4db 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -28,6 +28,7 @@ #include #include #include +#include #include diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 4f597c0730b4..9cb01c764fac 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -28,6 +28,7 @@ #include #include #include +#include struct drm_encoder; diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 16f5b66684ca..2af3f0a7d2e7 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -27,6 +27,7 @@ #include #include #include +#include struct drm_crtc; struct drm_printer; diff --git a/include/drm/kernel.h b/include/drm/kernel.h new file mode 100644 index 000000000000..6ea220c0c132 --- /dev/null +++ b/include/drm/kernel.h @@ -0,0 +1,32 @@ +/* + * Internal Header for the Direct Rendering Manager + * + * Copyright 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_KERNEL_H_ +#define _DRM_KERNEL_H_ + +/* helper for handling conditionals in various for_each macros */ +#define for_each_if(condition) if (!(condition)) {} else + +#endif From patchwork Mon Sep 3 16:54:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586141 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 063D55A4 for ; Mon, 3 Sep 2018 16:54:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E9AF228A73 for ; Mon, 3 Sep 2018 16:54:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DE2F128ED8; Mon, 3 Sep 2018 16:54:55 +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=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 8F85828A73 for ; Mon, 3 Sep 2018 16:54:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 72C2B6E2A0; Mon, 3 Sep 2018 16:54:51 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by gabe.freedesktop.org (Postfix) with ESMTPS id C1CD76E298 for ; Mon, 3 Sep 2018 16:54:49 +0000 (UTC) Received: by mail-ed1-x541.google.com with SMTP id z27-v6so1225199edb.10 for ; Mon, 03 Sep 2018 09:54:49 -0700 (PDT) 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=zjC+MRVWMbDQcv4QGOft87xqMW/4Rrp2dQaTPPe/59o=; b=Ma8m/jcuN5mHu6bDkGog63shrzXp+WN72nrEpsRlllwBwxrlS8OBzamUHPelHQ6ryz nItQKnd488Vinpgs66zhl0HtAQIf4P0GR7DqscxTWX6LV9WAyfxTlDJgpVX97lZDdjH4 K68Dgl3tObHblOHnnpggYzcKU7ZcyIaEVOhCODxDBAv+YhsM9wYvClN9DLJ+iO5T3dJQ ZoqZca4EFO1giyYD/9ZdYLGdPdRPIq00iUdDRiR5b/OuVdzof5IpCewjchNCyqm6+boL mmMxB9cyaXUmBx2d4VbgwSfnOohGGgSmFCgphuBew+z92RfKqlXMLvmuFIKsNAaujpxZ YCYg== X-Gm-Message-State: APzg51Bp5MT5goLLH0cAjSODpB8mcJvjB/iAtu3NjOrdDhOIWy4jGsTP ztg/24kidckY40HaAIKomspRhg== X-Google-Smtp-Source: ANB0VdZnfPxu6HnZYQn5ME73TjE95w/53MKmLBjkhkIDTzuDGTQqq7oAE1WOEgOPfFR3o/tjCPnOQA== X-Received: by 2002:a50:9034:: with SMTP id b49-v6mr34261415eda.174.1535993688489; Mon, 03 Sep 2018 09:54:48 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:47 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:27 +0200 Message-Id: <20180903165439.24845-2-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 02/14] drm: Drop drmP.h from drm_connector.c 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 , Intel Graphics Development , Daniel Vetter MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Only needed minimal changes in drm_internal.h (for the drm_ioctl_t type and a few forward declarations), plus a few missing includes in drm_connector.c. Yay, the last stage of the drm header cleanup can finally commence! v2: Compiles now, with drm/kernel.h extracted. Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_connector.c | 6 +++++- drivers/gpu/drm/drm_internal.h | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 6011d769d50b..526619f963e5 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -20,11 +20,15 @@ * OF THIS SOFTWARE. */ -#include #include #include #include #include +#include +#include +#include + +#include #include "drm_crtc_internal.h" #include "drm_internal.h" diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 40179c5fc6b8..0c4eb4a9ab31 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -21,9 +21,14 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include + #define DRM_IF_MAJOR 1 #define DRM_IF_MINOR 4 +struct drm_prime_file_private; +struct dma_buf; + /* drm_file.c */ extern struct mutex drm_global_mutex; struct drm_file *drm_file_alloc(struct drm_minor *minor); From patchwork Mon Sep 3 16:54:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586147 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 67635139B for ; Mon, 3 Sep 2018 16:55:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 558EE28CDB for ; Mon, 3 Sep 2018 16:55:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 48A3528ED8; Mon, 3 Sep 2018 16:55:01 +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=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 EAE6128A73 for ; Mon, 3 Sep 2018 16:55:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B45126E2A3; Mon, 3 Sep 2018 16:54:53 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by gabe.freedesktop.org (Postfix) with ESMTPS id 200606E299 for ; Mon, 3 Sep 2018 16:54:51 +0000 (UTC) Received: by mail-ed1-x542.google.com with SMTP id y20-v6so1259819edq.2 for ; Mon, 03 Sep 2018 09:54:51 -0700 (PDT) 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=rlGultffMh8AirwZjlTbPqTYcfIuIF/cJWo2cKU+2JU=; b=RpeaEJ8gw191lQlz5eWYt3y86x2yusFRXqelFUAkfF4255WUYR1yLNW4sGzWisyi8X 5BhdMWq8/GpmN/steRcqwNGCjuFjsKvtd8gkqtxJkSmeLk61KywPyFBux7dZsnBowasc dpWUiPMhKWqLKLPkGQI5B1fsRsTPTyTw3hYiNu6igOKSqmVnWOboJ36bcdbYwdwVp2Ov 7OOKqaOjrU/XgM6XENKfJeWqvvxYphfSWkGgvw+yUwkH7FQwEqHZZOIkb8JYhrJF1m1Q q8BAXUaNmMSLZdQvT2Ztc/IEh15sSYkJCrCIV0cmd/rM4DB10FXCYbS6OnjDLeBIsPK7 Aa7Q== X-Gm-Message-State: APzg51DeHmyLzhPK2qSBksELY9o2y6WTghiIK3JMb0QAfbvAVgonRFUP 2HnWYCdYbhpxUFN8cm45NZKhuw== X-Google-Smtp-Source: ANB0VdbR35NDoyYalXDxB4FouMtUnvD7Ga0k9VI83ifZjjsivYR2OCG02QqcPqT43L93QeclLWqc5g== X-Received: by 2002:a50:ce5e:: with SMTP id k30-v6mr32109980edj.207.1535993689787; Mon, 03 Sep 2018 09:54:49 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:49 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:28 +0200 Message-Id: <20180903165439.24845-3-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 03/14] drm: drop drmP.h include from drm_plane.c 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 , Intel Graphics Development , Daniel Vetter MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Just a bit of missing includes and pre declarations. v2: Compiles now, with drm/kernel.h extracted. Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_internal.h | 8 ++++++++ drivers/gpu/drm/drm_plane.c | 11 ++++++++++- include/drm/drm_color_mgmt.h | 1 + include/drm/drm_plane.h | 2 ++ include/drm/drm_property.h | 2 ++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index b61322763394..ff5e0d521c21 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -31,6 +31,14 @@ * and are not exported to drivers. */ +enum drm_mode_status; +enum drm_connector_force; + +struct drm_display_mode; +struct work_struct; +struct drm_connector; +struct drm_bridge; +struct edid; /* drm_crtc.c */ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 6153cbda239f..36bf3fe9ad21 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -20,8 +20,17 @@ * OF THIS SOFTWARE. */ -#include +#include +#include + #include +#include +#include +#include +#include +#include +#include +#include #include "drm_crtc_internal.h" diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 44f04233e3db..90ef9996d9a4 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -24,6 +24,7 @@ #define __DRM_COLOR_MGMT_H__ #include +#include struct drm_crtc; struct drm_plane; diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 2af3f0a7d2e7..fe6c4aee2d08 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include struct drm_crtc; diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h index c030f6ccab99..5b9efff35d6d 100644 --- a/include/drm/drm_property.h +++ b/include/drm/drm_property.h @@ -27,6 +27,8 @@ #include #include +#include + /** * struct drm_property_enum - symbolic values for enumerations * @value: numeric property value for this enum entry From patchwork Mon Sep 3 16:54:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586145 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 1CAE4139B for ; Mon, 3 Sep 2018 16:55:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0BC4928A73 for ; Mon, 3 Sep 2018 16:55:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F3A7F28ED8; Mon, 3 Sep 2018 16:54:59 +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=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 B818D28A73 for ; Mon, 3 Sep 2018 16:54:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 85DFC6E2A2; Mon, 3 Sep 2018 16:54:53 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5C1146E299 for ; Mon, 3 Sep 2018 16:54:52 +0000 (UTC) Received: by mail-ed1-x52f.google.com with SMTP id l5so1231097edw.9 for ; Mon, 03 Sep 2018 09:54:52 -0700 (PDT) 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=445dYZzlFz2Vczf09o2qHej/GJ8WzP71OvXY5JZxyA0=; b=D3cK1+HDQpb5Hh3ZvwRDEjSCBZn9THAm/Kym6/5IyGvVIHyFjlxVyOsQ7lrFvTlfNo zqnhG8h1nQ1AyCGQUFA+x2NNRtT9dnGt0bNVc+F8woERuCFEluUN9HjT23Ex7BIL4Jg/ EKe+8xa+ditoN2xxDTh8IQWAItQJetV/jHs2OdRIT7dj67UpoRhNfYzHC7fiUZLeqMX0 HrttB77RAMf4jNOO+prTW+VZKw5v/p2Zob711hKBaSclEB8oWTLiKgqMW8GslY+/fqGM DF6BnnV2u5Og90Yde3POJ3EkmIp4OtIr9pc9i8qTaCgfSRaDdigHPHlZtggZNnjnqMw2 VBJA== X-Gm-Message-State: APzg51CghYC0hETAjhuU2o+LvUI3FmRWeAcv+0WDyKGNJ20GfZaP9GbS s6fC2/hAN1KgbIDpFlJ4RBrWPg== X-Google-Smtp-Source: ANB0VdZOt4qPiBAdk5ZcFBtbZ5tGx0MsEVF6I0iRytpv82FeAhpLcN6E16p6rpFaVKV4cJgXh8H3Rg== X-Received: by 2002:a50:a0a6:: with SMTP id 35-v6mr33559960edo.280.1535993691044; Mon, 03 Sep 2018 09:54:51 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:50 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:29 +0200 Message-Id: <20180903165439.24845-4-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 04/14] drm: drop drmP.h include from drm_crtc.c 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 , Intel Graphics Development , Daniel Vetter MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP This is starting to become easy! v2: Compiles now, with drm/kernel.h extracted. Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index bae43938c8f6..2f6c877299e4 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include #include "drm_crtc_internal.h" #include "drm_internal.h" From patchwork Mon Sep 3 16:54:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586149 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 6353D5A4 for ; Mon, 3 Sep 2018 16:55:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5249328A73 for ; Mon, 3 Sep 2018 16:55:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 466D928CDB; Mon, 3 Sep 2018 16:55:03 +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=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 749EF28FF3 for ; Mon, 3 Sep 2018 16:55:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 760866E2A4; Mon, 3 Sep 2018 16:54:55 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by gabe.freedesktop.org (Postfix) with ESMTPS id D37306E2A4 for ; Mon, 3 Sep 2018 16:54:53 +0000 (UTC) Received: by mail-ed1-x541.google.com with SMTP id j62-v6so1239654edd.7 for ; Mon, 03 Sep 2018 09:54:53 -0700 (PDT) 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=5s+ErqNHGSsCZlpL8MVS1jfCgi9CO+OMacaZZtZ8HN4=; b=WKO/KMuW03+UNHd42XefAKcwaSDJ6EGPiR5tBfFdLbOqGP68t0qdDOKUPEX9Q4CBUV 3/UxUoJ0JNh3XSI12pNMkNhhGSSbv+OZXIk77Lg8mCSx4XuC/xxU7lF73gbM5gGwXX8j z5Gb99hh5+GiKnMusTc4YKhxCsmma37F/gTBLBy8pOg1II5Oh4s+FfxubndFEjMXoRBH hHlgBXpMsoJqdH1CCzRdSz9UbeVUSNIxxKyKM7aXkPIFLhJ8sBPJYzuhfgubfuQ4uCtk id6/dK6Y/K95gFAg5IEQ2DENbTCUeReKg1hm2LhYdMTgfjhGyr7iSV2g9QtNjM/BMszN rb+Q== X-Gm-Message-State: APzg51CT+okXd34CPrQDX7jtYZH25CNMVcFQn5YBOjSNs5N7T0qAhIXj 1QgtdLZpmLOrpTv1VTGz6NB27w== X-Google-Smtp-Source: ANB0VdaS1x3OFFYYYxWVh6rERX66E2ry9WL3xnJhsluC2J8nv5Ec4G7hCShPYDZUqF7M7Ei8VUG1nQ== X-Received: by 2002:a50:b410:: with SMTP id b16-v6mr33336556edh.190.1535993692496; Mon, 03 Sep 2018 09:54:52 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:51 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:30 +0200 Message-Id: <20180903165439.24845-5-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 05/14] drm/atomic: trim driver interface/docs 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 , Daniel Vetter , Intel Graphics Development , Sean Paul , Daniel Vetter MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Remove the kerneldoc and EXPORT_SYMBOL which aren't used and really shouldn't ever be used by drivers directly. Unfortunately this means we need to move the set_writeback_fb function around to avoid a forward decl. Signed-off-by: Daniel Vetter Cc: David Airlie Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul --- Documentation/gpu/drm-kms.rst | 3 - drivers/gpu/drm/drm_atomic.c | 219 ++++++---------------------------- include/drm/drm_atomic.h | 6 - 3 files changed, 34 insertions(+), 194 deletions(-) diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index f8f5bf11a6ca..3a9dd68b97c9 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -287,9 +287,6 @@ Atomic Mode Setting Function Reference .. kernel-doc:: drivers/gpu/drm/drm_atomic.c :export: -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c - :internal: - CRTC Abstraction ================ diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 151dd7162b3a..29a4e6959358 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -464,30 +464,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, } EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); -/** - * drm_atomic_replace_property_blob_from_id - lookup the new blob and replace the old one with it - * @dev: DRM device - * @blob: a pointer to the member blob to be replaced - * @blob_id: ID of the new blob - * @expected_size: total expected size of the blob data (in bytes) - * @expected_elem_size: expected element size of the blob data (in bytes) - * @replaced: did the blob get replaced? - * - * Replace @blob with another blob with the ID @blob_id. If @blob_id is zero - * @blob becomes NULL. - * - * If @expected_size is positive the new blob length is expected to be equal - * to @expected_size bytes. If @expected_elem_size is positive the new blob - * length is expected to be a multiple of @expected_elem_size bytes. Otherwise - * an error is returned. - * - * @replaced will indicate to the caller whether the blob was replaced or not. - * If the old and new blobs were in fact the same blob @replaced will be false - * otherwise it will be true. - * - * RETURNS: - * Zero on success, error code on failure. - */ static int drm_atomic_replace_property_blob_from_id(struct drm_device *dev, struct drm_property_blob **blob, @@ -521,22 +497,7 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev, return 0; } -/** - * drm_atomic_crtc_set_property - set property on CRTC - * @crtc: the drm CRTC to set a property on - * @state: the state object to update with the new property value - * @property: the property to set - * @val: the new property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_crtc_funcs.atomic_set_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ -int drm_atomic_crtc_set_property(struct drm_crtc *crtc, +static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, struct drm_crtc_state *state, struct drm_property *property, uint64_t val) { @@ -598,23 +559,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, return 0; } -EXPORT_SYMBOL(drm_atomic_crtc_set_property); -/** - * drm_atomic_crtc_get_property - get property value from CRTC state - * @crtc: the drm CRTC to set a property on - * @state: the state object to get the property value from - * @property: the property to set - * @val: return location for the property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_crtc_funcs.atomic_get_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_crtc_get_property(struct drm_crtc *crtc, const struct drm_crtc_state *state, @@ -643,16 +588,6 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, return 0; } -/** - * drm_atomic_crtc_check - check crtc state - * @crtc: crtc to check - * @state: crtc state to check - * - * Provides core sanity checks for crtc state. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -728,16 +663,6 @@ static void drm_atomic_crtc_print_state(struct drm_printer *p, crtc->funcs->atomic_print_state(p, state); } -/** - * drm_atomic_connector_check - check connector state - * @connector: connector to check - * @state: connector state to check - * - * Provides core sanity checks for connector state. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_connector_check(struct drm_connector *connector, struct drm_connector_state *state) { @@ -923,21 +848,6 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, return 0; } -/** - * drm_atomic_plane_get_property - get property value from plane state - * @plane: the drm plane to set a property on - * @state: the state object to get the property value from - * @property: the property to set - * @val: return location for the property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_plane_funcs.atomic_get_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_plane_get_property(struct drm_plane *plane, const struct drm_plane_state *state, @@ -1328,21 +1238,39 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_connector_state); -/** - * drm_atomic_connector_set_property - set property on connector. - * @connector: the drm connector to set a property on - * @state: the state object to update with the new property value - * @property: the property to set - * @val: the new property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_connector_funcs.atomic_set_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ +static struct drm_writeback_job * +drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) +{ + WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); + + if (!conn_state->writeback_job) + conn_state->writeback_job = + kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); + + return conn_state->writeback_job; +} + +static int drm_atomic_set_writeback_fb_for_connector( + struct drm_connector_state *conn_state, + struct drm_framebuffer *fb) +{ + struct drm_writeback_job *job = + drm_atomic_get_writeback_job(conn_state); + if (!job) + return -ENOMEM; + + drm_framebuffer_assign(&job->fb, fb); + + if (fb) + DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", + fb->base.id, conn_state); + else + DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", + conn_state); + + return 0; +} + static int drm_atomic_connector_set_property(struct drm_connector *connector, struct drm_connector_state *state, struct drm_property *property, uint64_t val) @@ -1449,21 +1377,6 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, connector->funcs->atomic_print_state(p, state); } -/** - * drm_atomic_connector_get_property - get property value from connector state - * @connector: the drm connector to set a property on - * @state: the state object to get the property value from - * @property: the property to set - * @val: return location for the property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_connector_funcs.atomic_get_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ static int drm_atomic_connector_get_property(struct drm_connector *connector, const struct drm_connector_state *state, @@ -1739,70 +1652,6 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, } EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector); -/* - * drm_atomic_get_writeback_job - return or allocate a writeback job - * @conn_state: Connector state to get the job for - * - * Writeback jobs have a different lifetime to the atomic state they are - * associated with. This convenience function takes care of allocating a job - * if there isn't yet one associated with the connector state, otherwise - * it just returns the existing job. - * - * Returns: The writeback job for the given connector state - */ -static struct drm_writeback_job * -drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) -{ - WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); - - if (!conn_state->writeback_job) - conn_state->writeback_job = - kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); - - return conn_state->writeback_job; -} - -/** - * drm_atomic_set_writeback_fb_for_connector - set writeback framebuffer - * @conn_state: atomic state object for the connector - * @fb: fb to use for the connector - * - * This is used to set the framebuffer for a writeback connector, which outputs - * to a buffer instead of an actual physical connector. - * Changing the assigned framebuffer requires us to grab a reference to the new - * fb and drop the reference to the old fb, if there is one. This function - * takes care of all these details besides updating the pointer in the - * state object itself. - * - * Note: The only way conn_state can already have an fb set is if the commit - * sets the property more than once. - * - * See also: drm_writeback_connector_init() - * - * Returns: 0 on success - */ -int drm_atomic_set_writeback_fb_for_connector( - struct drm_connector_state *conn_state, - struct drm_framebuffer *fb) -{ - struct drm_writeback_job *job = - drm_atomic_get_writeback_job(conn_state); - if (!job) - return -ENOMEM; - - drm_framebuffer_assign(&job->fb, fb); - - if (fb) - DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", - fb->base.id, conn_state); - else - DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", - conn_state); - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_writeback_fb_for_connector); - /** * drm_atomic_add_affected_connectors - add connectors for crtc * @state: atomic state diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 07b4cb1c9603..66e49ef7d3b5 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -374,9 +374,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state); struct drm_crtc_state * __must_check drm_atomic_get_crtc_state(struct drm_atomic_state *state, struct drm_crtc *crtc); -int drm_atomic_crtc_set_property(struct drm_crtc *crtc, - struct drm_crtc_state *state, struct drm_property *property, - uint64_t val); struct drm_plane_state * __must_check drm_atomic_get_plane_state(struct drm_atomic_state *state, struct drm_plane *plane); @@ -603,9 +600,6 @@ void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, int __must_check drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, struct drm_crtc *crtc); -int drm_atomic_set_writeback_fb_for_connector( - struct drm_connector_state *conn_state, - struct drm_framebuffer *fb); int __must_check drm_atomic_add_affected_connectors(struct drm_atomic_state *state, struct drm_crtc *crtc); From patchwork Mon Sep 3 16:54:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586161 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 99E2C5A4 for ; Mon, 3 Sep 2018 16:55:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7EF7928A73 for ; Mon, 3 Sep 2018 16:55:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7208328FE6; Mon, 3 Sep 2018 16:55:29 +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=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 0C54828A73 for ; Mon, 3 Sep 2018 16:55:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 73FF16E2A9; Mon, 3 Sep 2018 16:54:59 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x543.google.com (mail-ed1-x543.google.com [IPv6:2a00:1450:4864:20::543]) by gabe.freedesktop.org (Postfix) with ESMTPS id A0D8D6E2A9 for ; Mon, 3 Sep 2018 16:54:56 +0000 (UTC) Received: by mail-ed1-x543.google.com with SMTP id s10-v6so1222138edb.11 for ; Mon, 03 Sep 2018 09:54:56 -0700 (PDT) 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=EK6KoCDltHnlSY7AnG7I6r7LDDqZGNxEYkAiFyT9YUM=; b=oTnebbq/8HG62UAfNqTii9f31zV9tChSeznKItLfeTyy6x3apKuo6/uyWKwI0p2qk1 Uvf7xAeoSt1TiONoS2EE0xVmC3woNzXLW8eYYF9jCyO8zdOQjMK6KIekmo7/hXlb00Y8 VCR7PhU0V1T1rf6fnXtjirwh1nnsmQYOD4J/Zz8wCHAlPeZTz0nyQM9we8qKy4dKoM6w eIchWbh1a9ZJcUhLNr9l2X2dsJVPSpNJdgnca37Hx9FBK7YbRc8XMEqpyZbXTisv6x/2 s3jjSSyX7GwqbIV6xWyswfMI0O402cy2VJ7KQmkt7DijLuof+pMRRZB4sYHDbPrt/ij0 oJEA== X-Gm-Message-State: APzg51BcO29PyLXAx1YBh2rDaxfacvIy29xPlU1bdc94yOlli5KJJDp8 JKZisJ4a576GXURNTGGscTbBNw== X-Google-Smtp-Source: ANB0VdYUJs4PUeJlm/co6+TrZp9ziTFxyND4H6L80/nPTXRsa3sVTzrAfrpTrhI5HY7T95QVHyen6w== X-Received: by 2002:a50:a844:: with SMTP id j62-v6mr32955426edc.210.1535993694830; Mon, 03 Sep 2018 09:54:54 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:53 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:31 +0200 Message-Id: <20180903165439.24845-6-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 06/14] drm: extract drm_atomic_uapi.c 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 , Daniel Vetter , Intel Graphics Development , Rodrigo Vivi , Sean Paul , Daniel Vetter , freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP This leaves all the commit/check and state handling in drm_atomic.c, while pulling all the uapi glue and the huge ioctl itself into a seprate file. This seems to almost perfectly split the rather big drm_atomic.c file into 2 equal sizes. Also adjust the kerneldoc and type a very terse overview text. v2: Rebase. v3: Fix tiny typo. Signed-off-by: Daniel Vetter Cc: David Airlie Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Rob Clark Cc: Eric Anholt Cc: intel-gfx@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Acked-by: Rodrigo Vivi --- Documentation/gpu/drm-kms.rst | 11 +- drivers/gpu/drm/Makefile | 3 +- drivers/gpu/drm/drm_atomic.c | 1359 +---------------- drivers/gpu/drm/drm_atomic_helper.c | 1 + drivers/gpu/drm/drm_atomic_uapi.c | 1393 ++++++++++++++++++ drivers/gpu/drm/drm_crtc_helper.c | 1 + drivers/gpu/drm/drm_crtc_internal.h | 5 + drivers/gpu/drm/drm_framebuffer.c | 1 + drivers/gpu/drm/drm_gem_framebuffer_helper.c | 1 + drivers/gpu/drm/drm_plane_helper.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/msm/msm_atomic.c | 2 + drivers/gpu/drm/vc4/vc4_crtc.c | 1 + drivers/gpu/drm/vc4/vc4_plane.c | 1 + include/drm/drm_atomic.h | 16 - include/drm/drm_atomic_uapi.h | 58 + 16 files changed, 1480 insertions(+), 1375 deletions(-) create mode 100644 drivers/gpu/drm/drm_atomic_uapi.c create mode 100644 include/drm/drm_atomic_uapi.h diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 3a9dd68b97c9..4b1501b4835b 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -287,6 +287,15 @@ Atomic Mode Setting Function Reference .. kernel-doc:: drivers/gpu/drm/drm_atomic.c :export: +Atomic Mode Setting IOCTL and UAPI Functions +-------------------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c + :export: + CRTC Abstraction ================ @@ -563,7 +572,7 @@ Tile Group Property Explicit Fencing Properties --------------------------- -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c +.. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c :doc: explicit fencing properties Existing KMS Properties diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index a6771cef85e2..bc6a16a3c36e 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -18,7 +18,8 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_encoder.o drm_mode_object.o drm_property.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ - drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o + drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ + drm_atomic_uapi.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 29a4e6959358..19634e03b78e 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -309,285 +310,6 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_crtc_state); -static void set_out_fence_for_crtc(struct drm_atomic_state *state, - struct drm_crtc *crtc, s32 __user *fence_ptr) -{ - state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = fence_ptr; -} - -static s32 __user *get_out_fence_for_crtc(struct drm_atomic_state *state, - struct drm_crtc *crtc) -{ - s32 __user *fence_ptr; - - fence_ptr = state->crtcs[drm_crtc_index(crtc)].out_fence_ptr; - state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = NULL; - - return fence_ptr; -} - -static int set_out_fence_for_connector(struct drm_atomic_state *state, - struct drm_connector *connector, - s32 __user *fence_ptr) -{ - unsigned int index = drm_connector_index(connector); - - if (!fence_ptr) - return 0; - - if (put_user(-1, fence_ptr)) - return -EFAULT; - - state->connectors[index].out_fence_ptr = fence_ptr; - - return 0; -} - -static s32 __user *get_out_fence_for_connector(struct drm_atomic_state *state, - struct drm_connector *connector) -{ - unsigned int index = drm_connector_index(connector); - s32 __user *fence_ptr; - - fence_ptr = state->connectors[index].out_fence_ptr; - state->connectors[index].out_fence_ptr = NULL; - - return fence_ptr; -} - -/** - * drm_atomic_set_mode_for_crtc - set mode for CRTC - * @state: the CRTC whose incoming state to update - * @mode: kernel-internal mode to use for the CRTC, or NULL to disable - * - * Set a mode (originating from the kernel) on the desired CRTC state and update - * the enable property. - * - * RETURNS: - * Zero on success, error code on failure. Cannot return -EDEADLK. - */ -int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, - const struct drm_display_mode *mode) -{ - struct drm_crtc *crtc = state->crtc; - struct drm_mode_modeinfo umode; - - /* Early return for no change. */ - if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) - return 0; - - drm_property_blob_put(state->mode_blob); - state->mode_blob = NULL; - - if (mode) { - drm_mode_convert_to_umode(&umode, mode); - state->mode_blob = - drm_property_create_blob(state->crtc->dev, - sizeof(umode), - &umode); - if (IS_ERR(state->mode_blob)) - return PTR_ERR(state->mode_blob); - - drm_mode_copy(&state->mode, mode); - state->enable = true; - DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", - mode->name, crtc->base.id, crtc->name, state); - } else { - memset(&state->mode, 0, sizeof(state->mode)); - state->enable = false; - DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", - crtc->base.id, crtc->name, state); - } - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc); - -/** - * drm_atomic_set_mode_prop_for_crtc - set mode for CRTC - * @state: the CRTC whose incoming state to update - * @blob: pointer to blob property to use for mode - * - * Set a mode (originating from a blob property) on the desired CRTC state. - * This function will take a reference on the blob property for the CRTC state, - * and release the reference held on the state's existing mode property, if any - * was set. - * - * RETURNS: - * Zero on success, error code on failure. Cannot return -EDEADLK. - */ -int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, - struct drm_property_blob *blob) -{ - struct drm_crtc *crtc = state->crtc; - - if (blob == state->mode_blob) - return 0; - - drm_property_blob_put(state->mode_blob); - state->mode_blob = NULL; - - memset(&state->mode, 0, sizeof(state->mode)); - - if (blob) { - int ret; - - if (blob->length != sizeof(struct drm_mode_modeinfo)) { - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] bad mode blob length: %zu\n", - crtc->base.id, crtc->name, - blob->length); - return -EINVAL; - } - - ret = drm_mode_convert_umode(crtc->dev, - &state->mode, blob->data); - if (ret) { - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] invalid mode (ret=%d, status=%s):\n", - crtc->base.id, crtc->name, - ret, drm_get_mode_status_name(state->mode.status)); - drm_mode_debug_printmodeline(&state->mode); - return -EINVAL; - } - - state->mode_blob = drm_property_blob_get(blob); - state->enable = true; - DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", - state->mode.name, crtc->base.id, crtc->name, - state); - } else { - state->enable = false; - DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", - crtc->base.id, crtc->name, state); - } - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); - -static int -drm_atomic_replace_property_blob_from_id(struct drm_device *dev, - struct drm_property_blob **blob, - uint64_t blob_id, - ssize_t expected_size, - ssize_t expected_elem_size, - bool *replaced) -{ - struct drm_property_blob *new_blob = NULL; - - if (blob_id != 0) { - new_blob = drm_property_lookup_blob(dev, blob_id); - if (new_blob == NULL) - return -EINVAL; - - if (expected_size > 0 && - new_blob->length != expected_size) { - drm_property_blob_put(new_blob); - return -EINVAL; - } - if (expected_elem_size > 0 && - new_blob->length % expected_elem_size != 0) { - drm_property_blob_put(new_blob); - return -EINVAL; - } - } - - *replaced |= drm_property_replace_blob(blob, new_blob); - drm_property_blob_put(new_blob); - - return 0; -} - -static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, - struct drm_crtc_state *state, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *config = &dev->mode_config; - bool replaced = false; - int ret; - - if (property == config->prop_active) - state->active = val; - else if (property == config->prop_mode_id) { - struct drm_property_blob *mode = - drm_property_lookup_blob(dev, val); - ret = drm_atomic_set_mode_prop_for_crtc(state, mode); - drm_property_blob_put(mode); - return ret; - } else if (property == config->degamma_lut_property) { - ret = drm_atomic_replace_property_blob_from_id(dev, - &state->degamma_lut, - val, - -1, sizeof(struct drm_color_lut), - &replaced); - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->ctm_property) { - ret = drm_atomic_replace_property_blob_from_id(dev, - &state->ctm, - val, - sizeof(struct drm_color_ctm), -1, - &replaced); - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->gamma_lut_property) { - ret = drm_atomic_replace_property_blob_from_id(dev, - &state->gamma_lut, - val, - -1, sizeof(struct drm_color_lut), - &replaced); - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->prop_out_fence_ptr) { - s32 __user *fence_ptr = u64_to_user_ptr(val); - - if (!fence_ptr) - return 0; - - if (put_user(-1, fence_ptr)) - return -EFAULT; - - set_out_fence_for_crtc(state->state, crtc, fence_ptr); - } else if (crtc->funcs->atomic_set_property) { - return crtc->funcs->atomic_set_property(crtc, state, property, val); - } else { - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n", - crtc->base.id, crtc->name, - property->base.id, property->name); - return -EINVAL; - } - - return 0; -} - -static int -drm_atomic_crtc_get_property(struct drm_crtc *crtc, - const struct drm_crtc_state *state, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_active) - *val = state->active; - else if (property == config->prop_mode_id) - *val = (state->mode_blob) ? state->mode_blob->base.id : 0; - else if (property == config->degamma_lut_property) - *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; - else if (property == config->ctm_property) - *val = (state->ctm) ? state->ctm->base.id : 0; - else if (property == config->gamma_lut_property) - *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; - else if (property == config->prop_out_fence_ptr) - *val = 0; - else if (crtc->funcs->atomic_get_property) - return crtc->funcs->atomic_get_property(crtc, state, property, val); - else - return -EINVAL; - - return 0; -} - static int drm_atomic_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -761,144 +483,6 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_plane_state); -/** - * drm_atomic_plane_set_property - set property on plane - * @plane: the drm plane to set a property on - * @state: the state object to update with the new property value - * @property: the property to set - * @val: the new property value - * - * This function handles generic/core properties and calls out to driver's - * &drm_plane_funcs.atomic_set_property for driver properties. To ensure - * consistent behavior you must call this function rather than the driver hook - * directly. - * - * RETURNS: - * Zero on success, error code on failure - */ -static int drm_atomic_plane_set_property(struct drm_plane *plane, - struct drm_plane_state *state, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = plane->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_fb_id) { - struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); - drm_atomic_set_fb_for_plane(state, fb); - if (fb) - drm_framebuffer_put(fb); - } else if (property == config->prop_in_fence_fd) { - if (state->fence) - return -EINVAL; - - if (U642I64(val) == -1) - return 0; - - state->fence = sync_file_get_fence(val); - if (!state->fence) - return -EINVAL; - - } else if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); - return drm_atomic_set_crtc_for_plane(state, crtc); - } else if (property == config->prop_crtc_x) { - state->crtc_x = U642I64(val); - } else if (property == config->prop_crtc_y) { - state->crtc_y = U642I64(val); - } else if (property == config->prop_crtc_w) { - state->crtc_w = val; - } else if (property == config->prop_crtc_h) { - state->crtc_h = val; - } else if (property == config->prop_src_x) { - state->src_x = val; - } else if (property == config->prop_src_y) { - state->src_y = val; - } else if (property == config->prop_src_w) { - state->src_w = val; - } else if (property == config->prop_src_h) { - state->src_h = val; - } else if (property == plane->alpha_property) { - state->alpha = val; - } else if (property == plane->blend_mode_property) { - state->pixel_blend_mode = val; - } else if (property == plane->rotation_property) { - if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) { - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 0x%llx\n", - plane->base.id, plane->name, val); - return -EINVAL; - } - state->rotation = val; - } else if (property == plane->zpos_property) { - state->zpos = val; - } else if (property == plane->color_encoding_property) { - state->color_encoding = val; - } else if (property == plane->color_range_property) { - state->color_range = val; - } else if (plane->funcs->atomic_set_property) { - return plane->funcs->atomic_set_property(plane, state, - property, val); - } else { - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", - plane->base.id, plane->name, - property->base.id, property->name); - return -EINVAL; - } - - return 0; -} - -static int -drm_atomic_plane_get_property(struct drm_plane *plane, - const struct drm_plane_state *state, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = plane->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_fb_id) { - *val = (state->fb) ? state->fb->base.id : 0; - } else if (property == config->prop_in_fence_fd) { - *val = -1; - } else if (property == config->prop_crtc_id) { - *val = (state->crtc) ? state->crtc->base.id : 0; - } else if (property == config->prop_crtc_x) { - *val = I642U64(state->crtc_x); - } else if (property == config->prop_crtc_y) { - *val = I642U64(state->crtc_y); - } else if (property == config->prop_crtc_w) { - *val = state->crtc_w; - } else if (property == config->prop_crtc_h) { - *val = state->crtc_h; - } else if (property == config->prop_src_x) { - *val = state->src_x; - } else if (property == config->prop_src_y) { - *val = state->src_y; - } else if (property == config->prop_src_w) { - *val = state->src_w; - } else if (property == config->prop_src_h) { - *val = state->src_h; - } else if (property == plane->alpha_property) { - *val = state->alpha; - } else if (property == plane->blend_mode_property) { - *val = state->pixel_blend_mode; - } else if (property == plane->rotation_property) { - *val = state->rotation; - } else if (property == plane->zpos_property) { - *val = state->zpos; - } else if (property == plane->color_encoding_property) { - *val = state->color_encoding; - } else if (property == plane->color_range_property) { - *val = state->color_range; - } else if (plane->funcs->atomic_get_property) { - return plane->funcs->atomic_get_property(plane, state, property, val); - } else { - return -EINVAL; - } - - return 0; -} - static bool plane_switching_crtc(struct drm_atomic_state *state, struct drm_plane *plane, @@ -1238,129 +822,6 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_connector_state); -static struct drm_writeback_job * -drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) -{ - WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); - - if (!conn_state->writeback_job) - conn_state->writeback_job = - kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); - - return conn_state->writeback_job; -} - -static int drm_atomic_set_writeback_fb_for_connector( - struct drm_connector_state *conn_state, - struct drm_framebuffer *fb) -{ - struct drm_writeback_job *job = - drm_atomic_get_writeback_job(conn_state); - if (!job) - return -ENOMEM; - - drm_framebuffer_assign(&job->fb, fb); - - if (fb) - DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", - fb->base.id, conn_state); - else - DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", - conn_state); - - return 0; -} - -static int drm_atomic_connector_set_property(struct drm_connector *connector, - struct drm_connector_state *state, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = connector->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); - return drm_atomic_set_crtc_for_connector(state, crtc); - } else if (property == config->dpms_property) { - /* setting DPMS property requires special handling, which - * is done in legacy setprop path for us. Disallow (for - * now?) atomic writes to DPMS property: - */ - return -EINVAL; - } else if (property == config->tv_select_subconnector_property) { - state->tv.subconnector = val; - } else if (property == config->tv_left_margin_property) { - state->tv.margins.left = val; - } else if (property == config->tv_right_margin_property) { - state->tv.margins.right = val; - } else if (property == config->tv_top_margin_property) { - state->tv.margins.top = val; - } else if (property == config->tv_bottom_margin_property) { - state->tv.margins.bottom = val; - } else if (property == config->tv_mode_property) { - state->tv.mode = val; - } else if (property == config->tv_brightness_property) { - state->tv.brightness = val; - } else if (property == config->tv_contrast_property) { - state->tv.contrast = val; - } else if (property == config->tv_flicker_reduction_property) { - state->tv.flicker_reduction = val; - } else if (property == config->tv_overscan_property) { - state->tv.overscan = val; - } else if (property == config->tv_saturation_property) { - state->tv.saturation = val; - } else if (property == config->tv_hue_property) { - state->tv.hue = val; - } else if (property == config->link_status_property) { - /* Never downgrade from GOOD to BAD on userspace's request here, - * only hw issues can do that. - * - * For an atomic property the userspace doesn't need to be able - * to understand all the properties, but needs to be able to - * restore the state it wants on VT switch. So if the userspace - * tries to change the link_status from GOOD to BAD, driver - * silently rejects it and returns a 0. This prevents userspace - * from accidently breaking the display when it restores the - * state. - */ - if (state->link_status != DRM_LINK_STATUS_GOOD) - state->link_status = val; - } else if (property == config->aspect_ratio_property) { - state->picture_aspect_ratio = val; - } else if (property == config->content_type_property) { - state->content_type = 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 (property == config->writeback_fb_id_property) { - struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); - int ret = drm_atomic_set_writeback_fb_for_connector(state, fb); - if (fb) - drm_framebuffer_put(fb); - return ret; - } else if (property == config->writeback_out_fence_ptr_property) { - s32 __user *fence_ptr = u64_to_user_ptr(val); - - return set_out_fence_for_connector(state->state, connector, - fence_ptr); - } else if (connector->funcs->atomic_set_property) { - return connector->funcs->atomic_set_property(connector, - state, property, val); - } else { - DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] unknown property [PROP:%d:%s]]\n", - connector->base.id, connector->name, - property->base.id, property->name); - return -EINVAL; - } - - return 0; -} - static void drm_atomic_connector_print_state(struct drm_printer *p, const struct drm_connector_state *state) { @@ -1377,281 +838,6 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, connector->funcs->atomic_print_state(p, state); } -static int -drm_atomic_connector_get_property(struct drm_connector *connector, - const struct drm_connector_state *state, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = connector->dev; - struct drm_mode_config *config = &dev->mode_config; - - if (property == config->prop_crtc_id) { - *val = (state->crtc) ? state->crtc->base.id : 0; - } else if (property == config->dpms_property) { - *val = connector->dpms; - } else if (property == config->tv_select_subconnector_property) { - *val = state->tv.subconnector; - } else if (property == config->tv_left_margin_property) { - *val = state->tv.margins.left; - } else if (property == config->tv_right_margin_property) { - *val = state->tv.margins.right; - } else if (property == config->tv_top_margin_property) { - *val = state->tv.margins.top; - } else if (property == config->tv_bottom_margin_property) { - *val = state->tv.margins.bottom; - } else if (property == config->tv_mode_property) { - *val = state->tv.mode; - } else if (property == config->tv_brightness_property) { - *val = state->tv.brightness; - } else if (property == config->tv_contrast_property) { - *val = state->tv.contrast; - } else if (property == config->tv_flicker_reduction_property) { - *val = state->tv.flicker_reduction; - } else if (property == config->tv_overscan_property) { - *val = state->tv.overscan; - } else if (property == config->tv_saturation_property) { - *val = state->tv.saturation; - } else if (property == config->tv_hue_property) { - *val = state->tv.hue; - } else if (property == config->link_status_property) { - *val = state->link_status; - } else if (property == config->aspect_ratio_property) { - *val = state->picture_aspect_ratio; - } else if (property == config->content_type_property) { - *val = state->content_type; - } else if (property == connector->scaling_mode_property) { - *val = state->scaling_mode; - } else if (property == connector->content_protection_property) { - *val = state->content_protection; - } else if (property == config->writeback_fb_id_property) { - /* Writeback framebuffer is one-shot, write and forget */ - *val = 0; - } else if (property == config->writeback_out_fence_ptr_property) { - *val = 0; - } else if (connector->funcs->atomic_get_property) { - return connector->funcs->atomic_get_property(connector, - state, property, val); - } else { - return -EINVAL; - } - - return 0; -} - -int drm_atomic_get_property(struct drm_mode_object *obj, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = property->dev; - int ret; - - switch (obj->type) { - case DRM_MODE_OBJECT_CONNECTOR: { - struct drm_connector *connector = obj_to_connector(obj); - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); - ret = drm_atomic_connector_get_property(connector, - connector->state, property, val); - break; - } - case DRM_MODE_OBJECT_CRTC: { - struct drm_crtc *crtc = obj_to_crtc(obj); - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); - ret = drm_atomic_crtc_get_property(crtc, - crtc->state, property, val); - break; - } - case DRM_MODE_OBJECT_PLANE: { - struct drm_plane *plane = obj_to_plane(obj); - WARN_ON(!drm_modeset_is_locked(&plane->mutex)); - ret = drm_atomic_plane_get_property(plane, - plane->state, property, val); - break; - } - default: - ret = -EINVAL; - break; - } - - return ret; -} - -/** - * drm_atomic_set_crtc_for_plane - set crtc for plane - * @plane_state: the plane whose incoming state to update - * @crtc: crtc to use for the plane - * - * Changing the assigned crtc for a plane requires us to grab the lock and state - * for the new crtc, as needed. This function takes care of all these details - * besides updating the pointer in the state object itself. - * - * Returns: - * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK - * then the w/w mutex code has detected a deadlock and the entire atomic - * sequence must be restarted. All other errors are fatal. - */ -int -drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, - struct drm_crtc *crtc) -{ - struct drm_plane *plane = plane_state->plane; - struct drm_crtc_state *crtc_state; - /* Nothing to do for same crtc*/ - if (plane_state->crtc == crtc) - return 0; - if (plane_state->crtc) { - crtc_state = drm_atomic_get_crtc_state(plane_state->state, - plane_state->crtc); - if (WARN_ON(IS_ERR(crtc_state))) - return PTR_ERR(crtc_state); - - crtc_state->plane_mask &= ~drm_plane_mask(plane); - } - - plane_state->crtc = crtc; - - if (crtc) { - crtc_state = drm_atomic_get_crtc_state(plane_state->state, - crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); - crtc_state->plane_mask |= drm_plane_mask(plane); - } - - if (crtc) - DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [CRTC:%d:%s]\n", - plane->base.id, plane->name, plane_state, - crtc->base.id, crtc->name); - else - DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [NOCRTC]\n", - plane->base.id, plane->name, plane_state); - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane); - -/** - * drm_atomic_set_fb_for_plane - set framebuffer for plane - * @plane_state: atomic state object for the plane - * @fb: fb to use for the plane - * - * Changing the assigned framebuffer for a plane requires us to grab a reference - * to the new fb and drop the reference to the old fb, if there is one. This - * function takes care of all these details besides updating the pointer in the - * state object itself. - */ -void -drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, - struct drm_framebuffer *fb) -{ - struct drm_plane *plane = plane_state->plane; - - if (fb) - DRM_DEBUG_ATOMIC("Set [FB:%d] for [PLANE:%d:%s] state %p\n", - fb->base.id, plane->base.id, plane->name, - plane_state); - else - DRM_DEBUG_ATOMIC("Set [NOFB] for [PLANE:%d:%s] state %p\n", - plane->base.id, plane->name, plane_state); - - drm_framebuffer_assign(&plane_state->fb, fb); -} -EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); - -/** - * drm_atomic_set_fence_for_plane - set fence for plane - * @plane_state: atomic state object for the plane - * @fence: dma_fence to use for the plane - * - * Helper to setup the plane_state fence in case it is not set yet. - * By using this drivers doesn't need to worry if the user choose - * implicit or explicit fencing. - * - * This function will not set the fence to the state if it was set - * via explicit fencing interfaces on the atomic ioctl. In that case it will - * drop the reference to the fence as we are not storing it anywhere. - * Otherwise, if &drm_plane_state.fence is not set this function we just set it - * with the received implicit fence. In both cases this function consumes a - * reference for @fence. - * - * This way explicit fencing can be used to overrule implicit fencing, which is - * important to make explicit fencing use-cases work: One example is using one - * buffer for 2 screens with different refresh rates. Implicit fencing will - * clamp rendering to the refresh rate of the slower screen, whereas explicit - * fence allows 2 independent render and display loops on a single buffer. If a - * driver allows obeys both implicit and explicit fences for plane updates, then - * it will break all the benefits of explicit fencing. - */ -void -drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, - struct dma_fence *fence) -{ - if (plane_state->fence) { - dma_fence_put(fence); - return; - } - - plane_state->fence = fence; -} -EXPORT_SYMBOL(drm_atomic_set_fence_for_plane); - -/** - * drm_atomic_set_crtc_for_connector - set crtc for connector - * @conn_state: atomic state object for the connector - * @crtc: crtc to use for the connector - * - * Changing the assigned crtc for a connector requires us to grab the lock and - * state for the new crtc, as needed. This function takes care of all these - * details besides updating the pointer in the state object itself. - * - * Returns: - * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK - * then the w/w mutex code has detected a deadlock and the entire atomic - * sequence must be restarted. All other errors are fatal. - */ -int -drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, - struct drm_crtc *crtc) -{ - struct drm_connector *connector = conn_state->connector; - struct drm_crtc_state *crtc_state; - - if (conn_state->crtc == crtc) - return 0; - - if (conn_state->crtc) { - crtc_state = drm_atomic_get_new_crtc_state(conn_state->state, - conn_state->crtc); - - crtc_state->connector_mask &= - ~drm_connector_mask(conn_state->connector); - - drm_connector_put(conn_state->connector); - conn_state->crtc = NULL; - } - - if (crtc) { - crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); - - crtc_state->connector_mask |= - drm_connector_mask(conn_state->connector); - - drm_connector_get(conn_state->connector); - conn_state->crtc = crtc; - - DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [CRTC:%d:%s]\n", - connector->base.id, connector->name, - conn_state, crtc->base.id, crtc->name); - } else { - DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [NOCRTC]\n", - connector->base.id, connector->name, - conn_state); - } - - return 0; -} -EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector); - /** * drm_atomic_add_affected_connectors - add connectors for crtc * @state: atomic state @@ -1916,7 +1102,7 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state) } EXPORT_SYMBOL(drm_atomic_nonblocking_commit); -static void drm_atomic_print_state(const struct drm_atomic_state *state) +void drm_atomic_print_state(const struct drm_atomic_state *state) { struct drm_printer p = drm_info_printer(state->dev->dev); struct drm_plane *plane; @@ -2023,544 +1209,3 @@ int drm_atomic_debugfs_init(struct drm_minor *minor) } #endif -/* - * The big monster ioctl - */ - -static struct drm_pending_vblank_event *create_vblank_event( - struct drm_crtc *crtc, uint64_t user_data) -{ - struct drm_pending_vblank_event *e = NULL; - - e = kzalloc(sizeof *e, GFP_KERNEL); - if (!e) - return NULL; - - e->event.base.type = DRM_EVENT_FLIP_COMPLETE; - e->event.base.length = sizeof(e->event); - e->event.vbl.crtc_id = crtc->base.id; - e->event.vbl.user_data = user_data; - - return e; -} - -int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, - struct drm_connector *connector, - int mode) -{ - struct drm_connector *tmp_connector; - struct drm_connector_state *new_conn_state; - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - int i, ret, old_mode = connector->dpms; - bool active = false; - - ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex, - state->acquire_ctx); - if (ret) - return ret; - - if (mode != DRM_MODE_DPMS_ON) - mode = DRM_MODE_DPMS_OFF; - connector->dpms = mode; - - crtc = connector->state->crtc; - if (!crtc) - goto out; - ret = drm_atomic_add_affected_connectors(state, crtc); - if (ret) - goto out; - - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) { - ret = PTR_ERR(crtc_state); - goto out; - } - - for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) { - if (new_conn_state->crtc != crtc) - continue; - if (tmp_connector->dpms == DRM_MODE_DPMS_ON) { - active = true; - break; - } - } - - crtc_state->active = active; - ret = drm_atomic_commit(state); -out: - if (ret != 0) - connector->dpms = old_mode; - return ret; -} - -int drm_atomic_set_property(struct drm_atomic_state *state, - struct drm_mode_object *obj, - struct drm_property *prop, - uint64_t prop_value) -{ - struct drm_mode_object *ref; - int ret; - - if (!drm_property_change_valid_get(prop, prop_value, &ref)) - return -EINVAL; - - switch (obj->type) { - case DRM_MODE_OBJECT_CONNECTOR: { - struct drm_connector *connector = obj_to_connector(obj); - struct drm_connector_state *connector_state; - - connector_state = drm_atomic_get_connector_state(state, connector); - if (IS_ERR(connector_state)) { - ret = PTR_ERR(connector_state); - break; - } - - ret = drm_atomic_connector_set_property(connector, - connector_state, prop, prop_value); - break; - } - case DRM_MODE_OBJECT_CRTC: { - struct drm_crtc *crtc = obj_to_crtc(obj); - struct drm_crtc_state *crtc_state; - - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) { - ret = PTR_ERR(crtc_state); - break; - } - - ret = drm_atomic_crtc_set_property(crtc, - crtc_state, prop, prop_value); - break; - } - case DRM_MODE_OBJECT_PLANE: { - struct drm_plane *plane = obj_to_plane(obj); - struct drm_plane_state *plane_state; - - plane_state = drm_atomic_get_plane_state(state, plane); - if (IS_ERR(plane_state)) { - ret = PTR_ERR(plane_state); - break; - } - - ret = drm_atomic_plane_set_property(plane, - plane_state, prop, prop_value); - break; - } - default: - ret = -EINVAL; - break; - } - - drm_property_change_valid_put(prop, ref); - return ret; -} - -/** - * DOC: explicit fencing properties - * - * Explicit fencing allows userspace to control the buffer synchronization - * between devices. A Fence or a group of fences are transfered to/from - * userspace using Sync File fds and there are two DRM properties for that. - * IN_FENCE_FD on each DRM Plane to send fences to the kernel and - * OUT_FENCE_PTR on each DRM CRTC to receive fences from the kernel. - * - * As a contrast, with implicit fencing the kernel keeps track of any - * ongoing rendering, and automatically ensures that the atomic update waits - * for any pending rendering to complete. For shared buffers represented with - * a &struct dma_buf this is tracked in &struct reservation_object. - * Implicit syncing is how Linux traditionally worked (e.g. DRI2/3 on X.org), - * whereas explicit fencing is what Android wants. - * - * "IN_FENCE_FD”: - * Use this property to pass a fence that DRM should wait on before - * proceeding with the Atomic Commit request and show the framebuffer for - * the plane on the screen. The fence can be either a normal fence or a - * merged one, the sync_file framework will handle both cases and use a - * fence_array if a merged fence is received. Passing -1 here means no - * fences to wait on. - * - * If the Atomic Commit request has the DRM_MODE_ATOMIC_TEST_ONLY flag - * it will only check if the Sync File is a valid one. - * - * On the driver side the fence is stored on the @fence parameter of - * &struct drm_plane_state. Drivers which also support implicit fencing - * should set the implicit fence using drm_atomic_set_fence_for_plane(), - * to make sure there's consistent behaviour between drivers in precedence - * of implicit vs. explicit fencing. - * - * "OUT_FENCE_PTR”: - * Use this property to pass a file descriptor pointer to DRM. Once the - * Atomic Commit request call returns OUT_FENCE_PTR will be filled with - * the file descriptor number of a Sync File. This Sync File contains the - * CRTC fence that will be signaled when all framebuffers present on the - * Atomic Commit * request for that given CRTC are scanned out on the - * screen. - * - * The Atomic Commit request fails if a invalid pointer is passed. If the - * Atomic Commit request fails for any other reason the out fence fd - * returned will be -1. On a Atomic Commit with the - * DRM_MODE_ATOMIC_TEST_ONLY flag the out fence will also be set to -1. - * - * Note that out-fences don't have a special interface to drivers and are - * internally represented by a &struct drm_pending_vblank_event in struct - * &drm_crtc_state, which is also used by the nonblocking atomic commit - * helpers and for the DRM event handling for existing userspace. - */ - -struct drm_out_fence_state { - s32 __user *out_fence_ptr; - struct sync_file *sync_file; - int fd; -}; - -static int setup_out_fence(struct drm_out_fence_state *fence_state, - struct dma_fence *fence) -{ - fence_state->fd = get_unused_fd_flags(O_CLOEXEC); - if (fence_state->fd < 0) - return fence_state->fd; - - if (put_user(fence_state->fd, fence_state->out_fence_ptr)) - return -EFAULT; - - fence_state->sync_file = sync_file_create(fence); - if (!fence_state->sync_file) - return -ENOMEM; - - return 0; -} - -static int prepare_signaling(struct drm_device *dev, - struct drm_atomic_state *state, - struct drm_mode_atomic *arg, - struct drm_file *file_priv, - struct drm_out_fence_state **fence_state, - unsigned int *num_fences) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - struct drm_connector *conn; - struct drm_connector_state *conn_state; - int i, c = 0, ret; - - if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) - return 0; - - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { - s32 __user *fence_ptr; - - fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc); - - if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) { - struct drm_pending_vblank_event *e; - - e = create_vblank_event(crtc, arg->user_data); - if (!e) - return -ENOMEM; - - crtc_state->event = e; - } - - if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { - struct drm_pending_vblank_event *e = crtc_state->event; - - if (!file_priv) - continue; - - ret = drm_event_reserve_init(dev, file_priv, &e->base, - &e->event.base); - if (ret) { - kfree(e); - crtc_state->event = NULL; - return ret; - } - } - - if (fence_ptr) { - struct dma_fence *fence; - struct drm_out_fence_state *f; - - f = krealloc(*fence_state, sizeof(**fence_state) * - (*num_fences + 1), GFP_KERNEL); - if (!f) - return -ENOMEM; - - memset(&f[*num_fences], 0, sizeof(*f)); - - f[*num_fences].out_fence_ptr = fence_ptr; - *fence_state = f; - - fence = drm_crtc_create_fence(crtc); - if (!fence) - return -ENOMEM; - - ret = setup_out_fence(&f[(*num_fences)++], fence); - if (ret) { - dma_fence_put(fence); - return ret; - } - - crtc_state->event->base.fence = fence; - } - - c++; - } - - for_each_new_connector_in_state(state, conn, conn_state, i) { - struct drm_writeback_connector *wb_conn; - struct drm_writeback_job *job; - struct drm_out_fence_state *f; - struct dma_fence *fence; - s32 __user *fence_ptr; - - fence_ptr = get_out_fence_for_connector(state, conn); - if (!fence_ptr) - continue; - - job = drm_atomic_get_writeback_job(conn_state); - if (!job) - return -ENOMEM; - - f = krealloc(*fence_state, sizeof(**fence_state) * - (*num_fences + 1), GFP_KERNEL); - if (!f) - return -ENOMEM; - - memset(&f[*num_fences], 0, sizeof(*f)); - - f[*num_fences].out_fence_ptr = fence_ptr; - *fence_state = f; - - wb_conn = drm_connector_to_writeback(conn); - fence = drm_writeback_get_out_fence(wb_conn); - if (!fence) - return -ENOMEM; - - ret = setup_out_fence(&f[(*num_fences)++], fence); - if (ret) { - dma_fence_put(fence); - return ret; - } - - job->out_fence = fence; - } - - /* - * Having this flag means user mode pends on event which will never - * reach due to lack of at least one CRTC for signaling - */ - if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) - return -EINVAL; - - return 0; -} - -static void complete_signaling(struct drm_device *dev, - struct drm_atomic_state *state, - struct drm_out_fence_state *fence_state, - unsigned int num_fences, - bool install_fds) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - int i; - - if (install_fds) { - for (i = 0; i < num_fences; i++) - fd_install(fence_state[i].fd, - fence_state[i].sync_file->file); - - kfree(fence_state); - return; - } - - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { - struct drm_pending_vblank_event *event = crtc_state->event; - /* - * Free the allocated event. drm_atomic_helper_setup_commit - * can allocate an event too, so only free it if it's ours - * to prevent a double free in drm_atomic_state_clear. - */ - if (event && (event->base.fence || event->base.file_priv)) { - drm_event_cancel_free(dev, &event->base); - crtc_state->event = NULL; - } - } - - if (!fence_state) - return; - - for (i = 0; i < num_fences; i++) { - if (fence_state[i].sync_file) - fput(fence_state[i].sync_file->file); - if (fence_state[i].fd >= 0) - put_unused_fd(fence_state[i].fd); - - /* If this fails log error to the user */ - if (fence_state[i].out_fence_ptr && - put_user(-1, fence_state[i].out_fence_ptr)) - DRM_DEBUG_ATOMIC("Couldn't clear out_fence_ptr\n"); - } - - kfree(fence_state); -} - -int drm_mode_atomic_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_atomic *arg = data; - uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr); - uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr); - uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr); - uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr); - unsigned int copied_objs, copied_props; - struct drm_atomic_state *state; - struct drm_modeset_acquire_ctx ctx; - struct drm_out_fence_state *fence_state; - int ret = 0; - unsigned int i, j, num_fences; - - /* disallow for drivers not supporting atomic: */ - if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) - return -EINVAL; - - /* disallow for userspace that has not enabled atomic cap (even - * though this may be a bit overkill, since legacy userspace - * wouldn't know how to call this ioctl) - */ - if (!file_priv->atomic) - return -EINVAL; - - if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS) - return -EINVAL; - - if (arg->reserved) - return -EINVAL; - - if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) && - !dev->mode_config.async_page_flip) - return -EINVAL; - - /* can't test and expect an event at the same time. */ - if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) && - (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) - return -EINVAL; - - drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); - - state = drm_atomic_state_alloc(dev); - if (!state) - return -ENOMEM; - - state->acquire_ctx = &ctx; - state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); - -retry: - copied_objs = 0; - copied_props = 0; - fence_state = NULL; - num_fences = 0; - - for (i = 0; i < arg->count_objs; i++) { - uint32_t obj_id, count_props; - struct drm_mode_object *obj; - - if (get_user(obj_id, objs_ptr + copied_objs)) { - ret = -EFAULT; - goto out; - } - - obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY); - if (!obj) { - ret = -ENOENT; - goto out; - } - - if (!obj->properties) { - drm_mode_object_put(obj); - ret = -ENOENT; - goto out; - } - - if (get_user(count_props, count_props_ptr + copied_objs)) { - drm_mode_object_put(obj); - ret = -EFAULT; - goto out; - } - - copied_objs++; - - for (j = 0; j < count_props; j++) { - uint32_t prop_id; - uint64_t prop_value; - struct drm_property *prop; - - if (get_user(prop_id, props_ptr + copied_props)) { - drm_mode_object_put(obj); - ret = -EFAULT; - goto out; - } - - prop = drm_mode_obj_find_prop_id(obj, prop_id); - if (!prop) { - drm_mode_object_put(obj); - ret = -ENOENT; - goto out; - } - - if (copy_from_user(&prop_value, - prop_values_ptr + copied_props, - sizeof(prop_value))) { - drm_mode_object_put(obj); - ret = -EFAULT; - goto out; - } - - ret = drm_atomic_set_property(state, obj, prop, - prop_value); - if (ret) { - drm_mode_object_put(obj); - goto out; - } - - copied_props++; - } - - drm_mode_object_put(obj); - } - - ret = prepare_signaling(dev, state, arg, file_priv, &fence_state, - &num_fences); - if (ret) - goto out; - - if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { - ret = drm_atomic_check_only(state); - } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { - ret = drm_atomic_nonblocking_commit(state); - } else { - if (unlikely(drm_debug & DRM_UT_STATE)) - drm_atomic_print_state(state); - - ret = drm_atomic_commit(state); - } - -out: - complete_signaling(dev, state, fence_state, num_fences, !ret); - - if (ret == -EDEADLK) { - drm_atomic_state_clear(state); - ret = drm_modeset_backoff(&ctx); - if (!ret) - goto retry; - } - - drm_atomic_state_put(state); - - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); - - return ret; -} diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index daa04d29f8cc..8469a7e9afe3 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c new file mode 100644 index 000000000000..26690a664ec6 --- /dev/null +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -0,0 +1,1393 @@ +/* + * Copyright (C) 2014 Red Hat + * Copyright (C) 2014 Intel Corp. + * Copyright (C) 2018 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "drm_crtc_internal.h" + +/** + * DOC: overview + * + * This file contains the marshalling and demarshalling glue for the atomic UAPI + * in all it's form: The monster ATOMIC IOCTL itself, code for GET_PROPERTY and + * SET_PROPERTY IOCTls. Plus interface functions for compatibility helpers and + * drivers which have special needs to construct their own atomic updates, e.g. + * for load detect or similiar. + */ + +/** + * drm_atomic_set_mode_for_crtc - set mode for CRTC + * @state: the CRTC whose incoming state to update + * @mode: kernel-internal mode to use for the CRTC, or NULL to disable + * + * Set a mode (originating from the kernel) on the desired CRTC state and update + * the enable property. + * + * RETURNS: + * Zero on success, error code on failure. Cannot return -EDEADLK. + */ +int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, + const struct drm_display_mode *mode) +{ + struct drm_crtc *crtc = state->crtc; + struct drm_mode_modeinfo umode; + + /* Early return for no change. */ + if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0) + return 0; + + drm_property_blob_put(state->mode_blob); + state->mode_blob = NULL; + + if (mode) { + drm_mode_convert_to_umode(&umode, mode); + state->mode_blob = + drm_property_create_blob(state->crtc->dev, + sizeof(umode), + &umode); + if (IS_ERR(state->mode_blob)) + return PTR_ERR(state->mode_blob); + + drm_mode_copy(&state->mode, mode); + state->enable = true; + DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", + mode->name, crtc->base.id, crtc->name, state); + } else { + memset(&state->mode, 0, sizeof(state->mode)); + state->enable = false; + DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", + crtc->base.id, crtc->name, state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc); + +/** + * drm_atomic_set_mode_prop_for_crtc - set mode for CRTC + * @state: the CRTC whose incoming state to update + * @blob: pointer to blob property to use for mode + * + * Set a mode (originating from a blob property) on the desired CRTC state. + * This function will take a reference on the blob property for the CRTC state, + * and release the reference held on the state's existing mode property, if any + * was set. + * + * RETURNS: + * Zero on success, error code on failure. Cannot return -EDEADLK. + */ +int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, + struct drm_property_blob *blob) +{ + struct drm_crtc *crtc = state->crtc; + + if (blob == state->mode_blob) + return 0; + + drm_property_blob_put(state->mode_blob); + state->mode_blob = NULL; + + memset(&state->mode, 0, sizeof(state->mode)); + + if (blob) { + int ret; + + if (blob->length != sizeof(struct drm_mode_modeinfo)) { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] bad mode blob length: %zu\n", + crtc->base.id, crtc->name, + blob->length); + return -EINVAL; + } + + ret = drm_mode_convert_umode(crtc->dev, + &state->mode, blob->data); + if (ret) { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] invalid mode (ret=%d, status=%s):\n", + crtc->base.id, crtc->name, + ret, drm_get_mode_status_name(state->mode.status)); + drm_mode_debug_printmodeline(&state->mode); + return -EINVAL; + } + + state->mode_blob = drm_property_blob_get(blob); + state->enable = true; + DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", + state->mode.name, crtc->base.id, crtc->name, + state); + } else { + state->enable = false; + DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", + crtc->base.id, crtc->name, state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); + +/** + * drm_atomic_set_crtc_for_plane - set crtc for plane + * @plane_state: the plane whose incoming state to update + * @crtc: crtc to use for the plane + * + * Changing the assigned crtc for a plane requires us to grab the lock and state + * for the new crtc, as needed. This function takes care of all these details + * besides updating the pointer in the state object itself. + * + * Returns: + * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK + * then the w/w mutex code has detected a deadlock and the entire atomic + * sequence must be restarted. All other errors are fatal. + */ +int +drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, + struct drm_crtc *crtc) +{ + struct drm_plane *plane = plane_state->plane; + struct drm_crtc_state *crtc_state; + /* Nothing to do for same crtc*/ + if (plane_state->crtc == crtc) + return 0; + if (plane_state->crtc) { + crtc_state = drm_atomic_get_crtc_state(plane_state->state, + plane_state->crtc); + if (WARN_ON(IS_ERR(crtc_state))) + return PTR_ERR(crtc_state); + + crtc_state->plane_mask &= ~drm_plane_mask(plane); + } + + plane_state->crtc = crtc; + + if (crtc) { + crtc_state = drm_atomic_get_crtc_state(plane_state->state, + crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + crtc_state->plane_mask |= drm_plane_mask(plane); + } + + if (crtc) + DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [CRTC:%d:%s]\n", + plane->base.id, plane->name, plane_state, + crtc->base.id, crtc->name); + else + DRM_DEBUG_ATOMIC("Link [PLANE:%d:%s] state %p to [NOCRTC]\n", + plane->base.id, plane->name, plane_state); + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane); + +/** + * drm_atomic_set_fb_for_plane - set framebuffer for plane + * @plane_state: atomic state object for the plane + * @fb: fb to use for the plane + * + * Changing the assigned framebuffer for a plane requires us to grab a reference + * to the new fb and drop the reference to the old fb, if there is one. This + * function takes care of all these details besides updating the pointer in the + * state object itself. + */ +void +drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, + struct drm_framebuffer *fb) +{ + struct drm_plane *plane = plane_state->plane; + + if (fb) + DRM_DEBUG_ATOMIC("Set [FB:%d] for [PLANE:%d:%s] state %p\n", + fb->base.id, plane->base.id, plane->name, + plane_state); + else + DRM_DEBUG_ATOMIC("Set [NOFB] for [PLANE:%d:%s] state %p\n", + plane->base.id, plane->name, plane_state); + + drm_framebuffer_assign(&plane_state->fb, fb); +} +EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); + +/** + * drm_atomic_set_fence_for_plane - set fence for plane + * @plane_state: atomic state object for the plane + * @fence: dma_fence to use for the plane + * + * Helper to setup the plane_state fence in case it is not set yet. + * By using this drivers doesn't need to worry if the user choose + * implicit or explicit fencing. + * + * This function will not set the fence to the state if it was set + * via explicit fencing interfaces on the atomic ioctl. In that case it will + * drop the reference to the fence as we are not storing it anywhere. + * Otherwise, if &drm_plane_state.fence is not set this function we just set it + * with the received implicit fence. In both cases this function consumes a + * reference for @fence. + * + * This way explicit fencing can be used to overrule implicit fencing, which is + * important to make explicit fencing use-cases work: One example is using one + * buffer for 2 screens with different refresh rates. Implicit fencing will + * clamp rendering to the refresh rate of the slower screen, whereas explicit + * fence allows 2 independent render and display loops on a single buffer. If a + * driver allows obeys both implicit and explicit fences for plane updates, then + * it will break all the benefits of explicit fencing. + */ +void +drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, + struct dma_fence *fence) +{ + if (plane_state->fence) { + dma_fence_put(fence); + return; + } + + plane_state->fence = fence; +} +EXPORT_SYMBOL(drm_atomic_set_fence_for_plane); + +/** + * drm_atomic_set_crtc_for_connector - set crtc for connector + * @conn_state: atomic state object for the connector + * @crtc: crtc to use for the connector + * + * Changing the assigned crtc for a connector requires us to grab the lock and + * state for the new crtc, as needed. This function takes care of all these + * details besides updating the pointer in the state object itself. + * + * Returns: + * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK + * then the w/w mutex code has detected a deadlock and the entire atomic + * sequence must be restarted. All other errors are fatal. + */ +int +drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, + struct drm_crtc *crtc) +{ + struct drm_connector *connector = conn_state->connector; + struct drm_crtc_state *crtc_state; + + if (conn_state->crtc == crtc) + return 0; + + if (conn_state->crtc) { + crtc_state = drm_atomic_get_new_crtc_state(conn_state->state, + conn_state->crtc); + + crtc_state->connector_mask &= + ~drm_connector_mask(conn_state->connector); + + drm_connector_put(conn_state->connector); + conn_state->crtc = NULL; + } + + if (crtc) { + crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + crtc_state->connector_mask |= + drm_connector_mask(conn_state->connector); + + drm_connector_get(conn_state->connector); + conn_state->crtc = crtc; + + DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [CRTC:%d:%s]\n", + connector->base.id, connector->name, + conn_state, crtc->base.id, crtc->name); + } else { + DRM_DEBUG_ATOMIC("Link [CONNECTOR:%d:%s] state %p to [NOCRTC]\n", + connector->base.id, connector->name, + conn_state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector); + +static void set_out_fence_for_crtc(struct drm_atomic_state *state, + struct drm_crtc *crtc, s32 __user *fence_ptr) +{ + state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = fence_ptr; +} + +static s32 __user *get_out_fence_for_crtc(struct drm_atomic_state *state, + struct drm_crtc *crtc) +{ + s32 __user *fence_ptr; + + fence_ptr = state->crtcs[drm_crtc_index(crtc)].out_fence_ptr; + state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = NULL; + + return fence_ptr; +} + +static int set_out_fence_for_connector(struct drm_atomic_state *state, + struct drm_connector *connector, + s32 __user *fence_ptr) +{ + unsigned int index = drm_connector_index(connector); + + if (!fence_ptr) + return 0; + + if (put_user(-1, fence_ptr)) + return -EFAULT; + + state->connectors[index].out_fence_ptr = fence_ptr; + + return 0; +} + +static s32 __user *get_out_fence_for_connector(struct drm_atomic_state *state, + struct drm_connector *connector) +{ + unsigned int index = drm_connector_index(connector); + s32 __user *fence_ptr; + + fence_ptr = state->connectors[index].out_fence_ptr; + state->connectors[index].out_fence_ptr = NULL; + + return fence_ptr; +} + +static int +drm_atomic_replace_property_blob_from_id(struct drm_device *dev, + struct drm_property_blob **blob, + uint64_t blob_id, + ssize_t expected_size, + ssize_t expected_elem_size, + bool *replaced) +{ + struct drm_property_blob *new_blob = NULL; + + if (blob_id != 0) { + new_blob = drm_property_lookup_blob(dev, blob_id); + if (new_blob == NULL) + return -EINVAL; + + if (expected_size > 0 && + new_blob->length != expected_size) { + drm_property_blob_put(new_blob); + return -EINVAL; + } + if (expected_elem_size > 0 && + new_blob->length % expected_elem_size != 0) { + drm_property_blob_put(new_blob); + return -EINVAL; + } + } + + *replaced |= drm_property_replace_blob(blob, new_blob); + drm_property_blob_put(new_blob); + + return 0; +} + +static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, + struct drm_crtc_state *state, struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *config = &dev->mode_config; + bool replaced = false; + int ret; + + if (property == config->prop_active) + state->active = val; + else if (property == config->prop_mode_id) { + struct drm_property_blob *mode = + drm_property_lookup_blob(dev, val); + ret = drm_atomic_set_mode_prop_for_crtc(state, mode); + drm_property_blob_put(mode); + return ret; + } else if (property == config->degamma_lut_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->degamma_lut, + val, + -1, sizeof(struct drm_color_lut), + &replaced); + state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->ctm_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->ctm, + val, + sizeof(struct drm_color_ctm), -1, + &replaced); + state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->gamma_lut_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->gamma_lut, + val, + -1, sizeof(struct drm_color_lut), + &replaced); + state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->prop_out_fence_ptr) { + s32 __user *fence_ptr = u64_to_user_ptr(val); + + if (!fence_ptr) + return 0; + + if (put_user(-1, fence_ptr)) + return -EFAULT; + + set_out_fence_for_crtc(state->state, crtc, fence_ptr); + } else if (crtc->funcs->atomic_set_property) { + return crtc->funcs->atomic_set_property(crtc, state, property, val); + } else { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n", + crtc->base.id, crtc->name, + property->base.id, property->name); + return -EINVAL; + } + + return 0; +} + +static int +drm_atomic_crtc_get_property(struct drm_crtc *crtc, + const struct drm_crtc_state *state, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_active) + *val = state->active; + else if (property == config->prop_mode_id) + *val = (state->mode_blob) ? state->mode_blob->base.id : 0; + else if (property == config->degamma_lut_property) + *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; + else if (property == config->ctm_property) + *val = (state->ctm) ? state->ctm->base.id : 0; + else if (property == config->gamma_lut_property) + *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; + else if (property == config->prop_out_fence_ptr) + *val = 0; + else if (crtc->funcs->atomic_get_property) + return crtc->funcs->atomic_get_property(crtc, state, property, val); + else + return -EINVAL; + + return 0; +} + +static int drm_atomic_plane_set_property(struct drm_plane *plane, + struct drm_plane_state *state, struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = plane->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_fb_id) { + struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); + drm_atomic_set_fb_for_plane(state, fb); + if (fb) + drm_framebuffer_put(fb); + } else if (property == config->prop_in_fence_fd) { + if (state->fence) + return -EINVAL; + + if (U642I64(val) == -1) + return 0; + + state->fence = sync_file_get_fence(val); + if (!state->fence) + return -EINVAL; + + } else if (property == config->prop_crtc_id) { + struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); + return drm_atomic_set_crtc_for_plane(state, crtc); + } else if (property == config->prop_crtc_x) { + state->crtc_x = U642I64(val); + } else if (property == config->prop_crtc_y) { + state->crtc_y = U642I64(val); + } else if (property == config->prop_crtc_w) { + state->crtc_w = val; + } else if (property == config->prop_crtc_h) { + state->crtc_h = val; + } else if (property == config->prop_src_x) { + state->src_x = val; + } else if (property == config->prop_src_y) { + state->src_y = val; + } else if (property == config->prop_src_w) { + state->src_w = val; + } else if (property == config->prop_src_h) { + state->src_h = val; + } else if (property == plane->alpha_property) { + state->alpha = val; + } else if (property == plane->blend_mode_property) { + state->pixel_blend_mode = val; + } else if (property == plane->rotation_property) { + if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) { + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 0x%llx\n", + plane->base.id, plane->name, val); + return -EINVAL; + } + state->rotation = val; + } else if (property == plane->zpos_property) { + state->zpos = val; + } else if (property == plane->color_encoding_property) { + state->color_encoding = val; + } else if (property == plane->color_range_property) { + state->color_range = val; + } else if (plane->funcs->atomic_set_property) { + return plane->funcs->atomic_set_property(plane, state, + property, val); + } else { + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", + plane->base.id, plane->name, + property->base.id, property->name); + return -EINVAL; + } + + return 0; +} + +static int +drm_atomic_plane_get_property(struct drm_plane *plane, + const struct drm_plane_state *state, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = plane->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_fb_id) { + *val = (state->fb) ? state->fb->base.id : 0; + } else if (property == config->prop_in_fence_fd) { + *val = -1; + } else if (property == config->prop_crtc_id) { + *val = (state->crtc) ? state->crtc->base.id : 0; + } else if (property == config->prop_crtc_x) { + *val = I642U64(state->crtc_x); + } else if (property == config->prop_crtc_y) { + *val = I642U64(state->crtc_y); + } else if (property == config->prop_crtc_w) { + *val = state->crtc_w; + } else if (property == config->prop_crtc_h) { + *val = state->crtc_h; + } else if (property == config->prop_src_x) { + *val = state->src_x; + } else if (property == config->prop_src_y) { + *val = state->src_y; + } else if (property == config->prop_src_w) { + *val = state->src_w; + } else if (property == config->prop_src_h) { + *val = state->src_h; + } else if (property == plane->alpha_property) { + *val = state->alpha; + } else if (property == plane->blend_mode_property) { + *val = state->pixel_blend_mode; + } else if (property == plane->rotation_property) { + *val = state->rotation; + } else if (property == plane->zpos_property) { + *val = state->zpos; + } else if (property == plane->color_encoding_property) { + *val = state->color_encoding; + } else if (property == plane->color_range_property) { + *val = state->color_range; + } else if (plane->funcs->atomic_get_property) { + return plane->funcs->atomic_get_property(plane, state, property, val); + } else { + return -EINVAL; + } + + return 0; +} + +static struct drm_writeback_job * +drm_atomic_get_writeback_job(struct drm_connector_state *conn_state) +{ + WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); + + if (!conn_state->writeback_job) + conn_state->writeback_job = + kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); + + return conn_state->writeback_job; +} + +static int drm_atomic_set_writeback_fb_for_connector( + struct drm_connector_state *conn_state, + struct drm_framebuffer *fb) +{ + struct drm_writeback_job *job = + drm_atomic_get_writeback_job(conn_state); + if (!job) + return -ENOMEM; + + drm_framebuffer_assign(&job->fb, fb); + + if (fb) + DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n", + fb->base.id, conn_state); + else + DRM_DEBUG_ATOMIC("Set [NOFB] for connector state %p\n", + conn_state); + + return 0; +} + +static int drm_atomic_connector_set_property(struct drm_connector *connector, + struct drm_connector_state *state, struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = connector->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_crtc_id) { + struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); + return drm_atomic_set_crtc_for_connector(state, crtc); + } else if (property == config->dpms_property) { + /* setting DPMS property requires special handling, which + * is done in legacy setprop path for us. Disallow (for + * now?) atomic writes to DPMS property: + */ + return -EINVAL; + } else if (property == config->tv_select_subconnector_property) { + state->tv.subconnector = val; + } else if (property == config->tv_left_margin_property) { + state->tv.margins.left = val; + } else if (property == config->tv_right_margin_property) { + state->tv.margins.right = val; + } else if (property == config->tv_top_margin_property) { + state->tv.margins.top = val; + } else if (property == config->tv_bottom_margin_property) { + state->tv.margins.bottom = val; + } else if (property == config->tv_mode_property) { + state->tv.mode = val; + } else if (property == config->tv_brightness_property) { + state->tv.brightness = val; + } else if (property == config->tv_contrast_property) { + state->tv.contrast = val; + } else if (property == config->tv_flicker_reduction_property) { + state->tv.flicker_reduction = val; + } else if (property == config->tv_overscan_property) { + state->tv.overscan = val; + } else if (property == config->tv_saturation_property) { + state->tv.saturation = val; + } else if (property == config->tv_hue_property) { + state->tv.hue = val; + } else if (property == config->link_status_property) { + /* Never downgrade from GOOD to BAD on userspace's request here, + * only hw issues can do that. + * + * For an atomic property the userspace doesn't need to be able + * to understand all the properties, but needs to be able to + * restore the state it wants on VT switch. So if the userspace + * tries to change the link_status from GOOD to BAD, driver + * silently rejects it and returns a 0. This prevents userspace + * from accidently breaking the display when it restores the + * state. + */ + if (state->link_status != DRM_LINK_STATUS_GOOD) + state->link_status = val; + } else if (property == config->aspect_ratio_property) { + state->picture_aspect_ratio = val; + } else if (property == config->content_type_property) { + state->content_type = 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 (property == config->writeback_fb_id_property) { + struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); + int ret = drm_atomic_set_writeback_fb_for_connector(state, fb); + if (fb) + drm_framebuffer_put(fb); + return ret; + } else if (property == config->writeback_out_fence_ptr_property) { + s32 __user *fence_ptr = u64_to_user_ptr(val); + + return set_out_fence_for_connector(state->state, connector, + fence_ptr); + } else if (connector->funcs->atomic_set_property) { + return connector->funcs->atomic_set_property(connector, + state, property, val); + } else { + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] unknown property [PROP:%d:%s]]\n", + connector->base.id, connector->name, + property->base.id, property->name); + return -EINVAL; + } + + return 0; +} + +static int +drm_atomic_connector_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = connector->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (property == config->prop_crtc_id) { + *val = (state->crtc) ? state->crtc->base.id : 0; + } else if (property == config->dpms_property) { + *val = connector->dpms; + } else if (property == config->tv_select_subconnector_property) { + *val = state->tv.subconnector; + } else if (property == config->tv_left_margin_property) { + *val = state->tv.margins.left; + } else if (property == config->tv_right_margin_property) { + *val = state->tv.margins.right; + } else if (property == config->tv_top_margin_property) { + *val = state->tv.margins.top; + } else if (property == config->tv_bottom_margin_property) { + *val = state->tv.margins.bottom; + } else if (property == config->tv_mode_property) { + *val = state->tv.mode; + } else if (property == config->tv_brightness_property) { + *val = state->tv.brightness; + } else if (property == config->tv_contrast_property) { + *val = state->tv.contrast; + } else if (property == config->tv_flicker_reduction_property) { + *val = state->tv.flicker_reduction; + } else if (property == config->tv_overscan_property) { + *val = state->tv.overscan; + } else if (property == config->tv_saturation_property) { + *val = state->tv.saturation; + } else if (property == config->tv_hue_property) { + *val = state->tv.hue; + } else if (property == config->link_status_property) { + *val = state->link_status; + } else if (property == config->aspect_ratio_property) { + *val = state->picture_aspect_ratio; + } else if (property == config->content_type_property) { + *val = state->content_type; + } else if (property == connector->scaling_mode_property) { + *val = state->scaling_mode; + } else if (property == connector->content_protection_property) { + *val = state->content_protection; + } else if (property == config->writeback_fb_id_property) { + /* Writeback framebuffer is one-shot, write and forget */ + *val = 0; + } else if (property == config->writeback_out_fence_ptr_property) { + *val = 0; + } else if (connector->funcs->atomic_get_property) { + return connector->funcs->atomic_get_property(connector, + state, property, val); + } else { + return -EINVAL; + } + + return 0; +} + +int drm_atomic_get_property(struct drm_mode_object *obj, + struct drm_property *property, uint64_t *val) +{ + struct drm_device *dev = property->dev; + int ret; + + switch (obj->type) { + case DRM_MODE_OBJECT_CONNECTOR: { + struct drm_connector *connector = obj_to_connector(obj); + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + ret = drm_atomic_connector_get_property(connector, + connector->state, property, val); + break; + } + case DRM_MODE_OBJECT_CRTC: { + struct drm_crtc *crtc = obj_to_crtc(obj); + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + ret = drm_atomic_crtc_get_property(crtc, + crtc->state, property, val); + break; + } + case DRM_MODE_OBJECT_PLANE: { + struct drm_plane *plane = obj_to_plane(obj); + WARN_ON(!drm_modeset_is_locked(&plane->mutex)); + ret = drm_atomic_plane_get_property(plane, + plane->state, property, val); + break; + } + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/* + * The big monster ioctl + */ + +static struct drm_pending_vblank_event *create_vblank_event( + struct drm_crtc *crtc, uint64_t user_data) +{ + struct drm_pending_vblank_event *e = NULL; + + e = kzalloc(sizeof *e, GFP_KERNEL); + if (!e) + return NULL; + + e->event.base.type = DRM_EVENT_FLIP_COMPLETE; + e->event.base.length = sizeof(e->event); + e->event.vbl.crtc_id = crtc->base.id; + e->event.vbl.user_data = user_data; + + return e; +} + +int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, + struct drm_connector *connector, + int mode) +{ + struct drm_connector *tmp_connector; + struct drm_connector_state *new_conn_state; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int i, ret, old_mode = connector->dpms; + bool active = false; + + ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex, + state->acquire_ctx); + if (ret) + return ret; + + if (mode != DRM_MODE_DPMS_ON) + mode = DRM_MODE_DPMS_OFF; + connector->dpms = mode; + + crtc = connector->state->crtc; + if (!crtc) + goto out; + ret = drm_atomic_add_affected_connectors(state, crtc); + if (ret) + goto out; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + ret = PTR_ERR(crtc_state); + goto out; + } + + for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) { + if (new_conn_state->crtc != crtc) + continue; + if (tmp_connector->dpms == DRM_MODE_DPMS_ON) { + active = true; + break; + } + } + + crtc_state->active = active; + ret = drm_atomic_commit(state); +out: + if (ret != 0) + connector->dpms = old_mode; + return ret; +} + +int drm_atomic_set_property(struct drm_atomic_state *state, + struct drm_mode_object *obj, + struct drm_property *prop, + uint64_t prop_value) +{ + struct drm_mode_object *ref; + int ret; + + if (!drm_property_change_valid_get(prop, prop_value, &ref)) + return -EINVAL; + + switch (obj->type) { + case DRM_MODE_OBJECT_CONNECTOR: { + struct drm_connector *connector = obj_to_connector(obj); + struct drm_connector_state *connector_state; + + connector_state = drm_atomic_get_connector_state(state, connector); + if (IS_ERR(connector_state)) { + ret = PTR_ERR(connector_state); + break; + } + + ret = drm_atomic_connector_set_property(connector, + connector_state, prop, prop_value); + break; + } + case DRM_MODE_OBJECT_CRTC: { + struct drm_crtc *crtc = obj_to_crtc(obj); + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + ret = PTR_ERR(crtc_state); + break; + } + + ret = drm_atomic_crtc_set_property(crtc, + crtc_state, prop, prop_value); + break; + } + case DRM_MODE_OBJECT_PLANE: { + struct drm_plane *plane = obj_to_plane(obj); + struct drm_plane_state *plane_state; + + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) { + ret = PTR_ERR(plane_state); + break; + } + + ret = drm_atomic_plane_set_property(plane, + plane_state, prop, prop_value); + break; + } + default: + ret = -EINVAL; + break; + } + + drm_property_change_valid_put(prop, ref); + return ret; +} + +/** + * DOC: explicit fencing properties + * + * Explicit fencing allows userspace to control the buffer synchronization + * between devices. A Fence or a group of fences are transfered to/from + * userspace using Sync File fds and there are two DRM properties for that. + * IN_FENCE_FD on each DRM Plane to send fences to the kernel and + * OUT_FENCE_PTR on each DRM CRTC to receive fences from the kernel. + * + * As a contrast, with implicit fencing the kernel keeps track of any + * ongoing rendering, and automatically ensures that the atomic update waits + * for any pending rendering to complete. For shared buffers represented with + * a &struct dma_buf this is tracked in &struct reservation_object. + * Implicit syncing is how Linux traditionally worked (e.g. DRI2/3 on X.org), + * whereas explicit fencing is what Android wants. + * + * "IN_FENCE_FD”: + * Use this property to pass a fence that DRM should wait on before + * proceeding with the Atomic Commit request and show the framebuffer for + * the plane on the screen. The fence can be either a normal fence or a + * merged one, the sync_file framework will handle both cases and use a + * fence_array if a merged fence is received. Passing -1 here means no + * fences to wait on. + * + * If the Atomic Commit request has the DRM_MODE_ATOMIC_TEST_ONLY flag + * it will only check if the Sync File is a valid one. + * + * On the driver side the fence is stored on the @fence parameter of + * &struct drm_plane_state. Drivers which also support implicit fencing + * should set the implicit fence using drm_atomic_set_fence_for_plane(), + * to make sure there's consistent behaviour between drivers in precedence + * of implicit vs. explicit fencing. + * + * "OUT_FENCE_PTR”: + * Use this property to pass a file descriptor pointer to DRM. Once the + * Atomic Commit request call returns OUT_FENCE_PTR will be filled with + * the file descriptor number of a Sync File. This Sync File contains the + * CRTC fence that will be signaled when all framebuffers present on the + * Atomic Commit * request for that given CRTC are scanned out on the + * screen. + * + * The Atomic Commit request fails if a invalid pointer is passed. If the + * Atomic Commit request fails for any other reason the out fence fd + * returned will be -1. On a Atomic Commit with the + * DRM_MODE_ATOMIC_TEST_ONLY flag the out fence will also be set to -1. + * + * Note that out-fences don't have a special interface to drivers and are + * internally represented by a &struct drm_pending_vblank_event in struct + * &drm_crtc_state, which is also used by the nonblocking atomic commit + * helpers and for the DRM event handling for existing userspace. + */ + +struct drm_out_fence_state { + s32 __user *out_fence_ptr; + struct sync_file *sync_file; + int fd; +}; + +static int setup_out_fence(struct drm_out_fence_state *fence_state, + struct dma_fence *fence) +{ + fence_state->fd = get_unused_fd_flags(O_CLOEXEC); + if (fence_state->fd < 0) + return fence_state->fd; + + if (put_user(fence_state->fd, fence_state->out_fence_ptr)) + return -EFAULT; + + fence_state->sync_file = sync_file_create(fence); + if (!fence_state->sync_file) + return -ENOMEM; + + return 0; +} + +static int prepare_signaling(struct drm_device *dev, + struct drm_atomic_state *state, + struct drm_mode_atomic *arg, + struct drm_file *file_priv, + struct drm_out_fence_state **fence_state, + unsigned int *num_fences) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_connector *conn; + struct drm_connector_state *conn_state; + int i, c = 0, ret; + + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) + return 0; + + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + s32 __user *fence_ptr; + + fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc); + + if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) { + struct drm_pending_vblank_event *e; + + e = create_vblank_event(crtc, arg->user_data); + if (!e) + return -ENOMEM; + + crtc_state->event = e; + } + + if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { + struct drm_pending_vblank_event *e = crtc_state->event; + + if (!file_priv) + continue; + + ret = drm_event_reserve_init(dev, file_priv, &e->base, + &e->event.base); + if (ret) { + kfree(e); + crtc_state->event = NULL; + return ret; + } + } + + if (fence_ptr) { + struct dma_fence *fence; + struct drm_out_fence_state *f; + + f = krealloc(*fence_state, sizeof(**fence_state) * + (*num_fences + 1), GFP_KERNEL); + if (!f) + return -ENOMEM; + + memset(&f[*num_fences], 0, sizeof(*f)); + + f[*num_fences].out_fence_ptr = fence_ptr; + *fence_state = f; + + fence = drm_crtc_create_fence(crtc); + if (!fence) + return -ENOMEM; + + ret = setup_out_fence(&f[(*num_fences)++], fence); + if (ret) { + dma_fence_put(fence); + return ret; + } + + crtc_state->event->base.fence = fence; + } + + c++; + } + + for_each_new_connector_in_state(state, conn, conn_state, i) { + struct drm_writeback_connector *wb_conn; + struct drm_writeback_job *job; + struct drm_out_fence_state *f; + struct dma_fence *fence; + s32 __user *fence_ptr; + + fence_ptr = get_out_fence_for_connector(state, conn); + if (!fence_ptr) + continue; + + job = drm_atomic_get_writeback_job(conn_state); + if (!job) + return -ENOMEM; + + f = krealloc(*fence_state, sizeof(**fence_state) * + (*num_fences + 1), GFP_KERNEL); + if (!f) + return -ENOMEM; + + memset(&f[*num_fences], 0, sizeof(*f)); + + f[*num_fences].out_fence_ptr = fence_ptr; + *fence_state = f; + + wb_conn = drm_connector_to_writeback(conn); + fence = drm_writeback_get_out_fence(wb_conn); + if (!fence) + return -ENOMEM; + + ret = setup_out_fence(&f[(*num_fences)++], fence); + if (ret) { + dma_fence_put(fence); + return ret; + } + + job->out_fence = fence; + } + + /* + * Having this flag means user mode pends on event which will never + * reach due to lack of at least one CRTC for signaling + */ + if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) + return -EINVAL; + + return 0; +} + +static void complete_signaling(struct drm_device *dev, + struct drm_atomic_state *state, + struct drm_out_fence_state *fence_state, + unsigned int num_fences, + bool install_fds) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int i; + + if (install_fds) { + for (i = 0; i < num_fences; i++) + fd_install(fence_state[i].fd, + fence_state[i].sync_file->file); + + kfree(fence_state); + return; + } + + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + struct drm_pending_vblank_event *event = crtc_state->event; + /* + * Free the allocated event. drm_atomic_helper_setup_commit + * can allocate an event too, so only free it if it's ours + * to prevent a double free in drm_atomic_state_clear. + */ + if (event && (event->base.fence || event->base.file_priv)) { + drm_event_cancel_free(dev, &event->base); + crtc_state->event = NULL; + } + } + + if (!fence_state) + return; + + for (i = 0; i < num_fences; i++) { + if (fence_state[i].sync_file) + fput(fence_state[i].sync_file->file); + if (fence_state[i].fd >= 0) + put_unused_fd(fence_state[i].fd); + + /* If this fails log error to the user */ + if (fence_state[i].out_fence_ptr && + put_user(-1, fence_state[i].out_fence_ptr)) + DRM_DEBUG_ATOMIC("Couldn't clear out_fence_ptr\n"); + } + + kfree(fence_state); +} + +int drm_mode_atomic_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_atomic *arg = data; + uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr); + uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr); + uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr); + uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr); + unsigned int copied_objs, copied_props; + struct drm_atomic_state *state; + struct drm_modeset_acquire_ctx ctx; + struct drm_out_fence_state *fence_state; + int ret = 0; + unsigned int i, j, num_fences; + + /* disallow for drivers not supporting atomic: */ + if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) + return -EINVAL; + + /* disallow for userspace that has not enabled atomic cap (even + * though this may be a bit overkill, since legacy userspace + * wouldn't know how to call this ioctl) + */ + if (!file_priv->atomic) + return -EINVAL; + + if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS) + return -EINVAL; + + if (arg->reserved) + return -EINVAL; + + if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) && + !dev->mode_config.async_page_flip) + return -EINVAL; + + /* can't test and expect an event at the same time. */ + if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) && + (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) + return -EINVAL; + + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); + + state = drm_atomic_state_alloc(dev); + if (!state) + return -ENOMEM; + + state->acquire_ctx = &ctx; + state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); + +retry: + copied_objs = 0; + copied_props = 0; + fence_state = NULL; + num_fences = 0; + + for (i = 0; i < arg->count_objs; i++) { + uint32_t obj_id, count_props; + struct drm_mode_object *obj; + + if (get_user(obj_id, objs_ptr + copied_objs)) { + ret = -EFAULT; + goto out; + } + + obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY); + if (!obj) { + ret = -ENOENT; + goto out; + } + + if (!obj->properties) { + drm_mode_object_put(obj); + ret = -ENOENT; + goto out; + } + + if (get_user(count_props, count_props_ptr + copied_objs)) { + drm_mode_object_put(obj); + ret = -EFAULT; + goto out; + } + + copied_objs++; + + for (j = 0; j < count_props; j++) { + uint32_t prop_id; + uint64_t prop_value; + struct drm_property *prop; + + if (get_user(prop_id, props_ptr + copied_props)) { + drm_mode_object_put(obj); + ret = -EFAULT; + goto out; + } + + prop = drm_mode_obj_find_prop_id(obj, prop_id); + if (!prop) { + drm_mode_object_put(obj); + ret = -ENOENT; + goto out; + } + + if (copy_from_user(&prop_value, + prop_values_ptr + copied_props, + sizeof(prop_value))) { + drm_mode_object_put(obj); + ret = -EFAULT; + goto out; + } + + ret = drm_atomic_set_property(state, obj, prop, + prop_value); + if (ret) { + drm_mode_object_put(obj); + goto out; + } + + copied_props++; + } + + drm_mode_object_put(obj); + } + + ret = prepare_signaling(dev, state, arg, file_priv, &fence_state, + &num_fences); + if (ret) + goto out; + + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { + ret = drm_atomic_check_only(state); + } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { + ret = drm_atomic_nonblocking_commit(state); + } else { + if (unlikely(drm_debug & DRM_UT_STATE)) + drm_atomic_print_state(state); + + ret = drm_atomic_commit(state); + } + +out: + complete_signaling(dev, state, fence_state, num_fences, !ret); + + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry; + } + + drm_atomic_state_put(state); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + + return ret; +} diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 5a84c3bc915d..ce75e9506e85 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index ff5e0d521c21..ede20b55d50c 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -204,6 +204,9 @@ struct drm_minor; int drm_atomic_debugfs_init(struct drm_minor *minor); #endif +void drm_atomic_print_state(const struct drm_atomic_state *state); + +/* drm_atomic_uapi.c */ int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, struct drm_connector *connector, int mode); @@ -213,6 +216,8 @@ int drm_atomic_set_property(struct drm_atomic_state *state, uint64_t prop_value); int drm_atomic_get_property(struct drm_mode_object *obj, struct drm_property *property, uint64_t *val); + +/* IOCTL */ int drm_mode_atomic_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 781af1d42d76..7ca8c77223cb 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "drm_internal.h" diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index 2810d4131411..7607f9cd6f77 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 621f17643bb0..a393756b664e 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a85a83f31979..85cad16f31ed 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index c1f1779c980f..4bcdeca7479d 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -15,6 +15,8 @@ * this program. If not, see . */ +#include + #include "msm_drv.h" #include "msm_gem.h" #include "msm_kms.h" diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 0e6a121858d1..3ce136ba8791 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 6c6d37aa512a..9dc3fcbd290b 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "uapi/drm/vc4_drm.h" #include "vc4_drv.h" diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 66e49ef7d3b5..4aff40886acb 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -584,22 +584,6 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state, return plane->state; } -int __must_check -drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, - const struct drm_display_mode *mode); -int __must_check -drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, - struct drm_property_blob *blob); -int __must_check -drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, - struct drm_crtc *crtc); -void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, - struct drm_framebuffer *fb); -void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, - struct dma_fence *fence); -int __must_check -drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, - struct drm_crtc *crtc); int __must_check drm_atomic_add_affected_connectors(struct drm_atomic_state *state, struct drm_crtc *crtc); diff --git a/include/drm/drm_atomic_uapi.h b/include/drm/drm_atomic_uapi.h new file mode 100644 index 000000000000..8cec52ad1277 --- /dev/null +++ b/include/drm/drm_atomic_uapi.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 Red Hat + * Copyright (C) 2014 Intel Corp. + * Copyright (C) 2018 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#ifndef DRM_ATOMIC_UAPI_H_ +#define DRM_ATOMIC_UAPI_H_ + +struct drm_crtc_state; +struct drm_display_mode; +struct drm_property_blob; +struct drm_plane_state; +struct drm_crtc; +struct drm_connector_state; +struct dma_fence; +struct drm_framebuffer; + +int __must_check +drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, + const struct drm_display_mode *mode); +int __must_check +drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, + struct drm_property_blob *blob); +int __must_check +drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, + struct drm_crtc *crtc); +void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, + struct drm_framebuffer *fb); +void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state, + struct dma_fence *fence); +int __must_check +drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, + struct drm_crtc *crtc); + +#endif From patchwork Mon Sep 3 16:54:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586163 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 16BED139B for ; Mon, 3 Sep 2018 16:55:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 070F328F5D for ; Mon, 3 Sep 2018 16:55:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EFCC528FE7; Mon, 3 Sep 2018 16:55:32 +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=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 4B0E728FE6 for ; Mon, 3 Sep 2018 16:55:32 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D67A76E2B0; Mon, 3 Sep 2018 16:55:00 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8E92A6E2A9 for ; Mon, 3 Sep 2018 16:54:58 +0000 (UTC) Received: by mail-ed1-x541.google.com with SMTP id l5so1231270edw.9 for ; Mon, 03 Sep 2018 09:54:58 -0700 (PDT) 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=H56SPV9nmIPKe3ZPKYV11B/KCshnw8W0NMaZ0Q3jcRQ=; b=HmCNRU3cuWkw3RDa8Xjr9c8pXgLLOsRNmjis3bDb+XlG1Jc9oaI0+3tDoVRHv8i19W pA1W6zo4/3ZzU5yxy/gb30wDOgRCHIun5q9ARfGc/tv4AQVDLS9NZCjuaZNFTy6Wh6ii dPfuHfPACDq3difuNAQzwLyjWRb9pqb3jn+7D6zRmbaXvG3gQcJHJVkTo0CGLQ2i3PMh s2JDcXb+dGmb92fWu3rTx+nXQocZCiKysmWaQO7P54yvuJdASXt7sgsxYAz96FsZ+d9E e2bUL+QxMm+UfxqcivxfRdfcByj9r4qWP56gNEOaF8/vwumyc2BNu8sdb6GHs1DEG+t0 AUwg== X-Gm-Message-State: APzg51Bhq4/gNENfhBKQkGchLSI32CcBnDkKhTBiRGYsqAstZWpLbode 7SEOkYpgHCW74uA2RMQWhP8Wjg== X-Google-Smtp-Source: ANB0Vdb85O5+Nks3tjGj+Ty/HAVGdqKPRWGwPJC+tkqh+SpZwco7UzWisGRvr+YRKRFOQwvP2Shjpw== X-Received: by 2002:a50:98a3:: with SMTP id j32-v6mr31982641edb.6.1535993696986; Mon, 03 Sep 2018 09:54:56 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:56 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:32 +0200 Message-Id: <20180903165439.24845-7-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 07/14] drm/atomic-helper: Unexport drm_atomic_helper_best_encoder 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: Jernej Skrabec , Thomas Hellstrom , VMware Graphics , Sinclair Yeh , David Airlie , Intel Graphics Development , Neil Armstrong , Archit Taneja , Hans Verkuil , Jani Nikula , Russell King , Sean Paul , Laurent Pinchart , Daniel Vetter , Fabio Estevam , Daniel Vetter , Pierre-Hugues Husson MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP It's the default. The exported version was kinda a transition state, before we made this the default. To stop new atomic drivers from using it (instead of just relying on the default) let's unexport it. Signed-off-by: Daniel Vetter Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Cc: David Airlie Cc: VMware Graphics Cc: Sinclair Yeh Cc: Thomas Hellstrom Cc: Archit Taneja Cc: Neil Armstrong Cc: Laurent Pinchart Cc: Hans Verkuil Cc: Daniel Vetter Cc: Russell King Cc: Jernej Skrabec Cc: Jani Nikula Cc: Pierre-Hugues Husson Cc: Fabio Estevam --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 - drivers/gpu/drm/drm_atomic_helper.c | 24 +++++++---------------- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 1 - include/drm/drm_atomic_helper.h | 2 -- 6 files changed, 7 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 5971976284bf..0aed51799526 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1957,7 +1957,6 @@ static const struct drm_connector_funcs dw_hdmi_connector_funcs = { static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { .get_modes = dw_hdmi_connector_get_modes, - .best_encoder = drm_atomic_helper_best_encoder, }; static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 8469a7e9afe3..334b121bd4d9 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -92,6 +92,13 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state, } } +static struct drm_encoder * +drm_atomic_helper_best_encoder(struct drm_connector *connector) +{ + WARN_ON(connector->encoder_ids[1]); + return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); +} + static int handle_conflicting_encoders(struct drm_atomic_state *state, bool disable_conflicting_encoders) { @@ -3376,23 +3383,6 @@ int drm_atomic_helper_page_flip_target(struct drm_crtc *crtc, } EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); -/** - * drm_atomic_helper_best_encoder - Helper for - * &drm_connector_helper_funcs.best_encoder callback - * @connector: Connector control structure - * - * This is a &drm_connector_helper_funcs.best_encoder callback helper for - * connectors that support exactly 1 encoder, statically determined at driver - * init time. - */ -struct drm_encoder * -drm_atomic_helper_best_encoder(struct drm_connector *connector) -{ - WARN_ON(connector->encoder_ids[1]); - return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); -} -EXPORT_SYMBOL(drm_atomic_helper_best_encoder); - /** * DOC: atomic state reset and initialization * diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 723578117191..4b5378495eea 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -274,7 +274,6 @@ static const struct drm_connector_funcs vmw_legacy_connector_funcs = { static const struct drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = { - .best_encoder = drm_atomic_helper_best_encoder, }; /* diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index ad0de7f0cd60..4c68ad6f3605 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -389,7 +389,6 @@ static const struct drm_connector_funcs vmw_sou_connector_funcs = { static const struct drm_connector_helper_funcs vmw_sou_connector_helper_funcs = { - .best_encoder = drm_atomic_helper_best_encoder, }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 93f6b96ca7bb..f5b2fe8a7793 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -1037,7 +1037,6 @@ static const struct drm_connector_funcs vmw_stdu_connector_funcs = { static const struct drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = { - .best_encoder = drm_atomic_helper_best_encoder, }; diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 63e736eeb516..27aef91ca1c3 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -144,8 +144,6 @@ int drm_atomic_helper_page_flip_target( uint32_t flags, uint32_t target, struct drm_modeset_acquire_ctx *ctx); -struct drm_encoder * -drm_atomic_helper_best_encoder(struct drm_connector *connector); /* default implementations for state handling */ void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); From patchwork Mon Sep 3 16:54:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586167 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 4C5675A4 for ; Mon, 3 Sep 2018 16:55:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C54928CDB for ; Mon, 3 Sep 2018 16:55:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 30AAA28FE6; Mon, 3 Sep 2018 16:55:34 +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=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 CFA4428F5D for ; Mon, 3 Sep 2018 16:55:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BF0266E2B3; Mon, 3 Sep 2018 16:55:01 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by gabe.freedesktop.org (Postfix) with ESMTPS id 932FD6E2AA for ; Mon, 3 Sep 2018 16:54:59 +0000 (UTC) Received: by mail-ed1-x542.google.com with SMTP id z27-v6so1225486edb.10 for ; Mon, 03 Sep 2018 09:54:59 -0700 (PDT) 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=E/Viq/vk8oLVECyECf90Tr3EY2N7vTs6tECo1N3dKAE=; b=DXQ00iCCu9JIzB6YHh0Fq5T2h7oGoKv5mLD5hgCV0oaT/R4OSUhM7bdtT1ALL97XpQ 1KU0+kJPATqlwub9cfhacVu37aB6lzoyGcS+t4jyT5RFDxI3aOchDVq9/zIt1ZLY9s9e TR23SPJ18rt5PXOQIBKEvZhDmro3RwyRf8ZUjF7JsbHVke9mep1WQAGPEYEUwK9QrInt uBPswTRkpGiGjpEg4qbOtw/NV6zfRXgvVriK16M3GroWPO/pOLW1UhDTE55JGGdqPwD8 X+KGC2I5NllrUZlw/nVFxt2CrqvRNcx76v81qxXNNQOkrcKebQ/kTbt/IfHVMHztBi6+ WNfw== X-Gm-Message-State: APzg51CaQI6HRY5miKVRxk4KTJiQJUyrU0yUCk51nSX4Gi5tOxnvxH4a kd/+awvrs9y+DXSgYwMsDdviclFN2vgEXg== X-Google-Smtp-Source: ANB0VdbGFSJ4IxjgDQ/saaYbuNGoWDVwNFqBzd2kQLjVHe2f+g6cIQcAwuL8aMjbEVFN+ZER1y+leQ== X-Received: by 2002:aa7:cdc4:: with SMTP id h4-v6mr897459edw.314.1535993698280; Mon, 03 Sep 2018 09:54:58 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:57 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:33 +0200 Message-Id: <20180903165439.24845-8-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 08/14] drm/amdgpu: Remove default best_encoder hook from DC 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: Andrey Grodzovsky , "Leo \(Sunpeng\) Li" , Daniel Vetter , Intel Graphics Development , Shirish S , Tony Cheng , Alex Deucher , Daniel Vetter , Harry Wentland MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP For atomic driver this is the default, no need to reimplement it. We still need to keep the copypasta for not-atomic drivers though, since no one polished the legacy crtc helpers as much as the atomic ones. Signed-off-by: Daniel Vetter Cc: Alex Deucher Cc: Harry Wentland Cc: Andrey Grodzovsky Cc: Tony Cheng Cc: "Leo (Sunpeng) Li" Cc: Shirish S --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index af6adffba788..333f9904f135 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2794,28 +2794,6 @@ static const struct drm_connector_funcs amdgpu_dm_connector_funcs = { .atomic_get_property = amdgpu_dm_connector_atomic_get_property }; -static struct drm_encoder *best_encoder(struct drm_connector *connector) -{ - int enc_id = connector->encoder_ids[0]; - struct drm_mode_object *obj; - struct drm_encoder *encoder; - - DRM_DEBUG_DRIVER("Finding the best encoder\n"); - - /* pick the encoder ids */ - if (enc_id) { - obj = drm_mode_object_find(connector->dev, NULL, enc_id, DRM_MODE_OBJECT_ENCODER); - if (!obj) { - DRM_ERROR("Couldn't find a matching encoder for our connector\n"); - return NULL; - } - encoder = obj_to_encoder(obj); - return encoder; - } - DRM_ERROR("No encoder id\n"); - return NULL; -} - static int get_modes(struct drm_connector *connector) { return amdgpu_dm_connector_get_modes(connector); @@ -2934,7 +2912,6 @@ amdgpu_dm_connector_helper_funcs = { */ .get_modes = get_modes, .mode_valid = amdgpu_dm_connector_mode_valid, - .best_encoder = best_encoder }; static void dm_crtc_helper_disable(struct drm_crtc *crtc) From patchwork Mon Sep 3 16:54:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586171 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 749C5139B for ; Mon, 3 Sep 2018 16:55:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6170028A73 for ; Mon, 3 Sep 2018 16:55:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55BDA28F5D; Mon, 3 Sep 2018 16:55:39 +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=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 C774328A73 for ; Mon, 3 Sep 2018 16:55:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1766A6E2BA; Mon, 3 Sep 2018 16:55:04 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x543.google.com (mail-ed1-x543.google.com [IPv6:2a00:1450:4864:20::543]) by gabe.freedesktop.org (Postfix) with ESMTPS id 71C276E2B4 for ; Mon, 3 Sep 2018 16:55:01 +0000 (UTC) Received: by mail-ed1-x543.google.com with SMTP id s10-v6so1222275edb.11 for ; Mon, 03 Sep 2018 09:55:01 -0700 (PDT) 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=X/DTwVJgPOwCe0xrkr+eC1b7m1x1DJ1CXytm3QZi7uU=; b=kb/POorjqgBiuhkpHgb5/gQLKJKek4Hndn5YLI4a/xmJeVRypzRXFleZCQ8FdSOqu9 XzwjIp7ZCs3Wloy5Q44KFyEKZ2nONbDMXwy2ZGRTPQgHvCwqGQVaPMA41HjLRa5JhfKD ZBdDfk3L1rblwOmjzHHPI+HqDwifb7xdwfkcrxtFCU0pS4WxDBxUPP6gn9eMPrTqdV5u lgqPIDgGynosByVjx1VvBwxKEsOWidQO6HOJDzqMuOX4bL8MuOGRqWqldx9vk3LvNPYp eQtVpuEVzYN29RzhnEUEc3SB/o79o1M16f3YOmHX1ZQiVUsmnPlLbb8t+CEgmR6SoybI 9p9g== X-Gm-Message-State: APzg51CfohCPXhq2Q8e81D1VlfHyqAVZzCqHRxgtpOkHnnN3C2UstEJX QoUe4OfXK+zvdwobUZpCpOdP/Q== X-Google-Smtp-Source: ANB0VdZik53nprEJFXPOvADi3esuV32Ed/+lw4LzCG1Uov1v9fOaWiT8edMf2+Ah1HOFP6m8h4gVqA== X-Received: by 2002:a50:d1c7:: with SMTP id i7-v6mr31532961edg.169.1535993700101; Mon, 03 Sep 2018 09:55:00 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.54.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:54:58 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:34 +0200 Message-Id: <20180903165439.24845-9-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 09/14] drm: Update todo.rst 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 , Daniel Vetter , Intel Graphics Development , Sean Paul MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP - drmP.h is now fully split up. - vkms is happening (and will gain its own todo and docs under a new vkms.rst file real soon) - legacy cruft is completely hidden now, drm_vblank.c is split out from drm_irq.c now. - best_encoder atomic cleanup is done (it's now the default, not even exported anymore) - bunch of smaller things Signed-off-by: Daniel Vetter Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Cc: David Airlie --- Documentation/gpu/todo.rst | 68 ++++++-------------------------------- 1 file changed, 10 insertions(+), 58 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index a7c150d6b63f..96bfdbc9ebff 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -127,7 +127,8 @@ interfaces to fix these issues: the acquire context explicitly on stack and then also pass it down into drivers explicitly so that the legacy-on-atomic functions can use them. - Except for some driver code this is done. + Except for some driver code this is done. This task should be finished by + adding WARN_ON(!drm_drv_uses_atomic_modeset) in drm_modeset_lock_all(). * A bunch of the vtable hooks are now in the wrong place: DRM has a split between core vfunc tables (named ``drm_foo_funcs``), which are used to @@ -137,13 +138,6 @@ interfaces to fix these issues: ``_helper_funcs`` since they are not part of the core ABI. There's a ``FIXME`` comment in the kerneldoc for each such case in ``drm_crtc.h``. -* There's a new helper ``drm_atomic_helper_best_encoder()`` which could be - used by all atomic drivers which don't select the encoder for a given - connector at runtime. That's almost all of them, and would allow us to get - rid of a lot of ``best_encoder`` boilerplate in drivers. - - This was almost done, but new drivers added a few more cases again. - Contact: Daniel Vetter Get rid of dev->struct_mutex from GEM drivers @@ -164,9 +158,8 @@ private lock. The tricky part is the BO free functions, since those can't reliably take that lock any more. Instead state needs to be protected with suitable subordinate locks or some cleanup work pushed to a worker thread. For performance-critical drivers it might also be better to go with a more -fine-grained per-buffer object and per-context lockings scheme. Currently the -following drivers still use ``struct_mutex``: ``msm``, ``omapdrm`` and -``udl``. +fine-grained per-buffer object and per-context lockings scheme. Currently only the +``msm`` driver still use ``struct_mutex``. Contact: Daniel Vetter, respective driver maintainers @@ -190,7 +183,8 @@ Convert drivers to use simple modeset suspend/resume Most drivers (except i915 and nouveau) that use drm_atomic_helper_suspend/resume() can probably be converted to use -drm_mode_config_helper_suspend/resume(). +drm_mode_config_helper_suspend/resume(). Also there's still open-coded version +of the atomic suspend/resume code in older atomic modeset drivers. Contact: Maintainer of the driver you plan to convert @@ -246,20 +240,10 @@ Core refactorings Clean up the DRM header mess ---------------------------- -Currently the DRM subsystem has only one global header, ``drmP.h``. This is -used both for functions exported to helper libraries and drivers and functions -only used internally in the ``drm.ko`` module. The goal would be to move all -header declarations not needed outside of ``drm.ko`` into -``drivers/gpu/drm/drm_*_internal.h`` header files. ``EXPORT_SYMBOL`` also -needs to be dropped for these functions. - -This would nicely tie in with the below task to create kerneldoc after the API -is cleaned up. Or with the "hide legacy cruft better" task. - -Note that this is well in progress, but ``drmP.h`` is still huge. The updated -plan is to switch to per-file driver API headers, which will also structure -the kerneldoc better. This should also allow more fine-grained ``#include`` -directives. +The DRM subsystem originally had only one huge globale header, ``drmP.h``. This +is not split up, but many source files still include it. The remainig part of +the cleanup work here is to replace any ``#include `` by only the +headers needed (and fixing up any missing pre-declarations in the headers). In the end no .c file should need to include ``drmP.h`` anymore. @@ -278,26 +262,6 @@ See https://dri.freedesktop.org/docs/drm/ for what's there already. Contact: Daniel Vetter -Hide legacy cruft better ------------------------- - -Way back DRM supported only drivers which shadow-attached to PCI devices with -userspace or fbdev drivers setting up outputs. Modern DRM drivers take charge -of the entire device, you can spot them with the DRIVER_MODESET flag. - -Unfortunately there's still large piles of legacy code around which needs to -be hidden so that driver writers don't accidentally end up using it. And to -prevent security issues in those legacy IOCTLs from being exploited on modern -drivers. This has multiple possible subtasks: - -* Extract support code for legacy features into a ``drm-legacy.ko`` kernel - module and compile it only when one of the legacy drivers is enabled. - -This is mostly done, the only thing left is to split up ``drm_irq.c`` into -legacy cruft and the parts needed by modern KMS drivers. - -Contact: Daniel Vetter - Make panic handling work ------------------------ @@ -398,18 +362,6 @@ the non-i915 specific modeset tests. Contact: Daniel Vetter -Create a virtual KMS driver for testing (vkms) ----------------------------------------------- - -With all the latest helpers it should be fairly simple to create a virtual KMS -driver useful for testing, or for running X or similar on headless machines -(to be able to still use the GPU). This would be similar to vgem, but aimed at -the modeset side. - -Once the basics are there there's tons of possibilities to extend it. - -Contact: Daniel Vetter - Driver Specific =============== From patchwork Mon Sep 3 16:54:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586177 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 E8765139B for ; Mon, 3 Sep 2018 16:55:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D278528A73 for ; Mon, 3 Sep 2018 16:55:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C6B4B28F5D; Mon, 3 Sep 2018 16:55:52 +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=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 BD53328A73 for ; Mon, 3 Sep 2018 16:55:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BB58B6E2B8; Mon, 3 Sep 2018 16:55:05 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by gabe.freedesktop.org (Postfix) with ESMTPS id AF7246E2B8 for ; Mon, 3 Sep 2018 16:55:03 +0000 (UTC) Received: by mail-ed1-x541.google.com with SMTP id a20-v6so1243569edd.4 for ; Mon, 03 Sep 2018 09:55:03 -0700 (PDT) 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=gM5LezGetyR6Dcp811RyZmpTzpvEQKvfwsbodLKq1HU=; b=JTYF8RJ/E48Ryc2iCusLMyQdjbUvfApI9eZw1CdFMT1rYpKvSiZojNFejwbkqpp4R1 ZmQ7BQEWk1bMDHAheV0z3nPHKTLXExKaWApgp1i0fd4M4+gBxr6YDfv35eqnhGk0mflw X5J9R6wQz6mixXBipAoWIeP1PC11HZkaSRuyQhF7VpSmcncETnACBzef+UKi7M6JvB/K 7py0D9pAyELmQvOPpYkvI57c4MRxT8DKPPgBezju5s6mPm9tspEozatkXcjx+HxQt/RW f2oWJ+RNdhB3pugHI1t36SBNMEFTZqxkxJfeK+CsRry19HdjcMZd4+U5gLQmBfED4DaH CoOA== X-Gm-Message-State: APzg51AqBBHcHpH1mRlvsqJqk1yWiscv9mueIkDn9hv1N6Jz6RG0rJ43 psu7oGIlwdBcOFlXy9FfERBvbLsto7+eDA== X-Google-Smtp-Source: ANB0VdbsefQEZ/gXWCSyVs6OohN/2wjrAhTbg+8Z89r/I+7lfU7VmLsJH/JWpLLeuLZ1EghsXyQ+Nw== X-Received: by 2002:a50:95a8:: with SMTP id w37-v6mr1071129eda.33.1535993701602; Mon, 03 Sep 2018 09:55:01 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.55.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:55:00 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:35 +0200 Message-Id: <20180903165439.24845-10-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 10/14] drm: Extract drm_atomic_state_helper.[hc] 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 , Intel Graphics Development , Daniel Vetter MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP We already have a separate overview doc for this, makes sense to untangle it from the overall atomic helpers. Signed-off-by: Daniel Vetter --- Documentation/gpu/drm-kms-helpers.rst | 19 +- drivers/gpu/drm/Makefile | 3 +- drivers/gpu/drm/drm_atomic_helper.c | 568 -------------------- drivers/gpu/drm/drm_atomic_state_helper.c | 603 ++++++++++++++++++++++ include/drm/drm_atomic_helper.h | 44 +- include/drm/drm_atomic_state_helper.h | 80 +++ 6 files changed, 700 insertions(+), 617 deletions(-) create mode 100644 drivers/gpu/drm/drm_atomic_state_helper.c create mode 100644 include/drm/drm_atomic_state_helper.h diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index f9cfcdcdf024..4b4dc236ef6f 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -59,19 +59,28 @@ Implementing Asynchronous Atomic Commit .. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c :doc: implementing nonblocking commit +Helper Functions Reference +-------------------------- + +.. kernel-doc:: include/drm/drm_atomic_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :export: + Atomic State Reset and Initialization ------------------------------------- -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c +.. kernel-doc:: drivers/gpu/drm/drm_atomic_state_helper.c :doc: atomic state reset and initialization -Helper Functions Reference --------------------------- +Atomic State Helper Reference +----------------------------- -.. kernel-doc:: include/drm/drm_atomic_helper.h +.. kernel-doc:: include/drm/drm_atomic_state_helper.h :internal: -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c +.. kernel-doc:: drivers/gpu/drm/drm_atomic_state_helper.c :export: Simple KMS Helper Reference diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index bc6a16a3c36e..576ba985e138 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -36,7 +36,8 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ drm_simple_kms_helper.o drm_modeset_helper.o \ - drm_scdc_helper.o drm_gem_framebuffer_helper.o + drm_scdc_helper.o drm_gem_framebuffer_helper.o \ + drm_atomic_state_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 334b121bd4d9..a5edc8757056 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3382,571 +3382,3 @@ int drm_atomic_helper_page_flip_target(struct drm_crtc *crtc, return ret; } EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); - -/** - * DOC: atomic state reset and initialization - * - * Both the drm core and the atomic helpers assume that there is always the full - * and correct atomic software state for all connectors, CRTCs and planes - * available. Which is a bit a problem on driver load and also after system - * suspend. One way to solve this is to have a hardware state read-out - * infrastructure which reconstructs the full software state (e.g. the i915 - * driver). - * - * The simpler solution is to just reset the software state to everything off, - * which is easiest to do by calling drm_mode_config_reset(). To facilitate this - * the atomic helpers provide default reset implementations for all hooks. - * - * On the upside the precise state tracking of atomic simplifies system suspend - * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe - * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume(). - * For other drivers the building blocks are split out, see the documentation - * for these functions. - */ - -/** - * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs - * @crtc: drm CRTC - * - * Resets the atomic state for @crtc by freeing the state pointer (which might - * be NULL, e.g. at driver load time) and allocating a new empty state object. - */ -void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) -{ - if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); - - kfree(crtc->state); - crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); - - if (crtc->state) - crtc->state->crtc = crtc; -} -EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); - -/** - * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state - * @crtc: CRTC object - * @state: atomic CRTC state - * - * Copies atomic state from a CRTC's current state and resets inferred values. - * This is useful for drivers that subclass the CRTC state. - */ -void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, - struct drm_crtc_state *state) -{ - memcpy(state, crtc->state, sizeof(*state)); - - if (state->mode_blob) - drm_property_blob_get(state->mode_blob); - if (state->degamma_lut) - drm_property_blob_get(state->degamma_lut); - if (state->ctm) - drm_property_blob_get(state->ctm); - if (state->gamma_lut) - drm_property_blob_get(state->gamma_lut); - state->mode_changed = false; - state->active_changed = false; - state->planes_changed = false; - state->connectors_changed = false; - state->color_mgmt_changed = false; - state->zpos_changed = false; - state->commit = NULL; - state->event = NULL; - state->pageflip_flags = 0; -} -EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); - -/** - * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook - * @crtc: drm CRTC - * - * Default CRTC state duplicate hook for drivers which don't have their own - * subclassed CRTC state structure. - */ -struct drm_crtc_state * -drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc) -{ - struct drm_crtc_state *state; - - if (WARN_ON(!crtc->state)) - return NULL; - - state = kmalloc(sizeof(*state), GFP_KERNEL); - if (state) - __drm_atomic_helper_crtc_duplicate_state(crtc, state); - - return state; -} -EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); - -/** - * __drm_atomic_helper_crtc_destroy_state - release CRTC state - * @state: CRTC state object to release - * - * Releases all resources stored in the CRTC state without actually freeing - * the memory of the CRTC state. This is useful for drivers that subclass the - * CRTC state. - */ -void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) -{ - if (state->commit) { - /* - * In the event that a non-blocking commit returns - * -ERESTARTSYS before the commit_tail work is queued, we will - * have an extra reference to the commit object. Release it, if - * the event has not been consumed by the worker. - * - * state->event may be freed, so we can't directly look at - * state->event->base.completion. - */ - if (state->event && state->commit->abort_completion) - drm_crtc_commit_put(state->commit); - - kfree(state->commit->event); - state->commit->event = NULL; - - drm_crtc_commit_put(state->commit); - } - - drm_property_blob_put(state->mode_blob); - drm_property_blob_put(state->degamma_lut); - drm_property_blob_put(state->ctm); - drm_property_blob_put(state->gamma_lut); -} -EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); - -/** - * drm_atomic_helper_crtc_destroy_state - default state destroy hook - * @crtc: drm CRTC - * @state: CRTC state object to release - * - * Default CRTC state destroy hook for drivers which don't have their own - * subclassed CRTC state structure. - */ -void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, - struct drm_crtc_state *state) -{ - __drm_atomic_helper_crtc_destroy_state(state); - kfree(state); -} -EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); - -/** - * __drm_atomic_helper_plane_reset - resets planes state to default values - * @plane: plane object, must not be NULL - * @state: atomic plane state, must not be NULL - * - * Initializes plane state to default. This is useful for drivers that subclass - * the plane state. - */ -void __drm_atomic_helper_plane_reset(struct drm_plane *plane, - struct drm_plane_state *state) -{ - state->plane = plane; - state->rotation = DRM_MODE_ROTATE_0; - - /* Reset the alpha value to fully opaque if it matters */ - if (plane->alpha_property) - state->alpha = plane->alpha_property->values[1]; - state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; - - plane->state = state; -} -EXPORT_SYMBOL(__drm_atomic_helper_plane_reset); - -/** - * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes - * @plane: drm plane - * - * Resets the atomic state for @plane by freeing the state pointer (which might - * be NULL, e.g. at driver load time) and allocating a new empty state object. - */ -void drm_atomic_helper_plane_reset(struct drm_plane *plane) -{ - if (plane->state) - __drm_atomic_helper_plane_destroy_state(plane->state); - - kfree(plane->state); - plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); - if (plane->state) - __drm_atomic_helper_plane_reset(plane, plane->state); -} -EXPORT_SYMBOL(drm_atomic_helper_plane_reset); - -/** - * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state - * @plane: plane object - * @state: atomic plane state - * - * Copies atomic state from a plane's current state. This is useful for - * drivers that subclass the plane state. - */ -void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, - struct drm_plane_state *state) -{ - memcpy(state, plane->state, sizeof(*state)); - - if (state->fb) - drm_framebuffer_get(state->fb); - - state->fence = NULL; - state->commit = NULL; -} -EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); - -/** - * drm_atomic_helper_plane_duplicate_state - default state duplicate hook - * @plane: drm plane - * - * Default plane state duplicate hook for drivers which don't have their own - * subclassed plane state structure. - */ -struct drm_plane_state * -drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane) -{ - struct drm_plane_state *state; - - if (WARN_ON(!plane->state)) - return NULL; - - state = kmalloc(sizeof(*state), GFP_KERNEL); - if (state) - __drm_atomic_helper_plane_duplicate_state(plane, state); - - return state; -} -EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); - -/** - * __drm_atomic_helper_plane_destroy_state - release plane state - * @state: plane state object to release - * - * Releases all resources stored in the plane state without actually freeing - * the memory of the plane state. This is useful for drivers that subclass the - * plane state. - */ -void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) -{ - if (state->fb) - drm_framebuffer_put(state->fb); - - if (state->fence) - dma_fence_put(state->fence); - - if (state->commit) - drm_crtc_commit_put(state->commit); -} -EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); - -/** - * drm_atomic_helper_plane_destroy_state - default state destroy hook - * @plane: drm plane - * @state: plane state object to release - * - * Default plane state destroy hook for drivers which don't have their own - * subclassed plane state structure. - */ -void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, - struct drm_plane_state *state) -{ - __drm_atomic_helper_plane_destroy_state(state); - kfree(state); -} -EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); - -/** - * __drm_atomic_helper_connector_reset - reset state on connector - * @connector: drm connector - * @conn_state: connector state to assign - * - * Initializes the newly allocated @conn_state and assigns it to - * the &drm_conector->state pointer of @connector, usually required when - * initializing the drivers or when called from the &drm_connector_funcs.reset - * hook. - * - * This is useful for drivers that subclass the connector state. - */ -void -__drm_atomic_helper_connector_reset(struct drm_connector *connector, - struct drm_connector_state *conn_state) -{ - if (conn_state) - conn_state->connector = connector; - - connector->state = conn_state; -} -EXPORT_SYMBOL(__drm_atomic_helper_connector_reset); - -/** - * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors - * @connector: drm connector - * - * Resets the atomic state for @connector by freeing the state pointer (which - * might be NULL, e.g. at driver load time) and allocating a new empty state - * object. - */ -void drm_atomic_helper_connector_reset(struct drm_connector *connector) -{ - struct drm_connector_state *conn_state = - kzalloc(sizeof(*conn_state), GFP_KERNEL); - - if (connector->state) - __drm_atomic_helper_connector_destroy_state(connector->state); - - kfree(connector->state); - __drm_atomic_helper_connector_reset(connector, conn_state); -} -EXPORT_SYMBOL(drm_atomic_helper_connector_reset); - -/** - * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state - * @connector: connector object - * @state: atomic connector state - * - * Copies atomic state from a connector's current state. This is useful for - * drivers that subclass the connector state. - */ -void -__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, - struct drm_connector_state *state) -{ - memcpy(state, connector->state, sizeof(*state)); - if (state->crtc) - drm_connector_get(connector); - state->commit = NULL; - - /* Don't copy over a writeback job, they are used only once */ - state->writeback_job = NULL; -} -EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state); - -/** - * drm_atomic_helper_connector_duplicate_state - default state duplicate hook - * @connector: drm connector - * - * Default connector state duplicate hook for drivers which don't have their own - * subclassed connector state structure. - */ -struct drm_connector_state * -drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector) -{ - struct drm_connector_state *state; - - if (WARN_ON(!connector->state)) - return NULL; - - state = kmalloc(sizeof(*state), GFP_KERNEL); - if (state) - __drm_atomic_helper_connector_duplicate_state(connector, state); - - return state; -} -EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state); - -/** - * drm_atomic_helper_duplicate_state - duplicate an atomic state object - * @dev: DRM device - * @ctx: lock acquisition context - * - * Makes a copy of the current atomic state by looping over all objects and - * duplicating their respective states. This is used for example by suspend/ - * resume support code to save the state prior to suspend such that it can - * be restored upon resume. - * - * Note that this treats atomic state as persistent between save and restore. - * Drivers must make sure that this is possible and won't result in confusion - * or erroneous behaviour. - * - * Note that if callers haven't already acquired all modeset locks this might - * return -EDEADLK, which must be handled by calling drm_modeset_backoff(). - * - * Returns: - * A pointer to the copy of the atomic state object on success or an - * ERR_PTR()-encoded error code on failure. - * - * See also: - * drm_atomic_helper_suspend(), drm_atomic_helper_resume() - */ -struct drm_atomic_state * -drm_atomic_helper_duplicate_state(struct drm_device *dev, - struct drm_modeset_acquire_ctx *ctx) -{ - struct drm_atomic_state *state; - struct drm_connector *conn; - struct drm_connector_list_iter conn_iter; - struct drm_plane *plane; - struct drm_crtc *crtc; - int err = 0; - - state = drm_atomic_state_alloc(dev); - if (!state) - return ERR_PTR(-ENOMEM); - - state->acquire_ctx = ctx; - - drm_for_each_crtc(crtc, dev) { - struct drm_crtc_state *crtc_state; - - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) { - err = PTR_ERR(crtc_state); - goto free; - } - } - - drm_for_each_plane(plane, dev) { - struct drm_plane_state *plane_state; - - plane_state = drm_atomic_get_plane_state(state, plane); - if (IS_ERR(plane_state)) { - err = PTR_ERR(plane_state); - goto free; - } - } - - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(conn, &conn_iter) { - struct drm_connector_state *conn_state; - - conn_state = drm_atomic_get_connector_state(state, conn); - if (IS_ERR(conn_state)) { - err = PTR_ERR(conn_state); - drm_connector_list_iter_end(&conn_iter); - goto free; - } - } - drm_connector_list_iter_end(&conn_iter); - - /* clear the acquire context so that it isn't accidentally reused */ - state->acquire_ctx = NULL; - -free: - if (err < 0) { - drm_atomic_state_put(state); - state = ERR_PTR(err); - } - - return state; -} -EXPORT_SYMBOL(drm_atomic_helper_duplicate_state); - -/** - * __drm_atomic_helper_connector_destroy_state - release connector state - * @state: connector state object to release - * - * Releases all resources stored in the connector state without actually - * freeing the memory of the connector state. This is useful for drivers that - * subclass the connector state. - */ -void -__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state) -{ - if (state->crtc) - drm_connector_put(state->connector); - - if (state->commit) - drm_crtc_commit_put(state->commit); -} -EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); - -/** - * drm_atomic_helper_connector_destroy_state - default state destroy hook - * @connector: drm connector - * @state: connector state object to release - * - * Default connector state destroy hook for drivers which don't have their own - * subclassed connector state structure. - */ -void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, - struct drm_connector_state *state) -{ - __drm_atomic_helper_connector_destroy_state(state); - kfree(state); -} -EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); - -/** - * drm_atomic_helper_legacy_gamma_set - set the legacy gamma correction table - * @crtc: CRTC object - * @red: red correction table - * @green: green correction table - * @blue: green correction table - * @size: size of the tables - * @ctx: lock acquire context - * - * Implements support for legacy gamma correction table for drivers - * that support color management through the DEGAMMA_LUT/GAMMA_LUT - * properties. See drm_crtc_enable_color_mgmt() and the containing chapter for - * how the atomic color management and gamma tables work. - */ -int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, - u16 *red, u16 *green, u16 *blue, - uint32_t size, - struct drm_modeset_acquire_ctx *ctx) -{ - struct drm_device *dev = crtc->dev; - struct drm_atomic_state *state; - struct drm_crtc_state *crtc_state; - struct drm_property_blob *blob = NULL; - struct drm_color_lut *blob_data; - int i, ret = 0; - bool replaced; - - state = drm_atomic_state_alloc(crtc->dev); - if (!state) - return -ENOMEM; - - blob = drm_property_create_blob(dev, - sizeof(struct drm_color_lut) * size, - NULL); - if (IS_ERR(blob)) { - ret = PTR_ERR(blob); - blob = NULL; - goto fail; - } - - /* Prepare GAMMA_LUT with the legacy values. */ - blob_data = blob->data; - for (i = 0; i < size; i++) { - blob_data[i].red = red[i]; - blob_data[i].green = green[i]; - blob_data[i].blue = blue[i]; - } - - state->acquire_ctx = ctx; - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) { - ret = PTR_ERR(crtc_state); - goto fail; - } - - /* Reset DEGAMMA_LUT and CTM properties. */ - replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL); - replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL); - replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob); - crtc_state->color_mgmt_changed |= replaced; - - ret = drm_atomic_commit(state); - -fail: - drm_atomic_state_put(state); - drm_property_blob_put(blob); - return ret; -} -EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set); - -/** - * __drm_atomic_helper_private_duplicate_state - copy atomic private state - * @obj: CRTC object - * @state: new private object state - * - * Copies atomic state from a private objects's current state and resets inferred values. - * This is useful for drivers that subclass the private state. - */ -void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, - struct drm_private_state *state) -{ - memcpy(state, obj->state, sizeof(*state)); -} -EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state); diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c new file mode 100644 index 000000000000..6c6499b9dbea --- /dev/null +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -0,0 +1,603 @@ +/* + * Copyright (C) 2018 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + * DOC: atomic state reset and initialization + * + * Both the drm core and the atomic helpers assume that there is always the full + * and correct atomic software state for all connectors, CRTCs and planes + * available. Which is a bit a problem on driver load and also after system + * suspend. One way to solve this is to have a hardware state read-out + * infrastructure which reconstructs the full software state (e.g. the i915 + * driver). + * + * The simpler solution is to just reset the software state to everything off, + * which is easiest to do by calling drm_mode_config_reset(). To facilitate this + * the atomic helpers provide default reset implementations for all hooks. + * + * On the upside the precise state tracking of atomic simplifies system suspend + * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe + * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume(). + * For other drivers the building blocks are split out, see the documentation + * for these functions. + */ + +/** + * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs + * @crtc: drm CRTC + * + * Resets the atomic state for @crtc by freeing the state pointer (which might + * be NULL, e.g. at driver load time) and allocating a new empty state object. + */ +void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) +{ + if (crtc->state) + __drm_atomic_helper_crtc_destroy_state(crtc->state); + + kfree(crtc->state); + crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); + + if (crtc->state) + crtc->state->crtc = crtc; +} +EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); + +/** + * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state + * @crtc: CRTC object + * @state: atomic CRTC state + * + * Copies atomic state from a CRTC's current state and resets inferred values. + * This is useful for drivers that subclass the CRTC state. + */ +void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + memcpy(state, crtc->state, sizeof(*state)); + + if (state->mode_blob) + drm_property_blob_get(state->mode_blob); + if (state->degamma_lut) + drm_property_blob_get(state->degamma_lut); + if (state->ctm) + drm_property_blob_get(state->ctm); + if (state->gamma_lut) + drm_property_blob_get(state->gamma_lut); + state->mode_changed = false; + state->active_changed = false; + state->planes_changed = false; + state->connectors_changed = false; + state->color_mgmt_changed = false; + state->zpos_changed = false; + state->commit = NULL; + state->event = NULL; + state->pageflip_flags = 0; +} +EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); + +/** + * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook + * @crtc: drm CRTC + * + * Default CRTC state duplicate hook for drivers which don't have their own + * subclassed CRTC state structure. + */ +struct drm_crtc_state * +drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc) +{ + struct drm_crtc_state *state; + + if (WARN_ON(!crtc->state)) + return NULL; + + state = kmalloc(sizeof(*state), GFP_KERNEL); + if (state) + __drm_atomic_helper_crtc_duplicate_state(crtc, state); + + return state; +} +EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); + +/** + * __drm_atomic_helper_crtc_destroy_state - release CRTC state + * @state: CRTC state object to release + * + * Releases all resources stored in the CRTC state without actually freeing + * the memory of the CRTC state. This is useful for drivers that subclass the + * CRTC state. + */ +void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) +{ + if (state->commit) { + /* + * In the event that a non-blocking commit returns + * -ERESTARTSYS before the commit_tail work is queued, we will + * have an extra reference to the commit object. Release it, if + * the event has not been consumed by the worker. + * + * state->event may be freed, so we can't directly look at + * state->event->base.completion. + */ + if (state->event && state->commit->abort_completion) + drm_crtc_commit_put(state->commit); + + kfree(state->commit->event); + state->commit->event = NULL; + + drm_crtc_commit_put(state->commit); + } + + drm_property_blob_put(state->mode_blob); + drm_property_blob_put(state->degamma_lut); + drm_property_blob_put(state->ctm); + drm_property_blob_put(state->gamma_lut); +} +EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); + +/** + * drm_atomic_helper_crtc_destroy_state - default state destroy hook + * @crtc: drm CRTC + * @state: CRTC state object to release + * + * Default CRTC state destroy hook for drivers which don't have their own + * subclassed CRTC state structure. + */ +void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + __drm_atomic_helper_crtc_destroy_state(state); + kfree(state); +} +EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); + +/** + * __drm_atomic_helper_plane_reset - resets planes state to default values + * @plane: plane object, must not be NULL + * @state: atomic plane state, must not be NULL + * + * Initializes plane state to default. This is useful for drivers that subclass + * the plane state. + */ +void __drm_atomic_helper_plane_reset(struct drm_plane *plane, + struct drm_plane_state *state) +{ + state->plane = plane; + state->rotation = DRM_MODE_ROTATE_0; + + /* Reset the alpha value to fully opaque if it matters */ + if (plane->alpha_property) + state->alpha = plane->alpha_property->values[1]; + state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; + + plane->state = state; +} +EXPORT_SYMBOL(__drm_atomic_helper_plane_reset); + +/** + * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes + * @plane: drm plane + * + * Resets the atomic state for @plane by freeing the state pointer (which might + * be NULL, e.g. at driver load time) and allocating a new empty state object. + */ +void drm_atomic_helper_plane_reset(struct drm_plane *plane) +{ + if (plane->state) + __drm_atomic_helper_plane_destroy_state(plane->state); + + kfree(plane->state); + plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); + if (plane->state) + __drm_atomic_helper_plane_reset(plane, plane->state); +} +EXPORT_SYMBOL(drm_atomic_helper_plane_reset); + +/** + * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state + * @plane: plane object + * @state: atomic plane state + * + * Copies atomic state from a plane's current state. This is useful for + * drivers that subclass the plane state. + */ +void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, + struct drm_plane_state *state) +{ + memcpy(state, plane->state, sizeof(*state)); + + if (state->fb) + drm_framebuffer_get(state->fb); + + state->fence = NULL; + state->commit = NULL; +} +EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); + +/** + * drm_atomic_helper_plane_duplicate_state - default state duplicate hook + * @plane: drm plane + * + * Default plane state duplicate hook for drivers which don't have their own + * subclassed plane state structure. + */ +struct drm_plane_state * +drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane) +{ + struct drm_plane_state *state; + + if (WARN_ON(!plane->state)) + return NULL; + + state = kmalloc(sizeof(*state), GFP_KERNEL); + if (state) + __drm_atomic_helper_plane_duplicate_state(plane, state); + + return state; +} +EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); + +/** + * __drm_atomic_helper_plane_destroy_state - release plane state + * @state: plane state object to release + * + * Releases all resources stored in the plane state without actually freeing + * the memory of the plane state. This is useful for drivers that subclass the + * plane state. + */ +void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) +{ + if (state->fb) + drm_framebuffer_put(state->fb); + + if (state->fence) + dma_fence_put(state->fence); + + if (state->commit) + drm_crtc_commit_put(state->commit); +} +EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); + +/** + * drm_atomic_helper_plane_destroy_state - default state destroy hook + * @plane: drm plane + * @state: plane state object to release + * + * Default plane state destroy hook for drivers which don't have their own + * subclassed plane state structure. + */ +void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state) +{ + __drm_atomic_helper_plane_destroy_state(state); + kfree(state); +} +EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); + +/** + * __drm_atomic_helper_connector_reset - reset state on connector + * @connector: drm connector + * @conn_state: connector state to assign + * + * Initializes the newly allocated @conn_state and assigns it to + * the &drm_conector->state pointer of @connector, usually required when + * initializing the drivers or when called from the &drm_connector_funcs.reset + * hook. + * + * This is useful for drivers that subclass the connector state. + */ +void +__drm_atomic_helper_connector_reset(struct drm_connector *connector, + struct drm_connector_state *conn_state) +{ + if (conn_state) + conn_state->connector = connector; + + connector->state = conn_state; +} +EXPORT_SYMBOL(__drm_atomic_helper_connector_reset); + +/** + * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors + * @connector: drm connector + * + * Resets the atomic state for @connector by freeing the state pointer (which + * might be NULL, e.g. at driver load time) and allocating a new empty state + * object. + */ +void drm_atomic_helper_connector_reset(struct drm_connector *connector) +{ + struct drm_connector_state *conn_state = + kzalloc(sizeof(*conn_state), GFP_KERNEL); + + if (connector->state) + __drm_atomic_helper_connector_destroy_state(connector->state); + + kfree(connector->state); + __drm_atomic_helper_connector_reset(connector, conn_state); +} +EXPORT_SYMBOL(drm_atomic_helper_connector_reset); + +/** + * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state + * @connector: connector object + * @state: atomic connector state + * + * Copies atomic state from a connector's current state. This is useful for + * drivers that subclass the connector state. + */ +void +__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, + struct drm_connector_state *state) +{ + memcpy(state, connector->state, sizeof(*state)); + if (state->crtc) + drm_connector_get(connector); + state->commit = NULL; + + /* Don't copy over a writeback job, they are used only once */ + state->writeback_job = NULL; +} +EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state); + +/** + * drm_atomic_helper_connector_duplicate_state - default state duplicate hook + * @connector: drm connector + * + * Default connector state duplicate hook for drivers which don't have their own + * subclassed connector state structure. + */ +struct drm_connector_state * +drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector) +{ + struct drm_connector_state *state; + + if (WARN_ON(!connector->state)) + return NULL; + + state = kmalloc(sizeof(*state), GFP_KERNEL); + if (state) + __drm_atomic_helper_connector_duplicate_state(connector, state); + + return state; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state); + +/** + * drm_atomic_helper_duplicate_state - duplicate an atomic state object + * @dev: DRM device + * @ctx: lock acquisition context + * + * Makes a copy of the current atomic state by looping over all objects and + * duplicating their respective states. This is used for example by suspend/ + * resume support code to save the state prior to suspend such that it can + * be restored upon resume. + * + * Note that this treats atomic state as persistent between save and restore. + * Drivers must make sure that this is possible and won't result in confusion + * or erroneous behaviour. + * + * Note that if callers haven't already acquired all modeset locks this might + * return -EDEADLK, which must be handled by calling drm_modeset_backoff(). + * + * Returns: + * A pointer to the copy of the atomic state object on success or an + * ERR_PTR()-encoded error code on failure. + * + * See also: + * drm_atomic_helper_suspend(), drm_atomic_helper_resume() + */ +struct drm_atomic_state * +drm_atomic_helper_duplicate_state(struct drm_device *dev, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_atomic_state *state; + struct drm_connector *conn; + struct drm_connector_list_iter conn_iter; + struct drm_plane *plane; + struct drm_crtc *crtc; + int err = 0; + + state = drm_atomic_state_alloc(dev); + if (!state) + return ERR_PTR(-ENOMEM); + + state->acquire_ctx = ctx; + + drm_for_each_crtc(crtc, dev) { + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + err = PTR_ERR(crtc_state); + goto free; + } + } + + drm_for_each_plane(plane, dev) { + struct drm_plane_state *plane_state; + + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) { + err = PTR_ERR(plane_state); + goto free; + } + } + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(conn, &conn_iter) { + struct drm_connector_state *conn_state; + + conn_state = drm_atomic_get_connector_state(state, conn); + if (IS_ERR(conn_state)) { + err = PTR_ERR(conn_state); + drm_connector_list_iter_end(&conn_iter); + goto free; + } + } + drm_connector_list_iter_end(&conn_iter); + + /* clear the acquire context so that it isn't accidentally reused */ + state->acquire_ctx = NULL; + +free: + if (err < 0) { + drm_atomic_state_put(state); + state = ERR_PTR(err); + } + + return state; +} +EXPORT_SYMBOL(drm_atomic_helper_duplicate_state); + +/** + * __drm_atomic_helper_connector_destroy_state - release connector state + * @state: connector state object to release + * + * Releases all resources stored in the connector state without actually + * freeing the memory of the connector state. This is useful for drivers that + * subclass the connector state. + */ +void +__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state) +{ + if (state->crtc) + drm_connector_put(state->connector); + + if (state->commit) + drm_crtc_commit_put(state->commit); +} +EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); + +/** + * drm_atomic_helper_connector_destroy_state - default state destroy hook + * @connector: drm connector + * @state: connector state object to release + * + * Default connector state destroy hook for drivers which don't have their own + * subclassed connector state structure. + */ +void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, + struct drm_connector_state *state) +{ + __drm_atomic_helper_connector_destroy_state(state); + kfree(state); +} +EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); + +/** + * drm_atomic_helper_legacy_gamma_set - set the legacy gamma correction table + * @crtc: CRTC object + * @red: red correction table + * @green: green correction table + * @blue: green correction table + * @size: size of the tables + * @ctx: lock acquire context + * + * Implements support for legacy gamma correction table for drivers + * that support color management through the DEGAMMA_LUT/GAMMA_LUT + * properties. See drm_crtc_enable_color_mgmt() and the containing chapter for + * how the atomic color management and gamma tables work. + */ +int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, + u16 *red, u16 *green, u16 *blue, + uint32_t size, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_device *dev = crtc->dev; + struct drm_atomic_state *state; + struct drm_crtc_state *crtc_state; + struct drm_property_blob *blob = NULL; + struct drm_color_lut *blob_data; + int i, ret = 0; + bool replaced; + + state = drm_atomic_state_alloc(crtc->dev); + if (!state) + return -ENOMEM; + + blob = drm_property_create_blob(dev, + sizeof(struct drm_color_lut) * size, + NULL); + if (IS_ERR(blob)) { + ret = PTR_ERR(blob); + blob = NULL; + goto fail; + } + + /* Prepare GAMMA_LUT with the legacy values. */ + blob_data = blob->data; + for (i = 0; i < size; i++) { + blob_data[i].red = red[i]; + blob_data[i].green = green[i]; + blob_data[i].blue = blue[i]; + } + + state->acquire_ctx = ctx; + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + ret = PTR_ERR(crtc_state); + goto fail; + } + + /* Reset DEGAMMA_LUT and CTM properties. */ + replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL); + replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL); + replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob); + crtc_state->color_mgmt_changed |= replaced; + + ret = drm_atomic_commit(state); + +fail: + drm_atomic_state_put(state); + drm_property_blob_put(blob); + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set); + +/** + * __drm_atomic_helper_private_duplicate_state - copy atomic private state + * @obj: CRTC object + * @state: new private object state + * + * Copies atomic state from a private objects's current state and resets inferred values. + * This is useful for drivers that subclass the private state. + */ +void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + memcpy(state, obj->state, sizeof(*state)); +} +EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state); diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 27aef91ca1c3..6d6448c97ce0 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -31,6 +31,7 @@ #include #include #include +#include #include struct drm_atomic_state; @@ -145,49 +146,6 @@ int drm_atomic_helper_page_flip_target( uint32_t target, struct drm_modeset_acquire_ctx *ctx); -/* default implementations for state handling */ -void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); -void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, - struct drm_crtc_state *state); -struct drm_crtc_state * -drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc); -void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state); -void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, - struct drm_crtc_state *state); - -void __drm_atomic_helper_plane_reset(struct drm_plane *plane, - struct drm_plane_state *state); -void drm_atomic_helper_plane_reset(struct drm_plane *plane); -void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, - struct drm_plane_state *state); -struct drm_plane_state * -drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane); -void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state); -void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, - struct drm_plane_state *state); - -void __drm_atomic_helper_connector_reset(struct drm_connector *connector, - struct drm_connector_state *conn_state); -void drm_atomic_helper_connector_reset(struct drm_connector *connector); -void -__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, - struct drm_connector_state *state); -struct drm_connector_state * -drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector); -struct drm_atomic_state * -drm_atomic_helper_duplicate_state(struct drm_device *dev, - struct drm_modeset_acquire_ctx *ctx); -void -__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); -void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, - struct drm_connector_state *state); -int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, - u16 *red, u16 *green, u16 *blue, - uint32_t size, - struct drm_modeset_acquire_ctx *ctx); -void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, - struct drm_private_state *state); - /** * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC * @plane: the loop cursor diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h new file mode 100644 index 000000000000..5b82ccfdb502 --- /dev/null +++ b/include/drm/drm_atomic_state_helper.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2018 Intel Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#include + +struct drm_crtc; +struct drm_crtc_state; +struct drm_plane; +struct drm_plane_state; +struct drm_connector; +struct drm_connector_state; +struct drm_private_obj; +struct drm_private_state; +struct drm_modeset_acquire_ctx; +struct drm_device; + +void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); +void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, + struct drm_crtc_state *state); +struct drm_crtc_state * +drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc); +void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state); +void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state); + +void __drm_atomic_helper_plane_reset(struct drm_plane *plane, + struct drm_plane_state *state); +void drm_atomic_helper_plane_reset(struct drm_plane *plane); +void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, + struct drm_plane_state *state); +struct drm_plane_state * +drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane); +void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state); +void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state); + +void __drm_atomic_helper_connector_reset(struct drm_connector *connector, + struct drm_connector_state *conn_state); +void drm_atomic_helper_connector_reset(struct drm_connector *connector); +void +__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, + struct drm_connector_state *state); +struct drm_connector_state * +drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector); +struct drm_atomic_state * +drm_atomic_helper_duplicate_state(struct drm_device *dev, + struct drm_modeset_acquire_ctx *ctx); +void +__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); +void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, + struct drm_connector_state *state); +int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, + u16 *red, u16 *green, u16 *blue, + uint32_t size, + struct drm_modeset_acquire_ctx *ctx); +void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, + struct drm_private_state *state); From patchwork Mon Sep 3 16:54:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586179 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 F102B139B for ; Mon, 3 Sep 2018 16:55:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E020828CDB for ; Mon, 3 Sep 2018 16:55:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D4B6328F5D; Mon, 3 Sep 2018 16:55:54 +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=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 7064628FE6 for ; Mon, 3 Sep 2018 16:55:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0CB536E2B9; Mon, 3 Sep 2018 16:55:06 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by gabe.freedesktop.org (Postfix) with ESMTPS id F36C46E2B2 for ; Mon, 3 Sep 2018 16:55:03 +0000 (UTC) Received: by mail-ed1-x542.google.com with SMTP id a20-v6so1243586edd.4 for ; Mon, 03 Sep 2018 09:55:03 -0700 (PDT) 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=Xgpg9SrQEI7QSilImCQ+wvXmEmCTvZVuS+hzjic8sOA=; b=f2qr+WD/RjT+C6qZXs8t8zOLDpBckCYKUdA2REdmt6NhI8Jqy+xUfthyWZtq2vlRAi twrbv+Pc1+MHElQmr5j+v8PSTilNN6RbEv6YIbP8Nio5K5qsjz1ksxkg3vU3gDfRshko qJ/qNnsx5kUIvX8I7mxgvVNQTa3FedC9mgNiyxyMYOQjmPkaDoVHCnc226TUcPXPAZ7K t2EMELWYSu2XF9K+RdJ58e16M+0fnysZV3xT2Uh/si91Tq3XhWFU4pQcG9cKn9B7faBK 7ByZpzoA5qMYfSSe9S4pdP4YQoqfvwMZ22juIMrz2D5iPrz5bShDyDBeflqEU+EQQsCh mLTg== X-Gm-Message-State: APzg51BoXrLL+HAF61HkTBWhY/vn9SZrn9IkFyjwH4eI3pEJol1sZF+4 xof79d3Iv+hgdtd1gGKyvrntKA== X-Google-Smtp-Source: ANB0VdbPl0o7vsswZLUQCRkD8wNxnWXWpOzYXkfgfERLZI6nxpgnpDCKr2b/Mkpvdvdq9QNNCx1JdA== X-Received: by 2002:a50:94c4:: with SMTP id t4-v6mr32030277eda.306.1535993702692; Mon, 03 Sep 2018 09:55:02 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.55.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:55:02 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:36 +0200 Message-Id: <20180903165439.24845-11-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 11/14] drm/vmwgfx: Remove confused comment from vmw_du_connector_atomic_set_property 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 , Intel Graphics Development , VMware Graphics , Thomas Hellstrom , Sinclair Yeh MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP The core _does_ the call to drm_atomic_commit for you. That's pretty much the entire point of having the fancy new atomic_set/get_prop callbacks. Signed-off-by: Daniel Vetter Cc: VMware Graphics Cc: Sinclair Yeh Cc: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 0c25bb8faf80..0f7e116a59f0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2309,12 +2309,6 @@ vmw_du_connector_atomic_set_property(struct drm_connector *connector, if (property == dev_priv->implicit_placement_property) { vcs->is_implicit = val; - - /* - * We should really be doing a drm_atomic_commit() to - * commit the new state, but since this doesn't cause - * an immedate state change, this is probably ok - */ du->is_implicit = vcs->is_implicit; } else { return -EINVAL; From patchwork Mon Sep 3 16:54:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586185 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 B15FC139B for ; Mon, 3 Sep 2018 16:56:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A02F028A73 for ; Mon, 3 Sep 2018 16:56:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 94ED328F5D; Mon, 3 Sep 2018 16:56:03 +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=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 5A15E28A73 for ; Mon, 3 Sep 2018 16:56:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 21E8A6E2C2; Mon, 3 Sep 2018 16:55:08 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by gabe.freedesktop.org (Postfix) with ESMTPS id 811ED6E2B2 for ; Mon, 3 Sep 2018 16:55:05 +0000 (UTC) Received: by mail-ed1-x541.google.com with SMTP id u1-v6so1260459eds.1 for ; Mon, 03 Sep 2018 09:55:05 -0700 (PDT) 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=9sX3JeAneghiB3GYX9jGmonDCrUPY+SST7ZLAa81yTw=; b=f5S3GekQKuy9204ba9tPsNmfYcdPI6w4BWD19rlSnBOlQJ/n/pyRlyNnxwmyoZh90w qX4joFlapXnUMVkUSkpWny7S0CNfrmjHbCmOko5t53+E4qOrS376AhJxaUUDUTQLJ+TD ygw7AqSRMZtBXknjw0VjPkn3g1NVWSadzPdry1ZtibruIM7rrCcHlu+2+BpMcJ3xrAfU Nboa300ybB7GrWBBKpI0VnJMrBvBdBgnSu0N2svJyGCvXrN/N0DUzB2FL/o3RVtRtuCW Sks70tdUXha8ibWJvCsiMmCehahBWABaUlHDBEnoqzB776iDACPavyo6UH6L3SuWgcx3 t7dw== X-Gm-Message-State: APzg51AcdZYTHFavaTaSiSFxCpGESn7SIstalxRZ3XIc8xWPJaeS2r9N 0cOq441utJ3D7wdmcs155XMdXA== X-Google-Smtp-Source: ANB0VdYi2IovaBYZFPMabrfOL/GcE2lZjHlvANAyIYOSH8I3kA5xIBreMeIE7OxCkRgycTv75QwvIA== X-Received: by 2002:a50:8a66:: with SMTP id i93-v6mr31827661edi.281.1535993703911; Mon, 03 Sep 2018 09:55:03 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.55.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:55:03 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:37 +0200 Message-Id: <20180903165439.24845-12-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 12/14] drm/vmwgfx: Don't look at state->allow_modeset 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 , Intel Graphics Development MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP That's purely for the uapi layer to implement the ALLOW_MODESET flag. Drivers should instead look at the state, e.g. through drm_atomic_crtc_needs_modeset(), which vmwgfx already does. Also remove the confusing comment, since checking allow_modeset is at best a micro optimization. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 0f7e116a59f0..71b7460d140f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1683,14 +1683,6 @@ vmw_kms_atomic_check_modeset(struct drm_device *dev, if (ret) return ret; - if (!state->allow_modeset) - return ret; - - /* - * Legacy path do not set allow_modeset properly like - * @drm_atomic_helper_update_plane, This will result in unnecessary call - * to vmw_kms_check_topology. So extra set of check. - */ for_each_new_crtc_in_state(state, crtc, crtc_state, i) { if (drm_atomic_crtc_needs_modeset(crtc_state)) need_modeset = true; From patchwork Mon Sep 3 16:54:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586187 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 D968B5A4 for ; Mon, 3 Sep 2018 16:56:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C9B0928A73 for ; Mon, 3 Sep 2018 16:56:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BE68B28F5D; Mon, 3 Sep 2018 16:56:05 +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=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 7597F28A73 for ; Mon, 3 Sep 2018 16:56:05 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AEEE16E2C1; Mon, 3 Sep 2018 16:55:08 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by gabe.freedesktop.org (Postfix) with ESMTPS id 814996E2B2 for ; Mon, 3 Sep 2018 16:55:06 +0000 (UTC) Received: by mail-ed1-x542.google.com with SMTP id f38-v6so1232805edd.8 for ; Mon, 03 Sep 2018 09:55:06 -0700 (PDT) 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=f4rClaGBO05gUJYpOEx/4mNFGuGS0PHDn2WDRXJgokY=; b=f/IzuRNEHEMZcWGOwGcoRPsoO8FqRREMnGS8Vih3g8mwoQ/vzZeRj82dINRGzudDqo fq97MaOObucqka0A+nhQCmKb/IdEKktc7haO9FI2iWQWQa76YTCen9MwL1kvJN3egd7N 3k1GQUzCi2jWsmu/fujTd5s3iWvFTJ0LydN9IIeOuM9MhB4F7lIUuUIof9lTvIYJLvRc DGJREs8YxErXAusjmcagQ4ORTpqvGKy/F0IPp9qlzeSsfuhxxzJuh+6CV/DXuDqFy+C5 4L42IKWCh7uBhaQucx9SdXTWklBd8WDcZJJByeUVH8LmJF6FSCnFzQ1UnE+cjwfyzd5y zDEA== X-Gm-Message-State: APzg51B2MOAGVHjh13UDTgquus/HC+y3WauQ6L8SUXQp42GgtbOVVRQo Syikcifz3I0gFVo/vNXJw6Bmtw== X-Google-Smtp-Source: ANB0Vdb+mrrOLu5MN0AQAJcUH3WPbWmyh1InnOuUAiCjLxjqfEDJjvKXcRDCWdIeKHxBX0oqlphUKw== X-Received: by 2002:a50:cc95:: with SMTP id q21-v6mr32024072edi.98.1535993705121; Mon, 03 Sep 2018 09:55:05 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.55.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:55:04 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:38 +0200 Message-Id: <20180903165439.24845-13-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 13/14] drm/atomic: Improve docs for drm_atomic_state->allow_modeset 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 , Intel Graphics Development , Daniel Vetter MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Motivated by vmwgfx digging around in core uapi bits it shouldn't dig around in. Signed-off-by: Daniel Vetter --- include/drm/drm_atomic.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 4aff40886acb..91d896ec9c10 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -254,7 +254,6 @@ struct __drm_private_objs_state { * struct drm_atomic_state - the global state object for atomic updates * @ref: count of all references to this state (will not be freed until zero) * @dev: parent DRM device - * @allow_modeset: allow full modeset * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics * @async_update: hint for asynchronous plane update * @planes: pointer to array of structures with per-plane data @@ -273,6 +272,15 @@ struct drm_atomic_state { struct kref ref; struct drm_device *dev; + + /** + * @allow_modeset: + * + * Allow full modeset. This is used by the ATOMIC IOCTL handler to + * implement the DRM_MODE_ATOMIC_ALLOW_MODESET flag. Drivers should + * never consult this flag, instead looking at the output of + * drm_atomic_crtc_needs_modeset(). + */ bool allow_modeset : 1; bool legacy_cursor_update : 1; bool async_update : 1; From patchwork Mon Sep 3 16:54:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 10586197 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 F189B5A4 for ; Mon, 3 Sep 2018 16:56:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E017D28A73 for ; Mon, 3 Sep 2018 16:56:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D421728F5D; Mon, 3 Sep 2018 16:56:27 +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 7BC2028A73 for ; Mon, 3 Sep 2018 16:56:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 64F766E2C5; Mon, 3 Sep 2018 16:55:12 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by gabe.freedesktop.org (Postfix) with ESMTPS id C1E6A6E2BF for ; Mon, 3 Sep 2018 16:55:07 +0000 (UTC) Received: by mail-ed1-x541.google.com with SMTP id h33-v6so1241298edb.5 for ; Mon, 03 Sep 2018 09:55:07 -0700 (PDT) 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=iJFc0f0FVqUTq6NBMvlGn5NXn/bbANKECNzmbaTTv8s=; b=n+1tldwq1JJTPtTga4erVPqaKse0GxXbAnDchXgBonHD9q5zWUtA9UHTXxNdrg4fpK GReOIXT3uueRayqGK1wWMld/oeNmp2e8m2278erlABpVchz42IMK1Lt+Npnh3CSWQGDy hRSkkYhaBgeMB2S+2wDNzoq3uMXCkVvGbyiAcED08D8f+EPeRYOT2tgrheGWuH7v2rxt Uwn5vhlm0o80M+aP2ieYRoltLB5ODzQMzyCldkEf+bSw3y36pCLEfzn6B1fWjj/3s1MG 5pgavYDK/0kYIo2agoiQy/X1tvCbR7KMQM4TA7tpXSyHOuuIH9Zl8xSy4d0ANO1i9cAl Fxeg== X-Gm-Message-State: APzg51Cx2lEcWdtFAVr8xxy8DWLPMJPW1Zp8gYpAjv/hrX58BxF/KB/u PtmzHTKBu2Gs3m/NZNUknR9Cbg== X-Google-Smtp-Source: ANB0VdYEW7Pf0+8CBC32cnuLtW0uqmLpXxATjtU3zq9Oj4Omlxuqcm10Mh8JT+7tXG1eml9nlo0QQg== X-Received: by 2002:a50:cf42:: with SMTP id d2-v6mr29862205edk.242.1535993706487; Mon, 03 Sep 2018 09:55:06 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id u53-v6sm12777790edm.51.2018.09.03.09.55.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 09:55:05 -0700 (PDT) From: Daniel Vetter To: DRI Development Date: Mon, 3 Sep 2018 18:54:39 +0200 Message-Id: <20180903165439.24845-14-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165439.24845-1-daniel.vetter@ffwll.ch> References: <20180903165439.24845-1-daniel.vetter@ffwll.ch> Subject: [Intel-gfx] [PATCH 14/14] drm/vmwgfx: Add FIXME comments for customer page_flip handlers 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: Thomas Hellstrom , Sinclair Yeh , Daniel Vetter , Intel Graphics Development , VMware Graphics , Daniel Vetter MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP The idea behind allowing drivers to override legacy ioctls (instead of using the generic implementations unconditionally) is to handle bugs in old driver-specific userspace. Like e.g. vmw_kms_set_config does, to work around some vmwgfx userspace not clearing its ioctl structs properly. But you can't use it to augment semantics and put in additional checks, since from a correctly working userspace's pov there should not be any difference in behaviour between the legacy and the atomic paths. vmwgfx seems to be doing some strange things in its page_flip handlers. Since I'm not an expert of this codebase just wrap some FIXME comments around the potentially problematic code. Signed-off-by: Daniel Vetter Cc: VMware Graphics Cc: Sinclair Yeh Cc: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 4c68ad6f3605..8e692334c3b9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -326,6 +326,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, struct vmw_private *dev_priv = vmw_priv(crtc->dev); int ret; + /* FIMXE: This check needs to be moved into ->atomic_check code. */ if (!vmw_kms_crtc_flippable(dev_priv, crtc)) return -EINVAL; @@ -335,6 +336,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, return ret; } + /* FIMXE: This code needs to be moved into ->atomic_commit callbacks. */ if (vmw_crtc_to_du(crtc)->is_implicit) vmw_kms_update_implicit_fb(dev_priv, crtc); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index f5b2fe8a7793..1913e086d015 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -501,6 +501,7 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, struct vmw_screen_target_display_unit *stdu = vmw_crtc_to_stdu(crtc); int ret; + /* FIMXE: This check needs to be moved into ->atomic_check code. */ if (!stdu->defined || !vmw_kms_crtc_flippable(dev_priv, crtc)) return -EINVAL;