diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c index e4bb2a57b..7b81f5e83 100644 --- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c @@ -1,7 +1,7 @@ /* * Color decompression engine support * - * Copyright (c) 2014-2016, NVIDIA Corporation. All rights reserved. + * Copyright (c) 2014-2017, NVIDIA Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -24,6 +24,8 @@ #include +#include + #include "gk20a.h" #include "channel_gk20a.h" #include "mm_gk20a.h" @@ -864,7 +866,10 @@ __acquires(&cde_app->mutex) { struct gk20a_cde_app *cde_app = &g->cde_app; struct gk20a_cde_ctx *cde_ctx = NULL; - unsigned long end = jiffies + msecs_to_jiffies(MAX_CTX_RETRY_TIME); + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, MAX_CTX_RETRY_TIME, + NVGPU_TIMER_CPU_TIMER); do { cde_ctx = gk20a_cde_do_get_context(g); @@ -875,7 +880,7 @@ __acquires(&cde_app->mutex) mutex_unlock(&cde_app->mutex); cond_resched(); mutex_lock(&cde_app->mutex); - } while (time_before(jiffies, end)); + } while (!nvgpu_timeout_expired(&timeout)); return cde_ctx; } diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index d59013541..d36b5d340 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -36,6 +36,8 @@ #include "fence_gk20a.h" #include "semaphore_gk20a.h" +#include + #include #include #include @@ -557,8 +559,10 @@ void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) int gk20a_wait_channel_idle(struct channel_gk20a *ch) { bool channel_idle = false; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(ch->g)); + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(ch->g, &timeout, gk20a_get_gr_idle_timeout(ch->g), + NVGPU_TIMER_CPU_TIMER); do { channel_gk20a_joblist_lock(ch); @@ -568,8 +572,7 @@ int gk20a_wait_channel_idle(struct channel_gk20a *ch) break; usleep_range(1000, 3000); - } while (time_before(jiffies, end_jiffies) - || !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); if (!channel_idle) { gk20a_err(dev_from_gk20a(ch->g), "jobs not freed for channel %d\n", diff --git a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c index 7633c873f..9e116c364 100644 --- a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c index ab88d5cbd..6b77dff55 100644 --- a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 2daeb1d05..469148c29 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -16,6 +16,7 @@ * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ + #include #include #include @@ -23,6 +24,8 @@ #include #include +#include + #include "gk20a.h" #include "debug_gk20a.h" #include "ctxsw_trace_gk20a.h" @@ -1570,11 +1573,9 @@ static void gk20a_fifo_get_faulty_id_type(struct gk20a *g, int engine_id, static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, unsigned long engine_ids) { - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); + struct nvgpu_timeout timeout; unsigned long delay = GR_IDLE_CHECK_DEFAULT; unsigned long engine_id; - int ret; /* trigger faults for all bad engines */ for_each_set_bit(engine_id, &engine_ids, 32) { @@ -1593,21 +1594,16 @@ static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, } /* Wait for MMU fault to trigger */ - ret = -EBUSY; + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); do { if (gk20a_readl(g, fifo_intr_0_r()) & - fifo_intr_0_mmu_fault_pending_f()) { - ret = 0; + fifo_intr_0_mmu_fault_pending_f()) 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()); - - if (ret) - gk20a_err(dev_from_gk20a(g), "mmu fault timeout"); + } while (!nvgpu_timeout_expired_msg(&timeout, "mmu fault timeout")); /* release mmu fault trigger */ for_each_set_bit(engine_id, &engine_ids, 32) @@ -2366,9 +2362,8 @@ void gk20a_fifo_issue_preempt(struct gk20a *g, u32 id, bool is_tsg) static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) { + struct nvgpu_timeout timeout; u32 delay = GR_IDLE_CHECK_DEFAULT; - unsigned long end_jiffies = jiffies - + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); u32 ret = 0; gk20a_dbg_fn("%d", id); @@ -2379,6 +2374,8 @@ static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) gk20a_dbg_fn("%d", id); /* wait for preempt */ ret = -EBUSY; + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); do { if (!(gk20a_readl(g, fifo_preempt_r()) & fifo_preempt_pending_true_f())) { @@ -2388,8 +2385,7 @@ static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) 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)); gk20a_dbg_fn("%d", id); if (ret) { @@ -2668,11 +2664,13 @@ static void gk20a_fifo_runlist_reset_engines(struct gk20a *g, u32 runlist_id) static int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id) { struct fifo_runlist_info_gk20a *runlist; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); + struct nvgpu_timeout timeout; unsigned long delay = GR_IDLE_CHECK_DEFAULT; int ret = -ETIMEDOUT; + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); + runlist = &g->fifo.runlist_info[runlist_id]; do { if ((gk20a_readl(g, fifo_eng_runlist_r(runlist_id)) & @@ -2683,8 +2681,7 @@ static int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id) 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)); return ret; } @@ -3106,14 +3103,16 @@ bool gk20a_fifo_is_engine_busy(struct gk20a *g) int gk20a_fifo_wait_engine_idle(struct gk20a *g) { - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); + struct nvgpu_timeout timeout; unsigned long delay = GR_IDLE_CHECK_DEFAULT; int ret = -ETIMEDOUT; u32 i; gk20a_dbg_fn(""); + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); + for (i = 0; i < fifo_engine_status__size_1_v(); i++) { do { u32 status = gk20a_readl(g, fifo_engine_status_r(i)); @@ -3125,8 +3124,8 @@ int gk20a_fifo_wait_engine_idle(struct gk20a *g) usleep_range(delay, delay * 2); delay = min_t(unsigned long, delay << 1, GR_IDLE_CHECK_MAX); - } while (time_before(jiffies, end_jiffies) || - !tegra_platform_is_silicon()); + } while (!nvgpu_timeout_expired(&timeout)); + if (ret) { gk20a_dbg_info("cannot idle engine %u", i); break; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 5f365d4b4..9725442a6 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -44,6 +44,7 @@ #include #include +#include #include "gk20a.h" #include "nvgpu_common.h" @@ -1923,8 +1924,7 @@ int __gk20a_do_idle(struct device *dev, bool force_reset) { struct gk20a *g = get_gk20a(dev); struct gk20a_platform *platform = dev_get_drvdata(dev); - unsigned long timeout = jiffies + - msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS); + struct nvgpu_timeout timeout; int ref_cnt; int target_ref_cnt = 0; bool is_railgated; @@ -1958,11 +1958,14 @@ int __gk20a_do_idle(struct device *dev, bool force_reset) target_ref_cnt = 1; mutex_lock(&platform->railgate_lock); + nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS, + NVGPU_TIMER_CPU_TIMER); + /* check and wait until GPU is idle (with a timeout) */ do { msleep(1); ref_cnt = atomic_read(&dev->power.usage_count); - } while (ref_cnt != target_ref_cnt && time_before(jiffies, timeout)); + } while (ref_cnt != target_ref_cnt && !nvgpu_timeout_expired(&timeout)); if (ref_cnt != target_ref_cnt) { gk20a_err(dev, "failed to idle - refcount %d != 1\n", @@ -1973,6 +1976,9 @@ int __gk20a_do_idle(struct device *dev, bool force_reset) /* check if global force_reset flag is set */ force_reset |= platform->force_reset_in_do_idle; + nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS, + NVGPU_TIMER_CPU_TIMER); + if (platform->can_railgate && !force_reset) { /* * Case 1 : GPU railgate is supported @@ -1985,13 +1991,11 @@ int __gk20a_do_idle(struct device *dev, bool force_reset) /* add sufficient delay to allow GPU to rail gate */ msleep(platform->railgate_delay); - timeout = jiffies + msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS); - /* check in loop if GPU is railgated or not */ do { msleep(1); is_railgated = platform->is_railgated(dev); - } while (!is_railgated && time_before(jiffies, timeout)); + } while (!is_railgated && !nvgpu_timeout_expired(&timeout)); if (is_railgated) { return 0; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 00a580dd7..6ca5855ac 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -270,8 +270,8 @@ struct gpu_ops { u32 (*get_max_lts_per_ltc)(struct gk20a *g); u32* (*get_rop_l2_en_mask)(struct gk20a *g); void (*init_sm_dsm_reg_info)(void); - int (*wait_empty)(struct gk20a *g, unsigned long end_jiffies, - u32 expect_delay); + int (*wait_empty)(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay); void (*init_cyclestats)(struct gk20a *g); void (*enable_cde_in_fecs)(struct gk20a *g, struct mem_desc *mem); diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index c5e927c15..f20963832 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -31,6 +31,8 @@ #include #include +#include + #include "gk20a.h" #include "kind_gk20a.h" #include "gr_ctx_gk20a.h" @@ -321,7 +323,7 @@ static void gr_gk20a_load_falcon_imem(struct gk20a *g) } } -int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, +int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms, u32 expect_delay) { u32 delay = expect_delay; @@ -331,11 +333,15 @@ int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, u32 gr_engine_id; u32 engine_status; bool ctx_status_invalid; + struct nvgpu_timeout timeout; gk20a_dbg_fn(""); gr_engine_id = gk20a_fifo_get_gr_engine_id(g); + nvgpu_timeout_init(g, &timeout, (int)duration_ms, + NVGPU_TIMER_CPU_TIMER); + do { /* fmodel: host gets fifo_engine_status(gr) from gr only when gr_status is read */ @@ -366,8 +372,7 @@ int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, 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)); gk20a_err(dev_from_gk20a(g), "timeout, ctxsw busy : %d, gr busy : %d", @@ -376,18 +381,22 @@ int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, return -EAGAIN; } -int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, - u32 expect_delay) +int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay) { u32 val; u32 delay = expect_delay; struct gk20a_platform *platform = dev_get_drvdata(g->dev); + struct nvgpu_timeout timeout; if (platform->is_fmodel) return 0; gk20a_dbg_fn(""); + nvgpu_timeout_init(g, &timeout, (int)duration_ms, + NVGPU_TIMER_CPU_TIMER); + do { val = gk20a_readl(g, gr_status_r()); @@ -398,8 +407,7 @@ int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, 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)); gk20a_err(dev_from_gk20a(g), "timeout, fe busy : %x", val); @@ -412,8 +420,7 @@ int gr_gk20a_ctx_wait_ucode(struct gk20a *g, u32 mailbox_id, u32 mailbox_ok, u32 opc_fail, u32 mailbox_fail, bool sleepduringwait) { - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); + struct nvgpu_timeout timeout; u32 delay = GR_FECS_POLL_INTERVAL; u32 check = WAIT_UCODE_LOOP; u32 reg; @@ -423,9 +430,11 @@ int gr_gk20a_ctx_wait_ucode(struct gk20a *g, u32 mailbox_id, if (sleepduringwait) delay = GR_IDLE_CHECK_DEFAULT; + nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); + while (check == WAIT_UCODE_LOOP) { - if (!time_before(jiffies, end_jiffies) && - tegra_platform_is_silicon()) + if (nvgpu_timeout_expired(&timeout)) check = WAIT_UCODE_TIMEOUT; reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(mailbox_id)); @@ -1484,8 +1493,6 @@ static u32 gk20a_init_sw_bundle(struct gk20a *g) u32 last_bundle_data = 0; u32 err = 0; unsigned int i; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); /* disable fe_go_idle */ gk20a_writel(g, gr_fe_go_idle_timeout_r(), @@ -1507,11 +1514,12 @@ static u32 gk20a_init_sw_bundle(struct gk20a *g) if (gr_pipe_bundle_address_value_v(sw_bundle_init->l[i].addr) == GR_GO_IDLE_BUNDLE) - err |= gr_gk20a_wait_idle(g, end_jiffies, - GR_IDLE_CHECK_DEFAULT); + err |= gr_gk20a_wait_idle(g, + gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); - err = gr_gk20a_wait_fe_idle(g, end_jiffies, - GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_fe_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) break; } @@ -1521,7 +1529,8 @@ static u32 gk20a_init_sw_bundle(struct gk20a *g) gk20a_writel(g, gr_pipe_bundle_config_r(), gr_pipe_bundle_config_override_pipe_mode_disabled_f()); - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) return err; @@ -1548,8 +1557,6 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, u32 err = 0; 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; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); 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); @@ -1571,8 +1578,9 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, if (err) goto clean_up; - err = gr_gk20a_wait_idle(g, end_jiffies, - GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, + gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); } gk20a_mem_end(g, ctxheader); goto clean_up; @@ -1641,7 +1649,8 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, if (err) goto clean_up; - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); /* load ctx init */ for (i = 0; i < sw_ctx_load->count; i++) @@ -1654,7 +1663,8 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, if (g->ops.clock_gating.blcg_gr_load_gating_prod) g->ops.clock_gating.blcg_gr_load_gating_prod(g, g->blcg_enabled); - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) goto clean_up; @@ -1672,7 +1682,8 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g, /* floorsweep anything left */ g->ops.gr.init_fs_state(g); - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) goto restore_fe_go_idle; @@ -1685,7 +1696,8 @@ restore_fe_go_idle: gk20a_writel(g, gr_fe_go_idle_timeout_r(), gr_fe_go_idle_timeout_count_prod_f()); - if (err || gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT)) + if (err || gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT)) goto clean_up; /* load method init */ @@ -1708,7 +1720,8 @@ restore_fe_go_idle: sw_method_init->l[i].addr); } - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) goto clean_up; @@ -3980,8 +3993,6 @@ void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries) { struct fifo_gk20a *f = &g->fifo; struct fifo_engine_info_gk20a *gr_info = NULL; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); u32 ret; u32 engine_id; @@ -3995,7 +4006,8 @@ void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries) return; } - ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (ret) { gk20a_err(dev_from_gk20a(g), "failed to idle graphics"); @@ -4300,7 +4312,6 @@ int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, { struct fifo_gk20a *f = &g->fifo; struct fifo_engine_info_gk20a *gr_info = NULL; - unsigned long end_jiffies; int ret; u32 engine_id; @@ -4314,8 +4325,8 @@ int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, return ret; } - end_jiffies = jiffies + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); - ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (ret) { gk20a_err(dev_from_gk20a(g), "failed to idle graphics"); @@ -4698,8 +4709,6 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g) struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init; u32 data; u64 addr; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); u32 last_method_data = 0; u32 i, err; @@ -4791,7 +4800,8 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g) gk20a_writel(g, sw_ctx_load->l[i].addr, sw_ctx_load->l[i].value); - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) goto out; @@ -4813,7 +4823,8 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g) if (err) goto out; - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) goto restore_fe_go_idle; @@ -4822,7 +4833,8 @@ restore_fe_go_idle: gk20a_writel(g, gr_fe_go_idle_timeout_r(), gr_fe_go_idle_timeout_count_prod_f()); - if (err || gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT)) + if (err || gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT)) goto out; /* load method init */ @@ -4845,7 +4857,8 @@ restore_fe_go_idle: sw_method_init->l[i].addr); } - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) goto out; @@ -5008,8 +5021,6 @@ out: static int gk20a_init_gr_reset_enable_hw(struct gk20a *g) { struct av_list_gk20a *sw_non_ctx_load = &g->gr.ctx_vars.sw_non_ctx_load; - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); u32 i, err = 0; gk20a_dbg_fn(""); @@ -5027,7 +5038,8 @@ static int gk20a_init_gr_reset_enable_hw(struct gk20a *g) if (err) goto out; - err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (err) goto out; @@ -6610,13 +6622,12 @@ int gr_gk20a_fecs_set_reglist_virtual_addr(struct gk20a *g, u64 pmu_va) int gk20a_gr_suspend(struct gk20a *g) { - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); u32 ret = 0; gk20a_dbg_fn(""); - ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); + ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g), + GR_IDLE_CHECK_DEFAULT); if (ret) return ret; diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 40b3bd442..e5d7e83ba 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h @@ -600,7 +600,7 @@ int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, struct zbc_entry *zbc_val); void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); -int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, +int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms, u32 expect_delay); int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, bool *post_event, struct channel_gk20a *fault_ch, @@ -662,8 +662,8 @@ int gr_gk20a_get_ctx_id(struct gk20a *g, u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr); -int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, - u32 expect_delay); +int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay); bool gr_gk20a_suspend_context(struct channel_gk20a *ch); bool gr_gk20a_resume_context(struct channel_gk20a *ch); diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 74476fe43..b7ef21b32 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -1,7 +1,7 @@ /* * GK20A memory management * - * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -894,14 +894,17 @@ static int gk20a_vidmem_clear_all(struct gk20a *g) } if (gk20a_fence_out) { - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, + gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); do { - unsigned int timeout = jiffies_to_msecs(end_jiffies - jiffies); err = gk20a_fence_wait(gk20a_fence_out, - timeout); - } while ((err == -ERESTARTSYS) && time_before(jiffies, end_jiffies)); + gk20a_get_gr_idle_timeout(g)); + } while (err == -ERESTARTSYS && + !nvgpu_timeout_expired(&timeout)); gk20a_fence_put(gk20a_fence_out); if (err) { @@ -3103,14 +3106,17 @@ static int gk20a_gmmu_clear_vidmem_mem(struct gk20a *g, struct mem_desc *mem) } if (gk20a_last_fence) { - unsigned long end_jiffies = jiffies + - msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); + struct nvgpu_timeout timeout; + + nvgpu_timeout_init(g, &timeout, + gk20a_get_gr_idle_timeout(g), + NVGPU_TIMER_CPU_TIMER); do { - unsigned int timeout = jiffies_to_msecs(end_jiffies - jiffies); err = gk20a_fence_wait(gk20a_last_fence, - timeout); - } while ((err == -ERESTARTSYS) && time_before(jiffies, end_jiffies)); + gk20a_get_gr_idle_timeout(g)); + } while (err == -ERESTARTSYS && + !nvgpu_timeout_expired(&timeout)); gk20a_fence_put(gk20a_last_fence); if (err) diff --git a/drivers/gpu/nvgpu/gk20a/sched_gk20a.c b/drivers/gpu/nvgpu/gk20a/sched_gk20a.c index c2374b965..54dbcfd18 100644 --- a/drivers/gpu/nvgpu/gk20a/sched_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/sched_gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c index 93d7dcbd3..7eceb2a42 100644 --- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c @@ -31,6 +31,8 @@ #include "gp10b/gr_gp10b.h" #include "gp10b_sysfs.h" +#include + #include #include #include @@ -1353,8 +1355,8 @@ static bool gr_activity_empty_or_preempted(u32 val) return true; } -static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long end_jiffies, - u32 expect_delay) +static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long duration_ms, + u32 expect_delay) { u32 delay = expect_delay; bool gr_enabled; @@ -1362,9 +1364,12 @@ static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long end_jiffies, bool gr_busy; u32 gr_status; u32 activity0, activity1, activity2, activity4; + struct nvgpu_timeout timeout; gk20a_dbg_fn(""); + nvgpu_timeout_init(g, &timeout, duration_ms, NVGPU_TIMER_CPU_TIMER); + do { /* fmodel: host gets fifo_engine_status(gr) from gr only when gr_status is read */ @@ -1392,9 +1397,7 @@ static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long end_jiffies, 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)); gk20a_err(dev_from_gk20a(g), "timeout, ctxsw busy : %d, gr busy : %d, %08x, %08x, %08x, %08x",