Smart Reflex pm patches causes a kernel panic
diff mbox

Message ID 4A12A04D.1060109@nokia.com
State Superseded
Delegated to: Kevin Hilman
Headers show

Commit Message

Roger Quadros May 19, 2009, 12:04 p.m. UTC
ext Elvis Dowson wrote:
> Thanks for the info, Roger! I'll wait for that patch!
> 
> Elvis
> 
>>
>> Currently Smartreflex (SR) is dependent on SRF to get OPP levels. Just 
>> make sure you select CONFIG_OMAP_PM_SRF when using SR. OR you can 
>> disable Smartreflex till this issue is fixed.
>>
>> I am working on a patch that will make Smartreflex independent of SRF. 
>> I will post this soon.
> 

Elvis,

Can you please try and verify if the problem goes away with the attached patch.
Thanks.

-roger

Comments

Elvis Dowson May 19, 2009, 12:12 p.m. UTC | #1
Hi Roger,
			I'll try it right away.

Elvis

On May 19, 2009, at 4:04 PM, Roger Quadros wrote:

>>>
>
> Elvis,
>
> Can you please try and verify if the problem goes away with the  
> attached patch.
> Thanks.
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Roger Quadros May 19, 2009, 12:43 p.m. UTC | #2
ext Elvis Dowson wrote:
> Hi Roger,
>             I'll try it right away.
> 
> Elvis
> 
> On May 19, 2009, at 4:04 PM, Roger Quadros wrote:
> 
>>>>
>>
>> Elvis,
>>
>> Can you please try and verify if the problem goes away with the 
>> attached patch.
>> Thanks.
>>

My earlier patch will not work for you since smartreflex driver is still 
referencing mpu_opps without checking.

You will have to use this in your board init file

omap2_init_common_hw(NULL, omap3_mpu_rate_table,
                              omap3_dsp_rate_table, omap3_l3_rate_table);

The first parameter is SDRAM timings, you can figure out and pass something 
saner instead of NULL. e.g. mt46h32m32lf6_sdrc_params.

-roger
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Elvis Dowson May 19, 2009, 5:44 p.m. UTC | #3
Hi Roger,
			Which headers should I include for getting the mpu, dsp and l3 rate  
tables in for my board-overo.c file ? Just mach/omap-pm.h ? I see a  
couple of other headers file in the board-3430sdp.c file like pm.h and  
omap3-opp.h .. are those really required?

Elvis

On May 19, 2009, at 4:43 PM, Roger Quadros wrote:

>
>
> omap2_init_common_hw(NULL, omap3_mpu_rate_table,
>                             omap3_dsp_rate_table,  
> omap3_l3_rate_table);
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Elvis Dowson May 19, 2009, 5:50 p.m. UTC | #4
I guess the answer is all three.

Elvis

On May 19, 2009, at 9:44 PM, Elvis Dowson wrote:

> Hi Roger,
> 			Which headers should I include for getting the mpu, dsp and l3  
> rate tables in for my board-overo.c file ? Just mach/omap-pm.h ? I  
> see a couple of other headers file in the board-3430sdp.c file like  
> pm.h and omap3-opp.h .. are those really required?
>
> Elvis
>
> On May 19, 2009, at 4:43 PM, Roger Quadros wrote:
>
>>
>>
>> omap2_init_common_hw(NULL, omap3_mpu_rate_table,
>>                            omap3_dsp_rate_table,  
>> omap3_l3_rate_table);
>>

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Koen Kooi May 19, 2009, 7:13 p.m. UTC | #5
Op 19 mei 2009, om 19:50 heeft Elvis Dowson het volgende geschreven:

> I guess the answer is all three.

This works for me: http://cgit.openembedded.net/cgit.cgi?url=openembedded/tree/recipes/linux/linux-omap-pm/overo-cpufreq.diff

regards,

Koen
Elvis Dowson May 19, 2009, 7:26 p.m. UTC | #6
Hi Koen,
			Thanks I already got this to work!

Best regards,

Elvis

On May 19, 2009, at 11:13 PM, Koen Kooi wrote:

>
> Op 19 mei 2009, om 19:50 heeft Elvis Dowson het volgende geschreven:
>
>> I guess the answer is all three.
>
> This works for me: http://cgit.openembedded.net/cgit.cgi?url=openembedded/tree/recipes/linux/linux-omap-pm/overo-cpufreq.diff
>
> regards,
>
> Koen

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

Patch
diff mbox

From: Roger Quadros <ext-roger.quadros@nokia.com>
Date: Tue, 19 May 2009 14:15:56 +0300
Subject: [PATCH] OMAP3: PM: Make Smartreflex driver independent of SRF

This removes Smartreflex driver's dependency on SRF layer to get
OPPs for VDD1 and VDD2. Now Smartreflex is usable irrespective of the
underlying PM layer.

Signed-off-by: Roger Quadros <ext-roger.quadros@nokia.com>
---
 arch/arm/mach-omap2/smartreflex.c |   74 ++++++++++++++++++++++++++++++++-----
 1 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index b032366..b66d237 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -143,6 +143,57 @@  static u32 cal_test_nvalue(u32 sennval, u32 senpval)
 		(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
 }
 
