gpu: nvgpu: add API to preempt TSG

Add API gk20a_fifo_preempt_tsg() which takes ID of tsg
and preempts it

Bug 1514064
Bug 1470692

Change-Id: I1d52c1dd7a9aecc1314b0f223fe4eedecc033629
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/495583
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Deepak Nibade
2014-09-03 18:40:28 +05:30
committed by Dan Willemsen
parent 3ef352a05a
commit 48e19c6c28
4 changed files with 87 additions and 23 deletions

View File

@@ -1512,28 +1512,21 @@ void gk20a_fifo_nonstall_isr(struct gk20a *g)
return;
}
int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg)
{
struct fifo_gk20a *f = &g->fifo;
u32 delay = GR_IDLE_CHECK_DEFAULT;
unsigned long end_jiffies = jiffies
+ msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
u32 delay = GR_IDLE_CHECK_DEFAULT;
u32 ret = 0;
u32 token = PMU_INVALID_MUTEX_OWNER_ID;
u32 mutex_ret = 0;
u32 i;
gk20a_dbg_fn("%d", hw_chid);
/* we have no idea which runlist we are using. lock all */
for (i = 0; i < g->fifo.max_runlists; i++)
mutex_lock(&f->runlist_info[i].mutex);
mutex_ret = pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
/* issue preempt */
if (is_tsg)
gk20a_writel(g, fifo_preempt_r(),
fifo_preempt_chid_f(hw_chid) |
fifo_preempt_id_f(id) |
fifo_preempt_type_tsg_f());
else
gk20a_writel(g, fifo_preempt_r(),
fifo_preempt_chid_f(id) |
fifo_preempt_type_channel_f());
/* wait for preempt */
@@ -1551,15 +1544,69 @@ int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
!tegra_platform_is_silicon());
if (ret) {
struct channel_gk20a *ch = &g->fifo.channel[hw_chid];
if (is_tsg) {
/* TODO: recovery for TSG */
gk20a_err(dev_from_gk20a(g),
"preempt TSG %d timeout\n", id);
} else {
struct channel_gk20a *ch = &g->fifo.channel[id];
gk20a_err(dev_from_gk20a(g), "preempt channel %d timeout\n",
hw_chid);
gk20a_err(dev_from_gk20a(g),
"preempt channel %d timeout\n", id);
gk20a_set_error_notifier(ch,
NVHOST_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT);
gk20a_fifo_recover_ch(g, hw_chid, true);
gk20a_fifo_recover_ch(g, id, true);
}
}
return ret;
}
int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
{
struct fifo_gk20a *f = &g->fifo;
u32 ret = 0;
u32 token = PMU_INVALID_MUTEX_OWNER_ID;
u32 mutex_ret = 0;
u32 i;
gk20a_dbg_fn("%d", hw_chid);
/* we have no idea which runlist we are using. lock all */
for (i = 0; i < g->fifo.max_runlists; i++)
mutex_lock(&f->runlist_info[i].mutex);
mutex_ret = pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
ret = __locked_fifo_preempt(g, hw_chid, false);
if (!mutex_ret)
pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
for (i = 0; i < g->fifo.max_runlists; i++)
mutex_unlock(&f->runlist_info[i].mutex);
return ret;
}
int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid)
{
struct fifo_gk20a *f = &g->fifo;
u32 ret = 0;
u32 token = PMU_INVALID_MUTEX_OWNER_ID;
u32 mutex_ret = 0;
u32 i;
gk20a_dbg_fn("%d", tsgid);
/* we have no idea which runlist we are using. lock all */
for (i = 0; i < g->fifo.max_runlists; i++)
mutex_lock(&f->runlist_info[i].mutex);
mutex_ret = pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
ret = __locked_fifo_preempt(g, tsgid, true);
if (!mutex_ret)
pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token);

View File

@@ -146,6 +146,7 @@ void gk20a_fifo_isr(struct gk20a *g);
void gk20a_fifo_nonstall_isr(struct gk20a *g);
int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid);
int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid);
int gk20a_fifo_enable_engine_activity(struct gk20a *g,
struct fifo_engine_info_gk20a *eng_info);

View File

@@ -398,10 +398,18 @@ static inline u32 fifo_preempt_type_channel_f(void)
{
return 0x0;
}
static inline u32 fifo_preempt_type_tsg_f(void)
{
return 0x1000000;
}
static inline u32 fifo_preempt_chid_f(u32 v)
{
return (v & 0xfff) << 0;
}
static inline u32 fifo_preempt_id_f(u32 v)
{
return (v & 0xfff) << 0;
}
static inline u32 fifo_trigger_mmu_fault_r(u32 i)
{
return 0x00002a30 + i*4;

View File

@@ -346,10 +346,18 @@ static inline u32 fifo_preempt_type_channel_f(void)
{
return 0x0;
}
static inline u32 fifo_preempt_type_tsg_f(void)
{
return 0x1000000;
}
static inline u32 fifo_preempt_chid_f(u32 v)
{
return (v & 0xfff) << 0;
}
static inline u32 fifo_preempt_id_f(u32 v)
{
return (v & 0xfff) << 0;
}
static inline u32 fifo_trigger_mmu_fault_r(u32 i)
{
return 0x00002a30 + i*4;