diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 11 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 11 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 47 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 16 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 101 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 28 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/sched_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/gr_gp10b.c | 13 |
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) | |||
557 | int gk20a_wait_channel_idle(struct channel_gk20a *ch) | 559 | int 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, | |||
1570 | static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, | 1573 | static 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 | ||
2367 | static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) | 2363 | static 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) | |||
2668 | static int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id) | 2664 | static 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 | ||
3107 | int gk20a_fifo_wait_engine_idle(struct gk20a *g) | 3104 | int 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 | ||
324 | int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, | 326 | int 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 | ||
379 | int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, | 384 | int 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: | |||
5008 | static int gk20a_init_gr_reset_enable_hw(struct gk20a *g) | 5021 | static 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 | ||
6611 | int gk20a_gr_suspend(struct gk20a *g) | 6623 | int 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, | |||
600 | int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, | 600 | int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, |
601 | struct zbc_entry *zbc_val); | 601 | struct zbc_entry *zbc_val); |
602 | void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); | 602 | void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries); |
603 | int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, | 603 | int gr_gk20a_wait_idle(struct gk20a *g, unsigned long duration_ms, |
604 | u32 expect_delay); | 604 | u32 expect_delay); |
605 | int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, | 605 | int 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 | ||
663 | u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr); | 663 | u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr); |
664 | 664 | ||
665 | int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, | 665 | int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms, |
666 | u32 expect_delay); | 666 | u32 expect_delay); |
667 | 667 | ||
668 | bool gr_gk20a_suspend_context(struct channel_gk20a *ch); | 668 | bool gr_gk20a_suspend_context(struct channel_gk20a *ch); |
669 | bool gr_gk20a_resume_context(struct channel_gk20a *ch); | 669 | 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 @@ | |||
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 | ||
1356 | static int gr_gp10b_wait_empty(struct gk20a *g, unsigned long end_jiffies, | 1358 | static 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", |