From patchwork Mon Jan 22 10:35:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10178259 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 44D3B602B7 for ; Mon, 22 Jan 2018 10:52:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 41478205F7 for ; Mon, 22 Jan 2018 10:52:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 358D821F61; Mon, 22 Jan 2018 10:52:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7E1D8205F7 for ; Mon, 22 Jan 2018 10:52:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=cMafd6AxxjwFi6mVGXaW+OR3Voc4+WaATih/QOtQh0g=; b=r4b6iG6RMgUnQ9EABNVkIr1AU5 vyoiB8lsAGvCfZ5MuFLefhni2BOuqYcbLnG3Buirg85yRMWKuLg9vTn5cUXzr4Z5zARXrS3b8Zaej Hvc9o9i3gOuEDxlL1LEZaveBcnWh9nSNT7ISh/3BMk3hJg+aGXw/16ieqyo28dXWvOEFK3GVK1Eh7 VfZc+NazIw4X5GinZNPv7iLQ5uhcMf1FlmonylxYtGc3r6ZDmC3UI2TlU8znfyKxLayNSVcbMgeUA C14wBgLpCv6TB9Y9Oh9ZLNycq5CqlOqDio8q0SQI7OVhVZqOy5YFNNHyUnE7W8HFBFV2Rlhwxa8oR knOM/UVQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1edZia-00063r-Ob; Mon, 22 Jan 2018 10:52:48 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1edZiK-0004l9-BE for linux-arm-kernel@bombadil.infradead.org; Mon, 22 Jan 2018 10:52:32 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=a2UZT6iz/5P0+wHWJNsfgAJqWvWcO/NoZLA9CKljQSs=; b=Ydv9WsACgCI7+uZJGIrYYV9A1 Wa/ZXWcYgHgumgjv94EpJq9xV+PdOv8oi7rY2UZwaLMsqaf8YXZxp2vltPIPGJy2ph/yZKecNuf34 SwcrF6NqhSkxh6LY1hXZLMqPbdbXPJ/95uCmL5hYY1QauoieJx2rzeKrGMZzmmKStV+JDpdvOCOPl fYjEm7RcvobRwrrb96EtBfZOYoNgjflxFltoL+4cwgXwKuWcD80MTMxVYCxQvTWmhVoPK3YR3pFlm S3bd/O6xEXMk+TcGGXTTGHeFaX3alV2oY3plG9HXKnebTtkuP3OhnEKGyI1fDgqjOU15WCS5dgYW8 0kyUbrScw==; Received: from mail.free-electrons.com ([62.4.15.54]) by casper.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1edZSy-0000b5-Et for linux-arm-kernel@lists.infradead.org; Mon, 22 Jan 2018 10:36:43 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id A10F220737; Mon, 22 Jan 2018 11:36:20 +0100 (CET) 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 BCB7120730; 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 Subject: [PATCH v2 16/19] drm/sun4i: backend: Assign the pipes automatically Date: Mon, 22 Jan 2018 11:35:45 +0100 Message-Id: X-Mailer: git-send-email 2.14.3 In-Reply-To: References: In-Reply-To: References: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180122_103640_515969_4399B25A X-CRM114-Status: GOOD ( 28.30 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, thomas@vitsch.nl MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Since we now have a way to enforce the zpos, check for the number of alpha planes, the only missing part is to assign our pipe automatically instead of hardcoding it. The algorithm is quite simple, but requires two iterations over the list of planes. In the first one (which is the same one that we've had to check for alpha, the frontend usage, and so on), we order the planes by their zpos. We can then do a second iteration over that array by ascending zpos starting with the pipe 0. When and if we encounter our alpha plane, we put it and all the other subsequent planes in the second pipe. And since we have runtime checks and pipe assignments now, we can just remove the static declaration of the planes we used to have. Signed-off-by: Maxime Ripard Reviewed-by: Chen-Yu Tsai --- drivers/gpu/drm/sun4i/sun4i_backend.c | 41 +++++++++++++++++++++-- drivers/gpu/drm/sun4i/sun4i_layer.c | 50 ++++------------------------ drivers/gpu/drm/sun4i/sun4i_layer.h | 1 +- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index eb1749d2c0d5..38c4b44f6ff5 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -276,12 +276,16 @@ int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; + struct sun4i_layer_state *p_state = state_to_sun4i_layer_state(state); unsigned int priority = state->normalized_zpos; + unsigned int pipe = p_state->pipe; - DRM_DEBUG_DRIVER("Setting layer %d priority to %d\n", layer, priority); - + DRM_DEBUG_DRIVER("Setting layer %d priority to %d and pipe %d\n", + layer, priority, pipe); regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer), + SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK | SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK, + SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(p_state->pipe) | SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority)); return 0; @@ -326,12 +330,15 @@ static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct drm_crtc_state *crtc_state) { + struct drm_plane_state *plane_states[SUN4I_BACKEND_NUM_LAYERS] = { 0 }; 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; + unsigned int current_pipe = 0; + unsigned int i; DRM_DEBUG_DRIVER("Starting checking our planes\n"); @@ -344,6 +351,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(plane_state); struct drm_framebuffer *fb = plane_state->fb; + struct drm_format_name_buf format_name; if (sun4i_backend_plane_uses_frontend(plane_state)) { DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", @@ -361,9 +369,19 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, if (fb->format->has_alpha) num_alpha_planes++; + DRM_DEBUG_DRIVER("Plane zpos is %d\n", + plane_state->normalized_zpos); + + /* Sort our planes by Zpos */ + plane_states[plane_state->normalized_zpos] = plane_state; + num_planes++; } + /* All our planes were disabled, bail out */ + if (!num_planes) + return 0; + /* * The hardware is a bit unusual here. * @@ -400,6 +418,25 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, return -EINVAL; } + /* We can't have an alpha plane at the lowest position */ + if (plane_states[0]->fb->format->has_alpha) + return -EINVAL; + + for (i = 1; i < num_planes; i++) { + struct drm_plane_state *p_state = plane_states[i]; + struct drm_framebuffer *fb = p_state->fb; + struct sun4i_layer_state *s_state = state_to_sun4i_layer_state(p_state); + + /* + * The only alpha position is the lowest plane of the + * second pipe. + */ + if (fb->format->has_alpha) + current_pipe++; + + s_state->pipe = current_pipe; + } + if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) { DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n"); return -EINVAL; diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 900e716443b8..ec7b906dbb84 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -19,13 +19,6 @@ #include "sun4i_layer.h" #include "sunxi_engine.h" -struct sun4i_plane_desc { - enum drm_plane_type type; - u8 pipe; - const uint32_t *formats; - uint32_t nformats; -}; - static void sun4i_backend_layer_reset(struct drm_plane *plane) { struct sun4i_layer *layer = plane_to_sun4i_layer(plane); @@ -133,14 +126,7 @@ static const struct drm_plane_funcs sun4i_backend_layer_funcs = { .update_plane = drm_atomic_helper_update_plane, }; -static const uint32_t sun4i_backend_layer_formats_primary[] = { - DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB888, - DRM_FORMAT_RGB565, - DRM_FORMAT_XRGB8888, -}; - -static const uint32_t sun4i_backend_layer_formats_overlay[] = { +static const uint32_t sun4i_backend_layer_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_ARGB4444, DRM_FORMAT_ARGB1555, @@ -151,24 +137,9 @@ static const uint32_t sun4i_backend_layer_formats_overlay[] = { DRM_FORMAT_XRGB8888, }; -static const struct sun4i_plane_desc sun4i_backend_planes[] = { - { - .type = DRM_PLANE_TYPE_PRIMARY, - .pipe = 0, - .formats = sun4i_backend_layer_formats_primary, - .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_primary), - }, - { - .type = DRM_PLANE_TYPE_OVERLAY, - .pipe = 1, - .formats = sun4i_backend_layer_formats_overlay, - .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_overlay), - }, -}; - static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, struct sun4i_backend *backend, - const struct sun4i_plane_desc *plane) + enum drm_plane_type type) { struct sun4i_layer *layer; int ret; @@ -180,8 +151,9 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, /* possible crtcs are set later */ ret = drm_universal_plane_init(drm, &layer->plane, 0, &sun4i_backend_layer_funcs, - plane->formats, plane->nformats, - NULL, plane->type, NULL); + sun4i_backend_layer_formats, + ARRAY_SIZE(sun4i_backend_layer_formats), + NULL, type, NULL); if (ret) { dev_err(drm->dev, "Couldn't initialize layer\n"); return ERR_PTR(ret); @@ -206,11 +178,11 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm, if (!planes) return ERR_PTR(-ENOMEM); - for (i = 0; i < ARRAY_SIZE(sun4i_backend_planes); i++) { - const struct sun4i_plane_desc *plane = &sun4i_backend_planes[i]; + for (i = 0; i < SUN4I_BACKEND_NUM_LAYERS; i++) { + enum drm_plane_type type = i ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY; struct sun4i_layer *layer; - layer = sun4i_layer_init_one(drm, backend, plane); + layer = sun4i_layer_init_one(drm, backend, type); if (IS_ERR(layer)) { dev_err(drm->dev, "Couldn't initialize %s plane\n", i ? "overlay" : "primary"); @@ -219,12 +191,6 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm, drm_plane_create_zpos_immutable_property(&layer->plane, i); - DRM_DEBUG_DRIVER("Assigning %s plane to pipe %d\n", - i ? "overlay" : "primary", plane->pipe); - regmap_update_bits(engine->regs, SUN4I_BACKEND_ATTCTL_REG0(i), - SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK, - SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(plane->pipe)); - layer->id = i; planes[i] = &layer->plane; }; diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h b/drivers/gpu/drm/sun4i/sun4i_layer.h index 75b4868ba87c..36b20265bd31 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.h +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h @@ -24,6 +24,7 @@ struct sun4i_layer { struct sun4i_layer_state { struct drm_plane_state state; + unsigned int pipe; bool uses_frontend; };