diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 1dc5603f..817cb98d 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -55,6 +55,7 @@ | |||
55 | 55 | ||
56 | #define BLK_SIZE (256) | 56 | #define BLK_SIZE (256) |
57 | 57 | ||
58 | static int gk20a_init_gr_bind_fecs_elpg(struct gk20a *g); | ||
58 | static int gr_gk20a_commit_inst(struct channel_gk20a *c, u64 gpu_va); | 59 | static int gr_gk20a_commit_inst(struct channel_gk20a *c, u64 gpu_va); |
59 | 60 | ||
60 | /* global ctx buffer */ | 61 | /* global ctx buffer */ |
@@ -4560,6 +4561,91 @@ clean_up: | |||
4560 | return err; | 4561 | return err; |
4561 | } | 4562 | } |
4562 | 4563 | ||
4564 | static int gk20a_init_gr_bind_fecs_elpg(struct gk20a *g) | ||
4565 | { | ||
4566 | struct pmu_gk20a *pmu = &g->pmu; | ||
4567 | struct mm_gk20a *mm = &g->mm; | ||
4568 | struct vm_gk20a *vm = &mm->pmu.vm; | ||
4569 | struct device *d = dev_from_gk20a(g); | ||
4570 | int err = 0; | ||
4571 | |||
4572 | u32 size; | ||
4573 | struct sg_table *sgt_pg_buf; | ||
4574 | dma_addr_t iova; | ||
4575 | |||
4576 | gk20a_dbg_fn(""); | ||
4577 | |||
4578 | size = 0; | ||
4579 | |||
4580 | err = gr_gk20a_fecs_get_reglist_img_size(g, &size); | ||
4581 | if (err) { | ||
4582 | gk20a_err(dev_from_gk20a(g), | ||
4583 | "fail to query fecs pg buffer size"); | ||
4584 | return err; | ||
4585 | } | ||
4586 | |||
4587 | if (!pmu->pg_buf.cpuva) { | ||
4588 | pmu->pg_buf.cpuva = dma_alloc_coherent(d, size, | ||
4589 | &iova, | ||
4590 | GFP_KERNEL); | ||
4591 | if (!pmu->pg_buf.cpuva) { | ||
4592 | gk20a_err(d, "failed to allocate memory\n"); | ||
4593 | return -ENOMEM; | ||
4594 | } | ||
4595 | |||
4596 | pmu->pg_buf.iova = iova; | ||
4597 | pmu->pg_buf.size = size; | ||
4598 | |||
4599 | err = gk20a_get_sgtable(d, &sgt_pg_buf, | ||
4600 | pmu->pg_buf.cpuva, | ||
4601 | pmu->pg_buf.iova, | ||
4602 | size); | ||
4603 | if (err) { | ||
4604 | gk20a_err(d, "failed to create sg table\n"); | ||
4605 | goto err_free_pg_buf; | ||
4606 | } | ||
4607 | |||
4608 | pmu->pg_buf.pmu_va = gk20a_gmmu_map(vm, | ||
4609 | &sgt_pg_buf, | ||
4610 | size, | ||
4611 | 0, /* flags */ | ||
4612 | gk20a_mem_flag_none); | ||
4613 | if (!pmu->pg_buf.pmu_va) { | ||
4614 | gk20a_err(d, "failed to map fecs pg buffer"); | ||
4615 | err = -ENOMEM; | ||
4616 | goto err_free_sgtable; | ||
4617 | } | ||
4618 | |||
4619 | gk20a_free_sgtable(&sgt_pg_buf); | ||
4620 | } | ||
4621 | |||
4622 | |||
4623 | err = gr_gk20a_fecs_set_reglist_bind_inst(g, mm->pmu.inst_block.cpu_pa); | ||
4624 | if (err) { | ||
4625 | gk20a_err(dev_from_gk20a(g), | ||
4626 | "fail to bind pmu inst to gr"); | ||
4627 | return err; | ||
4628 | } | ||
4629 | |||
4630 | err = gr_gk20a_fecs_set_reglist_virtual_addr(g, pmu->pg_buf.pmu_va); | ||
4631 | if (err) { | ||
4632 | gk20a_err(dev_from_gk20a(g), | ||
4633 | "fail to set pg buffer pmu va"); | ||
4634 | return err; | ||
4635 | } | ||
4636 | |||
4637 | return err; | ||
4638 | |||
4639 | err_free_sgtable: | ||
4640 | gk20a_free_sgtable(&sgt_pg_buf); | ||
4641 | err_free_pg_buf: | ||
4642 | dma_free_coherent(d, size, | ||
4643 | pmu->pg_buf.cpuva, pmu->pg_buf.iova); | ||
4644 | pmu->pg_buf.cpuva = NULL; | ||
4645 | pmu->pg_buf.iova = 0; | ||
4646 | return err; | ||
4647 | } | ||
4648 | |||
4563 | int gk20a_init_gr_support(struct gk20a *g) | 4649 | int gk20a_init_gr_support(struct gk20a *g) |
4564 | { | 4650 | { |
4565 | u32 err; | 4651 | u32 err; |
@@ -4581,6 +4667,10 @@ int gk20a_init_gr_support(struct gk20a *g) | |||
4581 | if (err) | 4667 | if (err) |
4582 | return err; | 4668 | return err; |
4583 | 4669 | ||
4670 | err = gk20a_init_gr_bind_fecs_elpg(g); | ||
4671 | if (err) | ||
4672 | return err; | ||
4673 | |||
4584 | /* GR is inialized, signal possible waiters */ | 4674 | /* GR is inialized, signal possible waiters */ |
4585 | g->gr.initialized = true; | 4675 | g->gr.initialized = true; |
4586 | wake_up(&g->gr.init_wq); | 4676 | wake_up(&g->gr.init_wq); |