From 6ec4f8d0d91f2067870ce948fcd505620d0d2987 Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Sat, 5 Jul 2014 06:24:35 +0900 Subject: ARM: EXYNOS: add generic function to calculate cpu number The address of cpu power registers in pmu is based on cpu number offsets. This function calculate the same. This is essentially required in case of multi-cluster SoC's e.g Exynos5420. Signed-off-by: Chander Kashyap Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/regs-pmu.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h index 1d13b08708f..aff23bd395e 100644 --- a/arch/arm/mach-exynos/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h @@ -323,4 +323,13 @@ #define EXYNOS5420_SWRESET_KFC_SEL 0x3 +#include +#define MAX_CPUS_IN_CLUSTER 4 + +static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr) +{ + return ((MPIDR_AFFINITY_LEVEL(mpidr, 1) * MAX_CPUS_IN_CLUSTER) + + MPIDR_AFFINITY_LEVEL(mpidr, 0)); +} + #endif /* __ASM_ARCH_REGS_PMU_H */ -- cgit v1.2.3-70-g09d2 From b5a296cdf43e86e189c17537b85c6c0168aae750 Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Sat, 5 Jul 2014 06:24:35 +0900 Subject: ARM: EXYNOS: do not allow cpuidle registration for exynos5420 Exynos5420 is big.Little Soc. It uses cpuidle-big-litle generic cpuidle driver. Hence do not allow exynos cpuidle driver registration for Exynos5420. Signed-off-by: Chander Kashyap Reviewed-by: Tomasz Figa Acked-by: Daniel Lezcano Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/exynos.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 46d893fcbe8..c7d960aa95a 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -298,7 +298,9 @@ static void __init exynos_dt_machine_init(void) if (!IS_ENABLED(CONFIG_SMP)) exynos_sysram_init(); - exynos_cpuidle_init(); + if (!of_machine_is_compatible("samsung,exynos5420")) + exynos_cpuidle_init(); + exynos_cpufreq_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -- cgit v1.2.3-70-g09d2 From fc2cac41ebbfb16da8b036cba6ec6714ab780a6d Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Sat, 5 Jul 2014 06:24:35 +0900 Subject: ARM: EXYNOS: populate suspend and powered_up callbacks for mcpm In order to support cpuidle through mcpm, suspend and powered-up callbacks are required in mcpm platform code. Hence populate the same callbacks. Signed-off-by: Chander Kashyap Signed-off-by: Chander Kashyap Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/mcpm-exynos.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index ace0ed61747..13a210865c6 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -257,10 +257,46 @@ static int exynos_wait_for_powerdown(unsigned int cpu, unsigned int cluster) return -ETIMEDOUT; /* timeout */ } +static void exynos_powered_up(void) +{ + unsigned int mpidr, cpu, cluster; + + mpidr = read_cpuid_mpidr(); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + arch_spin_lock(&exynos_mcpm_lock); + if (cpu_use_count[cpu][cluster] == 0) + cpu_use_count[cpu][cluster] = 1; + arch_spin_unlock(&exynos_mcpm_lock); +} + +static void exynos_suspend(u64 residency) +{ + unsigned int mpidr, cpunr; + + exynos_power_down(); + + /* + * Execution reaches here only if cpu did not power down. + * Hence roll back the changes done in exynos_power_down function. + * + * CAUTION: "This function requires the stack data to be visible through + * power down and can only be executed on processors like A15 and A7 + * that hit the cache with the C bit clear in the SCTLR register." + */ + mpidr = read_cpuid_mpidr(); + cpunr = exynos_pmu_cpunr(mpidr); + + exynos_cpu_power_up(cpunr); +} + static const struct mcpm_platform_ops exynos_power_ops = { .power_up = exynos_power_up, .power_down = exynos_power_down, .wait_for_powerdown = exynos_wait_for_powerdown, + .suspend = exynos_suspend, + .powered_up = exynos_powered_up, }; static void __init exynos_mcpm_usage_count_init(void) -- cgit v1.2.3-70-g09d2