diff mbox

[1/2] ARM: EXYNOS: Support Suspend-to-RAM on EXYNOS5420

Message ID 1387195271-3613-1-git-send-email-a.kesavan@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Abhilash Kesavan Dec. 16, 2013, 12:01 p.m. UTC
Add PMU configuration table for various low power modes - AFTR/LPA/SLEEP.
Also, add core s2r support for Exynos5420.

Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
---
This patch depends on "ARM: EXYNOS5: Add PMU settings for exynos5420"
http://www.spinics.net/lists/linux-samsung-soc/msg24902.html

 arch/arm/mach-exynos/include/mach/regs-clock.h |   15 +++
 arch/arm/mach-exynos/include/mach/regs-pmu.h   |   84 ++++++++++++
 arch/arm/mach-exynos/pm.c                      |  151 +++++++++++++++++++---
 arch/arm/mach-exynos/pmu.c                     |  165 ++++++++++++++++++++++++
 4 files changed, 396 insertions(+), 19 deletions(-)

Comments

Bartlomiej Zolnierkiewicz Dec. 16, 2013, 12:48 p.m. UTC | #1
Hi,

On Monday, December 16, 2013 05:31:10 PM Abhilash Kesavan wrote:
> Add PMU configuration table for various low power modes - AFTR/LPA/SLEEP.
> Also, add core s2r support for Exynos5420.
> 
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> ---
> This patch depends on "ARM: EXYNOS5: Add PMU settings for exynos5420"
> http://www.spinics.net/lists/linux-samsung-soc/msg24902.html

[...]

> @@ -253,10 +316,20 @@ static int exynos_pm_suspend(void)
>  
>  	/* Setting SEQ_OPTION register */
>  
> -	tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
> -	__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
> +	if (soc_is_exynos5420()) {
> +		cluster_id = (read_cpuid(CPUID_MPIDR) >> 8) & 0xf;
> +		if (!cluster_id)
> +			__raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
> +				     S5P_CENTRAL_SEQ_OPTION);
> +		else
> +			__raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
> +				     S5P_CENTRAL_SEQ_OPTION);
> +	} else if (soc_is_exynos5250()) {

Adding a check here for EXYNOS5250 doesn't look correct
(the old code behavior for older EXYNOYS SoCs should be
preserved).

> +		tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
> +		__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
> +	}

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
Vaibhav Bedia Dec. 16, 2013, 1:27 p.m. UTC | #2
Hi,

On Mon, Dec 16, 2013 at 7:01 AM, Abhilash Kesavan <a.kesavan@samsung.com> wrote:
[...]
> +/* For EXYNOS5420 */
> +#define EXYNOS5420_CLKSRC_MASK_CPERI           EXYNOS_CLKREG(0x04300)
> +#define EXYNOS5420_CLKSRC_MASK_TOP0            EXYNOS_CLKREG(0x10300)
> +#define EXYNOS5420_CLKSRC_MASK_TOP1            EXYNOS_CLKREG(0x10304)
> +#define EXYNOS5420_CLKSRC_MASK_TOP2            EXYNOS_CLKREG(0x10308)
> +#define EXYNOS5420_CLKSRC_MASK_TOP7            EXYNOS_CLKREG(0x1031C)
> +#define EXYNOS5420_CLKSRC_MASK_DISP10          EXYNOS_CLKREG(0x1032C)
> +#define EXYNOS5420_CLKSRC_MASK_MAU             EXYNOS_CLKREG(0x10334)
> +#define EXYNOS5420_CLKSRC_MASK_FSYS            EXYNOS_CLKREG(0x10340)
> +#define EXYNOS5420_CLKSRC_MASK_PERIC0          EXYNOS_CLKREG(0x10350)
> +#define EXYNOS5420_CLKSRC_MASK_PERIC1          EXYNOS_CLKREG(0x10354)
> +#define EXYNOS5420_CLKSRC_MASK_ISP             EXYNOS_CLKREG(0x10370)
> +#define EXYNOS5420_CLKGATE_BUS_DISP1           EXYNOS_CLKREG(0x10728)
> +#define EXYNOS5420_CLKGATE_IP_PERIC            EXYNOS_CLKREG(0x10950)
> +

[...]

> +#define EXYNOS5420_IROM_DATA2                                  S5P_PMUREG(0x0988)
> +#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG                       S5P_PMUREG(0x1020)
> +#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG         S5P_PMUREG(0x1024)
> +#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG       S5P_PMUREG(0x1028)
> +#define EXYNOS5420_ARM_CORE3_SYS_PWR_REG                       S5P_PMUREG(0x1030)
> +#define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG         S5P_PMUREG(0x1034)
> +#define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG       S5P_PMUREG(0x1038)
> +#define EXYNOS5420_KFC_CORE0_SYS_PWR_REG                       S5P_PMUREG(0x1040)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG         S5P_PMUREG(0x1044)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG       S5P_PMUREG(0x1048)
> +#define EXYNOS5420_KFC_CORE1_SYS_PWR_REG                       S5P_PMUREG(0x1050)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG         S5P_PMUREG(0x1054)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG       S5P_PMUREG(0x1058)
> +#define EXYNOS5420_KFC_CORE2_SYS_PWR_REG                       S5P_PMUREG(0x1060)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG         S5P_PMUREG(0x1064)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG       S5P_PMUREG(0x1068)
> +#define EXYNOS5420_KFC_CORE3_SYS_PWR_REG                       S5P_PMUREG(0x1070)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG         S5P_PMUREG(0x1074)
> +#define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG       S5P_PMUREG(0x1078)
> +#define EXYNOS5420_ISP_ARM_SYS_PWR_REG                         S5P_PMUREG(0x1090)
> +#define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG           S5P_PMUREG(0x1094)
> +#define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG         S5P_PMUREG(0x1098)
> +#define EXYNOS5420_ARM_COMMON_SYS_PWR_REG                      S5P_PMUREG(0x10A0)
> +#define EXYNOS5420_KFC_COMMON_SYS_PWR_REG                      S5P_PMUREG(0x10B0)
> +#define EXYNOS5420_KFC_L2_SYS_PWR_REG                          S5P_PMUREG(0x10D0)
> +#define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG                     S5P_PMUREG(0x1158)
> +#define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG                     S5P_PMUREG(0x115C)
> +#define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG                     S5P_PMUREG(0x1160)
> +#define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG                     S5P_PMUREG(0x1174)
> +#define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG                     S5P_PMUREG(0x1178)
> +#define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG                      S5P_PMUREG(0x11B8)
> +#define EXYNOS5420_INTROM_MEM_SYS_PWR_REG                      S5P_PMUREG(0x11BC)
> +#define EXYNOS5420_ONENANDXL_MEM_SYS_PWR                       S5P_PMUREG(0x11C0)
> +#define EXYNOS5420_USBDEV_MEM_SYS_PWR                          S5P_PMUREG(0x11CC)
> +#define EXYNOS5420_USBDEV1_MEM_SYS_PWR                         S5P_PMUREG(0x11D0)
> +#define EXYNOS5420_SDMMC_MEM_SYS_PWR                           S5P_PMUREG(0x11D4)
> +#define EXYNOS5420_CSSYS_MEM_SYS_PWR                           S5P_PMUREG(0x11D8)
> +#define EXYNOS5420_SECSS_MEM_SYS_PWR                           S5P_PMUREG(0x11DC)
> +#define EXYNOS5420_ROTATOR_MEM_SYS_PWR                         S5P_PMUREG(0x11E0)
> +#define EXYNOS5420_INTRAM_MEM_SYS_PWR                          S5P_PMUREG(0x11E4)
> +#define EXYNOS5420_INTROM_MEM_SYS_PWR                          S5P_PMUREG(0x11E8)
> +#define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG              S5P_PMUREG(0x1208)
> +#define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG              S5P_PMUREG(0x1210)
> +#define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG              S5P_PMUREG(0x1214)
> +#define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG              S5P_PMUREG(0x1218)
> +#define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG              S5P_PMUREG(0x121C)
> +#define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG              S5P_PMUREG(0x1220)
> +#define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG               S5P_PMUREG(0x1224)
> +#define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG              S5P_PMUREG(0x1228)
> +#define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG              S5P_PMUREG(0x122C)
> +#define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG               S5P_PMUREG(0x1230)
> +#define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG      S5P_PMUREG(0x1234)
> +#define EXYNOS5420_DISP1_SYS_PWR_REG                           S5P_PMUREG(0x1410)
> +#define EXYNOS5420_MAU_SYS_PWR_REG                             S5P_PMUREG(0x1414)
> +#define EXYNOS5420_G2D_SYS_PWR_REG                             S5P_PMUREG(0x1418)
> +#define EXYNOS5420_MSC_SYS_PWR_REG                             S5P_PMUREG(0x141C)
> +#define EXYNOS5420_FSYS_SYS_PWR_REG                            S5P_PMUREG(0x1420)
> +#define EXYNOS5420_FSYS2_SYS_PWR_REG                           S5P_PMUREG(0x1424)
> +#define EXYNOS5420_PSGEN_SYS_PWR_REG                           S5P_PMUREG(0x1428)
> +#define EXYNOS5420_PERIC_SYS_PWR_REG                           S5P_PMUREG(0x142C)
> +#define EXYNOS5420_WCORE_SYS_PWR_REG                           S5P_PMUREG(0x1430)
>  #define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG               S5P_PMUREG(0x1490)
>  #define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG                 S5P_PMUREG(0x1494)
>  #define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG                 S5P_PMUREG(0x1498)
> @@ -402,6 +465,7 @@
>  #define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG                   S5P_PMUREG(0x1598)
>  #define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG                   S5P_PMUREG(0x159C)
>  #define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG                  S5P_PMUREG(0x15A0)
> +#define EXYNOS5420_SFR_AXI_CGDIS1                              S5P_PMUREG(0x15E4)
>  #define EXYNOS5420_ARM_COMMON_STATUS                           S5P_PMUREG(0x2504)
>  #define EXYNOS5420_ARM_COMMON_OPTION                           S5P_PMUREG(0x2508)
>  #define EXYNOS5420_KFC_COMMON_STATUS                           S5P_PMUREG(0x2584)
> @@ -410,7 +474,24 @@
>  #define EXYNOS5420_KFC_L2_OPTION                               S5P_PMUREG(0x2688)
>  #define EXYNOS5420_LOGIC_RESET_DURATION3                       S5P_PMUREG(0x2D1C)
>
> +#define EXYNOS5420_PAD_RET_DRAM_OPTION                         S5P_PMUREG(0x3008)
> +#define EXYNOS5420_PAD_RET_MAUDIO_OPTION                       S5P_PMUREG(0x3028)
> +#define EXYNOS5420_PAD_RET_JTAG_OPTION                         S5P_PMUREG(0x3048)
> +#define EXYNOS5420_PAD_RET_GPIO_OPTION                         S5P_PMUREG(0x30C8)
> +#define EXYNOS5420_PAD_RET_UART_OPTION                         S5P_PMUREG(0x30E8)
> +#define EXYNOS5420_PAD_RET_MMCA_OPTION                         S5P_PMUREG(0x3108)
> +#define EXYNOS5420_PAD_RET_MMCB_OPTION                         S5P_PMUREG(0x3128)
> +#define EXYNOS5420_PAD_RET_MMCC_OPTION                         S5P_PMUREG(0x3148)
> +#define EXYNOS5420_PAD_RET_HSI_OPTION                          S5P_PMUREG(0x3168)
> +#define EXYNOS5420_PAD_RET_EBIA_OPTION                         S5P_PMUREG(0x3188)
> +#define EXYNOS5420_PAD_RET_EBIB_OPTION                         S5P_PMUREG(0x31A8)
> +#define EXYNOS5420_PAD_RET_SPI_OPTION                          S5P_PMUREG(0x31C8)
> +#define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION                 S5P_PMUREG(0x31E8)
> +
> +

