From patchwork Mon Feb 22 21:08:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 102717 Delivered-To: patch@linaro.org Received: by 10.112.43.199 with SMTP id y7csp1478051lbl; Mon, 22 Feb 2016 13:12:11 -0800 (PST) X-Received: by 10.66.62.226 with SMTP id b2mr41098071pas.94.1456175531202; Mon, 22 Feb 2016 13:12:11 -0800 (PST) Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTP id vz3si41932837pab.93.2016.02.22.13.12.10; Mon, 22 Feb 2016 13:12:11 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0B4596E258; Mon, 22 Feb 2016 21:12:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.17.13]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1E7306E258 for ; Mon, 22 Feb 2016 21:12:06 +0000 (UTC) Received: from wuerfel.lan. ([78.42.132.4]) by mrelayeu.kundenserver.de (mreue104) with ESMTPA (Nemesis) id 0MRUgC-1aMqtx0RWy-00SjHo; Mon, 22 Feb 2016 22:12:05 +0100 From: Arnd Bergmann To: Rob Clark Subject: [PATCH 3/8] drm: msm: split out fence and iotrace modules Date: Mon, 22 Feb 2016 22:08:37 +0100 Message-Id: <1456175331-714117-4-git-send-email-arnd@arndb.de> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1456175331-714117-1-git-send-email-arnd@arndb.de> References: <1456175331-714117-1-git-send-email-arnd@arndb.de> X-Provags-ID: V03:K0:otQjPFm6MG+jlIFLxIAGpJi2fjVETgX9blVp7OZqzX8B7QK5+wY +kFNaUy4Gw7vswB/sB4+3fHxFpjDdfQ0j3bPNtcREU88t4V6nw81K2Im4jN0afPxB5QmFoA 5j2iWtvgFHKUY6Ctato9ICk0G1hevzMRGmvNo8KUPO7zBu/tL36Wa2hq/lLvGHWSuqkBdq/ UWFitXep2ovVrUkQp5l9g== X-UI-Out-Filterresults: notjunk:1; V01:K0:M3OHlKX6IXA=:9gJYF7bInSXvdmy4fCyeE5 mGBjY9JYin0RI0pGMasoVbiqVQiKr9U9faggvdRF+mKKBtOW6bBZGxGai5Zr1bi9TZckvN7Dd GMBKT0ijzocuhcBREBoIunAX0lbHDhp68VbSbyF4DY8q+q1cVxReWK4JQKydtl6jHUeHrlXpW yRbjIJAPtfWRWlrGT3ch/pseSoS67xexHSVuU6UkhFrZmoGqzzTrPfNbhAj7BXCMriYYUG/ul RB+Y/sucCO1tnKKspx0VS4keOa5quJkaTh8EYHc7LAlFgFeHOtSn5Evg+iRITiUA3I20+pIog le1suMBNcTelEBfWVOfL0hTozKXcPWKALmdHI0+ll2CmdS1J16fP2QU4+17GaXoYRXc2e17Xl A4lHwSq2G/OBWMTaPK3h3nmMuLA9+2DRtclCd1xyUFskPERu2jZyzrsoP34alVhu2M/v8oq2p SZdBrNV7NfaVqXLVMNPU5vGlOwmT/RxKhhDknyzTsKDOwcoEk+bi2AozXqtudseaFrx3azy2i 3/N4xjlwu+eImmzqda/6inJWzl46kH7unbQ9ChBUm+ZXHEDw649e5D2/UQ2YeNUoYOVIlnmQA MHxsaxrKQeiuxCSGW/fK718JHN1azSdTU9g72xFGNifp7MLjC8QhUJOyATC3h8eMx6lubZVtF 0I1SIRtDRoyHhBuqSLpNbVpkj1JKaJso5f36zO6UtTzST6Hn/MkRQrw4dXuqGrIl3rKE= Cc: dri-devel@lists.freedesktop.org, Arnd Bergmann , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 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" This is a preparation for having edp, dsi and hdmi in separate modules. Those three drivers depend on the iotrace code and, and edp depends on gem, which in turn depends on the fence. With this change, those two pieces of the main driver can be loaded first, to resolve circular dependencies. Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/msm/Kconfig | 2 +- drivers/gpu/drm/msm/Makefile | 4 +- drivers/gpu/drm/msm/msm_drv.c | 165 -------------------------------------- drivers/gpu/drm/msm/msm_drv.h | 12 +++ drivers/gpu/drm/msm/msm_fence.c | 115 ++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_iotrace.c | 65 +++++++++++++++ 6 files changed, 196 insertions(+), 167 deletions(-) create mode 100644 drivers/gpu/drm/msm/msm_fence.c create mode 100644 drivers/gpu/drm/msm/msm_iotrace.c diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index b8beb9bccd91..d987c584d817 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -21,7 +21,7 @@ config DRM_MSM_REGISTER_LOGGING help Compile in support for logging register reads/writes in a format that can be parsed by envytools demsm tool. If enabled, register - logging can be switched on via msm.reglog=y module param. + logging can be switched on via msm_iotrace.reglog=y module param. source "drivers/gpu/drm/msm/dsi/Kconfig" source "drivers/gpu/drm/msm/hdmi/Kconfig" diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 24f6fd2b9651..acc02aef1b42 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -44,4 +44,6 @@ obj-$(CONFIG_DRM_MSM_DSI) += dsi/ obj-$(CONFIG_DRM_MSM_HDMI) += hdmi/ obj-$(CONFIG_DRM_MSM_EDP) += edp/ -obj-$(CONFIG_DRM_MSM) += drm-msm.o +obj-$(CONFIG_DRM_MSM) += drm-msm.o drm_msm_helper.o + +drm_msm_helper-y += msm_iotrace.o msm_fence.o diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index d52910e2c26c..5430ea7d2375 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -46,14 +46,6 @@ int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu) return idx; } -#ifdef CONFIG_DRM_MSM_REGISTER_LOGGING -static bool reglog = false; -MODULE_PARM_DESC(reglog, "Enable register read/write logging"); -module_param(reglog, bool, 0600); -#else -#define reglog 0 -#endif - #ifdef CONFIG_DRM_FBDEV_EMULATION static bool fbdev = true; MODULE_PARM_DESC(fbdev, "Enable fbdev compat layer"); @@ -64,56 +56,6 @@ static char *vram = "16m"; MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU)"); module_param(vram, charp, 0); -/* - * Util/helpers: - */ - -void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, - const char *dbgname) -{ - struct resource *res; - unsigned long size; - void __iomem *ptr; - - if (name) - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); - else - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!res) { - dev_err(&pdev->dev, "failed to get memory resource: %s\n", name); - return ERR_PTR(-EINVAL); - } - - size = resource_size(res); - - ptr = devm_ioremap_nocache(&pdev->dev, res->start, size); - if (!ptr) { - dev_err(&pdev->dev, "failed to ioremap: %s\n", name); - return ERR_PTR(-ENOMEM); - } - - if (reglog) - printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size); - - return ptr; -} - -void msm_writel(u32 data, void __iomem *addr) -{ - if (reglog) - printk(KERN_DEBUG "IO:W %p %08x\n", addr, data); - writel(data, addr); -} - -u32 msm_readl(const void __iomem *addr) -{ - u32 val = readl(addr); - if (reglog) - printk(KERN_ERR "IO:R %p %08x\n", addr, val); - return val; -} - struct vblank_event { struct list_head node; int crtc_id; @@ -691,113 +633,6 @@ static void msm_debugfs_cleanup(struct drm_minor *minor) #endif /* - * 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 a2755b4a0d86..b8bd88b66c9c 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -330,8 +331,19 @@ static inline void msm_rd_dump_submit(struct msm_gem_submit *submit) {} void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, const char *dbgname); +#ifdef CONFIG_DRM_MSM_REGISTER_LOGGING void msm_writel(u32 data, void __iomem *addr); u32 msm_readl(const void __iomem *addr); +#else +static inline void msm_writel(u32 data, void __iomem *addr) +{ + writel(data, addr); +} +static inline u32 msm_readl(const void __iomem *addr) +{ + return readl(addr); +} +#endif #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c new file mode 100644 index 000000000000..df66e04e01d8 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -0,0 +1,115 @@ +#include +#include +#include + +#include + +#include "msm_drv.h" +#include "msm_gpu.h" + +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; +} +EXPORT_SYMBOL_GPL(msm_wait_fence); + +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; +} +EXPORT_SYMBOL_GPL(msm_queue_fence_cb); + +/* 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); +} +EXPORT_SYMBOL_GPL(msm_update_fence); + +void __msm_fence_worker(struct work_struct *work) +{ + struct msm_fence_cb *cb = container_of(work, struct msm_fence_cb, work); + cb->func(cb); +} +EXPORT_SYMBOL_GPL(__msm_fence_worker); diff --git a/drivers/gpu/drm/msm/msm_iotrace.c b/drivers/gpu/drm/msm/msm_iotrace.c new file mode 100644 index 000000000000..7761470eee26 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_iotrace.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +static bool reglog = false; + +#ifdef CONFIG_DRM_MSM_REGISTER_LOGGING +MODULE_PARM_DESC(reglog, "Enable register read/write logging"); +module_param(reglog, bool, 0600); + +void msm_writel(u32 data, void __iomem *addr) +{ + if (reglog) + printk(KERN_DEBUG "IO:W %p %08x\n", addr, data); + writel(data, addr); +} +EXPORT_SYMBOL_GPL(msm_writel); + +u32 msm_readl(const void __iomem *addr) +{ + u32 val = readl(addr); + if (reglog) + printk(KERN_ERR "IO:R %p %08x\n", addr, val); + return val; +} +EXPORT_SYMBOL_GPL(msm_readl); +#endif + +void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, + const char *dbgname) +{ + struct resource *res; + unsigned long size; + void __iomem *ptr; + + if (name) + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + else + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!res) { + dev_err(&pdev->dev, "failed to get memory resource: %s\n", name); + return ERR_PTR(-EINVAL); + } + + size = resource_size(res); + + ptr = devm_ioremap_nocache(&pdev->dev, res->start, size); + if (!ptr) { + dev_err(&pdev->dev, "failed to ioremap: %s\n", name); + return ERR_PTR(-ENOMEM); + } + + if (reglog) + printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size); + + return ptr; +} +EXPORT_SYMBOL_GPL(msm_ioremap); + +MODULE_AUTHOR("Rob Clark