From patchwork Wed May 21 08:59:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 30519 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f197.google.com (mail-ve0-f197.google.com [209.85.128.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1CC1F20671 for ; Wed, 21 May 2014 09:05:17 +0000 (UTC) Received: by mail-ve0-f197.google.com with SMTP id db11sf5868506veb.0 for ; Wed, 21 May 2014 02:05:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:in-reply-to:references :sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=cDrXDENMR4Vx8/ERkhY0NbC0p7y746DIQWuLzWfxekk=; b=JOCWMnHw47BGENKJIbt9or+zrO0oDsssOER2o+SQTeXDc7uV1HDIUQ1iFsExJGznQA QFhl5ngoKw0gk+P/aPxp0WkQGYlkEU3ZpbVkEB1aZWFSxf+IWuhSupXVsQYup38jpzHe oDFnKKkvdQHMIhe+DxHe+Vn3zjJHWOGssl/0Vn/QUQmnZtXHU/LqflgCkkYFLYTy14Ci bhVMg9lSrQB8Kqqo3/fhqzAPiLAA6g6sXqYvhNP43up4DnE92ZevuXC+aiF+Ju9cnnGA ZbF96QmmLUBFPamBXHkSDzY8cQKSWw9pfikjrUhTYVkEjuJpjkutHImRnPvXR9c5uM5m bu4w== X-Gm-Message-State: ALoCoQk8jABZcH2bspr1tTa6fCOel+C3tmvZkFAs9j7ut6Xx8oE7IsvXkbu1svh8fTMft1u3PuM2 X-Received: by 10.58.195.202 with SMTP id ig10mr8947073vec.38.1400663116942; Wed, 21 May 2014 02:05:16 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.94.118 with SMTP id f109ls671573qge.8.gmail; Wed, 21 May 2014 02:05:16 -0700 (PDT) X-Received: by 10.52.110.105 with SMTP id hz9mr7457816vdb.9.1400663116800; Wed, 21 May 2014 02:05:16 -0700 (PDT) Received: from mail-vc0-f179.google.com (mail-vc0-f179.google.com [209.85.220.179]) by mx.google.com with ESMTPS id xb10si2554340vcb.45.2014.05.21.02.05.16 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 21 May 2014 02:05:16 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.179 as permitted sender) client-ip=209.85.220.179; Received: by mail-vc0-f179.google.com with SMTP id im17so2136007vcb.38 for ; Wed, 21 May 2014 02:05:16 -0700 (PDT) X-Received: by 10.220.103.141 with SMTP id k13mr8667448vco.25.1400663116703; Wed, 21 May 2014 02:05:16 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp96140vcb; Wed, 21 May 2014 02:05:16 -0700 (PDT) X-Received: by 10.68.231.7 with SMTP id tc7mr42457639pbc.32.1400663115775; Wed, 21 May 2014 02:05:15 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id fn2si28246265pab.164.2014.05.21.02.05.15; Wed, 21 May 2014 02:05:15 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752238AbaEUJFD (ORCPT + 27 others); Wed, 21 May 2014 05:05:03 -0400 Received: from mail-qg0-f43.google.com ([209.85.192.43]:43487 "EHLO mail-qg0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751987AbaEUJE6 (ORCPT ); Wed, 21 May 2014 05:04:58 -0400 Received: by mail-qg0-f43.google.com with SMTP id 63so2745530qgz.30 for ; Wed, 21 May 2014 02:04:57 -0700 (PDT) X-Received: by 10.224.13.72 with SMTP id b8mr53162128qaa.4.1400663097803; Wed, 21 May 2014 02:04:57 -0700 (PDT) Received: from localhost (ec2-23-23-178-99.compute-1.amazonaws.com. [23.23.178.99]) by mx.google.com with ESMTPSA id d8sm1020765qas.24.2014.05.21.02.04.52 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 21 May 2014 02:04:57 -0700 (PDT) From: Viresh Kumar To: rjw@rjwysocki.net Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, arvind.chauhan@arm.com, swarren@nvidia.com, dianders@chromium.org, linux@arm.linux.org.uk, nicolas.pitre@linaro.org, thomas.abraham@linaro.org, pdeschrijver@nvidia.com, Viresh Kumar Subject: [PATCH V4 3/3] cpufreq: Tegra: implement intermediate frequency callbacks Date: Wed, 21 May 2014 14:29:31 +0530 Message-Id: X-Mailer: git-send-email 2.0.0.rc2 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.179 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Tegra had always been switching to intermediate frequency (pll_p_clk) since ever. CPUFreq core has better support for handling notifications for these frequencies and so we can adapt Tegra's driver to it. Also do a WARN() if clk_set_parent() fails while moving back to pll_x as we should have atleast restored to earlier frequency on error. Signed-off-by: Viresh Kumar --- drivers/cpufreq/tegra-cpufreq.c | 81 ++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index 6e774c6..a64b970 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c @@ -46,7 +46,24 @@ static struct clk *pll_x_clk; static struct clk *pll_p_clk; static struct clk *emc_clk; -static int tegra_cpu_clk_set_rate(unsigned long rate) +static unsigned int +tegra_get_intermediate(struct cpufreq_policy *policy, unsigned int index) +{ + unsigned int ifreq = clk_get_rate(pll_p_clk) / 1000; + + /* + * Don't switch to intermediate freq if: + * - we are already at it, i.e. policy->cur == ifreq + * - index corresponds to ifreq + */ + if ((freq_table[index].frequency == ifreq) || (policy->cur == ifreq)) + return 0; + + return ifreq; +} + +static int +tegra_target_intermediate(struct cpufreq_policy *policy, unsigned int index) { int ret; @@ -57,28 +74,9 @@ static int tegra_cpu_clk_set_rate(unsigned long rate) clk_prepare_enable(pll_x_clk); ret = clk_set_parent(cpu_clk, pll_p_clk); - if (ret) { - pr_err("Failed to switch cpu to clock pll_p\n"); - goto out; - } - - if (rate == clk_get_rate(pll_p_clk)) - goto out; - - ret = clk_set_rate(pll_x_clk, rate); - if (ret) { - pr_err("Failed to change pll_x to %lu\n", rate); - goto out; - } - - ret = clk_set_parent(cpu_clk, pll_x_clk); - if (ret) { - pr_err("Failed to switch cpu to clock pll_x\n"); - goto out; - } + if (ret) + clk_disable_unprepare(pll_x_clk); -out: - clk_disable_unprepare(pll_x_clk); return ret; } @@ -98,10 +96,23 @@ static int tegra_target(struct cpufreq_policy *policy, unsigned int index) else clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */ - ret = tegra_cpu_clk_set_rate(rate * 1000); + /* target freq == pll_p */ + if (rate * 1000 == clk_get_rate(pll_p_clk)) { + ret = tegra_target_intermediate(policy, index); + goto disable_pll_x; + } + + ret = clk_set_rate(pll_x_clk, rate * 1000); + /* Restore to earlier frequency on error, i.e. pll_x */ if (ret) - pr_err("cpu-tegra: Failed to set cpu frequency to %lu kHz\n", - rate); + pr_err("Failed to change pll_x to %lu\n", rate); + + ret = clk_set_parent(cpu_clk, pll_x_clk); + /* This shouldn't fail while changing or restoring */ + WARN_ON(ret); + +disable_pll_x: + clk_disable_unprepare(pll_x_clk); return ret; } @@ -137,16 +148,18 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy) } static struct cpufreq_driver tegra_cpufreq_driver = { - .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, - .verify = cpufreq_generic_frequency_table_verify, - .target_index = tegra_target, - .get = cpufreq_generic_get, - .init = tegra_cpu_init, - .exit = tegra_cpu_exit, - .name = "tegra", - .attr = cpufreq_generic_attr, + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, + .verify = cpufreq_generic_frequency_table_verify, + .get_intermediate = tegra_get_intermediate, + .target_intermediate = tegra_target_intermediate, + .target_index = tegra_target, + .get = cpufreq_generic_get, + .init = tegra_cpu_init, + .exit = tegra_cpu_exit, + .name = "tegra", + .attr = cpufreq_generic_attr, #ifdef CONFIG_PM - .suspend = cpufreq_generic_suspend, + .suspend = cpufreq_generic_suspend, #endif };