From patchwork Tue May 19 11:57:57 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 24702 X-Patchwork-Delegate: khilman@deeprootsystems.com Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n4JBxe1C020591 for ; Tue, 19 May 2009 11:59:40 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754240AbZESL6w (ORCPT ); Tue, 19 May 2009 07:58:52 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753850AbZESL6n (ORCPT ); Tue, 19 May 2009 07:58:43 -0400 Received: from smtp.nokia.com ([192.100.122.233]:31432 "EHLO mgw-mx06.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752339AbZESL6m (ORCPT ); Tue, 19 May 2009 07:58:42 -0400 Received: from vaebh105.NOE.Nokia.com (vaebh105.europe.nokia.com [10.160.244.31]) by mgw-mx06.nokia.com (Switch-3.2.6/Switch-3.2.6) with ESMTP id n4JBwWj1024696; Tue, 19 May 2009 14:58:35 +0300 Received: from esebh102.NOE.Nokia.com ([172.21.138.183]) by vaebh105.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 19 May 2009 14:58:37 +0300 Received: from mgw-da02.ext.nokia.com ([147.243.128.26]) by esebh102.NOE.Nokia.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Tue, 19 May 2009 14:58:36 +0300 Received: from localhost.localdomain (esdhcp039131.research.nokia.com [172.21.39.131]) by mgw-da02.ext.nokia.com (Switch-3.2.6/Switch-3.2.6) with ESMTP id n4JBwWvb016721; Tue, 19 May 2009 14:58:32 +0300 From: Roger Quadros To: khilman@deeprootsystems.com Cc: linux-omap@vger.kernel.org Subject: [PATCH] OMAP3: PM: Make Smartreflex driver independent of SRF Date: Tue, 19 May 2009 14:57:57 +0300 Message-Id: <1242734277-19890-1-git-send-email-ext-roger.quadros@nokia.com> X-Mailer: git-send-email 1.6.0.4 X-OriginalArrivalTime: 19 May 2009 11:58:37.0271 (UTC) FILETIME=[248E2E70:01C9D879] X-Nokia-AV: Clean Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org 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 --- 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;