aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/mali/common/mali_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/samsung/mali/common/mali_pm.c')
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pm.c552
1 files changed, 0 insertions, 552 deletions
diff --git a/drivers/media/video/samsung/mali/common/mali_pm.c b/drivers/media/video/samsung/mali/common/mali_pm.c
deleted file mode 100644
index 933e54e..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pm.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * Copyright (C) 2011-2012 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_pm.h"
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_gp_scheduler.h"
-#include "mali_pp_scheduler.h"
-#include "mali_platform.h"
-#include "mali_kernel_utilization.h"
-#include "mali_kernel_core.h"
-#include "mali_group.h"
-
-#define MALI_PM_LIGHT_SLEEP_TIMEOUT 1000
-
-enum mali_pm_scheme
-{
- MALI_PM_SCHEME_DYNAMIC,
- MALI_PM_SCHEME_OS_SUSPENDED,
- MALI_PM_SCHEME_ALWAYS_ON
-};
-
-enum mali_pm_level
-{
- MALI_PM_LEVEL_1_ON,
- MALI_PM_LEVEL_2_STANDBY,
- MALI_PM_LEVEL_3_LIGHT_SLEEP,
- MALI_PM_LEVEL_4_DEEP_SLEEP
-};
-static _mali_osk_lock_t *mali_pm_lock_set_next_state;
-static _mali_osk_lock_t *mali_pm_lock_set_core_states;
-static _mali_osk_lock_t *mali_pm_lock_execute_state_change;
-static _mali_osk_irq_t *wq_irq;
-
-static _mali_osk_timer_t *idle_timer = NULL;
-static mali_bool idle_timer_running = MALI_FALSE;
-static u32 mali_pm_event_number = 0;
-
-static u32 num_active_gps = 0;
-static u32 num_active_pps = 0;
-
-static enum mali_pm_scheme current_scheme = MALI_PM_SCHEME_DYNAMIC;
-static enum mali_pm_level current_level = MALI_PM_LEVEL_1_ON;
-static enum mali_pm_level next_level_dynamic = MALI_PM_LEVEL_2_STANDBY; /* Should be the state we go to when we go out of MALI_PM_SCHEME_ALWAYS_ON during init */
-
-
-
-static _mali_osk_errcode_t mali_pm_upper_half(void *data);
-static void mali_pm_bottom_half(void *data);
-static void mali_pm_powerup(void);
-static void mali_pm_powerdown(mali_power_mode power_mode);
-
-static void timeout_light_sleep(void* arg);
-#if 0
-/* Deep sleep timout not supported */
-static void timeout_deep_sleep(void* arg);
-#endif
-static u32 mali_pm_event_number_get(void);
-static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time );
-
-_mali_osk_errcode_t mali_pm_initialize(void)
-{
- mali_pm_lock_execute_state_change = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_EXECUTE);
-
- if (NULL != mali_pm_lock_execute_state_change )
- {
- mali_pm_lock_set_next_state = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ONELOCK| _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_LAST);
-
- if (NULL != mali_pm_lock_set_next_state)
- {
- mali_pm_lock_set_core_states = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_CORE_STATE);
-
- if (NULL != mali_pm_lock_set_core_states)
- {
- idle_timer = _mali_osk_timer_init();
- if (NULL != idle_timer)
- {
- wq_irq = _mali_osk_irq_init(_MALI_OSK_IRQ_NUMBER_PMM,
- mali_pm_upper_half,
- mali_pm_bottom_half,
- NULL,
- NULL,
- (void *)NULL,
- "Mali PM deferred work");
- if (NULL != wq_irq)
- {
- if (_MALI_OSK_ERR_OK == mali_platform_init())
- {
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- _mali_osk_pm_dev_enable();
- mali_pm_powerup();
-#endif
- return _MALI_OSK_ERR_OK;
- }
-
- _mali_osk_irq_term(wq_irq);
- }
-
- _mali_osk_timer_del(idle_timer);
- _mali_osk_timer_term(idle_timer);
- }
- _mali_osk_lock_term(mali_pm_lock_set_core_states);
- }
- _mali_osk_lock_term(mali_pm_lock_set_next_state);
- }
- _mali_osk_lock_term(mali_pm_lock_execute_state_change);
- }
-
- return _MALI_OSK_ERR_FAULT;
-}
-
-void mali_pm_terminate(void)
-{
- mali_platform_deinit();
- _mali_osk_irq_term(wq_irq);
- _mali_osk_timer_del(idle_timer);
- _mali_osk_timer_term(idle_timer);
- _mali_osk_lock_term(mali_pm_lock_execute_state_change);
- _mali_osk_lock_term(mali_pm_lock_set_next_state);
- _mali_osk_lock_term(mali_pm_lock_set_core_states);
-}
-
-
-inline void mali_pm_lock(void)
-{
- _mali_osk_lock_wait(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW);
-}
-
-inline void mali_pm_unlock(void)
-{
- _mali_osk_lock_signal(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW);
-}
-
-inline void mali_pm_execute_state_change_lock(void)
-{
- _mali_osk_lock_wait(mali_pm_lock_execute_state_change,_MALI_OSK_LOCKMODE_RW);
-}
-
-inline void mali_pm_execute_state_change_unlock(void)
-{
- _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
-}
-
-static void mali_pm_powerup(void)
-{
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT(3, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n"));
- mali_platform_power_mode_change(MALI_POWER_MODE_ON);
-#else
- /* Aquire our reference */
- _mali_osk_pm_dev_activate();
-#endif
- mali_group_power_on();
-}
-
-static void mali_pm_powerdown(mali_power_mode power_mode)
-{
- if ( (MALI_PM_LEVEL_1_ON == current_level) || (MALI_PM_LEVEL_2_STANDBY == current_level) )
- {
- mali_group_power_off();
- }
-
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
- mali_platform_power_mode_change(power_mode);
-#else
- _mali_osk_pm_dev_idle();
-
- if (MALI_POWER_MODE_DEEP_SLEEP == power_mode)
- {
- mali_platform_power_mode_change(power_mode);
- }
-#endif
-}
-
-mali_bool mali_pm_is_powered_on(void)
-{
- mali_bool is_on = MALI_TRUE;
-
- if( ! (MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme) )
- {
- is_on = MALI_FALSE;
- }
- else if ( ! (MALI_PM_LEVEL_1_ON == current_level || MALI_PM_LEVEL_2_STANDBY == current_level))
- {
- is_on = MALI_FALSE;
- }
- else if ( ! (MALI_PM_LEVEL_1_ON == next_level_dynamic || MALI_PM_LEVEL_2_STANDBY == next_level_dynamic))
- {
- is_on = MALI_FALSE;
- }
-
- return is_on;
-}
-
-MALI_DEBUG_CODE(
-static const char *state_as_string(enum mali_pm_level level)
-{
- switch(level)
- {
- case MALI_PM_LEVEL_1_ON:
- return "MALI_PM_LEVEL_1_ON";
- case MALI_PM_LEVEL_2_STANDBY:
- return "MALI_PM_LEVEL_2_STANDBY";
- case MALI_PM_LEVEL_3_LIGHT_SLEEP:
- return "MALI_PM_LEVEL_3_LIGHT_SLEEP";
- case MALI_PM_LEVEL_4_DEEP_SLEEP:
- return "MALI_PM_LEVEL_4_DEEP_SLEEP";
- default:
- return "UNKNOWN LEVEL";
- }
-});
-
-/* This could be used from another thread (work queue), if we need that */
-static void mali_pm_process_next(void)
-{
- enum mali_pm_level pm_level_to_set;
-
- _mali_osk_lock_wait(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
-
- pm_level_to_set = current_level;
-
- if (MALI_PM_SCHEME_DYNAMIC == current_scheme)
- {
- pm_level_to_set = next_level_dynamic;
-
- MALI_DEBUG_PRINT(4, ("Mali PM: Dynamic scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(pm_level_to_set)));
-
- if (current_level == pm_level_to_set)
- {
- goto end_function; /* early out, no change in power level */
- }
-
- /* Start timers according to new state, so we get STANDBY -> LIGHT_SLEEP -> DEEP_SLEEP */
-
- if (MALI_TRUE == idle_timer_running)
- {
- /* There is an existing timeout, so delete it */
- _mali_osk_timer_del(idle_timer);
- idle_timer_running = MALI_FALSE;
- }
-
- /* Making sure that we turn on through the platform file
- Since it was turned OFF directly through the platform file.
- This might lead to double turn-on, but the plaform file supports that.*/
- if ( current_level == MALI_PM_LEVEL_4_DEEP_SLEEP)
- {
- mali_pm_powerup();
- mali_kernel_core_wakeup();
-
- }
- if (MALI_PM_LEVEL_1_ON == pm_level_to_set)
- {
- if (MALI_PM_LEVEL_2_STANDBY != current_level)
- {
- /* We only need to do anything if we came from one of the sleeping states */
- mali_pm_powerup();
-
- /* Wake up Mali cores since we came from a sleep state */
- mali_kernel_core_wakeup();
- }
- }
- else if (MALI_PM_LEVEL_2_STANDBY == pm_level_to_set)
- {
- /* This is just an internal state, so we don't bother to report it to the platform file */
- idle_timer_running = MALI_TRUE;
- _mali_osk_timer_setcallback(idle_timer, timeout_light_sleep, (void*) mali_pm_event_number_get());
- _mali_osk_timer_add(idle_timer, _mali_osk_time_mstoticks(MALI_PM_LIGHT_SLEEP_TIMEOUT));
- }
- else if (MALI_PM_LEVEL_3_LIGHT_SLEEP == pm_level_to_set)
- {
- mali_pm_powerdown(MALI_POWER_MODE_LIGHT_SLEEP);
- }
- else if (MALI_PM_LEVEL_4_DEEP_SLEEP == pm_level_to_set)
- {
- MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n"));
- mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP);
- }
- }
- else if (MALI_PM_SCHEME_OS_SUSPENDED == current_scheme)
- {
- MALI_DEBUG_PRINT(4, ("Mali PM: OS scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_4_DEEP_SLEEP)));
-
- pm_level_to_set = MALI_PM_LEVEL_4_DEEP_SLEEP;
-
- if (current_level == pm_level_to_set)
- {
- goto end_function; /* early out, no change in power level */
- }
-
- /* Cancel any timers */
- if (MALI_TRUE == idle_timer_running)
- {
- /* There is an existing timeout, so delete it */
- _mali_osk_timer_del(idle_timer);
- idle_timer_running = MALI_FALSE;
- }
-
- MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n"));
- mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP);
- next_level_dynamic = current_level;
- }
- else if (MALI_PM_SCHEME_ALWAYS_ON == current_scheme)
- {
- MALI_DEBUG_PRINT(4, ("Mali PM: Always on scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_1_ON)));
-
- pm_level_to_set = MALI_PM_LEVEL_1_ON;
- if (current_level == pm_level_to_set)
- {
- goto end_function; /* early out, no change in power level */
- }
-
- MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n"));
- mali_pm_powerup();
- if (MALI_PM_LEVEL_2_STANDBY != current_level)
- {
- /* Wake up Mali cores since we came from a sleep state */
- mali_kernel_core_wakeup();
- }
- }
- else
- {
- MALI_PRINT_ERROR(("MALI PM: Illegal scheme"));
- }
-
- current_level = pm_level_to_set;
-
-end_function:
- _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
-
-}
-
-void mali_pm_always_on(mali_bool enable)
-{
- if (MALI_TRUE == enable)
- {
- /* The event is processed in current thread synchronously */
- mali_pm_event(MALI_PM_EVENT_SCHEME_ALWAYS_ON, MALI_FALSE, 0 );
- }
- else
- {
- /* The event is processed in current thread synchronously */
- mali_pm_event(MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL, MALI_FALSE, 0 );
- }
-}
-
-static _mali_osk_errcode_t mali_pm_upper_half(void *data)
-{
- /* not used */
- return _MALI_OSK_ERR_OK;
-}
-
-static void mali_pm_bottom_half(void *data)
-{
- mali_pm_process_next();
-}
-
-static u32 mali_pm_event_number_get(void)
-{
- u32 retval;
-
- mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */
- retval = ++mali_pm_event_number;
- if (0==retval ) retval = ++mali_pm_event_number;
- mali_pm_unlock();
-
- return retval;
-}
-
-static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time )
-{
- mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */
- /* Only timer events should set this variable, all other events must set it to zero. */
- if ( 0 != timer_time )
- {
- MALI_DEBUG_ASSERT( (pm_event==MALI_PM_EVENT_TIMER_LIGHT_SLEEP) || (pm_event==MALI_PM_EVENT_TIMER_DEEP_SLEEP) );
- if ( mali_pm_event_number != timer_time )
- {
- /* In this case there have been processed newer events since the timer event was set up.
- If so we always ignore the timing event */
- mali_pm_unlock();
- return;
- }
- }
- else
- {
- /* Delete possible ongoing timers
- if ( (MALI_PM_LEVEL_2_STANDBY==current_level) || (MALI_PM_LEVEL_3_LIGHT_SLEEP==current_level) )
- {
- _mali_osk_timer_del(idle_timer);
- }
- */
- }
- mali_pm_event_number++;
- switch (pm_event)
- {
- case MALI_PM_EVENT_CORES_WORKING:
- next_level_dynamic = MALI_PM_LEVEL_1_ON;
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- break;
- case MALI_PM_EVENT_CORES_IDLE:
- next_level_dynamic = MALI_PM_LEVEL_2_STANDBY;
- /*MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );*/
- break;
- case MALI_PM_EVENT_TIMER_LIGHT_SLEEP:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- next_level_dynamic = MALI_PM_LEVEL_3_LIGHT_SLEEP;
- break;
- case MALI_PM_EVENT_TIMER_DEEP_SLEEP:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP;
- break;
- case MALI_PM_EVENT_OS_SUSPEND:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- current_scheme = MALI_PM_SCHEME_OS_SUSPENDED;
- next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP; /* Dynamic scheme will go into level when we are resumed */
- break;
- case MALI_PM_EVENT_OS_RESUME:
- MALI_DEBUG_ASSERT(MALI_PM_SCHEME_OS_SUSPENDED == current_scheme );
- current_scheme = MALI_PM_SCHEME_DYNAMIC;
- break;
- case MALI_PM_EVENT_SCHEME_ALWAYS_ON:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- current_scheme = MALI_PM_SCHEME_ALWAYS_ON;
- break;
- case MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme );
- current_scheme = MALI_PM_SCHEME_DYNAMIC;
- break;
- default:
- MALI_DEBUG_PRINT_ERROR(("Unknown next state."));
- mali_pm_unlock();
- return;
- }
- mali_pm_unlock();
-
- if (MALI_TRUE == schedule_work)
- {
- _mali_osk_irq_schedulework(wq_irq);
- }
- else
- {
- mali_pm_process_next();
- }
-}
-
-static void timeout_light_sleep(void* arg)
-{
- /* State change only if no newer power events have happend from the time in arg.
- Actual work will be scheduled on worker thread. */
- mali_pm_event(MALI_PM_EVENT_TIMER_LIGHT_SLEEP, MALI_TRUE, (u32) arg);
-}
-
-void mali_pm_core_event(enum mali_core_event core_event)
-{
- mali_bool transition_working = MALI_FALSE;
- mali_bool transition_idle = MALI_FALSE;
-
- _mali_osk_lock_wait(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW);
-
- switch (core_event)
- {
- case MALI_CORE_EVENT_GP_START:
- if (num_active_pps + num_active_gps == 0)
- {
- transition_working = MALI_TRUE;
- }
- num_active_gps++;
- break;
- case MALI_CORE_EVENT_GP_STOP:
- if (num_active_pps + num_active_gps == 1)
- {
- transition_idle = MALI_TRUE;
- }
- num_active_gps--;
- break;
- case MALI_CORE_EVENT_PP_START:
- if (num_active_pps + num_active_gps == 0)
- {
- transition_working = MALI_TRUE;
- }
- num_active_pps++;
- break;
- case MALI_CORE_EVENT_PP_STOP:
- if (num_active_pps + num_active_gps == 1)
- {
- transition_idle = MALI_TRUE;
- }
- num_active_pps--;
- break;
- }
-
- if (transition_working == MALI_TRUE)
- {
-#ifdef CONFIG_MALI400_GPU_UTILIZATION
- mali_utilization_core_start(_mali_osk_time_get_ns());
-#endif
- mali_pm_event(MALI_PM_EVENT_CORES_WORKING, MALI_FALSE, 0); /* process event in same thread */
- }
- else if (transition_idle == MALI_TRUE)
- {
-#ifdef CONFIG_MALI400_GPU_UTILIZATION
- mali_utilization_core_end(_mali_osk_time_get_ns());
-#endif
- mali_pm_event(MALI_PM_EVENT_CORES_IDLE, MALI_FALSE, 0); /* process event in same thread */
- }
-
- _mali_osk_lock_signal(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW);
-}
-
-void mali_pm_os_suspend(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS suspending...\n"));
-
- mali_gp_scheduler_suspend();
- mali_pp_scheduler_suspend();
- mali_pm_event(MALI_PM_EVENT_OS_SUSPEND, MALI_FALSE, 0); /* process event in same thread */
-
- MALI_DEBUG_PRINT(2, ("Mali PM: OS suspend completed\n"));
-}
-
-void mali_pm_os_resume(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS resuming...\n"));
-
- mali_pm_event(MALI_PM_EVENT_OS_RESUME, MALI_FALSE, 0); /* process event in same thread */
- mali_gp_scheduler_resume();
- mali_pp_scheduler_resume();
-
- MALI_DEBUG_PRINT(2, ("Mali PM: OS resume completed\n"));
-}
-
-void mali_pm_runtime_suspend(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime suspended\n"));
- mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
-}
-
-void mali_pm_runtime_resume(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime resumed\n"));
- mali_platform_power_mode_change(MALI_POWER_MODE_ON);
-}