From patchwork Sun Jul 27 21:41:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 4631531 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E18BBC0338 for ; Sun, 27 Jul 2014 21:42:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D944620127 for ; Sun, 27 Jul 2014 21:42:12 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id BCABF2012F for ; Sun, 27 Jul 2014 21:42:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 077106E3B1; Sun, 27 Jul 2014 14:42:09 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-we0-f180.google.com (mail-we0-f180.google.com [74.125.82.180]) by gabe.freedesktop.org (Postfix) with ESMTP id 56CCD6E38A for ; Sun, 27 Jul 2014 14:41:59 -0700 (PDT) Received: by mail-we0-f180.google.com with SMTP id w61so6574392wes.25 for ; Sun, 27 Jul 2014 14:41:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=V2Ez97N2BRCab47IrkCIoOumjReLxAGQYoIo9/I7lNE=; b=DyrtDwTPluqdHDOm4u9uWs1YZGi83a824qYr12hkefbUC5LrAwymeGVELykgbEOpi+ PVpTTbN9iJAc5e1zhXn3erixu7/RCcaGxrs/6ImPkFc+wuvSJy7OmE/4PKajP3MyKctu XXxy8en+ran7ZooKC5VLE/DqM6c/o+y+MVk3g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=V2Ez97N2BRCab47IrkCIoOumjReLxAGQYoIo9/I7lNE=; b=EcMvtZCDrF8Tu4Ib651+1a55bO4k4aldNiHd5NhFb7MtDVk0eSeQUy+H78eQyKzQHx XUgz99HqXpAQKUGSfRg8WdQ+x7ILRmTjnIVoDF8UFDRAA9Ks5YLE2adG9bQNl7Pf2huG z+0n6kd/ap11DC9Lz+wHn8CPPHIVelBIdvAVhB7u3fUTEyEbRE+pujtIGWa9R5XnJKWT RiBeurdl8+g6mCr/6XIwmjFiDgUdc2+ojmJfhCNTxZsPmZgz/WSDId3I3Ve/URaaDJnp 75dmrmf/fN5nn//PMnNY70KOyAeKliqvKTZKBqB+4SthcbdKC7iV5OerwzK//w+wA4sq Vsbw== X-Gm-Message-State: ALoCoQl5XajsVHwIo+A7dSUjRyBbAXQo52QWAh61/fM688XVhti2XEg37GRIln6YqdIGKBv9Gx27 X-Received: by 10.194.110.10 with SMTP id hw10mr42235849wjb.81.1406497318497; Sun, 27 Jul 2014 14:41:58 -0700 (PDT) Received: from phenom.ffwll.local (84-73-67-144.dclient.hispeed.ch. [84.73.67.144]) by mx.google.com with ESMTPSA id di7sm44343171wjb.34.2014.07.27.14.41.57 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 27 Jul 2014 14:41:57 -0700 (PDT) From: Daniel Vetter To: DRI Development Subject: [PATCH 11/19] drm/crtc-helper: Transitional functions using atomic plane helpers Date: Sun, 27 Jul 2014 23:41:40 +0200 Message-Id: <1406497308-30733-12-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.0.1 In-Reply-To: <1406497308-30733-1-git-send-email-daniel.vetter@ffwll.ch> References: <1406497308-30733-1-git-send-email-daniel.vetter@ffwll.ch> Cc: Daniel Vetter X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 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-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP These two functions allow drivers to reuse their atomic plane helpers functions for the primary plane to implement the interfaces required by the crtc helpers for the legacy ->set_config callback. This is purely transitional and won't be used once the driver is fully converted. But it allows partial conversions to the atomic plane helpers which are functional. v2: - Use ->atomic_duplicate_state if available. - Don't forget to run crtc_funcs->atomic_check. v3: Shift source coordinates correctly for 16.16 fixed point. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_helper.c | 138 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 3 + include/drm/drm_crtc_helper.h | 7 ++ 3 files changed, 148 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 6c65a0a28fbd..751dcc9ba163 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -38,6 +38,7 @@ #include #include #include +#include #include MODULE_AUTHOR("David Airlie, Jesse Barnes"); @@ -888,3 +889,140 @@ void drm_helper_resume_force_mode(struct drm_device *dev) drm_modeset_unlock_all(dev); } EXPORT_SYMBOL(drm_helper_resume_force_mode); + +/** + * drm_helper_crtc_mode_set - mode_set implementation for atomic plane helpers + * + * This function implements a callback useable as the ->mode_set callback + * required by the crtc helpers. Besides the atomic plane helper functions for + * the primary plane the driver must also provide the ->mode_set_nofb callback + * to set up the crtc. + * + * This is a transitional helper useful for converting drivers to the atomic + * interfaces. + */ +int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_crtc_state *crtc_state; + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + int ret; + + if (crtc->funcs->atomic_duplicate_state) + crtc_state = crtc->funcs->atomic_duplicate_state(crtc); + else if (crtc->state) + crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), + GFP_KERNEL); + else + crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL); + if (!crtc_state) + return -ENOMEM; + + crtc_state->enable = true; + crtc_state->planes_changed = true; + drm_mode_copy(&crtc_state->mode, mode); + drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode); + + if (crtc_funcs->atomic_check) { + ret = crtc_funcs->atomic_check(crtc, crtc_state); + if (ret) { + kfree(crtc_state); + + return ret; + } + } + + swap(crtc->state, crtc_state); + + crtc_funcs->mode_set_nofb(crtc); + + kfree(crtc_state); + + return drm_helper_crtc_mode_set_base(crtc, x, y, old_fb); +} +EXPORT_SYMBOL(drm_helper_crtc_mode_set); + +/** + * drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic plane helpers + * + * This function implements a callback useable as the ->mode_set_base used + * required by the crtc helpers. The driver must provide the atomic plane helper + * functions for the primary plane. + * + * This is a transitional helper useful for converting drivers to the atomic + * interfaces. + */ +int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_plane_state *plane_state; + struct drm_plane_helper_funcs *plane_funcs; + struct drm_crtc_helper_funcs *crtc_funcs; + struct drm_plane *plane = crtc->primary; + int ret; + + if (plane->funcs->atomic_duplicate_state) + plane_state = plane->funcs->atomic_duplicate_state(plane); + else if (plane->state) + plane_state = kmemdup(plane->state, sizeof(*plane_state), + GFP_KERNEL); + else + plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); + if (!plane_state) + return -ENOMEM; + + plane_state->crtc = crtc; + plane_state->fb = crtc->primary->fb; + plane_state->crtc_x = 0; + plane_state->crtc_y = 0; + plane_state->crtc_h = crtc->mode.hdisplay; + plane_state->crtc_w = crtc->mode.vdisplay; + plane_state->src_x = x << 16; + plane_state->src_y = y << 16; + plane_state->src_h = crtc->mode.hdisplay << 16; + plane_state->src_w = crtc->mode.hdisplay << 16; + + plane_funcs = plane->helper_private; + + if (plane_funcs->atomic_check) { + ret = plane_funcs->atomic_check(plane, plane_state); + if (ret) + goto fail; + } + + if (plane_funcs->prepare_fb) { + ret = plane_funcs->prepare_fb(plane, plane_state->fb); + if (ret) + goto fail; + } + + /* Point of no return, commit sw state. */ + swap(plane->state, plane_state); + plane_state->fb = old_fb; + + crtc_funcs = crtc->helper_private; + + if (crtc_funcs && crtc_funcs->atomic_begin) + crtc_funcs->atomic_begin(crtc); + + plane_funcs->atomic_update(plane); + + if (crtc_funcs && crtc_funcs->atomic_flush) + crtc_funcs->atomic_flush(crtc); + + /* There's no way to figure out whether the crtc is running. */ + ret = drm_crtc_vblank_get(crtc); + if (ret == 0) { + drm_crtc_vblank_wait(crtc); + drm_crtc_vblank_put(crtc); + } + + if (plane_funcs->cleanup_fb && plane_state->fb) + plane_funcs->cleanup_fb(plane, plane_state->fb); +fail: + kfree(plane_state); + + return ret; +} +EXPORT_SYMBOL(drm_helper_crtc_mode_set_base); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index ff39aca5c266..1dec9911abc7 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -240,6 +240,9 @@ struct drm_crtc_state { /* computed state bits used by helpers and drivers */ bool planes_changed : 1; + /* adjusted_mode: for use by helpers and drivers */ + struct drm_display_mode adjusted_mode; + struct drm_display_mode mode; struct drm_pending_vblank_event *event; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index adec48b27aa5..7adbb65ea8ae 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -68,6 +68,7 @@ struct drm_crtc_helper_funcs { int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb); + void (*mode_set_nofb)(struct drm_crtc *crtc); /* Move the crtc on the current fb to the given position *optional* */ int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, @@ -167,6 +168,12 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, extern void drm_helper_resume_force_mode(struct drm_device *dev); +int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb); +int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb); + /* drm_probe_helper.c */ extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX,