MALI: utgard: upgrade DDK to r7p0-00rel0
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / mali400 / mali / common / mali_kernel_core.c
1 /*
2  * Copyright (C) 2010-2016 ARM Limited. All rights reserved.
3  * 
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  * 
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10
11 #include "mali_kernel_common.h"
12 #include "mali_session.h"
13 #include "mali_osk.h"
14 #include "mali_osk_mali.h"
15 #include "mali_ukk.h"
16 #include "mali_kernel_core.h"
17 #include "mali_memory.h"
18 #include "mali_mem_validation.h"
19 #include "mali_mmu.h"
20 #include "mali_mmu_page_directory.h"
21 #include "mali_dlbu.h"
22 #include "mali_broadcast.h"
23 #include "mali_gp.h"
24 #include "mali_pp.h"
25 #include "mali_executor.h"
26 #include "mali_pp_job.h"
27 #include "mali_group.h"
28 #include "mali_pm.h"
29 #include "mali_pmu.h"
30 #include "mali_scheduler.h"
31 #include "mali_kernel_utilization.h"
32 #include "mali_l2_cache.h"
33 #include "mali_timeline.h"
34 #include "mali_soft_job.h"
35 #include "mali_pm_domain.h"
36 #if defined(CONFIG_MALI400_PROFILING)
37 #include "mali_osk_profiling.h"
38 #endif
39 #if defined(CONFIG_MALI400_INTERNAL_PROFILING)
40 #include "mali_profiling_internal.h"
41 #endif
42 #include "mali_control_timer.h"
43 #include "mali_dvfs_policy.h"
44 #include <linux/sched.h>
45 #include <linux/atomic.h>
46 #if defined(CONFIG_MALI_DMA_BUF_FENCE)
47 #include <linux/fence.h>
48 #endif
49
50 #define MALI_SHARED_MEMORY_DEFAULT_SIZE 0xffffffff
51
52 /* Mali GPU memory. Real values come from module parameter or from device specific data */
53 unsigned int mali_dedicated_mem_start = 0;
54 unsigned int mali_dedicated_mem_size = 0;
55
56 /* Default shared memory size is set to 4G. */
57 unsigned int mali_shared_mem_size = MALI_SHARED_MEMORY_DEFAULT_SIZE;
58
59 /* Frame buffer memory to be accessible by Mali GPU */
60 int mali_fb_start = 0;
61 int mali_fb_size = 0;
62
63 /* Mali max job runtime */
64 extern int mali_max_job_runtime;
65
66 /** Start profiling from module load? */
67 int mali_boot_profiling = 0;
68
69 /** Limits for the number of PP cores behind each L2 cache. */
70 int mali_max_pp_cores_group_1 = 0xFF;
71 int mali_max_pp_cores_group_2 = 0xFF;
72
73 int mali_inited_pp_cores_group_1 = 0;
74 int mali_inited_pp_cores_group_2 = 0;
75
76 static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN;
77 static uintptr_t global_gpu_base_address = 0;
78 static u32 global_gpu_major_version = 0;
79 static u32 global_gpu_minor_version = 0;
80
81 mali_bool mali_gpu_class_is_mali450 = MALI_FALSE;
82 mali_bool mali_gpu_class_is_mali470 = MALI_FALSE;
83
84 static _mali_osk_errcode_t mali_set_global_gpu_base_address(void)
85 {
86         _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
87
88         global_gpu_base_address = _mali_osk_resource_base_address();
89         if (0 == global_gpu_base_address) {
90                 err = _MALI_OSK_ERR_ITEM_NOT_FOUND;
91         }
92
93         return err;
94 }
95
96 static u32 mali_get_bcast_id(_mali_osk_resource_t *resource_pp)
97 {
98         switch (resource_pp->base - global_gpu_base_address) {
99         case 0x08000:
100         case 0x20000: /* fall-through for aliased mapping */
101                 return 0x01;
102         case 0x0A000:
103         case 0x22000: /* fall-through for aliased mapping */
104                 return 0x02;
105         case 0x0C000:
106         case 0x24000: /* fall-through for aliased mapping */
107                 return 0x04;
108         case 0x0E000:
109         case 0x26000: /* fall-through for aliased mapping */
110                 return 0x08;
111         case 0x28000:
112                 return 0x10;
113         case 0x2A000:
114                 return 0x20;
115         case 0x2C000:
116                 return 0x40;
117         case 0x2E000:
118                 return 0x80;
119         default:
120                 return 0;
121         }
122 }
123
124 static _mali_osk_errcode_t mali_parse_product_info(void)
125 {
126         _mali_osk_resource_t first_pp_resource;
127
128         /* Find the first PP core resource (again) */
129         if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_PP0, &first_pp_resource)) {
130                 /* Create a dummy PP object for this core so that we can read the version register */
131                 struct mali_group *group = mali_group_create(NULL, NULL, NULL, MALI_DOMAIN_INDEX_PP0);
132                 if (NULL != group) {
133                         struct mali_pp_core *pp_core = mali_pp_create(&first_pp_resource, group, MALI_FALSE, mali_get_bcast_id(&first_pp_resource));
134                         if (NULL != pp_core) {
135                                 u32 pp_version;
136
137                                 pp_version = mali_pp_core_get_version(pp_core);
138
139                                 mali_group_delete(group);
140
141                                 global_gpu_major_version = (pp_version >> 8) & 0xFF;
142                                 global_gpu_minor_version = pp_version & 0xFF;
143
144                                 switch (pp_version >> 16) {
145                                 case MALI200_PP_PRODUCT_ID:
146                                         global_product_id = _MALI_PRODUCT_ID_MALI200;
147                                         MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
148                                         MALI_PRINT_ERROR(("Mali-200 is not supported by this driver.\n"));
149                                         _mali_osk_abort();
150                                         break;
151                                 case MALI300_PP_PRODUCT_ID:
152                                         global_product_id = _MALI_PRODUCT_ID_MALI300;
153                                         MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
154                                         break;
155                                 case MALI400_PP_PRODUCT_ID:
156                                         global_product_id = _MALI_PRODUCT_ID_MALI400;
157                                         MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
158                                         break;
159                                 case MALI450_PP_PRODUCT_ID:
160                                         global_product_id = _MALI_PRODUCT_ID_MALI450;
161                                         MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
162                                         break;
163                                 case MALI470_PP_PRODUCT_ID:
164                                         global_product_id = _MALI_PRODUCT_ID_MALI470;
165                                         MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-470 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
166                                         break;
167                                 default:
168                                         MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version));
169                                         return _MALI_OSK_ERR_FAULT;
170                                 }
171
172                                 return _MALI_OSK_ERR_OK;
173                         } else {
174                                 MALI_PRINT_ERROR(("Failed to create initial PP object\n"));
175                         }
176                 } else {
177                         MALI_PRINT_ERROR(("Failed to create initial group object\n"));
178                 }
179         } else {
180                 MALI_PRINT_ERROR(("First PP core not specified in config file\n"));
181         }
182
183         return _MALI_OSK_ERR_FAULT;
184 }
185
186 static void mali_delete_groups(void)
187 {
188         struct mali_group *group;
189
190         group = mali_group_get_glob_group(0);
191         while (NULL != group) {
192                 mali_group_delete(group);
193                 group = mali_group_get_glob_group(0);
194         }
195
196         MALI_DEBUG_ASSERT(0 == mali_group_get_glob_num_groups());
197 }
198
199 static void mali_delete_l2_cache_cores(void)
200 {
201         struct mali_l2_cache_core *l2;
202
203         l2 = mali_l2_cache_core_get_glob_l2_core(0);
204         while (NULL != l2) {
205                 mali_l2_cache_delete(l2);
206                 l2 = mali_l2_cache_core_get_glob_l2_core(0);
207         }
208
209         MALI_DEBUG_ASSERT(0 == mali_l2_cache_core_get_glob_num_l2_cores());
210 }
211
212 static struct mali_l2_cache_core *mali_create_l2_cache_core(_mali_osk_resource_t *resource, u32 domain_index)
213 {
214         struct mali_l2_cache_core *l2_cache = NULL;
215
216         if (NULL != resource) {
217
218                 MALI_DEBUG_PRINT(3, ("Found L2 cache %s\n", resource->description));
219
220                 l2_cache = mali_l2_cache_create(resource, domain_index);
221                 if (NULL == l2_cache) {
222                         MALI_PRINT_ERROR(("Failed to create L2 cache object\n"));
223                         return NULL;
224                 }
225         }
226         MALI_DEBUG_PRINT(3, ("Created L2 cache core object\n"));
227
228         return l2_cache;
229 }
230
231 static _mali_osk_errcode_t mali_parse_config_l2_cache(void)
232 {
233         struct mali_l2_cache_core *l2_cache = NULL;
234
235         if (mali_is_mali400()) {
236                 _mali_osk_resource_t l2_resource;
237                 if (_MALI_OSK_ERR_OK != _mali_osk_resource_find(MALI400_OFFSET_L2_CACHE0, &l2_resource)) {
238                         MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n"));
239                         return _MALI_OSK_ERR_FAULT;
240                 }
241
242                 l2_cache = mali_create_l2_cache_core(&l2_resource, MALI_DOMAIN_INDEX_L20);
243                 if (NULL == l2_cache) {
244                         return _MALI_OSK_ERR_FAULT;
245                 }
246         } else if (mali_is_mali450()) {
247                 /*
248                  * L2 for GP    at 0x10000
249                  * L2 for PP0-3 at 0x01000
250                  * L2 for PP4-7 at 0x11000 (optional)
251                  */
252
253                 _mali_osk_resource_t l2_gp_resource;
254                 _mali_osk_resource_t l2_pp_grp0_resource;
255                 _mali_osk_resource_t l2_pp_grp1_resource;
256
257                 /* Make cluster for GP's L2 */
258                 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI450_OFFSET_L2_CACHE0, &l2_gp_resource)) {
259                         MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for GP\n"));
260                         l2_cache = mali_create_l2_cache_core(&l2_gp_resource, MALI_DOMAIN_INDEX_L20);
261                         if (NULL == l2_cache) {
262                                 return _MALI_OSK_ERR_FAULT;
263                         }
264                 } else {
265                         MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
266                         return _MALI_OSK_ERR_FAULT;
267                 }
268
269                 /* Find corresponding l2 domain */
270                 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI450_OFFSET_L2_CACHE1, &l2_pp_grp0_resource)) {
271                         MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 0\n"));
272                         l2_cache = mali_create_l2_cache_core(&l2_pp_grp0_resource, MALI_DOMAIN_INDEX_L21);
273                         if (NULL == l2_cache) {
274                                 return _MALI_OSK_ERR_FAULT;
275                         }
276                 } else {
277                         MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n"));
278                         return _MALI_OSK_ERR_FAULT;
279                 }
280
281                 /* Second PP core group is optional, don't fail if we don't find it */
282                 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI450_OFFSET_L2_CACHE2, &l2_pp_grp1_resource)) {
283                         MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 1\n"));
284                         l2_cache = mali_create_l2_cache_core(&l2_pp_grp1_resource, MALI_DOMAIN_INDEX_L22);
285                         if (NULL == l2_cache) {
286                                 return _MALI_OSK_ERR_FAULT;
287                         }
288                 }
289         } else if (mali_is_mali470()) {
290                 _mali_osk_resource_t l2c1_resource;
291
292                 /* Make cluster for L2C1 */
293                 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI470_OFFSET_L2_CACHE1, &l2c1_resource)) {
294                         MALI_DEBUG_PRINT(3, ("Creating Mali-470 L2 cache 1\n"));
295                         l2_cache = mali_create_l2_cache_core(&l2c1_resource, MALI_DOMAIN_INDEX_L21);
296                         if (NULL == l2_cache) {
297                                 return _MALI_OSK_ERR_FAULT;
298                         }
299                 } else {
300                         MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for L2C1\n"));
301                         return _MALI_OSK_ERR_FAULT;
302                 }
303         }
304
305         return _MALI_OSK_ERR_OK;
306 }
307
308 static struct mali_group *mali_create_group(struct mali_l2_cache_core *cache,
309                 _mali_osk_resource_t *resource_mmu,
310                 _mali_osk_resource_t *resource_gp,
311                 _mali_osk_resource_t *resource_pp,
312                 u32 domain_index)
313 {
314         struct mali_mmu_core *mmu;
315         struct mali_group *group;
316
317         MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
318
319         /* Create the group object */
320         group = mali_group_create(cache, NULL, NULL, domain_index);
321         if (NULL == group) {
322                 MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
323                 return NULL;
324         }
325
326         /* Create the MMU object inside group */
327         mmu = mali_mmu_create(resource_mmu, group, MALI_FALSE);
328         if (NULL == mmu) {
329                 MALI_PRINT_ERROR(("Failed to create MMU object\n"));
330                 mali_group_delete(group);
331                 return NULL;
332         }
333
334         if (NULL != resource_gp) {
335                 /* Create the GP core object inside this group */
336                 struct mali_gp_core *gp_core = mali_gp_create(resource_gp, group);
337                 if (NULL == gp_core) {
338                         /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
339                         MALI_PRINT_ERROR(("Failed to create GP object\n"));
340                         mali_group_delete(group);
341                         return NULL;
342                 }
343         }
344
345         if (NULL != resource_pp) {
346                 struct mali_pp_core *pp_core;
347
348                 /* Create the PP core object inside this group */
349                 pp_core = mali_pp_create(resource_pp, group, MALI_FALSE, mali_get_bcast_id(resource_pp));
350                 if (NULL == pp_core) {
351                         /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
352                         MALI_PRINT_ERROR(("Failed to create PP object\n"));
353                         mali_group_delete(group);
354                         return NULL;
355                 }
356         }
357
358         return group;
359 }
360
361 static _mali_osk_errcode_t mali_create_virtual_group(_mali_osk_resource_t *resource_mmu_pp_bcast,
362                 _mali_osk_resource_t *resource_pp_bcast,
363                 _mali_osk_resource_t *resource_dlbu,
364                 _mali_osk_resource_t *resource_bcast)
365 {
366         struct mali_mmu_core *mmu_pp_bcast_core;
367         struct mali_pp_core *pp_bcast_core;
368         struct mali_dlbu_core *dlbu_core;
369         struct mali_bcast_unit *bcast_core;
370         struct mali_group *group;
371
372         MALI_DEBUG_PRINT(2, ("Starting new virtual group for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
373
374         /* Create the DLBU core object */
375         dlbu_core = mali_dlbu_create(resource_dlbu);
376         if (NULL == dlbu_core) {
377                 MALI_PRINT_ERROR(("Failed to create DLBU object \n"));
378                 return _MALI_OSK_ERR_FAULT;
379         }
380
381         /* Create the Broadcast unit core */
382         bcast_core = mali_bcast_unit_create(resource_bcast);
383         if (NULL == bcast_core) {
384                 MALI_PRINT_ERROR(("Failed to create Broadcast unit object!\n"));
385                 mali_dlbu_delete(dlbu_core);
386                 return _MALI_OSK_ERR_FAULT;
387         }
388
389         /* Create the group object */
390 #if defined(DEBUG)
391         /* Get a physical PP group to temporarily add to broadcast unit.  IRQ
392          * verification needs a physical group in the broadcast unit to test
393          * the broadcast unit interrupt line. */
394         {
395                 struct mali_group *phys_group = NULL;
396                 int i;
397                 for (i = 0; i < mali_group_get_glob_num_groups(); i++) {
398                         phys_group = mali_group_get_glob_group(i);
399                         if (NULL != mali_group_get_pp_core(phys_group)) break;
400                 }
401                 MALI_DEBUG_ASSERT(NULL != mali_group_get_pp_core(phys_group));
402
403                 /* Add the group temporarily to the broadcast, and update the
404                  * broadcast HW. Since the HW is not updated when removing the
405                  * group the IRQ check will work when the virtual PP is created
406                  * later.
407                  *
408                  * When the virtual group gets populated, the actually used
409                  * groups will be added to the broadcast unit and the HW will
410                  * be updated.
411                  */
412                 mali_bcast_add_group(bcast_core, phys_group);
413                 mali_bcast_reset(bcast_core);
414                 mali_bcast_remove_group(bcast_core, phys_group);
415         }
416 #endif /* DEBUG */
417         group = mali_group_create(NULL, dlbu_core, bcast_core, MALI_DOMAIN_INDEX_DUMMY);
418         if (NULL == group) {
419                 MALI_PRINT_ERROR(("Failed to create group object for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
420                 mali_bcast_unit_delete(bcast_core);
421                 mali_dlbu_delete(dlbu_core);
422                 return _MALI_OSK_ERR_FAULT;
423         }
424
425         /* Create the MMU object inside group */
426         mmu_pp_bcast_core = mali_mmu_create(resource_mmu_pp_bcast, group, MALI_TRUE);
427         if (NULL == mmu_pp_bcast_core) {
428                 MALI_PRINT_ERROR(("Failed to create MMU PP broadcast object\n"));
429                 mali_group_delete(group);
430                 return _MALI_OSK_ERR_FAULT;
431         }
432
433         /* Create the PP core object inside this group */
434         pp_bcast_core = mali_pp_create(resource_pp_bcast, group, MALI_TRUE, 0);
435         if (NULL == pp_bcast_core) {
436                 /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
437                 MALI_PRINT_ERROR(("Failed to create PP object\n"));
438                 mali_group_delete(group);
439                 return _MALI_OSK_ERR_FAULT;
440         }
441
442         return _MALI_OSK_ERR_OK;
443 }
444
445 static _mali_osk_errcode_t mali_parse_config_groups(void)
446 {
447         struct mali_group *group;
448         int cluster_id_gp = 0;
449         int cluster_id_pp_grp0 = 0;
450         int cluster_id_pp_grp1 = 0;
451         int i;
452
453         _mali_osk_resource_t resource_gp;
454         _mali_osk_resource_t resource_gp_mmu;
455         _mali_osk_resource_t resource_pp[8];
456         _mali_osk_resource_t resource_pp_mmu[8];
457         _mali_osk_resource_t resource_pp_mmu_bcast;
458         _mali_osk_resource_t resource_pp_bcast;
459         _mali_osk_resource_t resource_dlbu;
460         _mali_osk_resource_t resource_bcast;
461         _mali_osk_errcode_t resource_gp_found;
462         _mali_osk_errcode_t resource_gp_mmu_found;
463         _mali_osk_errcode_t resource_pp_found[8];
464         _mali_osk_errcode_t resource_pp_mmu_found[8];
465         _mali_osk_errcode_t resource_pp_mmu_bcast_found;
466         _mali_osk_errcode_t resource_pp_bcast_found;
467         _mali_osk_errcode_t resource_dlbu_found;
468         _mali_osk_errcode_t resource_bcast_found;
469
470         if (!(mali_is_mali400() || mali_is_mali450() || mali_is_mali470())) {
471                 /* No known HW core */
472                 return _MALI_OSK_ERR_FAULT;
473         }
474
475         if (MALI_MAX_JOB_RUNTIME_DEFAULT == mali_max_job_runtime) {
476                 /* Group settings are not overridden by module parameters, so use device settings */
477                 _mali_osk_device_data data = { 0, };
478
479                 if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
480                         /* Use device specific settings (if defined) */
481                         if (0 != data.max_job_runtime) {
482                                 mali_max_job_runtime = data.max_job_runtime;
483                         }
484                 }
485         }
486
487         if (mali_is_mali450()) {
488                 /* Mali-450 have separate L2s for GP, and PP core group(s) */
489                 cluster_id_pp_grp0 = 1;
490                 cluster_id_pp_grp1 = 2;
491         }
492
493         resource_gp_found = _mali_osk_resource_find(MALI_OFFSET_GP, &resource_gp);
494         resource_gp_mmu_found = _mali_osk_resource_find(MALI_OFFSET_GP_MMU, &resource_gp_mmu);
495         resource_pp_found[0] = _mali_osk_resource_find(MALI_OFFSET_PP0, &(resource_pp[0]));
496         resource_pp_found[1] = _mali_osk_resource_find(MALI_OFFSET_PP1, &(resource_pp[1]));
497         resource_pp_found[2] = _mali_osk_resource_find(MALI_OFFSET_PP2, &(resource_pp[2]));
498         resource_pp_found[3] = _mali_osk_resource_find(MALI_OFFSET_PP3, &(resource_pp[3]));
499         resource_pp_found[4] = _mali_osk_resource_find(MALI_OFFSET_PP4, &(resource_pp[4]));
500         resource_pp_found[5] = _mali_osk_resource_find(MALI_OFFSET_PP5, &(resource_pp[5]));
501         resource_pp_found[6] = _mali_osk_resource_find(MALI_OFFSET_PP6, &(resource_pp[6]));
502         resource_pp_found[7] = _mali_osk_resource_find(MALI_OFFSET_PP7, &(resource_pp[7]));
503         resource_pp_mmu_found[0] = _mali_osk_resource_find(MALI_OFFSET_PP0_MMU, &(resource_pp_mmu[0]));
504         resource_pp_mmu_found[1] = _mali_osk_resource_find(MALI_OFFSET_PP1_MMU, &(resource_pp_mmu[1]));
505         resource_pp_mmu_found[2] = _mali_osk_resource_find(MALI_OFFSET_PP2_MMU, &(resource_pp_mmu[2]));
506         resource_pp_mmu_found[3] = _mali_osk_resource_find(MALI_OFFSET_PP3_MMU, &(resource_pp_mmu[3]));
507         resource_pp_mmu_found[4] = _mali_osk_resource_find(MALI_OFFSET_PP4_MMU, &(resource_pp_mmu[4]));
508         resource_pp_mmu_found[5] = _mali_osk_resource_find(MALI_OFFSET_PP5_MMU, &(resource_pp_mmu[5]));
509         resource_pp_mmu_found[6] = _mali_osk_resource_find(MALI_OFFSET_PP6_MMU, &(resource_pp_mmu[6]));
510         resource_pp_mmu_found[7] = _mali_osk_resource_find(MALI_OFFSET_PP7_MMU, &(resource_pp_mmu[7]));
511
512
513         if (mali_is_mali450() || mali_is_mali470()) {
514                 resource_bcast_found = _mali_osk_resource_find(MALI_OFFSET_BCAST, &resource_bcast);
515                 resource_dlbu_found = _mali_osk_resource_find(MALI_OFFSET_DLBU, &resource_dlbu);
516                 resource_pp_mmu_bcast_found = _mali_osk_resource_find(MALI_OFFSET_PP_BCAST_MMU, &resource_pp_mmu_bcast);
517                 resource_pp_bcast_found = _mali_osk_resource_find(MALI_OFFSET_PP_BCAST, &resource_pp_bcast);
518
519                 if (_MALI_OSK_ERR_OK != resource_bcast_found ||
520                     _MALI_OSK_ERR_OK != resource_dlbu_found ||
521                     _MALI_OSK_ERR_OK != resource_pp_mmu_bcast_found ||
522                     _MALI_OSK_ERR_OK != resource_pp_bcast_found) {
523                         /* Missing mandatory core(s) for Mali-450 or Mali-470 */
524                         MALI_DEBUG_PRINT(2, ("Missing mandatory resources, Mali-450 needs DLBU, Broadcast unit, virtual PP core and virtual MMU\n"));
525                         return _MALI_OSK_ERR_FAULT;
526                 }
527         }
528
529         if (_MALI_OSK_ERR_OK != resource_gp_found ||
530             _MALI_OSK_ERR_OK != resource_gp_mmu_found ||
531             _MALI_OSK_ERR_OK != resource_pp_found[0] ||
532             _MALI_OSK_ERR_OK != resource_pp_mmu_found[0]) {
533                 /* Missing mandatory core(s) */
534                 MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU\n"));
535                 return _MALI_OSK_ERR_FAULT;
536         }
537
538         MALI_DEBUG_ASSERT(1 <= mali_l2_cache_core_get_glob_num_l2_cores());
539         group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_gp), &resource_gp_mmu, &resource_gp, NULL, MALI_DOMAIN_INDEX_GP);
540         if (NULL == group) {
541                 return _MALI_OSK_ERR_FAULT;
542         }
543
544         /* Create group for first (and mandatory) PP core */
545         MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */
546         group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[0], NULL, &resource_pp[0], MALI_DOMAIN_INDEX_PP0);
547         if (NULL == group) {
548                 return _MALI_OSK_ERR_FAULT;
549         }
550
551         mali_inited_pp_cores_group_1++;
552
553         /* Create groups for rest of the cores in the first PP core group */
554         for (i = 1; i < 4; i++) { /* First half of the PP cores belong to first core group */
555                 if (mali_inited_pp_cores_group_1 < mali_max_pp_cores_group_1) {
556                         if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i]) {
557                                 group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[i], NULL, &resource_pp[i], MALI_DOMAIN_INDEX_PP0 + i);
558                                 if (NULL == group) {
559                                         return _MALI_OSK_ERR_FAULT;
560                                 }
561
562                                 mali_inited_pp_cores_group_1++;
563                         }
564                 }
565         }
566
567         /* Create groups for cores in the second PP core group */
568         for (i = 4; i < 8; i++) { /* Second half of the PP cores belong to second core group */
569                 if (mali_inited_pp_cores_group_2 < mali_max_pp_cores_group_2) {
570                         if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i]) {
571                                 MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= 2); /* Only Mali-450 have a second core group */
572                                 group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp1), &resource_pp_mmu[i], NULL, &resource_pp[i], MALI_DOMAIN_INDEX_PP0 + i);
573                                 if (NULL == group) {
574                                         return _MALI_OSK_ERR_FAULT;
575                                 }
576
577                                 mali_inited_pp_cores_group_2++;
578                         }
579                 }
580         }
581
582         if (mali_is_mali450() || mali_is_mali470()) {
583                 _mali_osk_errcode_t err = mali_create_virtual_group(&resource_pp_mmu_bcast, &resource_pp_bcast, &resource_dlbu, &resource_bcast);
584                 if (_MALI_OSK_ERR_OK != err) {
585                         return err;
586                 }
587         }
588
589         mali_max_pp_cores_group_1 = mali_inited_pp_cores_group_1;
590         mali_max_pp_cores_group_2 = mali_inited_pp_cores_group_2;
591         MALI_DEBUG_PRINT(2, ("%d+%d PP cores initialized\n", mali_inited_pp_cores_group_1, mali_inited_pp_cores_group_2));
592
593         return _MALI_OSK_ERR_OK;
594 }
595
596 static _mali_osk_errcode_t mali_check_shared_interrupts(void)
597 {
598 #if !defined(CONFIG_MALI_SHARED_INTERRUPTS)
599         if (MALI_TRUE == _mali_osk_shared_interrupts()) {
600                 MALI_PRINT_ERROR(("Shared interrupts detected, but driver support is not enabled\n"));
601                 return _MALI_OSK_ERR_FAULT;
602         }
603 #endif /* !defined(CONFIG_MALI_SHARED_INTERRUPTS) */
604
605         /* It is OK to compile support for shared interrupts even if Mali is not using it. */
606         return _MALI_OSK_ERR_OK;
607 }
608
609 static _mali_osk_errcode_t mali_parse_config_pmu(void)
610 {
611         _mali_osk_resource_t resource_pmu;
612
613         MALI_DEBUG_ASSERT(0 != global_gpu_base_address);
614
615         if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_PMU, &resource_pmu)) {
616                 struct mali_pmu_core *pmu;
617
618                 pmu = mali_pmu_create(&resource_pmu);
619                 if (NULL == pmu) {
620                         MALI_PRINT_ERROR(("Failed to create PMU\n"));
621                         return _MALI_OSK_ERR_FAULT;
622                 }
623         }
624
625         /* It's ok if the PMU doesn't exist */
626         return _MALI_OSK_ERR_OK;
627 }
628
629 static _mali_osk_errcode_t mali_parse_config_memory(void)
630 {
631         _mali_osk_device_data data = { 0, };
632         _mali_osk_errcode_t ret;
633
634         /* The priority of setting the value of mali_shared_mem_size,
635          * mali_dedicated_mem_start and mali_dedicated_mem_size:
636          * 1. module parameter;
637          * 2. platform data;
638          * 3. default value;
639          **/
640         if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
641                 /* Memory settings are not overridden by module parameters, so use device settings */
642                 if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size) {
643                         /* Use device specific settings (if defined) */
644                         mali_dedicated_mem_start = data.dedicated_mem_start;
645                         mali_dedicated_mem_size = data.dedicated_mem_size;
646                 }
647
648                 if (MALI_SHARED_MEMORY_DEFAULT_SIZE == mali_shared_mem_size &&
649                     0 != data.shared_mem_size) {
650                         mali_shared_mem_size = data.shared_mem_size;
651                 }
652         }
653
654         if (0 < mali_dedicated_mem_size && 0 != mali_dedicated_mem_start) {
655                 MALI_DEBUG_PRINT(2, ("Mali memory settings (dedicated: 0x%08X@0x%08X)\n",
656                                      mali_dedicated_mem_size, mali_dedicated_mem_start));
657
658                 /* Dedicated memory */
659                 ret = mali_memory_core_resource_dedicated_memory(mali_dedicated_mem_start, mali_dedicated_mem_size);
660                 if (_MALI_OSK_ERR_OK != ret) {
661                         MALI_PRINT_ERROR(("Failed to register dedicated memory\n"));
662                         mali_memory_terminate();
663                         return ret;
664                 }
665         }
666
667         if (0 < mali_shared_mem_size) {
668                 MALI_DEBUG_PRINT(2, ("Mali memory settings (shared: 0x%08X)\n", mali_shared_mem_size));
669
670                 /* Shared OS memory */
671                 ret = mali_memory_core_resource_os_memory(mali_shared_mem_size);
672                 if (_MALI_OSK_ERR_OK != ret) {
673                         MALI_PRINT_ERROR(("Failed to register shared OS memory\n"));
674                         mali_memory_terminate();
675                         return ret;
676                 }
677         }
678
679         if (0 == mali_fb_start && 0 == mali_fb_size) {
680                 /* Frame buffer settings are not overridden by module parameters, so use device settings */
681                 _mali_osk_device_data data = { 0, };
682
683                 if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
684                         /* Use device specific settings (if defined) */
685                         mali_fb_start = data.fb_start;
686                         mali_fb_size = data.fb_size;
687                 }
688
689                 MALI_DEBUG_PRINT(2, ("Using device defined frame buffer settings (0x%08X@0x%08X)\n",
690                                      mali_fb_size, mali_fb_start));
691         } else {
692                 MALI_DEBUG_PRINT(2, ("Using module defined frame buffer settings (0x%08X@0x%08X)\n",
693                                      mali_fb_size, mali_fb_start));
694         }
695
696         if (0 != mali_fb_size) {
697                 /* Register frame buffer */
698                 ret = mali_mem_validation_add_range(mali_fb_start, mali_fb_size);
699                 if (_MALI_OSK_ERR_OK != ret) {
700                         MALI_PRINT_ERROR(("Failed to register frame buffer memory region\n"));
701                         mali_memory_terminate();
702                         return ret;
703                 }
704         }
705
706         return _MALI_OSK_ERR_OK;
707 }
708
709 static void mali_detect_gpu_class(void)
710 {
711         if (_mali_osk_identify_gpu_resource() == 0x450)
712                 mali_gpu_class_is_mali450 = MALI_TRUE;
713
714         if (_mali_osk_identify_gpu_resource() == 0x470)
715                 mali_gpu_class_is_mali470 = MALI_TRUE;
716 }
717
718 static _mali_osk_errcode_t mali_init_hw_reset(void)
719 {
720 #if (defined(CONFIG_MALI450) || defined(CONFIG_MALI470))
721         _mali_osk_resource_t resource_bcast;
722
723         /* Ensure broadcast unit is in a good state before we start creating
724          * groups and cores.
725          */
726         if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_BCAST, &resource_bcast)) {
727                 struct mali_bcast_unit *bcast_core;
728
729                 bcast_core = mali_bcast_unit_create(&resource_bcast);
730                 if (NULL == bcast_core) {
731                         MALI_PRINT_ERROR(("Failed to create Broadcast unit object!\n"));
732                         return _MALI_OSK_ERR_FAULT;
733                 }
734                 mali_bcast_unit_delete(bcast_core);
735         }
736 #endif /* (defined(CONFIG_MALI450) || defined(CONFIG_MALI470)) */
737
738         return _MALI_OSK_ERR_OK;
739 }
740
741 _mali_osk_errcode_t mali_initialize_subsystems(void)
742 {
743         _mali_osk_errcode_t err;
744
745 #ifdef CONFIG_MALI_DT
746         err = _mali_osk_resource_initialize();
747         if (_MALI_OSK_ERR_OK != err) {
748                 mali_terminate_subsystems();
749                 return err;
750         }
751 #endif
752
753         mali_pp_job_initialize();
754
755         mali_timeline_initialize();
756
757         err = mali_session_initialize();
758         if (_MALI_OSK_ERR_OK != err) {
759                 mali_terminate_subsystems();
760                 return err;
761         }
762
763         /*Try to init gpu secure mode */
764         _mali_osk_gpu_secure_mode_init();
765
766 #if defined(CONFIG_MALI400_PROFILING)
767         err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
768         if (_MALI_OSK_ERR_OK != err) {
769                 /* No biggie if we weren't able to initialize the profiling */
770                 MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
771         }
772 #endif
773
774         err = mali_memory_initialize();
775         if (_MALI_OSK_ERR_OK != err) {
776                 mali_terminate_subsystems();
777                 return err;
778         }
779
780         err = mali_executor_initialize();
781         if (_MALI_OSK_ERR_OK != err) {
782                 mali_terminate_subsystems();
783                 return err;
784         }
785
786         err = mali_scheduler_initialize();
787         if (_MALI_OSK_ERR_OK != err) {
788                 mali_terminate_subsystems();
789                 return err;
790         }
791
792         /* Configure memory early, needed by mali_mmu_initialize. */
793         err = mali_parse_config_memory();
794         if (_MALI_OSK_ERR_OK != err) {
795                 mali_terminate_subsystems();
796                 return err;
797         }
798
799         err = mali_set_global_gpu_base_address();
800         if (_MALI_OSK_ERR_OK != err) {
801                 mali_terminate_subsystems();
802                 return err;
803         }
804
805         /* Detect GPU class (uses L2 cache count) */
806         mali_detect_gpu_class();
807
808         err = mali_check_shared_interrupts();
809         if (_MALI_OSK_ERR_OK != err) {
810                 mali_terminate_subsystems();
811                 return err;
812         }
813
814         /* Initialize the MALI PMU (will not touch HW!) */
815         err = mali_parse_config_pmu();
816         if (_MALI_OSK_ERR_OK != err) {
817                 mali_terminate_subsystems();
818                 return err;
819         }
820
821         /* Initialize the power management module */
822         err = mali_pm_initialize();
823         if (_MALI_OSK_ERR_OK != err) {
824                 mali_terminate_subsystems();
825                 return err;
826         }
827
828         /* Make sure the entire GPU stays on for the rest of this function */
829         mali_pm_init_begin();
830
831         /* Ensure HW is in a good state before starting to access cores. */
832         err = mali_init_hw_reset();
833         if (_MALI_OSK_ERR_OK != err) {
834                 mali_terminate_subsystems();
835                 return err;
836         }
837
838         /* Detect which Mali GPU we are dealing with */
839         err = mali_parse_product_info();
840         if (_MALI_OSK_ERR_OK != err) {
841                 mali_pm_init_end();
842                 mali_terminate_subsystems();
843                 return err;
844         }
845
846         /* The global_product_id is now populated with the correct Mali GPU */
847
848         /* Start configuring the actual Mali hardware. */
849
850         err = mali_mmu_initialize();
851         if (_MALI_OSK_ERR_OK != err) {
852                 mali_pm_init_end();
853                 mali_terminate_subsystems();
854                 return err;
855         }
856
857         if (mali_is_mali450() || mali_is_mali470()) {
858                 err = mali_dlbu_initialize();
859                 if (_MALI_OSK_ERR_OK != err) {
860                         mali_pm_init_end();
861                         mali_terminate_subsystems();
862                         return err;
863                 }
864         }
865
866         err = mali_parse_config_l2_cache();
867         if (_MALI_OSK_ERR_OK != err) {
868                 mali_pm_init_end();
869                 mali_terminate_subsystems();
870                 return err;
871         }
872
873         err = mali_parse_config_groups();
874         if (_MALI_OSK_ERR_OK != err) {
875                 mali_pm_init_end();
876                 mali_terminate_subsystems();
877                 return err;
878         }
879
880         /* Move groups into executor */
881         mali_executor_populate();
882
883         /* Need call after all group has assigned a domain */
884         mali_pm_power_cost_setup();
885
886         /* Initialize the GPU timer */
887         err = mali_control_timer_init();
888         if (_MALI_OSK_ERR_OK != err) {
889                 mali_pm_init_end();
890                 mali_terminate_subsystems();
891                 return err;
892         }
893
894         /* Initialize the GPU utilization tracking */
895         err = mali_utilization_init();
896         if (_MALI_OSK_ERR_OK != err) {
897                 mali_pm_init_end();
898                 mali_terminate_subsystems();
899                 return err;
900         }
901
902 #if defined(CONFIG_MALI_DVFS)
903         err = mali_dvfs_policy_init();
904         if (_MALI_OSK_ERR_OK != err) {
905                 mali_pm_init_end();
906                 mali_terminate_subsystems();
907                 return err;
908         }
909 #endif
910
911         /* Allowing the system to be turned off */
912         mali_pm_init_end();
913
914         return _MALI_OSK_ERR_OK; /* all ok */
915 }
916
917 void mali_terminate_subsystems(void)
918 {
919         struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
920
921         MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
922
923         mali_utilization_term();
924         mali_control_timer_term();
925
926         mali_executor_depopulate();
927         mali_delete_groups(); /* Delete groups not added to executor */
928         mali_executor_terminate();
929
930         mali_scheduler_terminate();
931         mali_pp_job_terminate();
932         mali_delete_l2_cache_cores();
933         mali_mmu_terminate();
934
935         if (mali_is_mali450() || mali_is_mali470()) {
936                 mali_dlbu_terminate();
937         }
938
939         mali_pm_terminate();
940
941         if (NULL != pmu) {
942                 mali_pmu_delete(pmu);
943         }
944
945 #if defined(CONFIG_MALI400_PROFILING)
946         _mali_osk_profiling_term();
947 #endif
948
949         _mali_osk_gpu_secure_mode_deinit();
950
951         mali_memory_terminate();
952
953         mali_session_terminate();
954
955         mali_timeline_terminate();
956
957         global_gpu_base_address = 0;
958 }
959
960 _mali_product_id_t mali_kernel_core_get_product_id(void)
961 {
962         return global_product_id;
963 }
964
965 u32 mali_kernel_core_get_gpu_major_version(void)
966 {
967         return global_gpu_major_version;
968 }
969
970 u32 mali_kernel_core_get_gpu_minor_version(void)
971 {
972         return global_gpu_minor_version;
973 }
974
975 _mali_osk_errcode_t _mali_ukk_get_api_version(_mali_uk_get_api_version_s *args)
976 {
977         MALI_DEBUG_ASSERT_POINTER(args);
978         MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
979
980         /* check compatability */
981         if (args->version == _MALI_UK_API_VERSION) {
982                 args->compatible = 1;
983         } else {
984                 args->compatible = 0;
985         }
986
987         args->version = _MALI_UK_API_VERSION; /* report our version */
988
989         /* success regardless of being compatible or not */
990         MALI_SUCCESS;
991 }
992
993 _mali_osk_errcode_t _mali_ukk_get_api_version_v2(_mali_uk_get_api_version_v2_s *args)
994 {
995         MALI_DEBUG_ASSERT_POINTER(args);
996         MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
997
998         /* check compatability */
999         if (args->version == _MALI_UK_API_VERSION) {
1000                 args->compatible = 1;
1001         } else {
1002                 args->compatible = 0;
1003         }
1004
1005         args->version = _MALI_UK_API_VERSION; /* report our version */
1006
1007         /* success regardless of being compatible or not */
1008         return _MALI_OSK_ERR_OK;
1009 }
1010
1011 _mali_osk_errcode_t _mali_ukk_wait_for_notification(_mali_uk_wait_for_notification_s *args)
1012 {
1013         _mali_osk_errcode_t err;
1014         _mali_osk_notification_t *notification;
1015         _mali_osk_notification_queue_t *queue;
1016         struct mali_session_data *session;
1017
1018         /* check input */
1019         MALI_DEBUG_ASSERT_POINTER(args);
1020         MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1021
1022         session = (struct mali_session_data *)(uintptr_t)args->ctx;
1023         queue = session->ioctl_queue;
1024
1025         /* if the queue does not exist we're currently shutting down */
1026         if (NULL == queue) {
1027                 MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
1028                 args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS;
1029                 return _MALI_OSK_ERR_OK;
1030         }
1031
1032         /* receive a notification, might sleep */
1033         err = _mali_osk_notification_queue_receive(queue, &notification);
1034         if (_MALI_OSK_ERR_OK != err) {
1035                 MALI_ERROR(err); /* errcode returned, pass on to caller */
1036         }
1037
1038         /* copy the buffer to the user */
1039         args->type = (_mali_uk_notification_type)notification->notification_type;
1040         _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size);
1041
1042         /* finished with the notification */
1043         _mali_osk_notification_delete(notification);
1044
1045         return _MALI_OSK_ERR_OK; /* all ok */
1046 }
1047
1048 _mali_osk_errcode_t _mali_ukk_post_notification(_mali_uk_post_notification_s *args)
1049 {
1050         _mali_osk_notification_t *notification;
1051         _mali_osk_notification_queue_t *queue;
1052         struct mali_session_data *session;
1053
1054         /* check input */
1055         MALI_DEBUG_ASSERT_POINTER(args);
1056         MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1057
1058         session = (struct mali_session_data *)(uintptr_t)args->ctx;
1059         queue = session->ioctl_queue;
1060
1061         /* if the queue does not exist we're currently shutting down */
1062         if (NULL == queue) {
1063                 MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
1064                 return _MALI_OSK_ERR_OK;
1065         }
1066
1067         notification = _mali_osk_notification_create(args->type, 0);
1068         if (NULL == notification) {
1069                 MALI_PRINT_ERROR(("Failed to create notification object\n"));
1070                 return _MALI_OSK_ERR_NOMEM;
1071         }
1072
1073         _mali_osk_notification_queue_send(queue, notification);
1074
1075         return _MALI_OSK_ERR_OK; /* all ok */
1076 }
1077
1078 _mali_osk_errcode_t _mali_ukk_pending_submit(_mali_uk_pending_submit_s *args)
1079 {
1080         wait_queue_head_t *queue;
1081
1082         /* check input */
1083         MALI_DEBUG_ASSERT_POINTER(args);
1084         MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1085
1086         queue = mali_session_get_wait_queue();
1087
1088         /* check pending big job number, might sleep if larger than MAX allowed number */
1089         if (wait_event_interruptible(*queue, MALI_MAX_PENDING_BIG_JOB > mali_scheduler_job_gp_big_job_count())) {
1090                 return _MALI_OSK_ERR_RESTARTSYSCALL;
1091         }
1092
1093         return _MALI_OSK_ERR_OK; /* all ok */
1094 }
1095
1096
1097 _mali_osk_errcode_t _mali_ukk_request_high_priority(_mali_uk_request_high_priority_s *args)
1098 {
1099         struct mali_session_data *session;
1100
1101         MALI_DEBUG_ASSERT_POINTER(args);
1102         MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1103
1104         session = (struct mali_session_data *)(uintptr_t)args->ctx;
1105
1106         if (!session->use_high_priority_job_queue) {
1107                 session->use_high_priority_job_queue = MALI_TRUE;
1108                 MALI_DEBUG_PRINT(2, ("Session 0x%08X with pid %d was granted higher priority.\n", session, _mali_osk_get_pid()));
1109         }
1110
1111         return _MALI_OSK_ERR_OK;
1112 }
1113
1114 _mali_osk_errcode_t _mali_ukk_open(void **context)
1115 {
1116         u32 i;
1117         struct mali_session_data *session;
1118
1119         /* allocated struct to track this session */
1120         session = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data));
1121         MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_NOMEM);
1122
1123         MALI_DEBUG_PRINT(3, ("Session starting\n"));
1124
1125         /* create a response queue for this session */
1126         session->ioctl_queue = _mali_osk_notification_queue_init();
1127         if (NULL == session->ioctl_queue) {
1128                 goto err;
1129         }
1130
1131         /*create a wait queue for this session */
1132         session->wait_queue = _mali_osk_wait_queue_init();
1133         if (NULL == session->wait_queue) {
1134                 goto err_wait_queue;
1135         }
1136
1137         session->page_directory = mali_mmu_pagedir_alloc();
1138         if (NULL == session->page_directory) {
1139                 goto err_mmu;
1140         }
1141
1142         if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session->page_directory, MALI_DLBU_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE)) {
1143                 MALI_PRINT_ERROR(("Failed to map DLBU page into session\n"));
1144                 goto err_mmu;
1145         }
1146
1147         if (0 != mali_dlbu_phys_addr) {
1148                 mali_mmu_pagedir_update(session->page_directory, MALI_DLBU_VIRT_ADDR, mali_dlbu_phys_addr,
1149                                         _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT);
1150         }
1151
1152         if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session)) {
1153                 goto err_session;
1154         }
1155
1156         /* Create soft system. */
1157         session->soft_job_system = mali_soft_job_system_create(session);
1158         if (NULL == session->soft_job_system) {
1159                 goto err_soft;
1160         }
1161
1162         /* Initialize the dma fence context.*/
1163 #if defined(CONFIG_MALI_DMA_BUF_FENCE)
1164 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
1165         session->fence_context = fence_context_alloc(1);
1166         _mali_osk_atomic_init(&session->fence_seqno, 0);
1167 #else
1168         MALI_PRINT_ERROR(("The kernel version not support dma fence!\n"));
1169         goto err_time_line;
1170 #endif
1171 #endif
1172
1173         /* Create timeline system. */
1174         session->timeline_system = mali_timeline_system_create(session);
1175         if (NULL == session->timeline_system) {
1176                 goto err_time_line;
1177         }
1178
1179 #if defined(CONFIG_MALI_DVFS)
1180         _mali_osk_atomic_init(&session->number_of_window_jobs, 0);
1181 #endif
1182
1183         _mali_osk_atomic_init(&session->number_of_pp_jobs, 0);
1184
1185         session->use_high_priority_job_queue = MALI_FALSE;
1186
1187         /* Initialize list of PP jobs on this session. */
1188         _MALI_OSK_INIT_LIST_HEAD(&session->pp_job_list);
1189
1190         /* Initialize the pp_job_fb_lookup_list array used to quickly lookup jobs from a given frame builder */
1191         for (i = 0; i < MALI_PP_JOB_FB_LOOKUP_LIST_SIZE; ++i) {
1192                 _MALI_OSK_INIT_LIST_HEAD(&session->pp_job_fb_lookup_list[i]);
1193         }
1194
1195         session->pid = _mali_osk_get_pid();
1196         session->comm = _mali_osk_get_comm();
1197         session->max_mali_mem_allocated_size = 0;
1198         for (i = 0; i < MALI_MEM_TYPE_MAX; i ++) {
1199                 atomic_set(&session->mali_mem_array[i], 0);
1200         }
1201         atomic_set(&session->mali_mem_allocated_pages, 0);
1202         *context = (void *)session;
1203
1204         /* Add session to the list of all sessions. */
1205         mali_session_add(session);
1206
1207         MALI_DEBUG_PRINT(3, ("Session started\n"));
1208         return _MALI_OSK_ERR_OK;
1209
1210 err_time_line:
1211         mali_soft_job_system_destroy(session->soft_job_system);
1212 err_soft:
1213         mali_memory_session_end(session);
1214 err_session:
1215         mali_mmu_pagedir_free(session->page_directory);
1216 err_mmu:
1217         _mali_osk_wait_queue_term(session->wait_queue);
1218 err_wait_queue:
1219         _mali_osk_notification_queue_term(session->ioctl_queue);
1220 err:
1221         _mali_osk_free(session);
1222         MALI_ERROR(_MALI_OSK_ERR_NOMEM);
1223
1224 }
1225
1226 #if defined(DEBUG)
1227 /* parameter used for debug */
1228 extern u32 num_pm_runtime_resume;
1229 extern u32 num_pm_updates;
1230 extern u32 num_pm_updates_up;
1231 extern u32 num_pm_updates_down;
1232 #endif
1233
1234 _mali_osk_errcode_t _mali_ukk_close(void **context)
1235 {
1236         struct mali_session_data *session;
1237         MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
1238         session = (struct mali_session_data *)*context;
1239
1240         MALI_DEBUG_PRINT(3, ("Session ending\n"));
1241
1242         MALI_DEBUG_ASSERT_POINTER(session->soft_job_system);
1243         MALI_DEBUG_ASSERT_POINTER(session->timeline_system);
1244
1245         /* Remove session from list of all sessions. */
1246         mali_session_remove(session);
1247
1248         /* This flag is used to prevent queueing of jobs due to activation. */
1249         session->is_aborting = MALI_TRUE;
1250
1251         /* Stop the soft job timer. */
1252         mali_timeline_system_stop_timer(session->timeline_system);
1253
1254         /* Abort queued jobs */
1255         mali_scheduler_abort_session(session);
1256
1257         /* Abort executing jobs */
1258         mali_executor_abort_session(session);
1259
1260         /* Abort the soft job system. */
1261         mali_soft_job_system_abort(session->soft_job_system);
1262
1263         /* Force execution of all pending bottom half processing for GP and PP. */
1264         _mali_osk_wq_flush();
1265
1266         /* The session PP list should now be empty. */
1267         MALI_DEBUG_ASSERT(_mali_osk_list_empty(&session->pp_job_list));
1268
1269         /* At this point the GP and PP scheduler no longer has any jobs queued or running from this
1270          * session, and all soft jobs in the soft job system has been destroyed. */
1271
1272         /* Any trackers left in the timeline system are directly or indirectly waiting on external
1273          * sync fences.  Cancel all sync fence waiters to trigger activation of all remaining
1274          * trackers.  This call will sleep until all timelines are empty. */
1275         mali_timeline_system_abort(session->timeline_system);
1276
1277         /* Flush pending work.
1278          * Needed to make sure all bottom half processing related to this
1279          * session has been completed, before we free internal data structures.
1280          */
1281         _mali_osk_wq_flush();
1282
1283         /* Destroy timeline system. */
1284         mali_timeline_system_destroy(session->timeline_system);
1285         session->timeline_system = NULL;
1286
1287         /* Destroy soft system. */
1288         mali_soft_job_system_destroy(session->soft_job_system);
1289         session->soft_job_system = NULL;
1290
1291         /*Wait for the session job lists become empty.*/
1292         _mali_osk_wait_queue_wait_event(session->wait_queue, mali_session_pp_job_is_empty, (void *) session);
1293
1294         /* Free remaining memory allocated to this session */
1295         mali_memory_session_end(session);
1296
1297 #if defined(CONFIG_MALI_DVFS)
1298         _mali_osk_atomic_term(&session->number_of_window_jobs);
1299 #endif
1300
1301 #if defined(CONFIG_MALI400_PROFILING)
1302         _mali_osk_profiling_stop_sampling(session->pid);
1303 #endif
1304
1305         /* Free session data structures */
1306         mali_mmu_pagedir_unmap(session->page_directory, MALI_DLBU_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE);
1307         mali_mmu_pagedir_free(session->page_directory);
1308         _mali_osk_wait_queue_term(session->wait_queue);
1309         _mali_osk_notification_queue_term(session->ioctl_queue);
1310         _mali_osk_free(session);
1311
1312         *context = NULL;
1313
1314         MALI_DEBUG_PRINT(3, ("Session has ended\n"));
1315
1316 #if defined(DEBUG)
1317         MALI_DEBUG_PRINT(3, ("Stats: # runtime resumes: %u\n", num_pm_runtime_resume));
1318         MALI_DEBUG_PRINT(3, ("       # PM updates: .... %u (up %u, down %u)\n", num_pm_updates, num_pm_updates_up, num_pm_updates_down));
1319
1320         num_pm_runtime_resume = 0;
1321         num_pm_updates = 0;
1322         num_pm_updates_up = 0;
1323         num_pm_updates_down = 0;
1324 #endif
1325
1326         return _MALI_OSK_ERR_OK;;
1327 }
1328
1329 #if MALI_STATE_TRACKING
1330 u32 _mali_kernel_core_dump_state(char *buf, u32 size)
1331 {
1332         int n = 0; /* Number of bytes written to buf */
1333
1334         n += mali_scheduler_dump_state(buf + n, size - n);
1335         n += mali_executor_dump_state(buf + n, size - n);
1336
1337         return n;
1338 }
1339 #endif