From 3df84a13d142b20f63970b9523143dd0e46c2ff9 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Wed, 9 Apr 2014 13:33:31 +0300 Subject: gpu: nvgpu: Make trigger mmu fault GPU specific Add abstraction for triggering fake MMU fault, and a gk20a implementation. Also adds recovery to FE hardware warning exception to make testing easier. Bug 1495967 Change-Id: I6703cff37900a4c4592023423f9c0b31a8928db2 Signed-off-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 2 +- drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 2 +- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 76 +++++++++++++++++++-------------- drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 1 + drivers/gpu/nvgpu/gk20a/gk20a.h | 2 + drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 1 + 6 files changed, 51 insertions(+), 33 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 6056f558..4cce7260 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -1953,7 +1953,7 @@ clean_up: return ret; } -void gk20a_init_fifo(struct gpu_ops *gops) +void gk20a_init_channel(struct gpu_ops *gops) { gops->fifo.bind_channel = channel_gk20a_bind; } diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 429db85d..47fc714c 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h @@ -167,6 +167,6 @@ int gk20a_channel_release(struct inode *inode, struct file *filp); struct channel_gk20a *gk20a_get_channel_from_file(int fd); void gk20a_channel_update(struct channel_gk20a *c, int nr_completed); -void gk20a_init_fifo(struct gpu_ops *gops); +void gk20a_init_channel(struct gpu_ops *gops); #endif /*__CHANNEL_GK20A_H__*/ diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 5575b995..f1987ed5 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -1092,43 +1092,15 @@ static void gk20a_fifo_get_faulty_channel(struct gk20a *g, int engine_id, fifo_engine_status_id_v(status); } -void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, - bool verbose) +static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, + unsigned long engine_ids) { unsigned long end_jiffies = jiffies + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); unsigned long delay = GR_IDLE_CHECK_DEFAULT; - unsigned long engine_id, i; - unsigned long _engine_ids = __engine_ids; - unsigned long engine_ids = 0; + unsigned long engine_id; int ret; - if (verbose) - gk20a_debug_dump(g->dev); - - /* store faulted engines in advance */ - g->fifo.mmu_fault_engines = 0; - for_each_set_bit(engine_id, &_engine_ids, 32) { - bool ref_type_ch; - int ref_chid; - gk20a_fifo_get_faulty_channel(g, engine_id, &ref_chid, - &ref_type_ch); - - /* Reset *all* engines that use the - * same channel as faulty engine */ - for (i = 0; i < g->fifo.max_engines; i++) { - bool type_ch; - u32 chid; - gk20a_fifo_get_faulty_channel(g, i, &chid, &type_ch); - if (ref_type_ch == type_ch && ref_chid == chid) { - engine_ids |= BIT(i); - g->fifo.mmu_fault_engines |= - BIT(gk20a_engine_id_to_mmu_id(i)); - } - } - - } - /* trigger faults for all bad engines */ for_each_set_bit(engine_id, &engine_ids, 32) { if (engine_id > g->fifo.max_engines) { @@ -1164,6 +1136,42 @@ void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, gk20a_writel(g, fifo_trigger_mmu_fault_r(engine_id), 0); } +void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, + bool verbose) +{ + unsigned long engine_id, i; + unsigned long _engine_ids = __engine_ids; + unsigned long engine_ids = 0; + + if (verbose) + gk20a_debug_dump(g->dev); + + /* store faulted engines in advance */ + g->fifo.mmu_fault_engines = 0; + for_each_set_bit(engine_id, &_engine_ids, 32) { + bool ref_type_ch; + int ref_chid; + gk20a_fifo_get_faulty_channel(g, engine_id, &ref_chid, + &ref_type_ch); + + /* Reset *all* engines that use the + * same channel as faulty engine */ + for (i = 0; i < g->fifo.max_engines; i++) { + bool type_ch; + u32 chid; + gk20a_fifo_get_faulty_channel(g, i, &chid, &type_ch); + if (ref_type_ch == type_ch && ref_chid == chid) { + engine_ids |= BIT(i); + g->fifo.mmu_fault_engines |= + BIT(gk20a_engine_id_to_mmu_id(i)); + } + } + + } + + g->ops.fifo.trigger_mmu_fault(g, engine_ids); +} + static bool gk20a_fifo_handle_sched_error(struct gk20a *g) { @@ -1834,3 +1842,9 @@ bool gk20a_fifo_mmu_fault_pending(struct gk20a *g) else return false; } + +void gk20a_init_fifo(struct gpu_ops *gops) +{ + gk20a_init_channel(gops); + gops->fifo.trigger_mmu_fault = gk20a_fifo_trigger_mmu_fault; +} diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 051acda2..078ae8f0 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h @@ -158,6 +158,7 @@ int gk20a_fifo_suspend(struct gk20a *g); bool gk20a_fifo_mmu_fault_pending(struct gk20a *g); void gk20a_fifo_recover(struct gk20a *g, u32 engine_ids, bool verbose); int gk20a_init_fifo_reset_enable_hw(struct gk20a *g); +void gk20a_init_fifo(struct gpu_ops *gops); void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g, unsigned long fault_id); diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 7aca186e..7aa10692 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -137,6 +137,8 @@ struct gpu_ops { } clock_gating; struct { void (*bind_channel)(struct channel_gk20a *ch_gk20a); + void (*trigger_mmu_fault)(struct gk20a *g, + unsigned long engine_ids); } fifo; struct pmu_v { /*used for change of enum zbc update cmd id from ver 0 to ver1*/ diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index ced1f62f..b2a92f81 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -5333,6 +5333,7 @@ int gk20a_gr_isr(struct gk20a *g) u32 fe = gk20a_readl(g, gr_fe_hww_esr_r()); gk20a_dbg(gpu_dbg_intr, "fe warning %08x\n", fe); gk20a_writel(g, gr_fe_hww_esr_r(), fe); + need_reset |= -EFAULT; } /* check if a gpc exception has occurred */ -- cgit v1.2.2