From patchwork Sat Jun 27 03:02:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 50395 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 63688228FD for ; Sat, 27 Jun 2015 03:03:25 +0000 (UTC) Received: by wiws10 with SMTP id s10sf9780108wiw.2 for ; Fri, 26 Jun 2015 20:03:24 -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:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=tMUW+FcwH84BW/spiSOALuZLTvNMt8NxCdgxc9BpBvk=; b=RVeqcQegSAyPRI9YsepKYLwLXNsBhrVrSaJwPRoYki+GBoFthrZtCcSpuzEnD7Xc3R 5/s7xN7NshEPgf3oxJ6HHyv4mNuUWvAygKm9PXs0XmRMurYXGtXvFSMEso96k//t4Qx0 fdI5rDcElkyPP5+YWDQGerzUye2klK8y7GbqivqKbJepUt8UdXKqamd2WmfVuR9FSGf3 HEgROKXmuiqDjxJeahY1MMnl9RtloCHcErQLN4WZ5hT7R7gbr0bq8uP+j/sregqcnNOI RUyn2GdjcGgA1ZcFQtqfm5NOur5ACy9+4KrH/063jHMZ1xf9AMqT1yPgodzT8HdlWf8N B5yg== X-Gm-Message-State: ALoCoQljYCtbSzwoLHGZdLBdH+nZphfpTY7Nw1YI3y436SlQ/gEjYqFq7BBmw34C1Vyw1+nWwLNr X-Received: by 10.180.105.226 with SMTP id gp2mr913247wib.1.1435374204750; Fri, 26 Jun 2015 20:03:24 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.204.40 with SMTP id kv8ls567880lac.94.gmail; Fri, 26 Jun 2015 20:03:24 -0700 (PDT) X-Received: by 10.112.130.68 with SMTP id oc4mr4217884lbb.87.1435374204485; Fri, 26 Jun 2015 20:03:24 -0700 (PDT) Received: from mail-la0-f41.google.com (mail-la0-f41.google.com. [209.85.215.41]) by mx.google.com with ESMTPS id o7si28996416lbw.36.2015.06.26.20.03.24 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Jun 2015 20:03:24 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.41 as permitted sender) client-ip=209.85.215.41; Received: by laar3 with SMTP id r3so12601970laa.0 for ; Fri, 26 Jun 2015 20:03:24 -0700 (PDT) X-Received: by 10.152.206.75 with SMTP id lm11mr4207297lac.41.1435374204369; Fri, 26 Jun 2015 20:03:24 -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.112.108.230 with SMTP id hn6csp295309lbb; Fri, 26 Jun 2015 20:03:23 -0700 (PDT) X-Received: by 10.70.52.103 with SMTP id s7mr9120975pdo.117.1435374188667; Fri, 26 Jun 2015 20:03:08 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ay3si53186466pbc.54.2015.06.26.20.03.07; Fri, 26 Jun 2015 20:03:08 -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; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752340AbbF0DDG (ORCPT + 11 others); Fri, 26 Jun 2015 23:03:06 -0400 Received: from mail-pd0-f182.google.com ([209.85.192.182]:35922 "EHLO mail-pd0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752604AbbF0DDD (ORCPT ); Fri, 26 Jun 2015 23:03:03 -0400 Received: by pdcu2 with SMTP id u2so84847657pdc.3 for ; Fri, 26 Jun 2015 20:03:02 -0700 (PDT) X-Received: by 10.68.135.100 with SMTP id pr4mr9293209pbb.25.1435374182445; Fri, 26 Jun 2015 20:03:02 -0700 (PDT) Received: from ubuntu.localdomain (c-24-8-37-141.hsd1.co.comcast.net. [24.8.37.141]) by mx.google.com with ESMTPSA id j7sm34787756pdp.83.2015.06.26.20.03.01 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Jun 2015 20:03:02 -0700 (PDT) From: Lina Iyer To: rjw@rjwysocki.net, ulf.hansson@linaro.org, khilman@linaro.org Cc: geert@linux-m68k.org, k.kozlowski@samsung.com, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, msivasub@codeaurora.org, agross@codeaurora.org, Lina Iyer Subject: [PATCH RFC v2 12/16] drivers: qcom: spm: Enable runtime suspend/resume of CPU PM domain Date: Fri, 26 Jun 2015 21:02:32 -0600 Message-Id: <1435374156-19214-13-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1435374156-19214-1-git-send-email-lina.iyer@linaro.org> References: <1435374156-19214-1-git-send-email-lina.iyer@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lina.iyer@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.215.41 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: , On APQ8084 QCOM SoC's, the CPUs are powered by a single rail controlled by the L2 cache power controller (L2 SPM). The L2 power domain supplies power to all the CPUs and L2. It is safe to power down the domain when all the CPUs and the L2 are powered down. Powering down of the domain is done through the finite state machine on the L2 SAW. The L2 SPM can be configured to enter an idle state, when all CPUs enter their idle state. The L2 SPM state machine would turn off the cache and possibly power off the power domain as well. The SPM also guarantees that the h/w is ready for the CPU to resume, when woken up by an interrupt. Define a cluster that holds the SPM and possibly other common cluster elements. The L2 SAW is also the genpd domain provider and the CPUs are the devices attached to the domain. When CPUIdle powers down each CPU, the ARM domain framework would callback to notify that the domain may be powered off. Configure the L2 SPM at that time to flush the L2 cache and turn off the CPU power rail. Signed-off-by: Lina Iyer --- drivers/soc/qcom/spm.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c index bef2dfe1..ad1498e 100644 --- a/drivers/soc/qcom/spm.c +++ b/drivers/soc/qcom/spm.c @@ -24,9 +24,12 @@ #include #include #include +#include #include +#include #include +#include #include #include @@ -79,6 +82,7 @@ struct spm_driver_data { /* Group for domain entities */ struct cluster { struct spm_driver_data *domain_spm; + bool domain_off; }; static const u8 spm_reg_offset_v2_1[SPM_REG_NR] = { @@ -181,7 +185,23 @@ static void spm_set_low_power_mode(struct spm_driver_data *drv, static int qcom_pm_collapse(unsigned long int unused) { - qcom_scm_cpu_power_down(QCOM_SCM_CPU_PWR_DOWN_L2_ON); + int flags = QCOM_SCM_CPU_PWR_DOWN_L2_ON; + int cpu = smp_processor_id(); + bool domain_off; + + /* + * Check if the CPU domain will power off after this CPU + * enters idle. + * L2 cache may be turned off when the domain powers off, + * flush the non-secure cache before calling into secure. + */ + domain_off = per_cpu(cpu_spm_drv, cpu)->domain->domain_off; + if (domain_off) { + flags = QCOM_SCM_CPU_PWR_DOWN_L2_OFF; + flush_cache_all(); + } + + qcom_scm_cpu_power_down(flags); /* * Returns here only if there was a pending interrupt and we did not @@ -293,6 +313,35 @@ static struct cpuidle_ops qcom_cpuidle_ops __initdata = { CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v1, "qcom,kpss-acc-v1", &qcom_cpuidle_ops); CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v2, "qcom,kpss-acc-v2", &qcom_cpuidle_ops); +static int pd_power_on(struct generic_pm_domain *domain) +{ + struct spm_driver_data *drv = per_cpu(cpu_spm_drv, smp_processor_id()); + struct cluster *pmd = drv->domain; + + if (!pmd || !pmd->domain_spm) + return 0; + + pmd->domain_off = false; + spm_set_low_power_mode(pmd->domain_spm, PM_SLEEP_MODE_STBY); + + return 0; +} + +static int pd_power_off(struct generic_pm_domain *domain) +{ + struct spm_driver_data *drv = per_cpu(cpu_spm_drv, smp_processor_id()); + struct cluster *pmd = drv->domain; + + if (!pmd || !pmd->domain_spm) + return 0; + + pmd->domain_off = true; + spm_set_low_power_mode(pmd->domain_spm, PM_SLEEP_MODE_SPC); + + return 0; +} + + /* Match L2 SPM with their affinity level */ static const struct of_device_id cache_spm_table[] = { { }, @@ -418,8 +467,18 @@ static int spm_dev_probe(struct platform_device *pdev) spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY); /* We are ready to use the CPU/Cache SPM. */ - if (is_domain_spm) + if (is_domain_spm) { + struct of_phandle_args args; + int ret; + + args.np = pdev->dev.of_node; + args.args_count = 0; + ret = register_platform_domain_handlers(&args, + pd_power_on, pd_power_off); + if (ret) + dev_dbg(&pdev->dev, "Domain callback not registered\n"); cpu_domain[index].domain_spm = drv; + } else per_cpu(cpu_spm_drv, index) = drv;