From patchwork Fri Mar 18 23:14:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 8624311 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2329B9F44D for ; Fri, 18 Mar 2016 23:15:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AD18F20394 for ; Fri, 18 Mar 2016 23:15:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0D8FD20397 for ; Fri, 18 Mar 2016 23:15:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753607AbcCRXPW (ORCPT ); Fri, 18 Mar 2016 19:15:22 -0400 Received: from mail-qk0-f169.google.com ([209.85.220.169]:36085 "EHLO mail-qk0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752526AbcCRXPS (ORCPT ); Fri, 18 Mar 2016 19:15:18 -0400 Received: by mail-qk0-f169.google.com with SMTP id s68so55682178qkh.3 for ; Fri, 18 Mar 2016 16:15:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=C3Ts8m/qC38BhQXafrnh4kuPnzjEQUymXBCPKLPQtcw=; b=Q1EqoyaX0GTJqz5e2B1tGHvnZpbV4WfcNA1s/RZ9QVxU/fLubl1rplUeNUDJxnppk+ kkzVNotCvm1Sd6TXx9WeheuLwbDD7tH4PX9ago0PQx8AF0Nl8/KTyP/tMS4DveAJWbgq Z4VvdJIajom9J2EDC5BusuXD8PVenqha2tDmQmOUyb7NAPSFt8NVxruNr3nLZdK0QMfb pYMMJq+T8YtWhWTM2j2n6PnlupxjEnauan4G/dpG5abssW4FoTucjPh/UlPBA+TSZQlk udM9NNF+xLDuS/8GeFF7gfkjPTU9wMgjJL62SQGEL+EbwHKV8ii2L0e5hfcNbM7pCoP2 DGLA== 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=C3Ts8m/qC38BhQXafrnh4kuPnzjEQUymXBCPKLPQtcw=; b=g91mMarK4CVAUe1XVweXbTD6s6bN2HKREdXMzOK3YgpLO1gTmK6RmVu0JX/b37owzi TdV/olrvcHfPoFIEKYjcRucAcmFbFMAjnahDuK59O+xLbOFggncTONcIxac5a+OJ8YgA pnU9YJUOy3cZbhF/kZGOluIWM9xw5xRfV41uAVXDwUbCOIxWzippUsOJw28Nwx6izapr N1+JlAdTIgwvtJybEnm99yI9c1nn7t9bFUlkCvBhDmLCyPUcOqEzwVfWsweTr+WmKL8x iTSjvsa9BKUKMB0tGCpS2gLJxMx4T+avZHZYwnHauasmjGGYRm9HQ+Lc0T3rqUk+JcxB T98Q== X-Gm-Message-State: AD7BkJIsxbY1ClxtUD6i3PfHkzHoVUzbwBbg0K1n8eADiFyQoqMEBQsArUQAtfqX8EQq1w== X-Received: by 10.55.73.6 with SMTP id w6mr25459836qka.82.1458342916806; Fri, 18 Mar 2016 16:15:16 -0700 (PDT) Received: from localhost ([2601:184:4000:90da:6af7:28ff:fe77:e429]) by smtp.gmail.com with ESMTPSA id b67sm5731959qhd.11.2016.03.18.16.15.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 Mar 2016 16:15:16 -0700 (PDT) From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: Daniel Vetter , maarten.lankhorst@canonical.com, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, Rob Clark Subject: [PATCH 04/11] drm/msm: move fence code to it's own file Date: Fri, 18 Mar 2016 19:14:57 -0400 Message-Id: <1458342904-23326-5-git-send-email-robdclark@gmail.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1458342904-23326-1-git-send-email-robdclark@gmail.com> References: <1458342904-23326-1-git-send-email-robdclark@gmail.com> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/msm_atomic.c | 1 + drivers/gpu/drm/msm/msm_drv.c | 108 +------------------------------- drivers/gpu/drm/msm/msm_drv.h | 27 +------- drivers/gpu/drm/msm/msm_fence.c | 129 +++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_fence.h | 43 +++++++++++++ drivers/gpu/drm/msm/msm_gem.c | 1 + drivers/gpu/drm/msm/msm_gpu.c | 1 + 8 files changed, 178 insertions(+), 133 deletions(-) create mode 100644 drivers/gpu/drm/msm/msm_fence.c create mode 100644 drivers/gpu/drm/msm/msm_fence.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index cfec4bb..d2d9de8 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -26,6 +26,7 @@ msm-y := \ msm_debugfs.o \ msm_drv.o \ msm_fb.o \ + msm_fence.o \ msm_gem.o \ msm_gem_prime.o \ msm_gem_submit.o \ diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 7eb253b..3c0f7a8 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -18,6 +18,7 @@ #include "msm_drv.h" #include "msm_kms.h" #include "msm_gem.h" +#include "msm_fence.h" struct msm_commit { struct drm_device *dev; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 5e08ea9..6988285 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -17,6 +17,7 @@ #include "msm_drv.h" #include "msm_debugfs.h" +#include "msm_fence.h" #include "msm_gpu.h" #include "msm_kms.h" @@ -540,113 +541,6 @@ static void msm_disable_vblank(struct drm_device *dev, unsigned int pipe) } /* - * Fences: - */ - -int msm_wait_fence(struct drm_device *dev, uint32_t fence, - ktime_t *timeout , bool interruptible) -{ - struct msm_drm_private *priv = dev->dev_private; - int ret; - - if (!priv->gpu) - return 0; - - if (fence > priv->gpu->submitted_fence) { - DRM_ERROR("waiting on invalid fence: %u (of %u)\n", - fence, priv->gpu->submitted_fence); - return -EINVAL; - } - - if (!timeout) { - /* no-wait: */ - ret = fence_completed(dev, fence) ? 0 : -EBUSY; - } else { - ktime_t now = ktime_get(); - unsigned long remaining_jiffies; - - if (ktime_compare(*timeout, now) < 0) { - remaining_jiffies = 0; - } else { - ktime_t rem = ktime_sub(*timeout, now); - struct timespec ts = ktime_to_timespec(rem); - remaining_jiffies = timespec_to_jiffies(&ts); - } - - if (interruptible) - ret = wait_event_interruptible_timeout(priv->fence_event, - fence_completed(dev, fence), - remaining_jiffies); - else - ret = wait_event_timeout(priv->fence_event, - fence_completed(dev, fence), - remaining_jiffies); - - if (ret == 0) { - DBG("timeout waiting for fence: %u (completed: %u)", - fence, priv->completed_fence); - ret = -ETIMEDOUT; - } else if (ret != -ERESTARTSYS) { - ret = 0; - } - } - - return ret; -} - -int msm_queue_fence_cb(struct drm_device *dev, - struct msm_fence_cb *cb, uint32_t fence) -{ - struct msm_drm_private *priv = dev->dev_private; - int ret = 0; - - mutex_lock(&dev->struct_mutex); - if (!list_empty(&cb->work.entry)) { - ret = -EINVAL; - } else if (fence > priv->completed_fence) { - cb->fence = fence; - list_add_tail(&cb->work.entry, &priv->fence_cbs); - } else { - queue_work(priv->wq, &cb->work); - } - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -/* called from workqueue */ -void msm_update_fence(struct drm_device *dev, uint32_t fence) -{ - struct msm_drm_private *priv = dev->dev_private; - - mutex_lock(&dev->struct_mutex); - priv->completed_fence = max(fence, priv->completed_fence); - - while (!list_empty(&priv->fence_cbs)) { - struct msm_fence_cb *cb; - - cb = list_first_entry(&priv->fence_cbs, - struct msm_fence_cb, work.entry); - - if (cb->fence > priv->completed_fence) - break; - - list_del_init(&cb->work.entry); - queue_work(priv->wq, &cb->work); - } - - mutex_unlock(&dev->struct_mutex); - - wake_up_all(&priv->fence_event); -} - -void __msm_fence_worker(struct work_struct *work) -{ - struct msm_fence_cb *cb = container_of(work, struct msm_fence_cb, work); - cb->func(cb); -} - -/* * DRM ioctls: */ diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 6980aa4..dfd8c8b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -49,6 +49,7 @@ struct msm_mmu; struct msm_rd_state; struct msm_perf_state; struct msm_gem_submit; +struct msm_fence_cb; #define NUM_DOMAINS 2 /* one for KMS, then one per gpu core (?) */ @@ -157,20 +158,6 @@ struct msm_format { uint32_t pixel_format; }; -/* callback from wq once fence has passed: */ -struct msm_fence_cb { - struct work_struct work; - uint32_t fence; - void (*func)(struct msm_fence_cb *cb); -}; - -void __msm_fence_worker(struct work_struct *work); - -#define INIT_FENCE_CB(_cb, _func) do { \ - INIT_WORK(&(_cb)->work, __msm_fence_worker); \ - (_cb)->func = _func; \ - } while (0) - int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state); int msm_atomic_commit(struct drm_device *dev, @@ -178,12 +165,6 @@ int msm_atomic_commit(struct drm_device *dev, int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); -int msm_wait_fence(struct drm_device *dev, uint32_t fence, - ktime_t *timeout, bool interruptible); -int msm_queue_fence_cb(struct drm_device *dev, - struct msm_fence_cb *cb, uint32_t fence); -void msm_update_fence(struct drm_device *dev, uint32_t fence); - int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); @@ -336,12 +317,6 @@ u32 msm_readl(const void __iomem *addr); #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) -static inline bool fence_completed(struct drm_device *dev, uint32_t fence) -{ - struct msm_drm_private *priv = dev->dev_private; - return priv->completed_fence >= fence; -} - static inline int align_pitch(int width, int bpp) { int bytespp = (bpp + 7) / 8; diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c new file mode 100644 index 0000000..55a5f92 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2013-2016 Red Hat + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "msm_drv.h" +#include "msm_fence.h" +#include "msm_gpu.h" + +static inline bool fence_completed(struct drm_device *dev, uint32_t fence) +{ + struct msm_drm_private *priv = dev->dev_private; + return (int32_t)(priv->completed_fence - fence) >= 0; +} + +int msm_wait_fence(struct drm_device *dev, uint32_t fence, + ktime_t *timeout , bool interruptible) +{ + struct msm_drm_private *priv = dev->dev_private; + int ret; + + if (!priv->gpu) + return 0; + + if (fence > priv->gpu->submitted_fence) { + DRM_ERROR("waiting on invalid fence: %u (of %u)\n", + fence, priv->gpu->submitted_fence); + return -EINVAL; + } + + if (!timeout) { + /* no-wait: */ + ret = fence_completed(dev, fence) ? 0 : -EBUSY; + } else { + ktime_t now = ktime_get(); + unsigned long remaining_jiffies; + + if (ktime_compare(*timeout, now) < 0) { + remaining_jiffies = 0; + } else { + ktime_t rem = ktime_sub(*timeout, now); + struct timespec ts = ktime_to_timespec(rem); + remaining_jiffies = timespec_to_jiffies(&ts); + } + + if (interruptible) + ret = wait_event_interruptible_timeout(priv->fence_event, + fence_completed(dev, fence), + remaining_jiffies); + else + ret = wait_event_timeout(priv->fence_event, + fence_completed(dev, fence), + remaining_jiffies); + + if (ret == 0) { + DBG("timeout waiting for fence: %u (completed: %u)", + fence, priv->completed_fence); + ret = -ETIMEDOUT; + } else if (ret != -ERESTARTSYS) { + ret = 0; + } + } + + return ret; +} + +int msm_queue_fence_cb(struct drm_device *dev, + struct msm_fence_cb *cb, uint32_t fence) +{ + struct msm_drm_private *priv = dev->dev_private; + int ret = 0; + + mutex_lock(&dev->struct_mutex); + if (!list_empty(&cb->work.entry)) { + ret = -EINVAL; + } else if (fence > priv->completed_fence) { + cb->fence = fence; + list_add_tail(&cb->work.entry, &priv->fence_cbs); + } else { + queue_work(priv->wq, &cb->work); + } + mutex_unlock(&dev->struct_mutex); + + return ret; +} + +/* called from workqueue */ +void msm_update_fence(struct drm_device *dev, uint32_t fence) +{ + struct msm_drm_private *priv = dev->dev_private; + + mutex_lock(&dev->struct_mutex); + priv->completed_fence = max(fence, priv->completed_fence); + + while (!list_empty(&priv->fence_cbs)) { + struct msm_fence_cb *cb; + + cb = list_first_entry(&priv->fence_cbs, + struct msm_fence_cb, work.entry); + + if (cb->fence > priv->completed_fence) + break; + + list_del_init(&cb->work.entry); + queue_work(priv->wq, &cb->work); + } + + mutex_unlock(&dev->struct_mutex); + + wake_up_all(&priv->fence_event); +} + +void __msm_fence_worker(struct work_struct *work) +{ + struct msm_fence_cb *cb = container_of(work, struct msm_fence_cb, work); + cb->func(cb); +} diff --git a/drivers/gpu/drm/msm/msm_fence.h b/drivers/gpu/drm/msm/msm_fence.h new file mode 100644 index 0000000..6ddb81c --- /dev/null +++ b/drivers/gpu/drm/msm/msm_fence.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013-2016 Red Hat + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef __MSM_FENCE_H__ +#define __MSM_FENCE_H__ + +#include "msm_drv.h" + +/* callback from wq once fence has passed: */ +struct msm_fence_cb { + struct work_struct work; + uint32_t fence; + void (*func)(struct msm_fence_cb *cb); +}; + +void __msm_fence_worker(struct work_struct *work); + +#define INIT_FENCE_CB(_cb, _func) do { \ + INIT_WORK(&(_cb)->work, __msm_fence_worker); \ + (_cb)->func = _func; \ + } while (0) + +int msm_wait_fence(struct drm_device *dev, uint32_t fence, + ktime_t *timeout, bool interruptible); +int msm_queue_fence_cb(struct drm_device *dev, + struct msm_fence_cb *cb, uint32_t fence); +void msm_update_fence(struct drm_device *dev, uint32_t fence); + +#endif diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 3cedb8d..ef03ee7 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -21,6 +21,7 @@ #include #include "msm_drv.h" +#include "msm_fence.h" #include "msm_gem.h" #include "msm_gpu.h" #include "msm_mmu.h" diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 42e2284..5f6704c 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -18,6 +18,7 @@ #include "msm_gpu.h" #include "msm_gem.h" #include "msm_mmu.h" +#include "msm_fence.h" /*