Esempio n. 1
0
static int tegra114_idle_power_down(struct cpuidle_device *dev,
				    struct cpuidle_driver *drv,
				    int index)
{
	local_fiq_disable();

	tegra_set_cpu_in_lp2();
	cpu_pm_enter();

	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);

	call_firmware_op(prepare_idle);

	/* Do suspend by ourselves if the firmware does not implement it */
	if (call_firmware_op(do_idle) == -ENOSYS)
		cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);

	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);

	cpu_pm_exit();
	tegra_clear_cpu_in_lp2();

	local_fiq_enable();

	return index;
}
Esempio n. 2
0
static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
{
	int i;

	if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
		scu_enable(scu_base_addr());

	/*
	 * Write the address of secondary startup into the
	 * system-wide flags register. The boot monitor waits
	 * until it receives a soft interrupt, and then the
	 * secondary CPU branches to this address.
	 *
	 * Try using firmware operation first and fall back to
	 * boot register if it fails.
	 */
	for (i = 1; i < max_cpus; ++i) {
		unsigned long phys_cpu;
		unsigned long boot_addr;

		phys_cpu = cpu_logical_map(i);
		boot_addr = virt_to_phys(exynos4_secondary_startup);

		if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
			__raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
	}
}
Esempio n. 3
0
void show_pm_secure_mem_status(void)
{
	int i = 1;
	int val = 0;
	
#ifndef CONFIG_SUNXI_TRUSTZONE
	while(i < STANDBY_STATUS_REG_NUM) {
		pm_secure_status_reg_tmp.bits.reg_sel = i;
		if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.dwval = (*pm_secure_status_reg).dwval;
			hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
		}
		val = pm_secure_status_reg_tmp.bits.data_rd;
		printk("addr %x, value = %x. \n", (i), val);
		i++;
	}
#else
	while(i < STANDBY_STATUS_REG_NUM){
		val = call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_GET, (u32)pm_secure_status_reg, i);
		printk("addr %x, value = %x. \n", (i), val);
		i++;
	}
#endif

}
Esempio n. 4
0
File: suspend.c Progetto: 3bsa/linux
static void exynos_pm_resume(void)
{
	u32 cpuid = read_cpuid_part();

	if (exynos_pm_central_resume())
		goto early_wakeup;

	/* For release retention */
	exynos_pm_release_retention();

	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));

	if (cpuid == ARM_CPU_PART_CORTEX_A9)
		scu_enable(S5P_VA_SCU);

	if (call_firmware_op(resume) == -ENOSYS
	    && cpuid == ARM_CPU_PART_CORTEX_A9)
		exynos_cpu_restore_register();

early_wakeup:

	/* Clear SLEEP mode set in INFORM1 */
	pmu_raw_writel(0x0, S5P_INFORM1);
	exynos_set_delayed_reset_assertion(true);
}
Esempio n. 5
0
static void __init tegra_cpu_reset_handler_enable(void)
{
	void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
	const u32 reset_address = TEGRA_IRAM_RESET_BASE +
						tegra_cpu_reset_handler_offset;
	int err;

	BUG_ON(is_enabled);
	BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);

	memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
			tegra_cpu_reset_handler_size);

	err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
	switch (err) {
	case -ENOSYS:
		tegra_cpu_reset_handler_set(reset_address);
		/* pass-through */
	case 0:
		is_enabled = true;
		break;
	default:
		pr_crit("Cannot set CPU reset handler: %d\n", err);
		BUG();
	}
}
Esempio n. 6
0
void sun8i_set_secondary_entry(void *entry)
{
	if (sunxi_soc_is_secure()) {
		call_firmware_op(set_secondary_entry, entry);
	} else {
		sunxi_set_secondary_entry(entry);
	}
}
Esempio n. 7
0
static int tegra114_idle_power_down(struct cpuidle_device *dev,
				    struct cpuidle_driver *drv,
				    int index)
{
	local_fiq_disable();

	tegra_set_cpu_in_lp2();
	cpu_pm_enter();

	call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);

	/* Do suspend by ourselves if the firmware does not implement it */
	if (call_firmware_op(do_idle, 0) == -ENOSYS)
		cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);

	cpu_pm_exit();
	tegra_clear_cpu_in_lp2();

	local_fiq_enable();

	return index;
}
Esempio n. 8
0
__u32 get_pm_secure_mem_status(void)
{
	int val = 0;

#ifndef CONFIG_SUNXI_TRUSTZONE
	pm_secure_status_reg_tmp.bits.reg_sel = 1;
	if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
		(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
		pm_secure_status_reg_tmp.dwval = (*pm_secure_status_reg).dwval;
		hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
	}

	val = pm_secure_status_reg_tmp.bits.data_rd;
	return (val);
#else
	val = call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_GET, (u32)pm_secure_status_reg, 1);
	return (val);