+/* determine the current OPP from the frequency
+ * we need to give this function last element of OPP rate table
+ * and the frequency
+ */
+static u16 get_opp(struct omap_opp *opp_freq_table,
+					unsigned long freq)
+{
+	struct omap_opp *prcm_config;
+
+	prcm_config = opp_freq_table;
+
+	if (prcm_config->rate <= freq)
+		return prcm_config->opp_id; /* Return the Highest OPP */
+	for (; prcm_config->rate; prcm_config--)
+		if (prcm_config->rate < freq)
+			return (prcm_config+1)->opp_id;
+		else if (prcm_config->rate == freq)
+			return prcm_config->opp_id;
+	/* Return the least OPP */
+	return (prcm_config+1)->opp_id;
+}
+
+static u16 get_vdd1_opp(void)
+{
+	u16 opp;
+	struct clk *clk;
+
+	clk = clk_get(NULL, "dpll1_ck");
+
+	if (clk == NULL || IS_ERR(clk) || mpu_opps == NULL)
+		return 0;
+
+	opp = get_opp(mpu_opps + MAX_VDD1_OPP, clk->rate);
+	return opp;
+}
+
+static u16 get_vdd2_opp(void)
+{
+	u16 opp;
+	struct clk *clk;
+
+	clk = clk_get(NULL, "dpll3_m2_ck");
+
+	if (clk == NULL || IS_ERR(clk) || l3_opps == NULL)
+		return 0;
+
+	opp = get_opp(l3_opps + MAX_VDD2_OPP, clk->rate);
+	return opp;
+}
+
+
 static void sr_set_clk_length(struct omap_sr *sr)
 {
 	struct clk *sys_ck;
@@ -248,13 +299,15 @@  static void sr_configure_vp(int srid)
 {
 	u32 vpconfig;
 	u32 vsel;
+	u32 target_opp_no;
 
 	if (srid == SR1) {
-		if (!omap_pm_vdd1_get_opp())
+		target_opp_no = get_vdd1_opp();
+		if (!target_opp_no)
 			/* Assume Nominal OPP as current OPP unknown */
 			vsel = mpu_opps[VDD1_OPP3].vsel;
 		else
-			vsel = mpu_opps[omap_pm_vdd1_get_opp()].vsel;
+			vsel = mpu_opps[target_opp_no].vsel;
 
 		vpconfig = PRM_VP1_CONFIG_ERROROFFSET |
 			PRM_VP1_CONFIG_ERRORGAIN |
@@ -295,11 +348,12 @@  static void sr_configure_vp(int srid)
 				       OMAP3_PRM_VP1_CONFIG_OFFSET);
 
 	} else if (srid == SR2) {
-		if (!omap_pm_vdd2_get_opp())
+		target_opp_no = get_vdd2_opp();
+		if (!target_opp_no)
 			/* Assume Nominal OPP */
 			vsel = l3_opps[VDD2_OPP3].vsel;
 		else
-			vsel = l3_opps[omap_pm_vdd2_get_opp()].vsel;
+			vsel = l3_opps[target_opp_no].vsel;
 
 		vpconfig = PRM_VP2_CONFIG_ERROROFFSET |
 			PRM_VP2_CONFIG_ERRORGAIN |
@@ -397,7 +451,7 @@  static int sr_reset_voltage(int srid)
 	u32 vc_bypass_value;
 
 	if (srid == SR1) {
-		target_opp_no = omap_pm_vdd1_get_opp();
+		target_opp_no = get_vdd1_opp();
 		if (!target_opp_no) {
 			pr_info("Current OPP unknown: Cannot reset voltage\n");
 			return 1;
@@ -405,7 +459,7 @@  static int sr_reset_voltage(int srid)
 		vsel = mpu_opps[target_opp_no].vsel;
 		reg_addr = R_VDD1_SR_CONTROL;
 	} else if (srid == SR2) {
-		target_opp_no = omap_pm_vdd2_get_opp();
+		target_opp_no = get_vdd2_opp();
 		if (!target_opp_no) {
 			pr_info("Current OPP unknown: Cannot reset voltage\n");
 			return 1;
@@ -641,9 +695,9 @@  void enable_smartreflex(int srid)
 			sr_clk_enable(sr);
 
 			if (srid == SR1)
-				target_opp_no = omap_pm_vdd1_get_opp();
+				target_opp_no = get_vdd1_opp();
 			else if (srid == SR2)
-				target_opp_no = omap_pm_vdd2_get_opp();
+				target_opp_no = get_vdd2_opp();
 
 			if (!target_opp_no) {
 				pr_info("Current OPP unknown \
@@ -786,7 +840,7 @@  static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
 	if (value == 0) {
 		sr_stop_vddautocomap(SR1);
 	} else {
-		u32 current_vdd1opp_no = omap_pm_vdd1_get_opp();
+		u32 current_vdd1opp_no = get_vdd1_opp();
 		if (!current_vdd1opp_no) {
 			pr_err("sr_vdd1_autocomp: Current VDD1 opp unknown\n");
 			return -EINVAL;
@@ -826,7 +880,7 @@  static ssize_t omap_sr_vdd2_autocomp_store(struct kobject *kobj,
 	if (value == 0) {
 		sr_stop_vddautocomap(SR2);
 	} else {
-		u32 current_vdd2opp_no = omap_pm_vdd2_get_opp();
+		u32 current_vdd2opp_no = get_vdd2_opp();
 		if (!current_vdd2opp_no) {
 			pr_err("sr_vdd2_autocomp: Current VDD2 opp unknown\n");
 			return -EINVAL;
-- 
1.6.0.4