2 * Copyright (C) 2010-2016 ARM Limited. All rights reserved.
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.
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.
11 #include "mali_kernel_common.h"
12 #include "mali_session.h"
14 #include "mali_osk_mali.h"
16 #include "mali_kernel_core.h"
17 #include "mali_memory.h"
18 #include "mali_mem_validation.h"
20 #include "mali_mmu_page_directory.h"
21 #include "mali_dlbu.h"
22 #include "mali_broadcast.h"
25 #include "mali_executor.h"
26 #include "mali_pp_job.h"
27 #include "mali_group.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"
39 #if defined(CONFIG_MALI400_INTERNAL_PROFILING)
40 #include "mali_profiling_internal.h"
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>
50 #define MALI_SHARED_MEMORY_DEFAULT_SIZE 0xffffffff
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;
56 /* Default shared memory size is set to 4G. */
57 unsigned int mali_shared_mem_size = MALI_SHARED_MEMORY_DEFAULT_SIZE;
59 /* Frame buffer memory to be accessible by Mali GPU */
60 int mali_fb_start = 0;
63 /* Mali max job runtime */
64 extern int mali_max_job_runtime;
66 /** Start profiling from module load? */
67 int mali_boot_profiling = 0;
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;
73 int mali_inited_pp_cores_group_1 = 0;
74 int mali_inited_pp_cores_group_2 = 0;
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;
81 mali_bool mali_gpu_class_is_mali450 = MALI_FALSE;
82 mali_bool mali_gpu_class_is_mali470 = MALI_FALSE;
84 static _mali_osk_errcode_t mali_set_global_gpu_base_address(void)
86 _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
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;
96 static u32 mali_get_bcast_id(_mali_osk_resource_t *resource_pp)
98 switch (resource_pp->base - global_gpu_base_address) {
100 case 0x20000: /* fall-through for aliased mapping */
103 case 0x22000: /* fall-through for aliased mapping */
106 case 0x24000: /* fall-through for aliased mapping */
109 case 0x26000: /* fall-through for aliased mapping */
124 static _mali_osk_errcode_t mali_parse_product_info(void)
126 _mali_osk_resource_t first_pp_resource;
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);
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) {
137 pp_version = mali_pp_core_get_version(pp_core);
139 mali_group_delete(group);
141 global_gpu_major_version = (pp_version >> 8) & 0xFF;
142 global_gpu_minor_version = pp_version & 0xFF;
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"));
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));
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));
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));
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));
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;
172 return _MALI_OSK_ERR_OK;
174 MALI_PRINT_ERROR(("Failed to create initial PP object\n"));
177 MALI_PRINT_ERROR(("Failed to create initial group object\n"));
180 MALI_PRINT_ERROR(("First PP core not specified in config file\n"));
183 return _MALI_OSK_ERR_FAULT;
186 static void mali_delete_groups(void)
188 struct mali_group *group;
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);
196 MALI_DEBUG_ASSERT(0 == mali_group_get_glob_num_groups());
199 static void mali_delete_l2_cache_cores(void)
201 struct mali_l2_cache_core *l2;
203 l2 = mali_l2_cache_core_get_glob_l2_core(0);
205 mali_l2_cache_delete(l2);
206 l2 = mali_l2_cache_core_get_glob_l2_core(0);
209 MALI_DEBUG_ASSERT(0 == mali_l2_cache_core_get_glob_num_l2_cores());
212 static struct mali_l2_cache_core *mali_create_l2_cache_core(_mali_osk_resource_t *resource, u32 domain_index)
214 struct mali_l2_cache_core *l2_cache = NULL;
216 if (NULL != resource) {
218 MALI_DEBUG_PRINT(3, ("Found L2 cache %s\n", resource->description));
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"));
226 MALI_DEBUG_PRINT(3, ("Created L2 cache core object\n"));
231 static _mali_osk_errcode_t mali_parse_config_l2_cache(void)
233 struct mali_l2_cache_core *l2_cache = NULL;
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;
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;
246 } else if (mali_is_mali450()) {
248 * L2 for GP at 0x10000
249 * L2 for PP0-3 at 0x01000
250 * L2 for PP4-7 at 0x11000 (optional)
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;
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;
265 MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
266 return _MALI_OSK_ERR_FAULT;
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;
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;
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;
289 } else if (mali_is_mali470()) {
290 _mali_osk_resource_t l2c1_resource;
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;
300 MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for L2C1\n"));
301 return _MALI_OSK_ERR_FAULT;
305 return _MALI_OSK_ERR_OK;
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,
314 struct mali_mmu_core *mmu;
315 struct mali_group *group;
317 MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
319 /* Create the group object */
320 group = mali_group_create(cache, NULL, NULL, domain_index);
322 MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
326 /* Create the MMU object inside group */
327 mmu = mali_mmu_create(resource_mmu, group, MALI_FALSE);
329 MALI_PRINT_ERROR(("Failed to create MMU object\n"));
330 mali_group_delete(group);
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);
345 if (NULL != resource_pp) {
346 struct mali_pp_core *pp_core;
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);
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)
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;
372 MALI_DEBUG_PRINT(2, ("Starting new virtual group for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
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;
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;
389 /* Create the group object */
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. */
395 struct mali_group *phys_group = NULL;
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;
401 MALI_DEBUG_ASSERT(NULL != mali_group_get_pp_core(phys_group));
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
408 * When the virtual group gets populated, the actually used
409 * groups will be added to the broadcast unit and the HW will
412 mali_bcast_add_group(bcast_core, phys_group);
413 mali_bcast_reset(bcast_core);
414 mali_bcast_remove_group(bcast_core, phys_group);
417 group = mali_group_create(NULL, dlbu_core, bcast_core, MALI_DOMAIN_INDEX_DUMMY);
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;
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;
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;
442 return _MALI_OSK_ERR_OK;
445 static _mali_osk_errcode_t mali_parse_config_groups(void)
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;
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;
470 if (!(mali_is_mali400() || mali_is_mali450() || mali_is_mali470())) {
471 /* No known HW core */
472 return _MALI_OSK_ERR_FAULT;
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, };
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;
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;
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]));
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);
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;
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;
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);
541 return _MALI_OSK_ERR_FAULT;
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);
548 return _MALI_OSK_ERR_FAULT;
551 mali_inited_pp_cores_group_1++;
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);
559 return _MALI_OSK_ERR_FAULT;
562 mali_inited_pp_cores_group_1++;
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);
574 return _MALI_OSK_ERR_FAULT;
577 mali_inited_pp_cores_group_2++;
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) {
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));
593 return _MALI_OSK_ERR_OK;
596 static _mali_osk_errcode_t mali_check_shared_interrupts(void)
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;
603 #endif /* !defined(CONFIG_MALI_SHARED_INTERRUPTS) */
605 /* It is OK to compile support for shared interrupts even if Mali is not using it. */
606 return _MALI_OSK_ERR_OK;
609 static _mali_osk_errcode_t mali_parse_config_pmu(void)
611 _mali_osk_resource_t resource_pmu;
613 MALI_DEBUG_ASSERT(0 != global_gpu_base_address);
615 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_PMU, &resource_pmu)) {
616 struct mali_pmu_core *pmu;
618 pmu = mali_pmu_create(&resource_pmu);
620 MALI_PRINT_ERROR(("Failed to create PMU\n"));
621 return _MALI_OSK_ERR_FAULT;
625 /* It's ok if the PMU doesn't exist */
626 return _MALI_OSK_ERR_OK;
629 static _mali_osk_errcode_t mali_parse_config_memory(void)
631 _mali_osk_device_data data = { 0, };
632 _mali_osk_errcode_t ret;
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;
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;
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;
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));
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();
667 if (0 < mali_shared_mem_size) {
668 MALI_DEBUG_PRINT(2, ("Mali memory settings (shared: 0x%08X)\n", mali_shared_mem_size));
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();
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, };
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;
689 MALI_DEBUG_PRINT(2, ("Using device defined frame buffer settings (0x%08X@0x%08X)\n",
690 mali_fb_size, mali_fb_start));
692 MALI_DEBUG_PRINT(2, ("Using module defined frame buffer settings (0x%08X@0x%08X)\n",
693 mali_fb_size, mali_fb_start));
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();
706 return _MALI_OSK_ERR_OK;
709 static void mali_detect_gpu_class(void)
711 if (_mali_osk_identify_gpu_resource() == 0x450)
712 mali_gpu_class_is_mali450 = MALI_TRUE;
714 if (_mali_osk_identify_gpu_resource() == 0x470)
715 mali_gpu_class_is_mali470 = MALI_TRUE;
718 static _mali_osk_errcode_t mali_init_hw_reset(void)
720 #if (defined(CONFIG_MALI450) || defined(CONFIG_MALI470))
721 _mali_osk_resource_t resource_bcast;
723 /* Ensure broadcast unit is in a good state before we start creating
726 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_BCAST, &resource_bcast)) {
727 struct mali_bcast_unit *bcast_core;
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;
734 mali_bcast_unit_delete(bcast_core);
736 #endif /* (defined(CONFIG_MALI450) || defined(CONFIG_MALI470)) */
738 return _MALI_OSK_ERR_OK;
741 _mali_osk_errcode_t mali_initialize_subsystems(void)
743 _mali_osk_errcode_t err;
745 #ifdef CONFIG_MALI_DT
746 err = _mali_osk_resource_initialize();
747 if (_MALI_OSK_ERR_OK != err) {
748 mali_terminate_subsystems();
753 mali_pp_job_initialize();
755 mali_timeline_initialize();
757 err = mali_session_initialize();
758 if (_MALI_OSK_ERR_OK != err) {
759 mali_terminate_subsystems();
763 /*Try to init gpu secure mode */
764 _mali_osk_gpu_secure_mode_init();
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"));
774 err = mali_memory_initialize();
775 if (_MALI_OSK_ERR_OK != err) {
776 mali_terminate_subsystems();
780 err = mali_executor_initialize();
781 if (_MALI_OSK_ERR_OK != err) {
782 mali_terminate_subsystems();
786 err = mali_scheduler_initialize();
787 if (_MALI_OSK_ERR_OK != err) {
788 mali_terminate_subsystems();
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();
799 err = mali_set_global_gpu_base_address();
800 if (_MALI_OSK_ERR_OK != err) {
801 mali_terminate_subsystems();
805 /* Detect GPU class (uses L2 cache count) */
806 mali_detect_gpu_class();
808 err = mali_check_shared_interrupts();
809 if (_MALI_OSK_ERR_OK != err) {
810 mali_terminate_subsystems();
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();
821 /* Initialize the power management module */
822 err = mali_pm_initialize();
823 if (_MALI_OSK_ERR_OK != err) {
824 mali_terminate_subsystems();
828 /* Make sure the entire GPU stays on for the rest of this function */
829 mali_pm_init_begin();
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();
838 /* Detect which Mali GPU we are dealing with */
839 err = mali_parse_product_info();
840 if (_MALI_OSK_ERR_OK != err) {
842 mali_terminate_subsystems();
846 /* The global_product_id is now populated with the correct Mali GPU */
848 /* Start configuring the actual Mali hardware. */
850 err = mali_mmu_initialize();
851 if (_MALI_OSK_ERR_OK != err) {
853 mali_terminate_subsystems();
857 if (mali_is_mali450() || mali_is_mali470()) {
858 err = mali_dlbu_initialize();
859 if (_MALI_OSK_ERR_OK != err) {
861 mali_terminate_subsystems();
866 err = mali_parse_config_l2_cache();
867 if (_MALI_OSK_ERR_OK != err) {
869 mali_terminate_subsystems();
873 err = mali_parse_config_groups();
874 if (_MALI_OSK_ERR_OK != err) {
876 mali_terminate_subsystems();
880 /* Move groups into executor */
881 mali_executor_populate();
883 /* Need call after all group has assigned a domain */
884 mali_pm_power_cost_setup();
886 /* Initialize the GPU timer */
887 err = mali_control_timer_init();
888 if (_MALI_OSK_ERR_OK != err) {
890 mali_terminate_subsystems();
894 /* Initialize the GPU utilization tracking */
895 err = mali_utilization_init();
896 if (_MALI_OSK_ERR_OK != err) {
898 mali_terminate_subsystems();
902 #if defined(CONFIG_MALI_DVFS)
903 err = mali_dvfs_policy_init();
904 if (_MALI_OSK_ERR_OK != err) {
906 mali_terminate_subsystems();
911 /* Allowing the system to be turned off */
914 return _MALI_OSK_ERR_OK; /* all ok */
917 void mali_terminate_subsystems(void)
919 struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
921 MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
923 mali_utilization_term();
924 mali_control_timer_term();
926 mali_executor_depopulate();
927 mali_delete_groups(); /* Delete groups not added to executor */
928 mali_executor_terminate();
930 mali_scheduler_terminate();
931 mali_pp_job_terminate();
932 mali_delete_l2_cache_cores();
933 mali_mmu_terminate();
935 if (mali_is_mali450() || mali_is_mali470()) {
936 mali_dlbu_terminate();
942 mali_pmu_delete(pmu);
945 #if defined(CONFIG_MALI400_PROFILING)
946 _mali_osk_profiling_term();
949 _mali_osk_gpu_secure_mode_deinit();
951 mali_memory_terminate();
953 mali_session_terminate();
955 mali_timeline_terminate();
957 global_gpu_base_address = 0;
960 _mali_product_id_t mali_kernel_core_get_product_id(void)
962 return global_product_id;
965 u32 mali_kernel_core_get_gpu_major_version(void)
967 return global_gpu_major_version;
970 u32 mali_kernel_core_get_gpu_minor_version(void)
972 return global_gpu_minor_version;
975 _mali_osk_errcode_t _mali_ukk_get_api_version(_mali_uk_get_api_version_s *args)
977 MALI_DEBUG_ASSERT_POINTER(args);
978 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
980 /* check compatability */
981 if (args->version == _MALI_UK_API_VERSION) {
982 args->compatible = 1;
984 args->compatible = 0;
987 args->version = _MALI_UK_API_VERSION; /* report our version */
989 /* success regardless of being compatible or not */
993 _mali_osk_errcode_t _mali_ukk_get_api_version_v2(_mali_uk_get_api_version_v2_s *args)
995 MALI_DEBUG_ASSERT_POINTER(args);
996 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
998 /* check compatability */
999 if (args->version == _MALI_UK_API_VERSION) {
1000 args->compatible = 1;
1002 args->compatible = 0;
1005 args->version = _MALI_UK_API_VERSION; /* report our version */
1007 /* success regardless of being compatible or not */
1008 return _MALI_OSK_ERR_OK;
1011 _mali_osk_errcode_t _mali_ukk_wait_for_notification(_mali_uk_wait_for_notification_s *args)
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;
1019 MALI_DEBUG_ASSERT_POINTER(args);
1020 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1022 session = (struct mali_session_data *)(uintptr_t)args->ctx;
1023 queue = session->ioctl_queue;
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;
1032 /* receive a notification, might sleep */
1033 err = _mali_osk_notification_queue_receive(queue, ¬ification);
1034 if (_MALI_OSK_ERR_OK != err) {
1035 MALI_ERROR(err); /* errcode returned, pass on to caller */
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);
1042 /* finished with the notification */
1043 _mali_osk_notification_delete(notification);
1045 return _MALI_OSK_ERR_OK; /* all ok */
1048 _mali_osk_errcode_t _mali_ukk_post_notification(_mali_uk_post_notification_s *args)
1050 _mali_osk_notification_t *notification;
1051 _mali_osk_notification_queue_t *queue;
1052 struct mali_session_data *session;
1055 MALI_DEBUG_ASSERT_POINTER(args);
1056 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1058 session = (struct mali_session_data *)(uintptr_t)args->ctx;
1059 queue = session->ioctl_queue;
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;
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;
1073 _mali_osk_notification_queue_send(queue, notification);
1075 return _MALI_OSK_ERR_OK; /* all ok */
1078 _mali_osk_errcode_t _mali_ukk_pending_submit(_mali_uk_pending_submit_s *args)
1080 wait_queue_head_t *queue;
1083 MALI_DEBUG_ASSERT_POINTER(args);
1084 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1086 queue = mali_session_get_wait_queue();
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;
1093 return _MALI_OSK_ERR_OK; /* all ok */
1097 _mali_osk_errcode_t _mali_ukk_request_high_priority(_mali_uk_request_high_priority_s *args)
1099 struct mali_session_data *session;
1101 MALI_DEBUG_ASSERT_POINTER(args);
1102 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1104 session = (struct mali_session_data *)(uintptr_t)args->ctx;
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()));
1111 return _MALI_OSK_ERR_OK;
1114 _mali_osk_errcode_t _mali_ukk_open(void **context)
1117 struct mali_session_data *session;
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);
1123 MALI_DEBUG_PRINT(3, ("Session starting\n"));
1125 /* create a response queue for this session */
1126 session->ioctl_queue = _mali_osk_notification_queue_init();
1127 if (NULL == session->ioctl_queue) {
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;
1137 session->page_directory = mali_mmu_pagedir_alloc();
1138 if (NULL == session->page_directory) {
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"));
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);
1152 if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session)) {
1156 /* Create soft system. */
1157 session->soft_job_system = mali_soft_job_system_create(session);
1158 if (NULL == session->soft_job_system) {
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);
1168 MALI_PRINT_ERROR(("The kernel version not support dma fence!\n"));
1173 /* Create timeline system. */
1174 session->timeline_system = mali_timeline_system_create(session);
1175 if (NULL == session->timeline_system) {
1179 #if defined(CONFIG_MALI_DVFS)
1180 _mali_osk_atomic_init(&session->number_of_window_jobs, 0);
1183 _mali_osk_atomic_init(&session->number_of_pp_jobs, 0);
1185 session->use_high_priority_job_queue = MALI_FALSE;
1187 /* Initialize list of PP jobs on this session. */
1188 _MALI_OSK_INIT_LIST_HEAD(&session->pp_job_list);
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]);
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);
1201 atomic_set(&session->mali_mem_allocated_pages, 0);
1202 *context = (void *)session;
1204 /* Add session to the list of all sessions. */
1205 mali_session_add(session);
1207 MALI_DEBUG_PRINT(3, ("Session started\n"));
1208 return _MALI_OSK_ERR_OK;
1211 mali_soft_job_system_destroy(session->soft_job_system);
1213 mali_memory_session_end(session);
1215 mali_mmu_pagedir_free(session->page_directory);
1217 _mali_osk_wait_queue_term(session->wait_queue);
1219 _mali_osk_notification_queue_term(session->ioctl_queue);
1221 _mali_osk_free(session);
1222 MALI_ERROR(_MALI_OSK_ERR_NOMEM);
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;
1234 _mali_osk_errcode_t _mali_ukk_close(void **context)
1236 struct mali_session_data *session;
1237 MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
1238 session = (struct mali_session_data *)*context;
1240 MALI_DEBUG_PRINT(3, ("Session ending\n"));
1242 MALI_DEBUG_ASSERT_POINTER(session->soft_job_system);
1243 MALI_DEBUG_ASSERT_POINTER(session->timeline_system);
1245 /* Remove session from list of all sessions. */
1246 mali_session_remove(session);
1248 /* This flag is used to prevent queueing of jobs due to activation. */
1249 session->is_aborting = MALI_TRUE;
1251 /* Stop the soft job timer. */
1252 mali_timeline_system_stop_timer(session->timeline_system);
1254 /* Abort queued jobs */
1255 mali_scheduler_abort_session(session);
1257 /* Abort executing jobs */
1258 mali_executor_abort_session(session);
1260 /* Abort the soft job system. */
1261 mali_soft_job_system_abort(session->soft_job_system);
1263 /* Force execution of all pending bottom half processing for GP and PP. */
1264 _mali_osk_wq_flush();
1266 /* The session PP list should now be empty. */
1267 MALI_DEBUG_ASSERT(_mali_osk_list_empty(&session->pp_job_list));
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. */
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);
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.
1281 _mali_osk_wq_flush();
1283 /* Destroy timeline system. */
1284 mali_timeline_system_destroy(session->timeline_system);
1285 session->timeline_system = NULL;
1287 /* Destroy soft system. */
1288 mali_soft_job_system_destroy(session->soft_job_system);
1289 session->soft_job_system = NULL;
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);
1294 /* Free remaining memory allocated to this session */
1295 mali_memory_session_end(session);
1297 #if defined(CONFIG_MALI_DVFS)
1298 _mali_osk_atomic_term(&session->number_of_window_jobs);
1301 #if defined(CONFIG_MALI400_PROFILING)
1302 _mali_osk_profiling_stop_sampling(session->pid);
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);
1314 MALI_DEBUG_PRINT(3, ("Session has ended\n"));
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));
1320 num_pm_runtime_resume = 0;
1322 num_pm_updates_up = 0;
1323 num_pm_updates_down = 0;
1326 return _MALI_OSK_ERR_OK;;
1329 #if MALI_STATE_TRACKING
1330 u32 _mali_kernel_core_dump_state(char *buf, u32 size)
1332 int n = 0; /* Number of bytes written to buf */
1334 n += mali_scheduler_dump_state(buf + n, size - n);
1335 n += mali_executor_dump_state(buf + n, size - n);