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

Commit 3b6de348 authored by Archana Sathyakumar's avatar Archana Sathyakumar Committed by Mahesh Sivasubramanian
Browse files

lpm: Allow cpu to enter FPC from hypervisor



FPC using PSCI is entered from PSCI layer that is in Secure EL1.
Switching of EL layers incur additional latency, making FPC slower.
Issue wfi within hypervisor for cpu only sleep. This makes FPC much
faster than entering from PSCI layer.

Change-Id: Icf4c5f2484fdda79c991b842cb3a3185b638bfdb
Signed-off-by: default avatarArchana Sathyakumar <asathyak@codeaurora.org>
parent 8afacbe7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -90,6 +90,8 @@ Required properties:
	- qcom,is-reset: This boolean property will tell whether
	cluster level need power management notifications to be sent out
	or not for the drivers to prepare for cluster collapse.
	- qcom,hyp-psci: This property is used to determine if the cpu
        enters the low power mode within hypervisor.

[Node bindings for qcom,pm-cpu]
qcom,pm-cpu contains the low power modes that a cpu could enter. Currently it
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -563,6 +563,9 @@ static int parse_cpu_mode(struct device_node *n, struct lpm_cpu_level *l)
					n->name);
			return ret;
		}
		key = "qcom,hyp-psci";

		l->hyp_psci = of_property_read_bool(n, key);
	} else {
		l->mode = parse_cpu_spm_mode(l->name);

+9 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -796,6 +796,7 @@ unlock_and_return:
}

#if !defined(CONFIG_CPU_V7)
asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64);
bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle)
{
	/*
@@ -813,6 +814,13 @@ bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle)
			PSCI_POWER_STATE(cluster->cpu->levels[idx].is_reset);
		bool success = false;

		if (cluster->cpu->levels[idx].hyp_psci) {
			stop_critical_timings();
			__invoke_psci_fn_smc(0xC4000021, 0, 0, 0);
			start_critical_timings();
			return 1;
		}

		affinity_level = PSCI_AFFINITY_LEVEL(affinity_level);
		state_id |= (power_state | affinity_level
			| cluster->cpu->levels[idx].psci_id);
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014, 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -37,6 +37,7 @@ struct lpm_cpu_level {
	unsigned int psci_id;
	bool is_reset;
	bool jtag_save_restore;
	bool hyp_psci;
};

struct lpm_cpu {