summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 4f3363f2..ad7162fc 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -1561,6 +1561,54 @@ static u32 fifo_error_isr(struct gk20a *g, u32 fifo_intr)
1561 return handled; 1561 return handled;
1562} 1562}
1563 1563
1564static inline void gk20a_fifo_reset_pbdma_header(struct gk20a *g, int pbdma_id)
1565{
1566 gk20a_writel(g, pbdma_pb_header_r(pbdma_id),
1567 pbdma_pb_header_first_true_f() |
1568 pbdma_pb_header_type_non_inc_f());
1569}
1570
1571static inline void gk20a_fifo_reset_pbdma_method(struct gk20a *g, int pbdma_id,
1572 int pbdma_method_index)
1573{
1574 u32 pbdma_method_stride;
1575 u32 pbdma_method_reg;
1576
1577 pbdma_method_stride = pbdma_method1_r(pbdma_id) -
1578 pbdma_method0_r(pbdma_id);
1579
1580 pbdma_method_reg = pbdma_method0_r(pbdma_id) +
1581 (pbdma_method_index * pbdma_method_stride);
1582
1583 gk20a_writel(g, pbdma_method_reg,
1584 pbdma_method0_valid_true_f() |
1585 pbdma_method0_first_true_f() |
1586 pbdma_method0_addr_f(
1587 pbdma_udma_nop_r() >> 2));
1588}
1589
1590static bool gk20a_fifo_is_sw_method_subch(struct gk20a *g, int pbdma_id,
1591 int pbdma_method_index)
1592{
1593 u32 pbdma_method_stride;
1594 u32 pbdma_method_reg, pbdma_method_subch;
1595
1596 pbdma_method_stride = pbdma_method1_r(pbdma_id) -
1597 pbdma_method0_r(pbdma_id);
1598
1599 pbdma_method_reg = pbdma_method0_r(pbdma_id) +
1600 (pbdma_method_index * pbdma_method_stride);
1601
1602 pbdma_method_subch = pbdma_method0_subch_v(
1603 gk20a_readl(g, pbdma_method_reg));
1604
1605 if (pbdma_method_subch == 5 || pbdma_method_subch == 6 ||
1606 pbdma_method_subch == 7)
1607 return true;
1608
1609 return false;
1610}
1611
1564static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev, 1612static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
1565 struct gk20a *g, 1613 struct gk20a *g,
1566 struct fifo_gk20a *f, 1614 struct fifo_gk20a *f,
@@ -1570,6 +1618,7 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
1570 u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id)); 1618 u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id));
1571 u32 handled = 0; 1619 u32 handled = 0;
1572 bool reset = false; 1620 bool reset = false;
1621 int i;
1573 1622
1574 gk20a_dbg_fn(""); 1623 gk20a_dbg_fn("");
1575 1624
@@ -1580,11 +1629,15 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
1580 f->intr.pbdma.channel_fatal_0 | 1629 f->intr.pbdma.channel_fatal_0 |
1581 f->intr.pbdma.restartable_0) & pbdma_intr_0) { 1630 f->intr.pbdma.restartable_0) & pbdma_intr_0) {
1582 gk20a_err(dev_from_gk20a(g), 1631 gk20a_err(dev_from_gk20a(g),
1583 "pbdma_intr_0(%d):0x%08x PBH: %08x SHADOW: %08x M0: %08x", 1632 "pbdma_intr_0(%d):0x%08x PBH: %08x SHADOW: %08x M0: %08x %08x %08x %08x",
1584 pbdma_id, pbdma_intr_0, 1633 pbdma_id, pbdma_intr_0,
1585 gk20a_readl(g, pbdma_pb_header_r(pbdma_id)), 1634 gk20a_readl(g, pbdma_pb_header_r(pbdma_id)),
1586 gk20a_readl(g, pbdma_hdr_shadow_r(pbdma_id)), 1635 gk20a_readl(g, pbdma_hdr_shadow_r(pbdma_id)),
1587 gk20a_readl(g, pbdma_method0_r(pbdma_id))); 1636 gk20a_readl(g, pbdma_method0_r(pbdma_id)),
1637 gk20a_readl(g, pbdma_method1_r(pbdma_id)),
1638 gk20a_readl(g, pbdma_method2_r(pbdma_id)),
1639 gk20a_readl(g, pbdma_method3_r(pbdma_id))
1640 );
1588 reset = true; 1641 reset = true;
1589 handled |= ((f->intr.pbdma.device_fatal_0 | 1642 handled |= ((f->intr.pbdma.device_fatal_0 |
1590 f->intr.pbdma.channel_fatal_0 | 1643 f->intr.pbdma.channel_fatal_0 |
@@ -1592,7 +1645,29 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
1592 pbdma_intr_0); 1645 pbdma_intr_0);
1593 } 1646 }
1594 1647
1595 gk20a_writel(g, pbdma_method0_r(pbdma_id), 0); 1648 if (pbdma_intr_0 & pbdma_intr_0_pbentry_pending_f()) {
1649 gk20a_fifo_reset_pbdma_header(g, pbdma_id);
1650 gk20a_fifo_reset_pbdma_method(g, pbdma_id, 0);
1651 reset = true;
1652 }
1653
1654 if (pbdma_intr_0 & pbdma_intr_0_method_pending_f()) {
1655 gk20a_fifo_reset_pbdma_method(g, pbdma_id, 0);
1656 reset = true;
1657 }
1658
1659 if (pbdma_intr_0 & pbdma_intr_0_device_pending_f()) {
1660 gk20a_fifo_reset_pbdma_header(g, pbdma_id);
1661
1662 for (i = 0; i < 4; i++) {
1663 if (gk20a_fifo_is_sw_method_subch(g,
1664 pbdma_id, i))
1665 gk20a_fifo_reset_pbdma_method(g,
1666 pbdma_id, i);
1667 }
1668 reset = true;
1669 }
1670
1596 gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0); 1671 gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0);
1597 } 1672 }
1598 1673