From f56d50ddac2ea70c7d50f22b9cd74408b1042da3 Mon Sep 17 00:00:00 2001 From: Vijayakumar Date: Wed, 8 Oct 2014 20:07:37 +0530 Subject: gpu:nvgpu:gm20b: disable irqs when hs pmu executes bug 200040021 polling halt irq to check for hs bin completion keep irqs disabled to avoid executing irq handler Change-Id: Ic245d89580444dcbf1cf5ec34bfe0f8b0c5bbc0f Signed-off-by: Vijayakumar Reviewed-on: http://git-master/r/554659 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 2 +- drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 2 +- drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 47 +++++++++++++++++++++++++++++++++---- drivers/gpu/nvgpu/gm20b/acr_gm20b.h | 1 + 4 files changed, 45 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 64b126f6..7a62f05c 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -1048,7 +1048,7 @@ static int pmu_idle(struct pmu_gk20a *pmu) return 0; } -static void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable) +void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable) { struct gk20a *g = gk20a_from_pmu(pmu); diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h index 048520f9..bc5e474a 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h @@ -1145,5 +1145,5 @@ int gk20a_pmu_ap_send_command(struct gk20a *g, union pmu_ap_cmd *p_ap_cmd, bool b_block); int gk20a_aelpg_init(struct gk20a *g); int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id); - +void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable); #endif /*__PMU_GK20A_H__*/ diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index b717272c..acfcf41b 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c @@ -63,6 +63,11 @@ get_ucode_details pmu_acr_supp_ucode_list[] = { /*Once is LS mode, cpuctl_alias is only accessible*/ void start_gm20b_pmu(struct gk20a *g) { + /*disable irqs for hs falcon booting as we will poll for halt*/ + mutex_lock(&g->pmu.isr_mutex); + pmu_enable_irq(&g->pmu, true); + g->pmu.isr_enabled = true; + mutex_unlock(&g->pmu.isr_mutex); gk20a_writel(g, pwr_falcon_cpuctl_alias_r(), pwr_falcon_cpuctl_startcpu_f(1)); } @@ -1116,6 +1121,11 @@ int gm20b_init_pmu_setup_hw1(struct gk20a *g, struct flcn_bl_dmem_desc *desc, pmu_copy_to_dmem(pmu, g->acr.pmu_args, (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)), g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0); + /*disable irqs for hs falcon booting as we will poll for halt*/ + mutex_lock(&pmu->isr_mutex); + pmu_enable_irq(pmu, false); + pmu->isr_enabled = false; + mutex_unlock(&pmu->isr_mutex); err = bl_bootstrap(pmu, desc, bl_sz); if (err) return err; @@ -1216,8 +1226,9 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt) * to PMU halt */ - gk20a_writel(g, pwr_falcon_irqsclr_r(), - gk20a_readl(g, pwr_falcon_irqsclr_r()) & (~(0x10))); + if (clear_halt_interrupt_status(g, GPU_TIMEOUT_DEFAULT)) + goto err_unmap_bl; + gm20b_dbg_pmu("err reg :%x\n", readl(mc + MC_ERR_GENERALIZED_CARVEOUT_STATUS_0)); gm20b_dbg_pmu("phys sec reg %x\n", gk20a_readl(g, @@ -1228,10 +1239,11 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt) /* Poll for HALT */ if (b_wait_for_halt) { err = pmu_wait_for_halt(g, GPU_TIMEOUT_DEFAULT); - if (err == 0) + if (err == 0) { /* Clear the HALT interrupt */ - gk20a_writel(g, pwr_falcon_irqsclr_r(), - gk20a_readl(g, pwr_falcon_irqsclr_r()) & (~(0x10))); + if (clear_halt_interrupt_status(g, GPU_TIMEOUT_DEFAULT)) + goto err_unmap_bl; + } else goto err_unmap_bl; } @@ -1281,3 +1293,28 @@ int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout) return -EBUSY; return 0; } + +/*! +* Wait for PMU halt interrupt status to be cleared +* @param[in] g GPU object pointer +* @param[in] timeout_us Timeout in Us for PMU to halt +* @return '0' if PMU halt irq status is clear +*/ +int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout) +{ + u32 data = 0; + while (timeout != 0) { + gk20a_writel(g, pwr_falcon_irqsclr_r(), + gk20a_readl(g, pwr_falcon_irqsclr_r()) | (0x10)); + data = gk20a_readl(g, (pwr_falcon_irqstat_r())); + if ((data & pwr_falcon_irqstat_halt_true_f()) != + pwr_falcon_irqstat_halt_true_f()) + /*halt irq is clear*/ + break; + timeout--; + udelay(1); + } + if (timeout == 0) + return -EBUSY; + return 0; +} diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h index d1c42e46..5dddc0b2 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h @@ -383,4 +383,5 @@ int gm20b_bootstrap_hs_flcn(struct gk20a *g); int gm20b_pmu_setup_sw(struct gk20a *g); int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt); int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout_us); +int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout); #endif /*__ACR_GM20B_H_*/ -- cgit v1.2.2