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.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index c94cce96544c..2107b0daf8ef 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -467,14 +467,30 @@ again:
467 467
468 vc4_flush_caches(dev); 468 vc4_flush_caches(dev);
469 469
470 /* Only start the perfmon if it was not already started by a previous
471 * job.
472 */
473 if (exec->perfmon && vc4->active_perfmon != exec->perfmon)
474 vc4_perfmon_start(vc4, exec->perfmon);
475
470 /* Either put the job in the binner if it uses the binner, or 476 /* Either put the job in the binner if it uses the binner, or
471 * immediately move it to the to-be-rendered queue. 477 * immediately move it to the to-be-rendered queue.
472 */ 478 */
473 if (exec->ct0ca != exec->ct0ea) { 479 if (exec->ct0ca != exec->ct0ea) {
474 submit_cl(dev, 0, exec->ct0ca, exec->ct0ea); 480 submit_cl(dev, 0, exec->ct0ca, exec->ct0ea);
475 } else { 481 } else {
482 struct vc4_exec_info *next;
483
476 vc4_move_job_to_render(dev, exec); 484 vc4_move_job_to_render(dev, exec);
477 goto again; 485 next = vc4_first_bin_job(vc4);
486
487 /* We can't start the next bin job if the previous job had a
488 * different perfmon instance attached to it. The same goes
489 * if one of them had a perfmon attached to it and the other
490 * one doesn't.
491 */
492 if (next && next->perfmon == exec->perfmon)
493 goto again;
478 } 494 }
479} 495}
480 496
@@ -642,6 +658,7 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
642 struct ww_acquire_ctx *acquire_ctx) 658 struct ww_acquire_ctx *acquire_ctx)
643{ 659{
644 struct vc4_dev *vc4 = to_vc4_dev(dev); 660 struct vc4_dev *vc4 = to_vc4_dev(dev);
661 struct vc4_exec_info *renderjob;
645 uint64_t seqno; 662 uint64_t seqno;
646 unsigned long irqflags; 663 unsigned long irqflags;
647 struct vc4_fence *fence; 664 struct vc4_fence *fence;
@@ -667,11 +684,14 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
667 684
668 list_add_tail(&exec->head, &vc4->bin_job_list); 685 list_add_tail(&exec->head, &vc4->bin_job_list);
669 686
670 /* If no job was executing, kick ours off. Otherwise, it'll 687 /* If no bin job was executing and if the render job (if any) has the
671 * get started when the previous job's flush done interrupt 688 * same perfmon as our job attached to it (or if both jobs don't have
672 * occurs. 689 * perfmon activated), then kick ours off. Otherwise, it'll get
690 * started when the previous job's flush/render done interrupt occurs.
673 */ 691 */
674 if (vc4_first_bin_job(vc4) == exec) { 692 renderjob = vc4_first_render_job(vc4);
693 if (vc4_first_bin_job(vc4) == exec &&
694 (!renderjob || renderjob->perfmon == exec->perfmon)) {
675 vc4_submit_next_bin_job(dev); 695 vc4_submit_next_bin_job(dev);
676 vc4_queue_hangcheck(dev); 696 vc4_queue_hangcheck(dev);
677 } 697 }
@@ -936,6 +956,9 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
936 vc4->bin_alloc_used &= ~exec->bin_slots; 956 vc4->bin_alloc_used &= ~exec->bin_slots;
937 spin_unlock_irqrestore(&vc4->job_lock, irqflags); 957 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
938 958
959 /* Release the reference we had on the perf monitor. */
960 vc4_perfmon_put(exec->perfmon);
961
939 mutex_lock(&vc4->power_lock); 962 mutex_lock(&vc4->power_lock);
940 if (--vc4->power_refcount == 0) { 963 if (--vc4->power_refcount == 0) {
941 pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev); 964 pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
@@ -1088,6 +1111,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
1088 struct drm_file *file_priv) 1111 struct drm_file *file_priv)
1089{ 1112{
1090 struct vc4_dev *vc4 = to_vc4_dev(dev); 1113 struct vc4_dev *vc4 = to_vc4_dev(dev);
1114 struct vc4_file *vc4file = file_priv->driver_priv;
1091 struct drm_vc4_submit_cl *args = data; 1115 struct drm_vc4_submit_cl *args = data;
1092 struct vc4_exec_info *exec; 1116 struct vc4_exec_info *exec;
1093 struct ww_acquire_ctx acquire_ctx; 1117 struct ww_acquire_ctx acquire_ctx;
@@ -1101,6 +1125,11 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
1101 return -EINVAL; 1125 return -EINVAL;
1102 } 1126 }
1103 1127
1128 if (args->pad2 != 0) {
1129 DRM_DEBUG("->pad2 must be set to zero\n");
1130 return -EINVAL;
1131 }
1132
1104 exec = kcalloc(1, sizeof(*exec), GFP_KERNEL); 1133 exec = kcalloc(1, sizeof(*exec), GFP_KERNEL);
1105 if (!exec) { 1134 if (!exec) {
1106 DRM_ERROR("malloc failure on exec struct\n"); 1135 DRM_ERROR("malloc failure on exec struct\n");
@@ -1126,6 +1155,15 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
1126 if (ret) 1155 if (ret)
1127 goto fail; 1156 goto fail;
1128 1157
1158 if (args->perfmonid) {
1159 exec->perfmon = vc4_perfmon_find(vc4file,
1160 args->perfmonid);
1161 if (!exec->perfmon) {
1162 ret = -ENOENT;
1163 goto fail;
1164 }
1165 }
1166
1129 if (exec->args->bin_cl_size != 0) { 1167 if (exec->args->bin_cl_size != 0) {
1130 ret = vc4_get_bcl(dev, exec); 1168 ret = vc4_get_bcl(dev, exec);
1131 if (ret) 1169 if (ret)