diff options
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.c | 191 |
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 */ |