summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--drivers/gpu/nvgpu/gm20b/hw_fifo_gm20b.h8
4 files changed, 87 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;
diff --git a/drivers/gpu/nvgpu/gm20b/hw_fifo_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_fifo_gm20b.h
index 2b8bd9ce..09e311ef 100644
--- a/drivers/gpu/nvgpu/gm20b/hw_fifo_gm20b.h
+++ b/drivers/gpu/nvgpu/gm20b/hw_fifo_gm20b.h
@@ -346,10 +346,18 @@ static inline u32 fifo_preempt_type_channel_f(void)
346{ 346{
347 return 0x0; 347 return 0x0;
348} 348}
349static inline u32 fifo_preempt_type_tsg_f(void)
350{
351 return 0x1000000;
352}
349static inline u32 fifo_preempt_chid_f(u32 v) 353static inline u32 fifo_preempt_chid_f(u32 v)
350{ 354{
351 return (v & 0xfff) << 0; 355 return (v & 0xfff) << 0;
352} 356}
357static inline u32 fifo_preempt_id_f(u32 v)
358{
359 return (v & 0xfff) << 0;
360}
353static inline u32 fifo_trigger_mmu_fault_r(u32 i) 361static inline u32 fifo_trigger_mmu_fault_r(u32 i)
354{ 362{
355 return 0x00002a30 + i*4; 363 return 0x00002a30 + i*4;