RE: [PATCHv2 1/6] OMAP: Powerdomains: Add support for INACTIVE state on pwrdm level

2010-01-13 Thread Tero.Kristo
 

>-Original Message-
>From: ext Kevin Hilman [mailto:khil...@deeprootsystems.com] 
>Sent: 12 January, 2010 20:25
>To: Kristo Tero (Nokia-D/Tampere)
>Cc: linux-omap@vger.kernel.org
>Subject: Re: [PATCHv2 1/6] OMAP: Powerdomains: Add support for 
>INACTIVE state on pwrdm level
>
>Tero Kristo  writes:
>
>> From: Tero Kristo 
>>
>> Currently only ON, RET and OFF are supported, and ON is 
>arguably broken as it
>> allows the powerdomain to enter INACTIVE state unless idle 
>is prevented.
>> Now, pwrdm code prevents idle if ON is selected, and also 
>adds support for
>> INACTIVE. This simplifies the control needed inside sleep code.
>>
>> Signed-off-by: Tero Kristo 
>
>Hi Tero,
>
>apologies for the long delay in reviewing this updated series.

No problem, I have actually been on a holiday myself so I did not really miss 
review comments that much. Thanks for taking the time to look at this.

>I really like this idea as it indeed simplifies the control code
>inside the idle path.  This also needs a review by Paul and should
>merge via his powerdomain updates for 2.6.34.
>
>The changelog should also describe that the powerdomain struct
>now caches the next_state.

Yeah, I can add this comment.

>One minor comment.  I think the introduction of signed compares in
>certain cases leads to possible confusion and readability problems.
>
>I'm not sure I realy follow the need for the invalid state.  Instead
>of setting next_state to -1 in pwrdm_register, why not read the
>current HW value and use that as the starting value?

I guess this invalid stuff comes from my old lazy initialization habits. :) But 
yes, I can change this into a format where we just read the current value from 
the register.

>If the invalid state is really needed, instead of using -1 and having
>to change to using signed comparisons in certain cases, it seems like
>we could just define a new invalid state as zero, and move the others
>up a notch.

This is probably not good, as it would break the direct SW to HW value mapping, 
so I will go with the previous one.

