firmware: psci: setup OSI mode at init

Let's switch to OSI mode for QCOM platforms if setting the OSI mode is
supported. We should do this only if the lpm-levels driver is used.
Other VMs using the same kernel but defaulting to ARM cpuidle drivers,
will default to platform coordinated.

Change-Id: I69245bf33361970f37ea2006d669368e30e2ec9d
Signed-off-by: Lina Iyer <ilina@codeaurora.org>
This commit is contained in:
Lina Iyer 2019-10-10 12:01:48 +02:00
parent bd0cb90137
commit fe547ce1b4
3 changed files with 33 additions and 0 deletions

View File

@ -92,6 +92,7 @@ config ARM_QCOM_LPM_CPUIDLE
select CPU_IDLE_MULTIPLE_DRIVERS select CPU_IDLE_MULTIPLE_DRIVERS
select MSM_PM select MSM_PM
select QGKI_LPM_IPI_CHECK if QGKI select QGKI_LPM_IPI_CHECK if QGKI
select QGKI_PSCI_OSI_SUPPORT if QGKI
tristate "Qualcomm Technologies, Inc. (QTI) Power Management Drivers" tristate "Qualcomm Technologies, Inc. (QTI) Power Management Drivers"
help help
Platform specific power driver to manage cores and cluster low power Platform specific power driver to manage cores and cluster low power

View File

@ -12,3 +12,6 @@ config ARM_PSCI_CHECKER
The torture tests may interfere with the PSCI checker by turning CPUs The torture tests may interfere with the PSCI checker by turning CPUs
on and off through hotplug, so for now torture tests and PSCI checker on and off through hotplug, so for now torture tests and PSCI checker
are mutually exclusive. are mutually exclusive.
config QGKI_PSCI_OSI_SUPPORT
bool "Set PSCI OSI mode"

View File

@ -536,6 +536,27 @@ static int __init psci_0_1_init(struct device_node *np)
return 0; return 0;
} }
#ifdef CONFIG_QGKI_PSCI_OSI_SUPPORT
static int psci_set_osi_mode(void)
{
int err;
/*
* If SET_SUSPEND_MODE is not supported,
* assume HYP/firmware are defaulting to OSI
*/
err = psci_features(PSCI_1_0_FN_SET_SUSPEND_MODE);
if (err == PSCI_RET_NOT_SUPPORTED) {
pr_info("Assuming FW runs OSI.\n");
return 0;
}
err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE,
PSCI_1_0_SUSPEND_MODE_OSI, 0, 0);
return psci_to_linux_errno(err);
}
#endif /* CONFIG_QGKI_PSCI_OSI_SUPPORT */
static int __init psci_1_0_init(struct device_node *np) static int __init psci_1_0_init(struct device_node *np)
{ {
int err; int err;
@ -544,8 +565,16 @@ static int __init psci_1_0_init(struct device_node *np)
if (err) if (err)
return err; return err;
#ifdef CONFIG_QGKI_PSCI_OSI_SUPPORT
if (psci_has_osi_support()) {
pr_info("OSI mode supported.\n");
if (!psci_set_osi_mode())
pr_info("Switched to OSI mode.\n");
}
#else
if (psci_has_osi_support()) if (psci_has_osi_support())
pr_info("OSI mode supported.\n"); pr_info("OSI mode supported.\n");
#endif /* CONFIG_QGKI_PSCI_OSI_SUPPORT */
return 0; return 0;
} }