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