[PATCH 1/2] ARM: EXYNOS: Add initial support of PMU for Exynos5260

Vikas Sajjan sajjan.linux at gmail.com
Tue Dec 31 01:06:00 EST 2013


Hi Tomasz,

On Wed, Dec 18, 2013 at 10:05 PM, Tomasz Figa <t.figa at samsung.com> wrote:
> Hi Vikas, Pankaj,
>
> On Wednesday 11 of December 2013 16:25:15 Vikas Sajjan wrote:
>> Adds initial PMU support for Exynos5260
>>
>> Following are the changes done
>> ------------------------------
>>
>> 1) Added initial PMU support for exynos5260
>>
>> 2) Added exynos5260_iodesc for mapping 5260 specific SFRs. We modified
>> exynos5_map_io so that in case of exynos5260 only exynos5260_iodesc can
>> be initialized.
>>
>> 3) Added new macros for WAKEUP MASK for 5260, and modified exynos_pm_drvinit
>> accrodingly.
>>
>> Change-Id: Ie585d47a499c17813cfe0e5a668072ca7b13ffb5
>
> This line should be removed.


Yeah, right.


>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>> Signed-off-by: Vikas Sajjan <vikas.sajjan at samsung.com>
>> ---
>>  arch/arm/mach-exynos/common.c                |  89 ++++++++++-
>>  arch/arm/mach-exynos/common.h                |   5 +
>>  arch/arm/mach-exynos/include/mach/map.h      |  17 +++
>>  arch/arm/mach-exynos/include/mach/regs-pmu.h | 221 +++++++++++++++++++++++++++
>>  arch/arm/mach-exynos/pm.c                    |  33 +++-
>>  arch/arm/mach-exynos/pmu.c                   | 140 +++++++++++++++++
>>  arch/arm/plat-samsung/include/plat/map-s5p.h |  14 ++
>>  7 files changed, 508 insertions(+), 11 deletions(-)
> [snip]
>> +     }, {
>> +             .virtual        = (unsigned long)S5P_VA_SROMC,
>> +             .pfn            = __phys_to_pfn(EXYNOS5260_PA_SROMC),
>> +             .length         = SZ_4K,
>> +             .type           = MT_DEVICE,
>> +     }, {
>> +             .virtual        = (unsigned long)S5P_VA_SYSRAM,
>> +             .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
>> +             .length         = SZ_4K,
>> +             .type           = MT_DEVICE,
>> +     }, {
>>               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
>>               .pfn            = __phys_to_pfn(EXYNOS5260_PA_SYSRAM_NS),
>>               .length         = SZ_4K,
>>               .type           = MT_DEVICE,
>> +     }, {
>> +             .virtual        = (unsigned long)S5P_VA_PMU,
>> +             .pfn            = __phys_to_pfn(EXYNOS5260_PA_PMU),
>> +             .length         = SZ_64K,
>> +             .type           = MT_DEVICE,
>>       },
>
> Do you really need all these static mappings above? Why can't you create
> a mapping dynamically?

Sure, will keep only required static mapping like PMU.


