RE: [PATCH 11/16] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3

2010-03-05 Thread Gopinath, Thara


-Original Message-
From: Kevin Hilman [mailto:khil...@deeprootsystems.com]
Sent: Wednesday, March 03, 2010 6:08 AM
To: Gopinath, Thara
Cc: linux-omap@vger.kernel.org; p...@pwsan.com; Menon, Nishanth; Cousson, 
Benoit; Sripathy,
Vishwanath; Sawant, Anand
Subject: Re: [PATCH 11/16] OMAP3: PM: Configurations for Smartreflex Class 2 
and Smartreflex Class 3

Thara Gopinath th...@ti.com writes:

 There are two separate modules in SmartReflex-AVS :
 MinMaxAvg module and Error module. Class3 uses the Error module only.
 In Class2 you can choose between either module since it is software based.
 The registers are mapped to the modules as followed:

 MinMaxAvg module: AccumData, MinMaxAvgEnable, MinMaxAvgValid,
 MinMaxAvgAccumValid, SenVal, SenMin, SenMax, SenAverage,
 AverageWeight, MCUAccum, MCUValid, MCUBounds.

 Error module: SenNGain, SenPGain, SenPRN, SenNRN, AvgError,
 SenError, VPBounds, ErrWeight, ErrMaxLimit, ErrMinLimit.

 Shared between both: SRClkLength, SREnable, SenEnable, SenNEnable,
 SenPEnable, DelayCtrl, MCUDisableAck, ClkActivity.

 This patch introduces class specific configuration of registers in 
 smartreflex.c
 This also allows for choosing between Error module and Minmaxavg module
 for Class 2 SR. This patch allows allows for registering for smartreflex
 interrupt handler and notification of interrupts in case requested by
 the smartreflex class driver.

 Signed-off-by: Thara Gopinath th...@ti.com
 ---
  arch/arm/mach-omap2/smartreflex-class3.c |1 +
  arch/arm/mach-omap2/smartreflex.c|  199 
 --
  arch/arm/mach-omap2/smartreflex.h|   24 -
  3 files changed, 186 insertions(+), 38 deletions(-)

 diff --git a/arch/arm/mach-omap2/smartreflex-class3.c 
 b/arch/arm/mach-omap2/smartreflex-class3.c
 index 8e3b530..aae88b6 100644
 --- a/arch/arm/mach-omap2/smartreflex-class3.c
 +++ b/arch/arm/mach-omap2/smartreflex-class3.c
 @@ -43,6 +43,7 @@ static int sr_class3_disable(int id)
  struct omap_smartreflex_class_data class3_data = {
 .enable = sr_class3_enable,
 .disable = sr_class3_disable,
 +   .class_type = SR_CLASS3,
  };

  static int __init sr_class3_init(void)
 diff --git a/arch/arm/mach-omap2/smartreflex.c 
 b/arch/arm/mach-omap2/smartreflex.c
 index f7c1182..96dc76b 100644
 --- a/arch/arm/mach-omap2/smartreflex.c
 +++ b/arch/arm/mach-omap2/smartreflex.c
 @@ -38,6 +38,12 @@ struct omap_sr {
 int is_sr_reset;
 int is_autocomp_active;
 u32 clk_length;
 +   u32 err_weight;
 +   u32 err_minlimit;
 +   u32 err_maxlimit;
 +   u32 accum_data;
 +   u32 senn_avgweight;
 +   u32 senp_avgweight;
 void __iomem*srbase_addr;
 unsigned intirq;
 struct platform_device  *pdev;
 @@ -106,6 +112,24 @@ static void sr_clk_disable(struct omap_sr *sr)
 sr-is_sr_reset = 1;
  }

 +static irqreturn_t sr_omap_isr(int irq, void *data)
 +{
 +   struct omap_sr *sr_info = (struct omap_sr *)data;
 +   u32 status;
 +
 +   /* Read the status bits */
 +   status = sr_read_reg(sr_info, ERRCONFIG);
 +
 +   /* Clear them by writing back */
 +   sr_write_reg(sr_info, ERRCONFIG, status);
 +
 +   /* Call the class driver notify function if registered*/
 +   if (sr_class-class_type == SR_CLASS2  sr_class-notify)
 +   sr_class-notify(sr_info-srid, status);
 +
 +   return IRQ_HANDLED;
 +}
 +
  static void sr_set_clk_length(struct omap_sr *sr)
  {
 struct clk *sys_ck;
 @@ -137,50 +161,96 @@ static void sr_set_clk_length(struct omap_sr *sr)
 }
  }

 +static void sr_set_regfields(struct omap_sr *sr)
 +{
 +   /*
 +* For time being these values are defined in smartreflex.h
 +* and populated during init. May be they can be moved to board
 +* file or pmic specific data structure. In that case these structure
 +* fields will have to be populated using the pdata or pmic structure.
 +*/
 +   if (cpu_is_omap343x()) {
 +   sr-err_weight = OMAP3430_SR_ERRWEIGHT;
 +   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;
 +   }
 +   }
 +   /* TODO: 3630 and Omap4 specific bit field values */
 +}
 +
  static void sr_configure(struct omap_sr *sr)
  {
 u32 sr_config;
 u32 senp_en , senn_en;
 struct omap_smartreflex_data *pdata = sr-pdev-dev.platform_data

Re: [PATCH 11/16] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3

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

[...]

  /* PM Debug Fs enteries to enable disable smartreflex.*/
 @@ -448,6 +551,7 @@ static int __devinit omap_smartreflex_probe(struct 
 platform_device *pdev)
 if (odev-hwmods[0]-mpu_irqs)
 sr_info-irq = odev-hwmods[0]-mpu_irqs[0].irq;
 sr_set_clk_length(sr_info);
 +   sr_set_regfields(sr_info);

 /* Create the debug fs enteries */
 sprintf(name, sr%d_autocomp, sr_info-srid);
 @@ -456,8 +560,29 @@ static int __devinit omap_smartreflex_probe(struct 
 platform_device *pdev)

 odev-hwmods[0]-dev_attr = sr_info;
 list_add(sr_info-node, sr_list);
 -   pr_info(SmartReflex driver initialized\n);

 +   /*
 +* Register interrrupt handler if smartreflex class driver is already
 +* registered and has requested for interrupts. This will be attempted
 +* in the class driver register again if it does not happen here.
 +*/

Why the duplicate attempts to request_irq()?  Seems like it's only needed
in the register_class hook above.

 Duplicate attempt is so that it does not matter whether the class driver gets 
 registered before the smartreflex driver gets registered. So if smartreflex 
 driver gets registered first the request_irq will happen only when class 
 driver gets registered. On the other hand if class driver gets registered 
 first then the request_irq will happen from here. The thing to notice is that 
 there is only a duplicate attempt. Actual double registrations does not 
 happen.

OK, thanks for the clarification.

Then, the two blocks of code that reqest_irq + init_enable should be
combined into a subroutine (with comment) called from both places.
This will help avoid the confusion I had and increase readability.

Kevin

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 11/16] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3

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

 There are two separate modules in SmartReflex-AVS :
 MinMaxAvg module and Error module. Class3 uses the Error module only.
 In Class2 you can choose between either module since it is software based.
 The registers are mapped to the modules as followed:

 MinMaxAvg module: AccumData, MinMaxAvgEnable, MinMaxAvgValid,
 MinMaxAvgAccumValid, SenVal, SenMin, SenMax, SenAverage,
 AverageWeight, MCUAccum, MCUValid, MCUBounds.

 Error module: SenNGain, SenPGain, SenPRN, SenNRN, AvgError,
 SenError, VPBounds, ErrWeight, ErrMaxLimit, ErrMinLimit.

 Shared between both: SRClkLength, SREnable, SenEnable, SenNEnable,
 SenPEnable, DelayCtrl, MCUDisableAck, ClkActivity.

 This patch introduces class specific configuration of registers in 
 smartreflex.c
 This also allows for choosing between Error module and Minmaxavg module
 for Class 2 SR. This patch allows allows for registering for smartreflex
 interrupt handler and notification of interrupts in case requested by
 the smartreflex class driver.

 Signed-off-by: Thara Gopinath th...@ti.com
 ---
  arch/arm/mach-omap2/smartreflex-class3.c |1 +
  arch/arm/mach-omap2/smartreflex.c|  199 
 --
  arch/arm/mach-omap2/smartreflex.h|   24 -
  3 files changed, 186 insertions(+), 38 deletions(-)

 diff --git a/arch/arm/mach-omap2/smartreflex-class3.c 
 b/arch/arm/mach-omap2/smartreflex-class3.c
 index 8e3b530..aae88b6 100644
 --- a/arch/arm/mach-omap2/smartreflex-class3.c
 +++ b/arch/arm/mach-omap2/smartreflex-class3.c
 @@ -43,6 +43,7 @@ static int sr_class3_disable(int id)
  struct omap_smartreflex_class_data class3_data = {
   .enable = sr_class3_enable,
   .disable = sr_class3_disable,
 + .class_type = SR_CLASS3,
  };
  
  static int __init sr_class3_init(void)
 diff --git a/arch/arm/mach-omap2/smartreflex.c 
 b/arch/arm/mach-omap2/smartreflex.c
 index f7c1182..96dc76b 100644
 --- a/arch/arm/mach-omap2/smartreflex.c
 +++ b/arch/arm/mach-omap2/smartreflex.c
 @@ -38,6 +38,12 @@ struct omap_sr {
   int is_sr_reset;
   int is_autocomp_active;
   u32 clk_length;
 + u32 err_weight;
 + u32 err_minlimit;
 + u32 err_maxlimit;
 + u32 accum_data;
 + u32 senn_avgweight;
 + u32 senp_avgweight;
   void __iomem*srbase_addr;
   unsigned intirq;
   struct platform_device  *pdev;
 @@ -106,6 +112,24 @@ static void sr_clk_disable(struct omap_sr *sr)
   sr-is_sr_reset = 1;
  }
  
 +static irqreturn_t sr_omap_isr(int irq, void *data)
 +{
 + struct omap_sr *sr_info = (struct omap_sr *)data;
 + u32 status;
 +
 + /* Read the status bits */
 + status = sr_read_reg(sr_info, ERRCONFIG);
 +
 + /* Clear them by writing back */
 + sr_write_reg(sr_info, ERRCONFIG, status);
 +
 + /* Call the class driver notify function if registered*/
 + if (sr_class-class_type == SR_CLASS2  sr_class-notify)
 + sr_class-notify(sr_info-srid, status);
 +
 + return IRQ_HANDLED;
 +}
 +
  static void sr_set_clk_length(struct omap_sr *sr)
  {
   struct clk *sys_ck;
 @@ -137,50 +161,96 @@ static void sr_set_clk_length(struct omap_sr *sr)
   }
  }
  
 +static void sr_set_regfields(struct omap_sr *sr)
 +{
 + /*
 +  * For time being these values are defined in smartreflex.h
 +  * and populated during init. May be they can be moved to board
 +  * file or pmic specific data structure. In that case these structure
 +  * fields will have to be populated using the pdata or pmic structure.
 +  */
 + if (cpu_is_omap343x()) {
 + sr-err_weight = OMAP3430_SR_ERRWEIGHT;
 + 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;
 + }
 + }
 + /* TODO: 3630 and Omap4 specific bit field values */
 +}
 +
  static void sr_configure(struct omap_sr *sr)
  {
   u32 sr_config;
   u32 senp_en , senn_en;
   struct omap_smartreflex_data *pdata = sr-pdev-dev.platform_data;
  
 + /* Common settings for SR Class3 and SR Class2 */
   if (sr-clk_length == 0)
   sr_set_clk_length(sr);
  
   senp_en = pdata-senp_mod;
   senn_en = pdata-senn_mod;
 - if (sr-srid == SR1) {
 - sr_config = 

[PATCH 11/16] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3

2010-02-24 Thread Thara Gopinath
There are two separate modules in SmartReflex-AVS :
MinMaxAvg module and Error module. Class3 uses the Error module only.
In Class2 you can choose between either module since it is software based.
The registers are mapped to the modules as followed:

MinMaxAvg module: AccumData, MinMaxAvgEnable, MinMaxAvgValid,
MinMaxAvgAccumValid, SenVal, SenMin, SenMax, SenAverage,
AverageWeight, MCUAccum, MCUValid, MCUBounds.

Error module: SenNGain, SenPGain, SenPRN, SenNRN, AvgError,
SenError, VPBounds, ErrWeight, ErrMaxLimit, ErrMinLimit.

Shared between both: SRClkLength, SREnable, SenEnable, SenNEnable,
SenPEnable, DelayCtrl, MCUDisableAck, ClkActivity.

This patch introduces class specific configuration of registers in smartreflex.c
This also allows for choosing between Error module and Minmaxavg module
for Class 2 SR. This patch allows allows for registering for smartreflex
interrupt handler and notification of interrupts in case requested by
the smartreflex class driver.

Signed-off-by: Thara Gopinath th...@ti.com
---
 arch/arm/mach-omap2/smartreflex-class3.c |1 +
 arch/arm/mach-omap2/smartreflex.c|  199 --
 arch/arm/mach-omap2/smartreflex.h|   24 -
 3 files changed, 186 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex-class3.c 
b/arch/arm/mach-omap2/smartreflex-class3.c
index 8e3b530..aae88b6 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -43,6 +43,7 @@ static int sr_class3_disable(int id)
 struct omap_smartreflex_class_data class3_data = {
.enable = sr_class3_enable,
.disable = sr_class3_disable,
+   .class_type = SR_CLASS3,
 };
 
 static int __init sr_class3_init(void)
diff --git a/arch/arm/mach-omap2/smartreflex.c 
b/arch/arm/mach-omap2/smartreflex.c
index f7c1182..96dc76b 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -38,6 +38,12 @@ struct omap_sr {
int is_sr_reset;
int is_autocomp_active;
u32 clk_length;
+   u32 err_weight;
+   u32 err_minlimit;
+   u32 err_maxlimit;
+   u32 accum_data;
+   u32 senn_avgweight;
+   u32 senp_avgweight;
void __iomem*srbase_addr;
unsigned intirq;
struct platform_device  *pdev;
@@ -106,6 +112,24 @@ static void sr_clk_disable(struct omap_sr *sr)
sr-is_sr_reset = 1;
 }
 
+static irqreturn_t sr_omap_isr(int irq, void *data)
+{
+   struct omap_sr *sr_info = (struct omap_sr *)data;
+   u32 status;
+
+   /* Read the status bits */
+   status = sr_read_reg(sr_info, ERRCONFIG);
+
+   /* Clear them by writing back */
+   sr_write_reg(sr_info, ERRCONFIG, status);
+
+   /* Call the class driver notify function if registered*/
+   if (sr_class-class_type == SR_CLASS2  sr_class-notify)
+   sr_class-notify(sr_info-srid, status);
+
+   return IRQ_HANDLED;
+}
+
 static void sr_set_clk_length(struct omap_sr *sr)
 {
struct clk *sys_ck;
@@ -137,50 +161,96 @@ static void sr_set_clk_length(struct omap_sr *sr)
}
 }
 
+static void sr_set_regfields(struct omap_sr *sr)
+{
+   /*
+* For time being these values are defined in smartreflex.h
+* and populated during init. May be they can be moved to board
+* file or pmic specific data structure. In that case these structure
+* fields will have to be populated using the pdata or pmic structure.
+*/
+   if (cpu_is_omap343x()) {
+   sr-err_weight = OMAP3430_SR_ERRWEIGHT;
+   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;
+   }
+   }
+   /* TODO: 3630 and Omap4 specific bit field values */
+}
+
 static void sr_configure(struct omap_sr *sr)
 {
u32 sr_config;
u32 senp_en , senn_en;
struct omap_smartreflex_data *pdata = sr-pdev-dev.platform_data;
 
+   /* Common settings for SR Class3 and SR Class2 */
if (sr-clk_length == 0)
sr_set_clk_length(sr);
 
senp_en = pdata-senp_mod;
senn_en = pdata-senn_mod;
-   if (sr-srid == SR1) {
-   sr_config = SR1_SRCONFIG_ACCUMDATA |
-