From patchwork Sat Oct 13 00:49:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 12203 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 0AD9523EFB for ; Sat, 13 Oct 2012 00:49:40 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id AD9E1A1959F for ; Sat, 13 Oct 2012 00:49:39 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id e10so5509072iej.11 for ; Fri, 12 Oct 2012 17:49:39 -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=8/WkUeN53giq8W3oGA95e2ZsMnbSahS228JOL4o28r8=; b=ZAyE7QmnhDFFEFc94HIXWAYk8Cy2paJMg9eHVd9OkvA7YCUFZcfAgSreqq9nkgb4pF R2+vLCANdzzp/pvbaiVYGuZnqMiJ8Pj16YAyvheX0TltMdtJ3MfLhTu/oB7+HVOpbu/p kG9Z5N1Wm78vAIbjdQrUtwzpwLUq8ifXfphxAdMWYRgfmdhLuy2XYF5nHVMw3HP5Y1ro zyxmczcXIkReLDmw6mpdP5nIMuIADsAfBQajli3VxBJaquQHbo8pC8ma+/HCvA+wLqPU IJbmmFjNarg53UK5TBJxULryxNLaY+DTmEgR3mk9ONSknWxqIqETTkJMR9xKboJVrqnP U3Jw== Received: by 10.50.46.226 with SMTP id y2mr3590139igm.62.1350089379350; Fri, 12 Oct 2012 17:49:39 -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.50.67.148 with SMTP id n20csp274652igt; Fri, 12 Oct 2012 17:49:38 -0700 (PDT) Received: by 10.60.32.19 with SMTP id e19mr4981816oei.9.1350089378852; Fri, 12 Oct 2012 17:49:38 -0700 (PDT) Received: from mail-oa0-f50.google.com (mail-oa0-f50.google.com [209.85.219.50]) by mx.google.com with ESMTPS id d7si101453oea.52.2012.10.12.17.49.38 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 12 Oct 2012 17:49:38 -0700 (PDT) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.219.50 as permitted sender) client-ip=209.85.219.50; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.219.50 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass header.i=@gmail.com Received: by mail-oa0-f50.google.com with SMTP id n16so4214146oag.37 for ; Fri, 12 Oct 2012 17:49:38 -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=8/WkUeN53giq8W3oGA95e2ZsMnbSahS228JOL4o28r8=; b=yKOx5P/UQBcF2XB+7rxzdlknBI4ziRX/0qz5OHhtb/RiEsQh2qv5ag9Or0VeeeyYJQ hjxmbiUljTc9goCgLQaArxY80Xa4j47H02liZ/5Er2B5xjtP3qzuPplz9RSI3O1VSEo+ iA2Ea2em5QvP/LsB+ZzdHHi2jvqn4uEBZaHg2Kg0igIpT3f9xi/fHIX/Qoh1yGLDFt/c hswU8PypJ4B32d1lSqrITs9sNiipblmR3lVKFEc50NEetHYlw2Ii6Qc/hLs4unLCkkWM 3V4/ndoypI4Lq28xAFtRvLN8v5qCn3/6swqcL3QBxIqJrtMp5wo9XP3sW6nQWwtt1FEI Tl2Q== Received: by 10.60.32.19 with SMTP id e19mr4981813oei.9.1350089378713; Fri, 12 Oct 2012 17:49:38 -0700 (PDT) Received: from localhost (ppp-70-129-143-201.dsl.rcsntx.swbell.net. [70.129.143.201]) by mx.google.com with ESMTPS id h2sm8244793obn.11.2012.10.12.17.49.36 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 12 Oct 2012 17:49:37 -0700 (PDT) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: patches@linaro.org, ville.syrjala@linux.intel.com, jbarnes@virtuousgeek.org, daniel.vetter@ffwll.ch, krh@bitplanet.net, Rob Clark Subject: [RFC 08/11] drm: convert page_flip to properties Date: Fri, 12 Oct 2012 19:49:09 -0500 Message-Id: <1350089352-18162-9-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1350089352-18162-1-git-send-email-rob.clark@linaro.org> References: <1350089352-18162-1-git-send-email-rob.clark@linaro.org> X-Gm-Message-State: ALoCoQkpLW5gNSasEGSxLQI6QQX5hhCN22rmpPN3BJYuutsRuqNjc2XaLK1zZydFnelGbMTyZrWD From: Rob Clark Use atomic properties mechanism for CRTC page_flip. This by itself doesn't accomplish anything, but it avoids having multiple code paths to do the same thing when nuclear-pageflip and atomic-modeset are introduced. --- drivers/gpu/drm/drm_crtc.c | 167 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 63365f0..bcdd6be 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -441,9 +441,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) struct drm_mode_config *config = &dev->mode_config; struct drm_crtc *crtc; struct drm_plane *plane; - struct drm_mode_set set; void *state; - int ret; if (!dev_supports_atomic(dev)) { drm_framebuffer_remove_legacy(fb); @@ -460,12 +458,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (crtc->fb == fb) { /* should turn off the crtc */ - memset(&set, 0, sizeof(struct drm_mode_set)); - set.crtc = crtc; - set.fb = NULL; - ret = crtc->funcs->set_config(&set); - if (ret) - DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); + drm_mode_crtc_set_obj_prop(crtc, state, config->prop_fb_id, 0); } } @@ -508,6 +501,7 @@ EXPORT_SYMBOL(drm_framebuffer_remove); int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, const struct drm_crtc_funcs *funcs) { + struct drm_mode_config *config = &dev->mode_config; int ret; crtc->dev = dev; @@ -526,6 +520,13 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, list_add_tail(&crtc->head, &dev->mode_config.crtc_list); dev->mode_config.num_crtc++; + if (!dev_supports_atomic(dev)) + goto out; + + drm_object_attach_property(&crtc->base, config->prop_fb_id, 0); + drm_object_attach_property(&crtc->base, config->prop_crtc_x, 0); + drm_object_attach_property(&crtc->base, config->prop_crtc_y, 0); + out: mutex_unlock(&dev->mode_config.mutex); @@ -3960,7 +3961,53 @@ out: return ret; } -int drm_mode_page_flip_ioctl(struct drm_device *dev, +static struct drm_pending_vblank_event *create_vblank_event( + struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data) +{ + struct drm_pending_vblank_event *e = NULL; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + if (file_priv->event_space < sizeof e->event) { + spin_unlock_irqrestore(&dev->event_lock, flags); + goto out; + } + file_priv->event_space -= sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + + e = kzalloc(sizeof *e, GFP_KERNEL); + if (e == NULL) { + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + goto out; + } + + e->event.base.type = DRM_EVENT_FLIP_COMPLETE; + e->event.base.length = sizeof e->event; + e->event.user_data = user_data; + e->base.event = &e->event.base; + e->base.file_priv = file_priv; + e->base.destroy = + (void (*) (struct drm_pending_event *)) kfree; + +out: + return e; +} + +static void destroy_vblank_event(struct drm_device *dev, + struct drm_file *file_priv, struct drm_pending_vblank_event *e) +{ + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(e); +} + +/* Legacy version.. remove when all drivers converted to 'atomic' API */ +static int drm_mode_page_flip_ioctl_legacy(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_crtc_page_flip *page_flip = data; @@ -3968,7 +4015,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, struct drm_crtc *crtc; struct drm_framebuffer *fb; struct drm_pending_vblank_event *e = NULL; - unsigned long flags; int hdisplay, vdisplay; int ret = -EINVAL; @@ -4017,43 +4063,90 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, } if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - ret = -ENOMEM; - spin_lock_irqsave(&dev->event_lock, flags); - if (file_priv->event_space < sizeof e->event) { - spin_unlock_irqrestore(&dev->event_lock, flags); + e = create_vblank_event(dev, file_priv, page_flip->user_data); + if (!e) { + ret = -ENOMEM; goto out; } - file_priv->event_space -= sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); + } - e = kzalloc(sizeof *e, GFP_KERNEL); - if (e == NULL) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - goto out; - } + ret = crtc->funcs->page_flip(crtc, fb, e); + if (ret && e) + destroy_vblank_event(dev, file_priv, e); + +out: + mutex_unlock(&dev->mode_config.mutex); + return ret; +} + +int drm_mode_page_flip_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_crtc_page_flip *page_flip = data; + struct drm_mode_config *config = &dev->mode_config; + struct drm_mode_object *obj; + struct drm_crtc *crtc; + struct drm_pending_vblank_event *e = NULL; + void *state; + int ret = -EINVAL; + + if (!dev_supports_atomic(dev)) + return drm_mode_page_flip_ioctl_legacy(dev, data, file_priv); + + if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || + page_flip->reserved != 0) + return -EINVAL; - e->event.base.type = DRM_EVENT_FLIP_COMPLETE; - e->event.base.length = sizeof e->event; - e->event.user_data = page_flip->user_data; - e->base.event = &e->event.base; - e->base.file_priv = file_priv; - e->base.destroy = - (void (*) (struct drm_pending_event *)) kfree; + mutex_lock(&dev->mode_config.mutex); + + obj = drm_mode_object_find(dev, page_flip->crtc_id, + DRM_MODE_OBJECT_CRTC); + if (!obj) { + DRM_DEBUG_KMS("Unknown CRTC ID %d\n", page_flip->crtc_id); + ret = -ENOENT; + goto out_unlock; } + crtc = obj_to_crtc(obj); - ret = crtc->funcs->page_flip(crtc, fb, e); - if (ret) { - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); + state = dev->driver->atomic_begin(dev, crtc); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + goto out_unlock; + } + + if (crtc->fb == NULL) { + /* The framebuffer is currently unbound, presumably + * due to a hotplug event, that userspace has not + * yet discovered. + */ + ret = -EBUSY; + goto out; + } + + if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { + e = create_vblank_event(dev, file_priv, page_flip->user_data); + if (!e) { + ret = -ENOMEM; + goto out; } } + ret = drm_mode_set_obj_prop(obj, state, + config->prop_fb_id, page_flip->fb_id); + if (ret) + goto out; + + ret = dev->driver->atomic_check(dev, state); + if (ret) + goto out; + + ret = dev->driver->atomic_commit(dev, state, e); + if (ret && e) + destroy_vblank_event(dev, file_priv, e); + out: + dev->driver->atomic_end(dev, state); +out_unlock: mutex_unlock(&dev->mode_config.mutex); return ret; }