mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: Handle PBDMA errors
Add handling for PBDMA errors. Bug 1498688 Change-Id: Iff391110db1c270c05c76e6a14b7c666da8e3751 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
Dan Willemsen
parent
2ad53bb4ca
commit
5dc7fd0243
@@ -1335,35 +1335,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_0 = gk20a_readl(g, pbdma_intr_0_r(pbdma_id));
|
||||||
u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id));
|
u32 pbdma_intr_1 = gk20a_readl(g, pbdma_intr_1_r(pbdma_id));
|
||||||
u32 handled = 0;
|
u32 handled = 0;
|
||||||
bool reset_device = false;
|
bool reset = false;
|
||||||
bool reset_channel = false;
|
|
||||||
|
|
||||||
gk20a_dbg_fn("");
|
gk20a_dbg_fn("");
|
||||||
|
|
||||||
gk20a_dbg(gpu_dbg_intr, "pbdma id intr pending %d %08x %08x", pbdma_id,
|
gk20a_dbg(gpu_dbg_intr, "pbdma id intr pending %d %08x %08x", pbdma_id,
|
||||||
pbdma_intr_0, pbdma_intr_1);
|
pbdma_intr_0, pbdma_intr_1);
|
||||||
if (pbdma_intr_0) {
|
if (pbdma_intr_0) {
|
||||||
if (f->intr.pbdma.device_fatal_0 & pbdma_intr_0) {
|
if ((f->intr.pbdma.device_fatal_0 |
|
||||||
dev_err(dev, "unrecoverable device error: "
|
f->intr.pbdma.channel_fatal_0 |
|
||||||
"pbdma_intr_0(%d):0x%08x", pbdma_id, pbdma_intr_0);
|
f->intr.pbdma.restartable_0) & pbdma_intr_0) {
|
||||||
reset_device = true;
|
dev_err(dev, "pbdma_intr_0(%d):0x%08x PBH: %08x M0: %08x",
|
||||||
/* TODO: disable pbdma intrs */
|
pbdma_id, pbdma_intr_0,
|
||||||
handled |= f->intr.pbdma.device_fatal_0 & pbdma_intr_0;
|
gk20a_readl(g, pbdma_pb_header_r(pbdma_id)),
|
||||||
}
|
gk20a_readl(g, pbdma_method0_r(pbdma_id)));
|
||||||
if (f->intr.pbdma.channel_fatal_0 & pbdma_intr_0) {
|
reset = true;
|
||||||
dev_warn(dev, "channel error: "
|
handled |= ((f->intr.pbdma.device_fatal_0 |
|
||||||
"pbdma_intr_0(%d):0x%08x", pbdma_id, pbdma_intr_0);
|
f->intr.pbdma.channel_fatal_0 |
|
||||||
reset_channel = true;
|
f->intr.pbdma.restartable_0) &
|
||||||
/* TODO: clear pbdma channel errors */
|
pbdma_intr_0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0);
|
gk20a_writel(g, pbdma_intr_0_r(pbdma_id), pbdma_intr_0);
|
||||||
@@ -1374,11 +1364,41 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
|
|||||||
if (pbdma_intr_1) {
|
if (pbdma_intr_1) {
|
||||||
dev_err(dev, "channel hce error: pbdma_intr_1(%d): 0x%08x",
|
dev_err(dev, "channel hce error: pbdma_intr_1(%d): 0x%08x",
|
||||||
pbdma_id, pbdma_intr_1);
|
pbdma_id, pbdma_intr_1);
|
||||||
reset_channel = true;
|
reset = true;
|
||||||
gk20a_writel(g, pbdma_intr_1_r(pbdma_id), pbdma_intr_1);
|
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;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user