[...]

>
> +static struct exynos_pmu_conf exynos5420_pmu_config[] = {
> +       /* { .reg = address, .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,},
> +};
> +

Looking at a rather long list of register defines and soc_is_* checks here
makes me wonder how this is any different from the static data that the
other SoC vendors (TI) are trying very hard to move out of arch/arm...
Tomasz Figa Dec. 16, 2013, 4:15 p.m. UTC | #3
Hi,

On Monday 16 of December 2013 08:27:17 Vaibhav Bedia wrote:
> Hi,
> 
> On Mon, Dec 16, 2013 at 7:01 AM, Abhilash Kesavan <a.kesavan@samsung.com> wrote:
[snip]
> > +       { 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,},
> > +};
> > +
> 
> Looking at a rather long list of register defines and soc_is_* checks here
> makes me wonder how this is any different from the static data that the
> other SoC vendors (TI) are trying very hard to move out of arch/arm...

Well, this data will eventually get moved to a PMU driver once
drivers/syslib (as discussed on KS in Edinburgh) infrastructure shows up.

We can't get rid of these data from kernel sources, since there is no
other place where they would fit. (No, DT is not such place.)

Best regards,
Tomasz
Abhilash Kesavan Dec. 17, 2013, 3:10 a.m. UTC | #4
Hi Bartlomiej,

On Mon, Dec 16, 2013 at 6:18 PM, Bartlomiej Zolnierkiewicz
<b.zolnierkie@samsung.com> wrote:
>
> Hi,
>
> On Monday, December 16, 2013 05:31:10 PM Abhilash Kesavan wrote:
>> Add PMU configuration table for various low power modes - AFTR/LPA/SLEEP.
>> Also, add core s2r support for Exynos5420.
>>
>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
>> ---
>> This patch depends on "ARM: EXYNOS5: Add PMU settings for exynos5420"
>> http://www.spinics.net/lists/linux-samsung-soc/msg24902.html
>
> [...]
>
>> @@ -253,10 +316,20 @@ static int exynos_pm_suspend(void)
>>
>>       /* Setting SEQ_OPTION register */
>>
>> -     tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
>> -     __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
>> +     if (soc_is_exynos5420()) {
>> +             cluster_id = (read_cpuid(CPUID_MPIDR) >> 8) & 0xf;
>> +             if (!cluster_id)
>> +                     __raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
>> +                                  S5P_CENTRAL_SEQ_OPTION);
>> +             else
>> +                     __raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
>> +                                  S5P_CENTRAL_SEQ_OPTION);
>> +     } else if (soc_is_exynos5250()) {
>
> Adding a check here for EXYNOS5250 doesn't look correct
> (the old code behavior for older EXYNOYS SoCs should be
> preserved).

Yes, will fix this in the next version.

>
>> +             tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
>> +             __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
>> +     }
>
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
>
>

Thanks,
Abhilash
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Tomasz Figa Dec. 20, 2013, 9:37 p.m. UTC | #5
Hi Abhilash,

Please see my comments inline.

On Monday 16 of December 2013 17:31:10 Abhilash Kesavan wrote:
> Add PMU configuration table for various low power modes - AFTR/LPA/SLEEP.
> Also, add core s2r support for Exynos5420.
> 
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> ---
> This patch depends on "ARM: EXYNOS5: Add PMU settings for exynos5420"
> http://www.spinics.net/lists/linux-samsung-soc/msg24902.html
> 
>  arch/arm/mach-exynos/include/mach/regs-clock.h |   15 +++
>  arch/arm/mach-exynos/include/mach/regs-pmu.h   |   84 ++++++++++++
>  arch/arm/mach-exynos/pm.c                      |  151 +++++++++++++++++++---
>  arch/arm/mach-exynos/pmu.c                     |  165 ++++++++++++++++++++++++
>  4 files changed, 396 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
> index d36ad76..20008f6 100644
> --- a/arch/arm/mach-exynos/include/mach/regs-clock.h
> +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
> @@ -363,6 +363,21 @@
>  #define PWR_CTRL2_CORE2_UP_RATIO		(1 << 4)
>  #define PWR_CTRL2_CORE1_UP_RATIO		(1 << 0)
>  
> +/* For EXYNOS5420 */
> +#define EXYNOS5420_CLKSRC_MASK_CPERI		EXYNOS_CLKREG(0x04300)
> +#define EXYNOS5420_CLKSRC_MASK_TOP0		EXYNOS_CLKREG(0x10300)
> +#define EXYNOS5420_CLKSRC_MASK_TOP1		EXYNOS_CLKREG(0x10304)
> +#define EXYNOS5420_CLKSRC_MASK_TOP2		EXYNOS_CLKREG(0x10308)
> +#define EXYNOS5420_CLKSRC_MASK_TOP7		EXYNOS_CLKREG(0x1031C)
> +#define EXYNOS5420_CLKSRC_MASK_DISP10		EXYNOS_CLKREG(0x1032C)
> +#define EXYNOS5420_CLKSRC_MASK_MAU		EXYNOS_CLKREG(0x10334)
> +#define EXYNOS5420_CLKSRC_MASK_FSYS		EXYNOS_CLKREG(0x10340)
> +#define EXYNOS5420_CLKSRC_MASK_PERIC0		EXYNOS_CLKREG(0x10350)
> +#define EXYNOS5420_CLKSRC_MASK_PERIC1		EXYNOS_CLKREG(0x10354)
> +#define EXYNOS5420_CLKSRC_MASK_ISP		EXYNOS_CLKREG(0x10370)
> +#define EXYNOS5420_CLKGATE_BUS_DISP1		EXYNOS_CLKREG(0x10728)
> +#define EXYNOS5420_CLKGATE_IP_PERIC		EXYNOS_CLKREG(0x10950)

