RE: [PATCH 11/16] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3
-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
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
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
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 | -