244 lines
5.0 KiB
C
244 lines
5.0 KiB
C
/*
|
|
* Copyright (C) 2010-2011 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.
|
|
*/
|
|
|
|
/**
|
|
* @file mali_pmm_policy.c
|
|
* Implementation of the common routines for power management module
|
|
* policies
|
|
*/
|
|
|
|
#if USING_MALI_PMM
|
|
|
|
#include "mali_ukk.h"
|
|
#include "mali_kernel_common.h"
|
|
|
|
#include "mali_pmm.h"
|
|
#include "mali_pmm_system.h"
|
|
#include "mali_pmm_state.h"
|
|
#include "mali_pmm_policy.h"
|
|
|
|
#include "mali_pmm_policy_alwayson.h"
|
|
#include "mali_pmm_policy_jobcontrol.h"
|
|
|
|
/* Call back function for timer expiration */
|
|
static void pmm_policy_timer_callback( void *arg );
|
|
|
|
_mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 timeout, mali_pmm_event_id id )
|
|
{
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer);
|
|
|
|
/* All values get 0 as default */
|
|
_mali_osk_memset(pptimer, 0, sizeof(*pptimer));
|
|
|
|
pptimer->timer = _mali_osk_timer_init();
|
|
if( pptimer->timer )
|
|
{
|
|
_mali_osk_timer_setcallback( pptimer->timer, pmm_policy_timer_callback, (void *)pptimer );
|
|
pptimer->timeout = timeout;
|
|
pptimer->event_id = id;
|
|
MALI_SUCCESS;
|
|
}
|
|
|
|
return _MALI_OSK_ERR_FAULT;
|
|
}
|
|
|
|
static void pmm_policy_timer_callback( void *arg )
|
|
{
|
|
_pmm_policy_timer_t *pptimer = (_pmm_policy_timer_t *)arg;
|
|
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer);
|
|
MALI_DEBUG_ASSERT( pptimer->set );
|
|
|
|
/* Set timer expired and flag there is a policy to check */
|
|
pptimer->expired = MALI_TRUE;
|
|
malipmm_set_policy_check();
|
|
}
|
|
|
|
|
|
void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer )
|
|
{
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer);
|
|
|
|
_mali_osk_timer_del( pptimer->timer );
|
|
_mali_osk_timer_term( pptimer->timer );
|
|
pptimer->timer = NULL;
|
|
}
|
|
|
|
mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer )
|
|
{
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer);
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer->timer);
|
|
|
|
if( !(pptimer->set) )
|
|
{
|
|
pptimer->set = MALI_TRUE;
|
|
pptimer->expired = MALI_FALSE;
|
|
pptimer->start = _mali_osk_time_tickcount();
|
|
_mali_osk_timer_add( pptimer->timer, pptimer->timeout );
|
|
return MALI_TRUE;
|
|
}
|
|
|
|
return MALI_FALSE;
|
|
}
|
|
|
|
mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer )
|
|
{
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer);
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer->timer);
|
|
|
|
if( pptimer->set )
|
|
{
|
|
_mali_osk_timer_del( pptimer->timer );
|
|
pptimer->set = MALI_FALSE;
|
|
pptimer->expired = MALI_FALSE;
|
|
return MALI_TRUE;
|
|
}
|
|
|
|
return MALI_FALSE;
|
|
}
|
|
|
|
mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer )
|
|
{
|
|
MALI_DEBUG_ASSERT_POINTER(pptimer);
|
|
|
|
if( pptimer->expired )
|
|
{
|
|
_mali_uk_pmm_message_s event = {
|
|
NULL,
|
|
MALI_PMM_EVENT_TIMEOUT, /* Assume timeout id, but set it below */
|
|
0 };
|
|
|
|
event.id = pptimer->event_id;
|
|
event.data = (mali_pmm_message_data)pptimer->start;
|
|
|
|
/* Don't need to do any other notification with this timer */
|
|
pptimer->expired = MALI_FALSE;
|
|
/* Unset timer so it is free to be set again */
|
|
pptimer->set = MALI_FALSE;
|
|
|
|
_mali_ukk_pmm_event_message( &event );
|
|
|
|
return MALI_TRUE;
|
|
}
|
|
|
|
return MALI_FALSE;
|
|
}
|
|
|
|
mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start )
|
|
{
|
|
return (_mali_osk_time_after( other_start, timer_start ) == 0);
|
|
}
|
|
|
|
|
|
_mali_osk_errcode_t pmm_policy_init(_mali_pmm_internal_state_t *pmm)
|
|
{
|
|
_mali_osk_errcode_t err;
|
|
|
|
MALI_DEBUG_ASSERT_POINTER(pmm);
|
|
|
|
switch( pmm->policy )
|
|
{
|
|
case MALI_PMM_POLICY_ALWAYS_ON:
|
|
{
|
|
err = pmm_policy_init_always_on();
|
|
}
|
|
break;
|
|
|
|
case MALI_PMM_POLICY_JOB_CONTROL:
|
|
{
|
|
err = pmm_policy_init_job_control(pmm);
|
|
}
|
|
break;
|
|
|
|
case MALI_PMM_POLICY_NONE:
|
|
default:
|
|
err = _MALI_OSK_ERR_FAULT;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
void pmm_policy_term(_mali_pmm_internal_state_t *pmm)
|
|
{
|
|
MALI_DEBUG_ASSERT_POINTER(pmm);
|
|
|
|
switch( pmm->policy )
|
|
{
|
|
case MALI_PMM_POLICY_ALWAYS_ON:
|
|
{
|
|
pmm_policy_term_always_on();
|
|
}
|
|
break;
|
|
|
|
case MALI_PMM_POLICY_JOB_CONTROL:
|
|
{
|
|
pmm_policy_term_job_control();
|
|
}
|
|
break;
|
|
|
|
case MALI_PMM_POLICY_NONE:
|
|
default:
|
|
MALI_PRINT_ERROR( ("PMM: Invalid policy terminated %d\n", pmm->policy) );
|
|
}
|
|
}
|
|
|
|
|
|
_mali_osk_errcode_t pmm_policy_process(_mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event)
|
|
{
|
|
_mali_osk_errcode_t err;
|
|
|
|
MALI_DEBUG_ASSERT_POINTER(pmm);
|
|
MALI_DEBUG_ASSERT_POINTER(event);
|
|
|
|
switch( pmm->policy )
|
|
{
|
|
case MALI_PMM_POLICY_ALWAYS_ON:
|
|
{
|
|
err = pmm_policy_process_always_on( pmm, event );
|
|
}
|
|
break;
|
|
|
|
case MALI_PMM_POLICY_JOB_CONTROL:
|
|
{
|
|
err = pmm_policy_process_job_control( pmm, event );
|
|
}
|
|
break;
|
|
|
|
case MALI_PMM_POLICY_NONE:
|
|
default:
|
|
err = _MALI_OSK_ERR_FAULT;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
void pmm_policy_check_policy( _mali_pmm_internal_state_t *pmm )
|
|
{
|
|
MALI_DEBUG_ASSERT_POINTER(pmm);
|
|
|
|
switch( pmm->policy )
|
|
{
|
|
case MALI_PMM_POLICY_JOB_CONTROL:
|
|
{
|
|
pmm_policy_check_job_control();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/* Nothing needs to be done */
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
#endif /* USING_MALI_PMM */
|
|
|