mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) { MALI_DEBUG_ASSERT_POINTER(pmm); MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); pmm->cores_idle |= (cores); return pmm->cores_idle; }
mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) { MALI_DEBUG_ASSERT_POINTER(pmm); MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); /* Check core is not pending a power up */ MALI_DEBUG_ASSERT( (pmm->cores_pend_up & cores) != 0 ); /* Check core has not acknowledged power up more than once */ MALI_DEBUG_ASSERT( (pmm->cores_ack_up & cores) == 0 ); pmm->cores_ack_up |= (cores); return pmm->cores_ack_up; }
mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) { mali_pmm_core_mask cores_subset; MALI_DEBUG_ASSERT_POINTER(pmm); MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); /* Check that cores aren't pending power down when asked for power up */ MALI_DEBUG_ASSERT( pmm->cores_pend_down == 0 ); cores_subset = (~(pmm->cores_powered) & cores); if( cores_subset != 0 ) { /* There are some cores that need powering up */ pmm->cores_pend_up = cores_subset; } return cores_subset; }
void malipmm_core_unregister( mali_pmm_core_id core ) { _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; MALI_DEBUG_ASSERT_POINTER(pmm); MALI_PMM_LOCK(pmm); /* Check if the core is registered in PMM */ MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, core ); MALIPMM_DEBUG_PRINT( ("PMM: core unregistered: (0x%x) %s\n", core, pmm_trace_get_core_name(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); pmm->cores_pend_up &= (~core); pmm->cores_ack_down &= (~core); pmm->cores_ack_up &= (~core); pmm_update_system_state( pmm ); #if MALI_PMM_TRACE _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered ); #endif } MALI_PMM_UNLOCK(pmm); }
mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ) { mali_pmm_core_mask cores; MALI_DEBUG_ASSERT_POINTER(pmm); MALI_DEBUG_ASSERT_POINTER(event); switch( event->id ) { case MALI_PMM_EVENT_OS_POWER_UP: case MALI_PMM_EVENT_OS_POWER_DOWN: /* All cores - the system */ cores = pmm->cores_registered; break; case MALI_PMM_EVENT_JOB_SCHEDULED: case MALI_PMM_EVENT_JOB_QUEUED: case MALI_PMM_EVENT_JOB_FINISHED: case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK: case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK: /* Currently the main event data is only the cores * for these messages */ cores = (mali_pmm_core_mask)event->data; if( cores == MALI_PMM_CORE_SYSTEM ) { cores = pmm->cores_registered; } else if( cores == MALI_PMM_CORE_PP_ALL ) { /* Get the subset of registered PP cores */ cores = (pmm->cores_registered & MALI_PMM_CORE_PP_ALL); } MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); break; default: /* Assume timeout messages - report cores still powered */ cores = pmm->cores_powered; break; } return cores; }
void malipmm_core_unregister( mali_pmm_core_id core ) { _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; MALI_DEBUG_ASSERT_POINTER(pmm); MALI_PMM_LOCK(pmm); #if MALI_STATE_TRACKING pmm->mali_pmm_lock_acquired = 1; #endif /* MALI_STATE_TRACKING */ /* Check if the core is registered in PMM */ MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, core ); MALIPMM_DEBUG_PRINT( ("PMM: core unregistered: (0x%x) %s\n", core, pmm_trace_get_core_name(core)) ); { #if MALI_PMM_TRACE mali_pmm_core_mask old_power = pmm->cores_powered; #endif /* Remove the core from the system */ pmm->cores_idle &= (~core); pmm->cores_powered &= (~core); pmm->cores_pend_down &= (~core); pmm->cores_pend_up &= (~core); pmm->cores_ack_down &= (~core); pmm->cores_ack_up &= (~core); pmm_update_system_state( pmm ); #if MALI_PMM_TRACE _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered ); #endif } #if MALI_STATE_TRACKING pmm->mali_pmm_lock_acquired = 0; #endif /* MALI_STATE_TRACKING */ MALI_PMM_UNLOCK(pmm); }
mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only ) { mali_pmm_core_mask cores_subset; _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(pmm); MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); /* Check that cores aren't pending power up when asked for power down */ MALI_DEBUG_ASSERT( pmm->cores_pend_up == 0 ); cores_subset = (pmm->cores_powered & cores); if( cores_subset != 0 ) { int n; volatile mali_pmm_core_mask *ppowered = &(pmm->cores_powered); /* There are some cores that need powering up, but we may * need to wait until they are idle */ for( n = SIZEOF_CORES_LIST-1; n >= 0; n-- ) { if( (cores_list[n] & cores_subset) != 0 ) { /* Core is to be powered down */ pmm->cores_pend_down |= cores_list[n]; /* Can't hold the power lock, when acessing subsystem mutex via * the core power call. * Due to terminatation of driver requiring a subsystem mutex * and then power lock held to unregister a core. * This does mean that the following function could fail * as the core is unregistered before we tell it to power * down, but it does not matter as we are terminating */ MALI_PMM_UNLOCK(pmm); /* Signal the core to power down * If it is busy (not idle) it will set a pending power down flag * (as long as we don't want to only immediately power down). * If it isn't busy it will move out of the idle queue right * away */ err = mali_core_signal_power_down( cores_list[n], immediate_only ); MALI_PMM_LOCK(pmm); /* Re-read cores_subset in case it has changed */ cores_subset = (*ppowered & cores); if( err == _MALI_OSK_ERR_OK ) { /* We moved an idle core to the power down queue * which means it is now acknowledged (if it is still * registered) */ pmm->cores_ack_down |= (cores_list[n] & cores_subset); } else { MALI_DEBUG_ASSERT( err == _MALI_OSK_ERR_BUSY || (err == _MALI_OSK_ERR_FAULT && (*ppowered & cores_list[n]) == 0) ); /* If we didn't move a core - it must be active, so * leave it pending, so we get an acknowledgement (when * not in immediate only mode) * Alternatively we are shutting down and the core has * been unregistered */ } } } } return cores_subset; }