From bea4bb915a4a15042057a21170bcc2058f2bfb16 Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Tue, 10 Jun 2014 13:40:12 -0700 Subject: gpu: nvgpu: Implement L2 flush in fifo recovery Implement a full L2 flush (clean and invalidate) for gm20b in the fifo recovery path. Bug 1512176 Change-Id: Ibf89ede9cca65a6868ebff89825869053302a007 Signed-off-by: Alex Waterman Reviewed-on: http://git-master/r/416435 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gm20b/ltc_gm20b.c | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (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 a5056289..1f9bf44c 100644 --- a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c @@ -250,6 +250,53 @@ u32 gm20b_ltc_cbc_fix_config(struct gk20a *g, int base) return base; } +/* + * Performs a full flush of the L2 cache. + */ +void gm20b_flush_ltc(struct gk20a *g) +{ + u32 op_pending; + + /* Clean... */ + gk20a_writel(g, ltc_ltcs_ltss_tstg_cmgmt1_r(), + ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f() | + ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f() | + ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f() | + ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f() | + ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f() | + ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f()); + + /* Wait on each LTC individually. */ + do { + op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt1_r()); + } while (op_pending & + ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f()); + + do { + op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt1_r()); + } while (op_pending & + ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f()); + + /* And invalidate. */ + gk20a_writel(g, ltc_ltcs_ltss_tstg_cmgmt0_r(), + ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f() | + ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f() | + ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f() | + ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f() | + ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f()); + + /* Wait on each LTC individually. */ + do { + op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt0_r()); + } while (op_pending & + ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f()); + + do { + op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt0_r()); + } while (op_pending & + ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f()); +} + void gm20b_init_ltc(struct gpu_ops *gops) { /* Gk20a reused ops. */ @@ -266,4 +313,5 @@ void gm20b_init_ltc(struct gpu_ops *gops) gops->ltc.elpg_flush = gm20b_ltc_g_elpg_flush_locked; gops->ltc.isr = gm20b_ltc_isr; gops->ltc.cbc_fix_config = gm20b_ltc_cbc_fix_config; + gops->ltc.flush = gm20b_flush_ltc; } -- cgit v1.2.2