This looks suspicious. Let me see below if this is really needed for what
I think it is.

> +
>  /* Compatibility defines and inclusion */
>  
>  #include <mach/regs-pmu.h>
> diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
> index d5d5386..ad316f3 100644
> --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
> +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
> @@ -229,6 +229,7 @@
>  
>  /* For EXYNOS5 */
>  
> +#define EXYNOS5_SYS_DISP1_BLK_CFG				S5P_SYSREG(0x0214)

Is it really a definition common for all Exynos5 SoCs?

>  #define EXYNOS5_SYS_I2C_CFG					S5P_SYSREG(0x0234)
>  
>  #define EXYNOS5_AUTO_WDTRESET_DISABLE				S5P_PMUREG(0x0408)
> @@ -360,6 +361,7 @@
>  #define EXYNOS5_USE_SC_COUNTER					(1 << 0)
>  
>  #define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL			(1 << 2)
> +#define EXYNOS5_L2RSTDISABLE_VALUE				(1 << 3)

Ditto.

>  #define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN			(1 << 7)
>  
>  #define EXYNOS5_OPTION_USE_STANDBYWFE				(1 << 24)
[snip]
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index 7fb0f13..3ad103f 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -52,6 +52,22 @@ static const struct sleep_save exynos4210_set_clksrc[] = {
>  	{ .reg = EXYNOS4210_CLKSRC_MASK_LCD1		, .val = 0x00001111, },
>  };
>  
> +static struct sleep_save exynos5420_set_clksrc[] = {
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_CPERI,		.val = 0xffffffff, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP0,		.val = 0x11111111, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP1,		.val = 0x11101111, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP2,		.val = 0x11111110, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP7,		.val = 0x00111100, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_DISP10,		.val = 0x11111110, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_MAU,		.val = 0x10000000, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_FSYS,		.val = 0x11111110, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_PERIC0,		.val = 0x11111110, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_PERIC1,		.val = 0x11111100, },
> +	{ .reg = EXYNOS5420_CLKSRC_MASK_ISP,		.val = 0x11111000, },
> +	{ .reg = EXYNOS5420_CLKGATE_BUS_DISP1,		.val = 0xffffffff, },
> +	{ .reg = EXYNOS5420_CLKGATE_IP_PERIC,		.val = 0xffffffff, },
> +};
> +

OK, just as I thought...

NAK. Clock registers should be accessed only inside clock driver. Please
see my patch implementing similar thing for Exynos 4:

http://thread.gmane.org/gmane.linux.kernel.samsung-soc/24078/focus=24087


