From 38de7b64757cd683ec367b44976eda6bf41fb8c7 Mon Sep 17 00:00:00 2001 From: Arto Merilainen Date: Wed, 9 Apr 2014 15:04:33 +0300 Subject: gpu: nvgpu: Add CBC clean and invalidate Bug 1409151 Change-Id: I232af159d402f818cf972498d721c3b57846ce74 Signed-off-by: Arto Merilainen --- drivers/gpu/nvgpu/gk20a/gk20a.h | 9 +++++++- drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h | 8 +++++++ drivers/gpu/nvgpu/gk20a/ltc_gk20a.c | 40 +++++++++++++++++++++++----------- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 2 +- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 3bc53992..7aca186e 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -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); diff --git a/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h index 8ea4ef71..f60b34e2 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h @@ -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; diff --git a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c index 8450f664..74475d7a 100644 --- a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c @@ -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; diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index c6883b61..210fe1b3 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -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); } -- cgit v1.2.2