mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
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:
committed by
Dan Willemsen
parent
3ef352a05a
commit
48e19c6c28
@@ -1512,29 +1512,22 @@ 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 */
|
||||
gk20a_writel(g, fifo_preempt_r(),
|
||||
fifo_preempt_chid_f(hw_chid) |
|
||||
fifo_preempt_type_channel_f());
|
||||
if (is_tsg)
|
||||
gk20a_writel(g, fifo_preempt_r(),
|
||||
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 */
|
||||
ret = -EBUSY;
|
||||
@@ -1551,16 +1544,70 @@ 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_set_error_notifier(ch,
|
||||
NVHOST_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT);
|
||||
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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user