From patchwork Tue Oct 18 08:29:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 9381631 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 0F7A9607D0 for ; Tue, 18 Oct 2016 08:40:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EFA002940E for ; Tue, 18 Oct 2016 08:40:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E41BC29421; Tue, 18 Oct 2016 08:40:02 +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, 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 4A6A62940E for ; Tue, 18 Oct 2016 08:40:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B39B76E674; Tue, 18 Oct 2016 08:39:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.free-electrons.com (up.free-electrons.com [163.172.77.33]) by gabe.freedesktop.org (Postfix) with ESMTP id BE2876E670 for ; Tue, 18 Oct 2016 08:39:45 +0000 (UTC) Received: by mail.free-electrons.com (Postfix, from userid 110) id EC4D4228EF; Tue, 18 Oct 2016 10:29:41 +0200 (CEST) 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 C5404228EB; Tue, 18 Oct 2016 10:29:41 +0200 (CEST) From: Maxime Ripard To: Daniel Vetter , David Airlie Subject: [PATCH 3/5] drm/sun4i: Add custom crtc state Date: Tue, 18 Oct 2016 10:29:36 +0200 Message-Id: <3767617c131ac19912e30c9c0ea567ea73f54692.1476779323.git-series.maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: References: In-Reply-To: References: Cc: Thomas Petazzoni , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Hans de Goede , Chen-Yu Tsai , Laurent Pinchart , Maxime Ripard , linux-arm-kernel@lists.infradead.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP We'll need a custom CRTC state to deal with the overscan setup. We'll store in it the actual display size that can be used by the applications, and the size to use on the plane. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_backend.c | 18 +++++++++----- drivers/gpu/drm/sun4i/sun4i_crtc.c | 37 ++++++++++++++++++++++++++-- drivers/gpu/drm/sun4i/sun4i_crtc.h | 16 ++++++++++++- drivers/gpu/drm/sun4i/sun4i_rgb.c | 10 ++++++++- drivers/gpu/drm/sun4i/sun4i_tv.c | 14 +++++++++++- 5 files changed, 87 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index 32c0584e3c35..9b36b7104c15 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -22,6 +22,7 @@ #include #include "sun4i_backend.h" +#include "sun4i_crtc.h" #include "sun4i_drv.h" static u32 sunxi_rgb2yuv_coef[12] = { @@ -115,15 +116,19 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, { struct drm_plane_state *state = plane->state; struct drm_framebuffer *fb = state->fb; + struct sun4i_crtc_state *s_state = drm_crtc_state_to_sun4i_crtc_state(state->crtc->state); + u16 x, y; + DRM_DEBUG_DRIVER("Updating layer %d\n", layer); if (plane->type == DRM_PLANE_TYPE_PRIMARY) { DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", - state->crtc_w, state->crtc_h); + s_state->display_x_size, + s_state->display_y_size); regmap_write(backend->regs, SUN4I_BACKEND_DISSIZE_REG, - SUN4I_BACKEND_DISSIZE(state->crtc_w, - state->crtc_h)); + SUN4I_BACKEND_DISSIZE(s_state->display_x_size, + s_state->display_y_size)); } /* Set the line width */ @@ -139,11 +144,12 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, state->crtc_h)); /* Set base coordinates */ + x = s_state->plane_x_offset + state->crtc_x; + y = s_state->plane_y_offset + state->crtc_y; DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n", - state->crtc_x, state->crtc_y); + x, y); regmap_write(backend->regs, SUN4I_BACKEND_LAYCOOR_REG(layer), - SUN4I_BACKEND_LAYCOOR(state->crtc_x, - state->crtc_y)); + SUN4I_BACKEND_LAYCOOR(x, y)); return 0; } diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 4a192210574f..772e0ecd72db 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -104,9 +104,42 @@ static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { .enable = sun4i_crtc_enable, }; +struct drm_crtc_state *sun4i_crtc_duplicate_state(struct drm_crtc *crtc) +{ + struct sun4i_crtc_state *state = drm_crtc_state_to_sun4i_crtc_state(crtc->state); + struct sun4i_crtc_state *copy; + + copy = kmalloc(sizeof(*copy), GFP_KERNEL); + if (!copy) + return NULL; + + DRM_DEBUG_DRIVER("Copying state %p to %p", state, copy); + + __drm_atomic_helper_crtc_duplicate_state(crtc, ©->base); + + copy->display_x_size = state->display_x_size; + copy->display_y_size = state->display_y_size; + + copy->plane_x_offset = state->plane_x_offset; + copy->plane_y_offset = state->plane_y_offset; + + return ©->base; +} + +void sun4i_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *c_state) +{ + struct sun4i_crtc_state *s_state = drm_crtc_state_to_sun4i_crtc_state(c_state); + + DRM_DEBUG_DRIVER("Freeing state %p", s_state); + + __drm_atomic_helper_crtc_destroy_state(c_state); + kfree(s_state); +} + static const struct drm_crtc_funcs sun4i_crtc_funcs = { - .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = sun4i_crtc_destroy_state, + .atomic_duplicate_state = sun4i_crtc_duplicate_state, .destroy = drm_crtc_cleanup, .page_flip = drm_atomic_helper_page_flip, .reset = drm_atomic_helper_crtc_reset, diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.h b/drivers/gpu/drm/sun4i/sun4i_crtc.h index dec8ce4d9b25..625c9ac41434 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.h +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.h @@ -20,11 +20,27 @@ struct sun4i_crtc { struct sun4i_drv *drv; }; +struct sun4i_crtc_state { + struct drm_crtc_state base; + + u32 display_x_size; + u32 display_y_size; + + u32 plane_x_offset; + u32 plane_y_offset; +}; + static inline struct sun4i_crtc *drm_crtc_to_sun4i_crtc(struct drm_crtc *crtc) { return container_of(crtc, struct sun4i_crtc, crtc); } +static inline struct sun4i_crtc_state * +drm_crtc_state_to_sun4i_crtc_state(struct drm_crtc_state *state) +{ + return container_of(state, struct sun4i_crtc_state, base); +} + struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm); #endif /* _SUN4I_CRTC_H_ */ diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index c3ff10f559cc..b1f792ad84c2 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c @@ -17,6 +17,7 @@ #include #include +#include "sun4i_crtc.h" #include "sun4i_drv.h" #include "sun4i_tcon.h" #include "sun4i_rgb.h" @@ -141,6 +142,15 @@ static int sun4i_rgb_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct drm_display_mode *mode = &crtc_state->mode; + struct sun4i_crtc_state *state = drm_crtc_state_to_sun4i_crtc_state(crtc_state); + + state->display_x_size = mode->hdisplay; + state->display_y_size = mode->vdisplay; + + state->plane_x_offset = 0; + state->plane_y_offset = 0; + return 0; } diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c index 1dd3d9eabf2e..6f8077013be3 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tv.c +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c @@ -22,6 +22,7 @@ #include #include "sun4i_backend.h" +#include "sun4i_crtc.h" #include "sun4i_drv.h" #include "sun4i_tcon.h" @@ -343,6 +344,19 @@ static int sun4i_tv_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct drm_display_mode *mode = &crtc_state->mode; + const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode); + struct sun4i_crtc_state *state = drm_crtc_state_to_sun4i_crtc_state(crtc_state); + + if (!tv_mode) + return -EINVAL; + + state->display_x_size = tv_mode->hdisplay; + state->plane_x_offset = 0; + + state->display_y_size = tv_mode->vdisplay; + state->plane_y_offset = 0; + return 0; }