]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: Check bar1 bind
authorTerje Bergstrom <tbergstrom@nvidia.com>
Mon, 31 Mar 2014 09:36:55 +0000 (12:36 +0300)
committerTerje Bergstrom <tbergstrom@nvidia.com>
Tue, 1 Apr 2014 05:35:29 +0000 (22:35 -0700)
Add two fb flushes after bar1 bind. This should hang the thread instead
of whole system in case there is a BAR1 hang.

Change-Id: I2385a243711219297b889daa30c9fc81106e5825
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/390183

drivers/gpu/nvgpu/gk20a/mm_gk20a.c
drivers/gpu/nvgpu/gk20a/mm_gk20a.h

index b22df5e87de6c60953fa7360ee5a698d49a21211..208e52918dfa3eaf79c141ee0b7c670671862022 100644 (file)
@@ -377,13 +377,12 @@ static int gk20a_init_mm_setup_hw(struct gk20a *g)
        inst_pa = (u32)(inst_pa >> bar1_instance_block_shift_gk20a());
        gk20a_dbg_info("bar1 inst block ptr: 0x%08x",  (u32)inst_pa);
 
-       /* this is very early in init... can we defer this? */
-       {
-               gk20a_writel(g, bus_bar1_block_r(),
-                            bus_bar1_block_target_vid_mem_f() |
-                            bus_bar1_block_mode_virtual_f() |
-                            bus_bar1_block_ptr_f(inst_pa));
-       }
+       gk20a_writel(g, bus_bar1_block_r(),
+                    bus_bar1_block_target_vid_mem_f() |
+                    bus_bar1_block_mode_virtual_f() |
+                    bus_bar1_block_ptr_f(inst_pa));
+       if (gk20a_mm_fb_flush(g) || gk20a_mm_fb_flush(g))
+               return -EBUSY;
 
        gk20a_dbg_fn("done");
        return 0;
@@ -2702,11 +2701,12 @@ clean_up:
        return err;
 }
 
-void gk20a_mm_fb_flush(struct gk20a *g)
+int gk20a_mm_fb_flush(struct gk20a *g)
 {
        struct mm_gk20a *mm = &g->mm;
        u32 data;
        s32 retry = 100;
+       int ret = 0;
 
        gk20a_dbg_fn("");
 
@@ -2734,11 +2734,15 @@ void gk20a_mm_fb_flush(struct gk20a *g)
                        break;
        } while (retry >= 0 || !tegra_platform_is_silicon());
 
-       if (retry < 0)
+       if (retry < 0) {
                gk20a_warn(dev_from_gk20a(g),
                        "fb_flush too many retries");
+               ret = -EBUSY;
+       }
 
        mutex_unlock(&mm->l2_op_lock);
+
+       return ret;
 }
 
 static void gk20a_mm_l2_invalidate_locked(struct gk20a *g)
index 23d15c232763b2f96ffc262a20bfe9f5a8059d5b..cdbab13847e1fd0072c1045df7b76a7dc220abf7 100644 (file)
@@ -287,7 +287,7 @@ int gk20a_init_mm_setup_sw(struct gk20a *g);
 int gk20a_init_bar1_vm(struct mm_gk20a *mm);
 int gk20a_init_pmu_vm(struct mm_gk20a *mm);
 
-void gk20a_mm_fb_flush(struct gk20a *g);
+int gk20a_mm_fb_flush(struct gk20a *g);
 void gk20a_mm_l2_flush(struct gk20a *g, bool invalidate);
 void gk20a_mm_l2_invalidate(struct gk20a *g);