diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 63ae1da1f..b23cabe8d 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -20,7 +20,6 @@ #include /* for udelay */ #include /* for totalram_pages */ #include -#include #include #include #include @@ -1587,7 +1586,6 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, struct aiv_list_gk20a *sw_ctx_load = &g->gr.ctx_vars.sw_ctx_load; struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init; u32 last_method_data = 0; - int retries = FE_PWR_MODE_TIMEOUT_MAX / FE_PWR_MODE_TIMEOUT_DEFAULT; struct gk20a_platform *platform = dev_get_drvdata(g->dev); struct ctx_header_desc *ctx = &c->ch_ctx.ctx_header; struct mem_desc *ctxheader = &ctx->mem; @@ -1603,18 +1601,21 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, goto clean_up; } if (!platform->is_fmodel) { + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, FE_PWR_MODE_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); gk20a_writel(g, gr_fe_pwr_mode_r(), gr_fe_pwr_mode_req_send_f() | gr_fe_pwr_mode_mode_force_on_f()); do { u32 req = gr_fe_pwr_mode_req_v(gk20a_readl(g, gr_fe_pwr_mode_r())); if (req == gr_fe_pwr_mode_req_done_v()) break; - udelay(FE_PWR_MODE_TIMEOUT_MAX); - } while (--retries || !tegra_platform_is_silicon()); + udelay(FE_PWR_MODE_TIMEOUT_DEFAULT); + } while (!nvgpu_timeout_expired_msg(&timeout, + "timeout forcing FE on")); } - if (!retries) - gk20a_err(g->dev, "timeout forcing FE on"); gk20a_writel(g, gr_fecs_ctxsw_reset_ctl_r(), gr_fecs_ctxsw_reset_ctl_sys_halt_disabled_f() | @@ -1643,19 +1644,20 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, udelay(10); if (!platform->is_fmodel) { + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, FE_PWR_MODE_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); gk20a_writel(g, gr_fe_pwr_mode_r(), gr_fe_pwr_mode_req_send_f() | gr_fe_pwr_mode_mode_auto_f()); - retries = FE_PWR_MODE_TIMEOUT_MAX / FE_PWR_MODE_TIMEOUT_DEFAULT; do { u32 req = gr_fe_pwr_mode_req_v(gk20a_readl(g, gr_fe_pwr_mode_r())); if (req == gr_fe_pwr_mode_req_done_v()) break; udelay(FE_PWR_MODE_TIMEOUT_DEFAULT); - } while (--retries || !tegra_platform_is_silicon()); - - if (!retries) - gk20a_err(g->dev, "timeout setting FE power to auto"); + } while (!nvgpu_timeout_expired_msg(&timeout, + "timeout setting FE power to auto")); } /* clear scc ram */ @@ -4996,13 +4998,14 @@ static int gk20a_init_gr_prepare(struct gk20a *g) static int gr_gk20a_wait_mem_scrubbing(struct gk20a *g) { - int retries = CTXSW_MEM_SCRUBBING_TIMEOUT_MAX / - CTXSW_MEM_SCRUBBING_TIMEOUT_DEFAULT; + struct nvgpu_timeout timeout; bool fecs_scrubbing; bool gpccs_scrubbing; gk20a_dbg_fn(""); + nvgpu_timeout_init(g, &timeout, CTXSW_MEM_SCRUBBING_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); do { fecs_scrubbing = gk20a_readl(g, gr_fecs_dmactl_r()) & (gr_fecs_dmactl_imem_scrubbing_m() | @@ -5018,7 +5021,7 @@ static int gr_gk20a_wait_mem_scrubbing(struct gk20a *g) } udelay(CTXSW_MEM_SCRUBBING_TIMEOUT_DEFAULT); - } while (--retries || !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); gk20a_err(dev_from_gk20a(g), "Falcon mem scrubbing timeout"); return -ETIMEDOUT; @@ -8663,8 +8666,7 @@ int gk20a_gr_wait_for_sm_lock_down(struct gk20a *g, u32 gpc, u32 tpc, usleep_range(delay, delay * 2); delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); - } while (!nvgpu_timeout_expired(&timeout) - || !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); dbgr_control0 = gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset); diff --git a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c index 34a96971d..9942e58f5 100644 --- a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c @@ -17,7 +17,9 @@ */ #include + #include +#include #include "gk20a.h" @@ -106,7 +108,6 @@ static int gk20a_ltc_cbc_ctrl(struct gk20a *g, enum gk20a_cbc_op op, int err = 0; struct gr_gk20a *gr = &g->gr; u32 fbp, slice, ctrl1, val, hw_op = 0; - int retry = 200; u32 slices_per_fbp = ltc_ltcs_ltss_cbc_param_slices_per_fbp_v( gk20a_readl(g, ltc_ltcs_ltss_cbc_param_r())); @@ -140,6 +141,9 @@ static int gk20a_ltc_cbc_ctrl(struct gk20a *g, enum gk20a_cbc_op op, gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | hw_op); for (fbp = 0; fbp < gr->num_fbps; fbp++) { + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, 200, NVGPU_TIMER_RETRY_TIMER); for (slice = 0; slice < slices_per_fbp; slice++) { @@ -147,18 +151,15 @@ static int gk20a_ltc_cbc_ctrl(struct gk20a *g, enum gk20a_cbc_op op, fbp * ltc_stride + slice * lts_stride; - retry = 200; do { val = gk20a_readl(g, ctrl1); if (!(val & hw_op)) break; - retry--; udelay(5); - } while (retry >= 0 || - !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); - if (retry < 0 && tegra_platform_is_silicon()) { + if (nvgpu_timeout_peek_expired(&timeout)) { gk20a_err(dev_from_gk20a(g), "comp tag clear timeout\n"); err = -EBUSY; diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 9e6dc74cd..c31f84824 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -1543,7 +1542,6 @@ static void gk20a_vm_unmap_user(struct vm_gk20a *vm, u64 offset, struct vm_gk20a_mapping_batch *batch) { struct device *d = dev_from_vm(vm); - int retries = 10000; /* 50 ms */ struct mapped_buffer_node *mapped_buffer; nvgpu_mutex_acquire(&vm->update_gmmu_lock); @@ -1556,17 +1554,19 @@ static void gk20a_vm_unmap_user(struct vm_gk20a *vm, u64 offset, } if (mapped_buffer->flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) { + struct nvgpu_timeout timeout; + nvgpu_mutex_release(&vm->update_gmmu_lock); - while (retries >= 0 || !tegra_platform_is_silicon()) { + nvgpu_timeout_init(vm->mm->g, &timeout, 10000, + NVGPU_TIMER_RETRY_TIMER); + do { if (atomic_read(&mapped_buffer->ref.refcount) == 1) break; - retries--; udelay(5); - } - if (retries < 0 && tegra_platform_is_silicon()) - gk20a_err(d, "sync-unmap failed on 0x%llx", - offset); + } while (!nvgpu_timeout_expired_msg(&timeout, + "sync-unmap failed on 0x%llx")); + nvgpu_mutex_acquire(&vm->update_gmmu_lock); } diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 52e5d4db4..81a0aac9d 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 993cef7be..85fa8ea1c 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -2374,12 +2374,11 @@ void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable) int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable) { struct gk20a *g = gk20a_from_pmu(pmu); + struct nvgpu_timeout timeout; gk20a_dbg_fn(""); if (enable) { - int retries = PMU_MEM_SCRUBBING_TIMEOUT_MAX / - PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT; g->ops.mc.enable(g, mc_enable_pwr_enabled_f()); if (g->ops.clock_gating.slcg_pmu_load_gating_prod) @@ -2389,6 +2388,9 @@ int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable) g->ops.clock_gating.blcg_pmu_load_gating_prod(g, g->blcg_enabled); + nvgpu_timeout_init(g, &timeout, + PMU_MEM_SCRUBBING_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); do { u32 w = gk20a_readl(g, pwr_falcon_dmactl_r()) & (pwr_falcon_dmactl_dmem_scrubbing_m() | @@ -2399,7 +2401,7 @@ int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable) return 0; } udelay(PMU_MEM_SCRUBBING_TIMEOUT_DEFAULT); - } while (--retries || !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); g->ops.mc.disable(g, mc_enable_pwr_enabled_f()); gk20a_err(dev_from_gk20a(g), "Falcon mem scrubbing timeout"); diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c index 3993691ae..b72602185 100644 --- a/drivers/gpu/nvgpu/gm206/bios_gm206.c +++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "gk20a/gk20a.h" #include "gm20b/fifo_gm20b.h" @@ -99,13 +100,15 @@ static void upload_data(struct gk20a *g, u32 dst, u8 *src, u32 size, u8 port) static int gm206_bios_devinit(struct gk20a *g) { - int retries = PMU_BOOT_TIMEOUT_MAX / PMU_BOOT_TIMEOUT_DEFAULT; int err = 0; int devinit_completed; + struct nvgpu_timeout timeout; gk20a_dbg_fn(""); g->ops.pmu.reset(g); + nvgpu_timeout_init(g, &timeout, PMU_BOOT_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); do { u32 w = gk20a_readl(g, pwr_falcon_dmactl_r()) & (pwr_falcon_dmactl_dmem_scrubbing_m() | @@ -116,9 +119,13 @@ static int gm206_bios_devinit(struct gk20a *g) break; } udelay(PMU_BOOT_TIMEOUT_DEFAULT); - } while (--retries || !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); + + if (nvgpu_timeout_peek_expired(&timeout)) { + err = -ETIMEDOUT; + goto out; + } - /* todo check retries */ upload_code(g, g->bios.devinit.bootloader_phys_base, g->bios.devinit.bootloader, g->bios.devinit.bootloader_size, @@ -147,35 +154,39 @@ static int gm206_bios_devinit(struct gk20a *g) gk20a_writel(g, pwr_falcon_cpuctl_r(), pwr_falcon_cpuctl_startcpu_f(1)); - retries = PMU_BOOT_TIMEOUT_MAX / PMU_BOOT_TIMEOUT_DEFAULT; + nvgpu_timeout_init(g, &timeout, PMU_BOOT_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); do { devinit_completed = pwr_falcon_cpuctl_halt_intr_v( gk20a_readl(g, pwr_falcon_cpuctl_r())) && top_scratch1_devinit_completed_v( gk20a_readl(g, top_scratch1_r())); udelay(PMU_BOOT_TIMEOUT_DEFAULT); - } while (!devinit_completed && retries--); + } while (!devinit_completed && !nvgpu_timeout_expired(&timeout)); + + if (nvgpu_timeout_peek_expired(&timeout)) + err = -ETIMEDOUT; gk20a_writel(g, pwr_falcon_irqsclr_r(), pwr_falcon_irqstat_halt_true_f()); gk20a_readl(g, pwr_falcon_irqsclr_r()); - if (!retries) - err = -EINVAL; - +out: gk20a_dbg_fn("done"); return err; } static int gm206_bios_preos(struct gk20a *g) { - int retries = PMU_BOOT_TIMEOUT_MAX / PMU_BOOT_TIMEOUT_DEFAULT; int err = 0; int val; + struct nvgpu_timeout timeout; gk20a_dbg_fn(""); g->ops.pmu.reset(g); + nvgpu_timeout_init(g, &timeout, PMU_BOOT_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); do { u32 w = gk20a_readl(g, pwr_falcon_dmactl_r()) & (pwr_falcon_dmactl_dmem_scrubbing_m() | @@ -186,9 +197,13 @@ static int gm206_bios_preos(struct gk20a *g) break; } udelay(PMU_BOOT_TIMEOUT_DEFAULT); - } while (--retries || !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); + + if (nvgpu_timeout_peek_expired(&timeout)) { + err = -ETIMEDOUT; + goto out; + } - /* todo check retries */ upload_code(g, g->bios.preos.bootloader_phys_base, g->bios.preos.bootloader, g->bios.preos.bootloader_size, @@ -209,20 +224,24 @@ static int gm206_bios_preos(struct gk20a *g) gk20a_writel(g, pwr_falcon_cpuctl_r(), pwr_falcon_cpuctl_startcpu_f(1)); - retries = PMU_BOOT_TIMEOUT_MAX / PMU_BOOT_TIMEOUT_DEFAULT; + nvgpu_timeout_init(g, &timeout, PMU_BOOT_TIMEOUT_MAX / 1000, + NVGPU_TIMER_CPU_TIMER); do { val = pwr_falcon_cpuctl_halt_intr_v( gk20a_readl(g, pwr_falcon_cpuctl_r())); udelay(PMU_BOOT_TIMEOUT_DEFAULT); - } while (!val && retries--); + } while (!val && !nvgpu_timeout_expired(&timeout)); + + if (nvgpu_timeout_peek_expired(&timeout)) { + err = -ETIMEDOUT; + goto out; + } gk20a_writel(g, pwr_falcon_irqsclr_r(), pwr_falcon_irqstat_halt_true_f()); gk20a_readl(g, pwr_falcon_irqsclr_r()); - if (!retries) - err = -EINVAL; - +out: gk20a_dbg_fn("done"); return err; } diff --git a/drivers/gpu/nvgpu/gp106/sec2_gp106.c b/drivers/gpu/nvgpu/gp106/sec2_gp106.c index 0032bce7b..dd67f8826 100644 --- a/drivers/gpu/nvgpu/gp106/sec2_gp106.c +++ b/drivers/gpu/nvgpu/gp106/sec2_gp106.c @@ -35,10 +35,10 @@ int sec2_clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout) { u32 data = 0; - unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); + struct nvgpu_timeout to; - while (time_before(jiffies, end_jiffies) || - !tegra_platform_is_silicon()) { + nvgpu_timeout_init(g, &to, timeout, NVGPU_TIMER_CPU_TIMER); + do { gk20a_writel(g, psec_falcon_irqsclr_r(), gk20a_readl(g, psec_falcon_irqsclr_r()) | (0x10)); data = gk20a_readl(g, psec_falcon_irqstat_r()); @@ -46,10 +46,10 @@ int sec2_clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout) psec_falcon_irqstat_halt_true_f()) /*halt irq is clear*/ break; - timeout--; udelay(1); - } - if (timeout == 0) + } while (!nvgpu_timeout_expired(&to)); + + if (nvgpu_timeout_peek_expired(&to)) return -EBUSY; return 0; } @@ -58,10 +58,10 @@ int sec2_wait_for_halt(struct gk20a *g, unsigned int timeout) { u32 data = 0; int completion = -EBUSY; - unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); + struct nvgpu_timeout to; - while (time_before(jiffies, end_jiffies) || - !tegra_platform_is_silicon()) { + nvgpu_timeout_init(g, &to, timeout, NVGPU_TIMER_CPU_TIMER); + do { data = gk20a_readl(g, psec_falcon_cpuctl_r()); if (data & psec_falcon_cpuctl_halt_intr_m()) { /*CPU is halted break*/ @@ -69,21 +69,21 @@ int sec2_wait_for_halt(struct gk20a *g, unsigned int timeout) break; } udelay(1); - } - if (completion){ + } while (!nvgpu_timeout_expired(&to)); + + if (completion) { gk20a_err(dev_from_gk20a(g), "ACR boot timed out"); + return completion; } - else { - g->acr.capabilities = gk20a_readl(g, psec_falcon_mailbox1_r()); - gm20b_dbg_pmu("ACR capabilities %x\n", g->acr.capabilities); - data = gk20a_readl(g, psec_falcon_mailbox0_r()); - if (data) { + g->acr.capabilities = gk20a_readl(g, psec_falcon_mailbox1_r()); + gm20b_dbg_pmu("ACR capabilities %x\n", g->acr.capabilities); + data = gk20a_readl(g, psec_falcon_mailbox0_r()); + if (data) { - gk20a_err(dev_from_gk20a(g), - "ACR boot failed, err %x", data); - completion = -EAGAIN; - } + gk20a_err(dev_from_gk20a(g), + "ACR boot failed, err %x", data); + completion = -EAGAIN; } init_pmu_setup_hw1(g); diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c index 7f43a6ce1..cb6ef9c7b 100644 --- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c @@ -2041,21 +2041,21 @@ static int gr_gp10b_suspend_contexts(struct gk20a *g, struct channel_ctx_gk20a *ch_ctx = &cilp_preempt_pending_ch->ch_ctx; struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); + struct nvgpu_timeout timeout; gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, "CILP preempt pending, waiting %lu msecs for preemption", gk20a_get_gr_idle_timeout(g)); + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); do { if (!gr_ctx->t18x.cilp_preempt_pending) break; usleep_range(delay, delay * 2); delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); - } while (time_before(jiffies, end_jiffies) - || !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); /* If cilp is still pending at this point, timeout */ if (gr_ctx->t18x.cilp_preempt_pending)