| @@ -530,13 +530,16 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 529 unmodified lines |
| 530 | 530 | struct drm_v3d_submit_cl *args = data; |
| 531 | 531 | struct v3d_bin_job *bin = NULL; |
| 532 | 532 | struct v3d_render_job *render; |
| 533 | + struct v3d_job *clean_job = NULL; |
| 534 | + struct v3d_job *last_job; |
| 533 | 535 | struct ww_acquire_ctx acquire_ctx; |
| 534 | 536 | int ret = 0; |
| 535 | 537 | |
| 536 | 538 | trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); |
| 537 | 539 | |
| 538 | | − if (args->pad != 0) { |
| 539 | | − DRM_INFO("pad must be zero: %d\n", args->pad); |
| 540 | + if (args->flags != 0 && |
| 541 | + args->flags != DRM_V3D_SUBMIT_CL_FLUSH_CACHE) { |
| 542 | + DRM_INFO("invalid flags: %d\n", args->flags); |
| 540 | 543 | return -EINVAL; |
| 541 | 544 | } |
| 542 | 545 | |
| @@ -576,12 +579,31 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 33 unmodified lines |
| 576 | 579 | bin->render = render; |
| 577 | 580 | } |
| 578 | 581 | |
| 579 | | − ret = v3d_lookup_bos(dev, file_priv, &render->base, |
| 582 | + if (args->flags & DRM_V3D_SUBMIT_CL_FLUSH_CACHE) { |
| 583 | + clean_job = kcalloc(1, sizeof(*clean_job), GFP_KERNEL); |
| 584 | + if (!clean_job) { |
| 585 | + ret = -ENOMEM; |
| 586 | + goto fail; |
| 587 | + } |
| 588 | + |
| 589 | + ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0); |
| 590 | + if (ret) { |
| 591 | + kfree(clean_job); |
| 592 | + clean_job = NULL; |
| 593 | + goto fail; |
| 594 | + } |
| 595 | + |
| 596 | + last_job = clean_job; |
| 597 | + } else { |
| 598 | + last_job = &render->base; |
| 599 | + } |
| 600 | + |
| 601 | + ret = v3d_lookup_bos(dev, file_priv, last_job, |
| 580 | 602 | args->bo_handles, args->bo_handle_count); |
| 581 | 603 | if (ret) |
| 582 | 604 | goto fail; |
| 583 | 605 | |
| 584 | | − ret = v3d_lock_bo_reservations(&render->base, &acquire_ctx); |
| 606 | + ret = v3d_lock_bo_reservations(last_job, &acquire_ctx); |
| 585 | 607 | if (ret) |
| 586 | 608 | goto fail; |
| 587 | 609 | |
| @@ -600,28 +622,44 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 12 unmodified lines |
| 600 | 622 | ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); |
| 601 | 623 | if (ret) |
| 602 | 624 | goto fail_unreserve; |
| 625 | + |
| 626 | + if (clean_job) { |
| 627 | + struct dma_fence *render_fence = |
| 628 | + dma_fence_get(render->base.done_fence); |
| 629 | + ret = drm_gem_fence_array_add(&clean_job->deps, render_fence); |
| 630 | + if (ret) |
| 631 | + goto fail_unreserve; |
| 632 | + ret = v3d_push_job(v3d_priv, clean_job, V3D_CACHE_CLEAN); |
| 633 | + if (ret) |
| 634 | + goto fail_unreserve; |
| 635 | + } |
| 636 | + |
| 603 | 637 | mutex_unlock(&v3d->sched_lock); |
| 604 | 638 | |
| 605 | 639 | v3d_attach_fences_and_unlock_reservation(file_priv, |
| 606 | | − &render->base, |
| 640 | + last_job, |
| 607 | 641 | &acquire_ctx, |
| 608 | 642 | args->out_sync, |
| 609 | | − render->base.done_fence); |
| 643 | + last_job->done_fence); |
| 610 | 644 | |
| 611 | 645 | if (bin) |
| 612 | 646 | v3d_job_put(&bin->base); |
| 613 | 647 | v3d_job_put(&render->base); |
| 648 | + if (clean_job) |
| 649 | + v3d_job_put(clean_job); |
| 614 | 650 | |
| 615 | 651 | return 0; |
| 616 | 652 | |
| 617 | 653 | fail_unreserve: |
| 618 | 654 | mutex_unlock(&v3d->sched_lock); |
| 619 | | − drm_gem_unlock_reservations(render->base.bo, |
| 620 | | − render->base.bo_count, &acquire_ctx); |
| 655 | + drm_gem_unlock_reservations(last_job->bo, |
| 656 | + last_job->bo_count, &acquire_ctx); |
| 621 | 657 | fail: |
| 622 | 658 | if (bin) |
| 623 | 659 | v3d_job_put(&bin->base); |
| 624 | 660 | v3d_job_put(&render->base); |
| 661 | + if (clean_job) |
| 662 | + v3d_job_put(clean_job); |
| 625 | 663 | |
| 626 | 664 | return ret; |
| 627 | 665 | } |