summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gm20b/ltc_gm20b.c22
1 files changed, 22 insertions, 0 deletions
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 @@
14 */ 14 */
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/jiffies.h>
17 18
18#include "hw_ltc_gm20b.h" 19#include "hw_ltc_gm20b.h"
19#include "hw_top_gm20b.h" 20#include "hw_top_gm20b.h"
@@ -256,6 +257,19 @@ u32 gm20b_ltc_cbc_fix_config(struct gk20a *g, int base)
256void gm20b_flush_ltc(struct gk20a *g) 257void gm20b_flush_ltc(struct gk20a *g)
257{ 258{
258 u32 op_pending; 259 u32 op_pending;
260 unsigned long now, timeout;
261
262#define __timeout_init() \
263 do { \
264 now = jiffies; timeout = now + HZ; \
265 } while (0)
266#define __timeout_check() \
267 do { \
268 if (tegra_platform_is_silicon() && time_after(now, timeout)) { \
269 gk20a_err(dev_from_gk20a(g), "L2 flush timeout!"); \
270 break; \
271 } \
272 } while (0)
259 273
260 /* Clean... */ 274 /* Clean... */
261 gk20a_writel(g, ltc_ltcs_ltss_tstg_cmgmt1_r(), 275 gk20a_writel(g, ltc_ltcs_ltss_tstg_cmgmt1_r(),
@@ -267,13 +281,17 @@ void gm20b_flush_ltc(struct gk20a *g)
267 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f()); 281 ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f());
268 282
269 /* Wait on each LTC individually. */ 283 /* Wait on each LTC individually. */
284 __timeout_init();
270 do { 285 do {
271 op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt1_r()); 286 op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt1_r());
287 __timeout_check();
272 } while (op_pending & 288 } while (op_pending &
273 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f()); 289 ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f());
274 290
291 __timeout_init();
275 do { 292 do {
276 op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt1_r()); 293 op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt1_r());
294 __timeout_check();
277 } while (op_pending & 295 } while (op_pending &
278 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f()); 296 ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f());
279 297
@@ -286,13 +304,17 @@ void gm20b_flush_ltc(struct gk20a *g)
286 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f()); 304 ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f());
287 305
288 /* Wait on each LTC individually. */ 306 /* Wait on each LTC individually. */
307 __timeout_init();
289 do { 308 do {
290 op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt0_r()); 309 op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt0_r());
310 __timeout_check();
291 } while (op_pending & 311 } while (op_pending &
292 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f()); 312 ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f());
293 313
314 __timeout_init();
294 do { 315 do {
295 op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt0_r()); 316 op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt0_r());
317 __timeout_check();
296 } while (op_pending & 318 } while (op_pending &
297 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f()); 319 ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f());
298} 320}