[PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
Add machine-dependent MCPM call-backs for Exynos5420. These are used to power up/down the secondary CPUs during boot, shutdown, s2r and switching. Signed-off-by: Thomas Abraham thomas...@samsung.com Signed-off-by: Inderpal Singh inderpa...@samsung.com Signed-off-by: Andrew Bresticker abres...@chromium.org Signed-off-by: Abhilash Kesavan a.kesa...@samsung.com Reviewed-by: Nicolas Pitre nicolas.pi...@linaro.org --- arch/arm/mach-exynos/Kconfig |8 + arch/arm/mach-exynos/Makefile |2 + arch/arm/mach-exynos/mcpm-exynos.c | 346 arch/arm/mach-exynos/regs-pmu.h|3 + 4 files changed, 359 insertions(+) create mode 100644 arch/arm/mach-exynos/mcpm-exynos.c diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index fc8bf18..1602abc 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -110,4 +110,12 @@ config SOC_EXYNOS5440 endmenu +config EXYNOS5420_MCPM + bool Exynos5420 Multi-Cluster PM support + depends on MCPM SOC_EXYNOS5420 + select ARM_CCI + help + This is needed to provide CPU and cluster power management + on Exynos5420 implementing big.LITTLE. + endif diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index f6dcc25..2e0666d 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -24,3 +24,5 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_exynos-smc.o:=-Wa,-march=armv7-a$(plus_sec) + +obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c new file mode 100644 index 000..ec4ae00 --- /dev/null +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * arch/arm/mach-exynos/mcpm-exynos.c + * + * Based on arch/arm/mach-vexpress/dcscb.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/arm-cci.h +#include linux/delay.h +#include linux/io.h +#include linux/of_address.h + +#include asm/cputype.h +#include asm/cp15.h +#include asm/mcpm.h + +#include regs-pmu.h +#include common.h + +#define EXYNOS5420_CPUS_PER_CLUSTER4 +#define EXYNOS5420_NR_CLUSTERS 2 +#define MCPM_BOOT_ADDR_OFFSET 0x1c + +/* Non-secure iRAM base address */ +static void __iomem *ns_sram_base_addr; + +/* + * The common v7_exit_coherency_flush API could not be used because of the + * Erratum 799270 workaround. This macro is the same as the common one (in + * arch/arm/include/asm/cacheflush.h) except for the erratum handling. + */ +#define exynos_v7_exit_coherency_flush(level) \ + asm volatile( \ + stmfd sp!, {fp, ip}\n\t\ + mrcp15, 0, r0, c1, c0, 0 @ get SCTLR\n\t \ + bicr0, r0, #__stringify(CR_C)\n\t \ + mcrp15, 0, r0, c1, c0, 0 @ set SCTLR\n\t \ + isb\n\t\ + bl v7_flush_dcache___stringify(level)\n\t \ + clrex\n\t\ + mrcp15, 0, r0, c1, c0, 1 @ get ACTLR\n\t \ + bicr0, r0, #(1 6) @ disable local coherency\n\t \ + /* Dummy Load of a device register to avoid Erratum 799270 */ \ + ldrr4, [%0]\n\t \ + andr4, r4, #0\n\t \ + orrr0, r0, r4\n\t \ + mcrp15, 0, r0, c1, c0, 1 @ set ACTLR\n\t \ + isb\n\t \ + dsb\n\t \ + ldmfd sp!, {fp, ip} \ + : \ + : Ir (S5P_INFORM0) \ + : r0, r1, r2, r3, r4, r5, r6, r7, \ + r9, r10, lr, memory) + +/* + * We can't use regular spinlocks. In the switcher case, it is possible + * for an outbound CPU to call power_down() after its inbound counterpart + * is already live using the same logical CPU number which trips lockdep + * debugging. + */ +static arch_spinlock_t exynos_mcpm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int +cpu_use_count[EXYNOS5420_CPUS_PER_CLUSTER][EXYNOS5420_NR_CLUSTERS]; + +#define exynos_cluster_usecnt(cluster) \ + (cpu_use_count[0][cluster] + \ +cpu_use_count[1][cluster] + \ +cpu_use_count[2][cluster] + \ +cpu_use_count[3][cluster]) + +#define exynos_cluster_unused(cluster) !exynos_cluster_usecnt(cluster) + +static int exynos_cluster_power_control(unsigned int cluster, int enable) +{ + unsigned int tries = 100; + unsigned int val; + + if (enable) { + exynos_cluster_power_up(cluster); + val = S5P_CORE_LOCAL_PWR_EN; + } else { + exynos_cluster_power_down(cluster); + val = 0; + } + + /* Wait until cluster power control is applied */ + while (tries--) { + if (exynos_cluster_power_state(cluster) == val) + return
Re: [PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
On Tue, May 13, 2014 at 12:58:44PM +0100, Abhilash Kesavan wrote: [...] +static int __init exynos_mcpm_init(void) +{ + struct device_node *node; + int ret = 0; There is no point in initializing it to 0. + + node = of_find_compatible_node(NULL, NULL, samsung,exynos5420); + if (!node) + return -ENODEV; + of_node_put(node); + + if (!cci_probed()) + return -ENODEV; + + node = of_find_compatible_node(NULL, NULL, + samsung,exynos4210-sysram-ns); + if (!node) + return -ENODEV; + + ns_sram_base_addr = of_iomap(node, 0); + of_node_put(node); + if (!ns_sram_base_addr) { + pr_err(failed to map non-secure iRAM base address\n); + return -ENOMEM; + } + + /* +* To increase the stability of KFC reset we need to program +* the PMU SPARE3 register +*/ + __raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3); + + exynos_mcpm_usage_count_init(); + + ret = mcpm_platform_register(exynos_power_ops); + if (!ret) + ret = mcpm_sync_init(exynos_pm_power_up_setup); + if (ret) { + iounmap(ns_sram_base_addr); + return ret; + } + + mcpm_smp_set_ops(); + + pr_info(Exynos MCPM support installed\n); + + /* +* Future entries into the kernel can now go +* through the cluster entry vectors. +*/ + __raw_writel(virt_to_phys(mcpm_entry_point), + ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET); + ns_sram_base_addr must be unmapped, since it is unused after the write. Lorenzo + return ret; +} + +early_initcall(exynos_mcpm_init); diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h index f6b68a3..4179f6a 100644 --- a/arch/arm/mach-exynos/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h @@ -38,6 +38,7 @@ #define S5P_INFORM5S5P_PMUREG(0x0814) #define S5P_INFORM6S5P_PMUREG(0x0818) #define S5P_INFORM7S5P_PMUREG(0x081C) +#define S5P_PMU_SPARE3 S5P_PMUREG(0x090C) #define S5P_ARM_CORE0_LOWPWR S5P_PMUREG(0x1000) #define S5P_DIS_IRQ_CORE0 S5P_PMUREG(0x1004) @@ -322,4 +323,6 @@ #define EXYNOS5_OPTION_USE_RETENTION (1 4) +#define EXYNOS5420_SWRESET_KFC_SEL 0x3 + #endif /* __ASM_ARCH_REGS_PMU_H */ -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
Hi Lorenzo, On Tue, May 13, 2014 at 10:18 PM, Lorenzo Pieralisi lorenzo.pieral...@arm.com wrote: On Tue, May 13, 2014 at 12:58:44PM +0100, Abhilash Kesavan wrote: [...] +static int __init exynos_mcpm_init(void) +{ + struct device_node *node; + int ret = 0; There is no point in initializing it to 0. OK. + + node = of_find_compatible_node(NULL, NULL, samsung,exynos5420); + if (!node) + return -ENODEV; + of_node_put(node); + + if (!cci_probed()) + return -ENODEV; + + node = of_find_compatible_node(NULL, NULL, + samsung,exynos4210-sysram-ns); + if (!node) + return -ENODEV; + + ns_sram_base_addr = of_iomap(node, 0); + of_node_put(node); + if (!ns_sram_base_addr) { + pr_err(failed to map non-secure iRAM base address\n); + return -ENOMEM; + } + + /* +* To increase the stability of KFC reset we need to program +* the PMU SPARE3 register +*/ + __raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3); + + exynos_mcpm_usage_count_init(); + + ret = mcpm_platform_register(exynos_power_ops); + if (!ret) + ret = mcpm_sync_init(exynos_pm_power_up_setup); + if (ret) { + iounmap(ns_sram_base_addr); + return ret; + } + + mcpm_smp_set_ops(); + + pr_info(Exynos MCPM support installed\n); + + /* +* Future entries into the kernel can now go +* through the cluster entry vectors. +*/ + __raw_writel(virt_to_phys(mcpm_entry_point), + ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET); + ns_sram_base_addr must be unmapped, since it is unused after the write. Will unmap. Regards, Abhilash -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
On 14 May 2014 08:14, Abhilash Kesavan kesavan.abhil...@gmail.com wrote: Hi Lorenzo, On Tue, May 13, 2014 at 10:18 PM, Lorenzo Pieralisi lorenzo.pieral...@arm.com wrote: On Tue, May 13, 2014 at 12:58:44PM +0100, Abhilash Kesavan wrote: [...] +static int __init exynos_mcpm_init(void) +{ + struct device_node *node; + int ret = 0; There is no point in initializing it to 0. OK. + + node = of_find_compatible_node(NULL, NULL, samsung,exynos5420); + if (!node) + return -ENODEV; + of_node_put(node); + + if (!cci_probed()) + return -ENODEV; + + node = of_find_compatible_node(NULL, NULL, + samsung,exynos4210-sysram-ns); + if (!node) + return -ENODEV; + + ns_sram_base_addr = of_iomap(node, 0); + of_node_put(node); + if (!ns_sram_base_addr) { + pr_err(failed to map non-secure iRAM base address\n); + return -ENOMEM; + } + + /* +* To increase the stability of KFC reset we need to program +* the PMU SPARE3 register +*/ + __raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3); + + exynos_mcpm_usage_count_init(); + + ret = mcpm_platform_register(exynos_power_ops); + if (!ret) + ret = mcpm_sync_init(exynos_pm_power_up_setup); + if (ret) { + iounmap(ns_sram_base_addr); + return ret; + } + + mcpm_smp_set_ops(); + + pr_info(Exynos MCPM support installed\n); + + /* +* Future entries into the kernel can now go +* through the cluster entry vectors. +*/ + __raw_writel(virt_to_phys(mcpm_entry_point), + ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET); + ns_sram_base_addr must be unmapped, since it is unused after the write. Will unmap. This mapping is required in for cpuilde (suspend) to program mcpm_entry before going to suspend. Regards, Abhilash -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- with warm regards, Chander Kashyap -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
Hi Chander, On Wed, May 14, 2014 at 8:24 AM, Chander Kashyap chander.kash...@linaro.org wrote: On 14 May 2014 08:14, Abhilash Kesavan kesavan.abhil...@gmail.com wrote: Hi Lorenzo, On Tue, May 13, 2014 at 10:18 PM, Lorenzo Pieralisi lorenzo.pieral...@arm.com wrote: On Tue, May 13, 2014 at 12:58:44PM +0100, Abhilash Kesavan wrote: [...] +static int __init exynos_mcpm_init(void) +{ + struct device_node *node; + int ret = 0; There is no point in initializing it to 0. OK. + + node = of_find_compatible_node(NULL, NULL, samsung,exynos5420); + if (!node) + return -ENODEV; + of_node_put(node); + + if (!cci_probed()) + return -ENODEV; + + node = of_find_compatible_node(NULL, NULL, + samsung,exynos4210-sysram-ns); + if (!node) + return -ENODEV; + + ns_sram_base_addr = of_iomap(node, 0); + of_node_put(node); + if (!ns_sram_base_addr) { + pr_err(failed to map non-secure iRAM base address\n); + return -ENOMEM; + } + + /* +* To increase the stability of KFC reset we need to program +* the PMU SPARE3 register +*/ + __raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3); + + exynos_mcpm_usage_count_init(); + + ret = mcpm_platform_register(exynos_power_ops); + if (!ret) + ret = mcpm_sync_init(exynos_pm_power_up_setup); + if (ret) { + iounmap(ns_sram_base_addr); + return ret; + } + + mcpm_smp_set_ops(); + + pr_info(Exynos MCPM support installed\n); + + /* +* Future entries into the kernel can now go +* through the cluster entry vectors. +*/ + __raw_writel(virt_to_phys(mcpm_entry_point), + ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET); + ns_sram_base_addr must be unmapped, since it is unused after the write. Will unmap. This mapping is required in for cpuilde (suspend) to program mcpm_entry before going to suspend. I forgot about your cpuidle patches. I need to retain the mapping then. Abhilash Regards, Abhilash -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- with warm regards, Chander Kashyap -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
On Wed, 14 May 2014, Chander Kashyap wrote: On 14 May 2014 08:14, Abhilash Kesavan kesavan.abhil...@gmail.com wrote: Hi Lorenzo, On Tue, May 13, 2014 at 10:18 PM, Lorenzo Pieralisi lorenzo.pieral...@arm.com wrote: On Tue, May 13, 2014 at 12:58:44PM +0100, Abhilash Kesavan wrote: [...] +static int __init exynos_mcpm_init(void) +{ + struct device_node *node; + int ret = 0; There is no point in initializing it to 0. OK. + + node = of_find_compatible_node(NULL, NULL, samsung,exynos5420); + if (!node) + return -ENODEV; + of_node_put(node); + + if (!cci_probed()) + return -ENODEV; + + node = of_find_compatible_node(NULL, NULL, + samsung,exynos4210-sysram-ns); + if (!node) + return -ENODEV; + + ns_sram_base_addr = of_iomap(node, 0); + of_node_put(node); + if (!ns_sram_base_addr) { + pr_err(failed to map non-secure iRAM base address\n); + return -ENOMEM; + } + + /* +* To increase the stability of KFC reset we need to program +* the PMU SPARE3 register +*/ + __raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3); + + exynos_mcpm_usage_count_init(); + + ret = mcpm_platform_register(exynos_power_ops); + if (!ret) + ret = mcpm_sync_init(exynos_pm_power_up_setup); + if (ret) { + iounmap(ns_sram_base_addr); + return ret; + } + + mcpm_smp_set_ops(); + + pr_info(Exynos MCPM support installed\n); + + /* +* Future entries into the kernel can now go +* through the cluster entry vectors. +*/ + __raw_writel(virt_to_phys(mcpm_entry_point), + ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET); + ns_sram_base_addr must be unmapped, since it is unused after the write. Will unmap. This mapping is required in for cpuilde (suspend) to program mcpm_entry before going to suspend. Why? Nicolas -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
On 14 May 2014 08:32, Nicolas Pitre nicolas.pi...@linaro.org wrote: On Wed, 14 May 2014, Chander Kashyap wrote: On 14 May 2014 08:14, Abhilash Kesavan kesavan.abhil...@gmail.com wrote: Hi Lorenzo, On Tue, May 13, 2014 at 10:18 PM, Lorenzo Pieralisi lorenzo.pieral...@arm.com wrote: On Tue, May 13, 2014 at 12:58:44PM +0100, Abhilash Kesavan wrote: [...] +static int __init exynos_mcpm_init(void) +{ + struct device_node *node; + int ret = 0; There is no point in initializing it to 0. OK. + + node = of_find_compatible_node(NULL, NULL, samsung,exynos5420); + if (!node) + return -ENODEV; + of_node_put(node); + + if (!cci_probed()) + return -ENODEV; + + node = of_find_compatible_node(NULL, NULL, + samsung,exynos4210-sysram-ns); + if (!node) + return -ENODEV; + + ns_sram_base_addr = of_iomap(node, 0); + of_node_put(node); + if (!ns_sram_base_addr) { + pr_err(failed to map non-secure iRAM base address\n); + return -ENOMEM; + } + + /* +* To increase the stability of KFC reset we need to program +* the PMU SPARE3 register +*/ + __raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3); + + exynos_mcpm_usage_count_init(); + + ret = mcpm_platform_register(exynos_power_ops); + if (!ret) + ret = mcpm_sync_init(exynos_pm_power_up_setup); + if (ret) { + iounmap(ns_sram_base_addr); + return ret; + } + + mcpm_smp_set_ops(); + + pr_info(Exynos MCPM support installed\n); + + /* +* Future entries into the kernel can now go +* through the cluster entry vectors. +*/ + __raw_writel(virt_to_phys(mcpm_entry_point), + ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET); + ns_sram_base_addr must be unmapped, since it is unused after the write. Will unmap. This mapping is required in for cpuilde (suspend) to program mcpm_entry before going to suspend. Why? This is required to program the mcpm_entry point address (resume address) after cpuidle exit/fail. Abhilash, as i am not clearing it, it can be unmapped. Thanks Nicolas. Nicolas -- with warm regards, Chander Kashyap -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 5/5] arm: exynos: Add MCPM call-back functions
On Wed, 14 May 2014, Chander Kashyap wrote: On 14 May 2014 08:32, Nicolas Pitre nicolas.pi...@linaro.org wrote: On Wed, 14 May 2014, Chander Kashyap wrote: On 14 May 2014 08:14, Abhilash Kesavan kesavan.abhil...@gmail.com wrote: On Tue, May 13, 2014 at 10:18 PM, Lorenzo Pieralisi lorenzo.pieral...@arm.com wrote: On Tue, May 13, 2014 at 12:58:44PM +0100, Abhilash Kesavan wrote: + /* +* Future entries into the kernel can now go +* through the cluster entry vectors. +*/ + __raw_writel(virt_to_phys(mcpm_entry_point), + ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET); + ns_sram_base_addr must be unmapped, since it is unused after the write. Will unmap. This mapping is required in for cpuilde (suspend) to program mcpm_entry before going to suspend. Why? This is required to program the mcpm_entry point address (resume address) after cpuidle exit/fail. You should be using mcpm_set_entry_vector() for that. Once mcpm_entry_point is set, it shouldn't need to be changed. Nicolas -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html