| /* | 
|  * | 
|  * (C) COPYRIGHT 2014-2016 ARM Limited. All rights reserved. | 
|  * | 
|  * This program is free software and is provided to you under the terms of the | 
|  * GNU General Public License version 2 as published by the Free Software | 
|  * Foundation, and any use by you of this program is subject to the terms | 
|  * of such GNU licence. | 
|  * | 
|  * A copy of the licence is included with the program, and can also be obtained | 
|  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 
|  * Boston, MA  02110-1301, USA. | 
|  * | 
|  */ | 
|   | 
|   | 
|   | 
|   | 
| /* | 
|  * HW access job manager common APIs | 
|  */ | 
|   | 
| #include <mali_kbase.h> | 
| #include "mali_kbase_hwaccess_jm.h" | 
| #include "mali_kbase_jm.h" | 
|   | 
| /** | 
|  * kbase_jm_next_job() - Attempt to run the next @nr_jobs_to_submit jobs on slot | 
|  *             @js on the active context. | 
|  * @kbdev:        Device pointer | 
|  * @js:            Job slot to run on | 
|  * @nr_jobs_to_submit:    Number of jobs to attempt to submit | 
|  * | 
|  * Return: true if slot can still be submitted on, false if slot is now full. | 
|  */ | 
| static bool kbase_jm_next_job(struct kbase_device *kbdev, int js, | 
|                 int nr_jobs_to_submit) | 
| { | 
|     struct kbase_context *kctx; | 
|     int i; | 
|   | 
|     kctx = kbdev->hwaccess.active_kctx; | 
|   | 
|     if (!kctx) | 
|         return true; | 
|   | 
|     for (i = 0; i < nr_jobs_to_submit; i++) { | 
|         struct kbase_jd_atom *katom = kbase_js_pull(kctx, js); | 
|   | 
|         if (!katom) | 
|             return true; /* Context has no jobs on this slot */ | 
|   | 
|         kbase_backend_run_atom(kbdev, katom); | 
|     } | 
|   | 
|     return false; /* Slot ringbuffer should now be full */ | 
| } | 
|   | 
| u32 kbase_jm_kick(struct kbase_device *kbdev, u32 js_mask) | 
| { | 
|     u32 ret_mask = 0; | 
|   | 
|     lockdep_assert_held(&kbdev->hwaccess_lock); | 
|   | 
|     while (js_mask) { | 
|         int js = ffs(js_mask) - 1; | 
|         int nr_jobs_to_submit = kbase_backend_slot_free(kbdev, js); | 
|   | 
|         if (kbase_jm_next_job(kbdev, js, nr_jobs_to_submit)) | 
|             ret_mask |= (1 << js); | 
|   | 
|         js_mask &= ~(1 << js); | 
|     } | 
|   | 
|     return ret_mask; | 
| } | 
|   | 
| void kbase_jm_try_kick(struct kbase_device *kbdev, u32 js_mask) | 
| { | 
|     struct kbasep_js_device_data *js_devdata = &kbdev->js_data; | 
|   | 
|     lockdep_assert_held(&kbdev->hwaccess_lock); | 
|   | 
|     if (!down_trylock(&js_devdata->schedule_sem)) { | 
|         kbase_jm_kick(kbdev, js_mask); | 
|         up(&js_devdata->schedule_sem); | 
|     } | 
| } | 
|   | 
| void kbase_jm_try_kick_all(struct kbase_device *kbdev) | 
| { | 
|     struct kbasep_js_device_data *js_devdata = &kbdev->js_data; | 
|   | 
|     lockdep_assert_held(&kbdev->hwaccess_lock); | 
|   | 
|     if (!down_trylock(&js_devdata->schedule_sem)) { | 
|         kbase_jm_kick_all(kbdev); | 
|         up(&js_devdata->schedule_sem); | 
|     } | 
| } | 
|   | 
| void kbase_jm_idle_ctx(struct kbase_device *kbdev, struct kbase_context *kctx) | 
| { | 
|     lockdep_assert_held(&kbdev->hwaccess_lock); | 
|   | 
|     if (kbdev->hwaccess.active_kctx == kctx) | 
|         kbdev->hwaccess.active_kctx = NULL; | 
| } | 
|   | 
| struct kbase_jd_atom *kbase_jm_return_atom_to_js(struct kbase_device *kbdev, | 
|                 struct kbase_jd_atom *katom) | 
| { | 
|     lockdep_assert_held(&kbdev->hwaccess_lock); | 
|   | 
|     if (katom->event_code != BASE_JD_EVENT_STOPPED && | 
|             katom->event_code != BASE_JD_EVENT_REMOVED_FROM_NEXT) { | 
|         return kbase_js_complete_atom(katom, NULL); | 
|     } else { | 
|         kbase_js_unpull(katom->kctx, katom); | 
|         return NULL; | 
|     } | 
| } | 
|   | 
| struct kbase_jd_atom *kbase_jm_complete(struct kbase_device *kbdev, | 
|         struct kbase_jd_atom *katom, ktime_t *end_timestamp) | 
| { | 
|     lockdep_assert_held(&kbdev->hwaccess_lock); | 
|   | 
|     return kbase_js_complete_atom(katom, end_timestamp); | 
| } |