diff options
Diffstat (limited to 'drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm')
11 files changed, 656 insertions, 100 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 */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h index fe7a046cb47..6157746da0c 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h @@ -18,6 +18,7 @@ /* For mali_pmm_message_data and MALI_PMM_EVENT_UK_* defines */ #include "mali_uk_types.h" +#include "mali_platform.h" #ifdef __cplusplus extern "C" @@ -40,7 +41,7 @@ extern "C" /** @brief Compile option to switch between always on or job control PMM policy */ #define MALI_PMM_ALWAYS_ON 0 -/** @brief Overrides hardware PMU and uses software simulation instead +/** @brief Overrides hardware PMU and uses software simulation instead * @note This even stops intialization of PMU and cores being powered on at start up */ #define MALI_PMM_NO_PMU 0 @@ -52,7 +53,7 @@ extern "C" /** @brief power management event message identifiers. */ -/* These must match up with the pmm_trace_events & pmm_trace_events_internal +/* These must match up with the pmm_trace_events & pmm_trace_events_internal * arrays */ typedef enum mali_pmm_event_id @@ -95,6 +96,7 @@ typedef enum mali_pmm_core_id_tag MALI_PMM_CORE_PP_ALL = 0x0000003C /**< Mali 200 pixel processors 0-3 */ } mali_pmm_core_id; + /* @brief PMM bitmask of mali_pmm_core_ids */ typedef u32 mali_pmm_core_mask; @@ -137,6 +139,23 @@ typedef enum mali_pmm_policy_tag MALI_PMM_POLICY_RUNTIME_JOB_CONTROL = 3 /**< Run time power management control policy */ } mali_pmm_policy; +/** @brief Function to power up MALI + * + * @param cores core mask to power up the cores + * + * @return error code if MALI fails to power up + */ +_mali_osk_errcode_t malipmm_powerup( u32 cores ); + +/** @brief Function to power down MALI + * + * @param cores core mask to power down the cores + * @param The power mode to which MALI transitions + * + * @return error code if MALI fails to power down + */ +_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode ); + /** @brief Function to report to the OS when the power down has finished * * @param data The event message data that initiated the power down @@ -149,7 +168,7 @@ void _mali_osk_pmm_power_down_done(mali_pmm_message_data data); */ void _mali_osk_pmm_power_up_done(mali_pmm_message_data data); -/** @brief Function to report that DVFS operation done +/** @brief Function to report that DVFS operation done * * @param data The event message data */ @@ -164,6 +183,12 @@ void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id event_id); #endif +/** @brief Function to power up MALI + * + * @note powers up the MALI during MALI device driver is unloaded + */ +void malipmm_force_powerup( void ); + /** @brief Function to report the OS that device is idle * * @note inform the OS that device is idle @@ -176,6 +201,12 @@ _mali_osk_errcode_t _mali_osk_pmm_dev_idle( void ); */ void _mali_osk_pmm_dev_activate( void ); +/** @brief Function to report OS PMM for cleanup + * + * @note Function to report OS PMM for cleanup + */ +void _mali_osk_pmm_ospmm_cleanup( void ); + /** @brief Queries the current state of the PMM software * * @note the state of the PMM can change after this call has returned @@ -305,15 +336,9 @@ void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool receive /** @brief Dumps the current state of OS PMM thread */ #if MALI_STATE_TRACKING -void mali_pmm_dump_os_thread_state( void ); +u32 mali_pmm_dump_os_thread_state( char *buf, u32 size ); #endif /* MALI_STATE_TRACKING */ -#if (defined(DEBUG) || MALI_STATE_TRACKING) -/** @brief Dumps the current state of the PMM - */ -void malipmm_state_dump( void ); -#endif - /** @} */ /* end group pmmapi */ #ifdef __cplusplus diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c new file mode 100644 index 00000000000..da8957724e8 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c @@ -0,0 +1,350 @@ +/* + * 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_pmu.c + * Mali driver functions for Mali 400 PMU hardware + */ +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_platform.h" + +#if USING_MALI_PMU +#if USING_MALI_PMM + +#include "mali_pmm.h" + +/* Internal test on/off */ +#define PMU_TEST 0 + +#if MALI_POWER_MGMT_TEST_SUITE +#include "mali_platform_pmu_internal_testing.h" +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + +/** @brief PMU hardware info + */ +typedef struct platform_pmu +{ + u32 reg_base_addr; /**< PMU registers base address */ + u32 reg_size; /**< PMU registers size */ + const char *name; /**< PMU name */ + u32 irq_num; /**< PMU irq number */ + + mali_io_address reg_mapped; /**< IO-mapped pointer to registers */ +} platform_pmu_t; + +static platform_pmu_t *pmu_info = NULL; + +/** @brief Register layout for hardware PMU + */ +typedef enum { + PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */ + PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */ + PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */ + PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */ + PMU_REG_ADDR_MGMT_INT_RAWSTAT = 0x10, /*< Interrupt raw status register */ + PMU_REG_ADDR_MGMT_INT_STAT = 0x14, /*< Interrupt status register */ + PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */ + PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Software delay register */ + PMU_REG_ADDR_MGMT_MASTER_PWR_UP = 0x24, /*< Master power up register */ + PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */ +} pmu_reg_addr_mgmt_addr; + +/* Internal functions */ +static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address); +static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val); +static mali_pmm_core_mask pmu_translate_cores_to_pmu(mali_pmm_core_mask cores); +#if PMU_TEST +static void pmm_pmu_dump_regs( platform_pmu_t *pmu ); +static pmm_pmu_test( platform_pmu_t *pmu, u32 cores ); +#endif + +_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource) +{ + + if( resource->type == PMU ) + { + if( (resource->base == 0) || + (resource->description == NULL) ) + { + /* NOTE: We currently don't care about any other resource settings */ + MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n")); + MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + } + pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info)); + MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM ); + + /* All values get 0 as default */ + _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info)); + + pmu_info->reg_base_addr = resource->base; + pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE; + pmu_info->name = resource->description; + pmu_info->irq_num = resource->irq; + + if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) ) + { + MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n", + pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); + goto cleanup; + } + else + { + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n", + pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); + } + + pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name ); + + if( 0 == pmu_info->reg_mapped ) + { + MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name)); + _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size ); + goto cleanup; + } + else + { + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n", + (u32) pmu_info->reg_mapped, + ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1, + pmu_info->name)); + } + + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name)); + +#if PMU_TEST + pmu_test(pmu_info, (MALI_PMM_CORE_GP)); + pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0)); +#endif + + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) ); + } + else + { + /* Didn't expect a different resource */ + MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + } + + MALI_SUCCESS; + +cleanup: + _mali_osk_free(pmu_info); + pmu_info = NULL; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); +} + +_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type) +{ + if (*type == PMU) + { + if( pmu_info ) + { + _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped); + _mali_osk_mem_unreqregion(pmu_info->reg_base_addr, pmu_info->reg_size); + _mali_osk_free(pmu_info); + pmu_info = NULL; + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Terminated PMU\n") ); + } + } + else + { + /* Didn't expect a different resource */ + MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + } + + MALI_SUCCESS; + +} + +_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores) +{ + u32 stat; + u32 timeout; + u32 cores_pmu; + + MALI_DEBUG_ASSERT_POINTER(pmu_info); + MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power down (0x%x)\n", cores) ); + + cores_pmu = pmu_translate_cores_to_pmu(cores); + pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_DOWN, cores_pmu ); + + /* Wait for cores to be powered down */ + timeout = 10; /* 10ms */ + do + { + /* Get status of sleeping cores */ + stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); + stat &= cores_pmu; + if( stat == cores_pmu ) break; /* All cores we wanted are now asleep */ + _mali_osk_time_ubusydelay(1000); /* 1ms */ + timeout--; + } while( timeout > 0 ); + + if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores) +{ + u32 cores_pmu; + u32 stat; + u32 timeout; + + MALI_DEBUG_ASSERT_POINTER(pmu_info); + MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power up (0x%x)\n", cores) ); + + /* Don't use interrupts - just poll status */ + pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_INT_MASK, 0 ); + cores_pmu = pmu_translate_cores_to_pmu(cores); + pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_UP, cores_pmu ); + + timeout = 10; /* 10ms */ + do + { + /* Get status of sleeping cores */ + stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); + stat &= cores_pmu; + if( stat == 0 ) break; /* All cores we wanted are now awake */ + _mali_osk_time_ubusydelay(1000); /* 1ms */ + timeout--; + } while( timeout > 0 ); + + if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); + + MALI_SUCCESS; +} + + +/***** INTERNAL *****/ + +/** @brief Internal PMU function to translate the cores bit mask + * into something the hardware PMU understands + * + * @param cores PMM cores bitmask + * @return PMU hardware cores bitmask + */ +static u32 pmu_translate_cores_to_pmu(mali_pmm_core_mask cores) +{ + /* For Mali 400 PMU the cores mask is already the same as what + * the hardware PMU expects. + * For other hardware, some translation can be done here, by + * translating the MALI_PMM_CORE_* bits into specific hardware + * bits + */ + return cores; +} + +/** @brief Internal PMU function to read a PMU register + * + * @param pmu handle that identifies the PMU hardware + * @param relative_address relative PMU hardware address to read from + * @return 32-bit value that was read from the address + */ +static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address) +{ + u32 read_val; + + MALI_DEBUG_ASSERT_POINTER(pmu); + MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); + MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); + + read_val = _mali_osk_mem_ioread32(pmu->reg_mapped, relative_address); + + MALI_DEBUG_PRINT( 5, ("PMU: reg_read: %s Addr:0x%04X Val:0x%08x\n", + pmu->name, relative_address, read_val)); + + return read_val; +} + +/** @brief Internal PMU function to write to a PMU register + * + * @param pmu handle that identifies the PMU hardware + * @param relative_address relative PMU hardware address to write to + * @param new_val new 32-bit value to write into the address + */ +static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val) +{ + MALI_DEBUG_ASSERT_POINTER(pmu); + MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); + MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); + + MALI_DEBUG_PRINT( 5, ("PMU: reg_write: %s Addr:0x%04X Val:0x%08x\n", + pmu->name, relative_address, new_val)); + + _mali_osk_mem_iowrite32(pmu->reg_mapped, relative_address, new_val); +} + +#if PMU_TEST + +/***** TEST *****/ + +static void pmu_dump_regs( platform_pmu_t *pmu ) +{ + u32 addr; + for( addr = 0x0; addr < PMU_REGISTER_ADDRESS_SPACE_SIZE; addr += 0x4 ) + { + MALI_PRINT( ("PMU_REG: 0x%08x: 0x%04x\n", (addr + pmu->reg_base_addr), pmu_reg_read( pmu, addr ) ) ); + } +} + +/* This function is an internal test for the PMU without any Mali h/w interaction */ +static void pmu_test( platform_pmu_t *pmu, u32 cores ) +{ + u32 stat; + u32 timeout; + + MALI_PRINT( ("PMU_TEST: Start\n") ); + + pmu_dump_regs( pmu ); + + MALI_PRINT( ("PMU_TEST: Power down cores: 0x%x\n", cores) ); + _mali_pmm_pmu_power_down( pmu, cores, MALI_TRUE ); + + stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); + MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == cores ? "SUCCESS" : "FAIL" ) ); + + pmu_dump_regs( pmu ); + + MALI_PRINT( ("PMU_TEST: Power up cores: 0x%x\n", cores) ); + _mali_pmm_pmu_power_up( pmu, cores, MALI_FALSE ); + + MALI_PRINT( ("PMU_TEST: Waiting for power up...\n") ); + timeout = 1000; /* 1 sec */ + while( !_mali_pmm_pmu_irq_power_up(pmu) && timeout > 0 ) + { + _mali_osk_time_ubusydelay(1000); /* 1ms */ + timeout--; + } + + MALI_PRINT( ("PMU_TEST: Waited %dms for interrupt\n", (1000-timeout)) ); + stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); + MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == 0 ? "SUCCESS" : "FAIL" ) ); + + _mali_pmm_pmu_irq_power_up_clear(pmu); + + pmu_dump_regs( pmu ); + + MALI_PRINT( ("PMU_TEST: Finish\n") ); +} +#endif /* PMU_TEST */ + +#if MALI_POWER_MGMT_TEST_SUITE + +u32 pmu_get_power_up_down_info(void) +{ + return pmu_reg_read(pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS); +} + +#endif /* MALI_POWER_MGMT_TEST_SUITE */ +#endif /* USING_MALI_PMM */ +#endif /* USING_MALI_PMU */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h new file mode 100644 index 00000000000..112074b2010 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h @@ -0,0 +1,87 @@ +/* + * 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_platform.h + * Platform specific Mali driver functions + */ + +#include "mali_osk.h" + +#if !USING_MALI_PMM +/* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */ +#define MALI_PLATFORM_SYSTEM 0 +#endif + +#if USING_MALI_PMM +#if USING_MALI_PMU +#include "mali_pmm.h" + +/** @brief Platform specific setup and initialisation of MALI + * + * This is called from the entrypoint of the driver to initialize the platform + * When using PMM, it is also called from the PMM start up to initialise the + * system PMU + * + * @param resource This is NULL when called on first driver start up, else it will + * be a pointer to a PMU resource + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource); + +/** @brief Platform specific deinitialisation of MALI + * + * This is called on the exit of the driver to terminate the platform + * When using PMM, it is also called from the PMM termination code to clean up the + * system PMU + * + * @param type This is NULL when called on driver exit, else it will + * be a pointer to a PMU resource type (not the full resource) + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type); + +/** @brief Platform specific powerdown sequence of MALI + * + * Called as part of platform init if there is no PMM support, else the + * PMM will call it. + * + * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will + * be a mask of cores to power down based on the mali_pmm_core_id enum + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores); + +/** @brief Platform specific powerup sequence of MALI + * + * Called as part of platform deinit if there is no PMM support, else the + * PMM will call it. + * + * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will + * be a mask of cores to power down based on the mali_pmm_core_id enum + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores); + +#if MALI_POWER_MGMT_TEST_SUITE +#if USING_MALI_PMM +#if USING_MALI_PMU +/** @brief function to get status of individual cores + * + * This function is used by power management test suite to get the status of powered up/down the number + * of cores + * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. + */ +u32 pmu_get_power_up_down_info(void); +#endif +#endif +#endif +#endif +#endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h index 83cb7f29a92..739c4c4ef17 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h @@ -46,7 +46,7 @@ typedef struct _pmm_policy_timer /** @brief Policy timer initialization * * This will create a timer for use in policies, but won't start it - * + * * @param pptimer An empty timer structure to be initialized * @param timeout Timeout in ticks for the timer * @param id Event id that will be raised on timeout @@ -59,7 +59,7 @@ _mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 tim * * This will clean up a timer that was previously used in policies, it * will also stop it if started - * + * * @param pptimer An initialized timer structure to be terminated */ void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer ); @@ -67,10 +67,10 @@ void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer start * * This will start a previously created timer for use in policies - * When the timer expires after the initialized timeout it will raise + * When the timer expires after the initialized timeout it will raise * a PMM event of the event id given on initialization * As data for the event it will pass the start time of the timer - * + * * @param pptimer A previously initialized policy timer * @return MALI_TRUE if the timer was started, MALI_FALSE if it is already started */ @@ -79,7 +79,7 @@ mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer stop * * This will stop a previously created timer for use in policies - * + * * @param pptimer A previously started policy timer * @return MALI_TRUE if the timer was stopped, MALI_FALSE if it is already stopped */ @@ -88,7 +88,7 @@ mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer stop * * This raise an event for an expired timer - * + * * @param pptimer An expired policy timer * @return MALI_TRUE if an event was raised, else MALI_FALSE */ @@ -97,7 +97,7 @@ mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer valid checker * * This will check that a timer was started after a given time - * + * * @param timer_start Time the timer was started * @param other_start Time when another event or action occurred * @return MALI_TRUE if the timer was started after the other time, else MALI_FALSE @@ -106,7 +106,7 @@ mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start ); /** @brief Common policy initialization - * + * * This will initialize the current policy * * @note Any previously initialized policy should be terminated first diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c index 643bb04553b..a4b893b21e6 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c @@ -21,7 +21,6 @@ #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" _mali_osk_errcode_t pmm_policy_init_always_on(void) diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h index a158b09f610..da13224d955 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 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. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c index 8450bd722f4..7f339718354 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c @@ -231,7 +231,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * if( cores_subset != 0 ) { /* There are some cores that need powering down */ - if( !pmm_invoke_power_down( pmm ) ) + if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) { /* We need to wait until they are idle */ @@ -242,6 +242,11 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * break; } } + else + { + mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); + + } /* Set waiting status */ pmm->status = MALI_PMM_STATUS_OS_WAITING; /* All cores now down - respond to OS power event */ @@ -280,7 +285,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * /* Check if we can really power down, if not then we are not * really in-active */ - if( !pmm_invoke_power_down( pmm ) ) + if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_LIGHT_SLEEP ) ) { pmm_power_down_cancel( pmm ); } @@ -322,12 +327,16 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * pmm->status = MALI_PMM_STATUS_OS_WAITING; if ( pmm->cores_powered != 0 ) { - if ( pmm_invoke_power_down( pmm ) ) + if ( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) { _mali_osk_pmm_power_down_done( 0 ); break; } } + else + { + mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); + } _mali_osk_pmm_power_down_done( 0 ); break; default: @@ -384,7 +393,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * } /* Now check if we can power down */ - if( pmm_invoke_power_down( pmm ) ) + if( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) { if( pmm->status == MALI_PMM_STATUS_OS_POWER_DOWN ) { diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h index 455234b80bc..f1e7c2d9a82 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h @@ -27,10 +27,10 @@ extern "C" * @{ */ -/** @brief The jobcontrol policy inactivity latency timeout (in ticks) +/** @brief The jobcontrol policy inactivity latency timeout (in ticks) * before the hardware is switched off * - * @note Setting this low whilst tracing or producing debug output can + * @note Setting this low whilst tracing or producing debug output can * cause alot of timeouts to fire which can affect the PMM behaviour */ #define MALI_PMM_POLICY_JOBCONTROL_INACTIVITY_TIMEOUT 50 diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c index a0ac1c7790c..2e05555cf29 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c @@ -199,6 +199,7 @@ mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mal } else { + MALI_DEBUG_PRINT(1,("The error in PMM is ...%x...%x",err,*ppowered)); MALI_DEBUG_ASSERT( err == _MALI_OSK_ERR_BUSY || (err == _MALI_OSK_ERR_FAULT && (*ppowered & cores_list[n]) == 0) ); @@ -297,7 +298,7 @@ mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm ) return ( pmm->cores_pend_down == pmm->cores_ack_down ? MALI_TRUE : MALI_FALSE ); } -mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) +mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode ) { _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(pmm); @@ -315,8 +316,9 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) } else { + pmm->cores_powered &= ~(pmm->cores_pend_down); #if !MALI_PMM_NO_PMU - err = mali_platform_powerdown( pmm->cores_pend_down ); + err = malipmm_powerdown( pmm->cores_pend_down, power_mode); #else err = _MALI_OSK_ERR_OK; #endif @@ -327,7 +329,6 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) mali_pmm_core_mask old_power = pmm->cores_powered; #endif /* Remove powered down cores from idle and powered list */ - pmm->cores_powered &= ~(pmm->cores_pend_down); pmm->cores_idle &= ~(pmm->cores_pend_down); /* Reset pending/acknowledged status */ pmm->cores_pend_down = 0; @@ -338,6 +339,7 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) } else { + pmm->cores_powered |= pmm->cores_pend_down; MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power down cores - (0x%x) %s", pmm->cores_pend_down, pmm_trace_get_core_name(pmm->cores_pend_down)) ); pmm->fatal_power_err = MALI_TRUE; @@ -429,7 +431,7 @@ mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm ) { #if !MALI_PMM_NO_PMU /* Power up must now be done */ - err = mali_platform_powerup( pmm->cores_pend_up ); + err = malipmm_powerup( pmm->cores_pend_up ); #else err = _MALI_OSK_ERR_OK; #endif @@ -537,7 +539,7 @@ void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm ) int n; volatile mali_pmm_core_mask *pregistered = &(pmm->cores_registered); #if !MALI_PMM_NO_PMU - err = mali_platform_powerup( pmm->cores_registered ); + err = malipmm_powerup( pmm->cores_registered ); #endif if( err != _MALI_OSK_ERR_OK ) { diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h index 3c8c31f066d..849fe8b8048 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h @@ -55,8 +55,7 @@ typedef enum mali_pmm_status_tag 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_OS_POWER_DOWN, /**< OS initiated power down */ 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 */ @@ -96,12 +95,12 @@ typedef struct _mali_pmm_internal_state mali_bool fatal_power_err; /**< PMM has had a fatal power error? */ u32 is_dvfs_active; /**< PMM DVFS activity */ -#if (defined(DEBUG) || MALI_STATE_TRACKING) - u32 mali_last_pmm_status; - u32 mali_new_event_status; - u32 mali_pmm_lock_acquired; +#if MALI_STATE_TRACKING + mali_pmm_status mali_last_pmm_status; /**< The previous PMM status */ + mali_pmm_event_id mali_new_event_status;/**< The type of the last PMM event */ + mali_bool mali_pmm_lock_acquired; /**< Is the PMM lock held somewhere or not */ #endif - + #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) u32 messages_sent; /**< Total event messages sent */ u32 messages_received; /**< Total event messages received */ @@ -133,11 +132,11 @@ mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, m /** @brief Sort out which cores need to be powered up from the given core mask * - * All cores that can be powered up will be put into a pending state + * All cores that can be powered up will be put into a pending state * * @param pmm internal PMM state * @param cores mask of cores to check if they need to be powered up - * @return mask of cores that need to be powered up, this can be 0 if all cores + * @return mask of cores that need to be powered up, this can be 0 if all cores * are powered up already */ mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ); @@ -153,7 +152,7 @@ mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_ * @param cores mask of cores to check if they need to be powered down * @param immediate_only MALI_TRUE means that only cores that can power down now will * be put into a pending state - * @return mask of cores that need to be powered down, this can be 0 if all cores + * @return mask of cores that need to be powered down, this can be 0 if all cores * are powered down already */ mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only ); @@ -177,13 +176,13 @@ mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm ); /** @brief Try to make all the pending cores power down * - * If all the pending cores have acknowledged they can power down, this will call the + * If all the pending cores have acknowledged they can power down, this will call the * PMU power down function to turn them off * * @param pmm internal PMM state * @return MALI_TRUE if the pending cores have been powered down, else MALI_FALSE */ -mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ); +mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode ); /** @brief Check if all the pending cores to power up have done so * @@ -230,7 +229,7 @@ mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm /** @brief Set the cores that have acknowledged a pending power down * - * Updates which cores have acknowledged the pending power down and are now ready + * Updates which cores have acknowledged the pending power down and are now ready * to be turned off * * @param pmm internal PMM state @@ -253,15 +252,15 @@ mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_p /** @brief Tries to reset the PMM and PMU hardware to a known state after any fatal issues * - * This will try and make all the cores powered up and reset the PMM state - * to its initial state after core registration - all cores powered but not + * This will try and make all the cores powered up and reset the PMM state + * to its initial state after core registration - all cores powered but not * pending or active. * All events in the event queues will be thrown away. * * @note: Any pending power down will be cancelled including the OS calling for power down */ void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm ); - + /** @brief Save the OS specific data for an OS power up/down event * * @param pmm internal PMM state |