From patchwork Fri Aug 8 08:40:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Pokorny X-Patchwork-Id: 4694641 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 9B0FCC0338 for ; Fri, 8 Aug 2014 08:41:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AED23201B4 for ; Fri, 8 Aug 2014 08:41:10 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 9E641201C8 for ; Fri, 8 Aug 2014 08:41:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 007D86E27F; Fri, 8 Aug 2014 01:41:09 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from youngberry.canonical.com (youngberry.canonical.com [91.189.89.112]) by gabe.freedesktop.org (Postfix) with ESMTP id 4AC0C6E27F for ; Fri, 8 Aug 2014 01:41:07 -0700 (PDT) Received: from p5083d1a8.dip0.t-ipconnect.de ([80.131.209.168] helo=andreas-W740SU.fritz.box) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1XFfjW-0004U5-O3; Fri, 08 Aug 2014 08:41:06 +0000 From: Andreas Pokorny To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/2] Simple crtc page flipping emulated using buffer copy Date: Fri, 8 Aug 2014 10:40:55 +0200 Message-Id: <1407487256-31563-2-git-send-email-andreas.pokorny@canonical.com> X-Mailer: git-send-email 2.1.0.rc1 In-Reply-To: <1407487256-31563-1-git-send-email-andreas.pokorny@canonical.com> References: <1407487256-31563-1-git-send-email-andreas.pokorny@canonical.com> 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.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, 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 Signed-off-by: Andreas Pokorny --- drivers/gpu/drm/qxl/qxl_display.c | 49 +++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/qxl/qxl_drv.c | 18 ++++++++++++++ drivers/gpu/drm/qxl/qxl_kms.c | 16 +++++++++---- 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index b8ced08..af9e785 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -187,6 +187,54 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc) kfree(qxl_crtc); } +static int qxl_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) +{ + struct drm_device *dev = crtc->dev; + struct qxl_device *qdev = dev->dev_private; + struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); + struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb); + struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb); + struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj); + struct qxl_bo *bo = gem_to_qxl_bo(qfb_src->obj); + unsigned long flags; + struct drm_clip_rect norect = { + .x1 = 0, + .y1 = 0, + .x2 = fb->width, + .y2 = fb->height + }; + int inc = 1; + int one_clip_rect = 1; + int ret = 0; + + crtc->primary->fb = fb; + bo_old->is_primary = false; + bo->is_primary = true; + + ret = qxl_bo_reserve(bo, false); + if (ret) + return ret; + + qxl_draw_dirty_fb(qdev, qfb_src, bo, 0, 0, + &norect, one_clip_rect, inc); + + drm_vblank_get(dev, qcrtc->index); + + if (event) { + spin_lock_irqsave(&dev->event_lock, flags); + drm_send_vblank_event(dev, qcrtc->index, event); + spin_unlock_irqrestore(&dev->event_lock, flags); + } + drm_vblank_put(dev, qcrtc->index); + + qxl_bo_unreserve(bo); + + return 0; +} + static int qxl_hide_cursor(struct qxl_device *qdev) { @@ -374,6 +422,7 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = { .cursor_move = qxl_crtc_cursor_move, .set_config = drm_crtc_helper_set_config, .destroy = qxl_crtc_destroy, + .page_flip = qxl_crtc_page_flip, }; static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 6e93663..005dd18 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -84,6 +84,7 @@ static const struct file_operations qxl_fops = { .release = drm_release, .unlocked_ioctl = drm_ioctl, .poll = drm_poll, + .read = drm_read, .mmap = qxl_mmap, }; @@ -195,6 +196,20 @@ static int qxl_pm_restore(struct device *dev) return qxl_drm_resume(drm_dev, false); } +static u32 qxl_noop_get_vblank_counter(struct drm_device *dev, int crtc) +{ + return dev->vblank[crtc].count.counter; +} + +static int qxl_noop_enable_vblank(struct drm_device *dev, int crtc) +{ + return 0; +} + +static void qxl_noop_disable_vblank(struct drm_device *dev, int crtc) +{ +} + static const struct dev_pm_ops qxl_pm_ops = { .suspend = qxl_pm_suspend, .resume = qxl_pm_resume, @@ -216,6 +231,9 @@ static struct drm_driver qxl_driver = { DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, .load = qxl_driver_load, .unload = qxl_driver_unload, + .get_vblank_counter = qxl_noop_get_vblank_counter, + .enable_vblank = qxl_noop_enable_vblank, + .disable_vblank = qxl_noop_disable_vblank, .dumb_create = qxl_mode_dumb_create, .dumb_map_offset = qxl_mode_dumb_mmap, diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index fd88eb4..853f13b 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -297,6 +297,9 @@ int qxl_driver_unload(struct drm_device *dev) if (qdev == NULL) return 0; + + drm_vblank_cleanup(dev); + qxl_modeset_fini(qdev); qxl_device_fini(qdev); @@ -324,15 +327,20 @@ int qxl_driver_load(struct drm_device *dev, unsigned long flags) if (r) goto out; + r = drm_vblank_init(dev, 1); + if (r) + goto unload; + r = qxl_modeset_init(qdev); - if (r) { - qxl_driver_unload(dev); - goto out; - } + if (r) + goto unload; drm_kms_helper_poll_init(qdev->ddev); return 0; +unload: + qxl_driver_unload(dev); + out: kfree(qdev); return r;