>
>Then, use something like this to check for a valid state:
>
>static inline bool pwrdm_is_valid_state(struct powerdomain *pwrdm) {
>   return (pwrdm->state > PWRDM_POWER_INVALID) ? true : false;
>}
>
>Kevin
>
>> ---
>>  arch/arm/mach-omap2/powerdomain.c |   32 
>+
>>  arch/arm/mach-omap2/powerdomains34xx.h|   26 
>++--
>>  arch/arm/plat-omap/include/plat/powerdomain.h |6 -
>>  3 files changed, 45 insertions(+), 19 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/powerdomain.c 
>b/arch/arm/mach-omap2/powerdomain.c
>> index b6990e3..1237717 100644
>> --- a/arch/arm/mach-omap2/powerdomain.c
>> +++ b/arch/arm/mach-omap2/powerdomain.c
>> @@ -112,8 +112,8 @@ static struct powerdomain 
>*_pwrdm_deps_lookup(struct powerdomain *pwrdm,
>>  static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
>>  {
>>  
>> -int prev;
>> -int state;
>> +u8 prev;
>> +u8 state;
>>  
>>  if (pwrdm == NULL)
>>  return -EINVAL;
>> @@ -220,7 +220,7 @@ int pwrdm_register(struct powerdomain *pwrdm)
>>  
>>  pr_debug("powerdomain: registered %s\n", pwrdm->name);
>>  ret = 0;
>> -
>> +pwrdm->next_state = -1;
>
>>  pr_unlock:
>>  write_unlock_irqrestore(&pwrdm_rwlock, flags);
>>  
>> @@ -701,19 +701,38 @@ int pwrdm_get_mem_bank_count(struct 
>powerdomain *pwrdm)
>>   */
>>  int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
>>  {
>> +u8 prg_pwrst;
>> +
>>  if (!pwrdm)
>>  return -EINVAL;
>>  
>> +if (pwrdm->next_state == pwrst)
>> +return 0;
>> +
>>  if (!(pwrdm->pwrsts & (1 << pwrst)))
>>  return -EINVAL;
>>  
>>  pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
>>   pwrdm->name, pwrst);
>>  
>> +/* INACTIVE is reserved, so we program pwrdm as ON */
>> +if (pwrst == PWRDM_POWER_INACTIVE)
>> +prg_pwrst = PWRDM_POWER_ON;
>> +else
>> +prg_pwrst = pwrst;
>> +
>>  prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
>> - (pwrst << OMAP_POWERSTATE_SHIFT),
>> + (prg_pwrst << OMAP_POWERSTATE_SHIFT),
>>   pwrdm->prcm_offs, PM_PWSTCTRL);
>>  
>> +/* If next st

Re: [PATCHv2 1/6] OMAP: Powerdomains: Add support for INACTIVE state on pwrdm level

2010-01-12 Thread Kevin Hilman
Tero Kristo  writes:

> From: Tero Kristo 
>
> Currently only ON, RET and OFF are supported, and ON is arguably broken as it
> allows the powerdomain to enter INACTIVE state unless idle is prevented.
> Now, pwrdm code prevents idle if ON is selected, and also adds support for
> INACTIVE. This simplifies the control needed inside sleep code.
>
> Signed-off-by: Tero Kristo 

Hi Tero,

apologies for the long delay in reviewing this updated series.

I really like this idea as it indeed simplifies the control code
inside the idle path.  This also needs a review by Paul and should
merge via his powerdomain updates for 2.6.34.

The changelog should also describe that the powerdomain struct
now caches the next_state.

One minor comment.  I think the introduction of signed compares in
certain cases leads to possible confusion and readability problems.

I'm not sure I realy follow the need for the invalid state.  Instead
of setting next_state to -1 in pwrdm_register, why not read the
current HW value and use that as the starting value?

If the invalid state is really needed, instead of using -1 and having
to change to using signed comparisons in certain cases, it seems like
we could just define a new invalid state as zero, and move the others
up a notch.

Then, use something like this to check for a valid state:

static inline bool pwrdm_is_valid_state(struct powerdomain *pwrdm) {
   return (pwrdm->state > PWRDM_POWER_INVALID) ? true : false;
}

Kevin

> ---
>  arch/arm/mach-omap2/powerdomain.c |   32 
> +
>  arch/arm/mach-omap2/powerdomains34xx.h|   26 ++--
>  arch/arm/plat-omap/include/plat/powerdomain.h |6 -
>  3 files changed, 45 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/powerdomain.c 
> b/arch/arm/mach-omap2/powerdomain.c
> index b6990e3..1237717 100644
> --- a/arch/arm/mach-omap2/powerdomain.c
> +++ b/arch/arm/mach-omap2/powerdomain.c
> @@ -112,8 +112,8 @@ static struct powerdomain *_pwrdm_deps_lookup(struct 
> powerdomain *pwrdm,
>  static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
>  {
>  
> - int prev;
> - int state;
> + u8 prev;
> + u8 state;
>  
>   if (pwrdm == NULL)
>   return -EINVAL;
> @@ -220,7 +220,7 @@ int pwrdm_register(struct powerdomain *pwrdm)
>  
>   pr_debug("powerdomain: registered %s\n", pwrdm->name);
>   ret = 0;
> -
> + pwrdm->next_state = -1;

>  pr_unlock:
>   write_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
> @@ -701,19 +701,38 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
>   */
>  int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
>  {
> + u8 prg_pwrst;
> +
>   if (!pwrdm)
>   return -EINVAL;
>  
> + if (pwrdm->next_state == pwrst)
> + return 0;
> +
>   if (!(pwrdm->pwrsts & (1 << pwrst)))
>   return -EINVAL;
>  
>   pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
>pwrdm->name, pwrst);
>  
> + /* INACTIVE is reserved, so we program pwrdm as ON */
> + if (pwrst == PWRDM_POWER_INACTIVE)
> + prg_pwrst = PWRDM_POWER_ON;
> + else
> + prg_pwrst = pwrst;
> +
>   prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
> -  (pwrst << OMAP_POWERSTATE_SHIFT),
> +  (prg_pwrst << OMAP_POWERSTATE_SHIFT),
>pwrdm->prcm_offs, PM_PWSTCTRL);
>  
> + /* If next state is ON, prevent idle */
> + if (pwrst == PWRDM_POWER_ON)
> + omap2_clkdm_deny_idle(pwrdm->pwrdm_clkdms[0]);
> + else
> + omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
> +
> + pwrdm->next_state = pwrst;
> +
>   return 0;
>  }
>  
> @@ -730,8 +749,11 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
>   if (!pwrdm)
>   return -EINVAL;
>  
> + if (pwrdm->next_state > -1)
> + return pwrdm->next_state;
> +
>   return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
> - OMAP_POWERSTATE_MASK);
> +OMAP_POWERSTATE_MASK);
>  }
>  
>  /**
> diff --git a/arch/arm/mach-omap2/powerdomains34xx.h 
> b/arch/arm/mach-omap2/powerdomains34xx.h
> index fd09b08..9eb2dc5 100644
> --- a/arch/arm/mach-omap2/powerdomains34xx.h
> +++ b/arch/arm/mach-omap2/powerdomains34xx.h
> @@ -165,7 +165,7 @@ static struct powerdomain iva2_pwrdm = {
>   .omap_chip= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
>   .dep_bit  = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
>   .wkdep_srcs   = iva2_wkdeps,
> - .pwrsts   = PWRSTS_OFF_RET_ON,
> + .pwrsts   = PWRSTS_OFF_RET_INA_ON,
>   .pwrsts_logic_ret = PWRSTS_OFF_RET,
>   .banks= 4,
>   .pwrsts_mem_ret   = {
> @@ -188,7 +188,7 @@ static struct powerdomain mpu_34xx_pwrdm = {
>   .omap_chip= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
>   

[PATCHv2 1/6] OMAP: Powerdomains: Add support for INACTIVE state on pwrdm level

2009-12-04 Thread Tero Kristo
From: Tero Kristo 

Currently only ON, RET and OFF are supported, and ON is arguably broken as it
allows the powerdomain to enter INACTIVE state unless idle is prevented.
Now, pwrdm code prevents idle if ON is selected, and also adds support for
INACTIVE. This simplifies the control needed inside sleep code.

Signed-off-by: Tero Kristo 
---
 arch/arm/mach-omap2/powerdomain.c |   32 +
 arch/arm/mach-omap2/powerdomains34xx.h|   26 ++--
 arch/arm/plat-omap/include/plat/powerdomain.h |6 -
 3 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c 
b/arch/arm/mach-omap2/powerdomain.c
index b6990e3..1237717 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -112,8 +112,8 @@ static struct powerdomain *_pwrdm_deps_lookup(struct 
powerdomain *pwrdm,
 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 {
 
-   int prev;
-   int state;
+   u8 prev;
+   u8 state;
 
if (pwrdm == NULL)
return -EINVAL;
@@ -220,7 +220,7 @@ int pwrdm_register(struct powerdomain *pwrdm)
 
pr_debug("powerdomain: registered %s\n", pwrdm->name);
ret = 0;
-
+   pwrdm->next_state = -1;
 pr_unlock:
write_unlock_irqrestore(&pwrdm_rwlock, flags);
 
@@ -701,19 +701,38 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
  */
 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 {
+   u8 prg_pwrst;
+
if (!pwrdm)
return -EINVAL;
 
+   if (pwrdm->next_state == pwrst)
+   return 0;
+
if (!(pwrdm->pwrsts & (1 << pwrst)))
return -EINVAL;
 
pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
 pwrdm->name, pwrst);
 
