drivers/gpu/drm/msm/msm_fence.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/msm_fence.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/msm/msm_fence.c
Extension
.c
Size
5001 bytes
Lines
202
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct msm_fence {
	struct dma_fence base;
	struct msm_fence_context *fctx;
};

static inline struct msm_fence *to_msm_fence(struct dma_fence *fence)
{
	return container_of(fence, struct msm_fence, base);
}

static const char *msm_fence_get_driver_name(struct dma_fence *fence)
{
	return "msm";
}

static const char *msm_fence_get_timeline_name(struct dma_fence *fence)
{
	struct msm_fence *f = to_msm_fence(fence);
	return f->fctx->name;
}

static bool msm_fence_signaled(struct dma_fence *fence)
{
	struct msm_fence *f = to_msm_fence(fence);
	return msm_fence_completed(f->fctx, f->base.seqno);
}

static void msm_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
{
	struct msm_fence *f = to_msm_fence(fence);
	struct msm_fence_context *fctx = f->fctx;
	unsigned long flags;
	ktime_t now;

	spin_lock_irqsave(&fctx->spinlock, flags);
	now = ktime_get();

	if (ktime_after(now, fctx->next_deadline) ||
			ktime_before(deadline, fctx->next_deadline)) {
		fctx->next_deadline = deadline;
		fctx->next_deadline_fence =
			max(fctx->next_deadline_fence, (uint32_t)fence->seqno);

		/*
		 * Set timer to trigger boost 3ms before deadline, or
		 * if we are already less than 3ms before the deadline
		 * schedule boost work immediately.
		 */
		deadline = ktime_sub(deadline, ms_to_ktime(3));

		if (ktime_after(now, deadline)) {
			kthread_queue_work(fctx2gpu(fctx)->worker,
					&fctx->deadline_work);
		} else {
			hrtimer_start(&fctx->deadline_timer, deadline,
					HRTIMER_MODE_ABS);
		}
	}

	spin_unlock_irqrestore(&fctx->spinlock, flags);
}

static const struct dma_fence_ops msm_fence_ops = {
	.get_driver_name = msm_fence_get_driver_name,
	.get_timeline_name = msm_fence_get_timeline_name,
	.signaled = msm_fence_signaled,
	.set_deadline = msm_fence_set_deadline,
};

struct dma_fence *
msm_fence_alloc(void)
{
	struct msm_fence *f;

	f = kzalloc_obj(*f);
	if (!f)
		return ERR_PTR(-ENOMEM);

	return &f->base;
}

void
msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx)
{
	struct msm_fence *f = to_msm_fence(fence);

	f->fctx = fctx;

	/*
	 * Until this point, the fence was just some pre-allocated memory,

Annotation

Implementation Notes