From patchwork Fri Mar 29 02:45:01 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 2363771 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) by patchwork2.kernel.org (Postfix) with ESMTP id 879E7DF2A1 for ; Fri, 29 Mar 2013 02:59:12 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [IPv6:::1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 0F6BBE18; Fri, 29 Mar 2013 02:48:11 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTP id BFA7AE80 for ; Fri, 29 Mar 2013 02:47:57 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from kirsty.vergenet.net (kirsty.vergenet.net [202.4.237.240]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 4AC6720186 for ; Fri, 29 Mar 2013 02:47:55 +0000 (UTC) Received: from ayumi.akashicho.tokyo.vergenet.net (p8120-ipbfp1001kobeminato.hyogo.ocn.ne.jp [118.10.137.120]) by kirsty.vergenet.net (Postfix) with ESMTP id B5A282C6A9A; Fri, 29 Mar 2013 13:46:05 +1100 (EST) Received: by ayumi.akashicho.tokyo.vergenet.net (Postfix, from userid 7100) id 5E67BEDEA2D; Fri, 29 Mar 2013 11:46:04 +0900 (JST) From: Simon Horman To: ltsi-dev@lists.linuxfoundation.org Date: Fri, 29 Mar 2013 11:45:01 +0900 Message-Id: <1364525119-31791-373-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1364525119-31791-1-git-send-email-horms+renesas@verge.net.au> References: <1364525119-31791-1-git-send-email-horms+renesas@verge.net.au> X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Magnus Damm Subject: [LTSI-dev] [PATCH/RFC 372/390] drm/rcar-du: Add configurable z-order support for planes X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org From: Laurent Pinchart Create a new zpos property and instantiate it for each plane with an initial value of 0. Planes with a higher zpos will be displayed on top. Two planes with identical zpos values will be displayed in the plane index number. Signed-off-by: Laurent Pinchart (cherry picked from commit 678f6e92eef5f92e88422143a709209f58ded028) Signed-off-by: Simon Horman --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 49 ++++++++++++++++++--------- drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 3 +- drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 ++ drivers/gpu/drm/rcar-du/rcar_du_plane.c | 55 +++++++++++++++++++++++++++++-- drivers/gpu/drm/rcar-du/rcar_du_plane.h | 1 + 5 files changed, 91 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 934e6a5..57e6b89 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -111,36 +111,47 @@ static void rcar_du_crtc_start_stop(struct rcar_du_crtc *rcrtc, bool start) rcar_du_crtc_write(rcrtc, DSYSR, value | DSYSR_DRES); } -void rcar_du_crtc_enable_plane(struct rcar_du_plane *rplane, bool enable) +void rcar_du_crtc_update_planes(struct drm_crtc *crtc) { - struct rcar_du_crtc *rcrtc = to_rcar_crtc(rplane->crtc); - struct rcar_du_device *rcdu = rplane->crtc->dev->dev_private; - unsigned int prio; + struct rcar_du_device *rcdu = crtc->dev->dev_private; + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); + struct rcar_du_plane *planes[ARRAY_SIZE(rcdu->planes.planes)]; + unsigned int num_planes = 0; + unsigned int prio = 0; unsigned int i; u32 dspr = 0; - mutex_lock(&rcdu->planes.lock); - - rplane->enabled = enable; - - for (i = 0, prio = 28; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { + for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { struct rcar_du_plane *plane = &rcdu->planes.planes[i]; + unsigned int j; if (plane->crtc != &rcrtc->crtc || !plane->enabled) continue; - dspr |= (plane->hwindex + 1) << prio; + /* Insert the plane in the sorted planes array. */ + for (j = num_planes++; j > 0; --j) { + if (planes[j-1]->zpos <= plane->zpos) + break; + planes[j] = planes[j-1]; + } + + planes[j] = plane; + prio += plane->format->planes * 4; + } + + for (i = 0; i < num_planes; ++i) { + struct rcar_du_plane *plane = planes[i]; + prio -= 4; + dspr |= (plane->hwindex + 1) << prio; if (plane->format->planes == 2) { - dspr |= (plane->hwindex + 2) << prio; prio -= 4; + dspr |= (plane->hwindex + 2) << prio; } } rcar_du_crtc_write(rcrtc, DS1PR, dspr); - - mutex_unlock(&rcdu->planes.lock); } /* @@ -180,7 +191,11 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) rcar_du_crtc_set_display_timing(rcrtc); rcar_du_plane_setup(rcrtc->plane); - rcar_du_crtc_enable_plane(rcrtc->plane, true); + + mutex_lock(&rcdu->planes.lock); + rcrtc->plane->enabled = true; + rcar_du_crtc_update_planes(crtc); + mutex_unlock(&rcdu->planes.lock); /* Setup planes. */ list_for_each_entry(plane, &rcdu->ddev->mode_config.plane_list, head) { @@ -205,7 +220,11 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc) if (!rcrtc->started) return; - rcar_du_crtc_enable_plane(rcrtc->plane, false); + mutex_lock(&rcdu->planes.lock); + rcrtc->plane->enabled = false; + rcar_du_crtc_update_planes(crtc); + mutex_unlock(&rcdu->planes.lock); + rcar_du_crtc_start_stop(rcrtc, false); clk_disable(rcdu->clock); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index e0dde03..c7b668b 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h @@ -42,6 +42,7 @@ void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, struct drm_file *file); void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); -void rcar_du_crtc_enable_plane(struct rcar_du_plane *plane, bool enable); + +void rcar_du_crtc_update_planes(struct drm_crtc *crtc); #endif /* __RCAR_DU_CRTC_H__ */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index bddb4f8..62737bb 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h @@ -40,6 +40,8 @@ struct rcar_du_device { struct rcar_du_plane planes[8]; unsigned int free; struct mutex lock; + + struct drm_property *zpos; } planes; }; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 94bd0e2..cb4ded5 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -245,15 +245,24 @@ rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, rcar_du_plane_compute_base(rplane, fb); rcar_du_plane_setup(rplane); - rcar_du_crtc_enable_plane(rplane, true); + mutex_lock(&rcdu->planes.lock); + rplane->enabled = true; + rcar_du_crtc_update_planes(rplane->crtc); + mutex_unlock(&rcdu->planes.lock); + return 0; } static int rcar_du_plane_disable(struct drm_plane *plane) { + struct rcar_du_device *rcdu = plane->dev->dev_private; struct rcar_du_plane *rplane = to_rcar_plane(plane); - rcar_du_crtc_enable_plane(rplane, false); + mutex_lock(&rcdu->planes.lock); + rplane->enabled = false; + rcar_du_crtc_update_planes(rplane->crtc); + mutex_unlock(&rcdu->planes.lock); + rcar_du_plane_release(rplane); rplane->crtc = NULL; @@ -262,9 +271,35 @@ static int rcar_du_plane_disable(struct drm_plane *plane) return 0; } +static int rcar_du_plane_set_property(struct drm_plane *plane, + struct drm_property *property, + uint64_t value) +{ + struct rcar_du_device *rcdu = plane->dev->dev_private; + struct rcar_du_plane *rplane = to_rcar_plane(plane); + + if (property != rcdu->planes.zpos) + return -EINVAL; + + mutex_lock(&rcdu->planes.lock); + if (rplane->zpos == value) + goto done; + + rplane->zpos = value; + if (!rplane->enabled) + goto done; + + rcar_du_crtc_update_planes(rplane->crtc); + +done: + mutex_unlock(&rcdu->planes.lock); + return 0; +} + static const struct drm_plane_funcs rcar_du_plane_funcs = { .update_plane = rcar_du_plane_update, .disable_plane = rcar_du_plane_disable, + .set_property = rcar_du_plane_set_property, .destroy = drm_plane_cleanup, }; @@ -288,21 +323,35 @@ int rcar_du_plane_init(struct rcar_du_device *rcdu) mutex_init(&rcdu->planes.lock); rcdu->planes.free = 0xff; + rcdu->planes.zpos = + drm_property_create_range(rcdu->ddev, 0, "zpos", + ARRAY_SIZE(rcdu->crtc), + ARRAY_SIZE(rcdu->planes.planes) - 1); + if (rcdu->planes.zpos == NULL) + return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { struct rcar_du_plane *plane = &rcdu->planes.planes[i]; plane->dev = rcdu; plane->hwindex = -1; + plane->zpos = 1; /* Reserve one plane per CRTC */ - if (i < ARRAY_SIZE(rcdu->crtc)) + if (i < ARRAY_SIZE(rcdu->crtc)) { + plane->zpos = 0; continue; + } ret = drm_plane_init(rcdu->ddev, &plane->plane, 1, &rcar_du_plane_funcs, formats, ARRAY_SIZE(formats), false); if (ret < 0) return ret; + + drm_object_attach_property(&plane->plane.base, + rcdu->planes.zpos, 1); + } return 0; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h index 1e30237..2090ca4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h @@ -29,6 +29,7 @@ struct rcar_du_plane { bool enabled; int hwindex; /* 0-based, -1 means unused */ + unsigned int zpos; const struct rcar_du_format_info *format;