// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2019-2022 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#include <mali_kbase.h>
#include <mali_kbase_mem.h>
#include <mali_kbase_mem_pool_group.h>

#include "memory_group_manager.h"

void kbase_mem_pool_group_config_set_max_size(
	struct kbase_mem_pool_group_config *const configs,
	size_t const max_size)
{
	size_t const large_max_size = max_size >>
		(KBASE_MEM_POOL_2MB_PAGE_TABLE_ORDER -
		KBASE_MEM_POOL_4KB_PAGE_TABLE_ORDER);
	int gid;

	for (gid = 0; gid < MEMORY_GROUP_MANAGER_NR_GROUPS; ++gid) {
		kbase_mem_pool_config_set_max_size(&configs->small[gid],
			max_size);

		kbase_mem_pool_config_set_max_size(&configs->large[gid],
			large_max_size);
	}
}

int kbase_mem_pool_group_init(struct kbase_mem_pool_group *const mem_pools,
			      struct kbase_device *const kbdev,
			      const struct kbase_mem_pool_group_config *const configs,
			      struct kbase_mem_pool_group *next_pools)
{
	int gid, err = 0;

	for (gid = 0; gid < MEMORY_GROUP_MANAGER_NR_GROUPS; ++gid) {
		err = kbase_mem_pool_init(&mem_pools->small[gid], &configs->small[gid],
					  KBASE_MEM_POOL_4KB_PAGE_TABLE_ORDER, gid, kbdev,
					  next_pools ? &next_pools->small[gid] : NULL);

		if (!err) {
			err = kbase_mem_pool_init(&mem_pools->large[gid], &configs->large[gid],
						  KBASE_MEM_POOL_2MB_PAGE_TABLE_ORDER, gid, kbdev,
						  next_pools ? &next_pools->large[gid] : NULL);
			if (err)
				kbase_mem_pool_term(&mem_pools->small[gid]);
		}

		/* Break out of the loop early to avoid incrementing the count
		 * of memory pool pairs successfully initialized.
		 */
		if (err)
			break;
	}

	if (err) {
		/* gid gives the number of memory pool pairs successfully
		 * initialized, which is one greater than the array index of the
		 * last group.
		 */
		while (gid-- > 0) {
			kbase_mem_pool_term(&mem_pools->small[gid]);
			kbase_mem_pool_term(&mem_pools->large[gid]);
		}
	}

	return err;
}

void kbase_mem_pool_group_mark_dying(
	struct kbase_mem_pool_group *const mem_pools)
{
	int gid;

	for (gid = 0; gid < MEMORY_GROUP_MANAGER_NR_GROUPS; ++gid) {
		kbase_mem_pool_mark_dying(&mem_pools->small[gid]);
		kbase_mem_pool_mark_dying(&mem_pools->large[gid]);
	}
}

void kbase_mem_pool_group_term(
	struct kbase_mem_pool_group *const mem_pools)
{
	int gid;

	for (gid = 0; gid < MEMORY_GROUP_MANAGER_NR_GROUPS; ++gid) {
		kbase_mem_pool_term(&mem_pools->small[gid]);
		kbase_mem_pool_term(&mem_pools->large[gid]);
	}
}