>
>>  };
>>
> [snip]
>>  struct bus_type exynos_subsys = {
>> diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
>> index ff9b6a9..e2cabfe 100644
>> --- a/arch/arm/mach-exynos/common.h
>> +++ b/arch/arm/mach-exynos/common.h
>> @@ -47,6 +47,11 @@ enum sys_powerdown {
>>       NUM_SYS_POWERDOWN,
>>  };
>>
>> +enum running_cpu {
>> +     KFC,
>> +     ARM,
>> +};
>
> This isn't too meaningful. You should write a comment saying how this enum
> is used and describing its values.
>
> Also the name is too generic. It should be prefixed with exynos5260_
> probably.


Sure, will modify it as EXYNOS5_KFC and EXYNOS5_ARM, so that it can be
used by 5420 also, if needed.


>
>> +
>>  extern unsigned long l2x0_regs_phys;
>>  struct exynos_pmu_conf {
>>       void __iomem *reg;
>> diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
>> index bd6fa02..cc190b9 100644
>> --- a/arch/arm/mach-exynos/include/mach/map.h
>> +++ b/arch/arm/mach-exynos/include/mach/map.h
>> @@ -31,6 +31,23 @@
>>  #define EXYNOS5250_PA_SYSRAM_NS              0x0204F000
>>  #define EXYNOS5260_PA_SYSRAM_NS              0x02073000
>>
>> +#define EXYNOS5260_PA_PMU                            0x10D50000
>> +#define EXYNOS5260_PA_SROMC                          0x12180000
>> +#define EXYNOS5260_PA_PWM                            0x12D90000
>> +
>> +#define EXYNOS5260_PA_SYS_PERI                               0x10220000
>> +#define EXYNOS5260_PA_SYS_MIF                                0x10D00000
>> +#define EXYNOS5260_PA_SYS_MFC                                0x110A0000
>> +#define EXYNOS5260_PA_SYS_KFC                                0x10710000
>> +#define EXYNOS5260_PA_SYS_ISP                                0x133E0000
>> +#define EXYNOS5260_PA_SYS_GSCL                               0x13F20000
>> +#define EXYNOS5260_PA_SYS_G3D                                0x11850000
>> +#define EXYNOS5260_PA_SYS_G2D                                0x10A20000
>> +#define EXYNOS5260_PA_SYS_FSYS                               0x122F0000
>> +#define EXYNOS5260_PA_SYS_EGL                                0x10610000
>> +#define EXYNOS5260_PA_SYS_DISP                               0x14540000
>> +#define EXYNOS5260_PA_SYS_AUD                                0x128F0000
>> +
>
> Do you really need all the static addresses above?

Will remove them.


>
>>  #define EXYNOS_PA_CHIPID             0x10000000
>>
>>  #define EXYNOS4_PA_SYSCON            0x10010000
>> diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
>> index 09ae29a..ac53f85 100644
>> --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
>> +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
>> @@ -125,6 +125,25 @@
>>  #define S5P_ARM_CORE1_STATUS                 S5P_PMUREG(0x2084)
>>  #define S5P_ARM_CORE1_OPTION                 S5P_PMUREG(0x2088)
> [snip]
>> +#define EXYNOS5260_CORE_LOCAL_PWR_EN                         0xf
>> +#define EXYNOS5260_CPUS_PER_CLUSTER                          4
>> +#define EXYNOS5260_USE_DELAYED_RESET_ASSERTION                       (1 << 12)
>> +
>> +#define EXYNOS5260_WAKEUP_STAT2                      S5P_PMUREG(0x0604)
>> +#define EXYNOS5260_WAKEUP_STAT3                      S5P_PMUREG(0x0608)
>> +#define EXYNOS5260_EINT_WAKEUP_MASK          S5P_PMUREG(0x060C)
>> +#define EXYNOS5260_WAKEUP_MASK                       S5P_PMUREG(0x0610)
>> +#define EXYNOS5260_WAKEUP_MASK2                      S5P_PMUREG(0x0614)
>> +#define EXYNOS5260_WAKEUP_MASK3                      S5P_PMUREG(0x0618)
>> +
>> +
>> +/* Exynos5260 specific PMU SYS_PWR_REGs */
>> +#define      EXYNOS5260_A15_EGL0_SYS_PWR_REG                 S5P_PMUREG(0x1000)
>
> CodingStyle: There should be just one space between #define and definiton
> name. The same for a lot of definitons below.

OK.

>
>> +#define      EXYNOS5260_DIS_IRQ_A15_EGL0_LOCAL_SYS_PWR_REG   S5P_PMUREG(0x1004)
>> +#define      EXYNOS5260_DIS_IRQ_A15_EGL0_CNTRL_SYS_PWR_REG   S5P_PMUREG(0x1008)
>> +#define      EXYNOS5260_DIS_IRQ_A15_EGL0_EGLSEQ_SYS_PWR_REG  S5P_PMUREG(0x100C)
>> +#define      EXYNOS5260_A15_EGL1_SYS_PWR_REG                 S5P_PMUREG(0x1010)
> [snip]
>> +/* CENTRAL_SEQ_OPTION */
>> +#define EXYNOS5260_ARM_USE_STANDBY_WFI0                      (1 << 16)
>> +#define EXYNOS5260_ARM_USE_STANDBY_WFI1                      (1 << 17)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFI0                      (1 << 20)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFI1                      (1 << 21)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFI2                      (1 << 22)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFI3                      (1 << 23)
>> +#define EXYNOS5260_ARM_USE_STANDBY_WFE0                      (1 << 24)
>> +#define EXYNOS5260_ARM_USE_STANDBY_WFE1                      (1 << 25)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFE0                      (1 << 28)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFE1                      (1 << 29)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFE2                      (1 << 30)
>> +#define EXYNOS5260_KFC_USE_STANDBY_WFE3                      (1 << 31)
>> +
>> +#define EXYNOS5260_USE_STANDBY_WFI_ALL       (EXYNOS5260_ARM_USE_STANDBY_WFI0  \
>> +                                     | EXYNOS5260_ARM_USE_STANDBY_WFI1  \
>> +                                     | EXYNOS5260_KFC_USE_STANDBY_WFI0  \
>> +                                     | EXYNOS5260_KFC_USE_STANDBY_WFI1  \
>> +                                     | EXYNOS5260_KFC_USE_STANDBY_WFI2  \
>> +                                     | EXYNOS5260_KFC_USE_STANDBY_WFI3)
>
> This is not a definition of registers, so should be present in the file
> using it as a convenience macro.

OK.


>
>> +
>> +
>>  #endif /* __ASM_ARCH_REGS_PMU_H */
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index 78a22bf..c6def953 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -58,7 +58,7 @@ static int exynos_cpu_suspend(unsigned long arg)
>>       outer_flush_all();
>>  #endif
> [snip]
>>       /* Setting SEQ_OPTION register */
>> +     if (soc_is_exynos5250()) {
>> +             tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
>> +             __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
>> +     } else if (soc_is_exynos5260()) {
>> +             cluster_id = (read_cpuid(CPUID_MPIDR) >> 8) & 0xf;
>> +             if (!cluster_id)
>> +                     __raw_writel(EXYNOS5260_ARM_USE_STANDBY_WFI0,
>> +                                  S5P_CENTRAL_SEQ_OPTION);
>> +             else
>> +                     __raw_writel(EXYNOS5260_KFC_USE_STANDBY_WFI0,
>> +                                  S5P_CENTRAL_SEQ_OPTION);
>
> Hmm, this seems strange. Shouldn't just a single particular CPU (CPU0 most
> likely) be allowed to enter standby such as the code for other Exynos SoCs
> is doing?

We need to handle the case where the primary CPU can be KFC also.

>
>>
>> -     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_exynos5260()) {
>
> Is this condition really correct? It doesn't make much sense.

Will modify.


>
>>               /* Save Power control register */
>>               asm ("mrc p15, 0, %0, c15, c0, 0"
>>                    : "=r" (tmp) : : "cc");
>> @@ -174,7 +191,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_exynos5260()) {
>
> Ditto.

Will modify.


>
>>               /* Restore Power control register */
>>               tmp = save_arm_register[0];
>>               asm volatile ("mcr p15, 0, %0, c15, c0, 0"
>> diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
>> index 97d6885..c828d07 100644
>> --- a/arch/arm/mach-exynos/pmu.c
>> +++ b/arch/arm/mach-exynos/pmu.c
>> @@ -317,6 +317,99 @@ static struct exynos_pmu_conf exynos5250_pmu_config[] = {
>>       { PMU_TABLE_END,},
>>  };
> [snip]
>> +static void exynos5260_reset_assert_ctrl(bool on, enum running_cpu cluster)
>> +{
>> +     unsigned int i;
>> +     unsigned int option;
>> +     unsigned int cpu_s, cpu_f;
>> +
>> +     if (cluster == KFC) {
>> +             cpu_s = EXYNOS5260_CPUS_PER_CLUSTER;
>> +             cpu_f = cpu_s + EXYNOS5260_CPUS_PER_CLUSTER;
>> +     } else {
>> +             cpu_s = 0;
>> +             cpu_f = 2;
>
> Hmm, a magic number. I wonder what it means. It doesn't seem to be the
> Answer to the Ultimate Question of Life, The Universe, and Everything,
> though. ;)


:-) Will modify.



>
> [1] http://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker's_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life.2C_the_Universe.2C_and_Everything_.2842.29
>
>> +     }
>> +
>> +     for (i = cpu_s; i < cpu_f; i++) {
>> +             option = __raw_readl(EXYNOS_ARM_CORE_OPTION(i));
>> +             option = on ?
>> +             (option | EXYNOS5260_USE_DELAYED_RESET_ASSERTION) :
>> +                     (option & ~EXYNOS5260_USE_DELAYED_RESET_ASSERTION);
>
> Readability of this is quite poor. I'd recommend rewriting this to
> a simple


Sure.


>
>                 if (on)
>                         option |= EXYNOS5260_USE_DELAYED_RESET_ASSERTION;
>                 else
>                         option &= ~EXYNOS5260_USE_DELAYED_RESET_ASSERTION;
>
>> +             __raw_writel(option, EXYNOS_ARM_CORE_OPTION(i));
>> +     }
>> +}
>> +
>> +
>>  static int __init exynos_pmu_init(void)
>>  {
>>       unsigned int value;
>> @@ -415,6 +532,29 @@ static int __init exynos_pmu_init(void)
>>
>>               exynos_pmu_config = exynos5250_pmu_config;
>>               pr_info("EXYNOS5250 PMU Initialize\n");
>> +     } else if (soc_is_exynos5260()) {
>> +             /* Enable USE_STANDBY_WFI for all CORE */
>> +             __raw_writel(EXYNOS5260_USE_STANDBY_WFI_ALL,
>> +                     S5P_CENTRAL_SEQ_OPTION);
>> +             /*
>> +              * Set PSHOLD port for output high
>> +              */
>> +             value = __raw_readl(EXYNOS_PS_HOLD_CONTROL);
>> +             value |= EXYNOS_PS_HOLD_OUTPUT_HIGH;
>> +             __raw_writel(value, EXYNOS_PS_HOLD_CONTROL);
>> +
>> +             /*
>> +              * Enable signal for PSHOLD port
>> +              */
>> +             value = __raw_readl(EXYNOS_PS_HOLD_CONTROL);
>> +             value |= EXYNOS_PS_HOLD_EN;
>> +             __raw_writel(value, EXYNOS_PS_HOLD_CONTROL);
>
> Hmm, do you really need this? What about boards with different polarity
> of power hold signal in used PMIC? I believe this should be set correctly
> by the bootloader and never changed later, except in power off callback.

Right, can be removed.


>
> Best regards,
> Tomasz
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



More information about the linux-arm-kernel mailing list