diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 1dc5603f5..817cb98d8 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -55,6 +55,7 @@ #define BLK_SIZE (256) +static int gk20a_init_gr_bind_fecs_elpg(struct gk20a *g); static int gr_gk20a_commit_inst(struct channel_gk20a *c, u64 gpu_va); /* global ctx buffer */ @@ -4560,6 +4561,91 @@ clean_up: return err; } +static int gk20a_init_gr_bind_fecs_elpg(struct gk20a *g) +{ + struct pmu_gk20a *pmu = &g->pmu; + struct mm_gk20a *mm = &g->mm; + struct vm_gk20a *vm = &mm->pmu.vm; + struct device *d = dev_from_gk20a(g); + int err = 0; + + u32 size; + struct sg_table *sgt_pg_buf; + dma_addr_t iova; + + gk20a_dbg_fn(""); + + size = 0; + + err = gr_gk20a_fecs_get_reglist_img_size(g, &size); + if (err) { + gk20a_err(dev_from_gk20a(g), + "fail to query fecs pg buffer size"); + return err; + } + + if (!pmu->pg_buf.cpuva) { + pmu->pg_buf.cpuva = dma_alloc_coherent(d, size, + &iova, + GFP_KERNEL); + if (!pmu->pg_buf.cpuva) { + gk20a_err(d, "failed to allocate memory\n"); + return -ENOMEM; + } + + pmu->pg_buf.iova = iova; + pmu->pg_buf.size = size; + + err = gk20a_get_sgtable(d, &sgt_pg_buf, + pmu->pg_buf.cpuva, + pmu->pg_buf.iova, + size); + if (err) { + gk20a_err(d, "failed to create sg table\n"); + goto err_free_pg_buf; + } + + pmu->pg_buf.pmu_va = gk20a_gmmu_map(vm, + &sgt_pg_buf, + size, + 0, /* flags */ + gk20a_mem_flag_none); + if (!pmu->pg_buf.pmu_va) { + gk20a_err(d, "failed to map fecs pg buffer"); + err = -ENOMEM; + goto err_free_sgtable; + } + + gk20a_free_sgtable(&sgt_pg_buf); + } + + + err = gr_gk20a_fecs_set_reglist_bind_inst(g, mm->pmu.inst_block.cpu_pa); + if (err) { + gk20a_err(dev_from_gk20a(g), + "fail to bind pmu inst to gr"); + return err; + } + + err = gr_gk20a_fecs_set_reglist_virtual_addr(g, pmu->pg_buf.pmu_va); + if (err) { + gk20a_err(dev_from_gk20a(g), + "fail to set pg buffer pmu va"); + return err; + } + + return err; + +err_free_sgtable: + gk20a_free_sgtable(&sgt_pg_buf); +err_free_pg_buf: + dma_free_coherent(d, size, + pmu->pg_buf.cpuva, pmu->pg_buf.iova); + pmu->pg_buf.cpuva = NULL; + pmu->pg_buf.iova = 0; + return err; +} + int gk20a_init_gr_support(struct gk20a *g) { u32 err; @@ -4581,6 +4667,10 @@ int gk20a_init_gr_support(struct gk20a *g) if (err) return err; + err = gk20a_init_gr_bind_fecs_elpg(g); + if (err) + return err; + /* GR is inialized, signal possible waiters */ g->gr.initialized = true; wake_up(&g->gr.init_wq); diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 395afdd4d..e60de70bf 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -2174,93 +2174,11 @@ void pmu_setup_hw(struct work_struct *work) int gk20a_init_pmu_bind_fecs(struct gk20a *g) { struct pmu_gk20a *pmu = &g->pmu; - struct mm_gk20a *mm = &g->mm; - struct vm_gk20a *vm = &mm->pmu.vm; - struct device *d = dev_from_gk20a(g); struct pmu_cmd cmd; u32 desc; - int err; - u32 size; - struct sg_table *sgt_pg_buf; - dma_addr_t iova; - + int err = 0; gk20a_dbg_fn(""); - size = 0; - err = gr_gk20a_fecs_get_reglist_img_size(g, &size); - if (err && (pmu->pmu_state == PMU_STATE_ELPG_BOOTED)) { - gk20a_err(dev_from_gk20a(g), - "fail to query fecs pg buffer size"); - return err; - } - - if (err) { - gk20a_err(dev_from_gk20a(g), - "fail to query fecs pg buffer size invalid boot state"); - return err; - } - - if (!pmu->pg_buf.cpuva) { - pmu->pg_buf.cpuva = dma_alloc_coherent(d, size, - &iova, - GFP_KERNEL); - if (!pmu->pg_buf.cpuva) { - gk20a_err(d, "failed to allocate memory\n"); - return -ENOMEM; - } - - pmu->pg_buf.iova = iova; - pmu->pg_buf.size = size; - - err = gk20a_get_sgtable(d, &sgt_pg_buf, - pmu->pg_buf.cpuva, - pmu->pg_buf.iova, - size); - if (err) { - gk20a_err(d, "failed to create sg table\n"); - goto err_free_pg_buf; - } - - pmu->pg_buf.pmu_va = gk20a_gmmu_map(vm, - &sgt_pg_buf, - size, - 0, /* flags */ - gk20a_mem_flag_none); - if (!pmu->pg_buf.pmu_va) { - gk20a_err(d, "failed to map fecs pg buffer"); - err = -ENOMEM; - goto err_free_sgtable; - } - - gk20a_free_sgtable(&sgt_pg_buf); - } - - err = gr_gk20a_fecs_set_reglist_bind_inst(g, mm->pmu.inst_block.cpu_pa); - if (err && (pmu->pmu_state == PMU_STATE_ELPG_BOOTED)) { - gk20a_err(dev_from_gk20a(g), - "fail to bind pmu inst to gr"); - return err; - } - - if (err) { - gk20a_err(dev_from_gk20a(g), - "fail to bind pmu inst to gr invalid boot state"); - return err; - } - - err = gr_gk20a_fecs_set_reglist_virtual_addr(g, pmu->pg_buf.pmu_va); - if (err && (pmu->pmu_state == PMU_STATE_ELPG_BOOTED)) { - gk20a_err(dev_from_gk20a(g), - "fail to set pg buffer pmu va"); - return err; - } - - if (err) { - gk20a_err(dev_from_gk20a(g), - "fail to set pg buffer pmu va invalid boot state"); - return err; - } - memset(&cmd, 0, sizeof(struct pmu_cmd)); cmd.hdr.unit_id = PMU_UNIT_PG; cmd.hdr.size = PMU_CMD_HDR_SIZE + sizeof(struct pmu_pg_cmd_eng_buf_load); @@ -2278,15 +2196,6 @@ int gk20a_init_pmu_bind_fecs(struct gk20a *g) pmu_handle_pg_buf_config_msg, pmu, &desc, ~0); pmu->pmu_state = PMU_STATE_LOADING_PG_BUF; return err; - -err_free_sgtable: - gk20a_free_sgtable(&sgt_pg_buf); -err_free_pg_buf: - dma_free_coherent(d, size, - pmu->pg_buf.cpuva, pmu->pg_buf.iova); - pmu->pg_buf.cpuva = NULL; - pmu->pg_buf.iova = 0; - return err; } static void pmu_setup_hw_load_zbc(struct gk20a *g)