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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Paul,

Thanks for comments, my responses inline below.

>-----Original Message-----
>From: ext Paul Walmsley [mailto:paul@xxxxxxxxx] 
>Sent: 21 January, 2010 06:35
>To: Kristo Tero (Nokia-D/Tampere)
>Cc: linux-omap@xxxxxxxxxxxxxxx; khilman@xxxxxxxxxxxxxxxxxxx
>Subject: Re: [PATCHv3 1/6] OMAP: Powerdomains: Add support for 
>INACTIVE state on pwrdm level
>
>Hi Tero,
>
>I regret the delay in reviewing.  I haven't kept up on the comments on 
>this thread, so if I've asked a question that you've already answered, 
>please feel free to point me to the response.
>
>A few comments/questions:
>
>On Fri, 15 Jan 2010, Tero Kristo wrote:
>
>> From: Tero Kristo <tero.kristo@xxxxxxxxx>
>> 
>> 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.
>> 
>> This patch also requires caching of next power state inside 
>powerdomain code,
>> as INACTIVE is not directly supported by hardware.
>
>The idea seems like a good one, and a simplification for the 
>PM code.  I'm 
>a little worried that this patch mixes hardware-programmable 
>powerdomain 
>states with logical powerdomain states.  I wonder if we would 
>be better 
>off separating, for example, the logic of putting a powerdomain into 
>INACTIVE state and any other logical powerdomain management, from the 
>physical details of how the chip is programmed.  Just looking for your 
>comments on this, not necessarily any changes in your patches in this 
>regard.
>
>> Next powerstate is thus now stored for each powerdomain in 
>next_state.
>> 
>> Signed-off-by: Tero Kristo <tero.kristo@xxxxxxxxx>
>> ---
>>  arch/arm/mach-omap2/powerdomain.c             |   32 
>++++++++++++++++++++----
>>  arch/arm/mach-omap2/powerdomains34xx.h        |   26 
>++++++++++----------
>>  arch/arm/plat-omap/include/plat/powerdomain.h |    4 +++
>>  3 files changed, 43 insertions(+), 19 deletions(-)
>> 
>> diff --git a/arch/arm/mach-omap2/powerdomain.c 
>b/arch/arm/mach-omap2/powerdomain.c
>> index 26b3f3e..a08d596 100644
>> --- a/arch/arm/mach-omap2/powerdomain.c
>> +++ b/arch/arm/mach-omap2/powerdomain.c
>> @@ -110,8 +110,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;
>> @@ -218,7 +218,9 @@ int pwrdm_register(struct powerdomain *pwrdm)
>>  
>>  	pr_debug("powerdomain: registered %s\n", pwrdm->name);
>>  	ret = 0;
>> -
>> +	pwrdm->next_state =
>> +		prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
>> +			OMAP_POWERSTATE_MASK);
>>  pr_unlock:
>>  	write_unlock_irqrestore(&pwrdm_rwlock, flags);
>>  
>> @@ -699,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]);
>
>Looks like this will force clockdomains into hardware-supervised mode, 
>even if they were originally programmed into software-supervised mode.
>Please fix this so clockdomains that were originally programmed into 
>software-supervised mode aren't inadvertently switched.

I think the change here would be to only deny/allow idle if we are in hwsup mode. Probably needs caching of the setup also. I'll do the change for this.

>
>> +
>> +	pwrdm->next_state = pwrst;
>> +
>>  	return 0;
>>  }
>>  
>> @@ -728,8 +749,7 @@ int pwrdm_read_next_pwrst(struct 
>powerdomain *pwrdm)
>>  	if (!pwrdm)
>>  		return -EINVAL;
>>  
>> -	return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
>> -					OMAP_POWERSTATE_MASK);
>> +	return pwrdm->next_state;
>>  }
>>  
>>  /**
>> diff --git a/arch/arm/mach-omap2/powerdomains34xx.h 
>b/arch/arm/mach-omap2/powerdomains34xx.h
>> index 588f7e0..f50a3f2 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,
>>  	.flags		  = PWRDM_HAS_MPU_QUIRK,
>>  	.banks		  = 1,
>> @@ -207,7 +207,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	  = {
>> @@ -215,8 +215,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 */
>
>What's the thinking behind changing these memory bank states?  
>Will some 
>code try to call pwrdm_set_mem_onst() with pwrst = INACTIVE, 
>and if so, 
>what should it do?  Similarly, if we add a 
>pwrdm_read_mem_onst(), under 
>what conditions should it return pwrst = INACTIVE?  Will we also need 
>next_state variables for all of the banks?

Did some checking on the code + TRM, and true, these memory bank states should not be altered, HW only supports certain subset of states. I will remove these pieces from the patch. This was just some bogus logic of mine thinking also these needed to be changed as I added the support for INA.


