/*
 *
 * (C) COPYRIGHT 2013-2017 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.
 *
 */



/*
 * Base kernel core availability APIs
 */

#include <mali_kbase.h>
#include <mali_kbase_pm.h>
#include <backend/gpu/mali_kbase_pm_internal.h>

static const struct kbase_pm_ca_policy *const policy_list[] = {
	&kbase_pm_ca_fixed_policy_ops,
#ifdef CONFIG_MALI_DEVFREQ
	&kbase_pm_ca_devfreq_policy_ops,
#endif
#if !MALI_CUSTOMER_RELEASE
	&kbase_pm_ca_demand_policy_ops,
	&kbase_pm_ca_random_policy_ops,
#endif
};

/**
 * POLICY_COUNT - The number of policies available in the system.
 *
 * This is derived from the number of functions listed in policy_list.
 */
#define POLICY_COUNT (sizeof(policy_list)/sizeof(*policy_list))

int kbase_pm_ca_init(struct kbase_device *kbdev)
{
	KBASE_DEBUG_ASSERT(kbdev != NULL);

	kbdev->pm.backend.ca_current_policy = policy_list[0];

	kbdev->pm.backend.ca_current_policy->init(kbdev);

	return 0;
}

void kbase_pm_ca_term(struct kbase_device *kbdev)
{
	kbdev->pm.backend.ca_current_policy->term(kbdev);
}

int kbase_pm_ca_list_policies(const struct kbase_pm_ca_policy * const **list)
{
	if (!list)
		return POLICY_COUNT;

	*list = policy_list;

	return POLICY_COUNT;
}

KBASE_EXPORT_TEST_API(kbase_pm_ca_list_policies);

const struct kbase_pm_ca_policy
*kbase_pm_ca_get_policy(struct kbase_device *kbdev)
{
	KBASE_DEBUG_ASSERT(kbdev != NULL);

	return kbdev->pm.backend.ca_current_policy;
}

KBASE_EXPORT_TEST_API(kbase_pm_ca_get_policy);

void kbase_pm_ca_set_policy(struct kbase_device *kbdev,
				const struct kbase_pm_ca_policy *new_policy)
{
	const struct kbase_pm_ca_policy *old_policy;
	unsigned long flags;

	KBASE_DEBUG_ASSERT(kbdev != NULL);
	KBASE_DEBUG_ASSERT(new_policy != NULL);

	KBASE_TRACE_ADD(kbdev, PM_CA_SET_POLICY, NULL, NULL, 0u,
								new_policy->id);

	/* During a policy change we pretend the GPU is active */
	/* A suspend won't happen here, because we're in a syscall from a
	 * userspace thread */
	kbase_pm_context_active(kbdev);

	mutex_lock(&kbdev->pm.lock);

	/* Remove the policy to prevent IRQ handlers from working on it */
	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
	old_policy = kbdev->pm.backend.ca_current_policy;
	kbdev->pm.backend.ca_current_policy = NULL;
	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	if (old_policy->term)
		old_policy->term(kbdev);

	if (new_policy->init)
		new_policy->init(kbdev);

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
	kbdev->pm.backend.ca_current_policy = new_policy;

	/* If any core power state changes were previously attempted, but
	 * couldn't be made because the policy was changing (current_policy was
	 * NULL), then re-try them here. */
	kbase_pm_update_cores_state_nolock(kbdev);

	kbdev->pm.backend.ca_current_policy->update_core_status(kbdev,
					kbdev->shader_ready_bitmap,
					kbdev->shader_transitioning_bitmap);

	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	mutex_unlock(&kbdev->pm.lock);

	/* Now the policy change is finished, we release our fake context active
	 * reference */
	kbase_pm_context_idle(kbdev);
}

KBASE_EXPORT_TEST_API(kbase_pm_ca_set_policy);

u64 kbase_pm_ca_get_core_mask(struct kbase_device *kbdev)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);

	/* All cores must be enabled when instrumentation is in use */
	if (kbdev->pm.backend.instr_enabled)
		return kbdev->gpu_props.props.raw_props.shader_present &
				kbdev->pm.debug_core_mask_all;

	if (kbdev->pm.backend.ca_current_policy == NULL)
		return kbdev->gpu_props.props.raw_props.shader_present &
				kbdev->pm.debug_core_mask_all;

	return kbdev->pm.backend.ca_current_policy->get_core_mask(kbdev) &
						kbdev->pm.debug_core_mask_all;
}

KBASE_EXPORT_TEST_API(kbase_pm_ca_get_core_mask);

void kbase_pm_ca_update_core_status(struct kbase_device *kbdev, u64 cores_ready,
							u64 cores_transitioning)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);

	if (kbdev->pm.backend.ca_current_policy != NULL)
		kbdev->pm.backend.ca_current_policy->update_core_status(kbdev,
							cores_ready,
							cores_transitioning);
}

void kbase_pm_ca_instr_enable(struct kbase_device *kbdev)
{
	unsigned long flags;

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
	kbdev->pm.backend.instr_enabled = true;

	kbase_pm_update_cores_state_nolock(kbdev);
	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
}

void kbase_pm_ca_instr_disable(struct kbase_device *kbdev)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);
	kbdev->pm.backend.instr_enabled = false;

	kbase_pm_update_cores_state_nolock(kbdev);
}
