aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vc4/vc4_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_gem.c')
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 638540943c61..c94cce96544c 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -146,7 +146,7 @@ vc4_save_hang_state(struct drm_device *dev)
146 struct vc4_exec_info *exec[2]; 146 struct vc4_exec_info *exec[2];
147 struct vc4_bo *bo; 147 struct vc4_bo *bo;
148 unsigned long irqflags; 148 unsigned long irqflags;
149 unsigned int i, j, unref_list_count, prev_idx; 149 unsigned int i, j, k, unref_list_count;
150 150
151 kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL); 151 kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL);
152 if (!kernel_state) 152 if (!kernel_state)
@@ -182,7 +182,7 @@ vc4_save_hang_state(struct drm_device *dev)
182 return; 182 return;
183 } 183 }
184 184
185 prev_idx = 0; 185 k = 0;
186 for (i = 0; i < 2; i++) { 186 for (i = 0; i < 2; i++) {
187 if (!exec[i]) 187 if (!exec[i])
188 continue; 188 continue;
@@ -197,7 +197,7 @@ vc4_save_hang_state(struct drm_device *dev)
197 WARN_ON(!refcount_read(&bo->usecnt)); 197 WARN_ON(!refcount_read(&bo->usecnt));
198 refcount_inc(&bo->usecnt); 198 refcount_inc(&bo->usecnt);
199 drm_gem_object_get(&exec[i]->bo[j]->base); 199 drm_gem_object_get(&exec[i]->bo[j]->base);
200 kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->base; 200 kernel_state->bo[k++] = &exec[i]->bo[j]->base;
201 } 201 }
202 202
203 list_for_each_entry(bo, &exec[i]->unref_list, unref_head) { 203 list_for_each_entry(bo, &exec[i]->unref_list, unref_head) {
@@ -205,12 +205,12 @@ vc4_save_hang_state(struct drm_device *dev)
205 * because they are naturally unpurgeable. 205 * because they are naturally unpurgeable.
206 */ 206 */
207 drm_gem_object_get(&bo->base.base); 207 drm_gem_object_get(&bo->base.base);
208 kernel_state->bo[j + prev_idx] = &bo->base.base; 208 kernel_state->bo[k++] = &bo->base.base;
209 j++;
210 } 209 }
211 prev_idx = j + 1;
212 } 210 }
213 211
212 WARN_ON_ONCE(k != state->bo_count);
213
214 if (exec[0]) 214 if (exec[0])
215 state->start_bin = exec[0]->ct0ca; 215 state->start_bin = exec[0]->ct0ca;
216 if (exec[1]) 216 if (exec[1])
@@ -436,6 +436,19 @@ vc4_flush_caches(struct drm_device *dev)
436 VC4_SET_FIELD(0xf, V3D_SLCACTL_ICC)); 436 VC4_SET_FIELD(0xf, V3D_SLCACTL_ICC));
437} 437}
438 438
439static void
440vc4_flush_texture_caches(struct drm_device *dev)
441{
442 struct vc4_dev *vc4 = to_vc4_dev(dev);
443
444 V3D_WRITE(V3D_L2CACTL,
445 V3D_L2CACTL_L2CCLR);
446
447 V3D_WRITE(V3D_SLCACTL,
448 VC4_SET_FIELD(0xf, V3D_SLCACTL_T1CC) |
449 VC4_SET_FIELD(0xf, V3D_SLCACTL_T0CC));
450}
451
439/* Sets the registers for the next job to be actually be executed in 452/* Sets the registers for the next job to be actually be executed in
440 * the hardware. 453 * the hardware.
441 * 454 *
@@ -474,6 +487,14 @@ vc4_submit_next_render_job(struct drm_device *dev)
474 if (!exec) 487 if (!exec)
475 return; 488 return;
476 489
490 /* A previous RCL may have written to one of our textures, and
491 * our full cache flush at bin time may have occurred before
492 * that RCL completed. Flush the texture cache now, but not
493 * the instructions or uniforms (since we don't write those
494 * from an RCL).
495 */
496 vc4_flush_texture_caches(dev);
497
477 submit_cl(dev, 1, exec->ct1ca, exec->ct1ea); 498 submit_cl(dev, 1, exec->ct1ca, exec->ct1ea);
478} 499}
479 500