mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +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;
|
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
|
unsigned long end_jiffies = jiffies
|
||||||
+ msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
|
+ msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
|
||||||
u32 delay = GR_IDLE_CHECK_DEFAULT;
|
|
||||||
u32 ret = 0;
|
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 */
|
/* issue preempt */
|
||||||
gk20a_writel(g, fifo_preempt_r(),
|
if (is_tsg)
|
||||||
fifo_preempt_chid_f(hw_chid) |
|
gk20a_writel(g, fifo_preempt_r(),
|
||||||
fifo_preempt_type_channel_f());
|
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 */
|
/* wait for preempt */
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
@@ -1551,16 +1544,70 @@ int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
|
|||||||
!tegra_platform_is_silicon());
|
!tegra_platform_is_silicon());
|
||||||
|
|
||||||
if (ret) {
|
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",
|
gk20a_err(dev_from_gk20a(g),
|
||||||
hw_chid);
|
"preempt channel %d timeout\n", id);
|
||||||
|
|
||||||
gk20a_set_error_notifier(ch,
|
gk20a_set_error_notifier(ch,
|
||||||
NVHOST_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT);
|
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)
|
if (!mutex_ret)
|
||||||
pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
|
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);
|
void gk20a_fifo_nonstall_isr(struct gk20a *g);
|
||||||
|
|
||||||
int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid);
|
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,
|
int gk20a_fifo_enable_engine_activity(struct gk20a *g,
|
||||||
struct fifo_engine_info_gk20a *eng_info);
|
struct fifo_engine_info_gk20a *eng_info);
|
||||||
|
|||||||
@@ -398,10 +398,18 @@ static inline u32 fifo_preempt_type_channel_f(void)
|
|||||||
{
|
{
|
||||||
return 0x0;
|
return 0x0;
|
||||||
}
|
}
|
||||||
|
static inline u32 fifo_preempt_type_tsg_f(void)
|
||||||
|
{
|
||||||
|
return 0x1000000;
|
||||||
|
}
|
||||||
static inline u32 fifo_preempt_chid_f(u32 v)
|
static inline u32 fifo_preempt_chid_f(u32 v)
|
||||||
{
|
{
|
||||||
return (v & 0xfff) << 0;
|
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)
|
static inline u32 fifo_trigger_mmu_fault_r(u32 i)
|
||||||
{
|
{
|
||||||
return 0x00002a30 + i*4;
|
return 0x00002a30 + i*4;
|
||||||
|
|||||||
@@ -346,10 +346,18 @@ static inline u32 fifo_preempt_type_channel_f(void)
|
|||||||
{
|
{
|
||||||
return 0x0;
|
return 0x0;
|
||||||
}
|
}
|
||||||
|
static inline u32 fifo_preempt_type_tsg_f(void)
|
||||||
|
{
|
||||||
|
return 0x1000000;
|
||||||
|
}
|
||||||
static inline u32 fifo_preempt_chid_f(u32 v)
|
static inline u32 fifo_preempt_chid_f(u32 v)
|
||||||
{
|
{
|
||||||
return (v & 0xfff) << 0;
|
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)
|
static inline u32 fifo_trigger_mmu_fault_r(u32 i)
|
||||||
{
|
{
|
||||||
return 0x00002a30 + i*4;
|
return 0x00002a30 + i*4;
|
||||||
|
|||||||
Reference in New Issue
Block a user