summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/include
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2017-04-12 14:27:48 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-04-25 17:26:00 -0400
commit84dadb1a9ae2ab0473976ebf5ece1cb0d1e60205 (patch)
tree8ec8d404c319082dc472eae1ca1b56f2b7e7c197 /drivers/gpu/nvgpu/include
parentaff9d46c00a2a82c93d6cc43d790584e7e474d0e (diff)
gpu: nvgpu: Move semaphore impl to nvgpu_mem
Use struct nvgpu_mem for DMA allocations (and the corresponding nvgpu_dma_alloc_sys()) instead of custom rolled code. This migrates away from using linux scatter gather tables directly. Instead this is hidden in the nvgpu_mem struct. With this change the semaphore.c code no longer has any direct Linux dependencies. JIRA NVGPU-12 JIRA NVGPU-30 Change-Id: I92167c98aac9b413ae87496744dcee051cd60207 Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1464081 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/include')
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/semaphore.h72
1 files changed, 36 insertions, 36 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
index f197a918..45a3af5a 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
@@ -14,23 +14,22 @@
14#ifndef SEMAPHORE_GK20A_H 14#ifndef SEMAPHORE_GK20A_H
15#define SEMAPHORE_GK20A_H 15#define SEMAPHORE_GK20A_H
16 16
17#include <linux/delay.h>
18
19#include <nvgpu/log.h> 17#include <nvgpu/log.h>
20#include <nvgpu/allocator.h> 18#include <nvgpu/timers.h>
21#include <nvgpu/atomic.h> 19#include <nvgpu/atomic.h>
22#include <nvgpu/bug.h> 20#include <nvgpu/bug.h>
23#include <nvgpu/kref.h> 21#include <nvgpu/kref.h>
24#include <nvgpu/list.h> 22#include <nvgpu/list.h>
23#include <nvgpu/nvgpu_mem.h>
25 24
26#include "gk20a/gk20a.h" 25#include "gk20a/gk20a.h"
27#include "gk20a/mm_gk20a.h" 26#include "gk20a/mm_gk20a.h"
28#include "gk20a/channel_gk20a.h" 27#include "gk20a/channel_gk20a.h"
29 28
30#define gpu_sema_dbg(fmt, args...) \ 29#define gpu_sema_dbg(g, fmt, args...) \
31 gk20a_dbg(gpu_dbg_sema, fmt, ##args) 30 nvgpu_log(g, gpu_dbg_sema, fmt, ##args)
32#define gpu_sema_verbose_dbg(fmt, args...) \ 31#define gpu_sema_verbose_dbg(g, fmt, args...) \
33 gk20a_dbg(gpu_dbg_sema_v, fmt, ##args) 32 nvgpu_log(g, gpu_dbg_sema_v, fmt, ##args)
34 33
35/* 34/*
36 * Max number of channels that can be used is 512. This of course needs to be 35 * Max number of channels that can be used is 512. This of course needs to be
@@ -50,7 +49,6 @@ struct nvgpu_semaphore_int {
50 int idx; /* Semaphore index. */ 49 int idx; /* Semaphore index. */
51 u32 offset; /* Offset into the pool. */ 50 u32 offset; /* Offset into the pool. */
52 atomic_t next_value; /* Next available value. */ 51 atomic_t next_value; /* Next available value. */
53 u32 *value; /* Current value (access w/ readl()). */
54 u32 nr_incrs; /* Number of increments programmed. */ 52 u32 nr_incrs; /* Number of increments programmed. */
55 struct nvgpu_semaphore_pool *p; /* Pool that owns this sema. */ 53 struct nvgpu_semaphore_pool *p; /* Pool that owns this sema. */
56 struct channel_gk20a *ch; /* Channel that owns this sema. */ 54 struct channel_gk20a *ch; /* Channel that owns this sema. */
@@ -82,9 +80,7 @@ struct nvgpu_semaphore {
82 * A semaphore pool. Each address space will own exactly one of these. 80 * A semaphore pool. Each address space will own exactly one of these.
83 */ 81 */
84struct nvgpu_semaphore_pool { 82struct nvgpu_semaphore_pool {
85 struct page *page; /* This pool's page of memory */
86 struct nvgpu_list_node pool_list_entry; /* Node for list of pools. */ 83 struct nvgpu_list_node pool_list_entry; /* Node for list of pools. */
87 void *cpu_va; /* CPU access to the pool. */
88 u64 gpu_va; /* GPU access to the pool. */ 84 u64 gpu_va; /* GPU access to the pool. */
89 u64 gpu_va_ro; /* GPU access to the pool. */ 85 u64 gpu_va_ro; /* GPU access to the pool. */
90 int page_idx; /* Index into sea bitmap. */ 86 int page_idx; /* Index into sea bitmap. */
@@ -98,15 +94,10 @@ struct nvgpu_semaphore_pool {
98 94
99 /* 95 /*
100 * This is the address spaces's personal RW table. Other channels will 96 * This is the address spaces's personal RW table. Other channels will
101 * ultimately map this page as RO. 97 * ultimately map this page as RO. This is a sub-nvgpu_mem from the
102 */ 98 * sea's mem.
103 struct sg_table *rw_sg_table;
104
105 /*
106 * This is to keep track of whether the pool has had its sg_table
107 * updated during sea resizing.
108 */ 99 */
109 struct sg_table *ro_sg_table; 100 struct nvgpu_mem rw_mem;
110 101
111 int mapped; 102 int mapped;
112 103
@@ -148,11 +139,12 @@ struct nvgpu_semaphore_sea {
148 */ 139 */
149 int page_count; /* Pages allocated to pools. */ 140 int page_count; /* Pages allocated to pools. */
150 141
151 struct sg_table *ro_sg_table;
152 /* 142 /*
153 struct page *pages[SEMAPHORE_POOL_COUNT]; 143 * The read-only memory for the entire semaphore sea. Each semaphore
154 */ 144 * pool needs a sub-nvgpu_mem that will be mapped as RW in its address
155 145 * space. This sea_mem cannot be freed until all semaphore_pools have
146 * been freed.
147 */
156 struct nvgpu_mem sea_mem; 148 struct nvgpu_mem sea_mem;
157 149
158 /* 150 /*
@@ -224,12 +216,26 @@ static inline u64 nvgpu_hw_sema_addr(struct nvgpu_semaphore_int *hw_sema)
224 hw_sema->offset; 216 hw_sema->offset;
225} 217}
226 218
219static inline u32 __nvgpu_semaphore_read(struct nvgpu_semaphore_int *hw_sema)
220{
221 return nvgpu_mem_rd(hw_sema->ch->g,
222 &hw_sema->p->rw_mem, hw_sema->offset);
223}
224
225/*
226 * Read the underlying value from a semaphore.
227 */
228static inline u32 nvgpu_semaphore_read(struct nvgpu_semaphore *s)
229{
230 return __nvgpu_semaphore_read(s->hw_sema);
231}
232
227/* 233/*
228 * TODO: handle wrap around... Hmm, how to do this? 234 * TODO: handle wrap around... Hmm, how to do this?
229 */ 235 */
230static inline bool nvgpu_semaphore_is_released(struct nvgpu_semaphore *s) 236static inline bool nvgpu_semaphore_is_released(struct nvgpu_semaphore *s)
231{ 237{
232 u32 sema_val = readl(s->hw_sema->value); 238 u32 sema_val = nvgpu_semaphore_read(s);
233 239
234 /* 240 /*
235 * If the underlying semaphore value is greater than or equal to 241 * If the underlying semaphore value is greater than or equal to
@@ -244,14 +250,6 @@ static inline bool nvgpu_semaphore_is_acquired(struct nvgpu_semaphore *s)
244 return !nvgpu_semaphore_is_released(s); 250 return !nvgpu_semaphore_is_released(s);
245} 251}
246 252
247/*
248 * Read the underlying value from a semaphore.
249 */
250static inline u32 nvgpu_semaphore_read(struct nvgpu_semaphore *s)
251{
252 return readl(s->hw_sema->value);
253}
254
255static inline u32 nvgpu_semaphore_get_value(struct nvgpu_semaphore *s) 253static inline u32 nvgpu_semaphore_get_value(struct nvgpu_semaphore *s)
256{ 254{
257 return (u32)atomic_read(&s->value); 255 return (u32)atomic_read(&s->value);
@@ -269,6 +267,7 @@ static inline u32 nvgpu_semaphore_next_value(struct nvgpu_semaphore *s)
269static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, 267static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s,
270 bool force) 268 bool force)
271{ 269{
270 struct nvgpu_semaphore_int *hw_sema = s->hw_sema;
272 u32 current_val; 271 u32 current_val;
273 u32 val = nvgpu_semaphore_get_value(s); 272 u32 val = nvgpu_semaphore_get_value(s);
274 int attempts = 0; 273 int attempts = 0;
@@ -282,7 +281,7 @@ static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s,
282 while ((current_val = nvgpu_semaphore_read(s)) < (val - 1)) { 281 while ((current_val = nvgpu_semaphore_read(s)) < (val - 1)) {
283 if (force) 282 if (force)
284 break; 283 break;
285 msleep(100); 284 nvgpu_msleep(100);
286 attempts += 1; 285 attempts += 1;
287 if (attempts > 100) { 286 if (attempts > 100) {
288 WARN(1, "Stall on sema release!"); 287 WARN(1, "Stall on sema release!");
@@ -297,10 +296,10 @@ static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s,
297 if (current_val >= val) 296 if (current_val >= val)
298 return; 297 return;
299 298
300 writel(val, s->hw_sema->value); 299 nvgpu_mem_wr(hw_sema->ch->g, &hw_sema->p->rw_mem, hw_sema->offset, val);
301 300
302 gpu_sema_verbose_dbg("(c=%d) WRITE %u", 301 gpu_sema_verbose_dbg(hw_sema->p->sema_sea->gk20a,
303 s->hw_sema->ch->hw_chid, val); 302 "(c=%d) WRITE %u", hw_sema->ch->hw_chid, val);
304} 303}
305 304
306static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s) 305static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s)
@@ -324,7 +323,8 @@ static inline void nvgpu_semaphore_incr(struct nvgpu_semaphore *s)
324 atomic_set(&s->value, atomic_add_return(1, &s->hw_sema->next_value)); 323 atomic_set(&s->value, atomic_add_return(1, &s->hw_sema->next_value));
325 s->incremented = 1; 324 s->incremented = 1;
326 325
327 gpu_sema_verbose_dbg("INCR sema for c=%d (%u)", 326 gpu_sema_verbose_dbg(s->hw_sema->p->sema_sea->gk20a,
327 "INCR sema for c=%d (%u)",
328 s->hw_sema->ch->hw_chid, 328 s->hw_sema->ch->hw_chid,
329 nvgpu_semaphore_next_value(s)); 329 nvgpu_semaphore_next_value(s));
330} 330}