/** Function to handle a GPU state change for the always_on power policy.
 *
 * This function is called whenever the GPU has transitioned to another state. It first checks that the transition is 
 * complete and then moves the state machine to the next state.
 *
 * @param kbdev     The kbase device structure for the device
 */
static void always_on_state_changed(kbase_device *kbdev)
{
	kbasep_pm_policy_always_on *data = &kbdev->pm.policy_data.always_on;

	switch(data->state)
	{
	case KBASEP_PM_ALWAYS_ON_STATE_POWERING_UP:
		if (kbase_pm_get_pwr_active(kbdev))
		{
			/* Cores still transitioning */
			return;
		}
		/* All cores have transitioned, inform the OS */
		kbase_pm_power_up_done(kbdev);
		data->state = KBASEP_PM_ALWAYS_ON_STATE_POWERED_UP;

		break;
	case KBASEP_PM_ALWAYS_ON_STATE_POWERING_DOWN:
		if (kbase_pm_get_pwr_active(kbdev))
		{
			/* Cores still transitioning */
			return;
		}
		/* All cores have transitioned, turn the clock and interrupts off */
		kbase_pm_disable_interrupts(kbdev);
		kbase_pm_clock_off(kbdev);

		/* Inform the OS */
		kbase_pm_power_down_done(kbdev);

		data->state = KBASEP_PM_ALWAYS_ON_STATE_POWERED_DOWN;

		break;
	case KBASEP_PM_ALWAYS_ON_STATE_CHANGING_POLICY:
		if (kbase_pm_get_pwr_active(kbdev))
		{
			/* Cores still transitioning */
			return;
		}
		/* All cores have transitioned, inform the system we can change policy*/
		kbase_pm_change_policy(kbdev);

		break;
	default:
		break;
	}
}
Ejemplo n.º 2
0
/** Function to handle a GPU state change for the demand power policy
 *
 * This function is called whenever the GPU has transitioned to another state. It first checks that the transition is 
 * complete and then moves the state machine to the next state.
 */
static void demand_state_changed(kbase_device *kbdev)
{
	kbasep_pm_policy_demand *data = &kbdev->pm.policy_data.demand;

	switch(data->state) {
		case KBASEP_PM_DEMAND_STATE_CHANGING_POLICY:
		case KBASEP_PM_DEMAND_STATE_POWERING_UP:
		case KBASEP_PM_DEMAND_STATE_POWERING_DOWN:
			if (kbase_pm_get_pwr_active(kbdev)) {
				/* Cores are still transitioning - ignore the event */
				return;
			}
			break;
		default:
			/* Must not call kbase_pm_get_pwr_active here as the clock may be turned off */
			break;
	}

	switch(data->state)
	{
		case KBASEP_PM_DEMAND_STATE_CHANGING_POLICY:
			/* Signal power events before switching the policy */
			kbase_pm_power_up_done(kbdev);
			kbase_pm_power_down_done(kbdev);
			kbase_pm_change_policy(kbdev);
			break;
		case KBASEP_PM_DEMAND_STATE_POWERING_UP:
			data->state = KBASEP_PM_DEMAND_STATE_POWERED_UP;
			kbase_pm_power_up_done(kbdev);
			/* State changed, try to run jobs */
			kbase_js_try_run_jobs(kbdev);
			break;
		case KBASEP_PM_DEMAND_STATE_POWERING_DOWN:
			data->state = KBASEP_PM_DEMAND_STATE_POWERED_DOWN;
			/* Disable interrupts and turn the clock off */
			kbase_pm_disable_interrupts(kbdev);
			kbase_pm_clock_off(kbdev);
			kbase_pm_power_down_done(kbdev);
			break;
		case KBASEP_PM_DEMAND_STATE_POWERED_UP:
			/* Core states may have been changed, try to run jobs */
			kbase_js_try_run_jobs(kbdev);
			break;
		default:
			break;
	}
}
/** Function to handle a GPU state change for the coarse_demand power policy.
 *
 * This function is called whenever the GPU has transitioned to another state. It first checks that the transition is
 * complete and then moves the state machine to the next state.
 *
 * @param kbdev     The kbase device structure for the device
 */
