From patchwork Tue Nov 17 22:37:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 56896 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp2218478lbb; Tue, 17 Nov 2015 14:39:33 -0800 (PST) X-Received: by 10.66.156.106 with SMTP id wd10mr65646718pab.150.1447799958688; Tue, 17 Nov 2015 14:39:18 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id hx5si60778575pbc.82.2015.11.17.14.39.18; Tue, 17 Nov 2015 14:39:18 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dkim=neutral (body hash did not verify) header.i=@linaro_org.20150623.gappssmtp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932622AbbKQWi6 (ORCPT + 6 others); Tue, 17 Nov 2015 17:38:58 -0500 Received: from mail-pa0-f53.google.com ([209.85.220.53]:32943 "EHLO mail-pa0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932592AbbKQWiz (ORCPT ); Tue, 17 Nov 2015 17:38:55 -0500 Received: by pabfh17 with SMTP id fh17so22935878pab.0 for ; Tue, 17 Nov 2015 14:38:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vWZW5o0Skdf6PXWHZNitDM6duJCADwD7ysvec3cS1qA=; b=LQ7UDX/bzcqVv8o5U8Pxhq/JlRjR/izh10NcFyvQubtRpB9wABzJ0xfY8vpIyUftFm gd9mqimPk3mIYnTlWd4vuUUJiLvzMOELtV+eO3KuW1QNzFgL4vnaPL2uKAnTqSc6yuGm FXXVicXHL/2+vUM1bV1qqZ+jwj7e24n48/lWmrp+wsXNH8mBHHl2GGU8ez8O6kZT1jZl vK7gvpKiOXVkE8A3UoQRTUeo3NdeNEQcr51C/nux3KKKgBdoX9gdlEix1800IEvHBheh HtCxuwlWygO9YSucTzYYFU4PkMB9S59NGPwNGDcawYVPCUMrHjxVaJ/pOU/wZn8ko4KB uG6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vWZW5o0Skdf6PXWHZNitDM6duJCADwD7ysvec3cS1qA=; b=kRR5IqXTkE/Hi8kQxwxyaGhCmNgwRc1RbZtAqZIRz5Ob+WYGO56GFjpcLI3hEEYsyW Y3VsqJgODvnki2h3yhkpuJLcDLo7G16bXGYcsA+/F4eDxz9dlMcsLsQeYADH5wLZ88e0 YS6GN6IpAkgk/AQphoE/UDIVr1bqhH0uyqHENV2Mz8nvlWSyi5yhcAY8kpVrld1q5vYA N3R0K2m7KYa2/J7QuZ90BHMloMjRyFVGK7okb1mHSeG2lTKYKrUt4U9SxVns/nwTahqr qemj3BzxFkYpAc+H9MrSU5SWgU7fy2iaJW5ZMHo9uMoAlVjfzs1VMq3VgxP7ggs631U5 sUZw== X-Gm-Message-State: ALoCoQm/f1rt3uJGhTxnoIBWDJeZrgU+tQ0VJJF8j5n6lVTZEuXesDYcB+uZ+LMSIpf9gNrLNIw0 X-Received: by 10.67.23.229 with SMTP id id5mr67540940pad.64.1447799934800; Tue, 17 Nov 2015 14:38:54 -0800 (PST) Received: from ubuntu.localdomain ([8.42.77.226]) by smtp.gmail.com with ESMTPSA id hy1sm14875199pbb.63.2015.11.17.14.38.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Nov 2015 14:38:53 -0800 (PST) From: Lina Iyer To: ulf.hansson@linaro.org, khilman@linaro.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: geert@linux-m68k.org, k.kozlowski@samsung.com, msivasub@codeaurora.org, agross@codeaurora.org, sboyd@codeaurora.org, linux-arm-msm@vger.kernel.org, lorenzo.pieralisi@arm.com, ahaslam@baylibre.com, mtitinger@baylibre.com, Lina Iyer Subject: [PATCH RFC 18/27] drivers: cpu-pd: Add PM Domain governor for CPUs Date: Tue, 17 Nov 2015 15:37:42 -0700 Message-Id: <1447799871-56374-19-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> References: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org A PM domain comprising of CPUs may be powered off when all the CPUs in the domain are powered down. Powering down a CPU domain is generally a expensive operation and therefore the power performance trade offs should be considered. The time between the last CPU powering down and the first CPU powering up in a domain, is the time available for the domain to sleep. Ideally, the sleep time of the domain should fulfill the residency requirement of the domains' idle state. To do this effectively, read the time before the wakeup of the cluster's CPUs and ensure that the domain's idle state sleep time guarantees the QoS requirements of each of the CPU, the PM QoS CPU_DMA_LATENCY and the state's residency. Signed-off-by: Lina Iyer --- drivers/base/power/cpu-pd.c | 83 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c index 617ce54..a00abc1 100644 --- a/drivers/base/power/cpu-pd.c +++ b/drivers/base/power/cpu-pd.c @@ -21,6 +21,7 @@ #include #include #include +#include #define CPU_PD_NAME_MAX 36 @@ -66,6 +67,86 @@ static void get_cpus_in_domain(struct generic_pm_domain *genpd, } } +static bool cpu_pd_down_ok(struct dev_pm_domain *pd) +{ + struct generic_pm_domain *genpd = pd_to_genpd(pd); + struct cpu_pm_domain *cpu_pd = to_cpu_pd(genpd); + int qos = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); + u64 sleep_ns = ~0; + ktime_t earliest; + int cpu; + int i; + + /* Reset the last set genpd state, default to index 0 */ + genpd->state_idx = 0; + + /* We dont want to power down, if QoS is 0 */ + if (!qos) + return false; + + /* + * Find the sleep time for the cluster. + * The time between now and the first wake up of any CPU that + * are in this domain hierarchy is the time available for the + * domain to be idle. + */ + earliest.tv64 = KTIME_MAX; + for_each_cpu_and(cpu, cpu_pd->cpus, cpu_online_mask) { + struct device *cpu_dev = get_cpu_device(cpu); + struct gpd_timing_data *td; + + td = &dev_gpd_data(cpu_dev)->td; + + if (earliest.tv64 < td->next_wakeup.tv64) + earliest = td->next_wakeup; + } + + sleep_ns = ktime_to_ns(ktime_sub(earliest, ktime_get())); + if (sleep_ns <= 0) + return false; + + /* + * Find the deepest sleep state that satisfies the residency + * requirement and the QoS constraint + */ + for (i = genpd->state_count - 1; i > 0; i--) { + u64 state_sleep_ns; + + state_sleep_ns = genpd->states[i].power_off_latency_ns + + genpd->states[i].power_on_latency_ns + + genpd->states[i].residency_ns; + + /* + * If we cant sleep to save power in the state, move on + * to the next lower idle state. + */ + if (state_sleep_ns > sleep_ns) + continue; + + /* + * We also dont want to sleep more than we should to + * gaurantee QoS. + */ + if (state_sleep_ns < (qos * NSEC_PER_USEC)) + break; + } + + if (i >= 0) + genpd->state_idx = i; + + return (i >= 0) ? true : false; +} + +static bool cpu_stop_ok(struct device *dev) +{ + return true; +} + +struct dev_power_governor cpu_pd_gov = { + .power_down_ok = cpu_pd_down_ok, + .stop_ok = cpu_stop_ok, +}; + static int cpu_pd_power_off(struct generic_pm_domain *genpd) { struct cpu_pm_domain *pd = to_cpu_pd(genpd); @@ -183,7 +264,7 @@ int of_register_cpu_pm_domain(struct device_node *dn, /* Register the CPU genpd */ pr_debug("adding %s as CPU PM domain.\n", pd->genpd->name); - ret = of_pm_genpd_init(dn, pd->genpd, &simple_qos_governor, false); + ret = of_pm_genpd_init(dn, pd->genpd, &cpu_pd_gov, false); if (ret) { pr_err("Unable to initialize domain %s\n", dn->full_name); return ret;