summaryrefslogtreecommitdiff
path: root/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm')
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c191
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h45
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c350
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h87
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h16
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c1
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c17
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h4
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c12
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h31
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