]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu:nvgpu:gm20b: disable irqs when hs pmu executes
authorVijayakumar <vsubbu@nvidia.com>
Wed, 8 Oct 2014 14:37:37 +0000 (20:07 +0530)
committerTerje Bergstrom <tbergstrom@nvidia.com>
Sat, 11 Oct 2014 04:00:45 +0000 (21:00 -0700)
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 <vsubbu@nvidia.com>
Reviewed-on: http://git-master/r/554659
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
drivers/gpu/nvgpu/gm20b/acr_gm20b.c
drivers/gpu/nvgpu/gm20b/acr_gm20b.h

index 64b126f694e657f300c5eb89389a778bef893037..7a62f05c97c716ba3895fb6562a57498f6cbcca4 100644 (file)
@@ -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);
 
index 048520f9071d630d6ec3de8675fe1f94127290de..bc5e474a6f46d3b08513c8bf54cca5cd5bdb7b04 100644 (file)
@@ -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__*/
index b717272c55e074ce320dc2ecca64be0b92fea758..acfcf41b78c4b042f79c5824e8f69485d68112ce 100644 (file)
@@ -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;
+}
index d1c42e4674e38327ef994395c7f2218c7ae83850..5dddc0b268d41cacbcc555e3c251483b7977beb7 100644 (file)
@@ -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_*/