#endif
}
Esempio n. 9
0
File: suspend.c Progetto: 3bsa/linux
static int exynos_suspend_enter(suspend_state_t state)
{
	int ret;

	s3c_pm_debug_init();

	S3C_PMDBG("%s: suspending the system...\n", __func__);

	S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
			exynos_irqwake_intmask, exynos_get_eint_wake_mask());

	if (exynos_irqwake_intmask == -1U
	    && exynos_get_eint_wake_mask() == -1U) {
		pr_err("%s: No wake-up sources!\n", __func__);
		pr_err("%s: Aborting sleep\n", __func__);
		return -EINVAL;
	}

	s3c_pm_save_uarts();
	if (pm_data->pm_prepare)
		pm_data->pm_prepare();
	flush_cache_all();
	s3c_pm_check_store();

	ret = call_firmware_op(suspend);
	if (ret == -ENOSYS)
		ret = cpu_suspend(0, pm_data->cpu_suspend);
	if (ret)
		return ret;

	if (pm_data->pm_resume_prepare)
		pm_data->pm_resume_prepare();
	s3c_pm_restore_uarts();

	S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
			pmu_raw_readl(S5P_WAKEUP_STAT));

	s3c_pm_check_restore();

	S3C_PMDBG("%s: resuming the system...\n", __func__);

	return 0;
}
Esempio n. 10
0
File: suspend.c Progetto: 3bsa/linux
static void exynos3250_pm_resume(void)
{
	u32 cpuid = read_cpuid_part();

	if (exynos_pm_central_resume())
		goto early_wakeup;

	/* For release retention */
	exynos_pm_release_retention();

	pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);

	if (call_firmware_op(resume) == -ENOSYS
	    && cpuid == ARM_CPU_PART_CORTEX_A9)
		exynos_cpu_restore_register();

early_wakeup:

	/* Clear SLEEP mode set in INFORM1 */
	pmu_raw_writel(0x0, S5P_INFORM1);
}
Esempio n. 11
0
static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
{
	int i;

	exynos_sysram_init();

	if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
		scu_enable(scu_base_addr());

	/*
	 * Write the address of secondary startup into the
	 * system-wide flags register. The boot monitor waits
	 * until it receives a soft interrupt, and then the
	 * secondary CPU branches to this address.
	 *
	 * Try using firmware operation first and fall back to
	 * boot register if it fails.
	 */
	for (i = 1; i < max_cpus; ++i) {
		unsigned long boot_addr;
		u32 mpidr;
		u32 core_id;
		int ret;

		mpidr = cpu_logical_map(i);
		core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
		boot_addr = virt_to_phys(exynos4_secondary_startup);

		ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
		if (ret && ret != -ENOSYS)
			break;
		if (ret == -ENOSYS) {
			void __iomem *boot_reg = cpu_boot_reg(core_id);

			if (IS_ERR(boot_reg))
				break;
			__raw_writel(boot_addr, cpu_boot_reg(core_id));
		}
	}
}
Esempio n. 12
0
void save_pm_secure_mem_status_nommu(volatile __u32 val)
{
#ifndef CONFIG_SUNXI_TRUSTZONE
	if (!hwspin_lock_timeout_nommu(MEM_RTC_REG_HWSPINLOCK, 20000)) {
		pm_secure_status_reg_pa_tmp.bits.reg_sel = 1;
		pm_secure_status_reg_pa_tmp.bits.data_wr = val;
		(*pm_secure_status_reg_pa).dwval = pm_secure_status_reg_pa_tmp.dwval;
		pm_secure_status_reg_pa_tmp.bits.wr_pulse = 0;
		(*pm_secure_status_reg_pa).dwval = pm_secure_status_reg_pa_tmp.dwval;
		pm_secure_status_reg_pa_tmp.bits.wr_pulse = 1;
		(*pm_secure_status_reg_pa).dwval = pm_secure_status_reg_pa_tmp.dwval;
		pm_secure_status_reg_pa_tmp.bits.wr_pulse = 0;
		(*pm_secure_status_reg_pa).dwval = pm_secure_status_reg_pa_tmp.dwval;
		hwspin_unlock_nommu(MEM_RTC_REG_HWSPINLOCK);
	}

	return;
#else
	call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_SET,  (u32)pm_secure_status_reg_pa, val);
#endif

}
Esempio n. 13
0
void pm_secure_mem_status_clear(void)
{
#ifndef CONFIG_SUNXI_TRUSTZONE
	int i = 1;
	pm_secure_status_reg_tmp.dwval = (*pm_secure_status_reg).dwval;
	if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
		while(i < STANDBY_STATUS_REG_NUM){
			pm_secure_status_reg_tmp.bits.reg_sel = i;
			pm_secure_status_reg_tmp.bits.data_wr = 0;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.bits.wr_pulse = 0;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.bits.wr_pulse = 1;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.bits.wr_pulse = 0;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			i++;
	    	}
		hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
	}
