2 * Copyright (C) 2010-2015 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>
46 #define MALI_SHARED_MEMORY_DEFAULT_SIZE 0xffffffff
48 /* Mali GPU memory. Real values come from module parameter or from device specific data */
49 unsigned int mali_dedicated_mem_start = 0;
50 unsigned int mali_dedicated_mem_size = 0;
52 /* Default shared memory size is set to 4G. */
53 unsigned int mali_shared_mem_size = MALI_SHARED_MEMORY_DEFAULT_SIZE;
55 /* Frame buffer memory to be accessible by Mali GPU */
56 int mali_fb_start = 0;
59 /* Mali max job runtime */
60 extern int mali_max_job_runtime;
62 /** Start profiling from module load? */
63 int mali_boot_profiling = 0;
65 /** Limits for the number of PP cores behind each L2 cache. */
66 int mali_max_pp_cores_group_1 = 0xFF;
67 int mali_max_pp_cores_group_2 = 0xFF;
69 int mali_inited_pp_cores_group_1 = 0;
70 int mali_inited_pp_cores_group_2 = 0;
72 static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN;
73 static uintptr_t global_gpu_base_address = 0;
74 static u32 global_gpu_major_version = 0;
75 static u32 global_gpu_minor_version = 0;
77 mali_bool mali_gpu_class_is_mali450 = MALI_FALSE;
78 mali_bool mali_gpu_class_is_mali470 = MALI_FALSE;
80 static _mali_osk_errcode_t mali_set_global_gpu_base_address(void)
82 _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
84 global_gpu_base_address = _mali_osk_resource_base_address();
85 if (0 == global_gpu_base_address) {
86 err = _MALI_OSK_ERR_ITEM_NOT_FOUND;
92 static u32 mali_get_bcast_id(_mali_osk_resource_t *resource_pp)
94 switch (resource_pp->base - global_gpu_base_address) {
96 case 0x20000: /* fall-through for aliased mapping */
99 case 0x22000: /* fall-through for aliased mapping */
102 case 0x24000: /* fall-through for aliased mapping */
105 case 0x26000: /* fall-through for aliased mapping */
120 static _mali_osk_errcode_t mali_parse_product_info(void)
122 _mali_osk_resource_t first_pp_resource;
124 /* Find the first PP core resource (again) */
125 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_PP0, &first_pp_resource)) {
126 /* Create a dummy PP object for this core so that we can read the version register */
127 struct mali_group *group = mali_group_create(NULL, NULL, NULL, MALI_DOMAIN_INDEX_PP0);
129 struct mali_pp_core *pp_core = mali_pp_create(&first_pp_resource, group, MALI_FALSE, mali_get_bcast_id(&first_pp_resource));
130 if (NULL != pp_core) {
133 pp_version = mali_pp_core_get_version(pp_core);
135 mali_group_delete(group);
137 global_gpu_major_version = (pp_version >> 8) & 0xFF;
138 global_gpu_minor_version = pp_version & 0xFF;
140 switch (pp_version >> 16) {
141 case MALI200_PP_PRODUCT_ID:
142 global_product_id = _MALI_PRODUCT_ID_MALI200;
143 MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
144 MALI_PRINT_ERROR(("Mali-200 is not supported by this driver.\n"));
147 case MALI300_PP_PRODUCT_ID:
148 global_product_id = _MALI_PRODUCT_ID_MALI300;
149 MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
151 case MALI400_PP_PRODUCT_ID:
152 global_product_id = _MALI_PRODUCT_ID_MALI400;
153 MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
155 case MALI450_PP_PRODUCT_ID:
156 global_product_id = _MALI_PRODUCT_ID_MALI450;
157 MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
159 case MALI470_PP_PRODUCT_ID:
160 global_product_id = _MALI_PRODUCT_ID_MALI470;
161 MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-470 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
164 MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version));
165 return _MALI_OSK_ERR_FAULT;
168 return _MALI_OSK_ERR_OK;
170 MALI_PRINT_ERROR(("Failed to create initial PP object\n"));
173 MALI_PRINT_ERROR(("Failed to create initial group object\n"));
176 MALI_PRINT_ERROR(("First PP core not specified in config file\n"));
179 return _MALI_OSK_ERR_FAULT;
182 static void mali_delete_groups(void)
184 struct mali_group *group;
186 group = mali_group_get_glob_group(0);
187 while (NULL != group) {
188 mali_group_delete(group);
189 group = mali_group_get_glob_group(0);
192 MALI_DEBUG_ASSERT(0 == mali_group_get_glob_num_groups());
195 static void mali_delete_l2_cache_cores(void)
197 struct mali_l2_cache_core *l2;
199 l2 = mali_l2_cache_core_get_glob_l2_core(0);
201 mali_l2_cache_delete(l2);
202 l2 = mali_l2_cache_core_get_glob_l2_core(0);
205 MALI_DEBUG_ASSERT(0 == mali_l2_cache_core_get_glob_num_l2_cores());
208 static struct mali_l2_cache_core *mali_create_l2_cache_core(_mali_osk_resource_t *resource, u32 domain_index)
210 struct mali_l2_cache_core *l2_cache = NULL;
212 if (NULL != resource) {
214 MALI_DEBUG_PRINT(3, ("Found L2 cache %s\n", resource->description));
216 l2_cache = mali_l2_cache_create(resource, domain_index);
217 if (NULL == l2_cache) {
218 MALI_PRINT_ERROR(("Failed to create L2 cache object\n"));
222 MALI_DEBUG_PRINT(3, ("Created L2 cache core object\n"));
227 static _mali_osk_errcode_t mali_parse_config_l2_cache(void)
229 struct mali_l2_cache_core *l2_cache = NULL;
231 if (mali_is_mali400()) {
232 _mali_osk_resource_t l2_resource;
233 if (_MALI_OSK_ERR_OK != _mali_osk_resource_find(MALI400_OFFSET_L2_CACHE0, &l2_resource)) {
234 MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n"));
235 return _MALI_OSK_ERR_FAULT;
238 l2_cache = mali_create_l2_cache_core(&l2_resource, MALI_DOMAIN_INDEX_L20);
239 if (NULL == l2_cache) {
240 return _MALI_OSK_ERR_FAULT;
242 } else if (mali_is_mali450()) {
244 * L2 for GP at 0x10000
245 * L2 for PP0-3 at 0x01000
246 * L2 for PP4-7 at 0x11000 (optional)
249 _mali_osk_resource_t l2_gp_resource;
250 _mali_osk_resource_t l2_pp_grp0_resource;
251 _mali_osk_resource_t l2_pp_grp1_resource;
253 /* Make cluster for GP's L2 */
254 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI450_OFFSET_L2_CACHE0, &l2_gp_resource)) {
255 MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for GP\n"));
256 l2_cache = mali_create_l2_cache_core(&l2_gp_resource, MALI_DOMAIN_INDEX_L20);
257 if (NULL == l2_cache) {
258 return _MALI_OSK_ERR_FAULT;
261 MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
262 return _MALI_OSK_ERR_FAULT;
265 /* Find corresponding l2 domain */
266 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI450_OFFSET_L2_CACHE1, &l2_pp_grp0_resource)) {
267 MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 0\n"));
268 l2_cache = mali_create_l2_cache_core(&l2_pp_grp0_resource, MALI_DOMAIN_INDEX_L21);
269 if (NULL == l2_cache) {
270 return _MALI_OSK_ERR_FAULT;
273 MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n"));
274 return _MALI_OSK_ERR_FAULT;
277 /* Second PP core group is optional, don't fail if we don't find it */
278 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI450_OFFSET_L2_CACHE2, &l2_pp_grp1_resource)) {
279 MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 1\n"));
280 l2_cache = mali_create_l2_cache_core(&l2_pp_grp1_resource, MALI_DOMAIN_INDEX_L22);
281 if (NULL == l2_cache) {
282 return _MALI_OSK_ERR_FAULT;
285 } else if (mali_is_mali470()) {
286 _mali_osk_resource_t l2c1_resource;
288 /* Make cluster for L2C1 */
289 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI470_OFFSET_L2_CACHE1, &l2c1_resource)) {
290 MALI_DEBUG_PRINT(3, ("Creating Mali-470 L2 cache 1\n"));
291 l2_cache = mali_create_l2_cache_core(&l2c1_resource, MALI_DOMAIN_INDEX_L21);
292 if (NULL == l2_cache) {
293 return _MALI_OSK_ERR_FAULT;
296 MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for L2C1\n"));
297 return _MALI_OSK_ERR_FAULT;
301 return _MALI_OSK_ERR_OK;
304 static struct mali_group *mali_create_group(struct mali_l2_cache_core *cache,
305 _mali_osk_resource_t *resource_mmu,
306 _mali_osk_resource_t *resource_gp,
307 _mali_osk_resource_t *resource_pp,
310 struct mali_mmu_core *mmu;
311 struct mali_group *group;
313 MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
315 /* Create the group object */
316 group = mali_group_create(cache, NULL, NULL, domain_index);
318 MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
322 /* Create the MMU object inside group */
323 mmu = mali_mmu_create(resource_mmu, group, MALI_FALSE);
325 MALI_PRINT_ERROR(("Failed to create MMU object\n"));
326 mali_group_delete(group);
330 if (NULL != resource_gp) {
331 /* Create the GP core object inside this group */
332 struct mali_gp_core *gp_core = mali_gp_create(resource_gp, group);
333 if (NULL == gp_core) {
334 /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
335 MALI_PRINT_ERROR(("Failed to create GP object\n"));
336 mali_group_delete(group);
341 if (NULL != resource_pp) {
342 struct mali_pp_core *pp_core;
344 /* Create the PP core object inside this group */
345 pp_core = mali_pp_create(resource_pp, group, MALI_FALSE, mali_get_bcast_id(resource_pp));
346 if (NULL == pp_core) {
347 /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
348 MALI_PRINT_ERROR(("Failed to create PP object\n"));
349 mali_group_delete(group);
357 static _mali_osk_errcode_t mali_create_virtual_group(_mali_osk_resource_t *resource_mmu_pp_bcast,
358 _mali_osk_resource_t *resource_pp_bcast,
359 _mali_osk_resource_t *resource_dlbu,
360 _mali_osk_resource_t *resource_bcast)
362 struct mali_mmu_core *mmu_pp_bcast_core;
363 struct mali_pp_core *pp_bcast_core;
364 struct mali_dlbu_core *dlbu_core;
365 struct mali_bcast_unit *bcast_core;
366 struct mali_group *group;
368 MALI_DEBUG_PRINT(2, ("Starting new virtual group for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
370 /* Create the DLBU core object */
371 dlbu_core = mali_dlbu_create(resource_dlbu);
372 if (NULL == dlbu_core) {
373 MALI_PRINT_ERROR(("Failed to create DLBU object \n"));
374 return _MALI_OSK_ERR_FAULT;
377 /* Create the Broadcast unit core */
378 bcast_core = mali_bcast_unit_create(resource_bcast);
379 if (NULL == bcast_core) {
380 MALI_PRINT_ERROR(("Failed to create Broadcast unit object!\n"));
381 mali_dlbu_delete(dlbu_core);
382 return _MALI_OSK_ERR_FAULT;
385 /* Create the group object */
387 /* Get a physical PP group to temporarily add to broadcast unit. IRQ
388 * verification needs a physical group in the broadcast unit to test
389 * the broadcast unit interrupt line. */
391 struct mali_group *phys_group = NULL;
393 for (i = 0; i < mali_group_get_glob_num_groups(); i++) {
394 phys_group = mali_group_get_glob_group(i);
395 if (NULL != mali_group_get_pp_core(phys_group)) break;
397 MALI_DEBUG_ASSERT(NULL != mali_group_get_pp_core(phys_group));
399 /* Add the group temporarily to the broadcast, and update the
400 * broadcast HW. Since the HW is not updated when removing the
401 * group the IRQ check will work when the virtual PP is created
404 * When the virtual group gets populated, the actually used
405 * groups will be added to the broadcast unit and the HW will
408 mali_bcast_add_group(bcast_core, phys_group);
409 mali_bcast_reset(bcast_core);
410 mali_bcast_remove_group(bcast_core, phys_group);
413 group = mali_group_create(NULL, dlbu_core, bcast_core, MALI_DOMAIN_INDEX_DUMMY);
415 MALI_PRINT_ERROR(("Failed to create group object for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
416 mali_bcast_unit_delete(bcast_core);
417 mali_dlbu_delete(dlbu_core);
418 return _MALI_OSK_ERR_FAULT;
421 /* Create the MMU object inside group */
422 mmu_pp_bcast_core = mali_mmu_create(resource_mmu_pp_bcast, group, MALI_TRUE);
423 if (NULL == mmu_pp_bcast_core) {
424 MALI_PRINT_ERROR(("Failed to create MMU PP broadcast object\n"));
425 mali_group_delete(group);
426 return _MALI_OSK_ERR_FAULT;
429 /* Create the PP core object inside this group */
430 pp_bcast_core = mali_pp_create(resource_pp_bcast, group, MALI_TRUE, 0);
431 if (NULL == pp_bcast_core) {
432 /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
433 MALI_PRINT_ERROR(("Failed to create PP object\n"));
434 mali_group_delete(group);
435 return _MALI_OSK_ERR_FAULT;
438 return _MALI_OSK_ERR_OK;
441 static _mali_osk_errcode_t mali_parse_config_groups(void)
443 struct mali_group *group;
444 int cluster_id_gp = 0;
445 int cluster_id_pp_grp0 = 0;
446 int cluster_id_pp_grp1 = 0;
449 _mali_osk_resource_t resource_gp;
450 _mali_osk_resource_t resource_gp_mmu;
451 _mali_osk_resource_t resource_pp[8];
452 _mali_osk_resource_t resource_pp_mmu[8];
453 _mali_osk_resource_t resource_pp_mmu_bcast;
454 _mali_osk_resource_t resource_pp_bcast;
455 _mali_osk_resource_t resource_dlbu;
456 _mali_osk_resource_t resource_bcast;
457 _mali_osk_errcode_t resource_gp_found;
458 _mali_osk_errcode_t resource_gp_mmu_found;
459 _mali_osk_errcode_t resource_pp_found[8];
460 _mali_osk_errcode_t resource_pp_mmu_found[8];
461 _mali_osk_errcode_t resource_pp_mmu_bcast_found;
462 _mali_osk_errcode_t resource_pp_bcast_found;
463 _mali_osk_errcode_t resource_dlbu_found;
464 _mali_osk_errcode_t resource_bcast_found;
466 if (!(mali_is_mali400() || mali_is_mali450() || mali_is_mali470())) {
467 /* No known HW core */
468 return _MALI_OSK_ERR_FAULT;
471 if (MALI_MAX_JOB_RUNTIME_DEFAULT == mali_max_job_runtime) {
472 /* Group settings are not overridden by module parameters, so use device settings */
473 _mali_osk_device_data data = { 0, };
475 if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
476 /* Use device specific settings (if defined) */
477 if (0 != data.max_job_runtime) {
478 mali_max_job_runtime = data.max_job_runtime;
483 if (mali_is_mali450()) {
484 /* Mali-450 have separate L2s for GP, and PP core group(s) */
485 cluster_id_pp_grp0 = 1;
486 cluster_id_pp_grp1 = 2;
489 resource_gp_found = _mali_osk_resource_find(MALI_OFFSET_GP, &resource_gp);
490 resource_gp_mmu_found = _mali_osk_resource_find(MALI_OFFSET_GP_MMU, &resource_gp_mmu);
491 resource_pp_found[0] = _mali_osk_resource_find(MALI_OFFSET_PP0, &(resource_pp[0]));
492 resource_pp_found[1] = _mali_osk_resource_find(MALI_OFFSET_PP1, &(resource_pp[1]));
493 resource_pp_found[2] = _mali_osk_resource_find(MALI_OFFSET_PP2, &(resource_pp[2]));
494 resource_pp_found[3] = _mali_osk_resource_find(MALI_OFFSET_PP3, &(resource_pp[3]));
495 resource_pp_found[4] = _mali_osk_resource_find(MALI_OFFSET_PP4, &(resource_pp[4]));
496 resource_pp_found[5] = _mali_osk_resource_find(MALI_OFFSET_PP5, &(resource_pp[5]));
497 resource_pp_found[6] = _mali_osk_resource_find(MALI_OFFSET_PP6, &(resource_pp[6]));
498 resource_pp_found[7] = _mali_osk_resource_find(MALI_OFFSET_PP7, &(resource_pp[7]));
499 resource_pp_mmu_found[0] = _mali_osk_resource_find(MALI_OFFSET_PP0_MMU, &(resource_pp_mmu[0]));
500 resource_pp_mmu_found[1] = _mali_osk_resource_find(MALI_OFFSET_PP1_MMU, &(resource_pp_mmu[1]));
501 resource_pp_mmu_found[2] = _mali_osk_resource_find(MALI_OFFSET_PP2_MMU, &(resource_pp_mmu[2]));
502 resource_pp_mmu_found[3] = _mali_osk_resource_find(MALI_OFFSET_PP3_MMU, &(resource_pp_mmu[3]));
503 resource_pp_mmu_found[4] = _mali_osk_resource_find(MALI_OFFSET_PP4_MMU, &(resource_pp_mmu[4]));
504 resource_pp_mmu_found[5] = _mali_osk_resource_find(MALI_OFFSET_PP5_MMU, &(resource_pp_mmu[5]));
505 resource_pp_mmu_found[6] = _mali_osk_resource_find(MALI_OFFSET_PP6_MMU, &(resource_pp_mmu[6]));
506 resource_pp_mmu_found[7] = _mali_osk_resource_find(MALI_OFFSET_PP7_MMU, &(resource_pp_mmu[7]));
509 if (mali_is_mali450() || mali_is_mali470()) {
510 resource_bcast_found = _mali_osk_resource_find(MALI_OFFSET_BCAST, &resource_bcast);
511 resource_dlbu_found = _mali_osk_resource_find(MALI_OFFSET_DLBU, &resource_dlbu);
512 resource_pp_mmu_bcast_found = _mali_osk_resource_find(MALI_OFFSET_PP_BCAST_MMU, &resource_pp_mmu_bcast);
513 resource_pp_bcast_found = _mali_osk_resource_find(MALI_OFFSET_PP_BCAST, &resource_pp_bcast);
515 if (_MALI_OSK_ERR_OK != resource_bcast_found ||
516 _MALI_OSK_ERR_OK != resource_dlbu_found ||
517 _MALI_OSK_ERR_OK != resource_pp_mmu_bcast_found ||
518 _MALI_OSK_ERR_OK != resource_pp_bcast_found) {
519 /* Missing mandatory core(s) for Mali-450 or Mali-470 */
520 MALI_DEBUG_PRINT(2, ("Missing mandatory resources, Mali-450 needs DLBU, Broadcast unit, virtual PP core and virtual MMU\n"));
521 return _MALI_OSK_ERR_FAULT;
525 if (_MALI_OSK_ERR_OK != resource_gp_found ||
526 _MALI_OSK_ERR_OK != resource_gp_mmu_found ||
527 _MALI_OSK_ERR_OK != resource_pp_found[0] ||
528 _MALI_OSK_ERR_OK != resource_pp_mmu_found[0]) {
529 /* Missing mandatory core(s) */
530 MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU\n"));
531 return _MALI_OSK_ERR_FAULT;
534 MALI_DEBUG_ASSERT(1 <= mali_l2_cache_core_get_glob_num_l2_cores());
535 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);
537 return _MALI_OSK_ERR_FAULT;
540 /* Create group for first (and mandatory) PP core */
541 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 */
542 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);
544 return _MALI_OSK_ERR_FAULT;
547 mali_inited_pp_cores_group_1++;
549 /* Create groups for rest of the cores in the first PP core group */
550 for (i = 1; i < 4; i++) { /* First half of the PP cores belong to first core group */
551 if (mali_inited_pp_cores_group_1 < mali_max_pp_cores_group_1) {
552 if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i]) {
553 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);
555 return _MALI_OSK_ERR_FAULT;
558 mali_inited_pp_cores_group_1++;
563 /* Create groups for cores in the second PP core group */
564 for (i = 4; i < 8; i++) { /* Second half of the PP cores belong to second core group */
565 if (mali_inited_pp_cores_group_2 < mali_max_pp_cores_group_2) {
566 if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i]) {
567 MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= 2); /* Only Mali-450 have a second core group */
568 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);
570 return _MALI_OSK_ERR_FAULT;
573 mali_inited_pp_cores_group_2++;
578 if (mali_is_mali450() || mali_is_mali470()) {
579 _mali_osk_errcode_t err = mali_create_virtual_group(&resource_pp_mmu_bcast, &resource_pp_bcast, &resource_dlbu, &resource_bcast);
580 if (_MALI_OSK_ERR_OK != err) {
585 mali_max_pp_cores_group_1 = mali_inited_pp_cores_group_1;
586 mali_max_pp_cores_group_2 = mali_inited_pp_cores_group_2;
587 MALI_DEBUG_PRINT(2, ("%d+%d PP cores initialized\n", mali_inited_pp_cores_group_1, mali_inited_pp_cores_group_2));
589 return _MALI_OSK_ERR_OK;
592 static _mali_osk_errcode_t mali_check_shared_interrupts(void)
594 #if !defined(CONFIG_MALI_SHARED_INTERRUPTS)
595 if (MALI_TRUE == _mali_osk_shared_interrupts()) {
596 MALI_PRINT_ERROR(("Shared interrupts detected, but driver support is not enabled\n"));
597 return _MALI_OSK_ERR_FAULT;
599 #endif /* !defined(CONFIG_MALI_SHARED_INTERRUPTS) */
601 /* It is OK to compile support for shared interrupts even if Mali is not using it. */
602 return _MALI_OSK_ERR_OK;
605 static _mali_osk_errcode_t mali_parse_config_pmu(void)
607 _mali_osk_resource_t resource_pmu;
609 MALI_DEBUG_ASSERT(0 != global_gpu_base_address);
611 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_PMU, &resource_pmu)) {
612 struct mali_pmu_core *pmu;
614 pmu = mali_pmu_create(&resource_pmu);
616 MALI_PRINT_ERROR(("Failed to create PMU\n"));
617 return _MALI_OSK_ERR_FAULT;
621 /* It's ok if the PMU doesn't exist */
622 return _MALI_OSK_ERR_OK;
625 static _mali_osk_errcode_t mali_parse_config_memory(void)
627 _mali_osk_device_data data = { 0, };
628 _mali_osk_errcode_t ret;
630 /* The priority of setting the value of mali_shared_mem_size,
631 * mali_dedicated_mem_start and mali_dedicated_mem_size:
632 * 1. module parameter;
636 if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
637 /* Memory settings are not overridden by module parameters, so use device settings */
638 if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size) {
639 /* Use device specific settings (if defined) */
640 mali_dedicated_mem_start = data.dedicated_mem_start;
641 mali_dedicated_mem_size = data.dedicated_mem_size;
644 if (MALI_SHARED_MEMORY_DEFAULT_SIZE == mali_shared_mem_size &&
645 0 != data.shared_mem_size) {
646 mali_shared_mem_size = data.shared_mem_size;
650 if (0 < mali_dedicated_mem_size && 0 != mali_dedicated_mem_start) {
651 MALI_DEBUG_PRINT(2, ("Mali memory settings (dedicated: 0x%08X@0x%08X)\n",
652 mali_dedicated_mem_size, mali_dedicated_mem_start));
654 /* Dedicated memory */
655 ret = mali_memory_core_resource_dedicated_memory(mali_dedicated_mem_start, mali_dedicated_mem_size);
656 if (_MALI_OSK_ERR_OK != ret) {
657 MALI_PRINT_ERROR(("Failed to register dedicated memory\n"));
658 mali_memory_terminate();
663 if (0 < mali_shared_mem_size) {
664 MALI_DEBUG_PRINT(2, ("Mali memory settings (shared: 0x%08X)\n", mali_shared_mem_size));
666 /* Shared OS memory */
667 ret = mali_memory_core_resource_os_memory(mali_shared_mem_size);
668 if (_MALI_OSK_ERR_OK != ret) {
669 MALI_PRINT_ERROR(("Failed to register shared OS memory\n"));
670 mali_memory_terminate();
675 if (0 == mali_fb_start && 0 == mali_fb_size) {
676 /* Frame buffer settings are not overridden by module parameters, so use device settings */
677 _mali_osk_device_data data = { 0, };
679 if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
680 /* Use device specific settings (if defined) */
681 mali_fb_start = data.fb_start;
682 mali_fb_size = data.fb_size;
685 MALI_DEBUG_PRINT(2, ("Using device defined frame buffer settings (0x%08X@0x%08X)\n",
686 mali_fb_size, mali_fb_start));
688 MALI_DEBUG_PRINT(2, ("Using module defined frame buffer settings (0x%08X@0x%08X)\n",
689 mali_fb_size, mali_fb_start));
692 if (0 != mali_fb_size) {
693 /* Register frame buffer */
694 ret = mali_mem_validation_add_range(mali_fb_start, mali_fb_size);
695 if (_MALI_OSK_ERR_OK != ret) {
696 MALI_PRINT_ERROR(("Failed to register frame buffer memory region\n"));
697 mali_memory_terminate();
702 return _MALI_OSK_ERR_OK;
705 static void mali_detect_gpu_class(void)
707 if (_mali_osk_identify_gpu_resource() == 0x450)
708 mali_gpu_class_is_mali450 = MALI_TRUE;
710 if (_mali_osk_identify_gpu_resource() == 0x470)
711 mali_gpu_class_is_mali470 = MALI_TRUE;
714 static _mali_osk_errcode_t mali_init_hw_reset(void)
716 #if (defined(CONFIG_MALI450) || defined(CONFIG_MALI470))
717 _mali_osk_resource_t resource_bcast;
719 /* Ensure broadcast unit is in a good state before we start creating
722 if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_BCAST, &resource_bcast)) {
723 struct mali_bcast_unit *bcast_core;
725 bcast_core = mali_bcast_unit_create(&resource_bcast);
726 if (NULL == bcast_core) {
727 MALI_PRINT_ERROR(("Failed to create Broadcast unit object!\n"));
728 return _MALI_OSK_ERR_FAULT;
730 mali_bcast_unit_delete(bcast_core);
732 #endif /* (defined(CONFIG_MALI450) || defined(CONFIG_MALI470)) */
734 return _MALI_OSK_ERR_OK;
737 _mali_osk_errcode_t mali_initialize_subsystems(void)
739 _mali_osk_errcode_t err;
741 #ifdef CONFIG_MALI_DT
742 err = _mali_osk_resource_initialize();
743 if (_MALI_OSK_ERR_OK != err) {
744 mali_terminate_subsystems();
749 mali_pp_job_initialize();
751 mali_timeline_initialize();
753 err = mali_session_initialize();
754 if (_MALI_OSK_ERR_OK != err) {
755 mali_terminate_subsystems();
759 /*Try to init gpu secure mode */
760 _mali_osk_gpu_secure_mode_init();
762 #if defined(CONFIG_MALI400_PROFILING)
763 err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
764 if (_MALI_OSK_ERR_OK != err) {
765 /* No biggie if we weren't able to initialize the profiling */
766 MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
770 err = mali_memory_initialize();
771 if (_MALI_OSK_ERR_OK != err) {
772 mali_terminate_subsystems();
776 err = mali_executor_initialize();
777 if (_MALI_OSK_ERR_OK != err) {
778 mali_terminate_subsystems();
782 err = mali_scheduler_initialize();
783 if (_MALI_OSK_ERR_OK != err) {
784 mali_terminate_subsystems();
788 /* Configure memory early, needed by mali_mmu_initialize. */
789 err = mali_parse_config_memory();
790 if (_MALI_OSK_ERR_OK != err) {
791 mali_terminate_subsystems();
795 err = mali_set_global_gpu_base_address();
796 if (_MALI_OSK_ERR_OK != err) {
797 mali_terminate_subsystems();
801 /* Detect GPU class (uses L2 cache count) */
802 mali_detect_gpu_class();
804 err = mali_check_shared_interrupts();
805 if (_MALI_OSK_ERR_OK != err) {
806 mali_terminate_subsystems();
810 /* Initialize the MALI PMU (will not touch HW!) */
811 err = mali_parse_config_pmu();
812 if (_MALI_OSK_ERR_OK != err) {
813 mali_terminate_subsystems();
817 /* Initialize the power management module */
818 err = mali_pm_initialize();
819 if (_MALI_OSK_ERR_OK != err) {
820 mali_terminate_subsystems();
824 /* Make sure the entire GPU stays on for the rest of this function */
825 mali_pm_init_begin();
827 /* Ensure HW is in a good state before starting to access cores. */
828 err = mali_init_hw_reset();
829 if (_MALI_OSK_ERR_OK != err) {
830 mali_terminate_subsystems();
834 /* Detect which Mali GPU we are dealing with */
835 err = mali_parse_product_info();
836 if (_MALI_OSK_ERR_OK != err) {
838 mali_terminate_subsystems();
842 /* The global_product_id is now populated with the correct Mali GPU */
844 /* Start configuring the actual Mali hardware. */
846 err = mali_mmu_initialize();
847 if (_MALI_OSK_ERR_OK != err) {
849 mali_terminate_subsystems();
853 if (mali_is_mali450() || mali_is_mali470()) {
854 err = mali_dlbu_initialize();
855 if (_MALI_OSK_ERR_OK != err) {
857 mali_terminate_subsystems();
862 err = mali_parse_config_l2_cache();
863 if (_MALI_OSK_ERR_OK != err) {
865 mali_terminate_subsystems();
869 err = mali_parse_config_groups();
870 if (_MALI_OSK_ERR_OK != err) {
872 mali_terminate_subsystems();
876 /* Move groups into executor */
877 mali_executor_populate();
879 /* Need call after all group has assigned a domain */
880 mali_pm_power_cost_setup();
882 /* Initialize the GPU timer */
883 err = mali_control_timer_init();
884 if (_MALI_OSK_ERR_OK != err) {
886 mali_terminate_subsystems();
890 /* Initialize the GPU utilization tracking */
891 err = mali_utilization_init();
892 if (_MALI_OSK_ERR_OK != err) {
894 mali_terminate_subsystems();
898 #if defined(CONFIG_MALI_DVFS)
899 err = mali_dvfs_policy_init();
900 if (_MALI_OSK_ERR_OK != err) {
902 mali_terminate_subsystems();
907 /* Allowing the system to be turned off */
910 return _MALI_OSK_ERR_OK; /* all ok */
913 void mali_terminate_subsystems(void)
915 struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
917 MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
919 mali_utilization_term();
920 mali_control_timer_term();
922 mali_executor_depopulate();
923 mali_delete_groups(); /* Delete groups not added to executor */
924 mali_executor_terminate();
926 mali_scheduler_terminate();
927 mali_pp_job_terminate();
928 mali_delete_l2_cache_cores();
929 mali_mmu_terminate();
931 if (mali_is_mali450() || mali_is_mali470()) {
932 mali_dlbu_terminate();
938 mali_pmu_delete(pmu);
941 #if defined(CONFIG_MALI400_PROFILING)
942 _mali_osk_profiling_term();
945 _mali_osk_gpu_secure_mode_deinit();
947 mali_memory_terminate();
949 mali_session_terminate();
951 mali_timeline_terminate();
953 global_gpu_base_address = 0;
956 _mali_product_id_t mali_kernel_core_get_product_id(void)
958 return global_product_id;
961 u32 mali_kernel_core_get_gpu_major_version(void)
963 return global_gpu_major_version;
966 u32 mali_kernel_core_get_gpu_minor_version(void)
968 return global_gpu_minor_version;
971 _mali_osk_errcode_t _mali_ukk_get_api_version(_mali_uk_get_api_version_s *args)
973 MALI_DEBUG_ASSERT_POINTER(args);
974 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
976 /* check compatability */
977 if (args->version == _MALI_UK_API_VERSION) {
978 args->compatible = 1;
980 args->compatible = 0;
983 args->version = _MALI_UK_API_VERSION; /* report our version */
985 /* success regardless of being compatible or not */
989 _mali_osk_errcode_t _mali_ukk_get_api_version_v2(_mali_uk_get_api_version_v2_s *args)
991 MALI_DEBUG_ASSERT_POINTER(args);
992 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
994 /* check compatability */
995 if (args->version == _MALI_UK_API_VERSION) {
996 args->compatible = 1;
998 args->compatible = 0;
1001 args->version = _MALI_UK_API_VERSION; /* report our version */
1003 /* success regardless of being compatible or not */
1004 return _MALI_OSK_ERR_OK;
1007 _mali_osk_errcode_t _mali_ukk_wait_for_notification(_mali_uk_wait_for_notification_s *args)
1009 _mali_osk_errcode_t err;
1010 _mali_osk_notification_t *notification;
1011 _mali_osk_notification_queue_t *queue;
1012 struct mali_session_data *session;
1015 MALI_DEBUG_ASSERT_POINTER(args);
1016 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1018 session = (struct mali_session_data *)(uintptr_t)args->ctx;
1019 queue = session->ioctl_queue;
1021 /* if the queue does not exist we're currently shutting down */
1022 if (NULL == queue) {
1023 MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
1024 args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS;
1025 return _MALI_OSK_ERR_OK;
1028 /* receive a notification, might sleep */
1029 err = _mali_osk_notification_queue_receive(queue, ¬ification);
1030 if (_MALI_OSK_ERR_OK != err) {
1031 MALI_ERROR(err); /* errcode returned, pass on to caller */
1034 /* copy the buffer to the user */
1035 args->type = (_mali_uk_notification_type)notification->notification_type;
1036 _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size);
1038 /* finished with the notification */
1039 _mali_osk_notification_delete(notification);
1041 return _MALI_OSK_ERR_OK; /* all ok */
1044 _mali_osk_errcode_t _mali_ukk_post_notification(_mali_uk_post_notification_s *args)
1046 _mali_osk_notification_t *notification;
1047 _mali_osk_notification_queue_t *queue;
1048 struct mali_session_data *session;
1051 MALI_DEBUG_ASSERT_POINTER(args);
1052 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1054 session = (struct mali_session_data *)(uintptr_t)args->ctx;
1055 queue = session->ioctl_queue;
1057 /* if the queue does not exist we're currently shutting down */
1058 if (NULL == queue) {
1059 MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
1060 return _MALI_OSK_ERR_OK;
1063 notification = _mali_osk_notification_create(args->type, 0);
1064 if (NULL == notification) {
1065 MALI_PRINT_ERROR(("Failed to create notification object\n"));
1066 return _MALI_OSK_ERR_NOMEM;
1069 _mali_osk_notification_queue_send(queue, notification);
1071 return _MALI_OSK_ERR_OK; /* all ok */
1074 _mali_osk_errcode_t _mali_ukk_pending_submit(_mali_uk_pending_submit_s *args)
1076 wait_queue_head_t *queue;
1079 MALI_DEBUG_ASSERT_POINTER(args);
1080 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1082 queue = mali_session_get_wait_queue();
1084 /* check pending big job number, might sleep if larger than MAX allowed number */
1085 if (wait_event_interruptible(*queue, MALI_MAX_PENDING_BIG_JOB > mali_scheduler_job_gp_big_job_count())) {
1086 return _MALI_OSK_ERR_RESTARTSYSCALL;
1089 return _MALI_OSK_ERR_OK; /* all ok */
1093 _mali_osk_errcode_t _mali_ukk_request_high_priority(_mali_uk_request_high_priority_s *args)
1095 struct mali_session_data *session;
1097 MALI_DEBUG_ASSERT_POINTER(args);
1098 MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
1100 session = (struct mali_session_data *)(uintptr_t)args->ctx;
1102 if (!session->use_high_priority_job_queue) {
1103 session->use_high_priority_job_queue = MALI_TRUE;
1104 MALI_DEBUG_PRINT(2, ("Session 0x%08X with pid %d was granted higher priority.\n", session, _mali_osk_get_pid()));
1107 return _MALI_OSK_ERR_OK;
1110 _mali_osk_errcode_t _mali_ukk_open(void **context)
1113 struct mali_session_data *session;
1115 /* allocated struct to track this session */
1116 session = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data));
1117 MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_NOMEM);
1119 MALI_DEBUG_PRINT(3, ("Session starting\n"));
1121 /* create a response queue for this session */
1122 session->ioctl_queue = _mali_osk_notification_queue_init();
1123 if (NULL == session->ioctl_queue) {
1127 session->page_directory = mali_mmu_pagedir_alloc();
1128 if (NULL == session->page_directory) {
1132 if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session->page_directory, MALI_DLBU_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE)) {
1133 MALI_PRINT_ERROR(("Failed to map DLBU page into session\n"));
1137 if (0 != mali_dlbu_phys_addr) {
1138 mali_mmu_pagedir_update(session->page_directory, MALI_DLBU_VIRT_ADDR, mali_dlbu_phys_addr,
1139 _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT);
1142 if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session)) {
1146 /* Create soft system. */
1147 session->soft_job_system = mali_soft_job_system_create(session);
1148 if (NULL == session->soft_job_system) {
1152 /* Create timeline system. */
1153 session->timeline_system = mali_timeline_system_create(session);
1154 if (NULL == session->timeline_system) {
1158 #if defined(CONFIG_MALI_DVFS)
1159 _mali_osk_atomic_init(&session->number_of_window_jobs, 0);
1162 session->use_high_priority_job_queue = MALI_FALSE;
1164 /* Initialize list of PP jobs on this session. */
1165 _MALI_OSK_INIT_LIST_HEAD(&session->pp_job_list);
1167 /* Initialize the pp_job_fb_lookup_list array used to quickly lookup jobs from a given frame builder */
1168 for (i = 0; i < MALI_PP_JOB_FB_LOOKUP_LIST_SIZE; ++i) {
1169 _MALI_OSK_INIT_LIST_HEAD(&session->pp_job_fb_lookup_list[i]);
1172 session->pid = _mali_osk_get_pid();
1173 session->comm = _mali_osk_get_comm();
1174 session->max_mali_mem_allocated_size = 0;
1175 for (i = 0; i < MALI_MEM_TYPE_MAX; i ++) {
1176 atomic_set(&session->mali_mem_array[i], 0);
1178 atomic_set(&session->mali_mem_allocated_pages, 0);
1179 *context = (void *)session;
1181 /* Add session to the list of all sessions. */
1182 mali_session_add(session);
1184 MALI_DEBUG_PRINT(3, ("Session started\n"));
1185 return _MALI_OSK_ERR_OK;
1188 mali_soft_job_system_destroy(session->soft_job_system);
1190 mali_memory_session_end(session);
1192 mali_mmu_pagedir_free(session->page_directory);
1194 _mali_osk_notification_queue_term(session->ioctl_queue);
1196 _mali_osk_free(session);
1197 MALI_ERROR(_MALI_OSK_ERR_NOMEM);
1202 /* parameter used for debug */
1203 extern u32 num_pm_runtime_resume;
1204 extern u32 num_pm_updates;
1205 extern u32 num_pm_updates_up;
1206 extern u32 num_pm_updates_down;
1209 _mali_osk_errcode_t _mali_ukk_close(void **context)
1211 struct mali_session_data *session;
1212 MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
1213 session = (struct mali_session_data *)*context;
1215 MALI_DEBUG_PRINT(3, ("Session ending\n"));
1217 MALI_DEBUG_ASSERT_POINTER(session->soft_job_system);
1218 MALI_DEBUG_ASSERT_POINTER(session->timeline_system);
1220 /* Remove session from list of all sessions. */
1221 mali_session_remove(session);
1223 /* This flag is used to prevent queueing of jobs due to activation. */
1224 session->is_aborting = MALI_TRUE;
1226 /* Stop the soft job timer. */
1227 mali_timeline_system_stop_timer(session->timeline_system);
1229 /* Abort queued jobs */
1230 mali_scheduler_abort_session(session);
1232 /* Abort executing jobs */
1233 mali_executor_abort_session(session);
1235 /* Abort the soft job system. */
1236 mali_soft_job_system_abort(session->soft_job_system);
1238 /* Force execution of all pending bottom half processing for GP and PP. */
1239 _mali_osk_wq_flush();
1241 /* The session PP list should now be empty. */
1242 MALI_DEBUG_ASSERT(_mali_osk_list_empty(&session->pp_job_list));
1244 /* At this point the GP and PP scheduler no longer has any jobs queued or running from this
1245 * session, and all soft jobs in the soft job system has been destroyed. */
1247 /* Any trackers left in the timeline system are directly or indirectly waiting on external
1248 * sync fences. Cancel all sync fence waiters to trigger activation of all remaining
1249 * trackers. This call will sleep until all timelines are empty. */
1250 mali_timeline_system_abort(session->timeline_system);
1252 /* Flush pending work.
1253 * Needed to make sure all bottom half processing related to this
1254 * session has been completed, before we free internal data structures.
1256 _mali_osk_wq_flush();
1258 /* Destroy timeline system. */
1259 mali_timeline_system_destroy(session->timeline_system);
1260 session->timeline_system = NULL;
1262 /* Destroy soft system. */
1263 mali_soft_job_system_destroy(session->soft_job_system);
1264 session->soft_job_system = NULL;
1267 /* Check that the pp_job_fb_lookup_list array is empty. */
1269 for (i = 0; i < MALI_PP_JOB_FB_LOOKUP_LIST_SIZE; ++i)
1271 MALI_DEBUG_ASSERT(_mali_osk_list_empty(&session->pp_job_fb_lookup_list[i]));
1275 /* Free remaining memory allocated to this session */
1276 mali_memory_session_end(session);
1278 #if defined(CONFIG_MALI_DVFS)
1279 _mali_osk_atomic_term(&session->number_of_window_jobs);
1282 #if defined(CONFIG_MALI400_PROFILING)
1283 _mali_osk_profiling_stop_sampling(session->pid);
1286 /* Free session data structures */
1287 mali_mmu_pagedir_unmap(session->page_directory, MALI_DLBU_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE);
1288 mali_mmu_pagedir_free(session->page_directory);
1289 _mali_osk_notification_queue_term(session->ioctl_queue);
1290 _mali_osk_free(session);
1294 MALI_DEBUG_PRINT(3, ("Session has ended\n"));
1297 MALI_DEBUG_PRINT(3, ("Stats: # runtime resumes: %u\n", num_pm_runtime_resume));
1298 MALI_DEBUG_PRINT(3, (" # PM updates: .... %u (up %u, down %u)\n", num_pm_updates, num_pm_updates_up, num_pm_updates_down));
1300 num_pm_runtime_resume = 0;
1302 num_pm_updates_up = 0;
1303 num_pm_updates_down = 0;
1306 return _MALI_OSK_ERR_OK;;
1309 #if MALI_STATE_TRACKING
1310 u32 _mali_kernel_core_dump_state(char *buf, u32 size)
1312 int n = 0; /* Number of bytes written to buf */
1314 n += mali_scheduler_dump_state(buf + n, size - n);
1315 n += mali_executor_dump_state(buf + n, size - n);