diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/common/mm/nvgpu_mem.c | 109 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/posix/io.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c | 59 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/pramin.c | 72 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/io.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/pramin.h | 12 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/io.c | 12 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/nvgpu_mem.c | 201 |
8 files changed, 201 insertions, 270 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/nvgpu_mem.c b/drivers/gpu/nvgpu/common/mm/nvgpu_mem.c index 855d455d..9f3b6cfa 100644 --- a/drivers/gpu/nvgpu/common/mm/nvgpu_mem.c +++ b/drivers/gpu/nvgpu/common/mm/nvgpu_mem.c | |||
@@ -177,3 +177,112 @@ u64 nvgpu_sgt_alignment(struct gk20a *g, struct nvgpu_sgt *sgt) | |||
177 | 177 | ||
178 | return align; | 178 | return align; |
179 | } | 179 | } |
180 | |||
181 | u32 nvgpu_mem_rd32(struct gk20a *g, struct nvgpu_mem *mem, u32 w) | ||
182 | { | ||
183 | u32 data = 0; | ||
184 | |||
185 | if (mem->aperture == APERTURE_SYSMEM) { | ||
186 | u32 *ptr = mem->cpu_va; | ||
187 | |||
188 | WARN_ON(!ptr); | ||
189 | data = ptr[w]; | ||
190 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
191 | nvgpu_pramin_rd_n(g, mem, w * sizeof(u32), sizeof(u32), &data); | ||
192 | } else { | ||
193 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
194 | } | ||
195 | |||
196 | return data; | ||
197 | } | ||
198 | |||
199 | u32 nvgpu_mem_rd(struct gk20a *g, struct nvgpu_mem *mem, u32 offset) | ||
200 | { | ||
201 | WARN_ON(offset & 3); | ||
202 | return nvgpu_mem_rd32(g, mem, offset / sizeof(u32)); | ||
203 | } | ||
204 | |||
205 | void nvgpu_mem_rd_n(struct gk20a *g, struct nvgpu_mem *mem, | ||
206 | u32 offset, void *dest, u32 size) | ||
207 | { | ||
208 | WARN_ON(offset & 3); | ||
209 | WARN_ON(size & 3); | ||
210 | |||
211 | if (mem->aperture == APERTURE_SYSMEM) { | ||
212 | u8 *src = (u8 *)mem->cpu_va + offset; | ||
213 | |||
214 | WARN_ON(!mem->cpu_va); | ||
215 | memcpy(dest, src, size); | ||
216 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
217 | nvgpu_pramin_rd_n(g, mem, offset, size, dest); | ||
218 | } else { | ||
219 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | void nvgpu_mem_wr32(struct gk20a *g, struct nvgpu_mem *mem, u32 w, u32 data) | ||
224 | { | ||
225 | if (mem->aperture == APERTURE_SYSMEM) { | ||
226 | u32 *ptr = mem->cpu_va; | ||
227 | |||
228 | WARN_ON(!ptr); | ||
229 | ptr[w] = data; | ||
230 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
231 | nvgpu_pramin_wr_n(g, mem, w * sizeof(u32), sizeof(u32), &data); | ||
232 | if (!mem->skip_wmb) | ||
233 | nvgpu_wmb(); | ||
234 | } else { | ||
235 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | void nvgpu_mem_wr(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, u32 data) | ||
240 | { | ||
241 | WARN_ON(offset & 3); | ||
242 | nvgpu_mem_wr32(g, mem, offset / sizeof(u32), data); | ||
243 | } | ||
244 | |||
245 | void nvgpu_mem_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | ||
246 | void *src, u32 size) | ||
247 | { | ||
248 | WARN_ON(offset & 3); | ||
249 | WARN_ON(size & 3); | ||
250 | |||
251 | if (mem->aperture == APERTURE_SYSMEM) { | ||
252 | u8 *dest = (u8 *)mem->cpu_va + offset; | ||
253 | |||
254 | WARN_ON(!mem->cpu_va); | ||
255 | memcpy(dest, src, size); | ||
256 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
257 | nvgpu_pramin_wr_n(g, mem, offset, size, src); | ||
258 | if (!mem->skip_wmb) | ||
259 | nvgpu_wmb(); | ||
260 | } else { | ||
261 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | void nvgpu_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | ||
266 | u32 c, u32 size) | ||
267 | { | ||
268 | WARN_ON(offset & 3); | ||
269 | WARN_ON(size & 3); | ||
270 | WARN_ON(c & ~0xff); | ||
271 | |||
272 | c &= 0xff; | ||
273 | |||
274 | if (mem->aperture == APERTURE_SYSMEM) { | ||
275 | u8 *dest = (u8 *)mem->cpu_va + offset; | ||
276 | |||
277 | WARN_ON(!mem->cpu_va); | ||
278 | memset(dest, c, size); | ||
279 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
280 | u32 repeat_value = c | (c << 8) | (c << 16) | (c << 24); | ||
281 | |||
282 | nvgpu_pramin_memset(g, mem, offset, size, repeat_value); | ||
283 | if (!mem->skip_wmb) | ||
284 | nvgpu_wmb(); | ||
285 | } else { | ||
286 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
287 | } | ||
288 | } | ||
diff --git a/drivers/gpu/nvgpu/common/posix/io.c b/drivers/gpu/nvgpu/common/posix/io.c index ce018940..dc32c20e 100644 --- a/drivers/gpu/nvgpu/common/posix/io.c +++ b/drivers/gpu/nvgpu/common/posix/io.c | |||
@@ -35,6 +35,11 @@ void nvgpu_writel(struct gk20a *g, u32 r, u32 v) | |||
35 | BUG(); | 35 | BUG(); |
36 | } | 36 | } |
37 | 37 | ||
38 | void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v) | ||
39 | { | ||
40 | BUG(); | ||
41 | } | ||
42 | |||
38 | u32 nvgpu_readl(struct gk20a *g, u32 r) | 43 | u32 nvgpu_readl(struct gk20a *g, u32 r) |
39 | { | 44 | { |
40 | BUG(); | 45 | BUG(); |
diff --git a/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c b/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c index 7f3bf9f1..fa92a7c6 100644 --- a/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c +++ b/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c | |||
@@ -27,65 +27,6 @@ | |||
27 | #include <nvgpu/nvgpu_mem.h> | 27 | #include <nvgpu/nvgpu_mem.h> |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * DMA memory buffers - obviously we don't really have DMA in userspace but we | ||
31 | * can emulate a lot of the DMA mem functionality for unit testing purposes. | ||
32 | */ | ||
33 | |||
34 | u32 nvgpu_mem_rd32(struct gk20a *g, struct nvgpu_mem *mem, u32 w) | ||
35 | { | ||
36 | u32 *mem_ptr = (u32 *)mem->cpu_va; | ||
37 | |||
38 | return mem_ptr[w]; | ||
39 | } | ||
40 | |||
41 | u32 nvgpu_mem_rd(struct gk20a *g, struct nvgpu_mem *mem, u32 offset) | ||
42 | { | ||
43 | if (offset & 0x3) | ||
44 | BUG(); | ||
45 | |||
46 | return nvgpu_mem_rd32(g, mem, offset >> 2); | ||
47 | } | ||
48 | |||
49 | void nvgpu_mem_rd_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | ||
50 | void *dest, u32 size) | ||
51 | { | ||
52 | if (offset & 0x3 || size & 0x3) | ||
53 | BUG(); | ||
54 | |||
55 | memcpy(dest, ((char *)mem->cpu_va) + offset, size); | ||
56 | } | ||
57 | |||
58 | void nvgpu_mem_wr32(struct gk20a *g, struct nvgpu_mem *mem, u32 w, u32 data) | ||
59 | { | ||
60 | u32 *mem_ptr = (u32 *)mem->cpu_va; | ||
61 | |||
62 | mem_ptr[w] = data; | ||
63 | } | ||
64 | |||
65 | void nvgpu_mem_wr(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, u32 data) | ||
66 | { | ||
67 | if (offset & 0x3) | ||
68 | BUG(); | ||
69 | |||
70 | nvgpu_mem_wr32(g, mem, offset >> 2, data); | ||
71 | } | ||
72 | |||
73 | void nvgpu_mem_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | ||
74 | void *src, u32 size) | ||
75 | { | ||
76 | if (offset & 0x3 || size & 0x3) | ||
77 | BUG(); | ||
78 | |||
79 | memcpy(((char *)mem->cpu_va) + offset, src, size); | ||
80 | } | ||
81 | |||
82 | void nvgpu_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | ||
83 | u32 c, u32 size) | ||
84 | { | ||
85 | memset(((char *)mem->cpu_va) + offset, c, size); | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * These functions are somewhat meaningless. | 30 | * These functions are somewhat meaningless. |
90 | */ | 31 | */ |
91 | u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem) | 32 | u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem) |
diff --git a/drivers/gpu/nvgpu/common/pramin.c b/drivers/gpu/nvgpu/common/pramin.c index 4c6a4a0d..99d588aa 100644 --- a/drivers/gpu/nvgpu/common/pramin.c +++ b/drivers/gpu/nvgpu/common/pramin.c | |||
@@ -28,11 +28,18 @@ | |||
28 | #include "gk20a/gk20a.h" | 28 | #include "gk20a/gk20a.h" |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * This typedef is for functions that get called during the access_batched() | ||
32 | * operation. | ||
33 | */ | ||
34 | typedef void (*pramin_access_batch_fn)(struct gk20a *g, u32 start, u32 words, | ||
35 | u32 **arg); | ||
36 | |||
37 | /* | ||
31 | * The PRAMIN range is 1 MB, must change base addr if a buffer crosses that. | 38 | * The PRAMIN range is 1 MB, must change base addr if a buffer crosses that. |
32 | * This same loop is used for read/write/memset. Offset and size in bytes. | 39 | * This same loop is used for read/write/memset. Offset and size in bytes. |
33 | * One call to "loop" is done per range, with "arg" supplied. | 40 | * One call to "loop" is done per range, with "arg" supplied. |
34 | */ | 41 | */ |
35 | void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem, | 42 | static void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem, |
36 | u32 offset, u32 size, pramin_access_batch_fn loop, u32 **arg) | 43 | u32 offset, u32 size, pramin_access_batch_fn loop, u32 **arg) |
37 | { | 44 | { |
38 | struct nvgpu_page_alloc *alloc = NULL; | 45 | struct nvgpu_page_alloc *alloc = NULL; |
@@ -87,6 +94,69 @@ void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem, | |||
87 | } | 94 | } |
88 | } | 95 | } |
89 | 96 | ||
97 | static void nvgpu_pramin_access_batch_rd_n(struct gk20a *g, | ||
98 | u32 start, u32 words, u32 **arg) | ||
99 | { | ||
100 | u32 r = start, *dest_u32 = *arg; | ||
101 | |||
102 | while (words--) { | ||
103 | *dest_u32++ = nvgpu_readl(g, r); | ||
104 | r += sizeof(u32); | ||
105 | } | ||
106 | |||
107 | *arg = dest_u32; | ||
108 | } | ||
109 | |||
110 | void nvgpu_pramin_rd_n(struct gk20a *g, struct nvgpu_mem *mem, | ||
111 | u32 start, u32 size, void *dest) | ||
112 | { | ||
113 | u32 *dest_u32 = dest; | ||
114 | |||
115 | return nvgpu_pramin_access_batched(g, mem, start, size, | ||
116 | nvgpu_pramin_access_batch_rd_n, &dest_u32); | ||
117 | } | ||
118 | |||
119 | static void nvgpu_pramin_access_batch_wr_n(struct gk20a *g, | ||
120 | u32 start, u32 words, u32 **arg) | ||
121 | { | ||
122 | u32 r = start, *src_u32 = *arg; | ||
123 | |||
124 | while (words--) { | ||
125 | nvgpu_writel_relaxed(g, r, *src_u32++); | ||
126 | r += sizeof(u32); | ||
127 | } | ||
128 | |||
129 | *arg = src_u32; | ||
130 | } | ||
131 | |||
132 | void nvgpu_pramin_wr_n(struct gk20a *g, struct nvgpu_mem *mem, | ||
133 | u32 start, u32 size, void *src) | ||
134 | { | ||
135 | u32 *src_u32 = src; | ||
136 | |||
137 | return nvgpu_pramin_access_batched(g, mem, start, size, | ||
138 | nvgpu_pramin_access_batch_wr_n, &src_u32); | ||
139 | } | ||
140 | |||
141 | static void nvgpu_pramin_access_batch_set(struct gk20a *g, | ||
142 | u32 start, u32 words, u32 **arg) | ||
143 | { | ||
144 | u32 r = start, repeat = **arg; | ||
145 | |||
146 | while (words--) { | ||
147 | nvgpu_writel_relaxed(g, r, repeat); | ||
148 | r += sizeof(u32); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | void nvgpu_pramin_memset(struct gk20a *g, struct nvgpu_mem *mem, | ||
153 | u32 start, u32 size, u32 w) | ||
154 | { | ||
155 | u32 *p = &w; | ||
156 | |||
157 | return nvgpu_pramin_access_batched(g, mem, start, size, | ||
158 | nvgpu_pramin_access_batch_set, &p); | ||
159 | } | ||
90 | void nvgpu_init_pramin(struct mm_gk20a *mm) | 160 | void nvgpu_init_pramin(struct mm_gk20a *mm) |
91 | { | 161 | { |
92 | mm->pramin_window = 0; | 162 | mm->pramin_window = 0; |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/io.h b/drivers/gpu/nvgpu/include/nvgpu/io.h index 28011e04..8504829c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/io.h +++ b/drivers/gpu/nvgpu/include/nvgpu/io.h | |||
@@ -36,6 +36,7 @@ | |||
36 | struct gk20a; | 36 | struct gk20a; |
37 | 37 | ||
38 | void nvgpu_writel(struct gk20a *g, u32 r, u32 v); | 38 | void nvgpu_writel(struct gk20a *g, u32 r, u32 v); |
39 | void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v); | ||
39 | u32 nvgpu_readl(struct gk20a *g, u32 r); | 40 | u32 nvgpu_readl(struct gk20a *g, u32 r); |
40 | u32 __nvgpu_readl(struct gk20a *g, u32 r); | 41 | u32 __nvgpu_readl(struct gk20a *g, u32 r); |
41 | void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v); | 42 | void nvgpu_writel_check(struct gk20a *g, u32 r, u32 v); |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/pramin.h b/drivers/gpu/nvgpu/include/nvgpu/pramin.h index 33702bc8..c9f54a6f 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pramin.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pramin.h | |||
@@ -29,16 +29,10 @@ struct gk20a; | |||
29 | struct mm_gk20a; | 29 | struct mm_gk20a; |
30 | struct nvgpu_mem; | 30 | struct nvgpu_mem; |
31 | 31 | ||
32 | /* | ||
33 | * This typedef is for functions that get called during the access_batched() | ||
34 | * operation. | ||
35 | */ | ||
36 | typedef void (*pramin_access_batch_fn)(struct gk20a *g, u32 start, u32 words, | ||
37 | u32 **arg); | ||
38 | 32 | ||
39 | void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem, | 33 | void nvgpu_pramin_rd_n(struct gk20a *g, struct nvgpu_mem *mem, u32 start, u32 words, void *dest); |
40 | u32 offset, u32 size, | 34 | void nvgpu_pramin_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 start, u32 words, void *src); |
41 | pramin_access_batch_fn loop, u32 **arg); | 35 | void nvgpu_pramin_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 start, u32 words, u32 w); |
42 | 36 | ||
43 | void nvgpu_init_pramin(struct mm_gk20a *mm); | 37 | void nvgpu_init_pramin(struct mm_gk20a *mm); |
44 | 38 | ||
diff --git a/drivers/gpu/nvgpu/os/linux/io.c b/drivers/gpu/nvgpu/os/linux/io.c index c06512a5..9a0e29d7 100644 --- a/drivers/gpu/nvgpu/os/linux/io.c +++ b/drivers/gpu/nvgpu/os/linux/io.c | |||
@@ -31,6 +31,18 @@ void nvgpu_writel(struct gk20a *g, u32 r, u32 v) | |||
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v) | ||
35 | { | ||
36 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
37 | |||
38 | if (unlikely(!l->regs)) { | ||
39 | __gk20a_warn_on_no_regs(); | ||
40 | nvgpu_log(g, gpu_dbg_reg, "r=0x%x v=0x%x (failed)", r, v); | ||
41 | } else { | ||
42 | writel_relaxed(v, l->regs + r); | ||
43 | } | ||
44 | } | ||
45 | |||
34 | u32 nvgpu_readl(struct gk20a *g, u32 r) | 46 | u32 nvgpu_readl(struct gk20a *g, u32 r) |
35 | { | 47 | { |
36 | u32 v = __nvgpu_readl(g, r); | 48 | u32 v = __nvgpu_readl(g, r); |
diff --git a/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c b/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c index 04b2afa7..aa8fcd84 100644 --- a/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c +++ b/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c | |||
@@ -48,207 +48,6 @@ static u64 __nvgpu_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl) | |||
48 | return ipa; | 48 | return ipa; |
49 | } | 49 | } |
50 | 50 | ||
51 | static void pramin_access_batch_rd_n(struct gk20a *g, u32 start, u32 words, u32 **arg) | ||
52 | { | ||
53 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
54 | u32 r = start, *dest_u32 = *arg; | ||
55 | |||
56 | if (!l->regs) { | ||
57 | __gk20a_warn_on_no_regs(); | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | while (words--) { | ||
62 | *dest_u32++ = gk20a_readl(g, r); | ||
63 | r += sizeof(u32); | ||
64 | } | ||
65 | |||
66 | *arg = dest_u32; | ||
67 | } | ||
68 | |||
69 | u32 nvgpu_mem_rd32(struct gk20a *g, struct nvgpu_mem *mem, u32 w) | ||
70 | { | ||
71 | u32 data = 0; | ||
72 | |||
73 | if (mem->aperture == APERTURE_SYSMEM) { | ||
74 | u32 *ptr = mem->cpu_va; | ||
75 | |||
76 | WARN_ON(!ptr); | ||
77 | data = ptr[w]; | ||
78 | #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM | ||
79 | nvgpu_log(g, gpu_dbg_mem, " %p = 0x%x", ptr + w, data); | ||
80 | #endif | ||
81 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
82 | u32 value; | ||
83 | u32 *p = &value; | ||
84 | |||
85 | nvgpu_pramin_access_batched(g, mem, w * sizeof(u32), | ||
86 | sizeof(u32), pramin_access_batch_rd_n, &p); | ||
87 | |||
88 | data = value; | ||
89 | |||
90 | } else { | ||
91 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
92 | } | ||
93 | |||
94 | return data; | ||
95 | } | ||
96 | |||
97 | u32 nvgpu_mem_rd(struct gk20a *g, struct nvgpu_mem *mem, u32 offset) | ||
98 | { | ||
99 | WARN_ON(offset & 3); | ||
100 | return nvgpu_mem_rd32(g, mem, offset / sizeof(u32)); | ||
101 | } | ||
102 | |||
103 | void nvgpu_mem_rd_n(struct gk20a *g, struct nvgpu_mem *mem, | ||
104 | u32 offset, void *dest, u32 size) | ||
105 | { | ||
106 | WARN_ON(offset & 3); | ||
107 | WARN_ON(size & 3); | ||
108 | |||
109 | if (mem->aperture == APERTURE_SYSMEM) { | ||
110 | u8 *src = (u8 *)mem->cpu_va + offset; | ||
111 | |||
112 | WARN_ON(!mem->cpu_va); | ||
113 | memcpy(dest, src, size); | ||
114 | #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM | ||
115 | if (size) | ||
116 | nvgpu_log(g, gpu_dbg_mem, " %p = 0x%x ... [%d bytes]", | ||
117 | src, *dest, size); | ||
118 | #endif | ||
119 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
120 | u32 *dest_u32 = dest; | ||
121 | |||
122 | nvgpu_pramin_access_batched(g, mem, offset, size, | ||
123 | pramin_access_batch_rd_n, &dest_u32); | ||
124 | } else { | ||
125 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | static void pramin_access_batch_wr_n(struct gk20a *g, u32 start, u32 words, u32 **arg) | ||
130 | { | ||
131 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
132 | u32 r = start, *src_u32 = *arg; | ||
133 | |||
134 | if (!l->regs) { | ||
135 | __gk20a_warn_on_no_regs(); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | while (words--) { | ||
140 | writel_relaxed(*src_u32++, l->regs + r); | ||
141 | r += sizeof(u32); | ||
142 | } | ||
143 | |||
144 | *arg = src_u32; | ||
145 | } | ||
146 | |||
147 | void nvgpu_mem_wr32(struct gk20a *g, struct nvgpu_mem *mem, u32 w, u32 data) | ||
148 | { | ||
149 | if (mem->aperture == APERTURE_SYSMEM) { | ||
150 | u32 *ptr = mem->cpu_va; | ||
151 | |||
152 | WARN_ON(!ptr); | ||
153 | #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM | ||
154 | nvgpu_log(g, gpu_dbg_mem, " %p = 0x%x", ptr + w, data); | ||
155 | #endif | ||
156 | ptr[w] = data; | ||
157 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
158 | u32 value = data; | ||
159 | u32 *p = &value; | ||
160 | |||
161 | nvgpu_pramin_access_batched(g, mem, w * sizeof(u32), | ||
162 | sizeof(u32), pramin_access_batch_wr_n, &p); | ||
163 | if (!mem->skip_wmb) | ||
164 | wmb(); | ||
165 | } else { | ||
166 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | void nvgpu_mem_wr(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, u32 data) | ||
171 | { | ||
172 | WARN_ON(offset & 3); | ||
173 | nvgpu_mem_wr32(g, mem, offset / sizeof(u32), data); | ||
174 | } | ||
175 | |||
176 | void nvgpu_mem_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | ||
177 | void *src, u32 size) | ||
178 | { | ||
179 | WARN_ON(offset & 3); | ||
180 | WARN_ON(size & 3); | ||
181 | |||
182 | if (mem->aperture == APERTURE_SYSMEM) { | ||
183 | u8 *dest = (u8 *)mem->cpu_va + offset; | ||
184 | |||
185 | WARN_ON(!mem->cpu_va); | ||
186 | #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM | ||
187 | if (size) | ||
188 | nvgpu_log(g, gpu_dbg_mem, " %p = 0x%x ... [%d bytes]", | ||
189 | dest, *src, size); | ||
190 | #endif | ||
191 | memcpy(dest, src, size); | ||
192 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
193 | u32 *src_u32 = src; | ||
194 | |||
195 | nvgpu_pramin_access_batched(g, mem, offset, size, | ||
196 | pramin_access_batch_wr_n, &src_u32); | ||
197 | if (!mem->skip_wmb) | ||
198 | wmb(); | ||
199 | } else { | ||
200 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static void pramin_access_batch_set(struct gk20a *g, u32 start, u32 words, u32 **arg) | ||
205 | { | ||
206 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
207 | u32 r = start, repeat = **arg; | ||
208 | |||
209 | if (!l->regs) { | ||
210 | __gk20a_warn_on_no_regs(); | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | while (words--) { | ||
215 | writel_relaxed(repeat, l->regs + r); | ||
216 | r += sizeof(u32); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | void nvgpu_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, | ||
221 | u32 c, u32 size) | ||
222 | { | ||
223 | WARN_ON(offset & 3); | ||
224 | WARN_ON(size & 3); | ||
225 | WARN_ON(c & ~0xff); | ||
226 | |||
227 | c &= 0xff; | ||
228 | |||
229 | if (mem->aperture == APERTURE_SYSMEM) { | ||
230 | u8 *dest = (u8 *)mem->cpu_va + offset; | ||
231 | |||
232 | WARN_ON(!mem->cpu_va); | ||
233 | #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM | ||
234 | if (size) | ||
235 | nvgpu_log(g, gpu_dbg_mem, " %p = 0x%x [times %d]", | ||
236 | dest, c, size); | ||
237 | #endif | ||
238 | memset(dest, c, size); | ||
239 | } else if (mem->aperture == APERTURE_VIDMEM) { | ||
240 | u32 repeat_value = c | (c << 8) | (c << 16) | (c << 24); | ||
241 | u32 *p = &repeat_value; | ||
242 | |||
243 | nvgpu_pramin_access_batched(g, mem, offset, size, | ||
244 | pramin_access_batch_set, &p); | ||
245 | if (!mem->skip_wmb) | ||
246 | wmb(); | ||
247 | } else { | ||
248 | WARN_ON("Accessing unallocated nvgpu_mem"); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | /* | 51 | /* |
253 | * Obtain a SYSMEM address from a Linux SGL. This should eventually go away | 52 | * Obtain a SYSMEM address from a Linux SGL. This should eventually go away |
254 | * and/or become private to this file once all bad usages of Linux SGLs are | 53 | * and/or become private to this file once all bad usages of Linux SGLs are |