Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/v3d: Fix Indirect Dispatch configuration for V3D 7.1.6 and later

This commit is a resubmission of commit 1fe1c66274fb ("drm/v3d: Fix
Indirect Dispatch configuration for V3D 7.1.6 and later"), which was
accidentally reverted by commit 91dae758bdb8 ("Merge tag
'drm-misc-next-2024-08-01' of https://gitlab.freedesktop.org/drm/misc/kernel
into drm-next"), likely due to an unfortunate conflict resolution.

From the original commit message:

```
`args->cfg[4]` is configured in Indirect Dispatch using the number of
batches. Currently, for all V3D tech versions, `args->cfg[4]` equals the
number of batches subtracted by 1. But, for V3D 7.1.6 and later, we must not
subtract 1 from the number of batches.

Implement the fix by checking the V3D tech version and revision.

Fixes several `dEQP-VK.synchronization*` CTS tests related to Indirect Dispatch.
```

Fixes: 91dae758bdb8 ("Merge tag 'drm-misc-next-2024-08-01' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next")
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Link: https://lore.kernel.org/r/20250409205051.9639-1-mcanal@igalia.com

+13 -3
+13 -3
drivers/gpu/drm/v3d/v3d_sched.c
··· 428 428 struct v3d_bo *bo = to_v3d_bo(job->base.bo[0]); 429 429 struct v3d_bo *indirect = to_v3d_bo(indirect_csd->indirect); 430 430 struct drm_v3d_submit_csd *args = &indirect_csd->job->args; 431 - u32 *wg_counts; 431 + struct v3d_dev *v3d = job->base.v3d; 432 + u32 num_batches, *wg_counts; 432 433 433 434 v3d_get_bo_vaddr(bo); 434 435 v3d_get_bo_vaddr(indirect); ··· 442 441 args->cfg[0] = wg_counts[0] << V3D_CSD_CFG012_WG_COUNT_SHIFT; 443 442 args->cfg[1] = wg_counts[1] << V3D_CSD_CFG012_WG_COUNT_SHIFT; 444 443 args->cfg[2] = wg_counts[2] << V3D_CSD_CFG012_WG_COUNT_SHIFT; 445 - args->cfg[4] = DIV_ROUND_UP(indirect_csd->wg_size, 16) * 446 - (wg_counts[0] * wg_counts[1] * wg_counts[2]) - 1; 444 + 445 + num_batches = DIV_ROUND_UP(indirect_csd->wg_size, 16) * 446 + (wg_counts[0] * wg_counts[1] * wg_counts[2]); 447 + 448 + /* V3D 7.1.6 and later don't subtract 1 from the number of batches */ 449 + if (v3d->ver < 71 || (v3d->ver == 71 && v3d->rev < 6)) 450 + args->cfg[4] = num_batches - 1; 451 + else 452 + args->cfg[4] = num_batches; 453 + 454 + WARN_ON(args->cfg[4] == ~0); 447 455 448 456 for (int i = 0; i < 3; i++) { 449 457 /* 0xffffffff indicates that the uniform rewrite is not needed */