Merge tag 'lsk-android-14.04' into develop-3.10
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / mali_kbase_context.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 /**
21  * @file mali_kbase_context.c
22  * Base kernel context APIs
23  */
24
25 #include <mali_kbase.h>
26 #include <mali_midg_regmap.h>
27
28 #define MEMPOOL_PAGES 16384
29
30 /**
31  * @brief Create a kernel base context.
32  *
33  * Allocate and init a kernel base context.
34  */
35 kbase_context *kbase_create_context(kbase_device *kbdev)
36 {
37         kbase_context *kctx;
38         mali_error mali_err;
39
40         KBASE_DEBUG_ASSERT(kbdev != NULL);
41
42         /* zero-inited as lot of code assume it's zero'ed out on create */
43         kctx = vzalloc(sizeof(*kctx));
44
45         if (!kctx)
46                 goto out;
47
48         kctx->kbdev = kbdev;
49         kctx->as_nr = KBASEP_AS_NR_INVALID;
50 #ifdef CONFIG_MALI_TRACE_TIMELINE
51         kctx->timeline.owner_tgid = task_tgid_nr(current);
52 #endif
53         atomic_set(&kctx->setup_complete, 0);
54         atomic_set(&kctx->setup_in_progress, 0);
55         kctx->keep_gpu_powered = MALI_FALSE;
56         spin_lock_init(&kctx->mm_update_lock);
57         kctx->process_mm = NULL;
58         atomic_set(&kctx->nonmapped_pages, 0);
59
60         if (MALI_ERROR_NONE != kbase_mem_allocator_init(&kctx->osalloc, MEMPOOL_PAGES))
61                 goto free_kctx;
62
63         kctx->pgd_allocator = &kctx->osalloc;
64         atomic_set(&kctx->used_pages, 0);
65
66         if (kbase_jd_init(kctx))
67                 goto free_allocator;
68
69         mali_err = kbasep_js_kctx_init(kctx);
70         if (MALI_ERROR_NONE != mali_err)
71                 goto free_jd;   /* safe to call kbasep_js_kctx_term  in this case */
72
73         mali_err = kbase_event_init(kctx);
74         if (MALI_ERROR_NONE != mali_err)
75                 goto free_jd;
76
77         mutex_init(&kctx->reg_lock);
78
79         INIT_LIST_HEAD(&kctx->waiting_soft_jobs);
80 #ifdef CONFIG_KDS
81         INIT_LIST_HEAD(&kctx->waiting_kds_resource);
82 #endif
83
84         mali_err = kbase_mmu_init(kctx);
85         if (MALI_ERROR_NONE != mali_err)
86                 goto free_event;
87
88         kctx->pgd = kbase_mmu_alloc_pgd(kctx);
89         if (!kctx->pgd)
90                 goto free_mmu;
91
92         if (MALI_ERROR_NONE != kbase_mem_allocator_alloc(&kctx->osalloc, 1, &kctx->aliasing_sink_page))
93                 goto no_sink_page;
94
95         kctx->tgid = current->tgid;
96         kctx->pid = current->pid; 
97         init_waitqueue_head(&kctx->event_queue);
98
99         kctx->cookies = KBASE_COOKIE_MASK;
100
101         /* Make sure page 0 is not used... */
102         if (kbase_region_tracker_init(kctx))
103                 goto no_region_tracker;
104 #ifdef CONFIG_GPU_TRACEPOINTS
105         atomic_set(&kctx->jctx.work_id, 0);
106 #endif
107 #ifdef CONFIG_MALI_TRACE_TIMELINE
108         atomic_set(&kctx->timeline.jd_atoms_in_flight, 0);
109 #endif
110
111         return kctx;
112
113 no_region_tracker:
114 no_sink_page:
115         kbase_mem_allocator_free(&kctx->osalloc, 1, &kctx->aliasing_sink_page, 0);
116         kbase_mmu_free_pgd(kctx);
117 free_mmu:
118         kbase_mmu_term(kctx);
119 free_event:
120         kbase_event_cleanup(kctx);
121 free_jd:
122         /* Safe to call this one even when didn't initialize (assuming kctx was sufficiently zeroed) */
123         kbasep_js_kctx_term(kctx);
124         kbase_jd_exit(kctx);
125 free_allocator:
126         kbase_mem_allocator_term(&kctx->osalloc);
127 free_kctx:
128     vfree(kctx);
129 out:
130         return NULL;
131
132 }
133 KBASE_EXPORT_SYMBOL(kbase_create_context)
134
135 static void kbase_reg_pending_dtor(struct kbase_va_region *reg)
136 {
137         KBASE_LOG(2, reg->kctx->kbdev->dev, "Freeing pending unmapped region\n");
138         kbase_mem_phy_alloc_put(reg->alloc);
139         kfree(reg);
140 }
141
142 /**
143  * @brief Destroy a kernel base context.
144  *
145  * Destroy a kernel base context. Calls kbase_destroy_os_context() to
146  * free OS specific structures. Will release all outstanding regions.
147  */
148 void kbase_destroy_context(kbase_context *kctx)
149 {
150         kbase_device *kbdev;
151         int pages;
152         unsigned long pending_regions_to_clean;
153
154         KBASE_DEBUG_ASSERT(NULL != kctx);
155
156         kbdev = kctx->kbdev;
157         KBASE_DEBUG_ASSERT(NULL != kbdev);
158
159         KBASE_TRACE_ADD(kbdev, CORE_CTX_DESTROY, kctx, NULL, 0u, 0u);
160
161         /* Ensure the core is powered up for the destroy process */
162         /* A suspend won't happen here, because we're in a syscall from a userspace
163          * thread. */
164         kbase_pm_context_active(kbdev);
165
166         if (kbdev->hwcnt.kctx == kctx) {
167                 /* disable the use of the hw counters if the app didn't use the API correctly or crashed */
168                 KBASE_TRACE_ADD(kbdev, CORE_CTX_HWINSTR_TERM, kctx, NULL, 0u, 0u);
169                 dev_warn(kbdev->dev, "The privileged process asking for instrumentation forgot to disable it " "before exiting. Will end instrumentation for them");
170                 kbase_instr_hwcnt_disable(kctx);
171         }
172
173         kbase_jd_zap_context(kctx);
174         kbase_event_cleanup(kctx);
175
176         kbase_gpu_vm_lock(kctx);
177
178         /* MMU is disabled as part of scheduling out the context */
179         kbase_mmu_free_pgd(kctx);
180
181         /* drop the aliasing sink page now that it can't be mapped anymore */
182         kbase_mem_allocator_free(&kctx->osalloc, 1, &kctx->aliasing_sink_page, 0);
183
184         /* free pending region setups */
185         pending_regions_to_clean = (~kctx->cookies) & KBASE_COOKIE_MASK;
186         while (pending_regions_to_clean) {
187                 unsigned int cookie = __ffs(pending_regions_to_clean);
188                 BUG_ON(!kctx->pending_regions[cookie]);
189
190                 kbase_reg_pending_dtor(kctx->pending_regions[cookie]);
191
192                 kctx->pending_regions[cookie] = NULL;
193                 pending_regions_to_clean &= ~(1UL << cookie);
194         }
195
196         kbase_region_tracker_term(kctx);
197         kbase_gpu_vm_unlock(kctx);
198
199         /* Safe to call this one even when didn't initialize (assuming kctx was sufficiently zeroed) */
200         kbasep_js_kctx_term(kctx);
201
202         kbase_jd_exit(kctx);
203
204         kbase_pm_context_idle(kbdev);
205
206         kbase_mmu_term(kctx);
207
208         pages = atomic_read(&kctx->used_pages);
209         if (pages != 0)
210                 dev_warn(kbdev->dev, "%s: %d pages in use!\n", __func__, pages);
211
212         if (kctx->keep_gpu_powered) {
213                 atomic_dec(&kbdev->keep_gpu_powered_count);
214                 kbase_pm_context_idle(kbdev);
215         }
216
217         kbase_mem_allocator_term(&kctx->osalloc);
218         WARN_ON(atomic_read(&kctx->nonmapped_pages) != 0);
219         vfree(kctx);
220 }
221 KBASE_EXPORT_SYMBOL(kbase_destroy_context)
222
223 /**
224  * Set creation flags on a context
225  */
226 mali_error kbase_context_set_create_flags(kbase_context *kctx, u32 flags)
227 {
228         mali_error err = MALI_ERROR_NONE;
229         kbasep_js_kctx_info *js_kctx_info;
230         KBASE_DEBUG_ASSERT(NULL != kctx);
231
232         js_kctx_info = &kctx->jctx.sched_info;
233
234         /* Validate flags */
235         if (flags != (flags & BASE_CONTEXT_CREATE_KERNEL_FLAGS)) {
236                 err = MALI_ERROR_FUNCTION_FAILED;
237                 goto out;
238         }
239
240         mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
241
242         /* Translate the flags */
243         if ((flags & BASE_CONTEXT_SYSTEM_MONITOR_SUBMIT_DISABLED) == 0)
244                 js_kctx_info->ctx.flags &= ~((u32) KBASE_CTX_FLAG_SUBMIT_DISABLED);
245
246         if ((flags & BASE_CONTEXT_HINT_ONLY_COMPUTE) != 0)
247                 js_kctx_info->ctx.flags |= (u32) KBASE_CTX_FLAG_HINT_ONLY_COMPUTE;
248
249         /* Latch the initial attributes into the Job Scheduler */
250         kbasep_js_ctx_attr_set_initial_attrs(kctx->kbdev, kctx);
251
252         mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
253  out:
254         return err;
255 }
256 KBASE_EXPORT_SYMBOL(kbase_context_set_create_flags)