rockchip:midgard:update to r4p1_01dev0
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / mali_kbase_event.c
1 /*
2  *
3  * (C) COPYRIGHT ARM Limited. All rights reserved.
4  *
5  * This program is free software and is provided to you under the terms of the
6  * GNU General Public License version 2 as published by the Free Software
7  * Foundation, and any use by you of this program is subject to the terms
8  * of such GNU licence.
9  *
10  * A copy of the licence is included with the program, and can also be obtained
11  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12  * Boston, MA  02110-1301, USA.
13  *
14  */
15
16
17
18
19
20 #include <mali_kbase.h>
21 #include <mali_kbase_debug.h>
22
23 STATIC base_jd_udata kbase_event_process(kbase_context *kctx, kbase_jd_atom *katom)
24 {
25         base_jd_udata data;
26
27         KBASE_DEBUG_ASSERT(kctx != NULL);
28         KBASE_DEBUG_ASSERT(katom != NULL);
29         KBASE_DEBUG_ASSERT(katom->status == KBASE_JD_ATOM_STATE_COMPLETED);
30
31         data = katom->udata;
32
33         KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, atomic_sub_return(1, &kctx->timeline.jd_atoms_in_flight));
34
35         mutex_lock(&kctx->jctx.lock);
36         katom->status = KBASE_JD_ATOM_STATE_UNUSED;
37         mutex_unlock(&kctx->jctx.lock);
38
39         wake_up(&katom->completed);
40
41         return data;
42 }
43
44 int kbase_event_pending(kbase_context *ctx)
45 {
46         int ret;
47
48         KBASE_DEBUG_ASSERT(ctx);
49
50         mutex_lock(&ctx->event_mutex);
51         ret = (!list_empty(&ctx->event_list)) || (MALI_TRUE == ctx->event_closed);
52         mutex_unlock(&ctx->event_mutex);
53
54         return ret;
55 }
56
57 KBASE_EXPORT_TEST_API(kbase_event_pending)
58
59 int kbase_event_dequeue(kbase_context *ctx, base_jd_event_v2 *uevent)
60 {
61         kbase_jd_atom *atom;
62
63         KBASE_DEBUG_ASSERT(ctx);
64
65         mutex_lock(&ctx->event_mutex);
66
67         if (list_empty(&ctx->event_list)) {
68                 if (ctx->event_closed) {
69                         /* generate the BASE_JD_EVENT_DRV_TERMINATED message on the fly */
70                         mutex_unlock(&ctx->event_mutex);
71                         uevent->event_code = BASE_JD_EVENT_DRV_TERMINATED;
72                         memset(&uevent->udata, 0, sizeof(uevent->udata));
73                         dev_dbg(ctx->kbdev->dev,
74                                 "event system closed, returning BASE_JD_EVENT_DRV_TERMINATED(0x%X)\n",
75                                 BASE_JD_EVENT_DRV_TERMINATED);
76                         return 0;
77                 } else {
78                         mutex_unlock(&ctx->event_mutex);
79                         return -1;
80                 }
81         }
82
83         /* normal event processing */
84         atom = list_entry(ctx->event_list.next, kbase_jd_atom, dep_item[0]);
85         list_del(ctx->event_list.next);
86
87         mutex_unlock(&ctx->event_mutex);
88
89         dev_dbg(ctx->kbdev->dev, "event dequeuing %p\n", (void *)atom);
90         uevent->event_code = atom->event_code;
91         uevent->atom_number = (atom - ctx->jctx.atoms);
92         uevent->udata = kbase_event_process(ctx, atom);
93
94         return 0;
95 }
96
97 KBASE_EXPORT_TEST_API(kbase_event_dequeue)
98
99 static void kbase_event_post_worker(struct work_struct *data)
100 {
101         kbase_jd_atom *atom = CONTAINER_OF(data, kbase_jd_atom, work);
102         kbase_context *ctx = atom->kctx;
103
104         if (atom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES)
105                 kbase_jd_free_external_resources(atom);
106
107         if (atom->core_req & BASE_JD_REQ_EVENT_ONLY_ON_FAILURE) {
108                 if (atom->event_code == BASE_JD_EVENT_DONE) {
109                         /* Don't report the event */
110                         kbase_event_process(ctx, atom);
111                         return;
112                 }
113         }
114
115         if (atom->core_req & BASEP_JD_REQ_EVENT_NEVER) {
116                 /* Don't report the event */
117                 kbase_event_process(ctx, atom);
118                 return;
119         }
120
121         mutex_lock(&ctx->event_mutex);
122         list_add_tail(&atom->dep_item[0], &ctx->event_list);
123         mutex_unlock(&ctx->event_mutex);
124
125         kbase_event_wakeup(ctx);
126 }
127
128 void kbase_event_post(kbase_context *ctx, kbase_jd_atom *atom)
129 {
130         KBASE_DEBUG_ASSERT(ctx);
131         KBASE_DEBUG_ASSERT(ctx->event_workq);
132         KBASE_DEBUG_ASSERT(atom);
133
134         INIT_WORK(&atom->work, kbase_event_post_worker);
135         queue_work(ctx->event_workq, &atom->work);
136 }
137
138 KBASE_EXPORT_TEST_API(kbase_event_post)
139
140 void kbase_event_close(kbase_context *kctx)
141 {
142         mutex_lock(&kctx->event_mutex);
143         kctx->event_closed = MALI_TRUE;
144         mutex_unlock(&kctx->event_mutex);
145         kbase_event_wakeup(kctx);
146 }
147
148 mali_error kbase_event_init(kbase_context *kctx)
149 {
150         KBASE_DEBUG_ASSERT(kctx);
151
152         INIT_LIST_HEAD(&kctx->event_list);
153         mutex_init(&kctx->event_mutex);
154         kctx->event_closed = MALI_FALSE;
155         kctx->event_workq = alloc_workqueue("kbase_event", WQ_MEM_RECLAIM, 1);
156
157         if (NULL == kctx->event_workq)
158                 return MALI_ERROR_FUNCTION_FAILED;
159
160         return MALI_ERROR_NONE;
161 }
162
163 KBASE_EXPORT_TEST_API(kbase_event_init)
164
165 void kbase_event_cleanup(kbase_context *kctx)
166 {
167         KBASE_DEBUG_ASSERT(kctx);
168         KBASE_DEBUG_ASSERT(kctx->event_workq);
169
170         flush_workqueue(kctx->event_workq);
171         destroy_workqueue(kctx->event_workq);
172
173         /* We use kbase_event_dequeue to remove the remaining events as that
174          * deals with all the cleanup needed for the atoms.
175          *
176          * Note: use of kctx->event_list without a lock is safe because this must be the last
177          * thread using it (because we're about to terminate the lock)
178          */
179         while (!list_empty(&kctx->event_list)) {
180                 base_jd_event_v2 event;
181                 kbase_event_dequeue(kctx, &event);
182         }
183 }
184
185 KBASE_EXPORT_TEST_API(kbase_event_cleanup)