| @@ -530,13 +530,16 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 529 unmodified lines |
| 530 | struct drm_v3d_submit_cl *args = data; | 530 | struct drm_v3d_submit_cl *args = data; |
| 531 | struct v3d_bin_job *bin = NULL; | 531 | struct v3d_bin_job *bin = NULL; |
| 532 | struct v3d_render_job *render; | 532 | struct v3d_render_job *render; |
| | 533 | struct v3d_job *clean_job = NULL; |
| | 534 | struct v3d_job *last_job; |
| 533 | struct ww_acquire_ctx acquire_ctx; | 535 | struct ww_acquire_ctx acquire_ctx; |
| 534 | int ret = 0; | 536 | int ret = 0; |
| 535 | | 537 | |
| 536 | trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); | 538 | trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); |
| 537 | | 539 | |
| 538 | if (args->pad != 0) { | 540 | if (args->flags != 0 && |
| 539 | DRM_INFO("pad must be zero: %d\n", args->pad); | 541 | args->flags != DRM_V3D_SUBMIT_CL_FLUSH_CACHE) { |
| | 542 | DRM_INFO("invalid flags: %d\n", args->flags); |
| 540 | return -EINVAL; | 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 | bin->render = render; | 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 | args->bo_handles, args->bo_handle_count); | 602 | args->bo_handles, args->bo_handle_count); |
| 581 | if (ret) | 603 | if (ret) |
| 582 | goto fail; | 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 | if (ret) | 607 | if (ret) |
| 586 | goto fail; | 608 | goto fail; |
| 587 | | 609 | |
| @@ -600,28 +622,44 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 12 unmodified lines |
| 600 | ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); | 622 | ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); |
| 601 | if (ret) | 623 | if (ret) |
| 602 | goto fail_unreserve; | 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 | mutex_unlock(&v3d->sched_lock); | 637 | mutex_unlock(&v3d->sched_lock); |
| 604 | | 638 | |
| 605 | v3d_attach_fences_and_unlock_reservation(file_priv, | 639 | v3d_attach_fences_and_unlock_reservation(file_priv, |
| 606 | &render->base, | 640 | last_job, |
| 607 | &acquire_ctx, | 641 | &acquire_ctx, |
| 608 | args->out_sync, | 642 | args->out_sync, |
| 609 | render->base.done_fence); | 643 | last_job->done_fence); |
| 610 | | 644 | |
| 611 | if (bin) | 645 | if (bin) |
| 612 | v3d_job_put(&bin->base); | 646 | v3d_job_put(&bin->base); |
| 613 | v3d_job_put(&render->base); | 647 | v3d_job_put(&render->base); |
| | 648 | if (clean_job) |
| | 649 | v3d_job_put(clean_job); |
| 614 | | 650 | |
| 615 | return 0; | 651 | return 0; |
| 616 | | 652 | |
| 617 | fail_unreserve: | 653 | fail_unreserve: |
| 618 | mutex_unlock(&v3d->sched_lock); | 654 | mutex_unlock(&v3d->sched_lock); |
| 619 | drm_gem_unlock_reservations(render->base.bo, | 655 | drm_gem_unlock_reservations(last_job->bo, |
| 620 | render->base.bo_count, &acquire_ctx); | 656 | last_job->bo_count, &acquire_ctx); |
| 621 | fail: | 657 | fail: |
| 622 | if (bin) | 658 | if (bin) |
| 623 | v3d_job_put(&bin->base); | 659 | v3d_job_put(&bin->base); |
| 624 | v3d_job_put(&render->base); | 660 | v3d_job_put(&render->base); |
| | 661 | if (clean_job) |
| | 662 | v3d_job_put(clean_job); |
| 625 | | 663 | |
| 626 | return ret; | 664 | return ret; |
| 627 | } | 665 | } |