From patchwork Mon Jan 22 10:35:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 125395 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1081474ljf; Mon, 22 Jan 2018 02:37:15 -0800 (PST) X-Google-Smtp-Source: AH8x226Z0CM72zDMqg9XLQPrfnESQDhM+1yABfVF/3eyBfhAyivgNMIYNs8JC5IkYcE0bcBVXRHw X-Received: by 2002:a17:902:1a2:: with SMTP id b31-v6mr2816597plb.28.1516617434527; Mon, 22 Jan 2018 02:37:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516617434; cv=none; d=google.com; s=arc-20160816; b=xh8Xx7Ms89jkn4AR6z+hfAzpm1P5EN573IxS7enFeVhUpVJon9VdGXQL7+dGjVGMwR 4SPrVa1MBxRHbRyAg4ZKOkGAEZLyYe1VDweDbrnoLMuPz4uDoKeSeqHEgG0buHWSVs2R NEFo0IjSSO77Pzcxw7D8Hdm8N7liJqNuzG2IuasQZXBr+2yHEU0zXifbp/QRuZguq/lT D0xhL+/9E5lej46cDolbr3vKbVuitEhUl1y9aDejbNCJlm3WxUKJ3kujZhSdtpI2LcGQ gzjyA/3kdb941HyU0NEqBeZH7TLRtQwXlVUSaShjgj4C0RU0l1MUMqu6Y5OyFZ23jmR7 G3ZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=6Z9z+TqB1nLLr0E14i9Kui+gsKbIY+jGagCktR4CKG8=; b=ZYd1pF8lK7Vx5mAy/reOmavZVdf9fA1rTxheol94annjPlvy6pTC90MnfkCqkkKT6c 3aE5Sie85/ZPFl7UEYGDvriZ+AkccL+W/ZYvfEnY1ADzE0pZ72JHrGPw0CvrbvzVNAVR QkGj9EGQ7AeoFNg3M5+GLgL8XJARfQkMYjydf7vdxlZ8/GhCyBJQ74bhrSn4pcCfQ7HL CJJqFQk5fQ4LVA2b2OEr9g9pvHxFtca89A/4LZiy9jEJ5pHNqergDQHKUWP1Xi6JTQ7R r/7l72TvCiq1QYwNPUZLDyWa4eg1vO4SzLUQY9KqQYT68p0nfS6wE1Q0RV3K99PaMnxe SirQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r16si15291899pfe.369.2018.01.22.02.37.14; Mon, 22 Jan 2018 02:37:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751431AbeAVKgq (ORCPT + 28 others); Mon, 22 Jan 2018 05:36:46 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:46581 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751372AbeAVKgV (ORCPT ); Mon, 22 Jan 2018 05:36:21 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 9E8EB20724; Mon, 22 Jan 2018 11:36:20 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 5B16B2072C; Mon, 22 Jan 2018 11:35:56 +0100 (CET) From: Maxime Ripard To: Chen-Yu Tsai , Maxime Ripard , daniel.vetter@intel.com, jani.nikula@linux.intel.com, seanpaul@chromium.org Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas@vitsch.nl Subject: [PATCH v2 15/19] drm/sun4i: backend: Check for the number of alpha planes Date: Mon, 22 Jan 2018 11:35:44 +0100 Message-Id: <7371f62a1385f2cbe3ed75dfca2e746338eb2286.1516617243.git-series.maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Due to the way the composition is done in hardware, we can only have a single alpha-enabled plane active at a time, placed in the second (highest priority) pipe. Make sure of that in our atomic_check to not end up in an impossible scenario. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 50 ++++++++++++++++++++++++++++- drivers/gpu/drm/sun4i/sun4i_backend.h | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 23 +------------- 3 files changed, 53 insertions(+), 22 deletions(-) -- git-series 0.9.1 Reviewed-by: Chen-Yu Tsai diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index c4986054909b..eb1749d2c0d5 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -329,6 +329,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct drm_atomic_state *state = crtc_state->state; struct drm_device *drm = state->dev; struct drm_plane *plane; + unsigned int num_planes = 0; + unsigned int num_alpha_planes = 0; unsigned int num_frontend_planes = 0; DRM_DEBUG_DRIVER("Starting checking our planes\n"); @@ -341,6 +343,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, drm_atomic_get_plane_state(state, plane); struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; if (sun4i_backend_plane_uses_frontend(plane_state)) { DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", @@ -351,6 +354,50 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, } else { layer_state->uses_frontend = false; } + + DRM_DEBUG_DRIVER("Plane FB format is %s\n", + drm_get_format_name(fb->format->format, + &format_name)); + if (fb->format->has_alpha) + num_alpha_planes++; + + num_planes++; + } + + /* + * The hardware is a bit unusual here. + * + * Even though it supports 4 layers, it does the composition + * in two separate steps. + * + * The first one is assigning a layer to one of its two + * pipes. If more that 1 layer is assigned to the same pipe, + * and if pixels overlaps, the pipe will take the pixel from + * the layer with the highest priority. + * + * The second step is the actual alpha blending, that takes + * the two pipes as input, and uses the eventual alpha + * component to do the transparency between the two. + * + * This two steps scenario makes us unable to guarantee a + * robust alpha blending between the 4 layers in all + * situations, since this means that we need to have one layer + * with alpha at the lowest position of our two pipes. + * + * However, we cannot even do that, since the hardware has a + * bug where the lowest plane of the lowest pipe (pipe 0, + * priority 0), if it has any alpha, will discard the pixel + * entirely and just display the pixels in the background + * color (black by default). + * + * Since means that we effectively have only three valid + * configurations with alpha, all of them with the alpha being + * on pipe1 with the lowest position, which can be 1, 2 or 3 + * depending on the number of planes and their zpos. + */ + if (num_alpha_planes > SUN4I_BACKEND_NUM_ALPHA_LAYERS) { + DRM_DEBUG_DRIVER("Too many planes with alpha, rejecting...\n"); + return -EINVAL; } if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) { @@ -358,6 +405,9 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, return -EINVAL; } + DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video\n", + num_planes, num_alpha_planes, num_frontend_planes); + return 0; } diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h index 04a4f11b87a8..52e77591186a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.h +++ b/drivers/gpu/drm/sun4i/sun4i_backend.h @@ -146,6 +146,8 @@ #define SUN4I_BACKEND_HWCCOLORTAB_OFF 0x4c00 #define SUN4I_BACKEND_PIPE_OFF(p) (0x5000 + (0x400 * (p))) +#define SUN4I_BACKEND_NUM_LAYERS 4 +#define SUN4I_BACKEND_NUM_ALPHA_LAYERS 1 #define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1 struct sun4i_backend { diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index fbf25d59cf88..900e716443b8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -201,32 +201,11 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm, struct sun4i_backend *backend = engine_to_sun4i_backend(engine); int i; - planes = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes) + 1, + planes = devm_kcalloc(drm->dev, SUN4I_BACKEND_NUM_LAYERS, sizeof(*planes), GFP_KERNEL); if (!planes) return ERR_PTR(-ENOMEM); - /* - * The hardware is a bit unusual here. - * - * Even though it supports 4 layers, it does the composition - * in two separate steps. - * - * The first one is assigning a layer to one of its two - * pipes. If more that 1 layer is assigned to the same pipe, - * and if pixels overlaps, the pipe will take the pixel from - * the layer with the highest priority. - * - * The second step is the actual alpha blending, that takes - * the two pipes as input, and uses the eventual alpha - * component to do the transparency between the two. - * - * This two steps scenario makes us unable to guarantee a - * robust alpha blending between the 4 layers in all - * situations. So we just expose two layers, one per pipe. On - * SoCs that support it, sprites could fill the need for more - * layers. - */ for (i = 0; i < ARRAY_SIZE(sun4i_backend_planes); i++) { const struct sun4i_plane_desc *plane = &sun4i_backend_planes[i]; struct sun4i_layer *layer;