From 824e256c2af97a325475a3601cde0f3d6e3fc2a3 Mon Sep 17 00:00:00 2001 From: Bo Yan Date: Fri, 18 Apr 2014 17:22:38 -0700 Subject: gnu: nvgpu: gm20b: CBC clean and invalidate the CBC clean and invalidate is done for gk20a for bug 1409151, now it's time to do the same fo gm20b. the text of this change is strictly copied from gk20a, simply to make build pass. Change-Id: Id717cb1e2ca0fa3f8483c3fd40d7629a9cc85ec9 Signed-off-by: Bo Yan --- drivers/gpu/nvgpu/gm20b/ltc_gm20b.c | 39 ++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/nvgpu/gm20b/ltc_gm20b.c') diff --git a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c index 134ac491..305e28c2 100644 --- a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c @@ -103,10 +103,12 @@ static int gm20b_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr) return 0; } -static int gm20b_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) +static int gm20b_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; @@ -118,13 +120,23 @@ static int gm20b_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_ltc; slice++) { @@ -137,8 +149,7 @@ static int gm20b_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); @@ -151,11 +162,13 @@ static int gm20b_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; } @@ -192,6 +205,6 @@ void gm20b_init_ltc(struct gpu_ops *gops) /* GM20b specific ops. */ gops->ltc.init_fs_state = gm20b_ltc_init_fs_state; gops->ltc.init_comptags = gm20b_ltc_init_comptags; - gops->ltc.clear_comptags = gm20b_ltc_clear_comptags; + gops->ltc.cbc_ctrl = gm20b_ltc_cbc_ctrl; gops->ltc.elpg_flush = gk20a_mm_g_elpg_flush_locked; } -- cgit v1.2.2