From patchwork Thu Apr 26 10:12:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 134462 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp2053743lji; Thu, 26 Apr 2018 03:12:29 -0700 (PDT) X-Google-Smtp-Source: AIpwx48Fm+2sSO4710E1bKQdzkqpsXXyHjAFVjF1dRaBrNNkMqFR7CDMGvRL78M+dIAQvsk3WswG X-Received: by 2002:a17:902:7611:: with SMTP id k17-v6mr33175128pll.244.1524737549231; Thu, 26 Apr 2018 03:12:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524737549; cv=none; d=google.com; s=arc-20160816; b=H+zTcRqL2iHu8fv+BAoa+LqjP8t6gwqOXfMH6ebKZG1yewv2XVg1jZIj2YrdRG6Yzv ag+pni+LAeqYS1vHBbmXFY8x7aWuby/kzn5lOb0LqNmGsRlPLalDGLX8SQ9CvBih/Z9X j6pYEHMqwvKDPdScmdbAwnNW7/vN/OWQejvs7v3J45Mwd3jgX8ARsCOpNxAsm2bSgnq6 L2wZp7dnYC9mMUBvLk477W7VOXuKxNZWsvpRuI/iIvlGd3HkBD/7vkAriussc/ApVm4t LiFxNbEaxL2sjU8tyiK6UyfYNavRHuqJmjhJ+/OFr5Unx7oATK2u8G2BpIXkgBkZrdjR r+Pg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=WsbIvcxMVArTPYr7W185VQFVNGQQXvCW7wWwN3wEkFo=; b=q6WbiQKkgnO51O1+Uq6ctAzvBKtsvCYMD7RKcQTVMq7bQ/ONhA9LOGwbNY+Ld2creL YqswzQrMluq54eyV6eWN1NhBU0AHrOkrw0ViBKUVKUAGailIsGuxnWFv2xkllMvsxzQJ anfwc378/bTMRrSCPWtYrt0y/eCNTLWmpeO4sLtgncL0Z2ub774e3tHkcxrW8UbIDxt9 FiYfwZ3qRRcIGroghS/ZsXoj0nqKiI2Xx3vN9x/XaOYpZrP2kIpC5++dpiDd6CPbwxVn fWqx5jSo/JJjIa5gEQhxC6yGe3XxKG454MwLm4mK7Z8pScE/BXsaSWQcdzfebzyH7u1R LsQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=hJwFHgaq; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r1si18133333pfb.247.2018.04.26.03.12.28; Thu, 26 Apr 2018 03:12:29 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=hJwFHgaq; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753942AbeDZKM1 (ORCPT + 11 others); Thu, 26 Apr 2018 06:12:27 -0400 Received: from mail-pf0-f195.google.com ([209.85.192.195]:34897 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753879AbeDZKM0 (ORCPT ); Thu, 26 Apr 2018 06:12:26 -0400 Received: by mail-pf0-f195.google.com with SMTP id j5so17934578pfh.2 for ; Thu, 26 Apr 2018 03:12:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=WsbIvcxMVArTPYr7W185VQFVNGQQXvCW7wWwN3wEkFo=; b=hJwFHgaqVZcASXA8izjCF/FPuW+E0Kr4bahI0kB+qtcgCRqig6Ewu+5DjqzjmdQuBi iFJPeg1L5ZViwcViriRAz+tYGNL9EwHdhOqsi1IkEV8DWiPWFFHqYQWcvOydtlnszhs7 xRJQi/c2Qf2MUVr6gVx8F+octJrkctNi9QABk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=WsbIvcxMVArTPYr7W185VQFVNGQQXvCW7wWwN3wEkFo=; b=KBWikZDQWLO8orrNcGd/tx7mV8C7YuJ2AIAWOOE+yKR8LL5METh8TM7CCoMOQ0dsvS gMqMjtamTCvNhz2AVdgW4bsDb9x+I7uGvzG1ZoTi67c93yf8MV56WwsxqMFU2ZFk2dqA jnjoQXNmqVnyT+OAX0R5wStfAfmM+7JT5i8/O7eEV5bHwWvEkbL92pCz44makWoDluBM PVQCfvHDZbrGuAIB/M154CSc90G7J+c3p1tiuVEvw6m/TsrooNzdsWduXSzrlwPrKfmH qTIj7cApBgAc9XEMzKPzOGkmXgYusqrMTnRQDNArAsIkOrLbZSSlAygV8YQb5MpQ7BzE ez3A== X-Gm-Message-State: ALQs6tD29asaYl/GTG2Nj7W1VP27RCTTTUjtyDphZKDAL+u2Idxfydo6 nEd/Hmhuz1Z8U74WIG6e8hD1HQ== X-Received: by 10.98.185.23 with SMTP id z23mr31251917pfe.180.1524737546320; Thu, 26 Apr 2018 03:12:26 -0700 (PDT) Received: from localhost ([122.172.61.40]) by smtp.gmail.com with ESMTPSA id q126sm3216314pga.79.2018.04.26.03.12.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 26 Apr 2018 03:12:25 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , Jason Cooper , Andrew Lunn , Gregory Clement , Sebastian Hesselbarth Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Miquel Raynal , linux-arm-kernel@lists.infradead.org Subject: [PATCH V4 3/3] cpufreq: add suspend/resume support in Armada 37xx DVFS driver Date: Thu, 26 Apr 2018 15:42:17 +0530 Message-Id: X-Mailer: git-send-email 2.15.0.194.g9af6a3dea062 In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org From: Miquel Raynal Add suspend/resume hooks in Armada 37xx DVFS driver to handle S2RAM operations. As there is currently no 'driver' structure, create one to store both the regmap and the register values during suspend operation. Signed-off-by: Miquel Raynal Signed-off-by: Viresh Kumar --- V3->V4: - Fix the "unused put_clk label" build error that happened between V2 and V3. drivers/cpufreq/armada-37xx-cpufreq.c | 67 +++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) -- 2.15.0.194.g9af6a3dea062 Tested-by: Gregory CLEMENT diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c index 1d5db6f6ace9..739da90ff3f6 100644 --- a/drivers/cpufreq/armada-37xx-cpufreq.c +++ b/drivers/cpufreq/armada-37xx-cpufreq.c @@ -23,6 +23,8 @@ #include #include +#include "cpufreq-dt.h" + /* Power management in North Bridge register set */ #define ARMADA_37XX_NB_L0L1 0x18 #define ARMADA_37XX_NB_L2L3 0x1C @@ -56,6 +58,16 @@ */ #define LOAD_LEVEL_NR 4 +struct armada37xx_cpufreq_state { + struct regmap *regmap; + u32 nb_l0l1; + u32 nb_l2l3; + u32 nb_dyn_mod; + u32 nb_cpu_load; +}; + +static struct armada37xx_cpufreq_state *armada37xx_cpufreq_state; + struct armada_37xx_dvfs { u32 cpu_freq_max; u8 divider[LOAD_LEVEL_NR]; @@ -136,7 +148,7 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base, clk_set_parent(clk, parent); } -static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base) +static void armada37xx_cpufreq_disable_dvfs(struct regmap *base) { unsigned int reg = ARMADA_37XX_NB_DYN_MOD, mask = ARMADA_37XX_NB_DFS_EN; @@ -162,8 +174,44 @@ static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base) regmap_update_bits(base, reg, mask, mask); } +static int armada37xx_cpufreq_suspend(struct cpufreq_policy *policy) +{ + struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state; + + regmap_read(state->regmap, ARMADA_37XX_NB_L0L1, &state->nb_l0l1); + regmap_read(state->regmap, ARMADA_37XX_NB_L2L3, &state->nb_l2l3); + regmap_read(state->regmap, ARMADA_37XX_NB_CPU_LOAD, + &state->nb_cpu_load); + regmap_read(state->regmap, ARMADA_37XX_NB_DYN_MOD, &state->nb_dyn_mod); + + return 0; +} + +static int armada37xx_cpufreq_resume(struct cpufreq_policy *policy) +{ + struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state; + + /* Ensure DVFS is disabled otherwise the following registers are RO */ + armada37xx_cpufreq_disable_dvfs(state->regmap); + + regmap_write(state->regmap, ARMADA_37XX_NB_L0L1, state->nb_l0l1); + regmap_write(state->regmap, ARMADA_37XX_NB_L2L3, state->nb_l2l3); + regmap_write(state->regmap, ARMADA_37XX_NB_CPU_LOAD, + state->nb_cpu_load); + + /* + * NB_DYN_MOD register is the one that actually enable back DVFS if it + * was enabled before the suspend operation. This must be done last + * otherwise other registers are not writable. + */ + regmap_write(state->regmap, ARMADA_37XX_NB_DYN_MOD, state->nb_dyn_mod); + + return 0; +} + static int __init armada37xx_cpufreq_driver_init(void) { + struct cpufreq_dt_platform_data pdata; struct armada_37xx_dvfs *dvfs; struct platform_device *pdev; unsigned long freq; @@ -213,6 +261,15 @@ static int __init armada37xx_cpufreq_driver_init(void) return -EINVAL; } + armada37xx_cpufreq_state = kmalloc(sizeof(*armada37xx_cpufreq_state), + GFP_KERNEL); + if (!armada37xx_cpufreq_state) { + clk_put(clk); + return -ENOMEM; + } + + armada37xx_cpufreq_state->regmap = nb_pm_base; + armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider); clk_put(clk); @@ -228,7 +285,11 @@ static int __init armada37xx_cpufreq_driver_init(void) /* Now that everything is setup, enable the DVFS at hardware level */ armada37xx_cpufreq_enable_dvfs(nb_pm_base); - pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); + pdata.suspend = armada37xx_cpufreq_suspend; + pdata.resume = armada37xx_cpufreq_resume; + + pdev = platform_device_register_data(NULL, "cpufreq-dt", -1, &pdata, + sizeof(pdata)); ret = PTR_ERR_OR_ZERO(pdev); if (ret) goto disable_dvfs; @@ -244,6 +305,8 @@ static int __init armada37xx_cpufreq_driver_init(void) dev_pm_opp_remove(cpu_dev, freq); } + kfree(armada37xx_cpufreq_state); + return ret; } /* late_initcall, to guarantee the driver is loaded after A37xx clock driver */