Пример #1
0
/*******************************************************************************
 * RockChip handler called when a power domain is about to be suspended. The
 * target_state encodes the power state that each level should transition to.
 ******************************************************************************/
void rockchip_pwr_domain_suspend(const psci_power_state_t *target_state)
{
	uint32_t lvl;
	plat_local_state_t lvl_state;
	int ret;

	if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
		return;

	if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
		rockchip_soc_sys_pwr_dm_suspend();
	else
		rockchip_soc_cores_pwr_dm_suspend();

	/* Prevent interrupts from spuriously waking up this cpu */
	plat_rockchip_gic_cpuif_disable();

	/* Perform the common cluster specific operations */
	if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
		plat_cci_disable();

	if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
		return;

	for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
		lvl_state = target_state->pwr_domain_state[lvl];
		ret = rockchip_soc_hlvl_pwr_dm_suspend(lvl, lvl_state);
		if (ret == PSCI_E_NOT_SUPPORTED)
			break;
	}
}
Пример #2
0
/*******************************************************************************
 * RockChip handler called when a power domain has just been powered on after
 * being turned off earlier. The target_state encodes the low power state that
 * each level has woken up from.
 ******************************************************************************/
void rockchip_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
	uint32_t lvl;
	plat_local_state_t lvl_state;
	int ret;

	assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);

	for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
		lvl_state = target_state->pwr_domain_state[lvl];
		ret = rockchip_soc_hlvl_pwr_dm_on_finish(lvl, lvl_state);
		if (ret == PSCI_E_NOT_SUPPORTED)
			break;
	}

	rockchip_soc_cores_pwr_dm_on_finish();

	/* Perform the common cluster specific operations */
	if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
		/* Enable coherency if this cluster was off */
		plat_cci_enable();
	}

	/* Enable the gic cpu interface */
	plat_rockchip_gic_pcpu_init();

	/* Program the gic per-cpu distributor or re-distributor interface */
	plat_rockchip_gic_cpuif_enable();
}
Пример #3
0
/*******************************************************************************
 * RockChip handler called when a power domain is about to be suspended. The
 * target_state encodes the power state that each level should transition to.
 ******************************************************************************/
void rockchip_pwr_domain_suspend(const psci_power_state_t *target_state)
{
    uint32_t lvl;
    plat_local_state_t lvl_state;

    if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
        return;

    if (rockchip_ops) {
        if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE &&
                rockchip_ops->sys_pwr_dm_suspend) {
            rockchip_ops->sys_pwr_dm_suspend();
        } else if (rockchip_ops->cores_pwr_dm_suspend) {
            rockchip_ops->cores_pwr_dm_suspend();
        }
    }

    /* Prevent interrupts from spuriously waking up this cpu */
    plat_rockchip_gic_cpuif_disable();

    /* Perform the common cluster specific operations */
    if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
        plat_cci_disable();

    if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
        return;

    if (!rockchip_ops || !rockchip_ops->hlvl_pwr_dm_suspend)
        return;

    for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
        lvl_state = target_state->pwr_domain_state[lvl];
        rockchip_ops->hlvl_pwr_dm_suspend(lvl, lvl_state);
    }
}
Пример #4
0
/*******************************************************************************
 * RockChip handler called when a power domain is about to be turned off. The
 * target_state encodes the power state that each level should transition to.
 ******************************************************************************/
void rockchip_pwr_domain_off(const psci_power_state_t *target_state)
{
    uint32_t lvl;
    plat_local_state_t lvl_state;

    assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);

    plat_rockchip_gic_cpuif_disable();

    if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
        plat_cci_disable();

    if (!rockchip_ops || !rockchip_ops->cores_pwr_dm_off)
        return;

    rockchip_ops->cores_pwr_dm_off();

    if (!rockchip_ops->hlvl_pwr_dm_off)
        return;

    for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
        lvl_state = target_state->pwr_domain_state[lvl];
        rockchip_ops->hlvl_pwr_dm_off(lvl, lvl_state);
    }
}
Пример #5
0
static void
__dead2 rockchip_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
{
    if ((RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) &&
            (rockchip_ops)) {
        if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE &&
                rockchip_ops->sys_pwr_down_wfi)
            rockchip_ops->sys_pwr_down_wfi(target_state);
    }
    psci_power_down_wfi();
}
Пример #6
0
/*******************************************************************************
 * RockChip handler called when a power domain has just been powered on after
 * having been suspended earlier. The target_state encodes the low power state
 * that each level has woken up from.
 * TODO: At the moment we reuse the on finisher and reinitialize the secure
 * context. Need to implement a separate suspend finisher.
 ******************************************************************************/
void rockchip_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
{
    uint32_t lvl;
    plat_local_state_t lvl_state;

    /* Nothing to be done on waking up from retention from CPU level */
    if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
        return;

    /* Perform system domain restore if woken up from system suspend */
    if (!rockchip_ops)
        goto comm_finish;

    if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
        if (rockchip_ops->sys_pwr_dm_resume)
            rockchip_ops->sys_pwr_dm_resume();
        goto comm_finish;
    }

    if (rockchip_ops->hlvl_pwr_dm_resume) {
        for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
            lvl_state = target_state->pwr_domain_state[lvl];
            rockchip_ops->hlvl_pwr_dm_resume(lvl, lvl_state);
        }
    }

    if (rockchip_ops->cores_pwr_dm_resume)
        rockchip_ops->cores_pwr_dm_resume();
    /*
     * Program the gic per-cpu distributor or re-distributor interface.
     * For sys power domain operation, resuming of the gic needs to operate
     * in rockchip_ops->sys_pwr_dm_resume, according to the sys power mode
     * implements.
     */
    plat_rockchip_gic_cpuif_enable();

comm_finish:
    /* Perform the common cluster specific operations */
    if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
        /* Enable coherency if this cluster was off */
        plat_cci_enable();
    }
}
Пример #7
0
/*******************************************************************************
 * RockChip handler called when a power domain is about to be turned off. The
 * target_state encodes the power state that each level should transition to.
 ******************************************************************************/
void rockchip_pwr_domain_off(const psci_power_state_t *target_state)
{
	uint32_t lvl;
	plat_local_state_t lvl_state;
	int ret;

	assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);

	plat_rockchip_gic_cpuif_disable();

	if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
		plat_cci_disable();

	rockchip_soc_cores_pwr_dm_off();

	for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
		lvl_state = target_state->pwr_domain_state[lvl];
		ret = rockchip_soc_hlvl_pwr_dm_off(lvl, lvl_state);
		if (ret == PSCI_E_NOT_SUPPORTED)
			break;
	}
}