static void coarse_demand_state_changed(kbase_device *kbdev)
{
	kbasep_pm_policy_coarse_demand *data = &kbdev->pm.policy_data.coarse_demand;

	/* No need to early-out if cores transitioning during the POWERING_UP state */
	if (data->state != KBASEP_PM_COARSE_DEMAND_STATE_POWERING_UP
		&& kbase_pm_get_pwr_active(kbdev)) {
		/* Cores are still transitioning - ignore the event */
		return;
	}

	switch(data->state)
	{
	case KBASEP_PM_COARSE_DEMAND_STATE_POWERING_UP:
		/* All cores are ready, inform the OS */
		data->state = KBASEP_PM_COARSE_DEMAND_STATE_POWERED_UP;
		kbase_pm_power_up_done(kbdev);
		/*
		 * No need to submit jobs:
		 * - All cores will be powered on
		 * - Cores are made available even while they're transitioning to 'powered on'
		 * - We signal power_up_done after calling kbase_pm_check_transitions(), which makes the cores available.
		 * Hence, the submission of jobs will already be handled by the call-path that invoked kbase_pm_context_active()
		 */

		break;
	case KBASEP_PM_COARSE_DEMAND_STATE_POWERING_DOWN:
		data->state = KBASEP_PM_COARSE_DEMAND_STATE_POWERED_DOWN;
		/* All cores have transitioned, turn the clock and interrupts off */
		kbase_pm_clock_off(kbdev);

		/* Inform the OS */
		kbase_pm_power_down_done(kbdev);

		break;
	case KBASEP_PM_COARSE_DEMAND_STATE_CHANGING_POLICY:
		/* Signal power events before switching the policy */
		kbase_pm_power_up_done(kbdev);
		kbase_pm_power_down_done(kbdev);
		kbase_pm_change_policy(kbdev);

		break;
	default:
		break;
	}
}
/** The event callback function for the always_on power policy.
 *
 * This function is called to handle the events for the power policy. It calls the relevant handler function depending 
 * on the type of the event.
 *
 * @param kbdev     The kbase device structure for the device
 * @param event     The event that should be processed
 */
static void always_on_event(kbase_device *kbdev, kbase_pm_event event)
{
	kbasep_pm_policy_always_on *data = &kbdev->pm.policy_data.always_on;

	switch(event)
	{
	case KBASE_PM_EVENT_SYSTEM_SUSPEND:
		always_on_suspend(kbdev);
		break;
	case KBASE_PM_EVENT_POLICY_INIT: /* Init is the same as resume for this policy */
	case KBASE_PM_EVENT_SYSTEM_RESUME:
		always_on_resume(kbdev);
		break;
	case KBASE_PM_EVENT_GPU_STATE_CHANGED:
		always_on_state_changed(kbdev);
		break;
	case KBASE_PM_EVENT_POLICY_CHANGE:
		if (data->state == KBASEP_PM_ALWAYS_ON_STATE_POWERED_UP ||
		    data->state == KBASEP_PM_ALWAYS_ON_STATE_POWERED_DOWN)
		{
			kbase_pm_change_policy(kbdev);
		}
		else
		{
			data->state = KBASEP_PM_ALWAYS_ON_STATE_CHANGING_POLICY;
		}
		break;
	case KBASE_PM_EVENT_GPU_ACTIVE:
	case KBASE_PM_EVENT_GPU_IDLE:
	case KBASE_PM_EVENT_CHANGE_GPU_STATE:
		/* Not used - the GPU is always kept on */
		break;
	default:
		/* Unrecognised event - this should never happen */
		OSK_ASSERT(0);
	}
}
/** The event callback function for the always_on power policy.
 *
 * This function is called to handle the events for the power policy. It calls the relevant handler function depending
 * on the type of the event.
 *
 * @param kbdev     The kbase device structure for the device
 * @param event     The event that should be processed
 */
static void always_on_event(kbase_device *kbdev, kbase_pm_event event)
{
	kbasep_pm_policy_always_on *data = &kbdev->pm.policy_data.always_on;

	switch (event) {
	case KBASE_PM_EVENT_SYSTEM_SUSPEND:
		always_on_suspend(kbdev);
		break;
	case KBASE_PM_EVENT_POLICY_INIT:	/* Init is the same as resume for this policy */
	case KBASE_PM_EVENT_SYSTEM_RESUME:
		always_on_resume(kbdev);
		break;
	case KBASE_PM_EVENT_GPU_STATE_CHANGED:
		always_on_state_changed(kbdev);
		break;
	case KBASE_PM_EVENT_POLICY_CHANGE:
		if (data->state == KBASEP_PM_ALWAYS_ON_STATE_POWERED_UP || data->state == KBASEP_PM_ALWAYS_ON_STATE_POWERED_DOWN)
			kbase_pm_change_policy(kbdev);
		else
			data->state = KBASEP_PM_ALWAYS_ON_STATE_CHANGING_POLICY;
		break;
	case KBASE_PM_EVENT_GPU_ACTIVE:
	case KBASE_PM_EVENT_GPU_IDLE:
		break;
	case KBASE_PM_EVENT_CHANGE_GPU_STATE:
		/*
		 * Note that the GPU is always kept on, however we still may
		 * be required to update anyone waiting for power up events.
		 */
		kbase_pm_check_transitions(kbdev);
		break;
	default:
		/* Unrecognised event - this should never happen */
		KBASE_DEBUG_ASSERT(0);
	}
}
Ejemplo n.º 6
0
/** The event callback function for the demand power policy.
 *
 * This function is called to handle the events for the power policy. It calls the relevant handler function depending 
 * on the type of the event.
 *
 * @param kbdev     The kbase device structure for the device
 * @param event     The event that should be processed
 */
