RE: [PATCHv2 5/6] OMAP: Powerdomains: Add support for checking if pwrdm/clkdm can idle

2010-01-13 Thread Tero.Kristo
 

-Original Message-
From: linux-omap-ow...@vger.kernel.org 
[mailto:linux-omap-ow...@vger.kernel.org] On Behalf Of ext Kevin Hilman
Sent: 12 January, 2010 20:57
To: Kristo Tero (Nokia-D/Tampere)
Cc: linux-omap@vger.kernel.org
Subject: Re: [PATCHv2 5/6] OMAP: Powerdomains: Add support for 
checking if pwrdm/clkdm can idle

Tero Kristo tero.kri...@nokia.com writes:

 From: Tero Kristo tero.kri...@nokia.com

 pwrdm_can_idle(pwrdm) will check if the specified 
powerdomain can enter
 idle. This is done by checking all clockdomains under the powerdomain
 if they can idle also.

 omap2_clkdm_can_idle(clkdm) will check if the specified 
clockdomain can
 enter idle. This checks the functional clock status in the 
clockdomain.

 These calls can be used e.g. inside cpuidle to decide which 
power states
 core and mpu should enter during idle, as there are certain 
dependencies
 between wakeup capabilities and reset logic.

 Signed-off-by: Tero Kristo tero.kri...@nokia.com

This looks good by me, but needs a review from Paul to go upstream with
the rest of his clockdomain/powerdomain updates for 2.6.34.

One question... I'm wondering if it might be good to also check the
CM_IDLEST_pwrdm register in the can_idle function.  Even if all
clocks are disabled, if the idle modes of the module are not 
set correctly,
it may not enter the target state.

Hmm I guess you are right here. I think at least one case would be secure 
devices which do not have FCLK control on the non-secure kernel, but their 
IDLEST would indeed block state transition. I'll investigate this a bit and 
update the patch.



Kevin

 ---
  arch/arm/mach-omap2/clockdomain.c |   24 

  arch/arm/mach-omap2/clockdomains.h|   14 ++
  arch/arm/mach-omap2/powerdomain.c |   25 
+
  arch/arm/plat-omap/include/plat/clockdomain.h |   12 
  arch/arm/plat-omap/include/plat/powerdomain.h |1 +
  5 files changed, 76 insertions(+), 0 deletions(-)

 diff --git a/arch/arm/mach-omap2/clockdomain.c 
