mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-25 02:52:51 +03:00
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>
This commit is contained in:
committed by
mobile promotions
parent
8f5a42c4bf
commit
6e2237ef62
@@ -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 <trace/events/gk20a.h>
|
||||
|
||||
#include <nvgpu/timers.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "fence_gk20a.h"
|
||||
#include "semaphore_gk20a.h"
|
||||
|
||||
#include <nvgpu/timers.h>
|
||||
|
||||
#include <nvgpu/hw/gk20a/hw_ram_gk20a.h>
|
||||
#include <nvgpu/hw/gk20a/hw_fifo_gk20a.h>
|
||||
#include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h>
|
||||
@@ -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",
|
||||
|
||||
@@ -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 <linux/kthread.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/nvgpu.h>
|
||||
|
||||
@@ -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 <linux/kthread.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/nvgpu.h>
|
||||
|
||||
@@ -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 <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/scatterlist.h>
|
||||
@@ -23,6 +24,8 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/nvhost.h>
|
||||
|
||||
#include <nvgpu/timers.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <linux/version.h>
|
||||
|
||||
#include <nvgpu/allocator.h>
|
||||
#include <nvgpu/timers.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <linux/bsearch.h>
|
||||
#include <trace/events/gk20a.h>
|
||||
|
||||
#include <nvgpu/timers.h>
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 <linux/kthread.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/nvgpu.h>
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "gp10b/gr_gp10b.h"
|
||||
#include "gp10b_sysfs.h"
|
||||
|
||||
#include <nvgpu/timers.h>
|
||||
|
||||
#include <nvgpu/hw/gp10b/hw_gr_gp10b.h>
|
||||
#include <nvgpu/hw/gp10b/hw_fifo_gp10b.h>
|
||||
#include <nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h>
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user