static void demand_event(kbase_device *kbdev, kbase_pm_event event)
{
	kbasep_pm_policy_demand *data = &kbdev->pm.policy_data.demand;
	
	switch(event)
	{
		case KBASE_PM_EVENT_POLICY_INIT:
			demand_power_up(kbdev);
			break;
		case KBASE_PM_EVENT_POLICY_CHANGE:
			if (data->state == KBASEP_PM_DEMAND_STATE_POWERED_UP ||
			    data->state == KBASEP_PM_DEMAND_STATE_POWERED_DOWN)
			{
				kbase_pm_change_policy(kbdev);
			}
			else
			{
				data->state = KBASEP_PM_DEMAND_STATE_CHANGING_POLICY;
			}
			break;
		case KBASE_PM_EVENT_SYSTEM_RESUME:
		case KBASE_PM_EVENT_GPU_ACTIVE:
			switch (data->state)
			{
				case KBASEP_PM_DEMAND_STATE_POWERING_UP:
					break;
				case KBASEP_PM_DEMAND_STATE_POWERED_UP:
					kbase_pm_power_up_done(kbdev);
					break;
				default:	
					demand_power_up(kbdev);
			}
			break;
		case KBASE_PM_EVENT_SYSTEM_SUSPEND:
		case KBASE_PM_EVENT_GPU_IDLE:
			switch (data->state)
			{
				case KBASEP_PM_DEMAND_STATE_POWERING_DOWN:
					break;
				case KBASEP_PM_DEMAND_STATE_POWERED_DOWN:
					kbase_pm_power_down_done(kbdev);
					break;
				default:	
					demand_power_down(kbdev);
			}
			break;
		case KBASE_PM_EVENT_CHANGE_GPU_STATE:
			if (data->state != KBASEP_PM_DEMAND_STATE_POWERED_DOWN &&
			    data->state != KBASEP_PM_DEMAND_STATE_POWERING_DOWN)
			{
				demand_change_gpu_state(kbdev);
			}
			break;
		case KBASE_PM_EVENT_GPU_STATE_CHANGED:
			demand_state_changed(kbdev);
			break;
		default:
			/* unrecognized event, should never happen */
			OSK_ASSERT(0);
	}
}
/** The event callback function for the coarse_demand power policy.
 *
 * This function is called to handle the events for the power policy. It calls the relevant handler function depending
 * on the type of the event.
 *
 * @param kbdev     The kbase device structure for the device
 * @param event     The event that should be processed
 */
static void coarse_demand_event(kbase_device *kbdev, kbase_pm_event event)
{
	kbasep_pm_policy_coarse_demand *data = &kbdev->pm.policy_data.coarse_demand;

	switch(event)
	{
	case KBASE_PM_EVENT_POLICY_INIT:
		coarse_demand_power_up(kbdev);
		break;
	case KBASE_PM_EVENT_SYSTEM_SUSPEND:
		switch (data->state)
		{
			case KBASEP_PM_COARSE_DEMAND_STATE_POWERING_DOWN:
				break;
			case KBASEP_PM_COARSE_DEMAND_STATE_POWERED_DOWN:
				kbase_pm_power_down_done(kbdev);
				break;
			default:
				coarse_demand_suspend(kbdev);
		}
		break;
	case KBASE_PM_EVENT_GPU_IDLE:
		switch (data->state)
		{
			case KBASEP_PM_COARSE_DEMAND_STATE_POWERING_DOWN:
				break;
			case KBASEP_PM_COARSE_DEMAND_STATE_POWERED_DOWN:
				kbase_pm_power_down_done(kbdev);
				break;
			default:
				coarse_demand_power_down(kbdev);
		}
		break;
	case KBASE_PM_EVENT_GPU_ACTIVE:
	case KBASE_PM_EVENT_SYSTEM_RESUME:
		switch (data->state)
		{
			case KBASEP_PM_COARSE_DEMAND_STATE_POWERING_UP:
				break;
			case KBASEP_PM_COARSE_DEMAND_STATE_POWERED_UP:
				kbase_pm_power_up_done(kbdev);
				break;
			default:
				coarse_demand_power_up(kbdev);
		}
		break;
	case KBASE_PM_EVENT_GPU_STATE_CHANGED:
		coarse_demand_state_changed(kbdev);
		break;
	case KBASE_PM_EVENT_POLICY_CHANGE:
		if (data->state == KBASEP_PM_COARSE_DEMAND_STATE_POWERED_UP ||
		    data->state == KBASEP_PM_COARSE_DEMAND_STATE_POWERED_DOWN)
		{
			kbase_pm_change_policy(kbdev);
		}
		else
		{
			data->state = KBASEP_PM_COARSE_DEMAND_STATE_CHANGING_POLICY;
		}
		break;
	case KBASE_PM_EVENT_CHANGE_GPU_STATE:
		if (data->state != KBASEP_PM_COARSE_DEMAND_STATE_POWERED_DOWN &&
			data->state != KBASEP_PM_COARSE_DEMAND_STATE_POWERING_DOWN)
		{
			/*
			 * Update anyone waiting for power up events.
			 */
			kbase_pm_check_transitions(kbdev);
		}
		break;
	default:
		/* Unrecognised event - this should never happen */
		OSK_ASSERT(0);
	}
}