Example #1
0
_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
{
	_mali_osk_errcode_t err;
	_mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;

	if( pmm == NULL )
	{
		/* PMM state has not been created, this is because the PMU resource has not been 
		 * created yet.
		 * This probably means that the PMU resource has not been specfied as the first 
		 * resource in the config file
		 */
		MALI_PRINT_ERROR( ("PMM: Cannot register core %s because the PMU resource has not been\n initialized. Please make sure the PMU resource is the first resource in the\n resource configuration.\n", 
							pmm_trace_get_core_name(core)) );
		MALI_ERROR(_MALI_OSK_ERR_FAULT);
	}

	MALI_PMM_LOCK(pmm);

	/* Check if the core is registered more than once in PMM */
	MALI_DEBUG_ASSERT( (pmm->cores_registered & core) == 0 );

	MALIPMM_DEBUG_PRINT( ("PMM: core registered: (0x%x) %s\n", core, pmm_trace_get_core_name(core)) );

#if !MALI_PMM_NO_PMU
	/* Make sure the core is powered up */
	err = mali_platform_powerup( core );
#else
	err = _MALI_OSK_ERR_OK;
#endif
	if( _MALI_OSK_ERR_OK == err )
	{
#if MALI_PMM_TRACE
		mali_pmm_core_mask old_power = pmm->cores_powered;
#endif
		/* Assume a registered core is now powered up and idle */
		pmm->cores_registered |= core;
		pmm->cores_idle |= core;
		pmm->cores_powered |= core;
		pmm_update_system_state( pmm );

#if MALI_PMM_TRACE
		_mali_pmm_trace_hardware_change( old_power, pmm->cores_powered );
#endif		
	}
	else
	{
		MALI_PRINT_ERROR( ("PMM: Error(%d) powering up registered core: (0x%x) %s\n", 
								err, core, pmm_trace_get_core_name(core)) );
	}

	MALI_PMM_UNLOCK(pmm);
	
	return err;
}
Example #2
0
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);
}
Example #3
0
void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool received )
{
	const char *ename;
	const char *dname;
	const char *tname;
	const char *format = "PMM Trace: Event %s { (%d) %s, %d ticks, (0x%x) %s }";

	MALI_DEBUG_ASSERT_POINTER(event);

	tname = (received) ? "received" : "sent";

	if( event->id >= MALI_PMM_EVENT_INTERNALS )
	{
		ename = pmm_trace_events_internal[((int)event->id) - MALI_PMM_EVENT_INTERNALS];
	}
	else if( event->id >= MALI_PMM_EVENT_UKS )
	{
		ename = pmm_trace_events_uk[((int)event->id) - MALI_PMM_EVENT_UKS];
	}
	else
	{
		ename = pmm_trace_events[event->id];
	}

	switch( event->id )
	{
		case MALI_PMM_EVENT_OS_POWER_UP:
		case MALI_PMM_EVENT_OS_POWER_DOWN:
			dname = "os event";
			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:
			dname = pmm_trace_get_core_name( (mali_pmm_core_mask)event->data );
			break;
			
		case MALI_PMM_EVENT_TIMEOUT:
			dname = "timeout start";
			/* Print data with a different format */
			format = "PMM Trace: Event %s { (%d) %s, %d ticks, %d ticks %s }";
			break;
		default:
			dname = "unknown data";
	}

	MALI_PRINT( (format, tname, (u32)event->id, ename, event->ts, (u32)event->data, dname) );
}
Example #4
0
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);

	/* Check that cores are pending power down during power down invoke */
	MALI_DEBUG_ASSERT( pmm->cores_pend_down != 0 );
	/* Check that cores are not pending power up during power down invoke */
	MALI_DEBUG_ASSERT( pmm->cores_pend_up == 0 );

	if( !pmm_power_down_okay( pmm ) )
	{
		MALIPMM_DEBUG_PRINT( ("PMM: Waiting for cores to go idle for power off - 0x%08x / 0x%08x\n", 
				pmm->cores_pend_down, pmm->cores_ack_down) );
		return MALI_FALSE;
	}
	else
	{
		pmm->cores_powered &= ~(pmm->cores_pend_down);
#if !MALI_PMM_NO_PMU
		err = malipmm_powerdown( pmm->cores_pend_down, power_mode);
#else
		err = _MALI_OSK_ERR_OK;
#endif
		
		if( err == _MALI_OSK_ERR_OK )
		{
#if MALI_PMM_TRACE
			mali_pmm_core_mask old_power = pmm->cores_powered;
#endif
			/* Remove powered down cores from idle and powered list */
			pmm->cores_idle &= ~(pmm->cores_pend_down);
			/* Reset pending/acknowledged status */
			pmm->cores_pend_down = 0;
			pmm->cores_ack_down = 0;
#if MALI_PMM_TRACE
			_mali_pmm_trace_hardware_change( old_power, pmm->cores_powered );
#endif
		}
		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;
		}
	}

	return MALI_TRUE;
}
Example #5
0
void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate )
{
	const char *dname;
	const char *cname;
	const char *ename;

	if( old != newstate )
	{
		if( newstate == 0 )
		{
			dname = "NO cores";
		}
		else
		{
			dname = pmm_trace_get_core_name( newstate );
		}
			
		/* These state checks only work if the assumption that only cores can be
		 * turned on or turned off in seperate actions is true. If core power states can
		 * be toggled (some one, some off) at the same time, this check does not work
		 */
		if( old > newstate )
		{
			/* Cores have turned off */
			cname = pmm_trace_get_core_name( old - newstate );
			ename = "OFF";
		}
		else
		{
			/* Cores have turned on */
			cname = pmm_trace_get_core_name( newstate - old );
			ename = "ON";
		}
		MALI_PRINT( ("PMM Trace: Hardware %s ON, %s just turned %s. { 0x%08x -> 0x%08x }", dname, cname, ename, old, newstate) );
	}
}
Example #6
0
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);
}
Example #7
0
mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm )
{
	_mali_osk_errcode_t err;

	MALI_DEBUG_ASSERT_POINTER(pmm);

	/* Check that cores are pending power up during power up invoke */
	MALI_DEBUG_ASSERT( pmm->cores_pend_up != 0 );
	/* Check that cores are not pending power down during power up invoke */
	MALI_DEBUG_ASSERT( pmm->cores_pend_down == 0 );

	if( pmm_power_up_okay( pmm ) )
	{
		/* Power up has completed - sort out subsystem core status */
		
		int n;
		/* Use volatile to access, so that it is updated if any cores are unregistered */
		volatile mali_pmm_core_mask *ppendup = &(pmm->cores_pend_up);
#if MALI_PMM_TRACE
		mali_pmm_core_mask old_power = pmm->cores_powered;
#endif
		/* Move cores into idle queues */
		for( n = 0; n < SIZEOF_CORES_LIST; n++ )
		{
			if( (cores_list[n] & (*ppendup)) != 0 )
			{
				/* 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
				 * up, but it does not matter as we are terminating
				 */
				MALI_PMM_UNLOCK(pmm);
				err = mali_core_signal_power_up( cores_list[n], MALI_FALSE );
				MALI_PMM_LOCK(pmm);

				if( err != _MALI_OSK_ERR_OK )
				{
					MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_FAULT &&
										(*ppendup & cores_list[n]) == 0) );
					/* We only expect this to fail when we are shutting down 
					 * and the core has been unregistered
					 */
				}
			}
		}
		/* Finished power up - add cores to idle and powered list */
		pmm->cores_powered |= (*ppendup);
		pmm->cores_idle |= (*ppendup);
		/* Reset pending/acknowledge status */
		pmm->cores_pend_up = 0;
		pmm->cores_ack_up = 0;

#if MALI_PMM_TRACE
		_mali_pmm_trace_hardware_change( old_power, pmm->cores_powered );
#endif
		return MALI_TRUE;
	}
	else
	{
#if !MALI_PMM_NO_PMU
		/* Power up must now be done */
		err = mali_platform_powerup( pmm->cores_pend_up );
#else
		err = _MALI_OSK_ERR_OK;
#endif
		if( err != _MALI_OSK_ERR_OK )
		{
			MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power up cores - (0x%x) %s", 
					pmm->cores_pend_up, pmm_trace_get_core_name(pmm->cores_pend_up)) );
			pmm->fatal_power_err = MALI_TRUE;
		}
		else
		{
			/* TBD - Update core status immediately rather than use event message */
			_mali_uk_pmm_message_s event = {
				NULL,
				MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK,
				0 };
			/* All the cores that were pending power up, have now completed power up */
			event.data = pmm->cores_pend_up;
			_mali_ukk_pmm_event_message( &event );
			MALIPMM_DEBUG_PRINT( ("PMM: Sending ACK to power up") );
		}
	}

	/* Always return false, as we need an interrupt to acknowledge
	 * when power up is complete
	 */
	return MALI_FALSE;
}