summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2015-09-24 05:26:44 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-10-16 11:23:49 -0400
commit68099f8298d25e94579f7d45c61b959f2c7ac184 (patch)
tree9f5b75f3d8c28f3110bb3177c7ad69156bf96386 /drivers
parent5b7b59714a6f6ea34295e4827eca68f496f5df18 (diff)
gpu: nvgpu: fix pbdma intr handling
To handle any of the pbdma interrupt, we currently write zero to pbdma_method0 and then clear the interrupt But this is insufficient since we cannot use same intr clear method for all the interrupts Hence, add intr specific routines to handle those interrupts NV_PPBDMA_INTR_0_PBENTRY: - fix the pb_header to have a null opcode - fix the pbdma_method to have a valid nop NV_PPBDMA_INTR_0_METHOD: - fix the pbdma_method to have a valid nop NV_PPBDMA_INTR_0_DEVICE: - fix the pb_header to have a null opcode - go through all pbdma_method0/1/2/3 -- if they contain host s/w methods, replace those methods with a valid NOP Bug 200134238 Change-Id: I10c284a6cdc1441f9d437cea65aae00d3c33a8c8 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/814561 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c81
-rw-r--r--drivers/gpu/nvgpu/gk20a/hw_pbdma_gk20a.h38
-rw-r--r--drivers/gpu/nvgpu/gm20b/hw_pbdma_gm20b.h42
3 files changed, 156 insertions, 5 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
diff --git a/drivers/gpu/nvgpu/gk20a/hw_pbdma_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_pbdma_gk20a.h
index e124e17f..e83dbb5c 100644
--- a/drivers/gpu/nvgpu/gk20a/hw_pbdma_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/hw_pbdma_gk20a.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -190,6 +190,10 @@ static inline u32 pbdma_pb_header_type_inc_f(void)
190{ 190{
191 return 0x20000000; 191 return 0x20000000;
192} 192}
193static inline u32 pbdma_pb_header_type_non_inc_f(void)
194{
195 return 0x60000000;
196}
193static inline u32 pbdma_hdr_shadow_r(u32 i) 197static inline u32 pbdma_hdr_shadow_r(u32 i)
194{ 198{
195 return 0x00040118 + i*8192; 199 return 0x00040118 + i*8192;
@@ -214,6 +218,38 @@ static inline u32 pbdma_method0_r(u32 i)
214{ 218{
215 return 0x000400c0 + i*8192; 219 return 0x000400c0 + i*8192;
216} 220}
221static inline u32 pbdma_method0_addr_f(u32 v)
222{
223 return (v & 0xfff) << 2;
224}
225static inline u32 pbdma_method0_addr_v(u32 r)
226{
227 return (r >> 2) & 0xfff;
228}
229static inline u32 pbdma_method0_subch_v(u32 r)
230{
231 return (r >> 16) & 0x7;
232}
233static inline u32 pbdma_method0_first_true_f(void)
234{
235 return 0x400000;
236}
237static inline u32 pbdma_method0_valid_true_f(void)
238{
239 return 0x80000000;
240}
241static inline u32 pbdma_method1_r(u32 i)
242{
243 return 0x000400c8 + i*8192;
244}
245static inline u32 pbdma_method2_r(u32 i)
246{
247 return 0x000400d0 + i*8192;
248}
249static inline u32 pbdma_method3_r(u32 i)
250{
251 return 0x000400d8 + i*8192;
252}
217static inline u32 pbdma_data0_r(u32 i) 253static inline u32 pbdma_data0_r(u32 i)
218{ 254{
219 return 0x000400c4 + i*8192; 255 return 0x000400c4 + i*8192;
diff --git a/drivers/gpu/nvgpu/gm20b/hw_pbdma_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_pbdma_gm20b.h
index 7b25d4af..c03a377a 100644
--- a/drivers/gpu/nvgpu/gm20b/hw_pbdma_gm20b.h
+++ b/drivers/gpu/nvgpu/gm20b/hw_pbdma_gm20b.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -174,6 +174,10 @@ static inline u32 pbdma_pb_header_type_inc_f(void)
174{ 174{
175 return 0x20000000; 175 return 0x20000000;
176} 176}
177static inline u32 pbdma_pb_header_type_non_inc_f(void)
178{
179 return 0x60000000;
180}
177static inline u32 pbdma_hdr_shadow_r(u32 i) 181static inline u32 pbdma_hdr_shadow_r(u32 i)
178{ 182{
179 return 0x00040118 + i*8192; 183 return 0x00040118 + i*8192;
@@ -198,6 +202,42 @@ static inline u32 pbdma_method0_r(u32 i)
198{ 202{
199 return 0x000400c0 + i*8192; 203 return 0x000400c0 + i*8192;
200} 204}
205static inline u32 pbdma_method0_fifo_size_v(void)
206{
207 return 0x00000004;
208}
209static inline u32 pbdma_method0_addr_f(u32 v)
210{
211 return (v & 0xfff) << 2;
212}
213static inline u32 pbdma_method0_addr_v(u32 r)
214{
215 return (r >> 2) & 0xfff;
216}
217static inline u32 pbdma_method0_subch_v(u32 r)
218{
219 return (r >> 16) & 0x7;
220}
221static inline u32 pbdma_method0_first_true_f(void)
222{
223 return 0x400000;
224}
225static inline u32 pbdma_method0_valid_true_f(void)
226{
227 return 0x80000000;
228}
229static inline u32 pbdma_method1_r(u32 i)
230{
231 return 0x000400c8 + i*8192;
232}
233static inline u32 pbdma_method2_r(u32 i)
234{
235 return 0x000400d0 + i*8192;
236}
237static inline u32 pbdma_method3_r(u32 i)
238{
239 return 0x000400d8 + i*8192;
240}
201static inline u32 pbdma_data0_r(u32 i) 241static inline u32 pbdma_data0_r(u32 i)
202{ 242{
203 return 0x000400c4 + i*8192; 243 return 0x000400c4 + i*8192;