drm/panfrost: Simplify devfreq utilisation tracking
[linux-2.6-microblaze.git] / drivers / gpu / drm / panfrost / panfrost_job.c
index a585516..d411eb6 100644 (file)
@@ -155,8 +155,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
        }
 
        cfg = panfrost_mmu_as_get(pfdev, &job->file_priv->mmu);
-
-       panfrost_devfreq_record_transition(pfdev, js);
+       panfrost_devfreq_record_busy(pfdev);
 
        job_write(pfdev, JS_HEAD_NEXT_LO(js), jc_head & 0xFFFFFFFF);
        job_write(pfdev, JS_HEAD_NEXT_HI(js), jc_head >> 32);
@@ -381,13 +380,19 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job)
                job_read(pfdev, JS_TAIL_LO(js)),
                sched_job);
 
-       mutex_lock(&pfdev->reset_lock);
+       if (!mutex_trylock(&pfdev->reset_lock))
+               return;
 
-       for (i = 0; i < NUM_JOB_SLOTS; i++)
-               drm_sched_stop(&pfdev->js->queue[i].sched, sched_job);
+       for (i = 0; i < NUM_JOB_SLOTS; i++) {
+               struct drm_gpu_scheduler *sched = &pfdev->js->queue[i].sched;
+
+               drm_sched_stop(sched, sched_job);
+               if (js != i)
+                       /* Ensure any timeouts on other slots have finished */
+                       cancel_delayed_work_sync(&sched->work_tdr);
+       }
 
-       if (sched_job)
-               drm_sched_increase_karma(sched_job);
+       drm_sched_increase_karma(sched_job);
 
        spin_lock_irqsave(&pfdev->js->job_lock, flags);
        for (i = 0; i < NUM_JOB_SLOTS; i++) {
@@ -398,9 +403,7 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job)
        }
        spin_unlock_irqrestore(&pfdev->js->job_lock, flags);
 
-       /* panfrost_core_dump(pfdev); */
-
-       panfrost_devfreq_record_transition(pfdev, js);
+       panfrost_devfreq_record_idle(pfdev);
        panfrost_device_reset(pfdev);
 
        for (i = 0; i < NUM_JOB_SLOTS; i++)
@@ -463,7 +466,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void *data)
                                pfdev->jobs[j] = NULL;
 
                                panfrost_mmu_as_put(pfdev, &job->file_priv->mmu);
-                               panfrost_devfreq_record_transition(pfdev, j);
+                               panfrost_devfreq_record_idle(pfdev);
 
                                dma_fence_signal_locked(job->done_fence);
                                pm_runtime_put_autosuspend(pfdev->dev);
@@ -564,14 +567,14 @@ int panfrost_job_is_idle(struct panfrost_device *pfdev)
        struct panfrost_job_slot *js = pfdev->js;
        int i;
 
+       /* Check whether the hardware is idle */
+       if (atomic_read(&pfdev->devfreq.busy_count))
+               return false;
+
        for (i = 0; i < NUM_JOB_SLOTS; i++) {
                /* If there are any jobs in the HW queue, we're not idle */
                if (atomic_read(&js->queue[i].sched.hw_rq_count))
                        return false;
-
-               /* Check whether the hardware is idle */
-               if (pfdev->devfreq.slot[i].busy)
-                       return false;
        }
 
        return true;