>  static struct sleep_save exynos4_epll_save[] = {
>  	SAVE_ITEM(EXYNOS4_EPLL_CON0),
>  	SAVE_ITEM(EXYNOS4_EPLL_CON1),
> @@ -66,6 +82,14 @@ static struct sleep_save exynos5_sys_save[] = {
>  	SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
>  };
>  
> +static struct sleep_save exynos5420_sys_save[] = {
> +	SAVE_ITEM(EXYNOS5_SYS_DISP1_BLK_CFG),
> +};
> +
> +static struct sleep_save exynos5420_cpustate_save[] = {
> +	SAVE_ITEM(S5P_VA_SYSRAM + 0x28),
> +};
> +
>  static struct sleep_save exynos_core_save[] = {
>  	/* SROM side */
>  	SAVE_ITEM(S5P_SROM_BW),
> @@ -84,8 +108,15 @@ static int exynos_cpu_suspend(unsigned long arg)
>  #ifdef CONFIG_CACHE_L2X0
>  	outer_flush_all();
>  #endif
> +	/*
> +	 * Clear the IRAM register that holds a low power flag. The presence
> +	 * of this flag decides if the primary cpu starts executing the low
> +	 * power function at wake-up or not.
> +	 */
> +	if (soc_is_exynos5420())
> +		__raw_writel(0x0, S5P_VA_SYSRAM + 0x28);
>  
> -	if (soc_is_exynos5250())
> +	if (soc_is_exynos5250() || soc_is_exynos5420())
>  		flush_cache_all();
>  
>  	/* issue the standby signal into the pm unit. */
> @@ -101,9 +132,14 @@ static void exynos_pm_prepare(void)
>  
>  	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
>  
> -	if (!soc_is_exynos5250()) {
> +	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>  		s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
>  		s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
> +	} else if (soc_is_exynos5420()) {
> +		s3c_pm_do_save(exynos5420_sys_save,
> +					ARRAY_SIZE(exynos5420_sys_save));
> +		s3c_pm_do_save(exynos5420_cpustate_save,
> +			ARRAY_SIZE(exynos5420_cpustate_save));
>  	} else {
>  		s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
>  		/* Disable USE_RETENTION of JPEG_MEM_OPTION */

What about rewriting this code as follows:

	if (soc_is_exynos5420()) {
		// exynos5420 specific code
	} else if (soc_is_exynos5250()) {
		// exynos5250 specific code
	} else {
		// exynos4 specific code
	}

Still, I'd prefer this to be based on top of my series I mentioned above
which removes any clock handling from this file and so makes the exynos4
branch above disappear.

> @@ -123,12 +159,32 @@ static void exynos_pm_prepare(void)
>  
>  	/* Before enter central sequence mode, clock src register have to set */
>  
> -	if (!soc_is_exynos5250())
> +	if (!(soc_is_exynos5250() || soc_is_exynos5420()))
>  		s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
>  
>  	if (soc_is_exynos4210())
>  		s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
>  
> +	if (soc_is_exynos5420()) {
> +		s3c_pm_do_restore_core(exynos5420_set_clksrc,
> +				ARRAY_SIZE(exynos5420_set_clksrc));
> +
> +		tmp = __raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
> +		tmp |= EXYNOS5420_UFS;
> +		__raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
> +
> +		tmp = __raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
> +		tmp &= ~EXYNOS5_L2RSTDISABLE_VALUE;
> +		__raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
> +
> +		tmp = __raw_readl(EXYNOS5420_FSYS2_OPTION);
> +		tmp |= EXYNOS5420_EMULATION;
> +		__raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
> +
> +		tmp = __raw_readl(EXYNOS5420_PSGEN_OPTION);
> +		tmp |= EXYNOS5420_EMULATION;
> +		__raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
> +	}
>  }
>  
>  static int exynos_pm_add(struct device *dev, struct subsys_interface *sif)
> @@ -224,11 +280,17 @@ static __init int exynos_pm_drvinit(void)
>  
>  	/* All wakeup disable */
>  
> -	tmp = __raw_readl(S5P_WAKEUP_MASK);
> -	tmp |= ((0xFF << 8) | (0x1F << 1));
> -	__raw_writel(tmp, S5P_WAKEUP_MASK);
> +	if (soc_is_exynos5420()) {
> +		tmp = __raw_readl(S5P_WAKEUP_MASK);
> +		tmp |= ((0x7F << 7) | (0x1F << 1));
> +		__raw_writel(tmp, S5P_WAKEUP_MASK);
> +	} else {
> +		tmp = __raw_readl(S5P_WAKEUP_MASK);
> +		tmp |= ((0xFF << 8) | (0x1F << 1));
> +		__raw_writel(tmp, S5P_WAKEUP_MASK);
> +	}
>  
> -	if (!soc_is_exynos5250()) {
> +	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>  		pll_base = clk_get(NULL, "xtal");

This code is also removed by my series.

>  
>  		if (!IS_ERR(pll_base)) {
> @@ -244,6 +306,7 @@ arch_initcall(exynos_pm_drvinit);
>  static int exynos_pm_suspend(void)
>  {
>  	unsigned long tmp;
> +	unsigned int cluster_id;
>  
>  	/* Setting Central Sequence Register for power down mode */
>  
> @@ -253,10 +316,20 @@ static int exynos_pm_suspend(void)
>  
>  	/* Setting SEQ_OPTION register */
>  
> -	tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
> -	__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
> +	if (soc_is_exynos5420()) {
> +		cluster_id = (read_cpuid(CPUID_MPIDR) >> 8) & 0xf;
> +		if (!cluster_id)
> +			__raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
> +				     S5P_CENTRAL_SEQ_OPTION);
> +		else
> +			__raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
> +				     S5P_CENTRAL_SEQ_OPTION);
> +	} else if (soc_is_exynos5250()) {

This code should be also called on other Exynos SoCs, not just 5250.

> +		tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
> +		__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
> +	}
>  
> -	if (!soc_is_exynos5250()) {
> +	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>  		/* Save Power control register */
>  		asm ("mrc p15, 0, %0, c15, c0, 0"
>  		     : "=r" (tmp) : : "cc");
> @@ -275,6 +348,15 @@ static void exynos_pm_resume(void)
>  {
>  	unsigned long tmp;
>  
> +	if (soc_is_exynos5420()) {
> +		/* Restore the low power flag */
> +		s3c_pm_do_restore(exynos5420_cpustate_save,
> +			ARRAY_SIZE(exynos5420_cpustate_save));
> +
> +		__raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
> +			S5P_CENTRAL_SEQ_OPTION);
> +	}
> +
>  	/*
>  	 * If PMU failed while entering sleep mode, WFI will be
>  	 * ignored by PMU and then exiting cpu_do_idle().
> @@ -290,7 +372,7 @@ static void exynos_pm_resume(void)
>  		/* No need to perform below restore code */
>  		goto early_wakeup;
>  	}
> -	if (!soc_is_exynos5250()) {
> +	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>  		/* Restore Power control register */
>  		tmp = save_arm_register[0];
>  		asm volatile ("mcr p15, 0, %0, c15, c0, 0"
> @@ -306,21 +388,40 @@ static void exynos_pm_resume(void)
>  
>  	/* For release retention */
>  
> -	__raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
> -	__raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
> -	__raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
> -	__raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
> -	__raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
> -	__raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
> -	__raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
> +	 if (soc_is_exynos5420()) {

Indentation issue.

> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_DRAM_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MAUDIO_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_JTAG_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_EBIA_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_EBIB_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION);
> +		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION);
> +	} else {
> +		__raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
> +		__raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
> +		__raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
> +		__raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
> +		__raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
> +		__raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
> +		__raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
> +	}
>  
>  	if (soc_is_exynos5250())
>  		s3c_pm_do_restore(exynos5_sys_save,
>  			ARRAY_SIZE(exynos5_sys_save));
> +	else if (soc_is_exynos5420())
> +		s3c_pm_do_restore(exynos5420_sys_save,
> +			ARRAY_SIZE(exynos5420_sys_save));
>  
>  	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
>  
> -	if (!soc_is_exynos5250()) {
> +	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>  		exynos4_restore_pll();
>  
>  #ifdef CONFIG_SMP
> @@ -330,6 +431,18 @@ static void exynos_pm_resume(void)
>  
>  early_wakeup:
>  
> +	if (soc_is_exynos5420()) {
> +		tmp = __raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
> +		tmp &= ~EXYNOS5420_UFS;
> +		__raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
> +		tmp = __raw_readl(EXYNOS5420_FSYS2_OPTION);
> +		tmp &= ~EXYNOS5420_EMULATION;
> +		__raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
> +		tmp = __raw_readl(EXYNOS5420_PSGEN_OPTION);
> +		tmp &= ~EXYNOS5420_EMULATION;
> +		__raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
> +	}
> +
>  	/* Clear SLEEP mode set in INFORM1 */
>  	__raw_writel(0x0, S5P_INFORM1);
>  
> diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
> index e39cc75..1449404 100644
> --- a/arch/arm/mach-exynos/pmu.c
> +++ b/arch/arm/mach-exynos/pmu.c
> @@ -16,6 +16,8 @@
>  #include <mach/regs-clock.h>
>  #include <mach/regs-pmu.h>
>  
> +#include <asm/cputype.h>
> +
>  #include "common.h"
>  
>  static const struct exynos_pmu_conf *exynos_pmu_config;
> @@ -318,6 +320,151 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
>  	{ PMU_TABLE_END,},
>  };
>  
> +static struct exynos_pmu_conf exynos5420_pmu_config[] = {

static const?

Best regards,
Tomasz
Abhilash Kesavan Dec. 21, 2013, 7:18 a.m. UTC | #6
Hi Tomasz,

On Sat, Dec 21, 2013 at 3:07 AM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Abhilash,
>
> Please see my comments inline.
>
> On Monday 16 of December 2013 17:31:10 Abhilash Kesavan wrote:
>> Add PMU configuration table for various low power modes - AFTR/LPA/SLEEP.
>> Also, add core s2r support for Exynos5420.
>>
>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
>> ---
>> This patch depends on "ARM: EXYNOS5: Add PMU settings for exynos5420"
>> http://www.spinics.net/lists/linux-samsung-soc/msg24902.html
>>
>>  arch/arm/mach-exynos/include/mach/regs-clock.h |   15 +++
>>  arch/arm/mach-exynos/include/mach/regs-pmu.h   |   84 ++++++++++++
>>  arch/arm/mach-exynos/pm.c                      |  151 +++++++++++++++++++---
>>  arch/arm/mach-exynos/pmu.c                     |  165 ++++++++++++++++++++++++
>>  4 files changed, 396 insertions(+), 19 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
>> index d36ad76..20008f6 100644
>> --- a/arch/arm/mach-exynos/include/mach/regs-clock.h
>> +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
>> @@ -363,6 +363,21 @@
>>  #define PWR_CTRL2_CORE2_UP_RATIO             (1 << 4)
>>  #define PWR_CTRL2_CORE1_UP_RATIO             (1 << 0)
>>
>> +/* For EXYNOS5420 */
>> +#define EXYNOS5420_CLKSRC_MASK_CPERI         EXYNOS_CLKREG(0x04300)
>> +#define EXYNOS5420_CLKSRC_MASK_TOP0          EXYNOS_CLKREG(0x10300)
>> +#define EXYNOS5420_CLKSRC_MASK_TOP1          EXYNOS_CLKREG(0x10304)
>> +#define EXYNOS5420_CLKSRC_MASK_TOP2          EXYNOS_CLKREG(0x10308)
>> +#define EXYNOS5420_CLKSRC_MASK_TOP7          EXYNOS_CLKREG(0x1031C)
>> +#define EXYNOS5420_CLKSRC_MASK_DISP10                EXYNOS_CLKREG(0x1032C)
>> +#define EXYNOS5420_CLKSRC_MASK_MAU           EXYNOS_CLKREG(0x10334)
>> +#define EXYNOS5420_CLKSRC_MASK_FSYS          EXYNOS_CLKREG(0x10340)
>> +#define EXYNOS5420_CLKSRC_MASK_PERIC0                EXYNOS_CLKREG(0x10350)
>> +#define EXYNOS5420_CLKSRC_MASK_PERIC1                EXYNOS_CLKREG(0x10354)
>> +#define EXYNOS5420_CLKSRC_MASK_ISP           EXYNOS_CLKREG(0x10370)
>> +#define EXYNOS5420_CLKGATE_BUS_DISP1         EXYNOS_CLKREG(0x10728)
>> +#define EXYNOS5420_CLKGATE_IP_PERIC          EXYNOS_CLKREG(0x10950)
>
> This looks suspicious. Let me see below if this is really needed for what
> I think it is.
>
>> +
>>  /* Compatibility defines and inclusion */
>>
>>  #include <mach/regs-pmu.h>
>> diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
>> index d5d5386..ad316f3 100644
>> --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
>> +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
>> @@ -229,6 +229,7 @@
>>
>>  /* For EXYNOS5 */
>>
>> +#define EXYNOS5_SYS_DISP1_BLK_CFG                            S5P_SYSREG(0x0214)
>
> Is it really a definition common for all Exynos5 SoCs?

I do see the register in both 5250 and 5420 even though the bits differ.
>
>>  #define EXYNOS5_SYS_I2C_CFG                                  S5P_SYSREG(0x0234)
>>
>>  #define EXYNOS5_AUTO_WDTRESET_DISABLE                                S5P_PMUREG(0x0408)
>> @@ -360,6 +361,7 @@
>>  #define EXYNOS5_USE_SC_COUNTER                                       (1 << 0)
>>
>>  #define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL                  (1 << 2)
>> +#define EXYNOS5_L2RSTDISABLE_VALUE                           (1 << 3)
>
> Ditto.
No, I will make this 5420 specific.

>
>>  #define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN                       (1 << 7)
>>
>>  #define EXYNOS5_OPTION_USE_STANDBYWFE                                (1 << 24)
> [snip]
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index 7fb0f13..3ad103f 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -52,6 +52,22 @@ static const struct sleep_save exynos4210_set_clksrc[] = {
>>       { .reg = EXYNOS4210_CLKSRC_MASK_LCD1            , .val = 0x00001111, },
>>  };
>>
>> +static struct sleep_save exynos5420_set_clksrc[] = {
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_CPERI,          .val = 0xffffffff, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_TOP0,           .val = 0x11111111, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_TOP1,           .val = 0x11101111, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_TOP2,           .val = 0x11111110, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_TOP7,           .val = 0x00111100, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_DISP10,         .val = 0x11111110, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_MAU,            .val = 0x10000000, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_FSYS,           .val = 0x11111110, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_PERIC0,         .val = 0x11111110, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_PERIC1,         .val = 0x11111100, },
>> +     { .reg = EXYNOS5420_CLKSRC_MASK_ISP,            .val = 0x11111000, },
>> +     { .reg = EXYNOS5420_CLKGATE_BUS_DISP1,          .val = 0xffffffff, },
>> +     { .reg = EXYNOS5420_CLKGATE_IP_PERIC,           .val = 0xffffffff, },
>> +};
>> +
>
> OK, just as I thought...
>
> NAK. Clock registers should be accessed only inside clock driver. Please
> see my patch implementing similar thing for Exynos 4:
>
> http://thread.gmane.org/gmane.linux.kernel.samsung-soc/24078/focus=24087

I had not seen these changes, will re-base it on your changes.
>
>
>>  static struct sleep_save exynos4_epll_save[] = {
>>       SAVE_ITEM(EXYNOS4_EPLL_CON0),
>>       SAVE_ITEM(EXYNOS4_EPLL_CON1),
>> @@ -66,6 +82,14 @@ static struct sleep_save exynos5_sys_save[] = {
>>       SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
>>  };
>>
>> +static struct sleep_save exynos5420_sys_save[] = {
>> +     SAVE_ITEM(EXYNOS5_SYS_DISP1_BLK_CFG),
>> +};
>> +
>> +static struct sleep_save exynos5420_cpustate_save[] = {
>> +     SAVE_ITEM(S5P_VA_SYSRAM + 0x28),
>> +};
>> +
>>  static struct sleep_save exynos_core_save[] = {
>>       /* SROM side */
>>       SAVE_ITEM(S5P_SROM_BW),
>> @@ -84,8 +108,15 @@ static int exynos_cpu_suspend(unsigned long arg)
>>  #ifdef CONFIG_CACHE_L2X0
>>       outer_flush_all();
>>  #endif
>> +     /*
>> +      * Clear the IRAM register that holds a low power flag. The presence
>> +      * of this flag decides if the primary cpu starts executing the low
>> +      * power function at wake-up or not.
>> +      */
>> +     if (soc_is_exynos5420())
>> +             __raw_writel(0x0, S5P_VA_SYSRAM + 0x28);
>>
>> -     if (soc_is_exynos5250())
>> +     if (soc_is_exynos5250() || soc_is_exynos5420())
>>               flush_cache_all();
>>
>>       /* issue the standby signal into the pm unit. */
>> @@ -101,9 +132,14 @@ static void exynos_pm_prepare(void)
>>
>>       s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
>>
>> -     if (!soc_is_exynos5250()) {
>> +     if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>>               s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
>>               s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
>> +     } else if (soc_is_exynos5420()) {
>> +             s3c_pm_do_save(exynos5420_sys_save,
>> +                                     ARRAY_SIZE(exynos5420_sys_save));
>> +             s3c_pm_do_save(exynos5420_cpustate_save,
>> +                     ARRAY_SIZE(exynos5420_cpustate_save));
>>       } else {
>>               s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
>>               /* Disable USE_RETENTION of JPEG_MEM_OPTION */
>
> What about rewriting this code as follows:
>
>         if (soc_is_exynos5420()) {
>                 // exynos5420 specific code
>         } else if (soc_is_exynos5250()) {
>                 // exynos5250 specific code
>         } else {
>                 // exynos4 specific code
>         }
>
> Still, I'd prefer this to be based on top of my series I mentioned above
> which removes any clock handling from this file and so makes the exynos4
> branch above disappear.

OK..will re-base on your patches.
>
>> @@ -123,12 +159,32 @@ static void exynos_pm_prepare(void)
>>
>>       /* Before enter central sequence mode, clock src register have to set */
>>
>> -     if (!soc_is_exynos5250())
>> +     if (!(soc_is_exynos5250() || soc_is_exynos5420()))
>>               s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
>>
>>       if (soc_is_exynos4210())
>>               s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
>>
>> +     if (soc_is_exynos5420()) {
>> +             s3c_pm_do_restore_core(exynos5420_set_clksrc,
>> +                             ARRAY_SIZE(exynos5420_set_clksrc));
>> +
>> +             tmp = __raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
>> +             tmp |= EXYNOS5420_UFS;
>> +             __raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
>> +
>> +             tmp = __raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
>> +             tmp &= ~EXYNOS5_L2RSTDISABLE_VALUE;
>> +             __raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
>> +
>> +             tmp = __raw_readl(EXYNOS5420_FSYS2_OPTION);
>> +             tmp |= EXYNOS5420_EMULATION;
>> +             __raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
>> +
>> +             tmp = __raw_readl(EXYNOS5420_PSGEN_OPTION);
>> +             tmp |= EXYNOS5420_EMULATION;
>> +             __raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
>> +     }
>>  }
>>
>>  static int exynos_pm_add(struct device *dev, struct subsys_interface *sif)
>> @@ -224,11 +280,17 @@ static __init int exynos_pm_drvinit(void)
>>
>>       /* All wakeup disable */
>>
>> -     tmp = __raw_readl(S5P_WAKEUP_MASK);
>> -     tmp |= ((0xFF << 8) | (0x1F << 1));
>> -     __raw_writel(tmp, S5P_WAKEUP_MASK);
>> +     if (soc_is_exynos5420()) {
>> +             tmp = __raw_readl(S5P_WAKEUP_MASK);
>> +             tmp |= ((0x7F << 7) | (0x1F << 1));
>> +             __raw_writel(tmp, S5P_WAKEUP_MASK);
>> +     } else {
>> +             tmp = __raw_readl(S5P_WAKEUP_MASK);
>> +             tmp |= ((0xFF << 8) | (0x1F << 1));
>> +             __raw_writel(tmp, S5P_WAKEUP_MASK);
>> +     }
>>
>> -     if (!soc_is_exynos5250()) {
>> +     if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>>               pll_base = clk_get(NULL, "xtal");
>
> This code is also removed by my series.

Ok
>
>>
>>               if (!IS_ERR(pll_base)) {
>> @@ -244,6 +306,7 @@ arch_initcall(exynos_pm_drvinit);
>>  static int exynos_pm_suspend(void)
>>  {
>>       unsigned long tmp;
>> +     unsigned int cluster_id;
>>
>>       /* Setting Central Sequence Register for power down mode */
>>
>> @@ -253,10 +316,20 @@ static int exynos_pm_suspend(void)
>>
>>       /* Setting SEQ_OPTION register */
>>
>> -     tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
>> -     __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
>> +     if (soc_is_exynos5420()) {
>> +             cluster_id = (read_cpuid(CPUID_MPIDR) >> 8) & 0xf;
>> +             if (!cluster_id)
>> +                     __raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
>> +                                  S5P_CENTRAL_SEQ_OPTION);
>> +             else
>> +                     __raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
>> +                                  S5P_CENTRAL_SEQ_OPTION);
>> +     } else if (soc_is_exynos5250()) {
>
> This code should be also called on other Exynos SoCs, not just 5250.

Yes, Bartlomiej caught this in an earlier review.
>
>> +             tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
>> +             __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
>> +     }
>>
>> -     if (!soc_is_exynos5250()) {
>> +     if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>>               /* Save Power control register */
>>               asm ("mrc p15, 0, %0, c15, c0, 0"
>>                    : "=r" (tmp) : : "cc");
>> @@ -275,6 +348,15 @@ static void exynos_pm_resume(void)
>>  {
>>       unsigned long tmp;
>>
>> +     if (soc_is_exynos5420()) {
>> +             /* Restore the low power flag */
>> +             s3c_pm_do_restore(exynos5420_cpustate_save,
>> +                     ARRAY_SIZE(exynos5420_cpustate_save));
>> +
>> +             __raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
>> +                     S5P_CENTRAL_SEQ_OPTION);
>> +     }
>> +
>>       /*
>>        * If PMU failed while entering sleep mode, WFI will be
>>        * ignored by PMU and then exiting cpu_do_idle().
>> @@ -290,7 +372,7 @@ static void exynos_pm_resume(void)
>>               /* No need to perform below restore code */
>>               goto early_wakeup;
>>       }
>> -     if (!soc_is_exynos5250()) {
>> +     if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>>               /* Restore Power control register */
>>               tmp = save_arm_register[0];
>>               asm volatile ("mcr p15, 0, %0, c15, c0, 0"
>> @@ -306,21 +388,40 @@ static void exynos_pm_resume(void)
>>
>>       /* For release retention */
>>
>> -     __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
>> -     __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
>> -     __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
>> -     __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
>> -     __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
>> -     __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
>> -     __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
>> +      if (soc_is_exynos5420()) {
>
> Indentation issue.
>
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_DRAM_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_MAUDIO_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_JTAG_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_EBIA_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_EBIB_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION);
>> +             __raw_writel((1 << 28), EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION);
>> +     } else {
>> +             __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
>> +             __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
>> +             __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
>> +             __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
>> +             __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
>> +             __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
>> +             __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
>> +     }
>>
>>       if (soc_is_exynos5250())
>>               s3c_pm_do_restore(exynos5_sys_save,
>>                       ARRAY_SIZE(exynos5_sys_save));
>> +     else if (soc_is_exynos5420())
>> +             s3c_pm_do_restore(exynos5420_sys_save,
>> +                     ARRAY_SIZE(exynos5420_sys_save));
>>
>>       s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
>>
>> -     if (!soc_is_exynos5250()) {
>> +     if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
>>               exynos4_restore_pll();
>>
>>  #ifdef CONFIG_SMP
>> @@ -330,6 +431,18 @@ static void exynos_pm_resume(void)
>>
>>  early_wakeup:
>>
>> +     if (soc_is_exynos5420()) {
>> +             tmp = __raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
>> +             tmp &= ~EXYNOS5420_UFS;
>> +             __raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
>> +             tmp = __raw_readl(EXYNOS5420_FSYS2_OPTION);
>> +             tmp &= ~EXYNOS5420_EMULATION;
>> +             __raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
>> +             tmp = __raw_readl(EXYNOS5420_PSGEN_OPTION);
>> +             tmp &= ~EXYNOS5420_EMULATION;
>> +             __raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
>> +     }
>> +
>>       /* Clear SLEEP mode set in INFORM1 */
>>       __raw_writel(0x0, S5P_INFORM1);
>>
>> diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
>> index e39cc75..1449404 100644
>> --- a/arch/arm/mach-exynos/pmu.c
>> +++ b/arch/arm/mach-exynos/pmu.c
>> @@ -16,6 +16,8 @@
>>  #include <mach/regs-clock.h>
>>  #include <mach/regs-pmu.h>
>>
>> +#include <asm/cputype.h>
>> +
>>  #include "common.h"
>>
>>  static const struct exynos_pmu_conf *exynos_pmu_config;
>> @@ -318,6 +320,151 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
>>       { PMU_TABLE_END,},
>>  };
>>
>> +static struct exynos_pmu_conf exynos5420_pmu_config[] = {
>
> static const?
Will fix.

>
> Best regards,
> Tomasz

Abhilash
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff mbox

Patch

diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
index d36ad76..20008f6 100644
--- a/arch/arm/mach-exynos/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
@@ -363,6 +363,21 @@ 
 #define PWR_CTRL2_CORE2_UP_RATIO		(1 << 4)
 #define PWR_CTRL2_CORE1_UP_RATIO		(1 << 0)
 
+/* For EXYNOS5420 */
+#define EXYNOS5420_CLKSRC_MASK_CPERI		EXYNOS_CLKREG(0x04300)
+#define EXYNOS5420_CLKSRC_MASK_TOP0		EXYNOS_CLKREG(0x10300)
+#define EXYNOS5420_CLKSRC_MASK_TOP1		EXYNOS_CLKREG(0x10304)
+#define EXYNOS5420_CLKSRC_MASK_TOP2		EXYNOS_CLKREG(0x10308)
+#define EXYNOS5420_CLKSRC_MASK_TOP7		EXYNOS_CLKREG(0x1031C)
+#define EXYNOS5420_CLKSRC_MASK_DISP10		EXYNOS_CLKREG(0x1032C)
+#define EXYNOS5420_CLKSRC_MASK_MAU		EXYNOS_CLKREG(0x10334)
+#define EXYNOS5420_CLKSRC_MASK_FSYS		EXYNOS_CLKREG(0x10340)
+#define EXYNOS5420_CLKSRC_MASK_PERIC0		EXYNOS_CLKREG(0x10350)
+#define EXYNOS5420_CLKSRC_MASK_PERIC1		EXYNOS_CLKREG(0x10354)
+#define EXYNOS5420_CLKSRC_MASK_ISP		EXYNOS_CLKREG(0x10370)
+#define EXYNOS5420_CLKGATE_BUS_DISP1		EXYNOS_CLKREG(0x10728)
+#define EXYNOS5420_CLKGATE_IP_PERIC		EXYNOS_CLKREG(0x10950)
+
 /* Compatibility defines and inclusion */
 
 #include <mach/regs-pmu.h>
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index d5d5386..ad316f3 100644
--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -229,6 +229,7 @@ 
 
 /* For EXYNOS5 */
 
+#define EXYNOS5_SYS_DISP1_BLK_CFG				S5P_SYSREG(0x0214)
 #define EXYNOS5_SYS_I2C_CFG					S5P_SYSREG(0x0234)
 
 #define EXYNOS5_AUTO_WDTRESET_DISABLE				S5P_PMUREG(0x0408)
@@ -360,6 +361,7 @@ 
 #define EXYNOS5_USE_SC_COUNTER					(1 << 0)
 
 #define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL			(1 << 2)
+#define EXYNOS5_L2RSTDISABLE_VALUE				(1 << 3)
 #define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN			(1 << 7)
 
 #define EXYNOS5_OPTION_USE_STANDBYWFE				(1 << 24)
@@ -373,6 +375,67 @@ 
 #define EXYNOS5420_ARM_INTR_SPREAD_ENABLE			S5P_PMUREG(0x0100)
 #define EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI		S5P_PMUREG(0x0104)
 #define EXYNOS5420_UP_SCHEDULER					S5P_PMUREG(0x0120)
+#define EXYNOS5420_IROM_DATA2					S5P_PMUREG(0x0988)
+#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG			S5P_PMUREG(0x1020)
+#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG		S5P_PMUREG(0x1024)
+#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG	S5P_PMUREG(0x1028)
+#define EXYNOS5420_ARM_CORE3_SYS_PWR_REG			S5P_PMUREG(0x1030)
+#define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG		S5P_PMUREG(0x1034)
+#define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG	S5P_PMUREG(0x1038)
+#define EXYNOS5420_KFC_CORE0_SYS_PWR_REG			S5P_PMUREG(0x1040)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG		S5P_PMUREG(0x1044)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG	S5P_PMUREG(0x1048)
+#define EXYNOS5420_KFC_CORE1_SYS_PWR_REG			S5P_PMUREG(0x1050)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG		S5P_PMUREG(0x1054)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG	S5P_PMUREG(0x1058)
+#define EXYNOS5420_KFC_CORE2_SYS_PWR_REG			S5P_PMUREG(0x1060)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG		S5P_PMUREG(0x1064)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG	S5P_PMUREG(0x1068)
+#define EXYNOS5420_KFC_CORE3_SYS_PWR_REG			S5P_PMUREG(0x1070)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG		S5P_PMUREG(0x1074)
+#define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG	S5P_PMUREG(0x1078)
+#define EXYNOS5420_ISP_ARM_SYS_PWR_REG				S5P_PMUREG(0x1090)
+#define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG		S5P_PMUREG(0x1094)
+#define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG		S5P_PMUREG(0x1098)
+#define EXYNOS5420_ARM_COMMON_SYS_PWR_REG			S5P_PMUREG(0x10A0)
+#define EXYNOS5420_KFC_COMMON_SYS_PWR_REG			S5P_PMUREG(0x10B0)
+#define EXYNOS5420_KFC_L2_SYS_PWR_REG				S5P_PMUREG(0x10D0)
+#define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG			S5P_PMUREG(0x1158)
+#define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG			S5P_PMUREG(0x115C)
+#define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG			S5P_PMUREG(0x1160)
+#define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG			S5P_PMUREG(0x1174)
+#define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG			S5P_PMUREG(0x1178)
+#define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG			S5P_PMUREG(0x11B8)
+#define EXYNOS5420_INTROM_MEM_SYS_PWR_REG			S5P_PMUREG(0x11BC)
+#define EXYNOS5420_ONENANDXL_MEM_SYS_PWR			S5P_PMUREG(0x11C0)
+#define EXYNOS5420_USBDEV_MEM_SYS_PWR				S5P_PMUREG(0x11CC)
+#define EXYNOS5420_USBDEV1_MEM_SYS_PWR				S5P_PMUREG(0x11D0)
+#define EXYNOS5420_SDMMC_MEM_SYS_PWR				S5P_PMUREG(0x11D4)
+#define EXYNOS5420_CSSYS_MEM_SYS_PWR				S5P_PMUREG(0x11D8)
+#define EXYNOS5420_SECSS_MEM_SYS_PWR				S5P_PMUREG(0x11DC)
+#define EXYNOS5420_ROTATOR_MEM_SYS_PWR				S5P_PMUREG(0x11E0)
+#define EXYNOS5420_INTRAM_MEM_SYS_PWR				S5P_PMUREG(0x11E4)
+#define EXYNOS5420_INTROM_MEM_SYS_PWR				S5P_PMUREG(0x11E8)
+#define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG		S5P_PMUREG(0x1208)
+#define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG		S5P_PMUREG(0x1210)
+#define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG		S5P_PMUREG(0x1214)
+#define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG		S5P_PMUREG(0x1218)
+#define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG		S5P_PMUREG(0x121C)
+#define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG		S5P_PMUREG(0x1220)
+#define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG		S5P_PMUREG(0x1224)
+#define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG		S5P_PMUREG(0x1228)
+#define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG		S5P_PMUREG(0x122C)
+#define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG		S5P_PMUREG(0x1230)
+#define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG	S5P_PMUREG(0x1234)
+#define EXYNOS5420_DISP1_SYS_PWR_REG				S5P_PMUREG(0x1410)
+#define EXYNOS5420_MAU_SYS_PWR_REG				S5P_PMUREG(0x1414)
+#define EXYNOS5420_G2D_SYS_PWR_REG				S5P_PMUREG(0x1418)
+#define EXYNOS5420_MSC_SYS_PWR_REG				S5P_PMUREG(0x141C)
+#define EXYNOS5420_FSYS_SYS_PWR_REG				S5P_PMUREG(0x1420)
+#define EXYNOS5420_FSYS2_SYS_PWR_REG				S5P_PMUREG(0x1424)
+#define EXYNOS5420_PSGEN_SYS_PWR_REG				S5P_PMUREG(0x1428)
+#define EXYNOS5420_PERIC_SYS_PWR_REG				S5P_PMUREG(0x142C)
+#define EXYNOS5420_WCORE_SYS_PWR_REG				S5P_PMUREG(0x1430)
 #define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG		S5P_PMUREG(0x1490)
 #define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG			S5P_PMUREG(0x1494)
 #define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG			S5P_PMUREG(0x1498)
@@ -402,6 +465,7 @@ 
 #define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG			S5P_PMUREG(0x1598)
 #define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG			S5P_PMUREG(0x159C)
 #define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG			S5P_PMUREG(0x15A0)
+#define EXYNOS5420_SFR_AXI_CGDIS1				S5P_PMUREG(0x15E4)
 #define EXYNOS5420_ARM_COMMON_STATUS				S5P_PMUREG(0x2504)
 #define EXYNOS5420_ARM_COMMON_OPTION				S5P_PMUREG(0x2508)
 #define EXYNOS5420_KFC_COMMON_STATUS				S5P_PMUREG(0x2584)
@@ -410,7 +474,24 @@ 
 #define EXYNOS5420_KFC_L2_OPTION				S5P_PMUREG(0x2688)
 #define EXYNOS5420_LOGIC_RESET_DURATION3			S5P_PMUREG(0x2D1C)
 
+#define EXYNOS5420_PAD_RET_DRAM_OPTION				S5P_PMUREG(0x3008)
+#define EXYNOS5420_PAD_RET_MAUDIO_OPTION			S5P_PMUREG(0x3028)
+#define EXYNOS5420_PAD_RET_JTAG_OPTION				S5P_PMUREG(0x3048)
+#define EXYNOS5420_PAD_RET_GPIO_OPTION				S5P_PMUREG(0x30C8)
+#define EXYNOS5420_PAD_RET_UART_OPTION				S5P_PMUREG(0x30E8)
+#define EXYNOS5420_PAD_RET_MMCA_OPTION				S5P_PMUREG(0x3108)
+#define EXYNOS5420_PAD_RET_MMCB_OPTION				S5P_PMUREG(0x3128)
+#define EXYNOS5420_PAD_RET_MMCC_OPTION				S5P_PMUREG(0x3148)
+#define EXYNOS5420_PAD_RET_HSI_OPTION				S5P_PMUREG(0x3168)
+#define EXYNOS5420_PAD_RET_EBIA_OPTION				S5P_PMUREG(0x3188)
+#define EXYNOS5420_PAD_RET_EBIB_OPTION				S5P_PMUREG(0x31A8)
+#define EXYNOS5420_PAD_RET_SPI_OPTION				S5P_PMUREG(0x31C8)
+#define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION			S5P_PMUREG(0x31E8)
+
+
 #define EXYNOS5_XXTI_DURATION3					S5P_PMUREG(0x343C)
+#define EXYNOS5420_FSYS2_OPTION					S5P_PMUREG(0x4168)
+#define EXYNOS5420_PSGEN_OPTION					S5P_PMUREG(0x4188)
 
 /* For EXYNOS_CENTRAL_SEQ_OPTION */
 #define EXYNOS5420_ARM_USE_STANDBY_WFI0				(1 << 4)
@@ -447,4 +528,7 @@ 
 #define SPREAD_USE_STANDWFI					0xF
 #define EXYNOS5420_SWRESET_KFC_SEL				0x3
 
+#define EXYNOS5420_UFS						(1 << 8)
+#define EXYNOS5420_EMULATION					(1 << 31)
+
 #endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 7fb0f13..3ad103f 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -52,6 +52,22 @@  static const struct sleep_save exynos4210_set_clksrc[] = {
 	{ .reg = EXYNOS4210_CLKSRC_MASK_LCD1		, .val = 0x00001111, },
 };
 
+static struct sleep_save exynos5420_set_clksrc[] = {
+	{ .reg = EXYNOS5420_CLKSRC_MASK_CPERI,		.val = 0xffffffff, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP0,		.val = 0x11111111, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP1,		.val = 0x11101111, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP2,		.val = 0x11111110, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_TOP7,		.val = 0x00111100, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_DISP10,		.val = 0x11111110, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_MAU,		.val = 0x10000000, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_FSYS,		.val = 0x11111110, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_PERIC0,		.val = 0x11111110, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_PERIC1,		.val = 0x11111100, },
+	{ .reg = EXYNOS5420_CLKSRC_MASK_ISP,		.val = 0x11111000, },
+	{ .reg = EXYNOS5420_CLKGATE_BUS_DISP1,		.val = 0xffffffff, },
+	{ .reg = EXYNOS5420_CLKGATE_IP_PERIC,		.val = 0xffffffff, },
+};
+
 static struct sleep_save exynos4_epll_save[] = {
 	SAVE_ITEM(EXYNOS4_EPLL_CON0),
 	SAVE_ITEM(EXYNOS4_EPLL_CON1),
@@ -66,6 +82,14 @@  static struct sleep_save exynos5_sys_save[] = {
 	SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
 };
 
+static struct sleep_save exynos5420_sys_save[] = {
+	SAVE_ITEM(EXYNOS5_SYS_DISP1_BLK_CFG),
+};
+
+static struct sleep_save exynos5420_cpustate_save[] = {
+	SAVE_ITEM(S5P_VA_SYSRAM + 0x28),
+};
+
 static struct sleep_save exynos_core_save[] = {
 	/* SROM side */
 	SAVE_ITEM(S5P_SROM_BW),
@@ -84,8 +108,15 @@  static int exynos_cpu_suspend(unsigned long arg)
 #ifdef CONFIG_CACHE_L2X0
 	outer_flush_all();
 #endif
+	/*
+	 * Clear the IRAM register that holds a low power flag. The presence
+	 * of this flag decides if the primary cpu starts executing the low
+	 * power function at wake-up or not.
+	 */
+	if (soc_is_exynos5420())
+		__raw_writel(0x0, S5P_VA_SYSRAM + 0x28);
 
-	if (soc_is_exynos5250())
+	if (soc_is_exynos5250() || soc_is_exynos5420())
 		flush_cache_all();
 
 	/* issue the standby signal into the pm unit. */
@@ -101,9 +132,14 @@  static void exynos_pm_prepare(void)
 
 	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
 
-	if (!soc_is_exynos5250()) {
+	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
 		s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
 		s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
+	} else if (soc_is_exynos5420()) {
+		s3c_pm_do_save(exynos5420_sys_save,
+					ARRAY_SIZE(exynos5420_sys_save));
+		s3c_pm_do_save(exynos5420_cpustate_save,
+			ARRAY_SIZE(exynos5420_cpustate_save));
 	} else {
 		s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
 		/* Disable USE_RETENTION of JPEG_MEM_OPTION */
@@ -123,12 +159,32 @@  static void exynos_pm_prepare(void)
 
 	/* Before enter central sequence mode, clock src register have to set */
 
-	if (!soc_is_exynos5250())
+	if (!(soc_is_exynos5250() || soc_is_exynos5420()))
 		s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
 
 	if (soc_is_exynos4210())
 		s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
 
+	if (soc_is_exynos5420()) {
+		s3c_pm_do_restore_core(exynos5420_set_clksrc,
+				ARRAY_SIZE(exynos5420_set_clksrc));
+
+		tmp = __raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
+		tmp |= EXYNOS5420_UFS;
+		__raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
+
+		tmp = __raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
+		tmp &= ~EXYNOS5_L2RSTDISABLE_VALUE;
+		__raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
+
+		tmp = __raw_readl(EXYNOS5420_FSYS2_OPTION);
+		tmp |= EXYNOS5420_EMULATION;
+		__raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
+
+		tmp = __raw_readl(EXYNOS5420_PSGEN_OPTION);
+		tmp |= EXYNOS5420_EMULATION;
+		__raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
+	}
 }
 
 static int exynos_pm_add(struct device *dev, struct subsys_interface *sif)
@@ -224,11 +280,17 @@  static __init int exynos_pm_drvinit(void)
 
 	/* All wakeup disable */
 
-	tmp = __raw_readl(S5P_WAKEUP_MASK);
-	tmp |= ((0xFF << 8) | (0x1F << 1));
-	__raw_writel(tmp, S5P_WAKEUP_MASK);
+	if (soc_is_exynos5420()) {
+		tmp = __raw_readl(S5P_WAKEUP_MASK);
+		tmp |= ((0x7F << 7) | (0x1F << 1));
+		__raw_writel(tmp, S5P_WAKEUP_MASK);
+	} else {
+		tmp = __raw_readl(S5P_WAKEUP_MASK);
+		tmp |= ((0xFF << 8) | (0x1F << 1));
+		__raw_writel(tmp, S5P_WAKEUP_MASK);
+	}
 
-	if (!soc_is_exynos5250()) {
+	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
 		pll_base = clk_get(NULL, "xtal");
 
 		if (!IS_ERR(pll_base)) {
@@ -244,6 +306,7 @@  arch_initcall(exynos_pm_drvinit);
 static int exynos_pm_suspend(void)
 {
 	unsigned long tmp;
+	unsigned int cluster_id;
 
 	/* Setting Central Sequence Register for power down mode */
 
@@ -253,10 +316,20 @@  static int exynos_pm_suspend(void)
 
 	/* Setting SEQ_OPTION register */
 
-	tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
-	__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
+	if (soc_is_exynos5420()) {
+		cluster_id = (read_cpuid(CPUID_MPIDR) >> 8) & 0xf;
+		if (!cluster_id)
+			__raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
+				     S5P_CENTRAL_SEQ_OPTION);
+		else
+			__raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
+				     S5P_CENTRAL_SEQ_OPTION);
+	} else if (soc_is_exynos5250()) {
+		tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
+		__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
+	}
 
-	if (!soc_is_exynos5250()) {
+	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
 		/* Save Power control register */
 		asm ("mrc p15, 0, %0, c15, c0, 0"
 		     : "=r" (tmp) : : "cc");
@@ -275,6 +348,15 @@  static void exynos_pm_resume(void)
 {
 	unsigned long tmp;
 
+	if (soc_is_exynos5420()) {
+		/* Restore the low power flag */
+		s3c_pm_do_restore(exynos5420_cpustate_save,
+			ARRAY_SIZE(exynos5420_cpustate_save));
+
+		__raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
+			S5P_CENTRAL_SEQ_OPTION);
+	}
+
 	/*
 	 * If PMU failed while entering sleep mode, WFI will be
 	 * ignored by PMU and then exiting cpu_do_idle().
@@ -290,7 +372,7 @@  static void exynos_pm_resume(void)
 		/* No need to perform below restore code */
 		goto early_wakeup;
 	}
-	if (!soc_is_exynos5250()) {
+	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
 		/* Restore Power control register */
 		tmp = save_arm_register[0];
 		asm volatile ("mcr p15, 0, %0, c15, c0, 0"
@@ -306,21 +388,40 @@  static void exynos_pm_resume(void)
 
 	/* For release retention */
 
-	__raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
-	__raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
-	__raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
-	__raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
-	__raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
-	__raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
-	__raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
+	 if (soc_is_exynos5420()) {
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_DRAM_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MAUDIO_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_JTAG_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_GPIO_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_UART_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCA_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCB_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_MMCC_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_HSI_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_EBIA_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_EBIB_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_SPI_OPTION);
+		__raw_writel((1 << 28), EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION);
+	} else {
+		__raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
+		__raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
+		__raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
+		__raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
+		__raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
+		__raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
+		__raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
+	}
 
 	if (soc_is_exynos5250())
 		s3c_pm_do_restore(exynos5_sys_save,
 			ARRAY_SIZE(exynos5_sys_save));
+	else if (soc_is_exynos5420())
+		s3c_pm_do_restore(exynos5420_sys_save,
+			ARRAY_SIZE(exynos5420_sys_save));
 
 	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
 
-	if (!soc_is_exynos5250()) {
+	if (!(soc_is_exynos5250() || soc_is_exynos5420())) {
 		exynos4_restore_pll();
 
 #ifdef CONFIG_SMP
@@ -330,6 +431,18 @@  static void exynos_pm_resume(void)
 
 early_wakeup:
 
+	if (soc_is_exynos5420()) {
+		tmp = __raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
+		tmp &= ~EXYNOS5420_UFS;
+		__raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
+		tmp = __raw_readl(EXYNOS5420_FSYS2_OPTION);
+		tmp &= ~EXYNOS5420_EMULATION;
+		__raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
+		tmp = __raw_readl(EXYNOS5420_PSGEN_OPTION);
+		tmp &= ~EXYNOS5420_EMULATION;
+		__raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
+	}
+
 	/* Clear SLEEP mode set in INFORM1 */
 	__raw_writel(0x0, S5P_INFORM1);
 
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
index e39cc75..1449404 100644
--- a/arch/arm/mach-exynos/pmu.c
+++ b/arch/arm/mach-exynos/pmu.c
@@ -16,6 +16,8 @@ 
 #include <mach/regs-clock.h>
 #include <mach/regs-pmu.h>
 
+#include <asm/cputype.h>
+
 #include "common.h"
 
 static const struct exynos_pmu_conf *exynos_pmu_config;
@@ -318,6 +320,151 @@  static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
 	{ PMU_TABLE_END,},
 };
 
+static struct exynos_pmu_conf exynos5420_pmu_config[] = {
+	/* { .reg = address, .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 void __iomem * const exynos5_list_both_cnt_feed[] = {
 	EXYNOS5_ARM_CORE0_OPTION,
 	EXYNOS5_ARM_CORE1_OPTION,
@@ -410,6 +557,20 @@  static void exynos5_init_pmu(void)
 		__raw_writel(tmp, exynos5_list_diable_wfi_wfe[i]);
 	}
 }
+/*
+ * exynos_set_core_flag - set the cluster id to IROM register
+ *			  to ensure that we wake up with the
+ *			  current cluster.
+ */
+static void exynos_set_core_flag(void)
+{
+	int cluster_id = (read_cpuid_mpidr() >> 8) & 0xf;
+
+	if (cluster_id)
+		__raw_writel(1, EXYNOS5420_IROM_DATA2);
+	else
+		__raw_writel(0, EXYNOS5420_IROM_DATA2);
+}
 
 void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 {
@@ -418,6 +579,9 @@  void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 	if (soc_is_exynos5250())
 		exynos5_init_pmu();
 
+	if (soc_is_exynos5420())
+		exynos_set_core_flag();
+
 	for (i = 0; (exynos_pmu_config[i].reg != PMU_TABLE_END) ; i++)
 		__raw_writel(exynos_pmu_config[i].val[mode],
 				exynos_pmu_config[i].reg);
@@ -520,6 +684,7 @@  static int __init exynos_pmu_init(void)
 			EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI);
 		__raw_writel(0x1, EXYNOS5420_UP_SCHEDULER);
 
+		exynos_pmu_config = exynos5420_pmu_config;
 		pr_info("EXYNOS5420 PMU Initialized\n");
 	} else {
 		pr_info("EXYNOS: PMU not supported\n");