]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: Add CBC clean and invalidate
authorArto Merilainen <amerilainen@nvidia.com>
Wed, 9 Apr 2014 12:04:33 +0000 (15:04 +0300)
committerGerrit Code Review <gerrit2@nvidia.com>
Fri, 11 Apr 2014 07:13:04 +0000 (00:13 -0700)
Bug 1409151

Change-Id: I232af159d402f818cf972498d721c3b57846ce74
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
drivers/gpu/nvgpu/gk20a/gk20a.h
drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h
drivers/gpu/nvgpu/gk20a/ltc_gk20a.c
drivers/gpu/nvgpu/gk20a/mm_gk20a.c

index 3bc53992d17563d9dca43bae55b0e26f0561f14f..7aca186ed5dbe9b4a2c419c7752d157c05740c68 100644 (file)
@@ -56,12 +56,19 @@ struct cooling_device_gk20a {
        struct gk20a *g;
 };
 
+enum gk20a_cbc_op {
+       gk20a_cbc_op_clear,
+       gk20a_cbc_op_clean,
+       gk20a_cbc_op_invalidate,
+};
+
 struct gpu_ops {
        struct {
                int (*determine_L2_size_bytes)(struct gk20a *gk20a);
                void (*set_max_ways_evict_last)(struct gk20a *g, u32 max_ways);
                int (*init_comptags)(struct gk20a *g, struct gr_gk20a *gr);
-               int (*clear_comptags)(struct gk20a *g, u32 min, u32 max);
+               int (*cbc_ctrl)(struct gk20a *g, enum gk20a_cbc_op op,
+                               u32 min, u32 max);
                void (*set_zbc_color_entry)(struct gk20a *g,
                                            struct zbc_entry *color_val,
                                            u32 index);
index 8ea4ef714d3cad485c14ab3138c1a41d650f20bf..f60b34e20af106405f49990ccb4fa95705b3576c 100644 (file)
@@ -82,6 +82,14 @@ static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void)
 {
        return 0x0017e8c8;
 }
+static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void)
+{
+       return 0x1;
+}
+static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void)
+{
+       return 0x2;
+}
 static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r)
 {
        return (r >> 2) & 0x1;
index 8450f664ac3d828b491551cf6d95c0a61fec03d4..74475d7af0115e914862274ed70b9f37449a9342 100644 (file)
@@ -108,10 +108,12 @@ static int gk20a_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr)
        return 0;
 }
 
-static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max)
+static int gk20a_ltc_cbc_ctrl(struct gk20a *g, enum gk20a_cbc_op op,
+                             u32 min, u32 max)
 {
+       int err = 0;
        struct gr_gk20a *gr = &g->gr;
-       u32 fbp, slice, ctrl1, val;
+       u32 fbp, slice, ctrl1, val, hw_op = 0;
        unsigned long end_jiffies = jiffies +
                msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
        u32 delay = GR_IDLE_CHECK_DEFAULT;
@@ -124,13 +126,24 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max)
        if (gr->compbit_store.size == 0)
                return 0;
 
-       gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(),
-                    ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min));
-       gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(),
-                    ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max));
+       mutex_lock(&g->mm.l2_op_lock);
+
+       if (op == gk20a_cbc_op_clear) {
+               gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(),
+                            ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min));
+               gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(),
+                            ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max));
+               hw_op = ltc_ltcs_ltss_cbc_ctrl1_clear_active_f();
+       } else if (op == gk20a_cbc_op_clean) {
+               hw_op = ltc_ltcs_ltss_cbc_ctrl1_clean_active_f();
+       } else if (op == gk20a_cbc_op_invalidate) {
+               hw_op = ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f();
+       } else {
+               BUG_ON(1);
+       }
+
        gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(),
-                    gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) |
-                    ltc_ltcs_ltss_cbc_ctrl1_clear_active_f());
+                    gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | hw_op);
 
        for (fbp = 0; fbp < gr->num_fbps; fbp++) {
                for (slice = 0; slice < slices_per_fbp; slice++) {
@@ -143,8 +156,7 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max)
 
                        do {
                                val = gk20a_readl(g, ctrl1);
-                               if (ltc_ltcs_ltss_cbc_ctrl1_clear_v(val) !=
-                                   ltc_ltcs_ltss_cbc_ctrl1_clear_active_v())
+                               if (!(val & hw_op))
                                        break;
 
                                usleep_range(delay, delay * 2);
@@ -157,11 +169,13 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max)
                        if (!time_before(jiffies, end_jiffies)) {
                                gk20a_err(dev_from_gk20a(g),
                                           "comp tag clear timeout\n");
-                               return -EBUSY;
+                               err = -EBUSY;
+                               goto out;
                        }
                }
        }
-
+out:
+       mutex_unlock(&g->mm.l2_op_lock);
        return 0;
 }
 
@@ -200,7 +214,7 @@ void gk20a_init_ltc(struct gpu_ops *gops)
        gops->ltc.determine_L2_size_bytes = gk20a_determine_L2_size_bytes;
        gops->ltc.set_max_ways_evict_last = gk20a_ltc_set_max_ways_evict_last;
        gops->ltc.init_comptags = gk20a_ltc_init_comptags;
-       gops->ltc.clear_comptags = gk20a_ltc_clear_comptags;
+       gops->ltc.cbc_ctrl = gk20a_ltc_cbc_ctrl;
        gops->ltc.set_zbc_color_entry = gk20a_ltc_set_zbc_color_entry;
        gops->ltc.set_zbc_depth_entry = gk20a_ltc_set_zbc_depth_entry;
        gops->ltc.clear_zbc_color_entry = gk20a_ltc_clear_zbc_color_entry;
index c6883b6177278fcd195cdc94819a995d65f37cc5..210fe1b3b147ac06277b4c73cfbc02ced62ff18c 100644 (file)
@@ -1380,7 +1380,7 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
                        gk20a_get_comptags(d, dmabuf, &comptags);
 
                        /* init/clear the ctag buffer */
-                       g->ops.ltc.clear_comptags(g,
+                       g->ops.ltc.cbc_ctrl(g, gk20a_cbc_op_clear,
                                          comptags.offset,
                                          comptags.offset + comptags.lines - 1);
                }