Re: [PATCH 14/16] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence.

2010-03-02 Thread Kevin Hilman
Thara Gopinath th...@ti.com writes:

 This patch introduces OMAP3 specific values for Smartreflex and
 Voltage processor registers as per the latest TI recommendations.
 This patch also improves the smartreflex and voltage processor
 enable disable sequences as per the latest recommendations.

 These recommendations were first formed based on experimentations
 on Nokia Rover platform  and were implemented in the Rover code
 base first by Nishanth Menon and Paul Walmsley.

I think this was pointed out by others, but Rover should be replaced
with n900.

 Signed-off-by: Thara Gopinath th...@ti.com
 ---
  arch/arm/mach-omap2/smartreflex.c |   65 -
  arch/arm/mach-omap2/smartreflex.h |6 +-
  arch/arm/mach-omap2/voltage.c |   95 ++--
  arch/arm/mach-omap2/voltage.h |   16 ---
  4 files changed, 142 insertions(+), 40 deletions(-)

 diff --git a/arch/arm/mach-omap2/smartreflex.c 
 b/arch/arm/mach-omap2/smartreflex.c
 index 8a4c48b..ca2223d 100644
 --- a/arch/arm/mach-omap2/smartreflex.c
 +++ b/arch/arm/mach-omap2/smartreflex.c
 @@ -24,6 +24,7 @@
  #include linux/io.h
  #include linux/list.h
  #include linux/debugfs.h
 +#include linux/delay.h
  
  #include plat/control.h
  #include plat/omap_hwmod.h
 @@ -32,6 +33,7 @@
  #include smartreflex.h
  
  #define SMARTREFLEX_NAME_LEN 16
 +#define SR_DISABLE_TIMEOUT   200
  
  struct omap_sr {
   int srid;
 @@ -184,11 +186,9 @@ static void sr_set_regfields(struct omap_sr *sr)
   sr-err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
   sr-accum_data = OMAP3430_SR_ACCUMDATA;
   if (sr-srid == SR1) {
 - sr-err_minlimit = OMAP3430_SR1_ERRMINLIMIT;
   sr-senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
   sr-senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
   } else {
 - sr-err_minlimit = OMAP3430_SR2_ERRMINLIMIT;
   sr-senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
   sr-senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
   }
 @@ -280,11 +280,6 @@ static void sr_start_vddautocomap(int srid)
   return;
   }
  
 - if (sr-is_sr_reset == 1) {
 - sr_clk_enable(sr);
 - sr_configure(sr);
 - }
 -
   sr-is_autocomp_active = 1;
   if (!sr_class-enable(srid)) {
   sr-is_autocomp_active = 0;
 @@ -351,8 +346,20 @@ int sr_enable(int srid, u32 target_opp_no)
   return false;
   }
  
 - nvalue_reciprocal = pdata-sr_nvalue[target_opp_no - 1];
 + /*
 +  * For OMAP3430 errminlimit is dependent on opp. So choose
 +  * it appropriately
 +  */
 + if (cpu_is_omap343x())
 + sr-err_minlimit = (target_opp_no  2) ?
 + OMAP3430_SR_ERRMINLIMIT_HIGHOPP :
 + OMAP3430_SR_ERRMINLIMIT_LOWOPP;
 +
 + /* Enable the clocks and configure SR */
 + sr_clk_enable(sr);
 + sr_configure(sr);
  
 + nvalue_reciprocal = pdata-sr_nvalue[target_opp_no - 1];
   if (nvalue_reciprocal == 0) {
   pr_notice(OPP%d doesn't support SmartReflex\n,
   target_opp_no);
 @@ -375,10 +382,44 @@ int sr_enable(int srid, u32 target_opp_no)
  void sr_disable(int srid)
  {
   struct omap_sr *sr = _sr_lookup(srid);
 + int timeout = 0;
 +
 + /* Check if SR is already disabled. If yes do nothing */
 + if (!(sr_read_reg(sr, SRCONFIG)  SRCONFIG_SRENABLE))
 + return;
 +
 + /* Enable MCUDisableAcknowledge interrupt */
 + sr_modify_reg(sr, ERRCONFIG,
 + ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
  
 - sr-is_sr_reset = 1;
   /* SRCONFIG - disable SR */
 - sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
 + sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
 +
 + /* Disable all other SR interrupts and clear the status */
 + sr_modify_reg(sr, ERRCONFIG,
 + (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
 + ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN),
 + (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
 + ERRCONFIG_MCUBOUNDINTST | ERRCONFIG_VPBOUNDINTST));
 +
 + /* Wait for SR to be disabled.
 +  * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
 +  */
 + while ((timeout  SR_DISABLE_TIMEOUT) 
 + (!(sr_read_reg(sr, ERRCONFIG)  ERRCONFIG_MCUDISACKINTST))) {
 +
 + udelay(1);
 + timeout++;
 + }

Please use omap_test_timeout() from plat/common.h

 + if (timeout == SR_DISABLE_TIMEOUT)
 + pr_warning(SR%d disable timedout\n, srid);
 +
 + /* Disable MCUDisableAcknowledge interrupt  clear pending interrupt
 +  * Also enable VPBOUND interrrupt
 +  */
 + sr_modify_reg(sr, 

[PATCH 14/16] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence.

2010-02-24 Thread Thara Gopinath
This patch introduces OMAP3 specific values for Smartreflex and
Voltage processor registers as per the latest TI recommendations.
This patch also improves the smartreflex and voltage processor
enable disable sequences as per the latest recommendations.

These recommendations were first formed based on experimentations
on Nokia Rover platform  and were implemented in the Rover code
base first by Nishanth Menon and Paul Walmsley.

Signed-off-by: Thara Gopinath th...@ti.com
---
 arch/arm/mach-omap2/smartreflex.c |   65 -
 arch/arm/mach-omap2/smartreflex.h |6 +-
 arch/arm/mach-omap2/voltage.c |   95 ++--
 arch/arm/mach-omap2/voltage.h |   16 ---
 4 files changed, 142 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c 
b/arch/arm/mach-omap2/smartreflex.c
index 8a4c48b..ca2223d 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -24,6 +24,7 @@
 #include linux/io.h
 #include linux/list.h
 #include linux/debugfs.h
+#include linux/delay.h
 
 #include plat/control.h
 #include plat/omap_hwmod.h
@@ -32,6 +33,7 @@
 #include smartreflex.h
 
 #define SMARTREFLEX_NAME_LEN   16
+#define SR_DISABLE_TIMEOUT 200
 
 struct omap_sr {
int srid;
@@ -184,11 +186,9 @@ static void sr_set_regfields(struct omap_sr *sr)
sr-err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
sr-accum_data = OMAP3430_SR_ACCUMDATA;
if (sr-srid == SR1) {
-   sr-err_minlimit = OMAP3430_SR1_ERRMINLIMIT;
sr-senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
sr-senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
} else {
-   sr-err_minlimit = OMAP3430_SR2_ERRMINLIMIT;
sr-senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
sr-senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
}
@@ -280,11 +280,6 @@ static void sr_start_vddautocomap(int srid)
return;
}
 
-   if (sr-is_sr_reset == 1) {
-   sr_clk_enable(sr);
-   sr_configure(sr);
-   }
-
sr-is_autocomp_active = 1;
if (!sr_class-enable(srid)) {
sr-is_autocomp_active = 0;
@@ -351,8 +346,20 @@ int sr_enable(int srid, u32 target_opp_no)
return false;
}
 
-   nvalue_reciprocal = pdata-sr_nvalue[target_opp_no - 1];
+   /*
+* For OMAP3430 errminlimit is dependent on opp. So choose
+* it appropriately
+*/
+   if (cpu_is_omap343x())
+   sr-err_minlimit = (target_opp_no  2) ?
+   OMAP3430_SR_ERRMINLIMIT_HIGHOPP :
+   OMAP3430_SR_ERRMINLIMIT_LOWOPP;
+
+   /* Enable the clocks and configure SR */
+   sr_clk_enable(sr);
+   sr_configure(sr);
 
+   nvalue_reciprocal = pdata-sr_nvalue[target_opp_no - 1];
if (nvalue_reciprocal == 0) {
pr_notice(OPP%d doesn't support SmartReflex\n,
target_opp_no);
@@ -375,10 +382,44 @@ int sr_enable(int srid, u32 target_opp_no)
 void sr_disable(int srid)
 {
struct omap_sr *sr = _sr_lookup(srid);
+   int timeout = 0;
+
+   /* Check if SR is already disabled. If yes do nothing */
+   if (!(sr_read_reg(sr, SRCONFIG)  SRCONFIG_SRENABLE))
+   return;
+
+   /* Enable MCUDisableAcknowledge interrupt */
+   sr_modify_reg(sr, ERRCONFIG,
+   ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
 
-   sr-is_sr_reset = 1;
/* SRCONFIG - disable SR */
-   sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
+   sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+   /* Disable all other SR interrupts and clear the status */
+   sr_modify_reg(sr, ERRCONFIG,
+   (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+   ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN),
+   (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
+   ERRCONFIG_MCUBOUNDINTST | ERRCONFIG_VPBOUNDINTST));
+
+   /* Wait for SR to be disabled.
+* wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
+*/
+   while ((timeout  SR_DISABLE_TIMEOUT) 
+   (!(sr_read_reg(sr, ERRCONFIG)  ERRCONFIG_MCUDISACKINTST))) {
+
+   udelay(1);
+   timeout++;
+   }
+
+   if (timeout == SR_DISABLE_TIMEOUT)
+   pr_warning(SR%d disable timedout\n, srid);
+
+   /* Disable MCUDisableAcknowledge interrupt  clear pending interrupt
+* Also enable VPBOUND interrrupt
+*/
+   sr_modify_reg(sr, ERRCONFIG, ERRCONFIG_MCUDISACKINTEN,
+   ERRCONFIG_MCUDISACKINTST);
 }
 
 /**
@@ -407,10 +448,6 @@ void