summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/flcn_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/flcn_gk20a.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
index b52652e2..158f4d8b 100644
--- a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
@@ -269,6 +269,60 @@ static int gk20a_flcn_copy_to_dmem(struct nvgpu_falcon *flcn,
269 return 0; 269 return 0;
270} 270}
271 271
272static int gk20a_flcn_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst,
273 u8 *src, u32 size, u8 port, bool sec, u32 tag)
274{
275 struct gk20a *g = flcn->g;
276 u32 base_addr = flcn->flcn_base;
277 u32 *src_u32 = (u32 *)src;
278 u32 words = 0;
279 u32 blk = 0;
280 u32 i = 0;
281
282 nvgpu_log_info(g, "upload %d bytes to 0x%x", size, dst);
283
284 if (flcn_mem_overflow_check(flcn, dst, size, MEM_IMEM)) {
285 nvgpu_err(g, "incorrect parameters");
286 return -EINVAL;
287 }
288
289 nvgpu_mutex_acquire(&flcn->copy_lock);
290
291 words = size >> 2;
292 blk = dst >> 8;
293
294 nvgpu_log_info(g, "upload %d words to 0x%x block %d, tag 0x%x",
295 words, dst, blk, tag);
296
297 gk20a_writel(g, base_addr + falcon_falcon_imemc_r(port),
298 falcon_falcon_imemc_offs_f(dst >> 2) |
299 falcon_falcon_imemc_blk_f(blk) |
300 /* Set Auto-Increment on write */
301 falcon_falcon_imemc_aincw_f(1) |
302 sec << 28);
303
304 for (i = 0; i < words; i++) {
305 if (i % 64 == 0) {
306 /* tag is always 256B aligned */
307 gk20a_writel(g, base_addr + falcon_falcon_imemt_r(0),
308 tag);
309 tag++;
310 }
311
312 gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port),
313 src_u32[i]);
314 }
315
316 /* WARNING : setting remaining bytes in block to 0x0 */
317 while (i % 64) {
318 gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port), 0);
319 i++;
320 }
321
322 nvgpu_mutex_release(&flcn->copy_lock);
323
324 return 0;
325}
272 326
273static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn) 327static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn)
274{ 328{
@@ -302,6 +356,7 @@ void gk20a_falcon_ops(struct nvgpu_falcon *flcn)
302 flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done; 356 flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done;
303 flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem; 357 flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem;
304 flcn_ops->copy_to_dmem = gk20a_flcn_copy_to_dmem; 358 flcn_ops->copy_to_dmem = gk20a_flcn_copy_to_dmem;
359 flcn_ops->copy_to_imem = gk20a_flcn_copy_to_imem;
305 360
306 gk20a_falcon_engine_dependency_ops(flcn); 361 gk20a_falcon_engine_dependency_ops(flcn);
307} 362}