Adds PMU and S2R support for exynos5420
Subsystems (6)
v5 cover Adds PMU and S2R support for exynos5420
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(-)
Signature · 1 line
1.7.9.5
PATCH v5 1/3 arm: exynos5: Add PMU support for 5420
From: Abhilash Kesavan <[email protected]>
Add intial PMU settings for exynos5420. This is required for future S2R and Switching support.
--- arch/arm/mach-exynos/pmu.c | 290 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-exynos/regs-pmu.h | 229 +++++++++++++++++++++++++++++++ 2 files changed, 519 insertions(+)
arch/arm/mach-exynos/pmu.c +290 -0
@@ -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, + }, {}, };
arch/arm/mach-exynos/regs-pmu.h +229 -0
251 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v5 2/3 arm: exynos5: Add Suspend-to-RAM support for 5420
In reply to Vikas SajjanFrom: Abhilash Kesavan <[email protected]>
Adds Suspend-to-RAM support for EXYNOS5420
--- arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 16 deletions(-)
arch/arm/mach-exynos/pm.c +134 -16
@@ -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);
Signature · 1 line
1.7.9.5
PATCH v5 2/3 arm: exynos5: Add Suspend-to-RAM support for 5420
Hi Vikas, Abhilash,
Please see my comments inline.
Quoted 29 lines · Vikas Sajjan
From: Abhilash Kesavan <[email protected]>
Adds Suspend-to-RAM support for EXYNOS5420
Signed-off-by Abhilash Kesavan <[email protected]>Signed-off-by Vikas Sajjan <[email protected]>--- arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 16 deletions(-)arch/arm/mach-exynos/pm.c +4
-0@@ -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
arch/arm/mach-exynos/pm.c static struct sleep_save exynos_core_save[] = { · line 73
Quoted 6 lines
arch/arm/mach-exynos/pm.c +3
-0@@ -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?
arch/arm/mach-exynos/pm.c static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) · line 97
Quoted 10 lines
arch/arm/mach-exynos/pm.c +2
-1+/* * 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.
Quoted 8 lines
arch/arm/mach-exynos/pm.c +0
-1wkup_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 ())
arch/arm/mach-exynos/pm.c static int exynos_cpu_suspend(unsigned long arg) · line 270
Quoted 10 lines
arch/arm/mach-exynos/pm.c +10
-0+/* +* 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.
Quoted 34 lines
arch/arm/mach-exynos/pm.c +20
-0flush_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 ;
arch/arm/mach-exynos/pm.c static void exynos_pm_prepare(void) · line 335
Quoted 10 lines
arch/arm/mach-exynos/pm.c +10
-0+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.
arch/arm/mach-exynos/pm.c static void exynos_pm_prepare(void) · line 338
Quoted 3 lines
arch/arm/mach-exynos/pm.c +3
-0+ 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.
arch/arm/mach-exynos/pm.c static void exynos_pm_central_suspend(void) · line 358
Quoted 12 lines
arch/arm/mach-exynos/pm.c +5
-0+ 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.
arch/arm/mach-exynos/pm.c static void exynos_pm_central_suspend(void) · line 364
Quoted 8 lines
arch/arm/mach-exynos/pm.c +1
-2exynos_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.
arch/arm/mach-exynos/pm.c static void exynos_pm_central_suspend(void) · line 371
Quoted 7 lines
arch/arm/mach-exynos/pm.c +7
-0+ 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?
Quoted 34 lines
arch/arm/mach-exynos/pm.c +20
-0+ }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 );
arch/arm/mach-exynos/pm.c static void exynos_pm_resume(void) · line 440
Quoted 10 lines
arch/arm/mach-exynos/pm.c +10
-0+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.
Quoted 34 lines
arch/arm/mach-exynos/pm.c +18
-9+ }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));
arch/arm/mach-exynos/pm.c static void exynos_pm_resume(void) · line 473
Quoted 7 lines
arch/arm/mach-exynos/pm.c +4
-0@@ -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.
arch/arm/mach-exynos/pm.c static void exynos_pm_resume(void) · line 476
Quoted 3 lines
arch/arm/mach-exynos/pm.c +3
-0+ tmp =__raw_readl (pmu_base_addr +EXYNOS5420_FSYS2_OPTION ); + tmp &= ~EXYNOS5420_EMULATION ; +pmu_raw_writel (tmp,EXYNOS5420_FSYS2_OPTION );
Ditto.
Quoted 9 lines
arch/arm/mach-exynos/pm.c +5
-0+ 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 );
arch/arm/mach-exynos/pm.c void __init exynos_pm_init(void) · line 600
Quoted 9 lines
arch/arm/mach-exynos/pm.c +3
-3@@ -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
PATCH v5 2/3 arm: exynos5: Add Suspend-to-RAM support for 5420
Hi Tomasz,
Quoted 113 lines · Tomasz Figa
Hi Vikas, Abhilash,
Please see my comments inline.
Quoted 29 lines · Vikas Sajjan
From: Abhilash Kesavan <[email protected]>
Adds Suspend-to-RAM support for EXYNOS5420
Signed-off-by Abhilash Kesavan <[email protected]>Signed-off-by Vikas Sajjan <[email protected]>--- arch/arm/mach-exynos/pm.c | 150 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 16 deletions(-)arch/arm/mach-exynos/pm.c +4
-0@@ -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 arch/arm/mach-exynos/pm.c static struct sleep_save exynos_core_save[] = { · line 73
Quoted 6 lines
arch/arm/mach-exynos/pm.c +3
-0@@ -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?
arch/arm/mach-exynos/pm.c static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) · line 97
Quoted 10 lines
arch/arm/mach-exynos/pm.c +2
-1+/* * 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.
Quoted 8 lines
arch/arm/mach-exynos/pm.c +0
-1wkup_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 ())arch/arm/mach-exynos/pm.c static int exynos_cpu_suspend(unsigned long arg) · line 270
Quoted 10 lines
arch/arm/mach-exynos/pm.c +10
-0+/* +* 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.
Quoted 2 lines
arch/arm/mach-exynos/pm.c +0
-0flush_cache_all ();
Quoted 7 lines
arch/arm/mach-exynos/pm.c static void exynos_pm_prepare(void) · line 297
Quoted 7 lines
arch/arm/mach-exynos/pm.c +2
-0/* 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.,
Quoted 206 lines
Quoted 25 lines
arch/arm/mach-exynos/pm.c +18
-0+ +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 ;arch/arm/mach-exynos/pm.c static void exynos_pm_prepare(void) · line 335
Quoted 10 lines
arch/arm/mach-exynos/pm.c +10
-0+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.
arch/arm/mach-exynos/pm.c static void exynos_pm_prepare(void) · line 338
Quoted 3 lines
arch/arm/mach-exynos/pm.c +3
-0+ 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.
arch/arm/mach-exynos/pm.c static void exynos_pm_central_suspend(void) · line 358
Quoted 12 lines
arch/arm/mach-exynos/pm.c +5
-0+ 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.arch/arm/mach-exynos/pm.c static void exynos_pm_central_suspend(void) · line 364
Quoted 8 lines
arch/arm/mach-exynos/pm.c +1
-2exynos_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.
arch/arm/mach-exynos/pm.c static void exynos_pm_central_suspend(void) · line 371
Quoted 7 lines
arch/arm/mach-exynos/pm.c +7
-0+ 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?
Quoted 34 lines
arch/arm/mach-exynos/pm.c +20
-0+ }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 );arch/arm/mach-exynos/pm.c static void exynos_pm_resume(void) · line 440
Quoted 10 lines
arch/arm/mach-exynos/pm.c +10
-0+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_datastruct. Also while at it, the (1 << 28) could be replaced with proper macro.Quoted 34 lines
arch/arm/mach-exynos/pm.c +18
-9+ }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));arch/arm/mach-exynos/pm.c static void exynos_pm_resume(void) · line 473
Quoted 7 lines
arch/arm/mach-exynos/pm.c +4
-0@@ -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.
arch/arm/mach-exynos/pm.c static void exynos_pm_resume(void) · line 476
Quoted 3 lines
arch/arm/mach-exynos/pm.c +3
-0+ tmp =__raw_readl (pmu_base_addr +EXYNOS5420_FSYS2_OPTION ); + tmp &= ~EXYNOS5420_EMULATION ; +pmu_raw_writel (tmp,EXYNOS5420_FSYS2_OPTION );Ditto.
Quoted 9 lines
arch/arm/mach-exynos/pm.c +5
-0+ 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 );arch/arm/mach-exynos/pm.c void __init exynos_pm_init(void) · line 600
Quoted 9 lines
arch/arm/mach-exynos/pm.c +3
-3@@ -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
PATCH v5 3/3 clk: samsung: exynos5420: Setup clocks before system suspend
In reply to Vikas SajjanPrior 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.
--- drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/clk/samsung/clk-exynos5420.c +29 -0
@@ -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 ; }
Signature · 1 line
1.7.9.5
PATCH v5 3/3 clk: samsung: exynos5420: Setup clocks before system suspend
Hi Vikas, Abhilash,
Quoted 10 lines · Vikas Sajjan
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 <[email protected]>Signed-off-by Abhilash Kesavan <[email protected]>--- drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Looks good. Will apply.
Best regards,
Tomasz
PATCH v5 3/3 clk: samsung: exynos5420: Setup clocks before system suspend
Hi Kukjin,
Quoted 8 lines · Tomasz Figa
Hi Vikas, Abhilash,
Quoted 5 lines · Vikas Sajjan
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.
Quoted 8 lines
Quoted 5 lines
Signed-off-by Vikas Sajjan <[email protected]>Signed-off-by Abhilash Kesavan <[email protected]>--- drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)Looks good. Will apply.
Can you apply this patch.
Quoted 2 lines
Best regards,
Tomasz
PATCH v5 3/3 clk: samsung: exynos5420: Setup clocks before system suspend
Vikas,
Quoted 17 lines · Vikas Sajjan
Hi Kukjin,
Quoted 14 lines · Tomasz Figa
Hi Vikas, Abhilash,
Quoted 10 lines · Vikas Sajjan
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 <[email protected]>Signed-off-by Abhilash Kesavan <[email protected]>--- drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Quoted 4 lines
Quoted 2 lines
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
PATCH v5 3/3 clk: samsung: exynos5420: Setup clocks before system suspend
Quoted 20 lines · Tomasz Figa
Vikas,
Quoted 17 lines · Vikas Sajjan
Hi Kukjin,
Quoted 14 lines · Tomasz Figa
Hi Vikas, Abhilash,
Quoted 10 lines · Vikas Sajjan
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 <[email protected]>Signed-off-by Abhilash Kesavan <[email protected]>--- drivers/clk/samsung/clk-exynos5420.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
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.
Quoted 7 lines
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