summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h')
-rw-r--r--drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h97
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h b/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h
new file mode 100644
index 00000000..214db398
--- /dev/null
+++ b/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.h
@@ -0,0 +1,97 @@
1/*
2 * drivers/video/tegra/host/gk20a/semaphore_gk20a.h
3 *
4 * GK20A Semaphores
5 *
6 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 */
17
18#ifndef _GK20A_SEMAPHORE_H_
19#define _GK20A_SEMAPHORE_H_
20
21#include <linux/kref.h>
22#include "gk20a_allocator.h"
23#include "mm_gk20a.h"
24
25/* A memory pool for holding semaphores. */
26struct gk20a_semaphore_pool {
27 void *cpu_va;
28 dma_addr_t iova;
29 size_t size;
30 struct device *dev;
31 struct sg_table *sgt;
32 struct list_head maps;
33 struct mutex maps_mutex;
34 struct kref ref;
35 struct gk20a_allocator alloc;
36};
37
38/* A semaphore pool can be mapped to multiple GPU address spaces. */
39struct gk20a_semaphore_pool_map {
40 u64 gpu_va;
41 enum gk20a_mem_rw_flag rw_flag;
42 struct vm_gk20a *vm;
43 struct list_head list;
44};
45
46/* A semaphore that lives inside a semaphore pool. */
47struct gk20a_semaphore {
48 struct gk20a_semaphore_pool *pool;
49 u32 offset; /* byte offset within pool */
50 struct kref ref;
51 /* value is a pointer within the pool's coherent cpu_va.
52 * It is shared between CPU and GPU, hence volatile. */
53 volatile u32 *value; /* 0=acquired, 1=released */
54};
55
56/* Create a semaphore pool that can hold at most 'capacity' semaphores. */
57struct gk20a_semaphore_pool *
58gk20a_semaphore_pool_alloc(struct device *, const char *unique_name,
59 size_t capacity);
60void gk20a_semaphore_pool_put(struct gk20a_semaphore_pool *);
61int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *,
62 struct vm_gk20a *,
63 enum gk20a_mem_rw_flag);
64void gk20a_semaphore_pool_unmap(struct gk20a_semaphore_pool *,
65 struct vm_gk20a *);
66u64 gk20a_semaphore_pool_gpu_va(struct gk20a_semaphore_pool *,
67 struct vm_gk20a *);
68
69/* Allocate a semaphore from the semaphore pool. The newly allocated
70 * semaphore will be in acquired state (value=0). */
71struct gk20a_semaphore *
72gk20a_semaphore_alloc(struct gk20a_semaphore_pool *);
73void gk20a_semaphore_put(struct gk20a_semaphore *);
74void gk20a_semaphore_get(struct gk20a_semaphore *);
75
76static inline u64 gk20a_semaphore_gpu_va(struct gk20a_semaphore *s,
77 struct vm_gk20a *vm)
78{
79 return gk20a_semaphore_pool_gpu_va(s->pool, vm) + s->offset;
80}
81
82static inline bool gk20a_semaphore_is_acquired(struct gk20a_semaphore *s)
83{
84 u32 v = *s->value;
85
86 /* When often block on value reaching a certain threshold. We must make
87 * sure that if we get unblocked, we haven't read anything too early. */
88 smp_rmb();
89 return v == 0;
90}
91
92static inline void gk20a_semaphore_release(struct gk20a_semaphore *s)
93{
94 smp_wmb();
95 *s->value = 1;
96}
97#endif