Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2eb82145 authored by Archana Sathyakumar's avatar Archana Sathyakumar
Browse files

lpm_levels: Select mode based on steady state power for hotplug



Currently we choose power collapse or standalone power collapse
as default mode for hotplug. Instead select deepest mode based
on the least steady state power.

If lpm isn't probed yet, then check for mode availability for
this spm device and select this mode for cpu hotplug.

Change-Id: Ia54994ae4ed65af20318fdbe68095ac7177ad759
Signed-off-by: default avatarArchana Sathyakumar <asathyak@codeaurora.org>
parent 1fb7ca1e
Loading
Loading
Loading
Loading
+29 −15
Original line number Diff line number Diff line
@@ -1030,27 +1030,41 @@ void lpm_cpu_hotplug_enter(unsigned int cpu)
	int i;
	int idx = -1;

	if (lpm_cpu_mode_allow(cpu, MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
				false))
	/*
	 * If lpm isn't probed yet, try to put cpu into the one of the modes
	 * available
	 */
	if (!cluster) {
		if (msm_spm_is_mode_avail(MSM_SPM_MODE_POWER_COLLAPSE)) {
			mode = MSM_PM_SLEEP_MODE_POWER_COLLAPSE;
	else if (lpm_cpu_mode_allow(cpu,
			MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE, false))
		mode = MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE;
	else
		__WARN_printf("Power collapse modes not enabled for hotpug\n");

	if (mode == MSM_PM_SLEEP_MODE_NR)
		} else if (msm_spm_is_mode_avail(
				MSM_SPM_MODE_RETENTION)) {
			mode = MSM_PM_SLEEP_MODE_RETENTION;
		} else {
			pr_err("No mode avail for cpu%d hotplug\n", cpu);
			BUG_ON(1);
			return;
		}
	} else {
		struct lpm_cpu *lpm_cpu;
		uint32_t ss_pwr = ~0U;

	if (cluster) {
		for (i = cluster->cpu->nlevels - 1; i > -1; i--)
			if ((idx < 0) && cluster->cpu->levels[i].mode == mode)
		lpm_cpu = cluster->cpu;
		for (i = 0; i < lpm_cpu->nlevels; i++) {
			if (ss_pwr < lpm_cpu->levels[i].pwr.ss_power)
				continue;
			ss_pwr = lpm_cpu->levels[i].pwr.ss_power;
			idx = i;
			mode = lpm_cpu->levels[i].mode;
		}

		BUG_ON(idx < 0);
		if (mode == MSM_PM_SLEEP_MODE_NR)
			return;

		BUG_ON(idx < 0);
		cluster_prepare(cluster, get_cpu_mask(cpu), idx, false);
	}

	msm_cpu_pm_enter_sleep(mode, false);
}

+18 −0
Original line number Diff line number Diff line
@@ -297,6 +297,24 @@ void msm_spm_reinit(void)
}
EXPORT_SYMBOL(msm_spm_reinit);

/*
 * msm_spm_is_mode_avail() - Specifies if a mode is available for the cpu
 * It should only be used to decide a mode before lpm driver is probed.
 * @mode: SPM LPM mode to be selected
 */
bool msm_spm_is_mode_avail(unsigned int mode)
{
	struct msm_spm_device *dev = &__get_cpu_var(msm_cpu_spm_device);
	int i;

	for (i = 0; i < dev->num_modes; i++) {
		if (dev->modes[i].mode == mode)
			return true;
	}

	return false;
}

/**
 * msm_spm_set_low_power_mode() - Configure SPM start address for low power mode
 * @mode: SPM LPM mode to enter
+6 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct msm_spm_device *msm_spm_get_device_by_name(const char *name);
int msm_spm_config_low_power_mode(struct msm_spm_device *dev,
		unsigned int mode, bool notify_rpm);
int msm_spm_device_init(void);
bool msm_spm_is_mode_avail(unsigned int mode);

#if defined(CONFIG_MSM_L2_SPM)

@@ -96,5 +97,10 @@ struct msm_spm_device *msm_spm_get_device_by_name(const char *name)
	return NULL;
}

bool msm_spm_is_mode_avail(unsigned int mode)
{
	return false;
}

#endif  /* defined (CONFIG_MSM_SPM_V2) */
#endif  /* __ARCH_ARM_MACH_MSM_SPM_H */