From 2680d6be576ce2c1b74f03e6e4cc5cbf321ef2bc Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Mon, 16 Jun 2014 12:41:24 -0700 Subject: gpu: nvgpu: Add timeout to L2 flush Add a timeout mechanism to the L2 flushing code for gm20b. Previously the code could spin forever in a loop if some issue were to occur with the L2 causing the flush to fail. Change-Id: I742c7671bac92aeb8e9674c43d30c45b2de4a836 Signed-off-by: Alex Waterman Reviewed-on: http://git-master/r/423842 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gm20b/ltc_gm20b.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c index 1f9bf44c..7a2bb5fd 100644 --- a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c @@ -14,6 +14,7 @@ */ #include +#include #include "hw_ltc_gm20b.h" #include "hw_top_gm20b.h" @@ -256,6 +257,19 @@ u32 gm20b_ltc_cbc_fix_config(struct gk20a *g, int base) void gm20b_flush_ltc(struct gk20a *g) { u32 op_pending; + unsigned long now, timeout; + +#define __timeout_init() \ + do { \ + now = jiffies; timeout = now + HZ; \ + } while (0) +#define __timeout_check() \ + do { \ + if (tegra_platform_is_silicon() && time_after(now, timeout)) { \ + gk20a_err(dev_from_gk20a(g), "L2 flush timeout!"); \ + break; \ + } \ + } while (0) /* Clean... */ gk20a_writel(g, ltc_ltcs_ltss_tstg_cmgmt1_r(), @@ -267,13 +281,17 @@ void gm20b_flush_ltc(struct gk20a *g) ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f()); /* Wait on each LTC individually. */ + __timeout_init(); do { op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt1_r()); + __timeout_check(); } while (op_pending & ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f()); + __timeout_init(); do { op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt1_r()); + __timeout_check(); } while (op_pending & ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f()); @@ -286,13 +304,17 @@ void gm20b_flush_ltc(struct gk20a *g) ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f()); /* Wait on each LTC individually. */ + __timeout_init(); do { op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt0_r()); + __timeout_check(); } while (op_pending & ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f()); + __timeout_init(); do { op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt0_r()); + __timeout_check(); } while (op_pending & ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f()); } -- cgit v1.2.2