From 6e2237ef622113b8fa1149aa48988a99fa30594f Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Fri, 16 Dec 2016 12:29:34 -0800 Subject: gpu: nvgpu: Use timer API in gk20a code Use the timers API in the gk20a code instead of Linux specific API calls. This also changes the behavior of several functions to wait for the full timeout for each operation that can timeout. Previously the timeout was shared across each operation. Bug 1799159 Change-Id: I2bbed54630667b2b879b56a63a853266afc1e5d8 Signed-off-by: Alex Waterman Reviewed-on: http://git-master/r/1273826 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 11 ++- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 11 +-- drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c | 3 +- drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c | 3 +- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 47 +++++++------ drivers/gpu/nvgpu/gk20a/gk20a.c | 16 +++-- drivers/gpu/nvgpu/gk20a/gk20a.h | 4 +- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 101 +++++++++++++++------------- drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 6 +- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 28 +++++--- drivers/gpu/nvgpu/gk20a/sched_gk20a.c | 3 +- drivers/gpu/nvgpu/gp10b/gr_gp10b.c | 13 ++-- 12 files changed, 137 insertions(+), 109 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c index e4bb2a57..7b81f5e8 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 d5901354..d36b5d34 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 7633c873..9e116c36 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 ab88d5cb..6b77dff5 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 2daeb1d0..469148c2 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 5f365d4b..9725442a 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 00a580dd..6ca5855a 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 c5e927c1..f2096383 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 40b3bd44..e5d7e83b 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 74476fe4..b7ef21b3 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 c2374b96..54dbcfd1 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 93d7dcbd..7eceb2a4 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", -- cgit v1.2.2