* [PATCH v5 0/3] Adds PMU and S2R support for exynos5420 @ 2014-06-26 11:12 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel, linux-samsung-soc Cc: kgene.kim, tomasz.figa, joshi, sajjan.linux, dianders, Vikas Sajjan Rebased on 1] Kukjin Kim's tree, for-next branch https://git.kernel.org/cgit/linux/kernel/git/kgene/linux-samsung.git/log/?h=for-next 2] Pankaj Dubey's v5 PMU patchset http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg671625.html changes since v4: - Adressed comments from Tomasz figa and rebased on Pankaj Dubey's v5 PMU patchset changes since v3: Addressed the following comments from Pankaj Dubey, Bartlomiej Zolnierkiewicz, Tomasz Figa and Alim Akhtar: - Moved EXYNOS5420_USE_STANDBY_WFI_ALL define to regs-pmu.h. - Merged exynos5420_set_core_flag function into powerdown_conf. - Removed XXTI_DURATION3 register setting. - Updated the commit message and ordered the clock registers in clock patch. - Removed the code for SYS_DISP1_BLK_CFG handling. - Modified SoC checks to A9 specific checks in PM code. - Updated some comments in the code and added macros for register offsets. - Fixed code which was changing pad retention code for older SoCs. changes since v2: - Addressed comments from Tomasz figa - rebased on Pankaj's V3 patchset https://lkml.org/lkml/2014/5/2/612 - dropped patch "ARM: dts: Add node for GPIO keys on SMDK5420", will be sent separately. changes since v1: - Addressed comments from Tomasz figa. - restructured/consolidated as per Tomasz figa's PM consolidations for exynos Tested on Kukjin Kim's tree, for-next branch + 1] http://www.spinics.net/lists/arm-kernel/msg341884.html 2] http://www.spinics.net/lists/linux-samsung-soc/msg32923.html 3] http://www.mail-archive.com/linux-samsung-soc@vger.kernel.org/msg33067.html on Exynos5420 based chromebook (peach-pit board). NOTE: After system resume we are enabling boot cluster CCI in exynos_cpu_resume in sleep.S. Below procedures were followed to test S2R: Procedure A: 1. make multi_v7_defconfig 2 enable MCPM for 5420 3. enable S3C RTC 4. pass "no_console_suspend" in bootargs 5. echo +20 > /sys/class/rtc/rtc0/wakealarm && echo mem > /sys/power/state Procedure B: 1. make exynos_defconfig 2 enable MCPM for 5420 3 enable CONFIG_PL330_DMA 4. enable CONFIG_PM_RUNTIME 5. pass "no_console_suspend" in bootargs 6. echo +20 > /sys/class/rtc/rtc0/wakealarm && echo mem > /sys/power/state Abhilash Kesavan (2): arm: exynos5: Add PMU support for 5420 arm: exynos5: Add Suspend-to-RAM support for 5420 Vikas Sajjan (1): clk: samsung: exynos5420: Setup clocks before system suspend arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++-- arch/arm/mach-exynos/pmu.c | 290 ++++++++++++++++++++++++++++++++++ arch/arm/mach-exynos/regs-pmu.h | 229 +++++++++++++++++++++++++++ drivers/clk/samsung/clk-exynos5420.c | 29 ++++ 4 files changed, 682 insertions(+), 16 deletions(-) -- 1.7.9.5 ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 0/3] Adds PMU and S2R support for exynos5420 @ 2014-06-26 11:12 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel Rebased on 1] Kukjin Kim's tree, for-next branch https://git.kernel.org/cgit/linux/kernel/git/kgene/linux-samsung.git/log/?h=for-next 2] Pankaj Dubey's v5 PMU patchset http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg671625.html changes since v4: - Adressed comments from Tomasz figa and rebased on Pankaj Dubey's v5 PMU patchset changes since v3: Addressed the following comments from Pankaj Dubey, Bartlomiej Zolnierkiewicz, Tomasz Figa and Alim Akhtar: - Moved EXYNOS5420_USE_STANDBY_WFI_ALL define to regs-pmu.h. - Merged exynos5420_set_core_flag function into powerdown_conf. - Removed XXTI_DURATION3 register setting. - Updated the commit message and ordered the clock registers in clock patch. - Removed the code for SYS_DISP1_BLK_CFG handling. - Modified SoC checks to A9 specific checks in PM code. - Updated some comments in the code and added macros for register offsets. - Fixed code which was changing pad retention code for older SoCs. changes since v2: - Addressed comments from Tomasz figa - rebased on Pankaj's V3 patchset https://lkml.org/lkml/2014/5/2/612 - dropped patch "ARM: dts: Add node for GPIO keys on SMDK5420", will be sent separately. changes since v1: - Addressed comments from Tomasz figa. - restructured/consolidated as per Tomasz figa's PM consolidations for exynos Tested on Kukjin Kim's tree, for-next branch + 1] http://www.spinics.net/lists/arm-kernel/msg341884.html 2] http://www.spinics.net/lists/linux-samsung-soc/msg32923.html 3] http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg33067.html on Exynos5420 based chromebook (peach-pit board). NOTE: After system resume we are enabling boot cluster CCI in exynos_cpu_resume in sleep.S. Below procedures were followed to test S2R: Procedure A: 1. make multi_v7_defconfig 2 enable MCPM for 5420 3. enable S3C RTC 4. pass "no_console_suspend" in bootargs 5. echo +20 > /sys/class/rtc/rtc0/wakealarm && echo mem > /sys/power/state Procedure B: 1. make exynos_defconfig 2 enable MCPM for 5420 3 enable CONFIG_PL330_DMA 4. enable CONFIG_PM_RUNTIME 5. pass "no_console_suspend" in bootargs 6. echo +20 > /sys/class/rtc/rtc0/wakealarm && echo mem > /sys/power/state Abhilash Kesavan (2): arm: exynos5: Add PMU support for 5420 arm: exynos5: Add Suspend-to-RAM support for 5420 Vikas Sajjan (1): clk: samsung: exynos5420: Setup clocks before system suspend arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++-- arch/arm/mach-exynos/pmu.c | 290 ++++++++++++++++++++++++++++++++++ arch/arm/mach-exynos/regs-pmu.h | 229 +++++++++++++++++++++++++++ drivers/clk/samsung/clk-exynos5420.c | 29 ++++ 4 files changed, 682 insertions(+), 16 deletions(-) -- 1.7.9.5 ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 1/3] arm: exynos5: Add PMU support for 5420 2014-06-26 11:12 ` Vikas Sajjan @ 2014-06-26 11:12 ` Vikas Sajjan -1 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel, linux-samsung-soc Cc: kgene.kim, tomasz.figa, joshi, sajjan.linux, dianders, Abhilash Kesavan, Thomas Abraham, Vikas Sajjan From: Abhilash Kesavan <a.kesavan@samsung.com> Add intial PMU settings for exynos5420. This is required for future S2R and Switching support. Signed-off-by: Thomas Abraham <thomas.ab@samsung.com> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> --- arch/arm/mach-exynos/pmu.c | 290 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-exynos/regs-pmu.h | 229 +++++++++++++++++++++++++++++++ 2 files changed, 519 insertions(+) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index abaabe5..235d8a4 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */ +#include <linux/delay.h> #include <linux/module.h> #include <linux/io.h> #include <linux/of.h> @@ -17,6 +18,8 @@ #include <linux/regmap.h> #include <linux/mfd/syscon.h> +#include <asm/cputype.h> + #include "exynos-pmu.h" #include "regs-pmu.h" @@ -334,6 +337,151 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = { { PMU_TABLE_END,}, }; +static struct exynos_pmu_conf exynos5420_pmu_config[] = { + /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ + { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} }, + { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, + { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { PMU_TABLE_END,}, +}; + static unsigned int const exynos5_list_both_cnt_feed[] = { EXYNOS5_ARM_CORE0_OPTION, EXYNOS5_ARM_CORE1_OPTION, @@ -354,6 +502,74 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ISP_ARM_OPTION, }; +static unsigned int const exynos5420_list_disable_pmu_reg[] = { + EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, + EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, + EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, + EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, + EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, + EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, + EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, + EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, + EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, +}; + +static void exynos5_power_off(void) +{ + unsigned int tmp; + + pr_info("Power down.\n"); + tmp = __raw_readl(pmu_base_addr + EXYNOS_PS_HOLD_CONTROL); + tmp ^= (1 << 8); + __raw_writel(tmp, pmu_base_addr + EXYNOS_PS_HOLD_CONTROL); + + /* Wait a little so we don't give a false warning below */ + mdelay(100); + + pr_err("Power down failed, please power off system manually.\n"); + while (1) + ; +} + +void exynos5420_powerdown_conf(enum sys_powerdown mode) +{ + unsigned int this_cluster; + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); + + /* + * set the cluster id to IROM register to ensure that we wake + * up with the current cluster. + */ + __raw_writel(this_cluster, pmu_base_addr + EXYNOS_IROM_DATA2); +} + + static void exynos5_powerdown_conf(enum sys_powerdown mode) { unsigned int i; @@ -425,6 +641,70 @@ static void exynos5250_pmu_init(void) __raw_writel(value, pmu_base_addr + EXYNOS5_MASK_WDTRESET_REQUEST); } +static void exynos5420_pmu_init(void) +{ + unsigned int value; + int i; + + /* + * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers + * for local power blocks to Low initially as per Table 8-4: + * "System-Level Power-Down Configuration Registers". + */ + for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++) + __raw_writel(0, pmu_base_addr + exynos5420_list_disable_pmu_reg[i]); + + /* Enable USE_STANDBY_WFI for all CORE */ + __raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, + pmu_base_addr + S5P_CENTRAL_SEQ_OPTION); + + value = __raw_readl(pmu_base_addr + EXYNOS_L2_OPTION(0)); + value &= ~EXYNOS5_USE_RETENTION; + __raw_writel(value, pmu_base_addr + EXYNOS_L2_OPTION(0)); + + value = __raw_readl(pmu_base_addr + EXYNOS_L2_OPTION(1)); + value &= ~EXYNOS5_USE_RETENTION; + __raw_writel(value, pmu_base_addr + EXYNOS_L2_OPTION(1)); + + /* + * If L2_COMMON is turned off, clocks related to ATB async + * bridge are gated. Thus, when ISP power is gated, LPI + * may get stuck. + */ + value = __raw_readl(pmu_base_addr + EXYNOS5420_LPI_MASK); + value |= EXYNOS5420_ATB_ISP_ARM; + __raw_writel(value, pmu_base_addr + EXYNOS5420_LPI_MASK); + value = __raw_readl(pmu_base_addr + EXYNOS5420_LPI_MASK1); + value |= EXYNOS5420_ATB_KFC; + __raw_writel(value, pmu_base_addr + EXYNOS5420_LPI_MASK1); + + /* Prevent issue of new bus request from L2 memory */ + value = __raw_readl(pmu_base_addr + EXYNOS5420_ARM_COMMON_OPTION); + value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; + __raw_writel(value, pmu_base_addr + EXYNOS5420_ARM_COMMON_OPTION); + + value = __raw_readl(pmu_base_addr + EXYNOS5420_KFC_COMMON_OPTION); + + value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; + __raw_writel(value, pmu_base_addr + EXYNOS5420_KFC_COMMON_OPTION); + + /* This setting is to reduce suspend/resume time */ + __raw_writel(DUR_WAIT_RESET, + pmu_base_addr + EXYNOS5420_LOGIC_RESET_DURATION3); + + /* Serialized CPU wakeup of Eagle */ + __raw_writel(SPREAD_ENABLE, + pmu_base_addr + EXYNOS5420_ARM_INTR_SPREAD_ENABLE); + + __raw_writel(SPREAD_USE_STANDWFI, + pmu_base_addr + EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI); + + __raw_writel(0x1, pmu_base_addr + EXYNOS5420_UP_SCHEDULER); + + pm_power_off = exynos5_power_off; + pr_info("EXYNOS5420 PMU initialized\n"); +} + static struct exynos_pmu_data exynos4210_pmu_data = { .pmu_config = exynos4210_pmu_config, }; @@ -444,6 +724,12 @@ static struct exynos_pmu_data exynos5250_pmu_data = { .powerdown_conf = exynos5_powerdown_conf, }; +static struct exynos_pmu_data exynos5420_pmu_data = { + .pmu_config = exynos5420_pmu_config, + .pmu_init = exynos5420_pmu_init, + .powerdown_conf = exynos5420_powerdown_conf, +}; + static struct regmap_config pmu_regmap_config = { .reg_bits = 32, .val_bits = 32, @@ -470,6 +756,10 @@ static struct of_device_id exynos_pmu_of_device_ids[] = { .compatible = "samsung,exynos5250-pmu", .data = (void *)&exynos5250_pmu_data, }, + { + .compatible = "samsung,exynos5420-pmu", + .data = (void *)&exynos5420_pmu_data, + }, {}, }; diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h index efad6cb..08b6b2b 100644 --- a/arch/arm/mach-exynos/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h @@ -35,6 +35,7 @@ #define S5P_INFORM7 0x081C #define S5P_PMU_SPARE3 0x090C +#define EXYNOS_IROM_DATA2 0x0988 #define S5P_ARM_CORE0_LOWPWR 0x1000 #define S5P_DIS_IRQ_CORE0 0x1004 #define S5P_DIS_IRQ_CENTRAL0 0x1008 @@ -113,6 +114,33 @@ #define EXYNOS_COMMON_STATUS(_nr) \ (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x4) +#define EXYNOS_ARM_CORE_OPTION(_nr) (S5P_ARM_CORE0_OPTION \ + + ((_nr) * 0x80)) +#define EXYNOS_CORE_LOCAL_PWR_EN 0x3 + +#define EXYNOS_ARM_COMMON_STATUS 0x2504 +#define EXYNOS_COMMON_OPTION(_nr) \ + (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8) + +#define EXYNOS_ARM_L2_CONFIGURATION 0x2600 +#define EXYNOS_L2_CONFIGURATION(_nr) \ + (EXYNOS_ARM_L2_CONFIGURATION + ((_nr) * 0x80)) +#define EXYNOS_L2_STATUS(_nr) \ + (EXYNOS_L2_CONFIGURATION(_nr) + 0x4) +#define EXYNOS_L2_OPTION(_nr) \ + (EXYNOS_L2_CONFIGURATION(_nr) + 0x8) +#define EXYNOS_L2_COMMON_PWR_EN 0x3 + +#define EXYNOS_ARM_CORE_X_STATUS_OFFSET 0x4 + +#define EXYNOS5_APLL_SYSCLK_CONFIGURATION 0x2A00 +#define EXYNOS5_APLL_SYSCLK_STATUS 0x2A04 + +#define EXYNOS5_ARM_L2_OPTION 0x2608 +#define EXYNOS5_USE_RETENTION BIT(4) + +#define EXYNOS5_L2RSTDISABLE_VALUE BIT(3) + #define S5P_PAD_RET_MAUDIO_OPTION 0x3028 #define S5P_PAD_RET_GPIO_OPTION 0x3108 #define S5P_PAD_RET_UART_OPTION 0x3128 @@ -185,6 +213,7 @@ #define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408 #define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C +#define EXYNOS5_USE_RETENTION BIT(4) #define EXYNOS5_SYS_WDTRESET (1 << 20) #define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000 @@ -315,4 +344,204 @@ #define EXYNOS5420_SWRESET_KFC_SEL 0x3 +/* Only for EXYNOS5420 */ +#define EXYNOS5420_ISP_ARM_OPTION 0x2488 +#define EXYNOS5420_L2RSTDISABLE_VALUE BIT(3) + +#define EXYNOS5420_LPI_MASK 0x0004 +#define EXYNOS5420_LPI_MASK1 0x0008 +#define EXYNOS5420_UFS BIT(8) +#define EXYNOS5420_ATB_KFC BIT(13) +#define EXYNOS5420_ATB_ISP_ARM BIT(19) +#define EXYNOS5420_EMULATION BIT(31) +#define ATB_ISP_ARM BIT(12) +#define ATB_KFC BIT(13) +#define ATB_NOC BIT(14) + +#define EXYNOS5420_ARM_INTR_SPREAD_ENABLE 0x0100 +#define EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI 0x0104 +#define EXYNOS5420_UP_SCHEDULER 0x0120 +#define SPREAD_ENABLE 0xF +#define SPREAD_USE_STANDWFI 0xF + +#define EXYNOS5420_BB_CON1 0x0784 +#define EXYNOS5420_BB_SEL_EN BIT(31) +#define EXYNOS5420_BB_PMOS_EN BIT(7) +#define EXYNOS5420_BB_1300X 0XF + +#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020 +#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024 +#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028 +#define EXYNOS5420_ARM_CORE3_SYS_PWR_REG 0x1030 +#define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG 0x1034 +#define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG 0x1038 +#define EXYNOS5420_KFC_CORE0_SYS_PWR_REG 0x1040 +#define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG 0x1044 +#define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG 0x1048 +#define EXYNOS5420_KFC_CORE1_SYS_PWR_REG 0x1050 +#define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG 0x1054 +#define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG 0x1058 +#define EXYNOS5420_KFC_CORE2_SYS_PWR_REG 0x1060 +#define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG 0x1064 +#define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG 0x1068 +#define EXYNOS5420_KFC_CORE3_SYS_PWR_REG 0x1070 +#define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG 0x1074 +#define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG 0x1078 +#define EXYNOS5420_ISP_ARM_SYS_PWR_REG 0x1090 +#define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1094 +#define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1098 +#define EXYNOS5420_ARM_COMMON_SYS_PWR_REG 0x10A0 +#define EXYNOS5420_KFC_COMMON_SYS_PWR_REG 0x10B0 +#define EXYNOS5420_KFC_L2_SYS_PWR_REG 0x10D0 +#define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG 0x1158 +#define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG 0x115C +#define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG 0x1160 +#define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG 0x1174 +#define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG 0x1178 +#define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG 0x11B8 +#define EXYNOS5420_INTROM_MEM_SYS_PWR_REG 0x11BC +#define EXYNOS5420_ONENANDXL_MEM_SYS_PWR 0x11C0 +#define EXYNOS5420_USBDEV_MEM_SYS_PWR 0x11CC +#define EXYNOS5420_USBDEV1_MEM_SYS_PWR 0x11D0 +#define EXYNOS5420_SDMMC_MEM_SYS_PWR 0x11D4 +#define EXYNOS5420_CSSYS_MEM_SYS_PWR 0x11D8 +#define EXYNOS5420_SECSS_MEM_SYS_PWR 0x11DC +#define EXYNOS5420_ROTATOR_MEM_SYS_PWR 0x11E0 +#define EXYNOS5420_INTRAM_MEM_SYS_PWR 0x11E4 +#define EXYNOS5420_INTROM_MEM_SYS_PWR 0x11E8 +#define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1208 +#define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1210 +#define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG 0x1214 +#define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1218 +#define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG 0x121C +#define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1220 +#define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG 0x1224 +#define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1228 +#define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG 0x122C +#define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG 0x1230 +#define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG 0x1234 +#define EXYNOS5420_DISP1_SYS_PWR_REG 0x1410 +#define EXYNOS5420_MAU_SYS_PWR_REG 0x1414 +#define EXYNOS5420_G2D_SYS_PWR_REG 0x1418 +#define EXYNOS5420_MSC_SYS_PWR_REG 0x141C +#define EXYNOS5420_FSYS_SYS_PWR_REG 0x1420 +#define EXYNOS5420_FSYS2_SYS_PWR_REG 0x1424 +#define EXYNOS5420_PSGEN_SYS_PWR_REG 0x1428 +#define EXYNOS5420_PERIC_SYS_PWR_REG 0x142C +#define EXYNOS5420_WCORE_SYS_PWR_REG 0x1430 +#define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG 0x1490 +#define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG 0x1494 +#define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG 0x1498 +#define EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG 0x149C +#define EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG 0x14A0 +#define EXYNOS5420_CMU_CLKSTOP_FSYS2_SYS_PWR_REG 0x14A4 +#define EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG 0x14A8 +#define EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG 0x14AC +#define EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG 0x14B0 +#define EXYNOS5420_CMU_SYSCLK_TOPPWR_SYS_PWR_REG 0x14BC +#define EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG 0x14D0 +#define EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG 0x14D4 +#define EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG 0x14D8 +#define EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG 0x14DC +#define EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG 0x14E0 +#define EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG 0x14E4 +#define EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG 0x14E8 +#define EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG 0x14EC +#define EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG 0x14F0 +#define EXYNOS5420_CMU_SYSCLK_SYSMEM_TOPPWR_SYS_PWR_REG 0x14F4 +#define EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG 0x1570 +#define EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG 0x1574 +#define EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG 0x1578 +#define EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG 0x157C +#define EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG 0x1590 +#define EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG 0x1594 +#define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG 0x1598 +#define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG 0x159C +#define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG 0x15A0 +#define EXYNOS5420_SFR_AXI_CGDIS1 0x15E4 +#define EXYNOS_ARM_CORE2_CONFIGURATION 0x2100 +#define EXYNOS5420_ARM_CORE2_OPTION 0x2108 +#define EXYNOS_ARM_CORE3_CONFIGURATION 0x2180 +#define EXYNOS5420_ARM_CORE3_OPTION 0x2188 +#define EXYNOS5420_ARM_COMMON_STATUS 0x2504 +#define EXYNOS5420_ARM_COMMON_OPTION 0x2508 +#define EXYNOS5420_KFC_COMMON_STATUS 0x2584 +#define EXYNOS5420_KFC_COMMON_OPTION 0x2588 +#define EXYNOS5420_LOGIC_RESET_DURATION3 0x2D1C + +#define EXYNOS5420_PAD_RET_GPIO_OPTION 0x30C8 +#define EXYNOS5420_PAD_RET_UART_OPTION 0x30E8 +#define EXYNOS5420_PAD_RET_MMCA_OPTION 0x3108 +#define EXYNOS5420_PAD_RET_MMCB_OPTION 0x3128 +#define EXYNOS5420_PAD_RET_MMCC_OPTION 0x3148 +#define EXYNOS5420_PAD_RET_HSI_OPTION 0x3168 +#define EXYNOS5420_PAD_RET_SPI_OPTION 0x31C8 +#define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION 0x31E8 +#define EXYNOS_PAD_RET_DRAM_OPTION 0x3008 +#define EXYNOS_PAD_RET_MAUDIO_OPTION 0x3028 +#define EXYNOS_PAD_RET_JTAG_OPTION 0x3048 +#define EXYNOS_PAD_RET_GPIO_OPTION 0x3108 +#define EXYNOS_PAD_RET_UART_OPTION 0x3128 +#define EXYNOS_PAD_RET_MMCA_OPTION 0x3148 +#define EXYNOS_PAD_RET_MMCB_OPTION 0x3168 +#define EXYNOS_PAD_RET_EBIA_OPTION 0x3188 +#define EXYNOS_PAD_RET_EBIB_OPTION 0x31A8 + +#define EXYNOS_PS_HOLD_CONTROL 0x330C + +/* For SYS_PWR_REG */ +#define EXYNOS_SYS_PWR_CFG BIT(0) + +#define EXYNOS5420_MFC_CONFIGURATION 0x4060 +#define EXYNOS5420_MFC_STATUS 0x4064 +#define EXYNOS5420_MFC_OPTION 0x4068 +#define EXYNOS5420_G3D_CONFIGURATION 0x4080 +#define EXYNOS5420_G3D_STATUS 0x4084 +#define EXYNOS5420_G3D_OPTION 0x4088 +#define EXYNOS5420_DISP0_CONFIGURATION 0x40A0 +#define EXYNOS5420_DISP0_STATUS 0x40A4 +#define EXYNOS5420_DISP0_OPTION 0x40A8 +#define EXYNOS5420_DISP1_CONFIGURATION 0x40C0 +#define EXYNOS5420_DISP1_STATUS 0x40C4 +#define EXYNOS5420_DISP1_OPTION 0x40C8 +#define EXYNOS5420_MAU_CONFIGURATION 0x40E0 +#define EXYNOS5420_MAU_STATUS 0x40E4 +#define EXYNOS5420_MAU_OPTION 0x40E8 +#define EXYNOS5420_FSYS2_OPTION 0x4168 +#define EXYNOS5420_PSGEN_OPTION 0x4188 + +/* For EXYNOS_CENTRAL_SEQ_OPTION */ +#define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 BIT(16) +#define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 BUT(17) +#define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 BIT(24) +#define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 BIT(25) + +#define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4) +#define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5) +#define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6) +#define EXYNOS5420_ARM_USE_STANDBY_WFI3 BIT(7) +#define EXYNOS5420_KFC_USE_STANDBY_WFI0 BIT(8) +#define EXYNOS5420_KFC_USE_STANDBY_WFI1 BIT(9) +#define EXYNOS5420_KFC_USE_STANDBY_WFI2 BIT(10) +#define EXYNOS5420_KFC_USE_STANDBY_WFI3 BIT(11) +#define EXYNOS5420_ARM_USE_STANDBY_WFE0 BIT(16) +#define EXYNOS5420_ARM_USE_STANDBY_WFE1 BIT(17) +#define EXYNOS5420_ARM_USE_STANDBY_WFE2 BIT(18) +#define EXYNOS5420_ARM_USE_STANDBY_WFE3 BIT(19) +#define EXYNOS5420_KFC_USE_STANDBY_WFE0 BIT(20) +#define EXYNOS5420_KFC_USE_STANDBY_WFE1 BIT(21) +#define EXYNOS5420_KFC_USE_STANDBY_WFE2 BIT(22) +#define EXYNOS5420_KFC_USE_STANDBY_WFE3 BIT(23) + +#define DUR_WAIT_RESET 0xF + +#define EXYNOS5420_USE_STANDBY_WFI_ALL (EXYNOS5420_ARM_USE_STANDBY_WFI0 \ + | EXYNOS5420_ARM_USE_STANDBY_WFI1 \ + | EXYNOS5420_ARM_USE_STANDBY_WFI2 \ + | EXYNOS5420_ARM_USE_STANDBY_WFI3 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI0 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI1 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI2 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI3) + #endif /* __ASM_ARCH_REGS_PMU_H */ -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 1/3] arm: exynos5: Add PMU support for 5420 @ 2014-06-26 11:12 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel From: Abhilash Kesavan <a.kesavan@samsung.com> Add intial PMU settings for exynos5420. This is required for future S2R and Switching support. Signed-off-by: Thomas Abraham <thomas.ab@samsung.com> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> --- arch/arm/mach-exynos/pmu.c | 290 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-exynos/regs-pmu.h | 229 +++++++++++++++++++++++++++++++ 2 files changed, 519 insertions(+) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index abaabe5..235d8a4 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */ +#include <linux/delay.h> #include <linux/module.h> #include <linux/io.h> #include <linux/of.h> @@ -17,6 +18,8 @@ #include <linux/regmap.h> #include <linux/mfd/syscon.h> +#include <asm/cputype.h> + #include "exynos-pmu.h" #include "regs-pmu.h" @@ -334,6 +337,151 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = { { PMU_TABLE_END,}, }; +static struct exynos_pmu_conf exynos5420_pmu_config[] = { + /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ + { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} }, + { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, + { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { PMU_TABLE_END,}, +}; + static unsigned int const exynos5_list_both_cnt_feed[] = { EXYNOS5_ARM_CORE0_OPTION, EXYNOS5_ARM_CORE1_OPTION, @@ -354,6 +502,74 @@ static unsigned int const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ISP_ARM_OPTION, }; +static unsigned int const exynos5420_list_disable_pmu_reg[] = { + EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, + EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, + EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, + EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, + EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, + EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, + EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, + EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, + EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, + EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, + EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, + EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, +}; + +static void exynos5_power_off(void) +{ + unsigned int tmp; + + pr_info("Power down.\n"); + tmp = __raw_readl(pmu_base_addr + EXYNOS_PS_HOLD_CONTROL); + tmp ^= (1 << 8); + __raw_writel(tmp, pmu_base_addr + EXYNOS_PS_HOLD_CONTROL); + + /* Wait a little so we don't give a false warning below */ + mdelay(100); + + pr_err("Power down failed, please power off system manually.\n"); + while (1) + ; +} + +void exynos5420_powerdown_conf(enum sys_powerdown mode) +{ + unsigned int this_cluster; + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); + + /* + * set the cluster id to IROM register to ensure that we wake + * up with the current cluster. + */ + __raw_writel(this_cluster, pmu_base_addr + EXYNOS_IROM_DATA2); +} + + static void exynos5_powerdown_conf(enum sys_powerdown mode) { unsigned int i; @@ -425,6 +641,70 @@ static void exynos5250_pmu_init(void) __raw_writel(value, pmu_base_addr + EXYNOS5_MASK_WDTRESET_REQUEST); } +static void exynos5420_pmu_init(void) +{ + unsigned int value; + int i; + + /* + * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers + * for local power blocks to Low initially as per Table 8-4: + * "System-Level Power-Down Configuration Registers". + */ + for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++) + __raw_writel(0, pmu_base_addr + exynos5420_list_disable_pmu_reg[i]); + + /* Enable USE_STANDBY_WFI for all CORE */ + __raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, + pmu_base_addr + S5P_CENTRAL_SEQ_OPTION); + + value = __raw_readl(pmu_base_addr + EXYNOS_L2_OPTION(0)); + value &= ~EXYNOS5_USE_RETENTION; + __raw_writel(value, pmu_base_addr + EXYNOS_L2_OPTION(0)); + + value = __raw_readl(pmu_base_addr + EXYNOS_L2_OPTION(1)); + value &= ~EXYNOS5_USE_RETENTION; + __raw_writel(value, pmu_base_addr + EXYNOS_L2_OPTION(1)); + + /* + * If L2_COMMON is turned off, clocks related to ATB async + * bridge are gated. Thus, when ISP power is gated, LPI + * may get stuck. + */ + value = __raw_readl(pmu_base_addr + EXYNOS5420_LPI_MASK); + value |= EXYNOS5420_ATB_ISP_ARM; + __raw_writel(value, pmu_base_addr + EXYNOS5420_LPI_MASK); + value = __raw_readl(pmu_base_addr + EXYNOS5420_LPI_MASK1); + value |= EXYNOS5420_ATB_KFC; + __raw_writel(value, pmu_base_addr + EXYNOS5420_LPI_MASK1); + + /* Prevent issue of new bus request from L2 memory */ + value = __raw_readl(pmu_base_addr + EXYNOS5420_ARM_COMMON_OPTION); + value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; + __raw_writel(value, pmu_base_addr + EXYNOS5420_ARM_COMMON_OPTION); + + value = __raw_readl(pmu_base_addr + EXYNOS5420_KFC_COMMON_OPTION); + + value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; + __raw_writel(value, pmu_base_addr + EXYNOS5420_KFC_COMMON_OPTION); + + /* This setting is to reduce suspend/resume time */ + __raw_writel(DUR_WAIT_RESET, + pmu_base_addr + EXYNOS5420_LOGIC_RESET_DURATION3); + + /* Serialized CPU wakeup of Eagle */ + __raw_writel(SPREAD_ENABLE, + pmu_base_addr + EXYNOS5420_ARM_INTR_SPREAD_ENABLE); + + __raw_writel(SPREAD_USE_STANDWFI, + pmu_base_addr + EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI); + + __raw_writel(0x1, pmu_base_addr + EXYNOS5420_UP_SCHEDULER); + + pm_power_off = exynos5_power_off; + pr_info("EXYNOS5420 PMU initialized\n"); +} + static struct exynos_pmu_data exynos4210_pmu_data = { .pmu_config = exynos4210_pmu_config, }; @@ -444,6 +724,12 @@ static struct exynos_pmu_data exynos5250_pmu_data = { .powerdown_conf = exynos5_powerdown_conf, }; +static struct exynos_pmu_data exynos5420_pmu_data = { + .pmu_config = exynos5420_pmu_config, + .pmu_init = exynos5420_pmu_init, + .powerdown_conf = exynos5420_powerdown_conf, +}; + static struct regmap_config pmu_regmap_config = { .reg_bits = 32, .val_bits = 32, @@ -470,6 +756,10 @@ static struct of_device_id exynos_pmu_of_device_ids[] = { .compatible = "samsung,exynos5250-pmu", .data = (void *)&exynos5250_pmu_data, }, + { + .compatible = "samsung,exynos5420-pmu", + .data = (void *)&exynos5420_pmu_data, + }, {}, }; diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h index efad6cb..08b6b2b 100644 --- a/arch/arm/mach-exynos/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h @@ -35,6 +35,7 @@ #define S5P_INFORM7 0x081C #define S5P_PMU_SPARE3 0x090C +#define EXYNOS_IROM_DATA2 0x0988 #define S5P_ARM_CORE0_LOWPWR 0x1000 #define S5P_DIS_IRQ_CORE0 0x1004 #define S5P_DIS_IRQ_CENTRAL0 0x1008 @@ -113,6 +114,33 @@ #define EXYNOS_COMMON_STATUS(_nr) \ (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x4) +#define EXYNOS_ARM_CORE_OPTION(_nr) (S5P_ARM_CORE0_OPTION \ + + ((_nr) * 0x80)) +#define EXYNOS_CORE_LOCAL_PWR_EN 0x3 + +#define EXYNOS_ARM_COMMON_STATUS 0x2504 +#define EXYNOS_COMMON_OPTION(_nr) \ + (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8) + +#define EXYNOS_ARM_L2_CONFIGURATION 0x2600 +#define EXYNOS_L2_CONFIGURATION(_nr) \ + (EXYNOS_ARM_L2_CONFIGURATION + ((_nr) * 0x80)) +#define EXYNOS_L2_STATUS(_nr) \ + (EXYNOS_L2_CONFIGURATION(_nr) + 0x4) +#define EXYNOS_L2_OPTION(_nr) \ + (EXYNOS_L2_CONFIGURATION(_nr) + 0x8) +#define EXYNOS_L2_COMMON_PWR_EN 0x3 + +#define EXYNOS_ARM_CORE_X_STATUS_OFFSET 0x4 + +#define EXYNOS5_APLL_SYSCLK_CONFIGURATION 0x2A00 +#define EXYNOS5_APLL_SYSCLK_STATUS 0x2A04 + +#define EXYNOS5_ARM_L2_OPTION 0x2608 +#define EXYNOS5_USE_RETENTION BIT(4) + +#define EXYNOS5_L2RSTDISABLE_VALUE BIT(3) + #define S5P_PAD_RET_MAUDIO_OPTION 0x3028 #define S5P_PAD_RET_GPIO_OPTION 0x3108 #define S5P_PAD_RET_UART_OPTION 0x3128 @@ -185,6 +213,7 @@ #define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408 #define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C +#define EXYNOS5_USE_RETENTION BIT(4) #define EXYNOS5_SYS_WDTRESET (1 << 20) #define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000 @@ -315,4 +344,204 @@ #define EXYNOS5420_SWRESET_KFC_SEL 0x3 +/* Only for EXYNOS5420 */ +#define EXYNOS5420_ISP_ARM_OPTION 0x2488 +#define EXYNOS5420_L2RSTDISABLE_VALUE BIT(3) + +#define EXYNOS5420_LPI_MASK 0x0004 +#define EXYNOS5420_LPI_MASK1 0x0008 +#define EXYNOS5420_UFS BIT(8) +#define EXYNOS5420_ATB_KFC BIT(13) +#define EXYNOS5420_ATB_ISP_ARM BIT(19) +#define EXYNOS5420_EMULATION BIT(31) +#define ATB_ISP_ARM BIT(12) +#define ATB_KFC BIT(13) +#define ATB_NOC BIT(14) + +#define EXYNOS5420_ARM_INTR_SPREAD_ENABLE 0x0100 +#define EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI 0x0104 +#define EXYNOS5420_UP_SCHEDULER 0x0120 +#define SPREAD_ENABLE 0xF +#define SPREAD_USE_STANDWFI 0xF + +#define EXYNOS5420_BB_CON1 0x0784 +#define EXYNOS5420_BB_SEL_EN BIT(31) +#define EXYNOS5420_BB_PMOS_EN BIT(7) +#define EXYNOS5420_BB_1300X 0XF + +#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020 +#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024 +#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028 +#define EXYNOS5420_ARM_CORE3_SYS_PWR_REG 0x1030 +#define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG 0x1034 +#define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG 0x1038 +#define EXYNOS5420_KFC_CORE0_SYS_PWR_REG 0x1040 +#define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG 0x1044 +#define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG 0x1048 +#define EXYNOS5420_KFC_CORE1_SYS_PWR_REG 0x1050 +#define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG 0x1054 +#define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG 0x1058 +#define EXYNOS5420_KFC_CORE2_SYS_PWR_REG 0x1060 +#define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG 0x1064 +#define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG 0x1068 +#define EXYNOS5420_KFC_CORE3_SYS_PWR_REG 0x1070 +#define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG 0x1074 +#define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG 0x1078 +#define EXYNOS5420_ISP_ARM_SYS_PWR_REG 0x1090 +#define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1094 +#define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1098 +#define EXYNOS5420_ARM_COMMON_SYS_PWR_REG 0x10A0 +#define EXYNOS5420_KFC_COMMON_SYS_PWR_REG 0x10B0 +#define EXYNOS5420_KFC_L2_SYS_PWR_REG 0x10D0 +#define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG 0x1158 +#define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG 0x115C +#define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG 0x1160 +#define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG 0x1174 +#define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG 0x1178 +#define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG 0x11B8 +#define EXYNOS5420_INTROM_MEM_SYS_PWR_REG 0x11BC +#define EXYNOS5420_ONENANDXL_MEM_SYS_PWR 0x11C0 +#define EXYNOS5420_USBDEV_MEM_SYS_PWR 0x11CC +#define EXYNOS5420_USBDEV1_MEM_SYS_PWR 0x11D0 +#define EXYNOS5420_SDMMC_MEM_SYS_PWR 0x11D4 +#define EXYNOS5420_CSSYS_MEM_SYS_PWR 0x11D8 +#define EXYNOS5420_SECSS_MEM_SYS_PWR 0x11DC +#define EXYNOS5420_ROTATOR_MEM_SYS_PWR 0x11E0 +#define EXYNOS5420_INTRAM_MEM_SYS_PWR 0x11E4 +#define EXYNOS5420_INTROM_MEM_SYS_PWR 0x11E8 +#define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1208 +#define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1210 +#define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG 0x1214 +#define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1218 +#define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG 0x121C +#define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1220 +#define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG 0x1224 +#define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1228 +#define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG 0x122C +#define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG 0x1230 +#define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG 0x1234 +#define EXYNOS5420_DISP1_SYS_PWR_REG 0x1410 +#define EXYNOS5420_MAU_SYS_PWR_REG 0x1414 +#define EXYNOS5420_G2D_SYS_PWR_REG 0x1418 +#define EXYNOS5420_MSC_SYS_PWR_REG 0x141C +#define EXYNOS5420_FSYS_SYS_PWR_REG 0x1420 +#define EXYNOS5420_FSYS2_SYS_PWR_REG 0x1424 +#define EXYNOS5420_PSGEN_SYS_PWR_REG 0x1428 +#define EXYNOS5420_PERIC_SYS_PWR_REG 0x142C +#define EXYNOS5420_WCORE_SYS_PWR_REG 0x1430 +#define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG 0x1490 +#define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG 0x1494 +#define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG 0x1498 +#define EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG 0x149C +#define EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG 0x14A0 +#define EXYNOS5420_CMU_CLKSTOP_FSYS2_SYS_PWR_REG 0x14A4 +#define EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG 0x14A8 +#define EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG 0x14AC +#define EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG 0x14B0 +#define EXYNOS5420_CMU_SYSCLK_TOPPWR_SYS_PWR_REG 0x14BC +#define EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG 0x14D0 +#define EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG 0x14D4 +#define EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG 0x14D8 +#define EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG 0x14DC +#define EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG 0x14E0 +#define EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG 0x14E4 +#define EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG 0x14E8 +#define EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG 0x14EC +#define EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG 0x14F0 +#define EXYNOS5420_CMU_SYSCLK_SYSMEM_TOPPWR_SYS_PWR_REG 0x14F4 +#define EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG 0x1570 +#define EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG 0x1574 +#define EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG 0x1578 +#define EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG 0x157C +#define EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG 0x1590 +#define EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG 0x1594 +#define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG 0x1598 +#define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG 0x159C +#define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG 0x15A0 +#define EXYNOS5420_SFR_AXI_CGDIS1 0x15E4 +#define EXYNOS_ARM_CORE2_CONFIGURATION 0x2100 +#define EXYNOS5420_ARM_CORE2_OPTION 0x2108 +#define EXYNOS_ARM_CORE3_CONFIGURATION 0x2180 +#define EXYNOS5420_ARM_CORE3_OPTION 0x2188 +#define EXYNOS5420_ARM_COMMON_STATUS 0x2504 +#define EXYNOS5420_ARM_COMMON_OPTION 0x2508 +#define EXYNOS5420_KFC_COMMON_STATUS 0x2584 +#define EXYNOS5420_KFC_COMMON_OPTION 0x2588 +#define EXYNOS5420_LOGIC_RESET_DURATION3 0x2D1C + +#define EXYNOS5420_PAD_RET_GPIO_OPTION 0x30C8 +#define EXYNOS5420_PAD_RET_UART_OPTION 0x30E8 +#define EXYNOS5420_PAD_RET_MMCA_OPTION 0x3108 +#define EXYNOS5420_PAD_RET_MMCB_OPTION 0x3128 +#define EXYNOS5420_PAD_RET_MMCC_OPTION 0x3148 +#define EXYNOS5420_PAD_RET_HSI_OPTION 0x3168 +#define EXYNOS5420_PAD_RET_SPI_OPTION 0x31C8 +#define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION 0x31E8 +#define EXYNOS_PAD_RET_DRAM_OPTION 0x3008 +#define EXYNOS_PAD_RET_MAUDIO_OPTION 0x3028 +#define EXYNOS_PAD_RET_JTAG_OPTION 0x3048 +#define EXYNOS_PAD_RET_GPIO_OPTION 0x3108 +#define EXYNOS_PAD_RET_UART_OPTION 0x3128 +#define EXYNOS_PAD_RET_MMCA_OPTION 0x3148 +#define EXYNOS_PAD_RET_MMCB_OPTION 0x3168 +#define EXYNOS_PAD_RET_EBIA_OPTION 0x3188 +#define EXYNOS_PAD_RET_EBIB_OPTION 0x31A8 + +#define EXYNOS_PS_HOLD_CONTROL 0x330C + +/* For SYS_PWR_REG */ +#define EXYNOS_SYS_PWR_CFG BIT(0) + +#define EXYNOS5420_MFC_CONFIGURATION 0x4060 +#define EXYNOS5420_MFC_STATUS 0x4064 +#define EXYNOS5420_MFC_OPTION 0x4068 +#define EXYNOS5420_G3D_CONFIGURATION 0x4080 +#define EXYNOS5420_G3D_STATUS 0x4084 +#define EXYNOS5420_G3D_OPTION 0x4088 +#define EXYNOS5420_DISP0_CONFIGURATION 0x40A0 +#define EXYNOS5420_DISP0_STATUS 0x40A4 +#define EXYNOS5420_DISP0_OPTION 0x40A8 +#define EXYNOS5420_DISP1_CONFIGURATION 0x40C0 +#define EXYNOS5420_DISP1_STATUS 0x40C4 +#define EXYNOS5420_DISP1_OPTION 0x40C8 +#define EXYNOS5420_MAU_CONFIGURATION 0x40E0 +#define EXYNOS5420_MAU_STATUS 0x40E4 +#define EXYNOS5420_MAU_OPTION 0x40E8 +#define EXYNOS5420_FSYS2_OPTION 0x4168 +#define EXYNOS5420_PSGEN_OPTION 0x4188 + +/* For EXYNOS_CENTRAL_SEQ_OPTION */ +#define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 BIT(16) +#define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 BUT(17) +#define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 BIT(24) +#define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 BIT(25) + +#define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4) +#define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5) +#define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6) +#define EXYNOS5420_ARM_USE_STANDBY_WFI3 BIT(7) +#define EXYNOS5420_KFC_USE_STANDBY_WFI0 BIT(8) +#define EXYNOS5420_KFC_USE_STANDBY_WFI1 BIT(9) +#define EXYNOS5420_KFC_USE_STANDBY_WFI2 BIT(10) +#define EXYNOS5420_KFC_USE_STANDBY_WFI3 BIT(11) +#define EXYNOS5420_ARM_USE_STANDBY_WFE0 BIT(16) +#define EXYNOS5420_ARM_USE_STANDBY_WFE1 BIT(17) +#define EXYNOS5420_ARM_USE_STANDBY_WFE2 BIT(18) +#define EXYNOS5420_ARM_USE_STANDBY_WFE3 BIT(19) +#define EXYNOS5420_KFC_USE_STANDBY_WFE0 BIT(20) +#define EXYNOS5420_KFC_USE_STANDBY_WFE1 BIT(21) +#define EXYNOS5420_KFC_USE_STANDBY_WFE2 BIT(22) +#define EXYNOS5420_KFC_USE_STANDBY_WFE3 BIT(23) + +#define DUR_WAIT_RESET 0xF + +#define EXYNOS5420_USE_STANDBY_WFI_ALL (EXYNOS5420_ARM_USE_STANDBY_WFI0 \ + | EXYNOS5420_ARM_USE_STANDBY_WFI1 \ + | EXYNOS5420_ARM_USE_STANDBY_WFI2 \ + | EXYNOS5420_ARM_USE_STANDBY_WFI3 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI0 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI1 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI2 \ + | EXYNOS5420_KFC_USE_STANDBY_WFI3) + #endif /* __ASM_ARCH_REGS_PMU_H */ -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 2/3] arm: exynos5: Add Suspend-to-RAM support for 5420 2014-06-26 11:12 ` Vikas Sajjan @ 2014-06-26 11:12 ` Vikas Sajjan -1 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel, linux-samsung-soc Cc: kgene.kim, tomasz.figa, joshi, sajjan.linux, dianders, Abhilash Kesavan, Vikas Sajjan From: Abhilash Kesavan <a.kesavan@samsung.com> Adds Suspend-to-RAM support for EXYNOS5420 Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> --- arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index de61d48..bf8564a 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -38,9 +38,13 @@ #include "regs-pmu.h" #include "regs-sys.h" +#define EXYNOS5420_CPU_STATE 0x28 + #define pmu_raw_writel(val, offset) \ __raw_writel(val, pmu_base_addr + offset) +static int exynos5420_cpu_state; + /** * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping * @hwirq: Hardware IRQ signal of the GIC @@ -64,6 +68,10 @@ static struct sleep_save exynos_core_save[] = { SAVE_ITEM(S5P_SROM_BC3), }; +static struct sleep_save exynos5420_pmu_reg_save[] = { + SAVE_ITEM((void __iomem *)S5P_PMU_SPARE3), +}; + /* * GIC wake-up support */ @@ -86,7 +94,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) { const struct exynos_wkup_irq *wkup_irq; - if (soc_is_exynos5250()) + if (soc_is_exynos5250() || soc_is_exynos5420()) wkup_irq = exynos5250_wkup_irq; else wkup_irq = exynos4_wkup_irq; @@ -250,7 +258,16 @@ static int exynos_cpu_suspend(unsigned long arg) outer_flush_all(); #endif - if (soc_is_exynos5250()) + /* + * Clear sysram register for cpu state so that primary CPU does + * not enter low power start in U-Boot. + * This is specific to exynos5420 SoC only. + */ + if (soc_is_exynos5420()) + __raw_writel(0x0, + sysram_base_addr + EXYNOS5420_CPU_STATE); + + if (soc_is_exynos5250() || soc_is_exynos5420()) flush_cache_all(); /* issue the standby signal into the pm unit. */ @@ -276,6 +293,22 @@ static void exynos_pm_prepare(void) tmp = __raw_readl(pmu_base_addr + EXYNOS5_JPEG_MEM_OPTION); tmp &= ~EXYNOS5_OPTION_USE_RETENTION; pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); + } else if (soc_is_exynos5420()) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) + exynos5420_pmu_reg_save[i].val = + __raw_readl(pmu_base_addr + + (unsigned int)exynos5420_pmu_reg_save[i].reg); + /* + * The cpu state needs to be saved and restored so that the + * secondary CPUs will enter low power start. Though the U-Boot + * is setting the cpu state with low power flag, the kernel + * needs to restore it back in case, the primary cpu fails to + * suspend for any reason. + */ + exynos5420_cpu_state = + __raw_readl(sysram_base_addr + EXYNOS5420_CPU_STATE); } /* Set value of power down register for sleep mode */ @@ -286,6 +319,27 @@ static void exynos_pm_prepare(void) /* ensure at least INFORM0 has the resume address */ pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); + + if (soc_is_exynos5420()) { + tmp = __raw_readl(pmu_base_addr + EXYNOS5_ARM_L2_OPTION); + tmp &= ~EXYNOS5_USE_RETENTION; + pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); + + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); + tmp |= EXYNOS5420_UFS; + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); + + tmp = __raw_readl(pmu_base_addr + + EXYNOS5420_ARM_COMMON_OPTION); + tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; + pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); + tmp |= EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); + tmp |= EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); + } } static void exynos_pm_central_suspend(void) @@ -301,13 +355,24 @@ static void exynos_pm_central_suspend(void) static int exynos_pm_suspend(void) { unsigned long tmp; + unsigned int this_cluster; exynos_pm_central_suspend(); /* Setting SEQ_OPTION register */ - tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); - pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); + if (soc_is_exynos5420()) { + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); + if (!this_cluster) + pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, + S5P_CENTRAL_SEQ_OPTION); + else + pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, + S5P_CENTRAL_SEQ_OPTION); + } else { + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); + pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); + } if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) exynos_cpu_save_register(); @@ -340,6 +405,17 @@ static int exynos_pm_central_resume(void) static void exynos_pm_resume(void) { + unsigned int tmp; + + if (soc_is_exynos5420()) { + /* Restore the sysram cpu state register */ + __raw_writel(exynos5420_cpu_state, + sysram_base_addr + EXYNOS5420_CPU_STATE); + + pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, + S5P_CENTRAL_SEQ_OPTION); + } + if (exynos_pm_central_resume()) goto early_wakeup; @@ -347,18 +423,42 @@ static void exynos_pm_resume(void) exynos_cpu_restore_register(); /* For release retention */ + if (soc_is_exynos5420()) { + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_DRAM_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_MAUDIO_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_JTAG_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIA_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIB_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION); + pmu_raw_writel((1 << 28), + EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION); + } else { + pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); + } - pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); - - if (soc_is_exynos5250()) + if (soc_is_exynos5250()) { s3c_pm_do_restore(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); + } else if (soc_is_exynos5420()) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) + pmu_raw_writel( + (unsigned int)exynos5420_pmu_reg_save[i].val, + (unsigned int)exynos5420_pmu_reg_save[i].reg); + } s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); @@ -367,6 +467,18 @@ static void exynos_pm_resume(void) early_wakeup: + if (soc_is_exynos5420()) { + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); + tmp &= ~EXYNOS5420_UFS; + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); + tmp &= ~EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); + tmp &= ~EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); + } + /* Clear SLEEP mode set in INFORM1 */ pmu_raw_writel(0x0, S5P_INFORM1); @@ -483,9 +595,15 @@ void __init exynos_pm_init(void) gic_arch_extn.irq_set_wake = exynos_irq_set_wake; /* All wakeup disable */ - tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); - tmp |= ((0xFF << 8) | (0x1F << 1)); - pmu_raw_writel(tmp, S5P_WAKEUP_MASK); + if (soc_is_exynos5420()) { + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); + tmp |= ((0x7F << 7) | (0x1F << 1)); + pmu_raw_writel(tmp, S5P_WAKEUP_MASK); + } else { + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); + tmp |= ((0xFF << 8) | (0x1F << 1)); + pmu_raw_writel(tmp, S5P_WAKEUP_MASK); + } register_syscore_ops(&exynos_pm_syscore_ops); suspend_set_ops(&exynos_suspend_ops); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 2/3] arm: exynos5: Add Suspend-to-RAM support for 5420 @ 2014-06-26 11:12 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel From: Abhilash Kesavan <a.kesavan@samsung.com> Adds Suspend-to-RAM support for EXYNOS5420 Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> --- arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index de61d48..bf8564a 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -38,9 +38,13 @@ #include "regs-pmu.h" #include "regs-sys.h" +#define EXYNOS5420_CPU_STATE 0x28 + #define pmu_raw_writel(val, offset) \ __raw_writel(val, pmu_base_addr + offset) +static int exynos5420_cpu_state; + /** * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping * @hwirq: Hardware IRQ signal of the GIC @@ -64,6 +68,10 @@ static struct sleep_save exynos_core_save[] = { SAVE_ITEM(S5P_SROM_BC3), }; +static struct sleep_save exynos5420_pmu_reg_save[] = { + SAVE_ITEM((void __iomem *)S5P_PMU_SPARE3), +}; + /* * GIC wake-up support */ @@ -86,7 +94,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) { const struct exynos_wkup_irq *wkup_irq; - if (soc_is_exynos5250()) + if (soc_is_exynos5250() || soc_is_exynos5420()) wkup_irq = exynos5250_wkup_irq; else wkup_irq = exynos4_wkup_irq; @@ -250,7 +258,16 @@ static int exynos_cpu_suspend(unsigned long arg) outer_flush_all(); #endif - if (soc_is_exynos5250()) + /* + * Clear sysram register for cpu state so that primary CPU does + * not enter low power start in U-Boot. + * This is specific to exynos5420 SoC only. + */ + if (soc_is_exynos5420()) + __raw_writel(0x0, + sysram_base_addr + EXYNOS5420_CPU_STATE); + + if (soc_is_exynos5250() || soc_is_exynos5420()) flush_cache_all(); /* issue the standby signal into the pm unit. */ @@ -276,6 +293,22 @@ static void exynos_pm_prepare(void) tmp = __raw_readl(pmu_base_addr + EXYNOS5_JPEG_MEM_OPTION); tmp &= ~EXYNOS5_OPTION_USE_RETENTION; pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); + } else if (soc_is_exynos5420()) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) + exynos5420_pmu_reg_save[i].val = + __raw_readl(pmu_base_addr + + (unsigned int)exynos5420_pmu_reg_save[i].reg); + /* + * The cpu state needs to be saved and restored so that the + * secondary CPUs will enter low power start. Though the U-Boot + * is setting the cpu state with low power flag, the kernel + * needs to restore it back in case, the primary cpu fails to + * suspend for any reason. + */ + exynos5420_cpu_state = + __raw_readl(sysram_base_addr + EXYNOS5420_CPU_STATE); } /* Set value of power down register for sleep mode */ @@ -286,6 +319,27 @@ static void exynos_pm_prepare(void) /* ensure@least INFORM0 has the resume address */ pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); + + if (soc_is_exynos5420()) { + tmp = __raw_readl(pmu_base_addr + EXYNOS5_ARM_L2_OPTION); + tmp &= ~EXYNOS5_USE_RETENTION; + pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); + + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); + tmp |= EXYNOS5420_UFS; + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); + + tmp = __raw_readl(pmu_base_addr + + EXYNOS5420_ARM_COMMON_OPTION); + tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; + pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); + tmp |= EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); + tmp |= EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); + } } static void exynos_pm_central_suspend(void) @@ -301,13 +355,24 @@ static void exynos_pm_central_suspend(void) static int exynos_pm_suspend(void) { unsigned long tmp; + unsigned int this_cluster; exynos_pm_central_suspend(); /* Setting SEQ_OPTION register */ - tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); - pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); + if (soc_is_exynos5420()) { + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); + if (!this_cluster) + pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, + S5P_CENTRAL_SEQ_OPTION); + else + pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, + S5P_CENTRAL_SEQ_OPTION); + } else { + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); + pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); + } if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) exynos_cpu_save_register(); @@ -340,6 +405,17 @@ static int exynos_pm_central_resume(void) static void exynos_pm_resume(void) { + unsigned int tmp; + + if (soc_is_exynos5420()) { + /* Restore the sysram cpu state register */ + __raw_writel(exynos5420_cpu_state, + sysram_base_addr + EXYNOS5420_CPU_STATE); + + pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, + S5P_CENTRAL_SEQ_OPTION); + } + if (exynos_pm_central_resume()) goto early_wakeup; @@ -347,18 +423,42 @@ static void exynos_pm_resume(void) exynos_cpu_restore_register(); /* For release retention */ + if (soc_is_exynos5420()) { + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_DRAM_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_MAUDIO_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_JTAG_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIA_OPTION); + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIB_OPTION); + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION); + pmu_raw_writel((1 << 28), + EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION); + } else { + pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); + } - pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); - - if (soc_is_exynos5250()) + if (soc_is_exynos5250()) { s3c_pm_do_restore(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); + } else if (soc_is_exynos5420()) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) + pmu_raw_writel( + (unsigned int)exynos5420_pmu_reg_save[i].val, + (unsigned int)exynos5420_pmu_reg_save[i].reg); + } s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); @@ -367,6 +467,18 @@ static void exynos_pm_resume(void) early_wakeup: + if (soc_is_exynos5420()) { + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); + tmp &= ~EXYNOS5420_UFS; + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); + tmp &= ~EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); + tmp &= ~EXYNOS5420_EMULATION; + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); + } + /* Clear SLEEP mode set in INFORM1 */ pmu_raw_writel(0x0, S5P_INFORM1); @@ -483,9 +595,15 @@ void __init exynos_pm_init(void) gic_arch_extn.irq_set_wake = exynos_irq_set_wake; /* All wakeup disable */ - tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); - tmp |= ((0xFF << 8) | (0x1F << 1)); - pmu_raw_writel(tmp, S5P_WAKEUP_MASK); + if (soc_is_exynos5420()) { + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); + tmp |= ((0x7F << 7) | (0x1F << 1)); + pmu_raw_writel(tmp, S5P_WAKEUP_MASK); + } else { + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); + tmp |= ((0xFF << 8) | (0x1F << 1)); + pmu_raw_writel(tmp, S5P_WAKEUP_MASK); + } register_syscore_ops(&exynos_pm_syscore_ops); suspend_set_ops(&exynos_suspend_ops); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v5 2/3] arm: exynos5: Add Suspend-to-RAM support for 5420 2014-06-26 11:12 ` Vikas Sajjan @ 2014-06-30 17:57 ` Tomasz Figa -1 siblings, 0 replies; 20+ messages in thread From: Tomasz Figa @ 2014-06-30 17:57 UTC (permalink / raw) To: Vikas Sajjan, linux-arm-kernel, linux-samsung-soc Cc: kgene.kim, tomasz.figa, joshi, sajjan.linux, dianders, Abhilash Kesavan Hi Vikas, Abhilash, Please see my comments inline. On 26.06.2014 13:12, Vikas Sajjan wrote: > From: Abhilash Kesavan <a.kesavan@samsung.com> > > Adds Suspend-to-RAM support for EXYNOS5420 > > Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> > Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> > --- > arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 134 insertions(+), 16 deletions(-) > > diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c > index de61d48..bf8564a 100644 > --- a/arch/arm/mach-exynos/pm.c > +++ b/arch/arm/mach-exynos/pm.c > @@ -38,9 +38,13 @@ > #include "regs-pmu.h" > #include "regs-sys.h" > > +#define EXYNOS5420_CPU_STATE 0x28 > + > #define pmu_raw_writel(val, offset) \ > __raw_writel(val, pmu_base_addr + offset) > > +static int exynos5420_cpu_state; > + > /** > * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping > * @hwirq: Hardware IRQ signal of the GIC > @@ -64,6 +68,10 @@ static struct sleep_save exynos_core_save[] = { > SAVE_ITEM(S5P_SROM_BC3), > }; > > +static struct sleep_save exynos5420_pmu_reg_save[] = { > + SAVE_ITEM((void __iomem *)S5P_PMU_SPARE3), > +}; Do you need a whole array for this single register? > + > /* > * GIC wake-up support > */ > @@ -86,7 +94,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) > { > const struct exynos_wkup_irq *wkup_irq; > > - if (soc_is_exynos5250()) > + if (soc_is_exynos5250() || soc_is_exynos5420()) You should rework this to eliminate the need to use any SoC-specific checks. For example: 1) create a struct where any SoC/family specific data are stored, e.g. struct exynos_pm_data { const struct exynos_wkup_irq *wkup_irq; /* arrays, flags, values, function pointers, etc. */ }; 2) describe supported variants using instances of this struct, e.g. static const struct exynos_pm_data exynos5250_pm_data { .wkup_irq = exynos5250_wkup_irq, /* ... */ }; static const struct exynos_pm_data exynos5420_pm_data { .wkup_irq = exynos5250_wkup_irq, /* ... */ }; 3) put pointers to those structs in DT match table: static const struct of_device_id exynos_pm_matches[] = { { .compatible = "samsung,exynos5250-pmu", .data = &exynos5250_pm_data }, { .compatible = "samsung,exynos5420-pmu", .data = &exynos5420_pm_data }, }; 4) find a matching node in DT and use the struct pointed by match data. Also certain checks could probably be replaced with non-SoC-specific checks, e.g. by CPU part checks. > wkup_irq = exynos5250_wkup_irq; > else > wkup_irq = exynos4_wkup_irq; > @@ -250,7 +258,16 @@ static int exynos_cpu_suspend(unsigned long arg) > outer_flush_all(); > #endif > > - if (soc_is_exynos5250()) > + /* > + * Clear sysram register for cpu state so that primary CPU does > + * not enter low power start in U-Boot. > + * This is specific to exynos5420 SoC only. > + */ > + if (soc_is_exynos5420()) > + __raw_writel(0x0, > + sysram_base_addr + EXYNOS5420_CPU_STATE); > + > + if (soc_is_exynos5250() || soc_is_exynos5420()) This probably can be replaced with a check for Cortex A15 or A7. > flush_cache_all(); > > /* issue the standby signal into the pm unit. */ > @@ -276,6 +293,22 @@ static void exynos_pm_prepare(void) > tmp = __raw_readl(pmu_base_addr + EXYNOS5_JPEG_MEM_OPTION); > tmp &= ~EXYNOS5_OPTION_USE_RETENTION; > pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); > + } else if (soc_is_exynos5420()) { > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) > + exynos5420_pmu_reg_save[i].val = > + __raw_readl(pmu_base_addr + > + (unsigned int)exynos5420_pmu_reg_save[i].reg); > + /* > + * The cpu state needs to be saved and restored so that the > + * secondary CPUs will enter low power start. Though the U-Boot > + * is setting the cpu state with low power flag, the kernel > + * needs to restore it back in case, the primary cpu fails to > + * suspend for any reason. > + */ > + exynos5420_cpu_state = > + __raw_readl(sysram_base_addr + EXYNOS5420_CPU_STATE); > } > > /* Set value of power down register for sleep mode */ > @@ -286,6 +319,27 @@ static void exynos_pm_prepare(void) > /* ensure at least INFORM0 has the resume address */ > > pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); > + > + if (soc_is_exynos5420()) { > + tmp = __raw_readl(pmu_base_addr + EXYNOS5_ARM_L2_OPTION); > + tmp &= ~EXYNOS5_USE_RETENTION; > + pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); > + > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); > + tmp |= EXYNOS5420_UFS; > + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); > + > + tmp = __raw_readl(pmu_base_addr + > + EXYNOS5420_ARM_COMMON_OPTION); > + tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; > + pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); nit: A blank line here could improve readability. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); > + tmp |= EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); nit: A blank line here could improve readability. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); > + tmp |= EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); > + } > } > > static void exynos_pm_central_suspend(void) > @@ -301,13 +355,24 @@ static void exynos_pm_central_suspend(void) > static int exynos_pm_suspend(void) > { > unsigned long tmp; > + unsigned int this_cluster; nit: Two spaces between "int" and "this_cluster". Also it might be a better idea to use explicitly sized types with same size as register width. > > exynos_pm_central_suspend(); > > /* Setting SEQ_OPTION register */ > > - tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); > - pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); > + if (soc_is_exynos5420()) { I believe this is not Exynos5420-specific, but rather specific to any multi-cluster Exynos SoC. I think there might be a way to check the number of clusters. > + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); > + if (!this_cluster) > + pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, > + S5P_CENTRAL_SEQ_OPTION); > + else > + pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, > + S5P_CENTRAL_SEQ_OPTION); By the way, is it even possible to boot this SoC using other CPU than first Cortex A15? > + } else { > + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); > + pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); > + } > > if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) > exynos_cpu_save_register(); > @@ -340,6 +405,17 @@ static int exynos_pm_central_resume(void) > > static void exynos_pm_resume(void) > { > + unsigned int tmp; > + > + if (soc_is_exynos5420()) { > + /* Restore the sysram cpu state register */ > + __raw_writel(exynos5420_cpu_state, > + sysram_base_addr + EXYNOS5420_CPU_STATE); > + > + pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, > + S5P_CENTRAL_SEQ_OPTION); > + } > + > if (exynos_pm_central_resume()) > goto early_wakeup; > > @@ -347,18 +423,42 @@ static void exynos_pm_resume(void) > exynos_cpu_restore_register(); > > /* For release retention */ > + if (soc_is_exynos5420()) { > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_DRAM_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_MAUDIO_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_JTAG_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIA_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIB_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION); > + pmu_raw_writel((1 << 28), > + EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION); This could be replaced with an array of registers that is specified in the exynos_pm_data struct. Also while at it, the (1 << 28) could be replaced with proper macro. > + } else { > + pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); > + } > > - pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); > - > - if (soc_is_exynos5250()) > + if (soc_is_exynos5250()) { > s3c_pm_do_restore(exynos5_sys_save, > ARRAY_SIZE(exynos5_sys_save)); > + } else if (soc_is_exynos5420()) { > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) > + pmu_raw_writel( > + (unsigned int)exynos5420_pmu_reg_save[i].val, > + (unsigned int)exynos5420_pmu_reg_save[i].reg); > + } > > s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); > > @@ -367,6 +467,18 @@ static void exynos_pm_resume(void) > > early_wakeup: > > + if (soc_is_exynos5420()) { > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); > + tmp &= ~EXYNOS5420_UFS; > + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); nit: Spacing here would be nice. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); > + tmp &= ~EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); Ditto. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); > + tmp &= ~EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); > + } > + > /* Clear SLEEP mode set in INFORM1 */ > pmu_raw_writel(0x0, S5P_INFORM1); > > @@ -483,9 +595,15 @@ void __init exynos_pm_init(void) > gic_arch_extn.irq_set_wake = exynos_irq_set_wake; > > /* All wakeup disable */ > - tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); > - tmp |= ((0xFF << 8) | (0x1F << 1)); > - pmu_raw_writel(tmp, S5P_WAKEUP_MASK); > + if (soc_is_exynos5420()) { > + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); > + tmp |= ((0x7F << 7) | (0x1F << 1)); This mask could be also moved to the struct. Best regards, Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 2/3] arm: exynos5: Add Suspend-to-RAM support for 5420 @ 2014-06-30 17:57 ` Tomasz Figa 0 siblings, 0 replies; 20+ messages in thread From: Tomasz Figa @ 2014-06-30 17:57 UTC (permalink / raw) To: linux-arm-kernel Hi Vikas, Abhilash, Please see my comments inline. On 26.06.2014 13:12, Vikas Sajjan wrote: > From: Abhilash Kesavan <a.kesavan@samsung.com> > > Adds Suspend-to-RAM support for EXYNOS5420 > > Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> > Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> > --- > arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 134 insertions(+), 16 deletions(-) > > diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c > index de61d48..bf8564a 100644 > --- a/arch/arm/mach-exynos/pm.c > +++ b/arch/arm/mach-exynos/pm.c > @@ -38,9 +38,13 @@ > #include "regs-pmu.h" > #include "regs-sys.h" > > +#define EXYNOS5420_CPU_STATE 0x28 > + > #define pmu_raw_writel(val, offset) \ > __raw_writel(val, pmu_base_addr + offset) > > +static int exynos5420_cpu_state; > + > /** > * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping > * @hwirq: Hardware IRQ signal of the GIC > @@ -64,6 +68,10 @@ static struct sleep_save exynos_core_save[] = { > SAVE_ITEM(S5P_SROM_BC3), > }; > > +static struct sleep_save exynos5420_pmu_reg_save[] = { > + SAVE_ITEM((void __iomem *)S5P_PMU_SPARE3), > +}; Do you need a whole array for this single register? > + > /* > * GIC wake-up support > */ > @@ -86,7 +94,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) > { > const struct exynos_wkup_irq *wkup_irq; > > - if (soc_is_exynos5250()) > + if (soc_is_exynos5250() || soc_is_exynos5420()) You should rework this to eliminate the need to use any SoC-specific checks. For example: 1) create a struct where any SoC/family specific data are stored, e.g. struct exynos_pm_data { const struct exynos_wkup_irq *wkup_irq; /* arrays, flags, values, function pointers, etc. */ }; 2) describe supported variants using instances of this struct, e.g. static const struct exynos_pm_data exynos5250_pm_data { .wkup_irq = exynos5250_wkup_irq, /* ... */ }; static const struct exynos_pm_data exynos5420_pm_data { .wkup_irq = exynos5250_wkup_irq, /* ... */ }; 3) put pointers to those structs in DT match table: static const struct of_device_id exynos_pm_matches[] = { { .compatible = "samsung,exynos5250-pmu", .data = &exynos5250_pm_data }, { .compatible = "samsung,exynos5420-pmu", .data = &exynos5420_pm_data }, }; 4) find a matching node in DT and use the struct pointed by match data. Also certain checks could probably be replaced with non-SoC-specific checks, e.g. by CPU part checks. > wkup_irq = exynos5250_wkup_irq; > else > wkup_irq = exynos4_wkup_irq; > @@ -250,7 +258,16 @@ static int exynos_cpu_suspend(unsigned long arg) > outer_flush_all(); > #endif > > - if (soc_is_exynos5250()) > + /* > + * Clear sysram register for cpu state so that primary CPU does > + * not enter low power start in U-Boot. > + * This is specific to exynos5420 SoC only. > + */ > + if (soc_is_exynos5420()) > + __raw_writel(0x0, > + sysram_base_addr + EXYNOS5420_CPU_STATE); > + > + if (soc_is_exynos5250() || soc_is_exynos5420()) This probably can be replaced with a check for Cortex A15 or A7. > flush_cache_all(); > > /* issue the standby signal into the pm unit. */ > @@ -276,6 +293,22 @@ static void exynos_pm_prepare(void) > tmp = __raw_readl(pmu_base_addr + EXYNOS5_JPEG_MEM_OPTION); > tmp &= ~EXYNOS5_OPTION_USE_RETENTION; > pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); > + } else if (soc_is_exynos5420()) { > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) > + exynos5420_pmu_reg_save[i].val = > + __raw_readl(pmu_base_addr + > + (unsigned int)exynos5420_pmu_reg_save[i].reg); > + /* > + * The cpu state needs to be saved and restored so that the > + * secondary CPUs will enter low power start. Though the U-Boot > + * is setting the cpu state with low power flag, the kernel > + * needs to restore it back in case, the primary cpu fails to > + * suspend for any reason. > + */ > + exynos5420_cpu_state = > + __raw_readl(sysram_base_addr + EXYNOS5420_CPU_STATE); > } > > /* Set value of power down register for sleep mode */ > @@ -286,6 +319,27 @@ static void exynos_pm_prepare(void) > /* ensure at least INFORM0 has the resume address */ > > pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); > + > + if (soc_is_exynos5420()) { > + tmp = __raw_readl(pmu_base_addr + EXYNOS5_ARM_L2_OPTION); > + tmp &= ~EXYNOS5_USE_RETENTION; > + pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); > + > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); > + tmp |= EXYNOS5420_UFS; > + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); > + > + tmp = __raw_readl(pmu_base_addr + > + EXYNOS5420_ARM_COMMON_OPTION); > + tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; > + pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); nit: A blank line here could improve readability. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); > + tmp |= EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); nit: A blank line here could improve readability. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); > + tmp |= EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); > + } > } > > static void exynos_pm_central_suspend(void) > @@ -301,13 +355,24 @@ static void exynos_pm_central_suspend(void) > static int exynos_pm_suspend(void) > { > unsigned long tmp; > + unsigned int this_cluster; nit: Two spaces between "int" and "this_cluster". Also it might be a better idea to use explicitly sized types with same size as register width. > > exynos_pm_central_suspend(); > > /* Setting SEQ_OPTION register */ > > - tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); > - pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); > + if (soc_is_exynos5420()) { I believe this is not Exynos5420-specific, but rather specific to any multi-cluster Exynos SoC. I think there might be a way to check the number of clusters. > + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); > + if (!this_cluster) > + pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, > + S5P_CENTRAL_SEQ_OPTION); > + else > + pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, > + S5P_CENTRAL_SEQ_OPTION); By the way, is it even possible to boot this SoC using other CPU than first Cortex A15? > + } else { > + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); > + pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); > + } > > if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) > exynos_cpu_save_register(); > @@ -340,6 +405,17 @@ static int exynos_pm_central_resume(void) > > static void exynos_pm_resume(void) > { > + unsigned int tmp; > + > + if (soc_is_exynos5420()) { > + /* Restore the sysram cpu state register */ > + __raw_writel(exynos5420_cpu_state, > + sysram_base_addr + EXYNOS5420_CPU_STATE); > + > + pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, > + S5P_CENTRAL_SEQ_OPTION); > + } > + > if (exynos_pm_central_resume()) > goto early_wakeup; > > @@ -347,18 +423,42 @@ static void exynos_pm_resume(void) > exynos_cpu_restore_register(); > > /* For release retention */ > + if (soc_is_exynos5420()) { > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_DRAM_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_MAUDIO_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_JTAG_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIA_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIB_OPTION); > + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION); > + pmu_raw_writel((1 << 28), > + EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION); This could be replaced with an array of registers that is specified in the exynos_pm_data struct. Also while at it, the (1 << 28) could be replaced with proper macro. > + } else { > + pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); > + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); > + } > > - pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); > - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); > - > - if (soc_is_exynos5250()) > + if (soc_is_exynos5250()) { > s3c_pm_do_restore(exynos5_sys_save, > ARRAY_SIZE(exynos5_sys_save)); > + } else if (soc_is_exynos5420()) { > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) > + pmu_raw_writel( > + (unsigned int)exynos5420_pmu_reg_save[i].val, > + (unsigned int)exynos5420_pmu_reg_save[i].reg); > + } > > s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); > > @@ -367,6 +467,18 @@ static void exynos_pm_resume(void) > > early_wakeup: > > + if (soc_is_exynos5420()) { > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); > + tmp &= ~EXYNOS5420_UFS; > + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); nit: Spacing here would be nice. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); > + tmp &= ~EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); Ditto. > + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); > + tmp &= ~EXYNOS5420_EMULATION; > + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); > + } > + > /* Clear SLEEP mode set in INFORM1 */ > pmu_raw_writel(0x0, S5P_INFORM1); > > @@ -483,9 +595,15 @@ void __init exynos_pm_init(void) > gic_arch_extn.irq_set_wake = exynos_irq_set_wake; > > /* All wakeup disable */ > - tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); > - tmp |= ((0xFF << 8) | (0x1F << 1)); > - pmu_raw_writel(tmp, S5P_WAKEUP_MASK); > + if (soc_is_exynos5420()) { > + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); > + tmp |= ((0x7F << 7) | (0x1F << 1)); This mask could be also moved to the struct. Best regards, Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 2/3] arm: exynos5: Add Suspend-to-RAM support for 5420 2014-06-30 17:57 ` Tomasz Figa @ 2014-07-01 13:47 ` Vikas Sajjan -1 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-07-01 13:47 UTC (permalink / raw) To: Tomasz Figa Cc: linux-arm-kernel, linux-samsung-soc, Kukjin Kim, Tomasz Figa, sunil joshi, Doug Anderson, Abhilash Kesavan Hi Tomasz, On Mon, Jun 30, 2014 at 11:27 PM, Tomasz Figa <t.figa@samsung.com> wrote: > Hi Vikas, Abhilash, > > Please see my comments inline. > > On 26.06.2014 13:12, Vikas Sajjan wrote: >> From: Abhilash Kesavan <a.kesavan@samsung.com> >> >> Adds Suspend-to-RAM support for EXYNOS5420 >> >> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >> --- >> arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- >> 1 file changed, 134 insertions(+), 16 deletions(-) >> >> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c >> index de61d48..bf8564a 100644 >> --- a/arch/arm/mach-exynos/pm.c >> +++ b/arch/arm/mach-exynos/pm.c >> @@ -38,9 +38,13 @@ >> #include "regs-pmu.h" >> #include "regs-sys.h" >> >> +#define EXYNOS5420_CPU_STATE 0x28 >> + >> #define pmu_raw_writel(val, offset) \ >> __raw_writel(val, pmu_base_addr + offset) >> >> +static int exynos5420_cpu_state; >> + >> /** >> * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping >> * @hwirq: Hardware IRQ signal of the GIC >> @@ -64,6 +68,10 @@ static struct sleep_save exynos_core_save[] = { >> SAVE_ITEM(S5P_SROM_BC3), >> }; >> >> +static struct sleep_save exynos5420_pmu_reg_save[] = { >> + SAVE_ITEM((void __iomem *)S5P_PMU_SPARE3), >> +}; > > Do you need a whole array for this single register? > >> + >> /* >> * GIC wake-up support >> */ >> @@ -86,7 +94,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) >> { >> const struct exynos_wkup_irq *wkup_irq; >> >> - if (soc_is_exynos5250()) >> + if (soc_is_exynos5250() || soc_is_exynos5420()) > > You should rework this to eliminate the need to use any SoC-specific > checks. For example: > > 1) create a struct where any SoC/family specific data are stored, e.g. > > struct exynos_pm_data { > const struct exynos_wkup_irq *wkup_irq; > /* arrays, flags, values, function pointers, etc. */ > }; > > 2) describe supported variants using instances of this struct, e.g. > > static const struct exynos_pm_data exynos5250_pm_data { > .wkup_irq = exynos5250_wkup_irq, > /* ... */ > }; > > static const struct exynos_pm_data exynos5420_pm_data { > .wkup_irq = exynos5250_wkup_irq, > /* ... */ > }; > > 3) put pointers to those structs in DT match table: > > static const struct of_device_id exynos_pm_matches[] = { > { .compatible = "samsung,exynos5250-pmu", > .data = &exynos5250_pm_data }, > { .compatible = "samsung,exynos5420-pmu", > .data = &exynos5420_pm_data }, > }; > > 4) find a matching node in DT and use the struct pointed by match data. > > Also certain checks could probably be replaced with non-SoC-specific > checks, e.g. by CPU part checks. > >> wkup_irq = exynos5250_wkup_irq; >> else >> wkup_irq = exynos4_wkup_irq; >> @@ -250,7 +258,16 @@ static int exynos_cpu_suspend(unsigned long arg) >> outer_flush_all(); >> #endif >> >> - if (soc_is_exynos5250()) >> + /* >> + * Clear sysram register for cpu state so that primary CPU does >> + * not enter low power start in U-Boot. >> + * This is specific to exynos5420 SoC only. >> + */ >> + if (soc_is_exynos5420()) >> + __raw_writel(0x0, >> + sysram_base_addr + EXYNOS5420_CPU_STATE); >> + >> + if (soc_is_exynos5250() || soc_is_exynos5420()) > > This probably can be replaced with a check for Cortex A15 or A7. > >> flush_cache_all(); >> >> /* issue the standby signal into the pm unit. */ >> @@ -276,6 +293,22 @@ static void exynos_pm_prepare(void) >> tmp = __raw_readl(pmu_base_addr + EXYNOS5_JPEG_MEM_OPTION); >> tmp &= ~EXYNOS5_OPTION_USE_RETENTION; >> pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); >> + } else if (soc_is_exynos5420()) { >> + unsigned int i; I have a question here. I can come up with a function like exynos5420_pm_prepare(), which does the same as the code under this if condition. call it here like below, static void exynos_pm_prepare(void) { /* common to all SoCs */ ...... ..... ...... /* specific to given SoC */ exynos_pm_data->pm_prepare(); ........ ....... ....... } but at line -286,6 +319,27 @@ static void exynos_pm_prepare(void) also we have something specific to 5420. how do we handle such cases. Because in future there may be new a SoC which does SoC specific things at 3 different location in same function exynos_pm_prepare(). This will also apply to function like exynos_pm_suspend() exynos_pm_resume() etc., >> + >> + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) >> + exynos5420_pmu_reg_save[i].val = >> + __raw_readl(pmu_base_addr + >> + (unsigned int)exynos5420_pmu_reg_save[i].reg); >> + /* >> + * The cpu state needs to be saved and restored so that the >> + * secondary CPUs will enter low power start. Though the U-Boot >> + * is setting the cpu state with low power flag, the kernel >> + * needs to restore it back in case, the primary cpu fails to >> + * suspend for any reason. >> + */ >> + exynos5420_cpu_state = >> + __raw_readl(sysram_base_addr + EXYNOS5420_CPU_STATE); >> } >> >> /* Set value of power down register for sleep mode */ >> @@ -286,6 +319,27 @@ static void exynos_pm_prepare(void) >> /* ensure at least INFORM0 has the resume address */ >> >> pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); >> + >> + if (soc_is_exynos5420()) { >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5_ARM_L2_OPTION); >> + tmp &= ~EXYNOS5_USE_RETENTION; >> + pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); >> + >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); >> + tmp |= EXYNOS5420_UFS; >> + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); >> + >> + tmp = __raw_readl(pmu_base_addr + >> + EXYNOS5420_ARM_COMMON_OPTION); >> + tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; >> + pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); > > nit: A blank line here could improve readability. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); >> + tmp |= EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); > > nit: A blank line here could improve readability. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); >> + tmp |= EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); >> + } >> } >> >> static void exynos_pm_central_suspend(void) >> @@ -301,13 +355,24 @@ static void exynos_pm_central_suspend(void) >> static int exynos_pm_suspend(void) >> { >> unsigned long tmp; >> + unsigned int this_cluster; > > nit: Two spaces between "int" and "this_cluster". Also it might be a > better idea to use explicitly sized types with same size as register width. > >> >> exynos_pm_central_suspend(); >> >> /* Setting SEQ_OPTION register */ >> >> - tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); >> - pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); >> + if (soc_is_exynos5420()) { > > I believe this is not Exynos5420-specific, but rather specific to any > multi-cluster Exynos SoC. I think there might be a way to check the > number of clusters. > >> + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); >> + if (!this_cluster) >> + pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, >> + S5P_CENTRAL_SEQ_OPTION); >> + else >> + pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, >> + S5P_CENTRAL_SEQ_OPTION); > > By the way, is it even possible to boot this SoC using other CPU than > first Cortex A15? > >> + } else { >> + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); >> + pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); >> + } >> >> if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) >> exynos_cpu_save_register(); >> @@ -340,6 +405,17 @@ static int exynos_pm_central_resume(void) >> >> static void exynos_pm_resume(void) >> { >> + unsigned int tmp; >> + >> + if (soc_is_exynos5420()) { >> + /* Restore the sysram cpu state register */ >> + __raw_writel(exynos5420_cpu_state, >> + sysram_base_addr + EXYNOS5420_CPU_STATE); >> + >> + pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, >> + S5P_CENTRAL_SEQ_OPTION); >> + } >> + >> if (exynos_pm_central_resume()) >> goto early_wakeup; >> >> @@ -347,18 +423,42 @@ static void exynos_pm_resume(void) >> exynos_cpu_restore_register(); >> >> /* For release retention */ >> + if (soc_is_exynos5420()) { >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_DRAM_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_MAUDIO_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_JTAG_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIA_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIB_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION); >> + pmu_raw_writel((1 << 28), >> + EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION); > > This could be replaced with an array of registers that is specified in > the exynos_pm_data struct. Also while at it, the (1 << 28) could be > replaced with proper macro. > >> + } else { >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); >> + } >> >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); >> - >> - if (soc_is_exynos5250()) >> + if (soc_is_exynos5250()) { >> s3c_pm_do_restore(exynos5_sys_save, >> ARRAY_SIZE(exynos5_sys_save)); >> + } else if (soc_is_exynos5420()) { >> + unsigned int i; >> + >> + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) >> + pmu_raw_writel( >> + (unsigned int)exynos5420_pmu_reg_save[i].val, >> + (unsigned int)exynos5420_pmu_reg_save[i].reg); >> + } >> >> s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); >> >> @@ -367,6 +467,18 @@ static void exynos_pm_resume(void) >> >> early_wakeup: >> >> + if (soc_is_exynos5420()) { >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); >> + tmp &= ~EXYNOS5420_UFS; >> + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); > > nit: Spacing here would be nice. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); >> + tmp &= ~EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); > > Ditto. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); >> + tmp &= ~EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); >> + } >> + >> /* Clear SLEEP mode set in INFORM1 */ >> pmu_raw_writel(0x0, S5P_INFORM1); >> >> @@ -483,9 +595,15 @@ void __init exynos_pm_init(void) >> gic_arch_extn.irq_set_wake = exynos_irq_set_wake; >> >> /* All wakeup disable */ >> - tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); >> - tmp |= ((0xFF << 8) | (0x1F << 1)); >> - pmu_raw_writel(tmp, S5P_WAKEUP_MASK); >> + if (soc_is_exynos5420()) { >> + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); >> + tmp |= ((0x7F << 7) | (0x1F << 1)); > > This mask could be also moved to the struct. > > Best regards, > Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 2/3] arm: exynos5: Add Suspend-to-RAM support for 5420 @ 2014-07-01 13:47 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-07-01 13:47 UTC (permalink / raw) To: linux-arm-kernel Hi Tomasz, On Mon, Jun 30, 2014 at 11:27 PM, Tomasz Figa <t.figa@samsung.com> wrote: > Hi Vikas, Abhilash, > > Please see my comments inline. > > On 26.06.2014 13:12, Vikas Sajjan wrote: >> From: Abhilash Kesavan <a.kesavan@samsung.com> >> >> Adds Suspend-to-RAM support for EXYNOS5420 >> >> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >> --- >> arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- >> 1 file changed, 134 insertions(+), 16 deletions(-) >> >> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c >> index de61d48..bf8564a 100644 >> --- a/arch/arm/mach-exynos/pm.c >> +++ b/arch/arm/mach-exynos/pm.c >> @@ -38,9 +38,13 @@ >> #include "regs-pmu.h" >> #include "regs-sys.h" >> >> +#define EXYNOS5420_CPU_STATE 0x28 >> + >> #define pmu_raw_writel(val, offset) \ >> __raw_writel(val, pmu_base_addr + offset) >> >> +static int exynos5420_cpu_state; >> + >> /** >> * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping >> * @hwirq: Hardware IRQ signal of the GIC >> @@ -64,6 +68,10 @@ static struct sleep_save exynos_core_save[] = { >> SAVE_ITEM(S5P_SROM_BC3), >> }; >> >> +static struct sleep_save exynos5420_pmu_reg_save[] = { >> + SAVE_ITEM((void __iomem *)S5P_PMU_SPARE3), >> +}; > > Do you need a whole array for this single register? > >> + >> /* >> * GIC wake-up support >> */ >> @@ -86,7 +94,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) >> { >> const struct exynos_wkup_irq *wkup_irq; >> >> - if (soc_is_exynos5250()) >> + if (soc_is_exynos5250() || soc_is_exynos5420()) > > You should rework this to eliminate the need to use any SoC-specific > checks. For example: > > 1) create a struct where any SoC/family specific data are stored, e.g. > > struct exynos_pm_data { > const struct exynos_wkup_irq *wkup_irq; > /* arrays, flags, values, function pointers, etc. */ > }; > > 2) describe supported variants using instances of this struct, e.g. > > static const struct exynos_pm_data exynos5250_pm_data { > .wkup_irq = exynos5250_wkup_irq, > /* ... */ > }; > > static const struct exynos_pm_data exynos5420_pm_data { > .wkup_irq = exynos5250_wkup_irq, > /* ... */ > }; > > 3) put pointers to those structs in DT match table: > > static const struct of_device_id exynos_pm_matches[] = { > { .compatible = "samsung,exynos5250-pmu", > .data = &exynos5250_pm_data }, > { .compatible = "samsung,exynos5420-pmu", > .data = &exynos5420_pm_data }, > }; > > 4) find a matching node in DT and use the struct pointed by match data. > > Also certain checks could probably be replaced with non-SoC-specific > checks, e.g. by CPU part checks. > >> wkup_irq = exynos5250_wkup_irq; >> else >> wkup_irq = exynos4_wkup_irq; >> @@ -250,7 +258,16 @@ static int exynos_cpu_suspend(unsigned long arg) >> outer_flush_all(); >> #endif >> >> - if (soc_is_exynos5250()) >> + /* >> + * Clear sysram register for cpu state so that primary CPU does >> + * not enter low power start in U-Boot. >> + * This is specific to exynos5420 SoC only. >> + */ >> + if (soc_is_exynos5420()) >> + __raw_writel(0x0, >> + sysram_base_addr + EXYNOS5420_CPU_STATE); >> + >> + if (soc_is_exynos5250() || soc_is_exynos5420()) > > This probably can be replaced with a check for Cortex A15 or A7. > >> flush_cache_all(); >> >> /* issue the standby signal into the pm unit. */ >> @@ -276,6 +293,22 @@ static void exynos_pm_prepare(void) >> tmp = __raw_readl(pmu_base_addr + EXYNOS5_JPEG_MEM_OPTION); >> tmp &= ~EXYNOS5_OPTION_USE_RETENTION; >> pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); >> + } else if (soc_is_exynos5420()) { >> + unsigned int i; I have a question here. I can come up with a function like exynos5420_pm_prepare(), which does the same as the code under this if condition. call it here like below, static void exynos_pm_prepare(void) { /* common to all SoCs */ ...... ..... ...... /* specific to given SoC */ exynos_pm_data->pm_prepare(); ........ ....... ....... } but at line -286,6 +319,27 @@ static void exynos_pm_prepare(void) also we have something specific to 5420. how do we handle such cases. Because in future there may be new a SoC which does SoC specific things at 3 different location in same function exynos_pm_prepare(). This will also apply to function like exynos_pm_suspend() exynos_pm_resume() etc., >> + >> + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) >> + exynos5420_pmu_reg_save[i].val = >> + __raw_readl(pmu_base_addr + >> + (unsigned int)exynos5420_pmu_reg_save[i].reg); >> + /* >> + * The cpu state needs to be saved and restored so that the >> + * secondary CPUs will enter low power start. Though the U-Boot >> + * is setting the cpu state with low power flag, the kernel >> + * needs to restore it back in case, the primary cpu fails to >> + * suspend for any reason. >> + */ >> + exynos5420_cpu_state = >> + __raw_readl(sysram_base_addr + EXYNOS5420_CPU_STATE); >> } >> >> /* Set value of power down register for sleep mode */ >> @@ -286,6 +319,27 @@ static void exynos_pm_prepare(void) >> /* ensure at least INFORM0 has the resume address */ >> >> pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); >> + >> + if (soc_is_exynos5420()) { >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5_ARM_L2_OPTION); >> + tmp &= ~EXYNOS5_USE_RETENTION; >> + pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); >> + >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); >> + tmp |= EXYNOS5420_UFS; >> + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); >> + >> + tmp = __raw_readl(pmu_base_addr + >> + EXYNOS5420_ARM_COMMON_OPTION); >> + tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; >> + pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); > > nit: A blank line here could improve readability. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); >> + tmp |= EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); > > nit: A blank line here could improve readability. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); >> + tmp |= EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); >> + } >> } >> >> static void exynos_pm_central_suspend(void) >> @@ -301,13 +355,24 @@ static void exynos_pm_central_suspend(void) >> static int exynos_pm_suspend(void) >> { >> unsigned long tmp; >> + unsigned int this_cluster; > > nit: Two spaces between "int" and "this_cluster". Also it might be a > better idea to use explicitly sized types with same size as register width. > >> >> exynos_pm_central_suspend(); >> >> /* Setting SEQ_OPTION register */ >> >> - tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); >> - pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); >> + if (soc_is_exynos5420()) { > > I believe this is not Exynos5420-specific, but rather specific to any > multi-cluster Exynos SoC. I think there might be a way to check the > number of clusters. > >> + this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); >> + if (!this_cluster) >> + pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, >> + S5P_CENTRAL_SEQ_OPTION); >> + else >> + pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, >> + S5P_CENTRAL_SEQ_OPTION); > > By the way, is it even possible to boot this SoC using other CPU than > first Cortex A15? > >> + } else { >> + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); >> + pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); >> + } >> >> if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) >> exynos_cpu_save_register(); >> @@ -340,6 +405,17 @@ static int exynos_pm_central_resume(void) >> >> static void exynos_pm_resume(void) >> { >> + unsigned int tmp; >> + >> + if (soc_is_exynos5420()) { >> + /* Restore the sysram cpu state register */ >> + __raw_writel(exynos5420_cpu_state, >> + sysram_base_addr + EXYNOS5420_CPU_STATE); >> + >> + pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, >> + S5P_CENTRAL_SEQ_OPTION); >> + } >> + >> if (exynos_pm_central_resume()) >> goto early_wakeup; >> >> @@ -347,18 +423,42 @@ static void exynos_pm_resume(void) >> exynos_cpu_restore_register(); >> >> /* For release retention */ >> + if (soc_is_exynos5420()) { >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_DRAM_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_MAUDIO_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_JTAG_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIA_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS_PAD_RET_EBIB_OPTION); >> + pmu_raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION); >> + pmu_raw_writel((1 << 28), >> + EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION); > > This could be replaced with an array of registers that is specified in > the exynos_pm_data struct. Also while at it, the (1 << 28) could be > replaced with proper macro. > >> + } else { >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); >> + pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); >> + } >> >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); >> - pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); >> - >> - if (soc_is_exynos5250()) >> + if (soc_is_exynos5250()) { >> s3c_pm_do_restore(exynos5_sys_save, >> ARRAY_SIZE(exynos5_sys_save)); >> + } else if (soc_is_exynos5420()) { >> + unsigned int i; >> + >> + for (i = 0; i < ARRAY_SIZE(exynos5420_pmu_reg_save); i++) >> + pmu_raw_writel( >> + (unsigned int)exynos5420_pmu_reg_save[i].val, >> + (unsigned int)exynos5420_pmu_reg_save[i].reg); >> + } >> >> s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); >> >> @@ -367,6 +467,18 @@ static void exynos_pm_resume(void) >> >> early_wakeup: >> >> + if (soc_is_exynos5420()) { >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_SFR_AXI_CGDIS1); >> + tmp &= ~EXYNOS5420_UFS; >> + pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); > > nit: Spacing here would be nice. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_FSYS2_OPTION); >> + tmp &= ~EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION); > > Ditto. > >> + tmp = __raw_readl(pmu_base_addr + EXYNOS5420_PSGEN_OPTION); >> + tmp &= ~EXYNOS5420_EMULATION; >> + pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION); >> + } >> + >> /* Clear SLEEP mode set in INFORM1 */ >> pmu_raw_writel(0x0, S5P_INFORM1); >> >> @@ -483,9 +595,15 @@ void __init exynos_pm_init(void) >> gic_arch_extn.irq_set_wake = exynos_irq_set_wake; >> >> /* All wakeup disable */ >> - tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); >> - tmp |= ((0xFF << 8) | (0x1F << 1)); >> - pmu_raw_writel(tmp, S5P_WAKEUP_MASK); >> + if (soc_is_exynos5420()) { >> + tmp = __raw_readl(pmu_base_addr + S5P_WAKEUP_MASK); >> + tmp |= ((0x7F << 7) | (0x1F << 1)); > > This mask could be also moved to the struct. > > Best regards, > Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend 2014-06-26 11:12 ` Vikas Sajjan @ 2014-06-26 11:12 ` Vikas Sajjan -1 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel, linux-samsung-soc Cc: kgene.kim, tomasz.figa, joshi, sajjan.linux, dianders, Vikas Sajjan, Abhilash Kesavan Prior to suspending the system, we need to ensure that certain clock source and gate registers are unmasked. while at it, add these clks to save/restore list also. Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> --- drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 9d7d7ee..7e87d7c 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -28,6 +28,7 @@ #define GATE_BUS_CPU 0x700 #define GATE_SCLK_CPU 0x800 #define CLKOUT_CMU_CPU 0xa00 +#define SRC_MASK_CPERI 0x4300 #define GATE_IP_G2D 0x8800 #define CPLL_LOCK 0x10020 #define DPLL_LOCK 0x10030 @@ -70,6 +71,8 @@ #define SRC_TOP11 0x10284 #define SRC_TOP12 0x10288 #define SRC_TOP13 0x1028c /* 5800 specific */ +#define SRC_MASK_TOP0 0x10300 +#define SRC_MASK_TOP1 0x10304 #define SRC_MASK_TOP2 0x10308 #define SRC_MASK_TOP7 0x1031c #define SRC_MASK_DISP10 0x1032c @@ -77,6 +80,7 @@ #define SRC_MASK_FSYS 0x10340 #define SRC_MASK_PERIC0 0x10350 #define SRC_MASK_PERIC1 0x10354 +#define SRC_MASK_ISP 0x10370 #define DIV_TOP0 0x10500 #define DIV_TOP1 0x10504 #define DIV_TOP2 0x10508 @@ -98,6 +102,7 @@ #define DIV2_RATIO0 0x10590 #define DIV4_RATIO 0x105a0 #define GATE_BUS_TOP 0x10700 +#define GATE_BUS_DISP1 0x10728 #define GATE_BUS_GEN 0x1073c #define GATE_BUS_FSYS0 0x10740 #define GATE_BUS_FSYS2 0x10748 @@ -190,6 +195,10 @@ static unsigned long exynos5x_clk_regs[] __initdata = { SRC_MASK_FSYS, SRC_MASK_PERIC0, SRC_MASK_PERIC1, + SRC_MASK_TOP0, + SRC_MASK_TOP1, + SRC_MASK_MAU, + SRC_MASK_ISP, SRC_ISP, DIV_TOP0, DIV_TOP1, @@ -208,6 +217,7 @@ static unsigned long exynos5x_clk_regs[] __initdata = { SCLK_DIV_ISP1, DIV2_RATIO0, DIV4_RATIO, + GATE_BUS_DISP1, GATE_BUS_TOP, GATE_BUS_GEN, GATE_BUS_FSYS0, @@ -249,6 +259,22 @@ static unsigned long exynos5800_clk_regs[] __initdata = { GATE_IP_CAM, }; +static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = { + { .offset = SRC_MASK_CPERI, .value = 0xffffffff, }, + { .offset = SRC_MASK_TOP0, .value = 0x11111111, }, + { .offset = SRC_MASK_TOP1, .value = 0x11101111, }, + { .offset = SRC_MASK_TOP2, .value = 0x11111110, }, + { .offset = SRC_MASK_TOP7, .value = 0x00111100, }, + { .offset = SRC_MASK_DISP10, .value = 0x11111110, }, + { .offset = SRC_MASK_MAU, .value = 0x10000000, }, + { .offset = SRC_MASK_FSYS, .value = 0x11111110, }, + { .offset = SRC_MASK_PERIC0, .value = 0x11111110, }, + { .offset = SRC_MASK_PERIC1, .value = 0x11111100, }, + { .offset = SRC_MASK_ISP, .value = 0x11111000, }, + { .offset = GATE_BUS_DISP1, .value = 0xffffffff, }, + { .offset = GATE_IP_PERIC, .value = 0xffffffff, }, +}; + static int exynos5420_clk_suspend(void) { samsung_clk_save(reg_base, exynos5x_save, @@ -258,6 +284,9 @@ static int exynos5420_clk_suspend(void) samsung_clk_save(reg_base, exynos5800_save, ARRAY_SIZE(exynos5800_clk_regs)); + samsung_clk_restore(reg_base, exynos5420_set_clksrc, + ARRAY_SIZE(exynos5420_set_clksrc)); + return 0; } -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend @ 2014-06-26 11:12 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-06-26 11:12 UTC (permalink / raw) To: linux-arm-kernel Prior to suspending the system, we need to ensure that certain clock source and gate registers are unmasked. while at it, add these clks to save/restore list also. Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> --- drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 9d7d7ee..7e87d7c 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -28,6 +28,7 @@ #define GATE_BUS_CPU 0x700 #define GATE_SCLK_CPU 0x800 #define CLKOUT_CMU_CPU 0xa00 +#define SRC_MASK_CPERI 0x4300 #define GATE_IP_G2D 0x8800 #define CPLL_LOCK 0x10020 #define DPLL_LOCK 0x10030 @@ -70,6 +71,8 @@ #define SRC_TOP11 0x10284 #define SRC_TOP12 0x10288 #define SRC_TOP13 0x1028c /* 5800 specific */ +#define SRC_MASK_TOP0 0x10300 +#define SRC_MASK_TOP1 0x10304 #define SRC_MASK_TOP2 0x10308 #define SRC_MASK_TOP7 0x1031c #define SRC_MASK_DISP10 0x1032c @@ -77,6 +80,7 @@ #define SRC_MASK_FSYS 0x10340 #define SRC_MASK_PERIC0 0x10350 #define SRC_MASK_PERIC1 0x10354 +#define SRC_MASK_ISP 0x10370 #define DIV_TOP0 0x10500 #define DIV_TOP1 0x10504 #define DIV_TOP2 0x10508 @@ -98,6 +102,7 @@ #define DIV2_RATIO0 0x10590 #define DIV4_RATIO 0x105a0 #define GATE_BUS_TOP 0x10700 +#define GATE_BUS_DISP1 0x10728 #define GATE_BUS_GEN 0x1073c #define GATE_BUS_FSYS0 0x10740 #define GATE_BUS_FSYS2 0x10748 @@ -190,6 +195,10 @@ static unsigned long exynos5x_clk_regs[] __initdata = { SRC_MASK_FSYS, SRC_MASK_PERIC0, SRC_MASK_PERIC1, + SRC_MASK_TOP0, + SRC_MASK_TOP1, + SRC_MASK_MAU, + SRC_MASK_ISP, SRC_ISP, DIV_TOP0, DIV_TOP1, @@ -208,6 +217,7 @@ static unsigned long exynos5x_clk_regs[] __initdata = { SCLK_DIV_ISP1, DIV2_RATIO0, DIV4_RATIO, + GATE_BUS_DISP1, GATE_BUS_TOP, GATE_BUS_GEN, GATE_BUS_FSYS0, @@ -249,6 +259,22 @@ static unsigned long exynos5800_clk_regs[] __initdata = { GATE_IP_CAM, }; +static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = { + { .offset = SRC_MASK_CPERI, .value = 0xffffffff, }, + { .offset = SRC_MASK_TOP0, .value = 0x11111111, }, + { .offset = SRC_MASK_TOP1, .value = 0x11101111, }, + { .offset = SRC_MASK_TOP2, .value = 0x11111110, }, + { .offset = SRC_MASK_TOP7, .value = 0x00111100, }, + { .offset = SRC_MASK_DISP10, .value = 0x11111110, }, + { .offset = SRC_MASK_MAU, .value = 0x10000000, }, + { .offset = SRC_MASK_FSYS, .value = 0x11111110, }, + { .offset = SRC_MASK_PERIC0, .value = 0x11111110, }, + { .offset = SRC_MASK_PERIC1, .value = 0x11111100, }, + { .offset = SRC_MASK_ISP, .value = 0x11111000, }, + { .offset = GATE_BUS_DISP1, .value = 0xffffffff, }, + { .offset = GATE_IP_PERIC, .value = 0xffffffff, }, +}; + static int exynos5420_clk_suspend(void) { samsung_clk_save(reg_base, exynos5x_save, @@ -258,6 +284,9 @@ static int exynos5420_clk_suspend(void) samsung_clk_save(reg_base, exynos5800_save, ARRAY_SIZE(exynos5800_clk_regs)); + samsung_clk_restore(reg_base, exynos5420_set_clksrc, + ARRAY_SIZE(exynos5420_set_clksrc)); + return 0; } -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend 2014-06-26 11:12 ` Vikas Sajjan @ 2014-06-30 17:58 ` Tomasz Figa -1 siblings, 0 replies; 20+ messages in thread From: Tomasz Figa @ 2014-06-30 17:58 UTC (permalink / raw) To: Vikas Sajjan, linux-arm-kernel, linux-samsung-soc Cc: kgene.kim, tomasz.figa, joshi, sajjan.linux, dianders, Abhilash Kesavan Hi Vikas, Abhilash, On 26.06.2014 13:12, Vikas Sajjan wrote: > Prior to suspending the system, we need to ensure that certain > clock source and gate registers are unmasked. > > while at it, add these clks to save/restore list also. > > Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> > Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> > --- > drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) Looks good. Will apply. Best regards, Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend @ 2014-06-30 17:58 ` Tomasz Figa 0 siblings, 0 replies; 20+ messages in thread From: Tomasz Figa @ 2014-06-30 17:58 UTC (permalink / raw) To: linux-arm-kernel Hi Vikas, Abhilash, On 26.06.2014 13:12, Vikas Sajjan wrote: > Prior to suspending the system, we need to ensure that certain > clock source and gate registers are unmasked. > > while at it, add these clks to save/restore list also. > > Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> > Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> > --- > drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) Looks good. Will apply. Best regards, Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend 2014-06-30 17:58 ` Tomasz Figa @ 2014-07-08 4:34 ` Vikas Sajjan -1 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-07-08 4:34 UTC (permalink / raw) To: Kukjin Kim Cc: linux-arm-kernel, linux-samsung-soc, Tomasz Figa, sunil joshi, Doug Anderson, Abhilash Kesavan, Tomasz Figa Hi Kukjin, On Mon, Jun 30, 2014 at 11:28 PM, Tomasz Figa <t.figa@samsung.com> wrote: > Hi Vikas, Abhilash, > > On 26.06.2014 13:12, Vikas Sajjan wrote: >> Prior to suspending the system, we need to ensure that certain >> clock source and gate registers are unmasked. >> >> while at it, add these clks to save/restore list also. >> >> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >> --- >> drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ >> 1 file changed, 29 insertions(+) > > Looks good. Will apply. > Can you apply this patch. > Best regards, > Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend @ 2014-07-08 4:34 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-07-08 4:34 UTC (permalink / raw) To: linux-arm-kernel Hi Kukjin, On Mon, Jun 30, 2014 at 11:28 PM, Tomasz Figa <t.figa@samsung.com> wrote: > Hi Vikas, Abhilash, > > On 26.06.2014 13:12, Vikas Sajjan wrote: >> Prior to suspending the system, we need to ensure that certain >> clock source and gate registers are unmasked. >> >> while at it, add these clks to save/restore list also. >> >> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >> --- >> drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ >> 1 file changed, 29 insertions(+) > > Looks good. Will apply. > Can you apply this patch. > Best regards, > Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend 2014-07-08 4:34 ` Vikas Sajjan @ 2014-07-08 8:43 ` Tomasz Figa -1 siblings, 0 replies; 20+ messages in thread From: Tomasz Figa @ 2014-07-08 8:43 UTC (permalink / raw) To: Vikas Sajjan, Kukjin Kim Cc: linux-arm-kernel, linux-samsung-soc, sunil joshi, Doug Anderson, Abhilash Kesavan, Tomasz Figa Vikas, On 08.07.2014 06:34, Vikas Sajjan wrote: > Hi Kukjin, > > On Mon, Jun 30, 2014 at 11:28 PM, Tomasz Figa <t.figa@samsung.com> wrote: >> Hi Vikas, Abhilash, >> >> On 26.06.2014 13:12, Vikas Sajjan wrote: >>> Prior to suspending the system, we need to ensure that certain >>> clock source and gate registers are unmasked. >>> >>> while at it, add these clks to save/restore list also. >>> >>> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >>> --- >>> drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ >>> 1 file changed, 29 insertions(+) >> >> Looks good. Will apply. >> > > Can you apply this patch. As I said, I will take this through the samsung-clk tree. The patch should appear there soon. Best regards, Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend @ 2014-07-08 8:43 ` Tomasz Figa 0 siblings, 0 replies; 20+ messages in thread From: Tomasz Figa @ 2014-07-08 8:43 UTC (permalink / raw) To: linux-arm-kernel Vikas, On 08.07.2014 06:34, Vikas Sajjan wrote: > Hi Kukjin, > > On Mon, Jun 30, 2014 at 11:28 PM, Tomasz Figa <t.figa@samsung.com> wrote: >> Hi Vikas, Abhilash, >> >> On 26.06.2014 13:12, Vikas Sajjan wrote: >>> Prior to suspending the system, we need to ensure that certain >>> clock source and gate registers are unmasked. >>> >>> while at it, add these clks to save/restore list also. >>> >>> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >>> --- >>> drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ >>> 1 file changed, 29 insertions(+) >> >> Looks good. Will apply. >> > > Can you apply this patch. As I said, I will take this through the samsung-clk tree. The patch should appear there soon. Best regards, Tomasz ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend 2014-07-08 8:43 ` Tomasz Figa @ 2014-07-08 8:52 ` Vikas Sajjan -1 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-07-08 8:52 UTC (permalink / raw) To: Tomasz Figa Cc: Kukjin Kim, linux-arm-kernel, linux-samsung-soc, sunil joshi, Doug Anderson, Abhilash Kesavan, Tomasz Figa On Tue, Jul 8, 2014 at 2:13 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote: > Vikas, > > On 08.07.2014 06:34, Vikas Sajjan wrote: >> Hi Kukjin, >> >> On Mon, Jun 30, 2014 at 11:28 PM, Tomasz Figa <t.figa@samsung.com> wrote: >>> Hi Vikas, Abhilash, >>> >>> On 26.06.2014 13:12, Vikas Sajjan wrote: >>>> Prior to suspending the system, we need to ensure that certain >>>> clock source and gate registers are unmasked. >>>> >>>> while at it, add these clks to save/restore list also. >>>> >>>> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >>>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >>>> --- >>>> drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ >>>> 1 file changed, 29 insertions(+) >>> >>> Looks good. Will apply. >>> >> >> Can you apply this patch. > > As I said, I will take this through the samsung-clk tree. The patch > should appear there soon. OK, Thanks. > > Best regards, > Tomasz > -- > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend @ 2014-07-08 8:52 ` Vikas Sajjan 0 siblings, 0 replies; 20+ messages in thread From: Vikas Sajjan @ 2014-07-08 8:52 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jul 8, 2014 at 2:13 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote: > Vikas, > > On 08.07.2014 06:34, Vikas Sajjan wrote: >> Hi Kukjin, >> >> On Mon, Jun 30, 2014 at 11:28 PM, Tomasz Figa <t.figa@samsung.com> wrote: >>> Hi Vikas, Abhilash, >>> >>> On 26.06.2014 13:12, Vikas Sajjan wrote: >>>> Prior to suspending the system, we need to ensure that certain >>>> clock source and gate registers are unmasked. >>>> >>>> while at it, add these clks to save/restore list also. >>>> >>>> Signed-off-by: Vikas Sajjan <vikas.sajjan@samsung.com> >>>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> >>>> --- >>>> drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ >>>> 1 file changed, 29 insertions(+) >>> >>> Looks good. Will apply. >>> >> >> Can you apply this patch. > > As I said, I will take this through the samsung-clk tree. The patch > should appear there soon. OK, Thanks. > > Best regards, > Tomasz > -- > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2014-07-08 8:52 UTC | newest] Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-06-26 11:12 [PATCH v5 0/3] Adds PMU and S2R support for exynos5420 Vikas Sajjan 2014-06-26 11:12 ` Vikas Sajjan 2014-06-26 11:12 ` [PATCH v5 1/3] arm: exynos5: Add PMU support for 5420 Vikas Sajjan 2014-06-26 11:12 ` Vikas Sajjan 2014-06-26 11:12 ` [PATCH v5 2/3] arm: exynos5: Add Suspend-to-RAM " Vikas Sajjan 2014-06-26 11:12 ` Vikas Sajjan 2014-06-30 17:57 ` Tomasz Figa 2014-06-30 17:57 ` Tomasz Figa 2014-07-01 13:47 ` Vikas Sajjan 2014-07-01 13:47 ` Vikas Sajjan 2014-06-26 11:12 ` [PATCH v5 3/3] clk: samsung: exynos5420: Setup clocks before system suspend Vikas Sajjan 2014-06-26 11:12 ` Vikas Sajjan 2014-06-30 17:58 ` Tomasz Figa 2014-06-30 17:58 ` Tomasz Figa 2014-07-08 4:34 ` Vikas Sajjan 2014-07-08 4:34 ` Vikas Sajjan 2014-07-08 8:43 ` Tomasz Figa 2014-07-08 8:43 ` Tomasz Figa 2014-07-08 8:52 ` Vikas Sajjan 2014-07-08 8:52 ` Vikas Sajjan
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.