#else
	call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_CLEAR, (u32)pm_secure_status_reg, 0);
#endif
}
Esempio n. 14
0
static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	unsigned long timeout;
	unsigned long phys_cpu = cpu_logical_map(cpu);

	/*
	 * Set synchronisation state between this boot processor
	 * and the secondary one
	 */
	spin_lock(&boot_lock);

	/*
	 * The secondary processor is waiting to be released from
	 * the holding pen - release it, then wait for it to flag
	 * that it has been released by resetting pen_release.
	 *
	 * Note that "pen_release" is the hardware CPU ID, whereas
	 * "cpu" is Linux's internal ID.
	 */
	write_pen_release(phys_cpu);

	if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
		__raw_writel(S5P_CORE_LOCAL_PWR_EN,
			     S5P_ARM_CORE1_CONFIGURATION);

		timeout = 10;

		/* wait max 10 ms until cpu1 is on */
		while ((__raw_readl(S5P_ARM_CORE1_STATUS)
			& S5P_CORE_LOCAL_PWR_EN) != S5P_CORE_LOCAL_PWR_EN) {
			if (timeout-- == 0)
				break;

			mdelay(1);
		}

		if (timeout == 0) {
			printk(KERN_ERR "cpu1 power enable failed");
			spin_unlock(&boot_lock);
			return -ETIMEDOUT;
		}
	}
	/*
	 * Send the secondary CPU a soft interrupt, thereby causing
	 * the boot monitor to read the system wide flags register,
	 * and branch to the address found there.
	 */

	timeout = jiffies + (1 * HZ);
	while (time_before(jiffies, timeout)) {
		unsigned long boot_addr;

		smp_rmb();

		boot_addr = virt_to_phys(exynos4_secondary_startup);

		/*
		 * Try to set boot address using firmware first
		 * and fall back to boot register if it fails.
		 */
		if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
			__raw_writel(boot_addr, cpu_boot_reg(phys_cpu));

		call_firmware_op(cpu_boot, phys_cpu);

		arch_send_wakeup_ipi_mask(cpumask_of(cpu));

		if (pen_release == -1)
			break;

		udelay(10);
	}

	/*
	 * now the secondary core is starting up let it run its
	 * calibrations, then wait for it to finish
	 */
	spin_unlock(&boot_lock);

	return pen_release != -1 ? -ENOSYS : 0;
}
Esempio n. 15
0
static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	unsigned long timeout;
	u32 mpidr = cpu_logical_map(cpu);
	u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
	int ret = -ENOSYS;

	/*
	 * Set synchronisation state between this boot processor
	 * and the secondary one
	 */
	spin_lock(&boot_lock);

	/*
	 * The secondary processor is waiting to be released from
	 * the holding pen - release it, then wait for it to flag
	 * that it has been released by resetting pen_release.
	 *
	 * Note that "pen_release" is the hardware CPU core ID, whereas
	 * "cpu" is Linux's internal ID.
	 */
	write_pen_release(core_id);

	if (!soc_is_exynos5440() && !exynos_cpu_power_state(core_id)) {
		exynos_cpu_power_up(core_id);
		timeout = 10;

		/* wait max 10 ms until cpu1 is on */
		while (exynos_cpu_power_state(core_id)
		       != S5P_CORE_LOCAL_PWR_EN) {
			if (timeout-- == 0)
				break;

			mdelay(1);
		}

		if (timeout == 0) {
			printk(KERN_ERR "cpu1 power enable failed");
			spin_unlock(&boot_lock);
			return -ETIMEDOUT;
		}
	}
	/*
	 * Send the secondary CPU a soft interrupt, thereby causing
	 * the boot monitor to read the system wide flags register,
	 * and branch to the address found there.
	 */

	timeout = jiffies + (1 * HZ);
	while (time_before(jiffies, timeout)) {
		unsigned long boot_addr;

		smp_rmb();

		boot_addr = virt_to_phys(exynos4_secondary_startup);

		/*
		 * Try to set boot address using firmware first
		 * and fall back to boot register if it fails.
		 */
		ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
		if (ret && ret != -ENOSYS)
			goto fail;
		if (ret == -ENOSYS) {
			void __iomem *boot_reg = cpu_boot_reg(core_id);

			if (IS_ERR(boot_reg)) {
				ret = PTR_ERR(boot_reg);
				goto fail;
			}
			__raw_writel(boot_addr, cpu_boot_reg(core_id));
		}

		call_firmware_op(cpu_boot, core_id);

		arch_send_wakeup_ipi_mask(cpumask_of(cpu));

		if (pen_release == -1)
			break;

		udelay(10);
	}

	/*
	 * now the secondary core is starting up let it run its
	 * calibrations, then wait for it to finish
	 */
fail:
	spin_unlock(&boot_lock);

	return pen_release != -1 ? ret : 0;
}