b/arch/arm/mach-omap2/clockdomain.c
 index fcd8232..9ddeb96 100644
 --- a/arch/arm/mach-omap2/clockdomain.c
 +++ b/arch/arm/mach-omap2/clockdomain.c
 @@ -474,6 +474,30 @@ int omap2_clkdm_wakeup(struct 
clockdomain *clkdm)
  return 0;
  }
  
 +
 +/**
 + * omap2_clkdm_can_idle - check if clockdomain has any 
active clocks or not
 + * @clkdm: struct clockdomain *
 + *
 + * Checks if the clockdomain has any active clock or not, 
i.e. whether it
 + * can enter idle. Returns -EINVAL if clkdm is NULL; 0 if 
unable to idle;
 + * 1 if can idle.
 + */
 +int omap2_clkdm_can_idle(struct clockdomain *clkdm)
 +{
 +int i;
 +const int fclk_regs[] = { CM_FCLKEN, OMAP3430ES2_CM_FCLKEN3 };
 +
 +if (!clkdm)
 +return -EINVAL;
 +
 +for (i = 0; i  clkdm-fclk_reg_amt; i++)
 +if (cm_read_mod_reg(clkdm-pwrdm.ptr-prcm_offs,
 +fclk_regs[i])  
~clkdm-fclk_masks[i])
 +return 0;
 +return 1;
 +}
 +
  /**
   * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
   * @clkdm: struct clockdomain *
 diff --git a/arch/arm/mach-omap2/clockdomains.h 
b/arch/arm/mach-omap2/clockdomains.h
 index c4ee076..2cde82a 100644
 --- a/arch/arm/mach-omap2/clockdomains.h
 +++ b/arch/arm/mach-omap2/clockdomains.h
 @@ -167,6 +167,7 @@ static struct clockdomain iva2_clkdm = {
  .flags  = CLKDM_CAN_HWSUP_SWSUP,
  .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
  .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 +.fclk_reg_amt   = 1,
  };
  
  static struct clockdomain gfx_3430es1_clkdm = {
 @@ -183,6 +184,7 @@ static struct clockdomain sgx_clkdm = {
  .flags  = CLKDM_CAN_HWSUP_SWSUP,
  .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
  .omap_chip  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 +.fclk_reg_amt   = 1,
  };
  
  /*
 @@ -206,6 +208,11 @@ static struct clockdomain core_l3_34xx_clkdm = {
  .flags  = CLKDM_CAN_HWSUP,
  .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
  .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 +.fclk_reg_amt   = 2,
 +.fclk_masks = {
 +[0] = OMAP3430_EN_UART2 | OMAP3430_EN_UART1,
 +[1] = 0,
 +},
  };
  
  static struct clockdomain core_l4_34xx_clkdm = {
 @@ -222,6 +229,7 @@ static struct clockdomain dss_34xx_clkdm = {
  .flags  = CLKDM_CAN_HWSUP_SWSUP,
  .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
  .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 +.fclk_reg_amt   = 1,
  };
  
  static struct clockdomain cam_clkdm = {
 @@ -230,6 +238,7 @@ static struct clockdomain cam_clkdm = {
  .flags  = CLKDM_CAN_HWSUP_SWSUP,
  .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
  .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 +.fclk_reg_amt   = 1,
  };
  
  static struct clockdomain usbhost_clkdm = {
 @@ -238,6 +247,7

Re: [PATCHv2 5/6] OMAP: Powerdomains: Add support for checking if pwrdm/clkdm can idle

2010-01-12 Thread Kevin Hilman
Tero Kristo tero.kri...@nokia.com writes:

 From: Tero Kristo tero.kri...@nokia.com

 pwrdm_can_idle(pwrdm) will check if the specified powerdomain can enter
 idle. This is done by checking all clockdomains under the powerdomain
 if they can idle also.

 omap2_clkdm_can_idle(clkdm) will check if the specified clockdomain can
 enter idle. This checks the functional clock status in the clockdomain.

 These calls can be used e.g. inside cpuidle to decide which power states
 core and mpu should enter during idle, as there are certain dependencies
 between wakeup capabilities and reset logic.

 Signed-off-by: Tero Kristo tero.kri...@nokia.com

This looks good by me, but needs a review from Paul to go upstream with
the rest of his clockdomain/powerdomain updates for 2.6.34.

One question... I'm wondering if it might be good to also check the
CM_IDLEST_pwrdm register in the can_idle function.  Even if all
clocks are disabled, if the idle modes of the module are not set correctly,
it may not enter the target state.

Kevin

 ---
  arch/arm/mach-omap2/clockdomain.c |   24 
  arch/arm/mach-omap2/clockdomains.h|   14 ++
  arch/arm/mach-omap2/powerdomain.c |   25 
 +
  arch/arm/plat-omap/include/plat/clockdomain.h |   12 
  arch/arm/plat-omap/include/plat/powerdomain.h |1 +
  5 files changed, 76 insertions(+), 0 deletions(-)

 diff --git a/arch/arm/mach-omap2/clockdomain.c 
 b/arch/arm/mach-omap2/clockdomain.c
 index fcd8232..9ddeb96 100644
 --- a/arch/arm/mach-omap2/clockdomain.c
 +++ b/arch/arm/mach-omap2/clockdomain.c
 @@ -474,6 +474,30 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
   return 0;
  }
  
 +
 +/**
 + * omap2_clkdm_can_idle - check if clockdomain has any active clocks or not
 + * @clkdm: struct clockdomain *
 + *
 + * Checks if the clockdomain has any active clock or not, i.e. whether it
 + * can enter idle. Returns -EINVAL if clkdm is NULL; 0 if unable to idle;
 + * 1 if can idle.
 + */
 +int omap2_clkdm_can_idle(struct clockdomain *clkdm)
 +{
 + int i;
 + const int fclk_regs[] = { CM_FCLKEN, OMAP3430ES2_CM_FCLKEN3 };
 +
 + if (!clkdm)
 + return -EINVAL;
 +
 + for (i = 0; i  clkdm-fclk_reg_amt; i++)
 + if (cm_read_mod_reg(clkdm-pwrdm.ptr-prcm_offs,
 + fclk_regs[i])  ~clkdm-fclk_masks[i])
 + return 0;
 + return 1;
 +}
 +
  /**
   * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
   * @clkdm: struct clockdomain *
 diff --git a/arch/arm/mach-omap2/clockdomains.h 
 b/arch/arm/mach-omap2/clockdomains.h
 index c4ee076..2cde82a 100644
 --- a/arch/arm/mach-omap2/clockdomains.h
 +++ b/arch/arm/mach-omap2/clockdomains.h
 @@ -167,6 +167,7 @@ static struct clockdomain iva2_clkdm = {
   .flags  = CLKDM_CAN_HWSUP_SWSUP,
   .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
   .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 + .fclk_reg_amt   = 1,
  };
  
  static struct clockdomain gfx_3430es1_clkdm = {
 @@ -183,6 +184,7 @@ static struct clockdomain sgx_clkdm = {
   .flags  = CLKDM_CAN_HWSUP_SWSUP,
   .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
   .omap_chip  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 + .fclk_reg_amt   = 1,
  };
  
  /*
 @@ -206,6 +208,11 @@ static struct clockdomain core_l3_34xx_clkdm = {
   .flags  = CLKDM_CAN_HWSUP,
   .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
   .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 + .fclk_reg_amt   = 2,
 + .fclk_masks = {
 + [0] = OMAP3430_EN_UART2 | OMAP3430_EN_UART1,
 + [1] = 0,
 + },
  };
  
  static struct clockdomain core_l4_34xx_clkdm = {
 @@ -222,6 +229,7 @@ static struct clockdomain dss_34xx_clkdm = {
   .flags  = CLKDM_CAN_HWSUP_SWSUP,
   .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
   .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 + .fclk_reg_amt   = 1,
  };
  
  static struct clockdomain cam_clkdm = {
 @@ -230,6 +238,7 @@ static struct clockdomain cam_clkdm = {
   .flags  = CLKDM_CAN_HWSUP_SWSUP,
   .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
   .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 + .fclk_reg_amt   = 1,
  };
  
  static struct clockdomain usbhost_clkdm = {
 @@ -238,6 +247,7 @@ static struct clockdomain usbhost_clkdm = {
   .flags  = CLKDM_CAN_HWSUP_SWSUP,
   .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
   .omap_chip  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 + .fclk_reg_amt   = 1,
  };
  
  static struct clockdomain per_clkdm = {
 @@ -246,6 +256,10 @@ static struct clockdomain per_clkdm = {
   .flags  = CLKDM_CAN_HWSUP_SWSUP,
   .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
   .omap_chip  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 + .fclk_reg_amt   = 1,
 +