]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: separate API to get failing engine data
authorDeepak Nibade <dnibade@nvidia.com>
Tue, 8 Sep 2015 15:41:51 +0000 (21:11 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Thu, 5 Nov 2015 07:19:10 +0000 (23:19 -0800)
In gk20a_fifo_handle_sched_error(), we currently have a sequence
to identify failing engine (stuck on context switch) and
corresponding failing channel with its type

Separate out this sequence in new API
gk20a_fifo_get_failing_engine_data() so that it can be
reused from else where too

Bug 200133289

Change-Id: I3cef395170cf8990c014c7505c798fd6f2e37921
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/797070
(cherry picked from commit d642f1244638bbdf265e6f81ffa2614a419cbd7f)
Reviewed-on: http://git-master/r/806564
Signed-off-by: Thomas Fleury <tfleury@nvidia.com>
Change-Id: I8780a2d135c3ff6bfbf9755b7c27978458b673fd
Reviewed-on: http://git-master/r/815982
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
drivers/gpu/nvgpu/gk20a/fifo_gk20a.h

index b6c0bea2b66edb1f836f6f5ff5b2366faffc59bc..f2588a49e14a7683e3768a1f17fe67c6b582c928 100644 (file)
@@ -34,6 +34,7 @@
 #include "hw_top_gk20a.h"
 #include "hw_mc_gk20a.h"
 #include "hw_gr_gk20a.h"
+#define FECS_METHOD_WFI_RESTORE 0x80000
 
 static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
                                            u32 hw_chid, bool add,
@@ -1331,16 +1332,13 @@ int gk20a_fifo_force_reset_ch(struct channel_gk20a *ch, bool verbose)
        return 0;
 }
 
-static bool gk20a_fifo_handle_sched_error(struct gk20a *g)
+u32 gk20a_fifo_get_failing_engine_data(struct gk20a *g,
+                       int *__id, bool *__is_tsg)
 {
-       u32 sched_error;
-       u32 engine_id;
+       u32 engine_id = -1;
        int id = -1;
-       bool non_chid = false;
-       bool ret = false;
-
-       /* read the scheduler error register */
-       sched_error = gk20a_readl(g, fifo_intr_sched_error_r());
+       bool is_tsg = false;
+       u32 mailbox2;
 
        for (engine_id = 0; engine_id < g->fifo.max_engines; engine_id++) {
                u32 status = gk20a_readl(g, fifo_engine_status_r(engine_id));
@@ -1360,17 +1358,46 @@ static bool gk20a_fifo_handle_sched_error(struct gk20a *g)
                        || ctx_status ==
                                fifo_engine_status_ctx_status_ctxsw_load_v());
 
-               if (failing_engine) {
-                       id = (ctx_status ==
-                               fifo_engine_status_ctx_status_ctxsw_load_v()) ?
-                               fifo_engine_status_next_id_v(status) :
-                               fifo_engine_status_id_v(status);
-                       non_chid = fifo_pbdma_status_id_type_v(status) !=
-                               fifo_pbdma_status_id_type_chid_v();
-                       break;
+               if (!failing_engine)
+                       continue;
+
+               if (ctx_status ==
+                               fifo_engine_status_ctx_status_ctxsw_load_v()) {
+                       id = fifo_engine_status_next_id_v(status);
+                       is_tsg = fifo_pbdma_status_id_type_v(status)
+                               != fifo_pbdma_status_id_type_chid_v();
+               } else if (ctx_status ==
+                              fifo_engine_status_ctx_status_ctxsw_switch_v()) {
+                       mailbox2 = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(2));
+                       if (mailbox2 & FECS_METHOD_WFI_RESTORE)
+                               id = fifo_engine_status_next_id_v(status);
+                       else
+                               id = fifo_engine_status_id_v(status);
+               } else {
+                       id = fifo_engine_status_id_v(status);
                }
+               break;
        }
 
+       *__id = id;
+       *__is_tsg = is_tsg;
+
+       return engine_id;
+}
+
+static bool gk20a_fifo_handle_sched_error(struct gk20a *g)
+{
+       u32 sched_error;
+       u32 engine_id;
+       int id = -1;
+       bool is_tsg = false;
+       bool ret = false;
+
+       /* read the scheduler error register */
+       sched_error = gk20a_readl(g, fifo_intr_sched_error_r());
+
+       engine_id = gk20a_fifo_get_failing_engine_data(g, &id, &is_tsg);
+
        /* could not find the engine - should never happen */
        if (unlikely(engine_id >= g->fifo.max_engines)) {
                gk20a_err(dev_from_gk20a(g), "fifo sched error : 0x%08x, failed to find engine\n",
@@ -1384,7 +1411,7 @@ static bool gk20a_fifo_handle_sched_error(struct gk20a *g)
                struct fifo_gk20a *f = &g->fifo;
                struct channel_gk20a *ch = &f->channel[id];
 
-               if (non_chid) {
+               if (is_tsg) {
                        gk20a_fifo_recover(g, BIT(engine_id), id, true, true);
                        ret = true;
                        goto err;
@@ -1417,7 +1444,7 @@ static bool gk20a_fifo_handle_sched_error(struct gk20a *g)
        }
 
        gk20a_err(dev_from_gk20a(g), "fifo sched error : 0x%08x, engine=%u, %s=%d",
-               sched_error, engine_id, non_chid ? "non-ch" : "ch", id);
+               sched_error, engine_id, is_tsg ? "tsg" : "ch", id);
 
 err:
        return ret;
index ff5e8529265b00b996f1fb15c5caca3047946e77..a867691e86c41f1ee1cd521c076038ef719df959 100644 (file)
@@ -178,5 +178,7 @@ void fifo_gk20a_finish_mmu_fault_handling(struct gk20a *g,
 int gk20a_fifo_wait_engine_idle(struct gk20a *g);
 u32 gk20a_fifo_engine_interrupt_mask(struct gk20a *g);
 u32 gk20a_fifo_get_pbdma_signature(struct gk20a *g);
+u32 gk20a_fifo_get_failing_engine_data(struct gk20a *g,
+               int *__id, bool *__is_tsg);
 
 #endif /*__GR_GK20A_H__*/