diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/ltc_gm20b.c | 48 |
3 files changed, 52 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index f246c73e..cba1f0fd 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -1200,6 +1200,9 @@ void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, | |||
1200 | if (verbose) | 1200 | if (verbose) |
1201 | gk20a_debug_dump(g->dev); | 1201 | gk20a_debug_dump(g->dev); |
1202 | 1202 | ||
1203 | if (g->ops.ltc.flush) | ||
1204 | g->ops.ltc.flush(g); | ||
1205 | |||
1203 | /* store faulted engines in advance */ | 1206 | /* store faulted engines in advance */ |
1204 | g->fifo.mmu_fault_engines = 0; | 1207 | g->fifo.mmu_fault_engines = 0; |
1205 | for_each_set_bit(engine_id, &_engine_ids, 32) { | 1208 | for_each_set_bit(engine_id, &_engine_ids, 32) { |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index d8ceecd7..726994ff 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -82,6 +82,7 @@ struct gpu_ops { | |||
82 | void (*elpg_flush)(struct gk20a *g); | 82 | void (*elpg_flush)(struct gk20a *g); |
83 | void (*isr)(struct gk20a *g); | 83 | void (*isr)(struct gk20a *g); |
84 | u32 (*cbc_fix_config)(struct gk20a *g, int base); | 84 | u32 (*cbc_fix_config)(struct gk20a *g, int base); |
85 | void (*flush)(struct gk20a *g); | ||
85 | } ltc; | 86 | } ltc; |
86 | struct { | 87 | struct { |
87 | int (*init_fs_state)(struct gk20a *g); | 88 | int (*init_fs_state)(struct gk20a *g); |
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) | |||
250 | return base; | 250 | return base; |
251 | } | 251 | } |
252 | 252 | ||
253 | /* | ||
254 | * Performs a full flush of the L2 cache. | ||
255 | */ | ||
256 | void gm20b_flush_ltc(struct gk20a *g) | ||
257 | { | ||
258 | u32 op_pending; | ||
259 | |||
260 | /* Clean... */ | ||
261 | gk20a_writel(g, ltc_ltcs_ltss_tstg_cmgmt1_r(), | ||
262 | ltc_ltcs_ltss_tstg_cmgmt1_clean_pending_f() | | ||
263 | ltc_ltcs_ltss_tstg_cmgmt1_max_cycles_between_cleans_3_f() | | ||
264 | ltc_ltcs_ltss_tstg_cmgmt1_clean_wait_for_fb_to_pull_true_f() | | ||
265 | ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_last_class_true_f() | | ||
266 | ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_normal_class_true_f() | | ||
267 | ltc_ltcs_ltss_tstg_cmgmt1_clean_evict_first_class_true_f()); | ||
268 | |||
269 | /* Wait on each LTC individually. */ | ||
270 | do { | ||
271 | op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt1_r()); | ||
272 | } while (op_pending & | ||
273 | ltc_ltc0_ltss_tstg_cmgmt1_clean_pending_f()); | ||
274 | |||
275 | do { | ||
276 | op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt1_r()); | ||
277 | } while (op_pending & | ||
278 | ltc_ltc1_ltss_tstg_cmgmt1_clean_pending_f()); | ||
279 | |||
280 | /* And invalidate. */ | ||
281 | gk20a_writel(g, ltc_ltcs_ltss_tstg_cmgmt0_r(), | ||
282 | ltc_ltcs_ltss_tstg_cmgmt0_invalidate_pending_f() | | ||
283 | ltc_ltcs_ltss_tstg_cmgmt0_max_cycles_between_invalidates_3_f() | | ||
284 | ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_last_class_true_f() | | ||
285 | ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_normal_class_true_f() | | ||
286 | ltc_ltcs_ltss_tstg_cmgmt0_invalidate_evict_first_class_true_f()); | ||
287 | |||
288 | /* Wait on each LTC individually. */ | ||
289 | do { | ||
290 | op_pending = gk20a_readl(g, ltc_ltc0_ltss_tstg_cmgmt0_r()); | ||
291 | } while (op_pending & | ||
292 | ltc_ltc0_ltss_tstg_cmgmt0_invalidate_pending_f()); | ||
293 | |||
294 | do { | ||
295 | op_pending = gk20a_readl(g, ltc_ltc1_ltss_tstg_cmgmt0_r()); | ||
296 | } while (op_pending & | ||
297 | ltc_ltc1_ltss_tstg_cmgmt0_invalidate_pending_f()); | ||
298 | } | ||
299 | |||
253 | void gm20b_init_ltc(struct gpu_ops *gops) | 300 | void gm20b_init_ltc(struct gpu_ops *gops) |
254 | { | 301 | { |
255 | /* Gk20a reused ops. */ | 302 | /* Gk20a reused ops. */ |
@@ -266,4 +313,5 @@ void gm20b_init_ltc(struct gpu_ops *gops) | |||
266 | gops->ltc.elpg_flush = gm20b_ltc_g_elpg_flush_locked; | 313 | gops->ltc.elpg_flush = gm20b_ltc_g_elpg_flush_locked; |
267 | gops->ltc.isr = gm20b_ltc_isr; | 314 | gops->ltc.isr = gm20b_ltc_isr; |
268 | gops->ltc.cbc_fix_config = gm20b_ltc_cbc_fix_config; | 315 | gops->ltc.cbc_fix_config = gm20b_ltc_cbc_fix_config; |
316 | gops->ltc.flush = gm20b_flush_ltc; | ||
269 | } | 317 | } |