plat/marvell/a8k/common/plat_pm.c
/*
 * Power up CPU - part of Linux boot stage
 */
Power up CPU - part of Linux boot stage
Power up CPU - part of Linux boot stage
static int plat_marvell_cpu_powerup(u_register_t mpidr)
{
	uint32_t	reg_val;
	int	cpu_id = MPIDR_CPU_GET(mpidr), cluster = MPIDR_CLUSTER_GET(mpidr);
	int	exit_loop = REG_WR_VALIDATE_TIMEOUT;
	cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id;
	INFO("Powering on CPU%d\n", cpu_id);
	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
	reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET;
	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
	udelay(100);
	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
	reg_val |= 0x1 << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET;
	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
	do {
		reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
		exit_loop--;
	} while (!(reg_val & (0x1 << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)) && exit_loop > 0);
	if (exit_loop <= 0)
		goto cpu_poweron_error;
	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
	reg_val &= ~PWRC_CPUN_CR_ISO_ENABLE_MASK;
	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
	exit_loop = REG_WR_VALIDATE_TIMEOUT;
	do {
		reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
		exit_loop--;
	} while ((reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) && exit_loop > 0);
	reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
	reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET;
	mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val);
	exit_loop = REG_WR_VALIDATE_TIMEOUT;
	do {
		reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
		exit_loop--;
	} while (!(reg_val & (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)) && exit_loop > 0);
	if (exit_loop <= 0)
		goto cpu_poweron_error;
	INFO("Successfully powered on CPU%d\n", cpu_id);
	return 0;
cpu_poweron_error:
	ERROR("ERROR: Can't power up CPU%d\n" , cpu_id);
	return -1;
}
static int plat_marvell_cpu_powerup ( u_register_t mpidr ) { uint32_t reg_val ; int cpu_id = MPIDR_CPU_GET ( mpidr ) , cluster = MPIDR_CLUSTER_GET ( mpidr ) ; int exit_loop = REG_WR_VALIDATE_TIMEOUT ; cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id ; INFO ( " \n " , cpu_id ) ; reg_val = mmio_read_32 ( PWRC_CPUN_CR_REG ( cpu_id ) ) ; reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET ; mmio_write_32 ( PWRC_CPUN_CR_REG ( cpu_id ) , reg_val ) ; udelay ( 100 ) ; reg_val = mmio_read_32 ( PWRC_CPUN_CR_REG ( cpu_id ) ) ; reg_val |= 0x1 << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET ; mmio_write_32 ( PWRC_CPUN_CR_REG ( cpu_id ) , reg_val ) ; do { reg_val = mmio_read_32 ( PWRC_CPUN_CR_REG ( cpu_id ) ) ; exit_loop -- ; } while ( ! ( reg_val & ( 0x1 << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET ) ) && exit_loop > 0 ) ; if ( exit_loop <= 0 ) goto cpu_poweron_error ; reg_val = mmio_read_32 ( PWRC_CPUN_CR_REG ( cpu_id ) ) ; reg_val &= ~ PWRC_CPUN_CR_ISO_ENABLE_MASK ; mmio_write_32 ( PWRC_CPUN_CR_REG ( cpu_id ) , reg_val ) ; exit_loop = REG_WR_VALIDATE_TIMEOUT ; do { reg_val = mmio_read_32 ( PWRC_CPUN_CR_REG ( cpu_id ) ) ; exit_loop -- ; } while ( ( reg_val & ( 0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET ) ) && exit_loop > 0 ) ; reg_val = mmio_read_32 ( CCU_B_PRCRN_REG ( cpu_id ) ) ; reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET ; mmio_write_32 ( CCU_B_PRCRN_REG ( cpu_id ) , reg_val ) ; exit_loop = REG_WR_VALIDATE_TIMEOUT ; do { reg_val = mmio_read_32 ( CCU_B_PRCRN_REG ( cpu_id ) ) ; exit_loop -- ; } while ( ! ( reg_val & ( 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET ) ) && exit_loop > 0 ) ; if ( exit_loop <= 0 ) goto cpu_poweron_error ; INFO ( " \n " , cpu_id ) ; return 0 ; cpu_poweron_error : ERROR ( " \n " , cpu_id ) ; return -1 ; }
Power up CPU - part of Linux boot stage
Power up CPU - part of Linux boot stage
/* calculate absolute CPU ID */ /* 1. Switch CPU power ON */ /* 2. Wait for CPU on, up to 100 uSec: */ /* 3. Assert power ready */ /* 4. Read & Validate power ready - used in order to generate 16 Host CPU cycles */ /* 5. Isolation disable */ /* 6. Read and check Isolation enabled - verify bit set to 1 */ /* 7. De Assert CPU POR reset & Core reset */ /* 8. Read & Validate CPU POR reset */