All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomasz Figa <tomasz.figa@gmail.com>
To: Abhilash Kesavan <a.kesavan@samsung.com>
Cc: kgene.kim@samsung.com, linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, dianders@chromium.org,
	olof@lixom.net
Subject: Re: [PATCH 1/2] ARM: EXYNOS: Support Suspend-to-RAM on EXYNOS5420
Date: Fri, 20 Dec 2013 22:37:31 +0100	[thread overview]
Message-ID: <5028127.MZKgFYSMAv@flatron> (raw)
In-Reply-To: <1387195271-3613-1-git-send-email-a.kesavan@samsung.com>

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

WARNING: multiple messages have this Message-ID (diff)
From: tomasz.figa@gmail.com (Tomasz Figa)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] ARM: EXYNOS: Support Suspend-to-RAM on EXYNOS5420
Date: Fri, 20 Dec 2013 22:37:31 +0100	[thread overview]
Message-ID: <5028127.MZKgFYSMAv@flatron> (raw)
In-Reply-To: <1387195271-3613-1-git-send-email-a.kesavan@samsung.com>

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

  parent reply	other threads:[~2013-12-20 21:37 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-16 12:01 [PATCH 1/2] ARM: EXYNOS: Support Suspend-to-RAM on EXYNOS5420 Abhilash Kesavan
2013-12-16 12:01 ` Abhilash Kesavan
2013-12-16 12:01 ` [PATCH 2/2] ARM: dts: Add node for GPIO keys on SMDK5420 Abhilash Kesavan
2013-12-16 12:01   ` Abhilash Kesavan
2013-12-16 12:48 ` [PATCH 1/2] ARM: EXYNOS: Support Suspend-to-RAM on EXYNOS5420 Bartlomiej Zolnierkiewicz
2013-12-16 12:48   ` Bartlomiej Zolnierkiewicz
2013-12-17  3:10   ` Abhilash Kesavan
2013-12-17  3:10     ` Abhilash Kesavan
2013-12-20 10:26     ` sunil joshi
2013-12-20 10:26       ` sunil joshi
2013-12-20 11:38       ` Abhilash Kesavan
2013-12-20 11:38         ` Abhilash Kesavan
2013-12-20 11:53         ` sunil joshi
2013-12-20 11:53           ` sunil joshi
2013-12-20 21:22         ` Olof Johansson
2013-12-20 21:22           ` Olof Johansson
2013-12-20 21:23           ` Tomasz Figa
2013-12-20 21:23             ` Tomasz Figa
2013-12-20 21:25             ` Olof Johansson
2013-12-20 21:25               ` Olof Johansson
2013-12-20 21:25               ` Tomasz Figa
2013-12-20 21:25                 ` Tomasz Figa
2013-12-21  7:06           ` Abhilash Kesavan
2013-12-21  7:06             ` Abhilash Kesavan
2013-12-20 21:19       ` Tomasz Figa
2013-12-20 21:19         ` Tomasz Figa
2013-12-20 21:37         ` Olof Johansson
2013-12-20 21:37           ` Olof Johansson
2013-12-20 21:53           ` Tomasz Figa
2013-12-20 21:53             ` Tomasz Figa
2013-12-21  7:40             ` Abhilash Kesavan
2013-12-21  7:40               ` Abhilash Kesavan
2013-12-21  1:15         ` Doug Anderson
2013-12-21  1:15           ` Doug Anderson
     [not found]           ` <CAPQV+nO=Xe=z669QxCJSerrm-xP0b=WtyPveyh2uTcM2B3i5KQ@mail.gmail.com>
2014-01-18  2:44             ` Abhilash Kesavan
2014-01-18  2:44               ` Abhilash Kesavan
2013-12-16 13:27 ` Vaibhav Bedia
2013-12-16 13:27   ` Vaibhav Bedia
2013-12-16 16:15   ` Tomasz Figa
2013-12-16 16:15     ` Tomasz Figa
2013-12-20 21:37 ` Tomasz Figa [this message]
2013-12-20 21:37   ` Tomasz Figa
2013-12-21  7:18   ` Abhilash Kesavan
2013-12-21  7:18     ` Abhilash Kesavan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5028127.MZKgFYSMAv@flatron \
    --to=tomasz.figa@gmail.com \
    --cc=a.kesavan@samsung.com \
    --cc=dianders@chromium.org \
    --cc=kgene.kim@samsung.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=olof@lixom.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.