Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.2 116 lines 2.7 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2013-2016 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 */ 6 7#include <linux/dma-fence.h> 8 9#include "msm_drv.h" 10#include "msm_fence.h" 11 12 13struct msm_fence_context * 14msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr, 15 const char *name) 16{ 17 struct msm_fence_context *fctx; 18 static int index = 0; 19 20 fctx = kzalloc(sizeof(*fctx), GFP_KERNEL); 21 if (!fctx) 22 return ERR_PTR(-ENOMEM); 23 24 fctx->dev = dev; 25 strncpy(fctx->name, name, sizeof(fctx->name)); 26 fctx->context = dma_fence_context_alloc(1); 27 fctx->index = index++; 28 fctx->fenceptr = fenceptr; 29 spin_lock_init(&fctx->spinlock); 30 31 /* 32 * Start out close to the 32b fence rollover point, so we can 33 * catch bugs with fence comparisons. 34 */ 35 fctx->last_fence = 0xffffff00; 36 fctx->completed_fence = fctx->last_fence; 37 *fctx->fenceptr = fctx->last_fence; 38 39 return fctx; 40} 41 42void msm_fence_context_free(struct msm_fence_context *fctx) 43{ 44 kfree(fctx); 45} 46 47bool msm_fence_completed(struct msm_fence_context *fctx, uint32_t fence) 48{ 49 /* 50 * Note: Check completed_fence first, as fenceptr is in a write-combine 51 * mapping, so it will be more expensive to read. 52 */ 53 return (int32_t)(fctx->completed_fence - fence) >= 0 || 54 (int32_t)(*fctx->fenceptr - fence) >= 0; 55} 56 57/* called from irq handler and workqueue (in recover path) */ 58void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence) 59{ 60 unsigned long flags; 61 62 spin_lock_irqsave(&fctx->spinlock, flags); 63 if (fence_after(fence, fctx->completed_fence)) 64 fctx->completed_fence = fence; 65 spin_unlock_irqrestore(&fctx->spinlock, flags); 66} 67 68struct msm_fence { 69 struct dma_fence base; 70 struct msm_fence_context *fctx; 71}; 72 73static inline struct msm_fence *to_msm_fence(struct dma_fence *fence) 74{ 75 return container_of(fence, struct msm_fence, base); 76} 77 78static const char *msm_fence_get_driver_name(struct dma_fence *fence) 79{ 80 return "msm"; 81} 82 83static const char *msm_fence_get_timeline_name(struct dma_fence *fence) 84{ 85 struct msm_fence *f = to_msm_fence(fence); 86 return f->fctx->name; 87} 88 89static bool msm_fence_signaled(struct dma_fence *fence) 90{ 91 struct msm_fence *f = to_msm_fence(fence); 92 return msm_fence_completed(f->fctx, f->base.seqno); 93} 94 95static const struct dma_fence_ops msm_fence_ops = { 96 .get_driver_name = msm_fence_get_driver_name, 97 .get_timeline_name = msm_fence_get_timeline_name, 98 .signaled = msm_fence_signaled, 99}; 100 101struct dma_fence * 102msm_fence_alloc(struct msm_fence_context *fctx) 103{ 104 struct msm_fence *f; 105 106 f = kzalloc(sizeof(*f), GFP_KERNEL); 107 if (!f) 108 return ERR_PTR(-ENOMEM); 109 110 f->fctx = fctx; 111 112 dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock, 113 fctx->context, ++fctx->last_fence); 114 115 return &f->base; 116}