diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2014-05-23 12:46:58 +0300 |
---|---|---|
committer | Mrutyunjay Sawant <msawant@nvidia.com> | 2014-06-04 06:13:09 -0700 |
commit | 6f526945f0746db3d0eb0b2d76a212d96dc1c18d (patch) | |
tree | 4758162da6759fc6c5381d2c2207fcfd58bb42da | |
parent | 6c8f204fe29c074287147c7fcc3dfdbd61d038df (diff) |
gpu: nvgpu: Handle PBDMA errors
Add handling for PBDMA errors.
Bug 1498688
Change-Id: Iff391110db1c270c05c76e6a14b7c666da8e3751
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
(cherry picked from commit 85f46d83227893f283d0247937dfa9da3e2d54fd)
Reviewed-on: http://git-master/r/417729
Reviewed-by: Automatic_Commit_Validation_User
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 4cc7781ddbd3..8ee6177ae14f 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -1338,35 +1338,25 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev, u32 pbdma_intr_0 = gk20a_readl(g, pbdma_intr_0_r(pbdma_id)); u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id)); u32 handled = 0; - bool reset_device = false; - bool reset_channel = false; + bool reset = false; gk20a_dbg_fn(""); gk20a_dbg(gpu_dbg_intr, "pbdma id intr pending %d %08x %08x", pbdma_id, pbdma_intr_0, pbdma_intr_1); if (pbdma_intr_0) { - if (f->intr.pbdma.device_fatal_0 & pbdma_intr_0) { - dev_err(dev, "unrecoverable device error: " - "pbdma_intr_0(%d):0x%08x", pbdma_id, pbdma_intr_0); - reset_device = true; - /* TODO: disable pbdma intrs */ - handled |= f->intr.pbdma.device_fatal_0 & pbdma_intr_0; - } - if (f->intr.pbdma.channel_fatal_0 & pbdma_intr_0) { - dev_warn(dev, "channel error: " - "pbdma_intr_0(%d):0x%08x", pbdma_id, pbdma_intr_0); - reset_channel = true; - /* TODO: clear pbdma channel errors */ - handled |= f->intr.pbdma.channel_fatal_0 & pbdma_intr_0; - } - if (f->intr.pbdma.restartable_0 & pbdma_intr_0) { - dev_warn(dev, "sw method: %08x %08x", - gk20a_readl(g, pbdma_method0_r(0)), - gk20a_readl(g, pbdma_method0_r(0)+4)); - gk20a_writel(g, pbdma_method0_r(0), 0); - gk20a_writel(g, pbdma_method0_r(0)+4, 0); - handled |= f->intr.pbdma.restartable_0 & pbdma_intr_0; + if ((f->intr.pbdma.device_fatal_0 | + f->intr.pbdma.channel_fatal_0 | + f->intr.pbdma.restartable_0) & pbdma_intr_0) { + dev_err(dev, "pbdma_intr_0(%d):0x%08x PBH: %08x M0: %08x", + pbdma_id, pbdma_intr_0, + gk20a_readl(g, pbdma_pb_header_r(pbdma_id)), + gk20a_readl(g, pbdma_method0_r(pbdma_id))); + reset = true; + handled |= ((f->intr.pbdma.device_fatal_0 | + f->intr.pbdma.channel_fatal_0 | + f->intr.pbdma.restartable_0) & + pbdma_intr_0); } gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0); @@ -1377,11 +1367,41 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev, if (pbdma_intr_1) { dev_err(dev, "channel hce error: pbdma_intr_1(%d): 0x%08x", pbdma_id, pbdma_intr_1); - reset_channel = true; + reset = true; gk20a_writel(g, pbdma_intr_1_r(pbdma_id), pbdma_intr_1); } - + if (reset) { + /* Remove the channel from runlist */ + u32 status = gk20a_readl(g, fifo_pbdma_status_r(pbdma_id)); + if (fifo_pbdma_status_id_type_v(status) + == fifo_pbdma_status_id_type_chid_v()) { + struct channel_gk20a *ch = g->fifo.channel + + fifo_pbdma_status_id_v(status); + struct fifo_runlist_info_gk20a *runlist = + g->fifo.runlist_info; + int i; + bool verbose; + + /* disable the channel from hw and increment + * syncpoints */ + gk20a_disable_channel_no_update(ch); + + /* remove the channel from runlist */ + clear_bit(ch->hw_chid, + runlist->active_channels); + ch->has_timedout = true; + + /* Recreate the runlist */ + for (i = 0; i < g->fifo.max_runlists; i++) + gk20a_fifo_update_runlist(g, + 0, ~0, false, false); + + verbose = gk20a_fifo_set_ctx_mmu_error(g, ch); + if (verbose) + gk20a_debug_dump(g->dev); + } + } return handled; } |