/*
 * Copyright (C) 2013-2014, 2016 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 licence.
 * 
 * A copy of the licence is included with the program, and can also be obtained from Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "mali_kernel_common.h"
#include "mali_osk.h"
#include "mali_pm_domain.h"
#include "mali_pmu.h"
#include "mali_group.h"
#include "mali_pm.h"

static struct mali_pm_domain *mali_pm_domains[MALI_MAX_NUMBER_OF_DOMAINS] =
{ NULL, };

void mali_pm_domain_initialize(void)
{
	/* Domains will be initialized/created on demand */
}

void mali_pm_domain_terminate(void)
{
	int i;

	/* Delete all domains that has been created */
	for (i = 0; i < MALI_MAX_NUMBER_OF_DOMAINS; i++) {
		mali_pm_domain_delete(mali_pm_domains[i]);
		mali_pm_domains[i] = NULL;
	}
}

struct mali_pm_domain *mali_pm_domain_create(u32 pmu_mask)
{
	struct mali_pm_domain *domain = NULL;
	u32 domain_id = 0;

	domain = mali_pm_domain_get_from_mask(pmu_mask);
	if (NULL != domain) return domain;

	MALI_DEBUG_PRINT(2,
			 ("Mali PM domain: Creating Mali PM domain (mask=0x%08X)\n",
			  pmu_mask));

	domain = (struct mali_pm_domain *)_mali_osk_malloc(
			 sizeof(struct mali_pm_domain));
	if (NULL != domain) {
		domain->power_is_on = MALI_FALSE;
		domain->pmu_mask = pmu_mask;
		domain->use_count = 0;
		_mali_osk_list_init(&domain->group_list);
		_mali_osk_list_init(&domain->l2_cache_list);

		domain_id = _mali_osk_fls(pmu_mask) - 1;
		/* Verify the domain_id */
		MALI_DEBUG_ASSERT(MALI_MAX_NUMBER_OF_DOMAINS > domain_id);
		/* Verify that pmu_mask only one bit is set */
		MALI_DEBUG_ASSERT((1 << domain_id) == pmu_mask);
		mali_pm_domains[domain_id] = domain;

		return domain;
	} else {
		MALI_DEBUG_PRINT_ERROR(("Unable to create PM domain\n"));
	}

	return NULL;
}

void mali_pm_domain_delete(struct mali_pm_domain *domain)
{
	if (NULL == domain) {
		return;
	}

	_mali_osk_list_delinit(&domain->group_list);
	_mali_osk_list_delinit(&domain->l2_cache_list);

	_mali_osk_free(domain);
}

void mali_pm_domain_add_group(struct mali_pm_domain *domain,
			      struct mali_group *group)
{
	MALI_DEBUG_ASSERT_POINTER(domain);
	MALI_DEBUG_ASSERT_POINTER(group);

	/*
	 * Use addtail because virtual group is created last and it needs
	 * to be at the end of the list (in order to be activated after
	 * all children.
	 */
	_mali_osk_list_addtail(&group->pm_domain_list, &domain->group_list);
}

void mali_pm_domain_add_l2_cache(struct mali_pm_domain *domain,
				 struct mali_l2_cache_core *l2_cache)
{
	MALI_DEBUG_ASSERT_POINTER(domain);
	MALI_DEBUG_ASSERT_POINTER(l2_cache);
	_mali_osk_list_add(&l2_cache->pm_domain_list, &domain->l2_cache_list);
}

struct mali_pm_domain *mali_pm_domain_get_from_mask(u32 mask)
{
	u32 id = 0;

	if (0 == mask) {
		return NULL;
	}

	id = _mali_osk_fls(mask) - 1;

	MALI_DEBUG_ASSERT(MALI_MAX_NUMBER_OF_DOMAINS > id);
	/* Verify that pmu_mask only one bit is set */
	MALI_DEBUG_ASSERT((1 << id) == mask);

	return mali_pm_domains[id];
}

struct mali_pm_domain *mali_pm_domain_get_from_index(u32 id)
{
	MALI_DEBUG_ASSERT(MALI_MAX_NUMBER_OF_DOMAINS > id);

	return mali_pm_domains[id];
}

u32 mali_pm_domain_ref_get(struct mali_pm_domain *domain)
{
	MALI_DEBUG_ASSERT_POINTER(domain);

	if (0 == domain->use_count) {
		_mali_osk_pm_dev_ref_get_async();
	}

	++domain->use_count;
	MALI_DEBUG_PRINT(4, ("PM domain %p: ref_get, use_count => %u\n", domain, domain->use_count));

	/* Return our mask so caller can check this against wanted mask */
	return domain->pmu_mask;
}

u32 mali_pm_domain_ref_put(struct mali_pm_domain *domain)
{
	MALI_DEBUG_ASSERT_POINTER(domain);

	--domain->use_count;
	MALI_DEBUG_PRINT(4, ("PM domain %p: ref_put, use_count => %u\n", domain, domain->use_count));

	if (0 == domain->use_count) {
		_mali_osk_pm_dev_ref_put();
	}

	/*
	 * Return the PMU mask which now could be be powered down
	 * (the bit for this domain).
	 * This is the responsibility of the caller (mali_pm)
	 */
	return (0 == domain->use_count ? domain->pmu_mask : 0);
}

#if MALI_STATE_TRACKING
u32 mali_pm_domain_get_id(struct mali_pm_domain *domain)
{
	u32 id = 0;

	MALI_DEBUG_ASSERT_POINTER(domain);
	MALI_DEBUG_ASSERT(0 != domain->pmu_mask);

	id = _mali_osk_fls(domain->pmu_mask) - 1;

	MALI_DEBUG_ASSERT(MALI_MAX_NUMBER_OF_DOMAINS > id);
	/* Verify that pmu_mask only one bit is set */
	MALI_DEBUG_ASSERT((1 << id) == domain->pmu_mask);
	/* Verify that we have stored the domain at right id/index */
	MALI_DEBUG_ASSERT(domain == mali_pm_domains[id]);

	return id;
}
#endif

#if defined(DEBUG)
mali_bool mali_pm_domain_all_unused(void)
{
	int i;

	for (i = 0; i < MALI_MAX_NUMBER_OF_DOMAINS; i++) {
		if (NULL == mali_pm_domains[i]) {
			/* Nothing to check */
			continue;
		}

		if (MALI_TRUE == mali_pm_domains[i]->power_is_on) {
			/* Not ready for suspend! */
			return MALI_FALSE;
		}

		if (0 != mali_pm_domains[i]->use_count) {
			/* Not ready for suspend! */
			return MALI_FALSE;
		}
	}

	return MALI_TRUE;
}
#endif
