summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-09-03 09:10:28 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:13 -0400
commit48e19c6c2857047a1d0f56d98bbe48dcd4726fcd (patch)
treee7f730a65e7e1731fa5713111f1aaada345f77ba /drivers/gpu/nvgpu/gk20a
parent3ef352a05a027231d9cb88b63f465e6a0da89759 (diff)
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>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c93
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h8
3 files changed, 79 insertions, 23 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 230e1722..56ff4c87 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -1512,29 +1512,22 @@ void gk20a_fifo_nonstall_isr(struct gk20a *g)
1512 return; 1512 return;
1513} 1513}
1514 1514
1515int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid) 1515static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg)
1516{ 1516{
1517 struct fifo_gk20a *f = &g->fifo; 1517 u32 delay = GR_IDLE_CHECK_DEFAULT;
1518 unsigned long end_jiffies = jiffies 1518 unsigned long end_jiffies = jiffies
1519 + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); 1519 + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
1520 u32 delay = GR_IDLE_CHECK_DEFAULT;
1521 u32 ret = 0; 1520 u32 ret = 0;
1522 u32 token = PMU_INVALID_MUTEX_OWNER_ID;
1523 u32 mutex_ret = 0;
1524 u32 i;
1525
1526 gk20a_dbg_fn("%d", hw_chid);
1527
1528 /* we have no idea which runlist we are using. lock all */
1529 for (i = 0; i < g->fifo.max_runlists; i++)
1530 mutex_lock(&f->runlist_info[i].mutex);
1531
1532 mutex_ret = pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
1533 1521
1534 /* issue preempt */ 1522 /* issue preempt */
1535 gk20a_writel(g, fifo_preempt_r(), 1523 if (is_tsg)
1536 fifo_preempt_chid_f(hw_chid) | 1524 gk20a_writel(g, fifo_preempt_r(),
1537 fifo_preempt_type_channel_f()); 1525 fifo_preempt_id_f(id) |
1526 fifo_preempt_type_tsg_f());
1527 else
1528 gk20a_writel(g, fifo_preempt_r(),
1529 fifo_preempt_chid_f(id) |
1530 fifo_preempt_type_channel_f());
1538 1531
1539 /* wait for preempt */ 1532 /* wait for preempt */
1540 ret = -EBUSY; 1533 ret = -EBUSY;
@@ -1551,16 +1544,70 @@ int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
1551 !tegra_platform_is_silicon()); 1544 !tegra_platform_is_silicon());
1552 1545
1553 if (ret) { 1546 if (ret) {
1554 struct channel_gk20a *ch = &g->fifo.channel[hw_chid]; 1547 if (is_tsg) {
1548 /* TODO: recovery for TSG */
1549 gk20a_err(dev_from_gk20a(g),
1550 "preempt TSG %d timeout\n", id);
1551 } else {
1552 struct channel_gk20a *ch = &g->fifo.channel[id];
1555 1553
1556 gk20a_err(dev_from_gk20a(g), "preempt channel %d timeout\n", 1554 gk20a_err(dev_from_gk20a(g),
1557 hw_chid); 1555 "preempt channel %d timeout\n", id);
1558 1556
1559 gk20a_set_error_notifier(ch, 1557 gk20a_set_error_notifier(ch,
1560 NVHOST_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT); 1558 NVHOST_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT);
1561 gk20a_fifo_recover_ch(g, hw_chid, true); 1559 gk20a_fifo_recover_ch(g, id, true);
1560 }
1562 } 1561 }
1563 1562
1563 return ret;
1564}
1565
1566int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
1567{
1568 struct fifo_gk20a *f = &g->fifo;
1569 u32 ret = 0;
1570 u32 token = PMU_INVALID_MUTEX_OWNER_ID;
1571 u32 mutex_ret = 0;
1572 u32 i;
1573
1574 gk20a_dbg_fn("%d", hw_chid);
1575
1576 /* we have no idea which runlist we are using. lock all */
1577 for (i = 0; i < g->fifo.max_runlists; i++)
1578 mutex_lock(&f->runlist_info[i].mutex);
1579
1580 mutex_ret = pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
1581
1582 ret = __locked_fifo_preempt(g, hw_chid, false);
1583
1584 if (!mutex_ret)
1585 pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
1586
1587 for (i = 0; i < g->fifo.max_runlists; i++)
1588 mutex_unlock(&f->runlist_info[i].mutex);
1589
1590 return ret;
1591}
1592
1593int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid)
1594{
1595 struct fifo_gk20a *f = &g->fifo;
1596 u32 ret = 0;
1597 u32 token = PMU_INVALID_MUTEX_OWNER_ID;
1598 u32 mutex_ret = 0;
1599 u32 i;
1600
1601 gk20a_dbg_fn("%d", tsgid);
1602
1603 /* we have no idea which runlist we are using. lock all */
1604 for (i = 0; i < g->fifo.max_runlists; i++)
1605 mutex_lock(&f->runlist_info[i].mutex);
1606
1607 mutex_ret = pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
1608
1609 ret = __locked_fifo_preempt(g, tsgid, true);
1610
1564 if (!mutex_ret) 1611 if (!mutex_ret)
1565 pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); 1612 pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
1566 1613
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
index bed8a361..04d22abb 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
@@ -146,6 +146,7 @@ void gk20a_fifo_isr(struct gk20a *g);
146void gk20a_fifo_nonstall_isr(struct gk20a *g); 146void gk20a_fifo_nonstall_isr(struct gk20a *g);
147 147
148int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid); 148int gk20a_fifo_preempt_channel(struct gk20a *g, u32 hw_chid);
149int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid);
149 150
150int gk20a_fifo_enable_engine_activity(struct gk20a *g, 151int gk20a_fifo_enable_engine_activity(struct gk20a *g,
151 struct fifo_engine_info_gk20a *eng_info); 152 struct fifo_engine_info_gk20a *eng_info);
diff --git a/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h
index 83e7d776..aa77d026 100644
--- a/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h
@@ -398,10 +398,18 @@ static inline u32 fifo_preempt_type_channel_f(void)
398{ 398{
399 return 0x0; 399 return 0x0;
400} 400}
401static inline u32 fifo_preempt_type_tsg_f(void)
402{
403 return 0x1000000;
404}
401static inline u32 fifo_preempt_chid_f(u32 v) 405static inline u32 fifo_preempt_chid_f(u32 v)
402{ 406{
403 return (v & 0xfff) << 0; 407 return (v & 0xfff) << 0;
404} 408}
409static inline u32 fifo_preempt_id_f(u32 v)
410{
411 return (v & 0xfff) << 0;
412}
405static inline u32 fifo_trigger_mmu_fault_r(u32 i) 413static inline u32 fifo_trigger_mmu_fault_r(u32 i)
406{ 414{
407 return 0x00002a30 + i*4; 415 return 0x00002a30 + i*4;