+   /* INACTIVE is reserved, so we program pwrdm as ON */
+   if (pwrst == PWRDM_POWER_INACTIVE)
+   prg_pwrst = PWRDM_POWER_ON;
+   else
+   prg_pwrst = pwrst;
+
prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
-(pwrst << OMAP_POWERSTATE_SHIFT),
+(prg_pwrst << OMAP_POWERSTATE_SHIFT),
 pwrdm->prcm_offs, PM_PWSTCTRL);
 
+   /* If next state is ON, prevent idle */
+   if (pwrst == PWRDM_POWER_ON)
+   omap2_clkdm_deny_idle(pwrdm->pwrdm_clkdms[0]);
+   else
+   omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+
+   pwrdm->next_state = pwrst;
+
return 0;
 }
 
@@ -730,8 +749,11 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
if (!pwrdm)
return -EINVAL;
 
+   if (pwrdm->next_state > -1)
+   return pwrdm->next_state;
+
return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
-   OMAP_POWERSTATE_MASK);
+  OMAP_POWERSTATE_MASK);
 }
 
 /**
diff --git a/arch/arm/mach-omap2/powerdomains34xx.h 
b/arch/arm/mach-omap2/powerdomains34xx.h
index fd09b08..9eb2dc5 100644
--- a/arch/arm/mach-omap2/powerdomains34xx.h
+++ b/arch/arm/mach-omap2/powerdomains34xx.h
@@ -165,7 +165,7 @@ static struct powerdomain iva2_pwrdm = {
.omap_chip= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.dep_bit  = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
.wkdep_srcs   = iva2_wkdeps,
-   .pwrsts   = PWRSTS_OFF_RET_ON,
+   .pwrsts   = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks= 4,
.pwrsts_mem_ret   = {
@@ -188,7 +188,7 @@ static struct powerdomain mpu_34xx_pwrdm = {
.omap_chip= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.dep_bit  = OMAP3430_EN_MPU_SHIFT,
.wkdep_srcs   = mpu_34xx_wkdeps,
-   .pwrsts   = PWRSTS_OFF_RET_ON,
+   .pwrsts   = PWRSTS_OFF_RET_INA_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks= 1,
.pwrsts_mem_ret   = {
@@ -206,7 +206,7 @@ static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
.omap_chip= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
   CHIP_IS_OMAP3430ES2 |
   CHIP_IS_OMAP3430ES3_0),
-   .pwrsts   = PWRSTS_OFF_RET_ON,
+   .pwrsts   = PWRSTS_OFF_RET_INA_ON,
.dep_bit  = OMAP3430_EN_CORE_SHIFT,
.banks= 2,
.pwrsts_mem_ret   = {
@@ -214,8 +214,8 @@ static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
[1] = PWRSTS_OFF_RET,/* MEM2RETSTATE */
},
.pwrsts_mem_on= {
-   [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
-   [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+   [0] = PWRSTS_OFF_RET_INA_ON, /* MEM1ONSTATE */
+   [1] = PWRSTS_OFF_RET_INA_ON, /* MEM2ONSTATE */
},
 };
 
@@ -224,7 +224,7 @