>
>>  	},
>>  };
>>  
>> @@ -225,7 +225,7 @@ static struct powerdomain 
>core_34xx_es3_1_pwrdm = {
>>  	.name		  = "core_pwrdm",
>>  	.prcm_offs	  = CORE_MOD,
>>  	.omap_chip	  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1),
>> -	.pwrsts		  = PWRSTS_OFF_RET_ON,
>> +	.pwrsts		  = PWRSTS_OFF_RET_INA_ON,
>>  	.dep_bit	  = OMAP3430_EN_CORE_SHIFT,
>>  	.flags		  = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
>>  	.banks		  = 2,
>> @@ -234,8 +234,8 @@ static struct powerdomain 
>core_34xx_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 */
>>  	},
>>  };
>>  
>> @@ -247,7 +247,7 @@ static struct powerdomain dss_pwrdm = {
>>  	.dep_bit	  = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
>>  	.wkdep_srcs	  = cam_dss_wkdeps,
>>  	.sleepdep_srcs	  = dss_per_usbhost_sleepdeps,
>> -	.pwrsts		  = PWRSTS_OFF_RET_ON,
>> +	.pwrsts		  = PWRSTS_OFF_RET_INA_ON,
>>  	.pwrsts_logic_ret = PWRDM_POWER_RET,
>>  	.banks		  = 1,
>>  	.pwrsts_mem_ret	  = {
>> @@ -287,7 +287,7 @@ static struct powerdomain cam_pwrdm = {
>>  	.prcm_offs	  = OMAP3430_CAM_MOD,
>>  	.wkdep_srcs	  = cam_dss_wkdeps,
>>  	.sleepdep_srcs	  = cam_gfx_sleepdeps,
>> -	.pwrsts		  = PWRSTS_OFF_RET_ON,
>> +	.pwrsts		  = PWRSTS_OFF_RET_INA_ON,
>>  	.pwrsts_logic_ret = PWRDM_POWER_RET,
>>  	.banks		  = 1,
>>  	.pwrsts_mem_ret	  = {
>> @@ -305,7 +305,7 @@ static struct powerdomain per_pwrdm = {
>>  	.dep_bit	  = OMAP3430_EN_PER_SHIFT,
>>  	.wkdep_srcs	  = per_usbhost_wkdeps,
>>  	.sleepdep_srcs	  = dss_per_usbhost_sleepdeps,
>> -	.pwrsts		  = PWRSTS_OFF_RET_ON,
>> +	.pwrsts		  = PWRSTS_OFF_RET_INA_ON,
>>  	.pwrsts_logic_ret = PWRSTS_OFF_RET,
>>  	.banks		  = 1,
>>  	.pwrsts_mem_ret	  = {
>> @@ -327,7 +327,7 @@ static struct powerdomain neon_pwrdm = {
>>  	.prcm_offs	  = OMAP3430_NEON_MOD,
>>  	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
>>  	.wkdep_srcs	  = neon_wkdeps,
>> -	.pwrsts		  = PWRSTS_OFF_RET_ON,
>> +	.pwrsts		  = PWRSTS_OFF_RET_INA_ON,
>>  	.pwrsts_logic_ret = PWRDM_POWER_RET,
>>  };
>>  
>> @@ -337,7 +337,7 @@ static struct powerdomain usbhost_pwrdm = {
>>  	.omap_chip	  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
>>  	.wkdep_srcs	  = per_usbhost_wkdeps,
>>  	.sleepdep_srcs	  = dss_per_usbhost_sleepdeps,
>> -	.pwrsts		  = PWRSTS_OFF_RET_ON,
>> +	.pwrsts		  = PWRSTS_OFF_RET_INA_ON,
>>  	.pwrsts_logic_ret = PWRDM_POWER_RET,
>>  	/*
>>  	 * REVISIT: Enabling usb host save and restore 
>mechanism seems to
>> diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h 
>b/arch/arm/plat-omap/include/plat/powerdomain.h
>> index 0b96005..159e4ad 100644
>> --- a/arch/arm/plat-omap/include/plat/powerdomain.h
>> +++ b/arch/arm/plat-omap/include/plat/powerdomain.h
>> @@ -39,6 +39,9 @@
>>  
>>  #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
>>  
>> +#define PWRSTS_OFF_RET_INA_ON	(PWRSTS_OFF_RET_ON | \
>> +				 (1 << PWRDM_POWER_INACTIVE))
>> +
>>  
>>  /* Powerdomain flags */
>>  #define PWRDM_HAS_HDWR_SAR	(1 << 0) /* hardware 
>save-and-restore support */
>> @@ -123,6 +126,7 @@ struct powerdomain {
>>  	struct list_head node;
>>  
>>  	int state;
>> +	int next_state;
>>  	unsigned state_counter[PWRDM_MAX_PWRSTS];
>>  
>>  #ifdef CONFIG_PM_DEBUG
>> -- 
>> 1.5.4.3
>> 
>> --
>> To unsubscribe from this list: send the line "unsubscribe 
>linux-omap" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> 
>
>regards,
>
>- Paul
>--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux