summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2016-12-16 15:29:34 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-01-18 19:46:33 -0500
commit6e2237ef622113b8fa1149aa48988a99fa30594f (patch)
tree1356c45dda5751f7094f37aa93019f1199b635fb /drivers/gpu
parent8f5a42c4bf9c323b86452065d39ed7632b126561 (diff)
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 <alexw@nvidia.com> Reviewed-on: http://git-master/r/1273826 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/cde_gk20a.c11
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c11
-rw-r--r--drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c47
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c16
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h4
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c101
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.h6
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c28
-rw-r--r--drivers/gpu/nvgpu/gk20a/sched_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_gp10b.c13
12 files changed, 137 insertions, 109 deletions
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 @@
1/* 1/*
2 * Color decompression engine support 2 * Color decompression engine support
3 * 3 *
4 * Copyright (c) 2014-2016, NVIDIA Corporation. All rights reserved. 4 * Copyright (c) 2014-2017, NVIDIA Corporation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -24,6 +24,8 @@
24 24
25#include <trace/events/gk20a.h> 25#include <trace/events/gk20a.h>
26 26
27#include <nvgpu/timers.h>
28
27#include "gk20a.h" 29#include "gk20a.h"
28#include "channel_gk20a.h" 30#include "channel_gk20a.h"
29#include "mm_gk20a.h" 31#include "mm_gk20a.h"
@@ -864,7 +866,10 @@ __acquires(&cde_app->mutex)
864{ 866{
865 struct gk20a_cde_app *cde_app = &g->cde_app; 867 struct gk20a_cde_app *cde_app = &g->cde_app;
866 struct gk20a_cde_ctx *cde_ctx = NULL; 868 struct gk20a_cde_ctx *cde_ctx = NULL;
867 unsigned long end = jiffies + msecs_to_jiffies(MAX_CTX_RETRY_TIME); 869 struct nvgpu_timeout timeout;
870
871 nvgpu_timeout_init(g, &timeout, MAX_CTX_RETRY_TIME,
872 NVGPU_TIMER_CPU_TIMER);
868 873
869 do { 874 do {
870 cde_ctx = gk20a_cde_do_get_context(g); 875 cde_ctx = gk20a_cde_do_get_context(g);
@@ -875,7 +880,7 @@ __acquires(&cde_app->mutex)
875 mutex_unlock(&cde_app->mutex); 880 mutex_unlock(&cde_app->mutex);
876 cond_resched(); 881 cond_resched();
877 mutex_lock(&cde_app->mutex); 882 mutex_lock(&cde_app->mutex);
878 } while (time_before(jiffies, end)); 883 } while (!nvgpu_timeout_expired(&timeout));
879 884
880 return cde_ctx; 885 return cde_ctx;
881} 886}
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 @@
36#include "fence_gk20a.h" 36#include "fence_gk20a.h"
37#include "semaphore_gk20a.h" 37#include "semaphore_gk20a.h"
38 38
39#include <nvgpu/timers.h>
40
39#include <nvgpu/hw/gk20a/hw_ram_gk20a.h> 41#include <nvgpu/hw/gk20a/hw_ram_gk20a.h>
40#include <nvgpu/hw/gk20a/hw_fifo_gk20a.h> 42#include <nvgpu/hw/gk20a/hw_fifo_gk20a.h>
41#include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h> 43#include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h>
@@ -557,8 +559,10 @@ void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt)
557int gk20a_wait_channel_idle(struct channel_gk20a *ch) 559int gk20a_wait_channel_idle(struct channel_gk20a *ch)
558{ 560{
559 bool channel_idle = false; 561 bool channel_idle = false;
560 unsigned long end_jiffies = jiffies + 562 struct nvgpu_timeout timeout;
561 msecs_to_jiffies(gk20a_get_gr_idle_timeout(ch->g)); 563
564 nvgpu_timeout_init(ch->g, &timeout, gk20a_get_gr_idle_timeout(ch->g),
565 NVGPU_TIMER_CPU_TIMER);
562 566
563 do { 567 do {
564 channel_gk20a_joblist_lock(ch); 568 channel_gk20a_joblist_lock(ch);
@@ -568,8 +572,7 @@ int gk20a_wait_channel_idle(struct channel_gk20a *ch)
568 break; 572 break;
569 573
570 usleep_range(1000, 3000); 574 usleep_range(1000, 3000);
571 } while (time_before(jiffies, end_jiffies) 575 } while (!nvgpu_timeout_expired(&timeout));
572 || !tegra_platform_is_silicon());
573 576
574 if (!channel_idle) { 577 if (!channel_idle) {
575 gk20a_err(dev_from_gk20a(ch->g), "jobs not freed for channel %d\n", 578 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 @@
1/* 1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -16,7 +16,6 @@
16#include <linux/kthread.h> 16#include <linux/kthread.h>
17#include <linux/circ_buf.h> 17#include <linux/circ_buf.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/jiffies.h>
20#include <linux/wait.h> 19#include <linux/wait.h>
21#include <linux/ktime.h> 20#include <linux/ktime.h>
22#include <linux/nvgpu.h> 21#include <linux/nvgpu.h>
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 @@
1/* 1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -16,7 +16,6 @@
16#include <linux/kthread.h> 16#include <linux/kthread.h>
17#include <linux/circ_buf.h> 17#include <linux/circ_buf.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/jiffies.h>
20#include <linux/wait.h> 19#include <linux/wait.h>
21#include <linux/ktime.h> 20#include <linux/ktime.h>
22#include <linux/nvgpu.h> 21#include <linux/nvgpu.h>
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 @@
16 * this program; if not, write to the Free Software Foundation, Inc., 16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */ 18 */
19
19#include <linux/delay.h> 20#include <linux/delay.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/scatterlist.h> 22#include <linux/scatterlist.h>
@@ -23,6 +24,8 @@
23#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
24#include <linux/nvhost.h> 25#include <linux/nvhost.h>
25 26
27#include <nvgpu/timers.h>
28
26#include "gk20a.h" 29#include "gk20a.h"
27#include "debug_gk20a.h" 30#include "debug_gk20a.h"
28#include "ctxsw_trace_gk20a.h" 31#include "ctxsw_trace_gk20a.h"
@@ -1570,11 +1573,9 @@ static void gk20a_fifo_get_faulty_id_type(struct gk20a *g, int engine_id,
1570static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, 1573static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g,
1571 unsigned long engine_ids) 1574 unsigned long engine_ids)
1572{ 1575{
1573 unsigned long end_jiffies = jiffies + 1576 struct nvgpu_timeout timeout;
1574 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
1575 unsigned long delay = GR_IDLE_CHECK_DEFAULT; 1577 unsigned long delay = GR_IDLE_CHECK_DEFAULT;
1576 unsigned long engine_id; 1578 unsigned long engine_id;
1577 int ret;
1578 1579
1579 /* trigger faults for all bad engines */ 1580 /* trigger faults for all bad engines */
1580 for_each_set_bit(engine_id, &engine_ids, 32) { 1581 for_each_set_bit(engine_id, &engine_ids, 32) {
@@ -1593,21 +1594,16 @@ static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g,
1593 } 1594 }
1594 1595
1595 /* Wait for MMU fault to trigger */ 1596 /* Wait for MMU fault to trigger */
1596 ret = -EBUSY; 1597 nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g),
1598 NVGPU_TIMER_CPU_TIMER);
1597 do { 1599 do {
1598 if (gk20a_readl(g, fifo_intr_0_r()) & 1600 if (gk20a_readl(g, fifo_intr_0_r()) &
1599 fifo_intr_0_mmu_fault_pending_f()) { 1601 fifo_intr_0_mmu_fault_pending_f())
1600 ret = 0;
1601 break; 1602 break;
1602 }
1603 1603
1604 usleep_range(delay, delay * 2); 1604 usleep_range(delay, delay * 2);
1605 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); 1605 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
1606 } while (time_before(jiffies, end_jiffies) || 1606 } while (!nvgpu_timeout_expired_msg(&timeout, "mmu fault timeout"));
1607 !tegra_platform_is_silicon());
1608
1609 if (ret)
1610 gk20a_err(dev_from_gk20a(g), "mmu fault timeout");
1611 1607
1612 /* release mmu fault trigger */ 1608 /* release mmu fault trigger */
1613 for_each_set_bit(engine_id, &engine_ids, 32) 1609 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)
2366 2362
2367static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) 2363static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg)
2368{ 2364{
2365 struct nvgpu_timeout timeout;
2369 u32 delay = GR_IDLE_CHECK_DEFAULT; 2366 u32 delay = GR_IDLE_CHECK_DEFAULT;
2370 unsigned long end_jiffies = jiffies
2371 + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
2372 u32 ret = 0; 2367 u32 ret = 0;
2373 2368
2374 gk20a_dbg_fn("%d", id); 2369 gk20a_dbg_fn("%d", id);
@@ -2379,6 +2374,8 @@ static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg)
2379 gk20a_dbg_fn("%d", id); 2374 gk20a_dbg_fn("%d", id);
2380 /* wait for preempt */ 2375 /* wait for preempt */
2381 ret = -EBUSY; 2376 ret = -EBUSY;
2377 nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g),
2378 NVGPU_TIMER_CPU_TIMER);
2382 do { 2379 do {
2383 if (!(gk20a_readl(g, fifo_preempt_r()) & 2380 if (!(gk20a_readl(g, fifo_preempt_r()) &
2384 fifo_preempt_pending_true_f())) { 2381 fifo_preempt_pending_true_f())) {
@@ -2388,8 +2385,7 @@ static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg)
2388 2385
2389 usleep_range(delay, delay * 2); 2386 usleep_range(delay, delay * 2);
2390 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); 2387 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
2391 } while (time_before(jiffies, end_jiffies) || 2388 } while (!nvgpu_timeout_expired(&timeout));
2392 !tegra_platform_is_silicon());
2393 2389
2394 gk20a_dbg_fn("%d", id); 2390 gk20a_dbg_fn("%d", id);
2395 if (ret) { 2391 if (ret) {
@@ -2668,11 +2664,13 @@ static void gk20a_fifo_runlist_reset_engines(struct gk20a *g, u32 runlist_id)
2668static int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id) 2664static int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id)
2669{ 2665{
2670 struct fifo_runlist_info_gk20a *runlist; 2666 struct fifo_runlist_info_gk20a *runlist;
2671 unsigned long end_jiffies = jiffies + 2667 struct nvgpu_timeout timeout;
2672 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
2673 unsigned long delay = GR_IDLE_CHECK_DEFAULT; 2668 unsigned long delay = GR_IDLE_CHECK_DEFAULT;
2674 int ret = -ETIMEDOUT; 2669 int ret = -ETIMEDOUT;
2675 2670
2671 nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g),
2672 NVGPU_TIMER_CPU_TIMER);
2673
2676 runlist = &g->fifo.runlist_info[runlist_id]; 2674 runlist = &g->fifo.runlist_info[runlist_id];
2677 do { 2675 do {
2678 if ((gk20a_readl(g, fifo_eng_runlist_r(runlist_id)) & 2676 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)
2683 2681
2684 usleep_range(delay, delay * 2); 2682 usleep_range(delay, delay * 2);
2685 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); 2683 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
2686 } while (time_before(jiffies, end_jiffies) || 2684 } while (!nvgpu_timeout_expired(&timeout));
2687 !tegra_platform_is_silicon());
2688 2685
2689 return ret; 2686 return ret;
2690} 2687}
@@ -3106,14 +3103,16 @@ bool gk20a_fifo_is_engine_busy(struct gk20a *g)
3106 3103
3107int gk20a_fifo_wait_engine_idle(struct gk20a *g) 3104int gk20a_fifo_wait_engine_idle(struct gk20a *g)
3108{ 3105{
3109 unsigned long end_jiffies = jiffies + 3106 struct nvgpu_timeout timeout;
3110 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
3111 unsigned long delay = GR_IDLE_CHECK_DEFAULT; 3107 unsigned long delay = GR_IDLE_CHECK_DEFAULT;
3112 int ret = -ETIMEDOUT; 3108 int ret = -ETIMEDOUT;
3113 u32 i; 3109 u32 i;
3114 3110
3115 gk20a_dbg_fn(""); 3111 gk20a_dbg_fn("");
3116 3112
3113 nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g),
3114 NVGPU_TIMER_CPU_TIMER);
3115
3117 for (i = 0; i < fifo_engine_status__size_1_v(); i++) { 3116 for (i = 0; i < fifo_engine_status__size_1_v(); i++) {
3118 do { 3117 do {
3119 u32 status = gk20a_readl(g, fifo_engine_status_r(i)); 3118 u32 status = gk20a_readl(g, fifo_engine_status_r(i));
@@ -3125,8 +3124,8 @@ int gk20a_fifo_wait_engine_idle(struct gk20a *g)
3125 usleep_range(delay, delay * 2); 3124 usleep_range(delay, delay * 2);
3126 delay = min_t(unsigned long, 3125 delay = min_t(unsigned long,
3127 delay << 1, GR_IDLE_CHECK_MAX); 3126 delay << 1, GR_IDLE_CHECK_MAX);
3128 } while (time_before(jiffies, end_jiffies) || 3127 } while (!nvgpu_timeout_expired(&timeout));
3129 !tegra_platform_is_silicon()); 3128
3130 if (ret) { 3129 if (ret) {
3131 gk20a_dbg_info("cannot idle engine %u", i); 3130 gk20a_dbg_info("cannot idle engine %u", i);
3132 break; 3131 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 @@
44#include <linux/version.h> 44#include <linux/version.h>
45 45
46#include <nvgpu/allocator.h> 46#include <nvgpu/allocator.h>
47#include <nvgpu/timers.h>
47 48
48#include "gk20a.h" 49#include "gk20a.h"
49#include "nvgpu_common.h" 50#include "nvgpu_common.h"
@@ -1923,8 +1924,7 @@ int __gk20a_do_idle(struct device *dev, bool force_reset)
1923{ 1924{
1924 struct gk20a *g = get_gk20a(dev); 1925 struct gk20a *g = get_gk20a(dev);
1925 struct gk20a_platform *platform = dev_get_drvdata(dev); 1926 struct gk20a_platform *platform = dev_get_drvdata(dev);
1926 unsigned long timeout = jiffies + 1927 struct nvgpu_timeout timeout;
1927 msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS);
1928 int ref_cnt; 1928 int ref_cnt;
1929 int target_ref_cnt = 0; 1929 int target_ref_cnt = 0;
1930 bool is_railgated; 1930 bool is_railgated;
@@ -1958,11 +1958,14 @@ int __gk20a_do_idle(struct device *dev, bool force_reset)
1958 target_ref_cnt = 1; 1958 target_ref_cnt = 1;
1959 mutex_lock(&platform->railgate_lock); 1959 mutex_lock(&platform->railgate_lock);
1960 1960
1961 nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS,
1962 NVGPU_TIMER_CPU_TIMER);
1963
1961 /* check and wait until GPU is idle (with a timeout) */ 1964 /* check and wait until GPU is idle (with a timeout) */
1962 do { 1965 do {
1963 msleep(1); 1966 msleep(1);
1964 ref_cnt = atomic_read(&dev->power.usage_count); 1967 ref_cnt = atomic_read(&dev->power.usage_count);
1965 } while (ref_cnt != target_ref_cnt && time_before(jiffies, timeout)); 1968 } while (ref_cnt != target_ref_cnt && !nvgpu_timeout_expired(&timeout));
1966 1969
1967 if (ref_cnt != target_ref_cnt) { 1970 if (ref_cnt != target_ref_cnt) {
1968 gk20a_err(dev, "failed to idle - refcount %d != 1\n", 1971 gk20a_err(dev, "failed to idle - refcount %d != 1\n",
@@ -1973,6 +1976,9 @@ int __gk20a_do_idle(struct device *dev, bool force_reset)
1973 /* check if global force_reset flag is set */ 1976 /* check if global force_reset flag is set */
1974 force_reset |= platform->force_reset_in_do_idle; 1977 force_reset |= platform->force_reset_in_do_idle;
1975 1978
1979 nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS,
1980 NVGPU_TIMER_CPU_TIMER);
1981
1976 if (platform->can_railgate && !force_reset) { 1982 if (platform->can_railgate && !force_reset) {
1977 /* 1983 /*
1978 * Case 1 : GPU railgate is supported 1984 * Case 1 : GPU railgate is supported
@@ -1985,13 +1991,11 @@ int __gk20a_do_idle(struct device *dev, bool force_reset)
1985 /* add sufficient delay to allow GPU to rail gate */ 1991 /* add sufficient delay to allow GPU to rail gate */
1986 msleep(platform->railgate_delay); 1992 msleep(platform->railgate_delay);
1987 1993
1988 timeout = jiffies + msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS);
1989
1990 /* check in loop if GPU is railgated or not */ 1994 /* check in loop if GPU is railgated or not */
1991 do { 1995 do {
1992 msleep(1); 1996 msleep(1);
1993 is_railgated = platform->is_railgated(dev); 1997 is_railgated = platform->is_railgated(dev);
1994 } while (!is_railgated && time_before(jiffies, timeout)); 1998 } while (!is_railgated && !nvgpu_timeout_expired(&timeout));
1995 1999
1996 if (is_railgated) { 2000 if (is_railgated) {
1997 return 0; 2001 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 {
270 u32 (*get_max_lts_per_ltc)(struct gk20a *g); 270 u32 (*get_max_lts_per_ltc)(struct gk20a *g);
271 u32* (*get_rop_l2_en_mask)(struct gk20a *g); 271 u32* (*get_rop_l2_en_mask)(struct gk20a *g);
272 void (*init_sm_dsm_reg_info)(void); 272 void (*init_sm_dsm_reg_info)(void);
273 int (*wait_empty)(struct gk20a *g, unsigned long end_jiffies, 273 int (*wait_empty)(struct gk20a *g, unsigned long duration_ms,
274 u32 expect_delay); 274 u32 expect_delay);
275 void (*init_cyclestats)(struct gk20a *g); 275 void (*init_cyclestats)(struct gk20a *g);
276 void (*enable_cde_in_fecs)(struct gk20a *g, 276 void (*enable_cde_in_fecs)(struct gk20a *g,
277 struct mem_desc *mem); 277 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 @@
31#include <linux/bsearch.h> 31#include <linux/bsearch.h>
32#include <trace/events/gk20a.h> 32#include <trace/events/gk20a.h>
33 33
34#include <nvgpu/timers.h>
35
34#include "gk20a.h" 36#include "gk20a.h"
35#include "kind_gk20a.h" 37#include "kind_gk20a.h"
36#include "gr_ctx_gk20a.h" 38#include "gr_ctx_gk20a.h"
@@ -321,7 +323,7 @@ static void gr_gk20a_load_falcon_imem(struct gk20a *g)
321 } 323 }
322} 324}
323 325
324int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, 326int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms,
325 u32 expect_delay) 327 u32 expect_delay)
326{ 328{
327 u32 delay = expect_delay; 329 u32 delay = expect_delay;
@@ -331,11 +333,15 @@ int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies,
331 u32 gr_engine_id; 333 u32 gr_engine_id;
332 u32 engine_status; 334 u32 engine_status;
333 bool ctx_status_invalid; 335 bool ctx_status_invalid;
336 struct nvgpu_timeout timeout;
334 337
335 gk20a_dbg_fn(""); 338 gk20a_dbg_fn("");
336 339
337 gr_engine_id = gk20a_fifo_get_gr_engine_id(g); 340 gr_engine_id = gk20a_fifo_get_gr_engine_id(g);
338 341
342 nvgpu_timeout_init(g, &timeout, (int)duration_ms,
343 NVGPU_TIMER_CPU_TIMER);
344
339 do { 345 do {
340 /* fmodel: host gets fifo_engine_status(gr) from gr 346 /* fmodel: host gets fifo_engine_status(gr) from gr
341 only when gr_status is read */ 347 only when gr_status is read */
@@ -366,8 +372,7 @@ int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies,
366 usleep_range(delay, delay * 2); 372 usleep_range(delay, delay * 2);
367 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); 373 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
368 374
369 } while (time_before(jiffies, end_jiffies) 375 } while (!nvgpu_timeout_expired(&timeout));
370 || !tegra_platform_is_silicon());
371 376
372 gk20a_err(dev_from_gk20a(g), 377 gk20a_err(dev_from_gk20a(g),
373 "timeout, ctxsw busy : %d, gr busy : %d", 378 "timeout, ctxsw busy : %d, gr busy : %d",
@@ -376,18 +381,22 @@ int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies,
376 return -EAGAIN; 381 return -EAGAIN;
377} 382}
378 383
379int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, 384int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms,
380 u32 expect_delay) 385 u32 expect_delay)
381{ 386{
382 u32 val; 387 u32 val;
383 u32 delay = expect_delay; 388 u32 delay = expect_delay;
384 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 389 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
390 struct nvgpu_timeout timeout;
385 391
386 if (platform->is_fmodel) 392 if (platform->is_fmodel)
387 return 0; 393 return 0;
388 394
389 gk20a_dbg_fn(""); 395 gk20a_dbg_fn("");
390 396
397 nvgpu_timeout_init(g, &timeout, (int)duration_ms,
398 NVGPU_TIMER_CPU_TIMER);
399
391 do { 400 do {
392 val = gk20a_readl(g, gr_status_r()); 401 val = gk20a_readl(g, gr_status_r());
393 402
@@ -398,8 +407,7 @@ int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies,
398 407
399 usleep_range(delay, delay * 2); 408 usleep_range(delay, delay * 2);
400 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); 409 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
401 } while (time_before(jiffies, end_jiffies) 410 } while (!nvgpu_timeout_expired(&timeout));
402 || !tegra_platform_is_silicon());
403 411
404 gk20a_err(dev_from_gk20a(g), 412 gk20a_err(dev_from_gk20a(g),
405 "timeout, fe busy : %x", val); 413 "timeout, fe busy : %x", val);
@@ -412,8 +420,7 @@ int gr_gk20a_ctx_wait_ucode(struct gk20a *g, u32 mailbox_id,
412 u32 mailbox_ok, u32 opc_fail, 420 u32 mailbox_ok, u32 opc_fail,
413 u32 mailbox_fail, bool sleepduringwait) 421 u32 mailbox_fail, bool sleepduringwait)
414{ 422{
415 unsigned long end_jiffies = jiffies + 423 struct nvgpu_timeout timeout;
416 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
417 u32 delay = GR_FECS_POLL_INTERVAL; 424 u32 delay = GR_FECS_POLL_INTERVAL;
418 u32 check = WAIT_UCODE_LOOP; 425 u32 check = WAIT_UCODE_LOOP;
419 u32 reg; 426 u32 reg;
@@ -423,9 +430,11 @@ int gr_gk20a_ctx_wait_ucode(struct gk20a *g, u32 mailbox_id,
423 if (sleepduringwait) 430 if (sleepduringwait)
424 delay = GR_IDLE_CHECK_DEFAULT; 431 delay = GR_IDLE_CHECK_DEFAULT;
425 432
433 nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g),
434 NVGPU_TIMER_CPU_TIMER);
435
426 while (check == WAIT_UCODE_LOOP) { 436 while (check == WAIT_UCODE_LOOP) {
427 if (!time_before(jiffies, end_jiffies) && 437 if (nvgpu_timeout_expired(&timeout))
428 tegra_platform_is_silicon())
429 check = WAIT_UCODE_TIMEOUT; 438 check = WAIT_UCODE_TIMEOUT;
430 439
431 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(mailbox_id)); 440 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(mailbox_id));
@@ -1484,8 +1493,6 @@ static u32 gk20a_init_sw_bundle(struct gk20a *g)
1484 u32 last_bundle_data = 0; 1493 u32 last_bundle_data = 0;
1485 u32 err = 0; 1494 u32 err = 0;
1486 unsigned int i; 1495 unsigned int i;
1487 unsigned long end_jiffies = jiffies +
1488 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
1489 1496
1490 /* disable fe_go_idle */ 1497 /* disable fe_go_idle */
1491 gk20a_writel(g, gr_fe_go_idle_timeout_r(), 1498 gk20a_writel(g, gr_fe_go_idle_timeout_r(),
@@ -1507,11 +1514,12 @@ static u32 gk20a_init_sw_bundle(struct gk20a *g)
1507 1514
1508 if (gr_pipe_bundle_address_value_v(sw_bundle_init->l[i].addr) == 1515 if (gr_pipe_bundle_address_value_v(sw_bundle_init->l[i].addr) ==
1509 GR_GO_IDLE_BUNDLE) 1516 GR_GO_IDLE_BUNDLE)
1510 err |= gr_gk20a_wait_idle(g, end_jiffies, 1517 err |= gr_gk20a_wait_idle(g,
1511 GR_IDLE_CHECK_DEFAULT); 1518 gk20a_get_gr_idle_timeout(g),
1519 GR_IDLE_CHECK_DEFAULT);
1512 1520
1513 err = gr_gk20a_wait_fe_idle(g, end_jiffies, 1521 err = gr_gk20a_wait_fe_idle(g, gk20a_get_gr_idle_timeout(g),
1514 GR_IDLE_CHECK_DEFAULT); 1522 GR_IDLE_CHECK_DEFAULT);
1515 if (err) 1523 if (err)
1516 break; 1524 break;
1517 } 1525 }
@@ -1521,7 +1529,8 @@ static u32 gk20a_init_sw_bundle(struct gk20a *g)
1521 gk20a_writel(g, gr_pipe_bundle_config_r(), 1529 gk20a_writel(g, gr_pipe_bundle_config_r(),
1522 gr_pipe_bundle_config_override_pipe_mode_disabled_f()); 1530 gr_pipe_bundle_config_override_pipe_mode_disabled_f());
1523 1531
1524 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 1532 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
1533 GR_IDLE_CHECK_DEFAULT);
1525 if (err) 1534 if (err)
1526 return err; 1535 return err;
1527 1536
@@ -1548,8 +1557,6 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g,
1548 u32 err = 0; 1557 u32 err = 0;
1549 struct aiv_list_gk20a *sw_ctx_load = &g->gr.ctx_vars.sw_ctx_load; 1558 struct aiv_list_gk20a *sw_ctx_load = &g->gr.ctx_vars.sw_ctx_load;
1550 struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init; 1559 struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init;
1551 unsigned long end_jiffies = jiffies +
1552 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
1553 u32 last_method_data = 0; 1560 u32 last_method_data = 0;
1554 int retries = FE_PWR_MODE_TIMEOUT_MAX / FE_PWR_MODE_TIMEOUT_DEFAULT; 1561 int retries = FE_PWR_MODE_TIMEOUT_MAX / FE_PWR_MODE_TIMEOUT_DEFAULT;
1555 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 1562 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
@@ -1571,8 +1578,9 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g,
1571 if (err) 1578 if (err)
1572 goto clean_up; 1579 goto clean_up;
1573 1580
1574 err = gr_gk20a_wait_idle(g, end_jiffies, 1581 err = gr_gk20a_wait_idle(g,
1575 GR_IDLE_CHECK_DEFAULT); 1582 gk20a_get_gr_idle_timeout(g),
1583 GR_IDLE_CHECK_DEFAULT);
1576 } 1584 }
1577 gk20a_mem_end(g, ctxheader); 1585 gk20a_mem_end(g, ctxheader);
1578 goto clean_up; 1586 goto clean_up;
@@ -1641,7 +1649,8 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g,
1641 if (err) 1649 if (err)
1642 goto clean_up; 1650 goto clean_up;
1643 1651
1644 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 1652 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
1653 GR_IDLE_CHECK_DEFAULT);
1645 1654
1646 /* load ctx init */ 1655 /* load ctx init */
1647 for (i = 0; i < sw_ctx_load->count; i++) 1656 for (i = 0; i < sw_ctx_load->count; i++)
@@ -1654,7 +1663,8 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g,
1654 if (g->ops.clock_gating.blcg_gr_load_gating_prod) 1663 if (g->ops.clock_gating.blcg_gr_load_gating_prod)
1655 g->ops.clock_gating.blcg_gr_load_gating_prod(g, g->blcg_enabled); 1664 g->ops.clock_gating.blcg_gr_load_gating_prod(g, g->blcg_enabled);
1656 1665
1657 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 1666 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
1667 GR_IDLE_CHECK_DEFAULT);
1658 if (err) 1668 if (err)
1659 goto clean_up; 1669 goto clean_up;
1660 1670
@@ -1672,7 +1682,8 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g,
1672 /* floorsweep anything left */ 1682 /* floorsweep anything left */
1673 g->ops.gr.init_fs_state(g); 1683 g->ops.gr.init_fs_state(g);
1674 1684
1675 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 1685 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
1686 GR_IDLE_CHECK_DEFAULT);
1676 if (err) 1687 if (err)
1677 goto restore_fe_go_idle; 1688 goto restore_fe_go_idle;
1678 1689
@@ -1685,7 +1696,8 @@ restore_fe_go_idle:
1685 gk20a_writel(g, gr_fe_go_idle_timeout_r(), 1696 gk20a_writel(g, gr_fe_go_idle_timeout_r(),
1686 gr_fe_go_idle_timeout_count_prod_f()); 1697 gr_fe_go_idle_timeout_count_prod_f());
1687 1698
1688 if (err || gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT)) 1699 if (err || gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
1700 GR_IDLE_CHECK_DEFAULT))
1689 goto clean_up; 1701 goto clean_up;
1690 1702
1691 /* load method init */ 1703 /* load method init */
@@ -1708,7 +1720,8 @@ restore_fe_go_idle:
1708 sw_method_init->l[i].addr); 1720 sw_method_init->l[i].addr);
1709 } 1721 }
1710 1722
1711 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 1723 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
1724 GR_IDLE_CHECK_DEFAULT);
1712 if (err) 1725 if (err)
1713 goto clean_up; 1726 goto clean_up;
1714 1727
@@ -3980,8 +3993,6 @@ void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries)
3980{ 3993{
3981 struct fifo_gk20a *f = &g->fifo; 3994 struct fifo_gk20a *f = &g->fifo;
3982 struct fifo_engine_info_gk20a *gr_info = NULL; 3995 struct fifo_engine_info_gk20a *gr_info = NULL;
3983 unsigned long end_jiffies = jiffies +
3984 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
3985 u32 ret; 3996 u32 ret;
3986 u32 engine_id; 3997 u32 engine_id;
3987 3998
@@ -3995,7 +4006,8 @@ void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries)
3995 return; 4006 return;
3996 } 4007 }
3997 4008
3998 ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 4009 ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g),
4010 GR_IDLE_CHECK_DEFAULT);
3999 if (ret) { 4011 if (ret) {
4000 gk20a_err(dev_from_gk20a(g), 4012 gk20a_err(dev_from_gk20a(g),
4001 "failed to idle graphics"); 4013 "failed to idle graphics");
@@ -4300,7 +4312,6 @@ int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr,
4300{ 4312{
4301 struct fifo_gk20a *f = &g->fifo; 4313 struct fifo_gk20a *f = &g->fifo;
4302 struct fifo_engine_info_gk20a *gr_info = NULL; 4314 struct fifo_engine_info_gk20a *gr_info = NULL;
4303 unsigned long end_jiffies;
4304 int ret; 4315 int ret;
4305 u32 engine_id; 4316 u32 engine_id;
4306 4317
@@ -4314,8 +4325,8 @@ int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr,
4314 return ret; 4325 return ret;
4315 } 4326 }
4316 4327
4317 end_jiffies = jiffies + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); 4328 ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g),
4318 ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 4329 GR_IDLE_CHECK_DEFAULT);
4319 if (ret) { 4330 if (ret) {
4320 gk20a_err(dev_from_gk20a(g), 4331 gk20a_err(dev_from_gk20a(g),
4321 "failed to idle graphics"); 4332 "failed to idle graphics");
@@ -4698,8 +4709,6 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g)
4698 struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init; 4709 struct av_list_gk20a *sw_method_init = &g->gr.ctx_vars.sw_method_init;
4699 u32 data; 4710 u32 data;
4700 u64 addr; 4711 u64 addr;
4701 unsigned long end_jiffies = jiffies +
4702 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
4703 u32 last_method_data = 0; 4712 u32 last_method_data = 0;
4704 u32 i, err; 4713 u32 i, err;
4705 4714
@@ -4791,7 +4800,8 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g)
4791 gk20a_writel(g, sw_ctx_load->l[i].addr, 4800 gk20a_writel(g, sw_ctx_load->l[i].addr,
4792 sw_ctx_load->l[i].value); 4801 sw_ctx_load->l[i].value);
4793 4802
4794 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 4803 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
4804 GR_IDLE_CHECK_DEFAULT);
4795 if (err) 4805 if (err)
4796 goto out; 4806 goto out;
4797 4807
@@ -4813,7 +4823,8 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g)
4813 if (err) 4823 if (err)
4814 goto out; 4824 goto out;
4815 4825
4816 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 4826 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
4827 GR_IDLE_CHECK_DEFAULT);
4817 if (err) 4828 if (err)
4818 goto restore_fe_go_idle; 4829 goto restore_fe_go_idle;
4819 4830
@@ -4822,7 +4833,8 @@ restore_fe_go_idle:
4822 gk20a_writel(g, gr_fe_go_idle_timeout_r(), 4833 gk20a_writel(g, gr_fe_go_idle_timeout_r(),
4823 gr_fe_go_idle_timeout_count_prod_f()); 4834 gr_fe_go_idle_timeout_count_prod_f());
4824 4835
4825 if (err || gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT)) 4836 if (err || gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
4837 GR_IDLE_CHECK_DEFAULT))
4826 goto out; 4838 goto out;
4827 4839
4828 /* load method init */ 4840 /* load method init */
@@ -4845,7 +4857,8 @@ restore_fe_go_idle:
4845 sw_method_init->l[i].addr); 4857 sw_method_init->l[i].addr);
4846 } 4858 }
4847 4859
4848 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 4860 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
4861 GR_IDLE_CHECK_DEFAULT);
4849 if (err) 4862 if (err)
4850 goto out; 4863 goto out;
4851 4864
@@ -5008,8 +5021,6 @@ out:
5008static int gk20a_init_gr_reset_enable_hw(struct gk20a *g) 5021static int gk20a_init_gr_reset_enable_hw(struct gk20a *g)
5009{ 5022{
5010 struct av_list_gk20a *sw_non_ctx_load = &g->gr.ctx_vars.sw_non_ctx_load; 5023 struct av_list_gk20a *sw_non_ctx_load = &g->gr.ctx_vars.sw_non_ctx_load;
5011 unsigned long end_jiffies = jiffies +
5012 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
5013 u32 i, err = 0; 5024 u32 i, err = 0;
5014 5025
5015 gk20a_dbg_fn(""); 5026 gk20a_dbg_fn("");
@@ -5027,7 +5038,8 @@ static int gk20a_init_gr_reset_enable_hw(struct gk20a *g)
5027 if (err) 5038 if (err)
5028 goto out; 5039 goto out;
5029 5040
5030 err = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 5041 err = gr_gk20a_wait_idle(g, gk20a_get_gr_idle_timeout(g),
5042 GR_IDLE_CHECK_DEFAULT);
5031 if (err) 5043 if (err)
5032 goto out; 5044 goto out;
5033 5045
@@ -6610,13 +6622,12 @@ int gr_gk20a_fecs_set_reglist_virtual_addr(struct gk20a *g, u64 pmu_va)
6610 6622
6611int gk20a_gr_suspend(struct gk20a *g) 6623int gk20a_gr_suspend(struct gk20a *g)
6612{ 6624{
6613 unsigned long end_jiffies = jiffies +
6614 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
6615 u32 ret = 0; 6625 u32 ret = 0;
6616 6626
6617 gk20a_dbg_fn(""); 6627 gk20a_dbg_fn("");
6618 6628
6619 ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); 6629 ret = g->ops.gr.wait_empty(g, gk20a_get_gr_idle_timeout(g),
6630 GR_IDLE_CHECK_DEFAULT);
6620 if (ret) 6631 if (ret)
6621 return ret; 6632 return ret;
6622 6633
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,
600int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, 600int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr,
601 struct zbc_entry *zbc_val); 601 struct zbc_entry *zbc_val);
602void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); 602void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries);
603int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, 603int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms,
604 u32 expect_delay); 604 u32 expect_delay);
605int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, 605int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
606 bool *post_event, struct channel_gk20a *fault_ch, 606 bool *post_event, struct channel_gk20a *fault_ch,
@@ -662,8 +662,8 @@ int gr_gk20a_get_ctx_id(struct gk20a *g,
662 662
663u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr); 663u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr);
664 664
665int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, 665int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms,
666 u32 expect_delay); 666 u32 expect_delay);
667 667
668bool gr_gk20a_suspend_context(struct channel_gk20a *ch); 668bool gr_gk20a_suspend_context(struct channel_gk20a *ch);
669bool gr_gk20a_resume_context(struct channel_gk20a *ch); 669bool 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 @@
1/* 1/*
2 * GK20A memory management 2 * GK20A memory management
3 * 3 *
4 * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -894,14 +894,17 @@ static int gk20a_vidmem_clear_all(struct gk20a *g)
894 } 894 }
895 895
896 if (gk20a_fence_out) { 896 if (gk20a_fence_out) {
897 unsigned long end_jiffies = jiffies + 897 struct nvgpu_timeout timeout;
898 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); 898
899 nvgpu_timeout_init(g, &timeout,
900 gk20a_get_gr_idle_timeout(g),
901 NVGPU_TIMER_CPU_TIMER);
899 902
900 do { 903 do {
901 unsigned int timeout = jiffies_to_msecs(end_jiffies - jiffies);
902 err = gk20a_fence_wait(gk20a_fence_out, 904 err = gk20a_fence_wait(gk20a_fence_out,
903 timeout); 905 gk20a_get_gr_idle_timeout(g));
904 } while ((err == -ERESTARTSYS) && time_before(jiffies, end_jiffies)); 906 } while (err == -ERESTARTSYS &&
907 !nvgpu_timeout_expired(&timeout));
905 908
906 gk20a_fence_put(gk20a_fence_out); 909 gk20a_fence_put(gk20a_fence_out);
907 if (err) { 910 if (err) {
@@ -3103,14 +3106,17 @@ static int gk20a_gmmu_clear_vidmem_mem(struct gk20a *g, struct mem_desc *mem)
3103 } 3106 }
3104 3107
3105 if (gk20a_last_fence) { 3108 if (gk20a_last_fence) {
3106 unsigned long end_jiffies = jiffies + 3109 struct nvgpu_timeout timeout;
3107 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); 3110
3111 nvgpu_timeout_init(g, &timeout,
3112 gk20a_get_gr_idle_timeout(g),
3113 NVGPU_TIMER_CPU_TIMER);
3108 3114
3109 do { 3115 do {
3110 unsigned int timeout = jiffies_to_msecs(end_jiffies - jiffies);
3111 err = gk20a_fence_wait(gk20a_last_fence, 3116 err = gk20a_fence_wait(gk20a_last_fence,
3112 timeout); 3117 gk20a_get_gr_idle_timeout(g));
3113 } while ((err == -ERESTARTSYS) && time_before(jiffies, end_jiffies)); 3118 } while (err == -ERESTARTSYS &&
3119 !nvgpu_timeout_expired(&timeout));
3114 3120
3115 gk20a_fence_put(gk20a_last_fence); 3121 gk20a_fence_put(gk20a_last_fence);
3116 if (err) 3122 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 @@
1/* 1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -16,7 +16,6 @@
16#include <linux/kthread.h> 16#include <linux/kthread.h>
17#include <linux/circ_buf.h> 17#include <linux/circ_buf.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/jiffies.h>
20#include <linux/wait.h> 19#include <linux/wait.h>
21#include <linux/ktime.h> 20#include <linux/ktime.h>
22#include <linux/nvgpu.h> 21#include <linux/nvgpu.h>
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 @@
31#include "gp10b/gr_gp10b.h" 31#include "gp10b/gr_gp10b.h"
32#include "gp10b_sysfs.h" 32#include "gp10b_sysfs.h"
33 33
34#include <nvgpu/timers.h>
35
34#include <nvgpu/hw/gp10b/hw_gr_gp10b.h> 36#include <nvgpu/hw/gp10b/hw_gr_gp10b.h>
35#include <nvgpu/hw/gp10b/hw_fifo_gp10b.h> 37#include <nvgpu/hw/gp10b/hw_fifo_gp10b.h>
36#include <nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h> 38#include <nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h>
@@ -1353,8 +1355,8 @@ static bool gr_activity_empty_or_preempted(u32 val)
1353 return true; 1355 return true;
1354} 1356}
1355 1357
1356static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long end_jiffies, 1358static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long duration_ms,
1357 u32 expect_delay) 1359 u32 expect_delay)
1358{ 1360{
1359 u32 delay = expect_delay; 1361 u32 delay = expect_delay;
1360 bool gr_enabled; 1362 bool gr_enabled;
@@ -1362,9 +1364,12 @@ static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long end_jiffies,
1362 bool gr_busy; 1364 bool gr_busy;
1363 u32 gr_status; 1365 u32 gr_status;
1364 u32 activity0, activity1, activity2, activity4; 1366 u32 activity0, activity1, activity2, activity4;
1367 struct nvgpu_timeout timeout;
1365 1368
1366 gk20a_dbg_fn(""); 1369 gk20a_dbg_fn("");
1367 1370
1371 nvgpu_timeout_init(g, &timeout, duration_ms, NVGPU_TIMER_CPU_TIMER);
1372
1368 do { 1373 do {
1369 /* fmodel: host gets fifo_engine_status(gr) from gr 1374 /* fmodel: host gets fifo_engine_status(gr) from gr
1370 only when gr_status is read */ 1375 only when gr_status is read */
@@ -1392,9 +1397,7 @@ static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long end_jiffies,
1392 1397
1393 usleep_range(delay, delay * 2); 1398 usleep_range(delay, delay * 2);
1394 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); 1399 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
1395 1400 } while (!nvgpu_timeout_expired(&timeout));
1396 } while (time_before(jiffies, end_jiffies)
1397 || !tegra_platform_is_silicon());
1398 1401
1399 gk20a_err(dev_from_gk20a(g), 1402 gk20a_err(dev_from_gk20a(g),
1400 "timeout, ctxsw busy : %d, gr busy : %d, %08x, %08x, %08x, %08x", 1403 "timeout, ctxsw busy : %d, gr busy : %d, %08x, %08x, %08x, %08x",