mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
ARM: exynos: Add CPU state management for Exynos542x under secure firmware
Add required CPU state management done via secure monitor call for Exynos542x running unsed Secure Firmware. Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> [mszyprow: rewrote code to use defines and sysram base address instead of the magic numbers, added second smc call in pm_resume, rephrased subject and commit message] Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
This commit is contained in:
parent
47efaf6ba6
commit
3a1f2f38fb
@ -91,6 +91,7 @@ extern u32 cp15_save_power;
|
|||||||
|
|
||||||
extern void __iomem *sysram_ns_base_addr;
|
extern void __iomem *sysram_ns_base_addr;
|
||||||
extern void __iomem *sysram_base_addr;
|
extern void __iomem *sysram_base_addr;
|
||||||
|
extern phys_addr_t sysram_base_phys;
|
||||||
extern void __iomem *pmu_base_addr;
|
extern void __iomem *pmu_base_addr;
|
||||||
void exynos_sysram_init(void);
|
void exynos_sysram_init(void);
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ static struct platform_device exynos_cpuidle = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void __iomem *sysram_base_addr __ro_after_init;
|
void __iomem *sysram_base_addr __ro_after_init;
|
||||||
|
phys_addr_t sysram_base_phys __ro_after_init;
|
||||||
void __iomem *sysram_ns_base_addr __ro_after_init;
|
void __iomem *sysram_ns_base_addr __ro_after_init;
|
||||||
|
|
||||||
void __init exynos_sysram_init(void)
|
void __init exynos_sysram_init(void)
|
||||||
@ -43,6 +44,8 @@ void __init exynos_sysram_init(void)
|
|||||||
if (!of_device_is_available(node))
|
if (!of_device_is_available(node))
|
||||||
continue;
|
continue;
|
||||||
sysram_base_addr = of_iomap(node, 0);
|
sysram_base_addr = of_iomap(node, 0);
|
||||||
|
sysram_base_phys = of_translate_address(node,
|
||||||
|
of_get_address(node, 0, NULL, NULL));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <asm/suspend.h>
|
#include <asm/suspend.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "smc.h"
|
||||||
|
|
||||||
#define REG_TABLE_END (-1U)
|
#define REG_TABLE_END (-1U)
|
||||||
|
|
||||||
@ -62,6 +63,8 @@ struct exynos_pm_state {
|
|||||||
int cpu_state;
|
int cpu_state;
|
||||||
unsigned int pmu_spare3;
|
unsigned int pmu_spare3;
|
||||||
void __iomem *sysram_base;
|
void __iomem *sysram_base;
|
||||||
|
phys_addr_t sysram_phys;
|
||||||
|
bool secure_firmware;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct exynos_pm_data *pm_data __ro_after_init;
|
static const struct exynos_pm_data *pm_data __ro_after_init;
|
||||||
@ -340,6 +343,10 @@ static void exynos5420_pm_prepare(void)
|
|||||||
pm_state.cpu_state = readl_relaxed(pm_state.sysram_base +
|
pm_state.cpu_state = readl_relaxed(pm_state.sysram_base +
|
||||||
EXYNOS5420_CPU_STATE);
|
EXYNOS5420_CPU_STATE);
|
||||||
writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE);
|
writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE);
|
||||||
|
if (pm_state.secure_firmware)
|
||||||
|
exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(pm_state.sysram_phys +
|
||||||
|
EXYNOS5420_CPU_STATE),
|
||||||
|
0, 0);
|
||||||
|
|
||||||
exynos_pm_enter_sleep_mode();
|
exynos_pm_enter_sleep_mode();
|
||||||
|
|
||||||
@ -459,6 +466,11 @@ static void exynos5420_pm_resume(void)
|
|||||||
/* Restore the sysram cpu state register */
|
/* Restore the sysram cpu state register */
|
||||||
writel_relaxed(pm_state.cpu_state,
|
writel_relaxed(pm_state.cpu_state,
|
||||||
pm_state.sysram_base + EXYNOS5420_CPU_STATE);
|
pm_state.sysram_base + EXYNOS5420_CPU_STATE);
|
||||||
|
if (pm_state.secure_firmware)
|
||||||
|
exynos_smc(SMC_CMD_REG,
|
||||||
|
SMC_REG_ID_SFR_W(pm_state.sysram_phys +
|
||||||
|
EXYNOS5420_CPU_STATE),
|
||||||
|
EXYNOS_AFTR_MAGIC, 0);
|
||||||
|
|
||||||
pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
|
pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
|
||||||
S5P_CENTRAL_SEQ_OPTION);
|
S5P_CENTRAL_SEQ_OPTION);
|
||||||
@ -658,8 +670,11 @@ void __init exynos_pm_init(void)
|
|||||||
* Applicable as of now only to Exynos542x. If booted under secure
|
* Applicable as of now only to Exynos542x. If booted under secure
|
||||||
* firmware, the non-secure region of sysram should be used.
|
* firmware, the non-secure region of sysram should be used.
|
||||||
*/
|
*/
|
||||||
if (exynos_secure_firmware_available())
|
if (exynos_secure_firmware_available()) {
|
||||||
|
pm_state.sysram_phys = sysram_base_phys;
|
||||||
pm_state.sysram_base = sysram_ns_base_addr;
|
pm_state.sysram_base = sysram_ns_base_addr;
|
||||||
else
|
pm_state.secure_firmware = true;
|
||||||
|
} else {
|
||||||
pm_state.sysram_base = sysram_base_addr;
|
pm_state.sysram_base = sysram_base_addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user