summaryrefslogtreecommitdiff
path: root/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c')
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c191
1 files changed, 138 insertions, 53 deletions
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c
index eeb29589ddc..1b17a9ffe95 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c
@@ -23,6 +23,7 @@
#include "mali_pmm_system.h"
#include "mali_pmm_state.h"
#include "mali_pmm_policy.h"
+#include "mali_pmm_pmu.h"
#include "mali_platform.h"
/* Internal PMM subsystem state */
@@ -64,7 +65,7 @@ _mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifi
void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id );
#if MALI_STATE_TRACKING
- void malipmm_subsystem_dump_state( void );
+u32 malipmm_subsystem_dump_state( char *buf, u32 size );
#endif
@@ -295,7 +296,7 @@ _mali_osk_errcode_t _mali_pmm_get_policy( mali_pmm_policy *policy )
MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS );
}
-#if MALI_PMM_TRACE
+#if ( MALI_PMM_TRACE || MALI_STATE_TRACKING )
/* Event names - order must match mali_pmm_event_id enum */
static char *pmm_trace_events[] = {
@@ -307,19 +308,6 @@ static char *pmm_trace_events[] = {
"TIMEOUT",
};
-/* UK event names - order must match mali_pmm_event_id enum */
-static char *pmm_trace_events_uk[] = {
- "UKS",
- "UK_EXAMPLE",
-};
-
-/* Internal event names - order must match mali_pmm_event_id enum */
-static char *pmm_trace_events_internal[] = {
- "INTERNALS",
- "INTERNAL_POWER_UP_ACK",
- "INTERNAL_POWER_DOWN_ACK",
-};
-
/* State names - order must match mali_pmm_state enum */
static char *pmm_trace_state[] = {
"UNAVAILABLE",
@@ -335,6 +323,35 @@ static char *pmm_trace_policy[] = {
"JOB CONTROL",
};
+/* Status names - order must match mali_pmm_status enum */
+static char *pmm_trace_status[] = {
+ "MALI_PMM_STATUS_IDLE", /**< PMM is waiting next event */
+ "MALI_PMM_STATUS_POLICY_POWER_DOWN", /**< Policy initiated power down */
+ "MALI_PMM_STATUS_POLICY_POWER_UP", /**< Policy initiated power down */
+ "MALI_PMM_STATUS_OS_WAITING", /**< PMM is waiting for OS power up */
+ "MALI_PMM_STATUS_OS_POWER_DOWN", /**< OS initiated power down */
+ "MALI_PMM_STATUS_RUNTIME_IDLE_IN_PROGRESS",
+ "MALI_PMM_STATUS_DVFS_PAUSE", /**< PMM DVFS Status Pause */
+ "MALI_PMM_STATUS_OS_POWER_UP", /**< OS initiated power up */
+ "MALI_PMM_STATUS_OFF", /**< PMM is not active */
+};
+
+#endif /* MALI_PMM_TRACE || MALI_STATE_TRACKING */
+#if MALI_PMM_TRACE
+
+/* UK event names - order must match mali_pmm_event_id enum */
+static char *pmm_trace_events_uk[] = {
+ "UKS",
+ "UK_EXAMPLE",
+};
+
+/* Internal event names - order must match mali_pmm_event_id enum */
+static char *pmm_trace_events_internal[] = {
+ "INTERNALS",
+ "INTERNAL_POWER_UP_ACK",
+ "INTERNAL_POWER_DOWN_ACK",
+};
+
void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate )
{
const char *dname;
@@ -480,11 +497,11 @@ _mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource)
/* Set up assumes all values are initialized to NULL or MALI_FALSE, so
* we can exit halfway through set up and perform clean up
*/
-#if !MALI_PMM_NO_PMU
- if( mali_platform_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup;
- pmm_state->pmu_initialized = MALI_TRUE;
-#endif
+#if USING_MALI_PMU
+ if( mali_pmm_pmu_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup;
+ pmm_state->pmu_initialized = MALI_TRUE;
+#endif
pmm_state->queue = _mali_osk_notification_queue_init();
if( !pmm_state->queue ) goto pmm_fail_cleanup;
@@ -518,12 +535,18 @@ pmm_fail_cleanup:
MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") );
if( pmm_state )
{
- _mali_osk_resource_type_t t = PMU;
if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock );
if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq );
if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue );
if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue );
- if( pmm_state->pmu_initialized ) ( mali_platform_deinit(&t) );
+#if USING_MALI_PMU
+ if( pmm_state->pmu_initialized )
+ {
+ _mali_osk_resource_type_t t = PMU;
+ mali_pmm_pmu_deinit(&t);
+ }
+#endif /* USING_MALI_PMU */
+
_mali_osk_free(pmm_state);
pmm_state = NULL;
}
@@ -547,6 +570,23 @@ _mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifi
return pmm_policy_init( pmm );
}
+void malipmm_force_powerup( void )
+{
+ _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
+ MALI_DEBUG_ASSERT_POINTER(pmm);
+ MALI_PMM_LOCK(pmm);
+ pmm->status = MALI_PMM_STATUS_OFF;
+ MALI_PMM_UNLOCK(pmm);
+
+ /* flush PMM workqueue */
+ _mali_osk_flush_workqueue( pmm->irq );
+
+ if (pmm->cores_powered == 0)
+ {
+ malipmm_powerup(pmm->cores_registered);
+ }
+}
+
void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
{
/* Check this is the right system */
@@ -555,7 +595,6 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
if( pmm_state )
{
- _mali_osk_resource_type_t t = PMU;
#if PMM_OS_TEST
power_test_end();
#endif
@@ -569,11 +608,20 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
pmm_state->mali_pmm_lock_acquired = 0;
#endif /* MALI_STATE_TRACKING */
MALI_PMM_UNLOCK(pmm_state);
+ _mali_osk_pmm_ospmm_cleanup();
pmm_policy_term(pmm_state);
_mali_osk_irq_term( pmm_state->irq );
_mali_osk_notification_queue_term( pmm_state->queue );
_mali_osk_notification_queue_term( pmm_state->iqueue );
- if( pmm_state->pmu_initialized ) mali_platform_deinit(&t);
+ if (pmm_state->cores_registered) malipmm_powerdown(pmm_state->cores_registered,MALI_POWER_MODE_LIGHT_SLEEP);
+#if USING_MALI_PMU
+ if( pmm_state->pmu_initialized )
+ {
+ _mali_osk_resource_type_t t = PMU;
+ mali_pmm_pmu_deinit(&t);
+ }
+#endif /* USING_MALI_PMU */
+
_mali_osk_atomic_term( &(pmm_state->messages_queued) );
MALI_PMM_LOCK_TERM(pmm_state);
_mali_osk_free(pmm_state);
@@ -583,6 +631,47 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") );
}
+_mali_osk_errcode_t malipmm_powerup( u32 cores )
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+ _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
+
+ /* If all the cores are powered down, power up the MALI */
+ if (pmm->cores_powered == 0)
+ {
+ mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+ /* Initiate the power up */
+ _mali_osk_pmm_dev_activate();
+#endif
+ }
+
+#if USING_MALI_PMU
+ err = mali_pmm_pmu_powerup( cores );
+#endif
+ return err;
+}
+
+_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode )
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+ _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
+#if USING_MALI_PMU
+ err = mali_pmm_pmu_powerdown( cores );
+#endif
+
+ /* If all cores are powered down, power off the MALI */
+ if (pmm->cores_powered == 0)
+ {
+#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+ /* Initiate the power down */
+ _mali_osk_pmm_dev_idle();
+#endif
+ mali_platform_power_mode_change(power_mode);
+ }
+ return err;
+}
+
_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
{
_mali_osk_errcode_t err;
@@ -614,7 +703,7 @@ _mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
#if !MALI_PMM_NO_PMU
/* Make sure the core is powered up */
- err = mali_platform_powerup( core );
+ err = malipmm_powerup( core );
#else
err = _MALI_OSK_ERR_OK;
#endif
@@ -668,18 +757,7 @@ void malipmm_core_unregister( mali_pmm_core_id core )
#if MALI_PMM_TRACE
mali_pmm_core_mask old_power = pmm->cores_powered;
#endif
-
-#if !MALI_PMM_NO_PMU
- /* Turn off the core */
- if( mali_platform_powerdown( core ) != _MALI_OSK_ERR_OK )
- {
- MALI_PRINT_ERROR( ("PMM: Error powering down unregistered core: (0x%x) %s\n",
- core, pmm_trace_get_core_name(core)) );
- }
-#endif
-
/* Remove the core from the system */
- pmm->cores_registered &= (~core);
pmm->cores_idle &= (~core);
pmm->cores_powered &= (~core);
pmm->cores_pend_down &= (~core);
@@ -740,7 +818,7 @@ void malipmm_irq_bhandler(void *data)
#endif
MALI_PMM_LOCK(pmm);
-#ifdef MALI_STATE_TRACKING
+#if MALI_STATE_TRACKING
pmm->mali_pmm_lock_acquired = 1;
#endif /* MALI_STATE_TRACKING */
@@ -825,10 +903,10 @@ static void pmm_event_process( void )
return;
}
else
- {
+ {
#if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->messages_received++;
- #endif
+ #endif
}
}
else
@@ -843,7 +921,7 @@ static void pmm_event_process( void )
{
#if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->imessages_received++;
- #endif
+ #endif
}
MALI_DEBUG_ASSERT_POINTER( msg );
@@ -893,29 +971,36 @@ static void pmm_event_process( void )
}
#if MALI_STATE_TRACKING
-void malipmm_subsystem_dump_state(void)
-{
- malipmm_state_dump();
-}
-#endif
-
-#if (defined(DEBUG) || MALI_STATE_TRACKING)
-void malipmm_state_dump()
+u32 malipmm_subsystem_dump_state(char *buf, u32 size)
{
+ int len = 0;
_mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
if( !pmm )
{
- MALI_PRINT(("PMM: Null state\n"));
+ len += _mali_osk_snprintf(buf + len, size + len, "PMM: Null state\n");
}
else
{
- MALI_PRINT(("Locks::\nPMM_LOCK_STATUS=%ld",pmm->mali_pmm_lock_acquired));
- MALI_PRINT(("PMM state:\nPrevious_status=%d\nstatus=%d\nCurrent_event=%d\npolicy=%d\ncheck_policy=%d\nstate=%d\n", pmm->mali_last_pmm_status,pmm->status, pmm->mali_new_event_status, pmm->policy, pmm->check_policy, pmm->state));
- MALI_PRINT(("PMM cores:\ncores_registered=%d\ncores_powered=%d\ncores_idle=%d\ncores_pend_down=%d\ncores_pend_up=%d\ncores_ack_down=%d\ncores_ack_up=%d\n", pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down, pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up));
- MALI_PRINT(("PMM misc:\npmu_init=%d\nmessages_queued=%d\nwaiting=%d\nno_events=%d\nmissed=%d\nfatal_power_err=%d\n", pmm->pmu_initialized, _mali_osk_atomic_read( &(pmm->messages_queued) ), pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err));
+ len += _mali_osk_snprintf(buf+len, size+len, "Locks:\n PMM lock acquired: %s\n",
+ pmm->mali_pmm_lock_acquired ? "true" : "false");
+ len += _mali_osk_snprintf(buf+len, size+len,
+ "PMM state:\n Previous status: %s\n Status: %s\n Current event: %s\n Policy: %s\n Check policy: %s\n State: %s\n",
+ pmm_trace_status[pmm->mali_last_pmm_status], pmm_trace_status[pmm->status],
+ pmm_trace_events[pmm->mali_new_event_status], pmm_trace_policy[pmm->policy],
+ pmm->check_policy ? "true" : "false", pmm_trace_state[pmm->state]);
+ len += _mali_osk_snprintf(buf+len, size+len,
+ "PMM cores:\n Cores registered: %d\n Cores powered: %d\n Cores idle: %d\n"
+ " Cores pending down: %d\n Cores pending up: %d\n Cores ack down: %d\n Cores ack up: %d\n",
+ pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down,
+ pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up);
+ len += _mali_osk_snprintf(buf+len, size+len, "PMM misc:\n PMU init: %s\n Messages queued: %d\n"
+ " Waiting: %d\n No events: %d\n Missed events: %d\n Fatal power error: %s\n",
+ pmm->pmu_initialized ? "true" : "false", _mali_osk_atomic_read(&(pmm->messages_queued)),
+ pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err ? "true" : "false");
}
+ return len;
}
-#endif
+#endif /* MALI_STATE_TRACKING */
#endif /* USING_MALI_PMM */