From patchwork Mon Mar 12 02:11:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 7217 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4827123E14 for ; Mon, 12 Mar 2012 02:11:16 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id DA7C8A1823D for ; Mon, 12 Mar 2012 02:11:15 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id e36so7948962iag.11 for ; Sun, 11 Mar 2012 19:11:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :dkim-signature:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=MtYADsovh3BgF/Nywk+5jqVFsSmU9vvhwFHShFvs578=; b=RfN+YpDbkqaRzy79uhJqxA29InV/6PYRcv2laXjTYLgddEFHBVqK82zrUW0Q/YV296 o3dRxUhlUoZqBzSK5FPd+9QCcZNHxxjXt9qFgJx6kBVVwsJLUQ7bRCgqufxTwMG9KnoA aItR6g5f43ALaCae1CKh6uSxhfvxVJqR7fo48kV/VGB6mJJa7UNW0wHknEGQMph7VgBy 5iPZ5r0fgXPWKt+OH9ufsVFs4SX4hPuow5/sty7iVfFFCjobtiD7m6hYKAzklE2ajSWZ XIpphWwEXf34WyLmb5lgDc9Naq1c+opjNBY2loPoCIt0uJdRx3euhnHJXGRg/S02+WGe aEeA== Received: by 10.50.158.133 with SMTP id wu5mr16332694igb.50.1331518275663; Sun, 11 Mar 2012 19:11:15 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.53.18 with SMTP id k18csp31436ibg; Sun, 11 Mar 2012 19:11:15 -0700 (PDT) Received: by 10.236.116.195 with SMTP id g43mr11435636yhh.26.1331518274788; Sun, 11 Mar 2012 19:11:14 -0700 (PDT) Received: from mail-gy0-f178.google.com (mail-gy0-f178.google.com [209.85.160.178]) by mx.google.com with ESMTPS id t19si5426529ani.4.2012.03.11.19.11.14 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 11 Mar 2012 19:11:14 -0700 (PDT) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.160.178 as permitted sender) client-ip=209.85.160.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.160.178 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass header.i=@gmail.com Received: by ghbf1 with SMTP id f1so2515379ghb.37 for ; Sun, 11 Mar 2012 19:11:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=MtYADsovh3BgF/Nywk+5jqVFsSmU9vvhwFHShFvs578=; b=RnVeaSMQWggNwrobxFfZ4K9rWLYV70vxhHVV7vYygbrhAiGDx3YNtetK9vcunR6rdR 4Oz1gzfer1/WVebb21tZWMrU30quJq4O9xLigzWPdccb9jzoCiW15Au2l9c9px6XqH2k 5kAk5kpVvpW27qzLbA+oOlWCHw38je8gu8jVYoJuwYxr6O+5PJKNuXwhESpfw08DbPbo UW3VvQqFR/JCGvihadfzbo6gNpnC7UHMVPlWRjy8YiJZLn6d2+4fpDl/3O8cCpJhgQzS Q9cXVXe8RAgw1ZBjyYc1Zaey+YHlH9PTrcRj4QroWgqe8+hFbx4IMy6gpG+lovqYRXz2 ZH1Q== Received: by 10.60.6.100 with SMTP id z4mr386948oez.1.1331518274401; Sun, 11 Mar 2012 19:11:14 -0700 (PDT) Received: from localhost (ppp-70-129-134-19.dsl.rcsntx.swbell.net. [70.129.134.19]) by mx.google.com with ESMTPS id g4sm8944818oeg.5.2012.03.11.19.11.13 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 11 Mar 2012 19:11:13 -0700 (PDT) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org, linux-omap@vger.kernel.org Cc: patches@linaro.org, Greg KH , Tomi Valkeinen , Andy Gross , Rob Clark Subject: [PATCH 2/3] staging: drm/omap: send page-flip event after endwin Date: Sun, 11 Mar 2012 21:11:21 -0500 Message-Id: <1331518282-6870-2-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1331518282-6870-1-git-send-email-rob.clark@linaro.org> References: <1331518282-6870-1-git-send-email-rob.clark@linaro.org> X-Gm-Message-State: ALoCoQlMTVVqWwRbnJ2Pn12T7bbFiQm/e25Qiz4nIehtsV3X/ue+yH+0va4jcKl5f6HWoeAkzYCt From: Rob Clark The endwin irq indicates that DSS has finished scanning out a buffer. Use this to trigger page-flip event to userspace, so this happens only *after* the previous buffer is finished. Signed-off-by: Rob Clark --- drivers/staging/omapdrm/omap_crtc.c | 27 ++++++++++++---- drivers/staging/omapdrm/omap_drv.h | 2 + drivers/staging/omapdrm/omap_plane.c | 56 +++++++++++++++++++++++++++------- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index 17ca163..13e3c7f 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -118,25 +118,21 @@ static void omap_crtc_load_lut(struct drm_crtc *crtc) { } -static void page_flip_cb(void *arg) +static void vblank_cb(void *arg) { + static uint32_t sequence = 0; struct drm_crtc *crtc = arg; struct drm_device *dev = crtc->dev; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct drm_pending_vblank_event *event = omap_crtc->event; - struct drm_framebuffer *old_fb = omap_crtc->old_fb; - struct timeval now; unsigned long flags; + struct timeval now; WARN_ON(!event); omap_crtc->event = NULL; - omap_crtc->old_fb = NULL; - - omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb); /* wakeup userspace */ - /* TODO: this should happen *after* flip in vsync IRQ handler */ if (event) { spin_lock_irqsave(&dev->event_lock, flags); event->event.sequence = drm_vblank_count_and_time( @@ -150,6 +146,23 @@ static void page_flip_cb(void *arg) } } +static void page_flip_cb(void *arg) +{ + struct drm_crtc *crtc = arg; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_framebuffer *old_fb = omap_crtc->old_fb; + + omap_crtc->old_fb = NULL; + + omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb); + + /* really we'd like to setup the callback atomically w/ setting the + * new scanout buffer to avoid getting stuck waiting an extra vblank + * cycle.. for now go for correctness and later figure out speed.. + */ + omap_plane_on_endwin(omap_crtc->plane, vblank_cb, crtc); +} + static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event) diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 21e48cf..b7e0f07 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -85,6 +85,8 @@ int omap_plane_mode_set(struct drm_plane *plane, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h); +void omap_plane_on_endwin(struct drm_plane *plane, + void (*fxn)(void *), void *arg); struct drm_encoder *omap_encoder_init(struct drm_device *dev, struct omap_overlay_manager *mgr); diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c index 9b3bfa0..7997be7 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/staging/omapdrm/omap_plane.c @@ -31,6 +31,11 @@ * plane funcs */ +struct callback { + void (*fxn)(void *); + void *arg; +}; + #define to_omap_plane(x) container_of(x, struct omap_plane, base) struct omap_plane { @@ -58,6 +63,9 @@ struct omap_plane { /* for deferred unpin when we need to wait for scanout complete irq */ struct work_struct work; + + /* callback on next endwin irq */ + struct callback endwin; }; /* map from ovl->id to the irq we are interested in for scanout-done */ @@ -84,6 +92,7 @@ static void unpin_worker(struct work_struct *work) { struct omap_plane *omap_plane = container_of(work, struct omap_plane, work); + struct callback endwin; mutex_lock(&omap_plane->unpin_mutex); DBG("unpinning %d of %d", omap_plane->num_unpins, @@ -96,7 +105,28 @@ static void unpin_worker(struct work_struct *work) drm_gem_object_unreference_unlocked(bo); omap_plane->num_unpins--; } + endwin = omap_plane->endwin; + omap_plane->endwin.fxn = NULL; mutex_unlock(&omap_plane->unpin_mutex); + + if (endwin.fxn) + endwin.fxn(endwin.arg); +} + +static void install_irq(struct drm_plane *plane) +{ + struct omap_plane *omap_plane = to_omap_plane(plane); + struct omap_overlay *ovl = omap_plane->ovl; + int ret; + + ret = omap_dispc_register_isr(dispc_isr, plane, id2irq[ovl->id]); + + /* + * omapdss has upper limit on # of registered irq handlers, + * which we shouldn't hit.. but if we do the limit should + * be raised or bad things happen: + */ + WARN_ON(ret == -EBUSY); } /* push changes down to dss2 */ @@ -146,17 +176,8 @@ static int commit(struct drm_plane *plane) * NOTE: really this should be atomic w/ mgr->apply() but * omapdss does not expose such an API */ - if (omap_plane->num_unpins > 0) { - ret = omap_dispc_register_isr(dispc_isr, - plane, id2irq[ovl->id]); - } - - /* - * omapdss has upper limit on # of registered irq handlers, - * which we shouldn't hit.. but if we do the limit should - * be raised or bad things happen: - */ - WARN_ON(ret == -EBUSY); + if (omap_plane->num_unpins > 0) + install_irq(plane); } else { struct omap_drm_private *priv = dev->dev_private; @@ -375,6 +396,19 @@ int omap_plane_dpms(struct drm_plane *plane, int mode) return r; } +void omap_plane_on_endwin(struct drm_plane *plane, + void (*fxn)(void *), void *arg) +{ + struct omap_plane *omap_plane = to_omap_plane(plane); + + mutex_lock(&omap_plane->unpin_mutex); + omap_plane->endwin.fxn = fxn; + omap_plane->endwin.arg = arg; + mutex_unlock(&omap_plane->unpin_mutex); + + install_irq(plane); +} + static const struct drm_plane_funcs omap_plane_funcs = { .update_plane = omap_plane_update, .disable_plane = omap_plane_disable,