From patchwork Tue Sep 19 22:32:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 113071 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp34958qgf; Tue, 19 Sep 2017 15:34:13 -0700 (PDT) X-Received: by 10.84.138.193 with SMTP id 59mr115639plp.414.1505860453588; Tue, 19 Sep 2017 15:34:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505860453; cv=none; d=google.com; s=arc-20160816; b=A0pT6MIxYr6GpQP71yD2dEKNcNYXs/WQw2mDDzN4OSJp5Z/o+UsqcrmdNB76i7j8U6 4h6LkSlMvt4Dbr4zWMJr7Oh+h6fuPUNA0uQyp3BwGjrkm63zt+5MvukffaRy6yd0J+AO DSHLexER0Ho3PJI0p2lovKHqW/a32Vnx6848bCwpxfS+R38tMPmeAqufZpz/NGeCWhRC yJcN2Bqchp7ir3leYw+5HnwGAXQqrQrobSEuqDet81paxbuESYJYLfvSC8EosyUoetjz z30iUs5C4l3vK+oQU/0I8h4UDJ4J7YnOeEnoBEZs9IHeOncEwgm1P803skLCKblxyZ9C ejHg== 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=LDInNzQqi0kfwi+YD241hE2JtkAkUc/AWSifUBGwiAA=; b=GG9olpaoFHzmMiMSO/YtNcvVhKqaNKjIcyxHIxPNFV5+rAY+y7WmaLIBFO6qYU4+E4 xc2SWLlEH30PKuVsWuzHBSeOqZZgK7yynD0rZ4/gZCh/ysIwNl7oMmxcB0nU/H1FZHt2 OqjEiCNK4AkYOYXyNVCUlm4BYwGAPlUtTjRL4XXLLtVDRO59Y9EzT53NgxeEnwLgSocI 8N7KwQrAxU0B/R8LKUkzD/8wwGtZz4jejaHKiQMavVoJNgT/YdW15wdocIMUaHyTkahg 4vyYgou/nbdCLueyIKNKCxaLporBLSoY3mtK1FhYYoQIjLTkVvBQryXwY1EfQUibprZU ooKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LDWKYem4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 e6si1973729pfg.3.2017.09.19.15.34.13; Tue, 19 Sep 2017 15:34:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=LDWKYem4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 S1751883AbdISWeL (ORCPT + 26 others); Tue, 19 Sep 2017 18:34:11 -0400 Received: from mail-pg0-f44.google.com ([74.125.83.44]:52649 "EHLO mail-pg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751653AbdISWcj (ORCPT ); Tue, 19 Sep 2017 18:32:39 -0400 Received: by mail-pg0-f44.google.com with SMTP id i195so601523pgd.9 for ; Tue, 19 Sep 2017 15:32:39 -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=LDInNzQqi0kfwi+YD241hE2JtkAkUc/AWSifUBGwiAA=; b=LDWKYem43/wpnPPp29DMHPJ/ELt56QcOhKfCkNbjkz05xMNVPAYhyvrim5AsfLXRzf Tj7gj0P2IkyKiNgV9vMID/k/5Nru0vZ+NJrt2viGhHgTY62dFYzpckJuVGR1kaeT2r6z EErkP2BQr9VL4ABKB4gFHfiqd8hSqMoXyOako= 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=LDInNzQqi0kfwi+YD241hE2JtkAkUc/AWSifUBGwiAA=; b=LwsUD+WdM5GOsjTCRHA0n/e4HcCbQlMEDZXzgkfOSsCwdG3U4VLkCc6/n7fsvNozwa SrhhSRcvA4QLSF7z86kTdWB9jjBO5fe6weTsylZgRDoJiQYkxaRf7Vc11y5VGziGxYML ATgwAsjBydVktV8Js26CASdnSHWnx3QdbU9CQxhqh3KkN6REXCQPIZC6lS5X2Q/Fvmcd ZZIKpMWMSY7Fj7HF9XxGfnuRTVFONkZQOhs5ewTdMDLEah66k08/vOVWjtyfBi2w2Zda 8lv51CyXSUzNLOioZnoonxwGfclagCQc9kmBEaiMoIbLn0Z8pNcCZnTsMnEsQHuJhfzG V7/Q== X-Gm-Message-State: AHPjjUjyQtRLB5XoO8Za9wUJSv5HYqZyuoixkqXiymTIabAIce5sgQob q3cxHvQL402CC2XVa8+BipSoCg== X-Google-Smtp-Source: AOwi7QA0ZHF8wjMq1aqYCIbUinnTSjXdEPy/kqjVz7cBvshYjOQePqc/Jf98HiIpDwfPGUzuk3neVg== X-Received: by 10.98.207.134 with SMTP id b128mr130844pfg.202.1505860358464; Tue, 19 Sep 2017 15:32:38 -0700 (PDT) Received: from localhost (cpe-172-88-64-62.socal.res.rr.com. [172.88.64.62]) by smtp.gmail.com with ESMTPSA id m69sm4671555pfc.38.2017.09.19.15.32.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Sep 2017 15:32:37 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V10 1/7] PM / Domains: Add support to select performance-state of domains Date: Tue, 19 Sep 2017 15:32:17 -0700 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some platforms have the capability to configure the performance state of PM domains and this patch updates the genpd core to support them. The performance levels (within the genpd core) are identified by positive integer values, a lower value represents lower performance state. This patch adds two new genpd APIs: - int dev_pm_genpd_has_performance_state(struct device *dev) This can be called (only once) by the device drivers to make sure all dependencies are met and the PM domain of the device supports performance states. - int dev_pm_genpd_update_performance_state(struct device *dev, unsigned long rate); This can be called (any number of times) by the device drivers after they have called dev_pm_genpd_has_performance_state() once and it returned "true". This call will update the performance state of the PM domain of the device (for which this routine is called) and propagate it to the masters of the PM domain. This requires certain callbacks to be available for the genpd of the device, which are internally called by this routine in the order in which they are described below. - dev_get_performance_state() This shall return the performance state (integer value) corresponding to a target frequency for the device. This state is used by the genpd core as device's requested performance state and would be used while aggregating the requested states of all the devices and subdomains for a PM domain. Note that the same state value will be used by the device's PM domain and its masters hierarchy. We may want to implement master specific states later on once we have more complex cases available. Providing this callback is mandatory for any genpd which needs to manage performance states and is registered as master of one or more devices. Domains which only have sub domains and no devices, should not implement this callback. - genpd_set_performance_state() The aggregate of the performance states of the devices and subdomains of a PM genpd is then passed to this callback, which must change the performance state of the genpd. This callback of the masters of the genpd are also called to propagate the change. The power domains can avoid supplying these callbacks, if they don't support setting performance-states. Tested-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 277 +++++++++++++++++++++++++++++++++++++++++++- include/linux/pm_domain.h | 23 ++++ 2 files changed, 298 insertions(+), 2 deletions(-) -- 2.7.4 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index e8ca5e2cf1e5..6d05c91cf44f 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -237,6 +237,267 @@ static void genpd_update_accounting(struct generic_pm_domain *genpd) static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {} #endif +/** + * dev_pm_genpd_has_performance_state - Checks if power domain does performance + * state management. + * + * @dev: Device whose power domain is getting inquired. + * + * This can be called by the user drivers, before they start calling + * dev_pm_genpd_update_performance_state(), to guarantee that all dependencies + * are met and the device's genpd supports performance states. + * + * It is assumed that the user driver guarantees that the genpd wouldn't be + * detached while this routine is getting called. + * + * Returns "true" if device's genpd supports performance states, "false" + * otherwise. + */ +bool dev_pm_genpd_has_performance_state(struct device *dev) +{ + struct generic_pm_domain *genpd = genpd_lookup_dev(dev); + + return !IS_ERR_OR_NULL(genpd) && genpd->dev_get_performance_state; +} +EXPORT_SYMBOL_GPL(dev_pm_genpd_has_performance_state); + +static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd, + int state, int depth); + +/* Returns -ve errors or 0 on success */ +static int _genpd_set_performance_state(struct generic_pm_domain *genpd, + int state, int depth) +{ + struct generic_pm_domain *master; + struct gpd_link *link; + int prev = genpd->performance_state, ret; + + /* Propagate to masters of genpd */ + list_for_each_entry(link, &genpd->slave_links, slave_node) { + master = link->master; + + genpd_lock_nested(master, depth + 1); + + link->performance_state = state; + ret = _genpd_reeval_performance_state(master, state, depth + 1); + if (ret) + link->performance_state = prev; + + genpd_unlock(master); + + if (ret) + goto err; + } + + if (genpd->genpd_set_performance_state) { + ret = genpd->genpd_set_performance_state(genpd, state); + if (ret) + goto err; + } + + /* + * The masters are updated now, lets get genpd performance_state in sync + * with those. + */ + genpd->performance_state = state; + return 0; + +err: + /* Encountered an error, lets rollback */ + list_for_each_entry_continue_reverse(link, &genpd->slave_links, + slave_node) { + master = link->master; + + genpd_lock_nested(master, depth + 1); + link->performance_state = prev; + if (_genpd_reeval_performance_state(master, prev, depth + 1)) { + pr_err("%s: Failed to roll back to %d performance state\n", + master->name, prev); + } + genpd_unlock(master); + } + + return ret; +} + +/* + * Re-evaluate performance state of a genpd. Finds the highest requested + * performance state by the devices and subdomains within the genpd and then + * change genpd's performance state (if required). The request is then + * propagated to the masters of the genpd. + * + * @genpd: PM domain whose state needs to be reevaluated. + * @state: Newly requested performance state of the device or subdomain for + * which this routine is called. + * @depth: nesting count for lockdep. + * + * Locking rules followed are: + * + * - Device's state (pd_data->performance_state) should be accessed from within + * its master's lock protected section. + * + * - Subdomains have a separate state field (link->performance_state) per master + * domain and is accessed only from within master's lock protected section. + * + * - Subdomain's state (genpd->performance_state) should be accessed from within + * its own lock protected section. + * + * - The locks are always taken in bottom->up order, i.e. subdomain first, + * followed by its masters. + * + * Returns -ve errors or 0 on success. + */ +static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd, + int state, int depth) +{ + struct generic_pm_domain_data *pd_data; + struct pm_domain_data *pdd; + struct gpd_link *link; + + /* New requested state is same as Max requested state */ + if (state == genpd->performance_state) + return 0; + + /* New requested state is higher than Max requested state */ + if (state > genpd->performance_state) + goto update_state; + + /* Traverse all devices within the domain */ + list_for_each_entry(pdd, &genpd->dev_list, list_node) { + pd_data = to_gpd_data(pdd); + + if (pd_data->performance_state > state) + state = pd_data->performance_state; + } + + /* + * Traverse all subdomains within the domain. This can be done without + * any additional locks as all link->performance_state fields are + * protected by genpd->lock, which is already taken. + */ + list_for_each_entry(link, &genpd->master_links, master_node) { + if (link->performance_state > state) + state = link->performance_state; + } + +update_state: + return _genpd_set_performance_state(genpd, state, depth); +} + +static void __genpd_dev_update_performance_state(struct device *dev, int state) +{ + struct generic_pm_domain_data *gpd_data; + + spin_lock_irq(&dev->power.lock); + + if (!dev->power.subsys_data || !dev->power.subsys_data->domain_data) { + WARN_ON(1); + goto unlock; + } + + gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); + gpd_data->performance_state = state; + +unlock: + spin_unlock_irq(&dev->power.lock); +} + +/** + * dev_pm_genpd_update_performance_state - Update performance state of device's + * power domain for the target frequency for the device. + * + * @dev: Device for which the performance-state needs to be adjusted. + * @rate: Device's next frequency. This can be set as 0 when the device doesn't + * have any performance state constraints left (And so the device wouldn't + * participate anymore to find the target performance state of the genpd). + * + * The user drivers may want to call dev_pm_genpd_has_performance_state() (only + * once) before calling this routine (any number of times) to guarantee that all + * dependencies are met. + * + * It is assumed that the user driver guarantees that the genpd wouldn't be + * detached while this routine is getting called. + * + * Returns 0 on success and negative error values on failures. + */ +int dev_pm_genpd_update_performance_state(struct device *dev, + unsigned long rate) +{ + struct generic_pm_domain *genpd; + int ret, state; + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -ENODEV; + + genpd_lock(genpd); + + if (!genpd_status_on(genpd)) { + ret = -EBUSY; + goto unlock; + } + + state = genpd->dev_get_performance_state(dev, rate); + if (state < 0) { + ret = state; + goto unlock; + } + + ret = _genpd_reeval_performance_state(genpd, state, 0); + if (!ret) { + /* + * Since we are passing "state" to + * _genpd_reeval_performance_state() as well, we don't need to + * call __genpd_dev_update_performance_state() before updating + * genpd's state with the above call. Update it only after the + * state of master domain is updated. + */ + __genpd_dev_update_performance_state(dev, state); + } + +unlock: + genpd_unlock(genpd); + + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_genpd_update_performance_state); + +static int _genpd_on_update_performance_state(struct generic_pm_domain *genpd, + int depth) +{ + int ret, prev = genpd->prev_performance_state; + + if (likely(!prev)) + return 0; + + ret = _genpd_set_performance_state(genpd, prev, depth); + if (ret) { + pr_err("%s: Failed to restore performance state to %d (%d)\n", + genpd->name, prev, ret); + } else { + genpd->prev_performance_state = 0; + } + + return ret; +} + +static void _genpd_off_update_performance_state(struct generic_pm_domain *genpd, + int depth) +{ + int ret, state = genpd->performance_state; + + if (likely(!state)) + return; + + ret = _genpd_set_performance_state(genpd, 0, depth); + if (ret) { + pr_err("%s: Failed to set performance state to 0 (%d)\n", + genpd->name, ret); + } else { + genpd->prev_performance_state = state; + } +} + static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) { unsigned int state_idx = genpd->state_idx; @@ -388,6 +649,8 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, return ret; } + _genpd_off_update_performance_state(genpd, depth); + genpd->status = GPD_STATE_POWER_OFF; genpd_update_accounting(genpd); @@ -437,15 +700,21 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) } } - ret = _genpd_power_on(genpd, true); + ret = _genpd_on_update_performance_state(genpd, depth); if (ret) goto err; + ret = _genpd_power_on(genpd, true); + if (ret) + goto err_power_on; + genpd->status = GPD_STATE_ACTIVE; genpd_update_accounting(genpd); return 0; + err_power_on: + _genpd_off_update_performance_state(genpd, depth); err: list_for_each_entry_continue_reverse(link, &genpd->slave_links, @@ -807,6 +1076,8 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, if (_genpd_power_off(genpd, false)) return; + _genpd_off_update_performance_state(genpd, depth); + genpd->status = GPD_STATE_POWER_OFF; list_for_each_entry(link, &genpd->slave_links, slave_node) { @@ -852,7 +1123,9 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, genpd_unlock(link->master); } - _genpd_power_on(genpd, false); + if (!_genpd_on_update_performance_state(genpd, depth)) + if (_genpd_power_on(genpd, false)) + _genpd_off_update_performance_state(genpd, depth); genpd->status = GPD_STATE_ACTIVE; } diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 84f423d5633e..715cca7ac399 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -64,8 +64,13 @@ struct generic_pm_domain { unsigned int device_count; /* Number of devices */ unsigned int suspended_count; /* System suspend device counter */ unsigned int prepared_count; /* Suspend counter of prepared devices */ + unsigned int performance_state; /* Max requested performance state */ + unsigned int prev_performance_state; /* Performance state before power off */ int (*power_off)(struct generic_pm_domain *domain); int (*power_on)(struct generic_pm_domain *domain); + int (*dev_get_performance_state)(struct device *dev, unsigned long rate); + int (*genpd_set_performance_state)(struct generic_pm_domain *genpd, + unsigned int state); struct gpd_dev_ops dev_ops; s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; @@ -102,6 +107,9 @@ struct gpd_link { struct list_head master_node; struct generic_pm_domain *slave; struct list_head slave_node; + + /* Sub-domain's per-master domain performance state */ + unsigned int performance_state; }; struct gpd_timing_data { @@ -121,6 +129,7 @@ struct generic_pm_domain_data { struct pm_domain_data base; struct gpd_timing_data td; struct notifier_block nb; + unsigned int performance_state; void *data; }; @@ -148,6 +157,9 @@ extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, extern int pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); extern int pm_genpd_remove(struct generic_pm_domain *genpd); +extern bool dev_pm_genpd_has_performance_state(struct device *dev); +extern int dev_pm_genpd_update_performance_state(struct device *dev, + unsigned long rate); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; @@ -188,6 +200,17 @@ static inline int pm_genpd_remove(struct generic_pm_domain *genpd) return -ENOTSUPP; } +static inline bool dev_pm_genpd_has_performance_state(struct device *dev) +{ + return false; +} + +static inline int dev_pm_genpd_update_performance_state(struct device *dev, + unsigned long rate) +{ + return -ENOTSUPP; +} + #define simple_qos_governor (*(struct dev_power_governor *)(NULL)) #define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL)) #endif From patchwork Tue Sep 19 22:32:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 113065 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp33886qgf; Tue, 19 Sep 2017 15:32:50 -0700 (PDT) X-Received: by 10.159.204.147 with SMTP id t19mr108565plo.7.1505860370143; Tue, 19 Sep 2017 15:32:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505860370; cv=none; d=google.com; s=arc-20160816; b=gJEZmEYOuBPTNKpIB9yKqJaxjBFfx0uyo2AlLhLgdGLXkLxv/yMnHMPlMxFpLmzIWR 9LJvaceVkeAF2RAtEeEfKcc+Sdkl2u9tPW9l6ws59FLqG9ArFZWnfAKEwVkqCEUl5rt3 QzgbVQOu3f1PmUXWCWlOcEZ6PKbBriHNWsctwJ6+ZU362nyM7f8kRnpG23XZUTarFvFV 5/bAbUE1fk9M9TEqdY5XsdtWX4qbV9Fn4s6+eemNBpYVdN8ddAxy40IDnhRhjlIa9+oH +wFdWwe7Q7OxLyUdmmNXsDTuCRPWx3iXmJYXZHTXL3KhpwP8WzdDxnTK0ShtF82e+6cD ULxQ== 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=i57D9fWP9Kp+I1ZmXQ0JvWo8eiljeI6SSp4Mn792sMA=; b=y23iC84/o6OQxiQewP/WgnerVOBxBDW/GrKNIQuVUk4Ld4zvPZztNbNwaLDyrsO0PL ZPlzOiWpeIr2zOL/jXuX6YWkcYtYBw37R3m07Duxwfo9YrgFOE/lM7EpeSVh3CuYxcIy tOjRlCqtmGJVNhHE95dmuugbz4raBmVBJSYljHcRtddgRuW8KO1vXZmXAOSFiX4VqxHe dpLLSdgkaV/ijnnQat9vowkBdbi9184bVfeDLFQFSuc/Sfhf79Kg1VtIU0KBjeqs/i5I S9z4s4F8cSxN8DIwNNl3RyTMG+LXXL6iEE3vC7RWXaIB8zGdldzTKLMz2PZrU3WmkZcG LkpA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RKO7vygl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 k7si1967400pgp.676.2017.09.19.15.32.49; Tue, 19 Sep 2017 15:32:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=RKO7vygl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 S1751763AbdISWcp (ORCPT + 26 others); Tue, 19 Sep 2017 18:32:45 -0400 Received: from mail-pf0-f174.google.com ([209.85.192.174]:48651 "EHLO mail-pf0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751663AbdISWcl (ORCPT ); Tue, 19 Sep 2017 18:32:41 -0400 Received: by mail-pf0-f174.google.com with SMTP id n24so540903pfk.5 for ; Tue, 19 Sep 2017 15:32:40 -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=i57D9fWP9Kp+I1ZmXQ0JvWo8eiljeI6SSp4Mn792sMA=; b=RKO7vyglqRQmwn9lXpPfGf4xqZ29i3DxkeHGCS7Sfl+5GYPFqPN81Ktwyfu49UKDNF vEhAqK4Uo3CT96dpEBAonLXZoufILfhR2+h5XJioky5rny8BSS/tu1TEkfurfA8ZcA/p fnIPf/Wb9n7oqCHd7D3JiTmll4g8EOoYbKujM= 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=i57D9fWP9Kp+I1ZmXQ0JvWo8eiljeI6SSp4Mn792sMA=; b=lC/b17w+jjMdNOgbJQLc3YrKeWkall7d3y501K3pDZwFcHVVcFtPV3BxipplpW8sDe 7K5bHSDv672oYmyvuZVmJxcVCyDpqd+MvLNtuCIHoaK3AnB5j6QOYohJomGZ1kR1g2B/ fcCCaSrrFIAZQhnoMr8VhdoTCEGoNtj49m9W/3w6GgJPlf6/yu3y2XCn7f3dSKiBWfWG RMUBqnaZxgcvaY65o+WFkv63MejZJK4j8NVqyTiV9ffgiYwwaRnr+7zy4udq+7zz2o+S hryE+siywlekoOsNjGaokhBWEUoRScV4kzrOXlTVlFE7ylA3zlrVV0wR0VVfQSo+emAx znxA== X-Gm-Message-State: AHPjjUhxfQZOAYs3DNcSywCOLx5I0UlP68YUZxvIBu7bqfKehk6CzP0g SacnvbLIhEAHQZOJe+U+3ktS4w== X-Google-Smtp-Source: AOwi7QArOJrzoJytfbyu7RItwqEDBDRZ82tu4A3+JKY8znIwckb2ybDdRNscxZu3rOcZijxAoHv54w== X-Received: by 10.99.39.129 with SMTP id n123mr132934pgn.240.1505860360113; Tue, 19 Sep 2017 15:32:40 -0700 (PDT) Received: from localhost (cpe-172-88-64-62.socal.res.rr.com. [172.88.64.62]) by smtp.gmail.com with ESMTPSA id e27sm5538722pfk.41.2017.09.19.15.32.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Sep 2017 15:32:39 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V10 2/7] PM / OPP: Support updating performance state of device's power domains Date: Tue, 19 Sep 2017 15:32:18 -0700 Message-Id: <8850bb5088dc6fec4463247b0ec5040ce6415f2d.1505859768.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The genpd framework now provides an API to request device's power domain to update its performance state based on a particular target frequency for the device. Use that interface from the OPP core for devices whose power domains support performance states. Note that the current implementation is restricted to the case where the device doesn't have separate regulators for itself. We shouldn't over engineer the code before we have real use case for them. We can always come back and add more code to support such cases later on. Tested-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/base/power/opp/core.c | 48 ++++++++++++++++++++++++++++++++++++++++++- drivers/base/power/opp/opp.h | 2 ++ 2 files changed, 49 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index a8cc14fd8ae4..4360b4efcd4c 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "opp.h" @@ -535,6 +536,42 @@ _generic_set_opp_clk_only(struct device *dev, struct clk *clk, return ret; } +static inline int +_generic_set_opp_domain(struct device *dev, struct clk *clk, + unsigned long old_freq, unsigned long freq) +{ + int ret; + + /* Scaling up? Scale domain performance state before frequency */ + if (freq > old_freq) { + ret = dev_pm_genpd_update_performance_state(dev, freq); + if (ret) + return ret; + } + + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + if (ret) + goto restore_domain_state; + + /* Scaling down? Scale domain performance state after frequency */ + if (freq < old_freq) { + ret = dev_pm_genpd_update_performance_state(dev, freq); + if (ret) + goto restore_freq; + } + + return 0; + +restore_freq: + if (_generic_set_opp_clk_only(dev, clk, freq, old_freq)) + dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", + __func__, old_freq); +restore_domain_state: + dev_pm_genpd_update_performance_state(dev, old_freq); + + return ret; +} + static int _generic_set_opp_regulator(const struct opp_table *opp_table, struct device *dev, unsigned long old_freq, @@ -653,7 +690,14 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) /* Only frequency scaling */ if (!opp_table->regulators) { - ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + /* + * We don't support devices with both regulator and + * domain performance-state for now. + */ + if (opp_table->genpd_performance_state) + ret = _generic_set_opp_domain(dev, clk, old_freq, freq); + else + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); } else if (!opp_table->set_opp) { ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq, IS_ERR(old_opp) ? NULL : old_opp->supplies, @@ -755,6 +799,8 @@ static struct opp_table *_allocate_opp_table(struct device *dev) ret); } + opp_table->genpd_performance_state = dev_pm_genpd_has_performance_state(dev); + BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head); INIT_LIST_HEAD(&opp_table->opp_list); mutex_init(&opp_table->lock); diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index 166eef990599..1efa253e1934 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h @@ -135,6 +135,7 @@ enum opp_table_access { * @clk: Device's clock handle * @regulators: Supply regulators * @regulator_count: Number of power supply regulators + * @genpd_performance_state: Device's power domain support performance state. * @set_opp: Platform specific set_opp callback * @set_opp_data: Data to be passed to set_opp callback * @dentry: debugfs dentry pointer of the real device directory (not links). @@ -170,6 +171,7 @@ struct opp_table { struct clk *clk; struct regulator **regulators; unsigned int regulator_count; + bool genpd_performance_state; int (*set_opp)(struct dev_pm_set_opp_data *data); struct dev_pm_set_opp_data *set_opp_data; From patchwork Tue Sep 19 22:32:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 113070 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp34728qgf; Tue, 19 Sep 2017 15:33:57 -0700 (PDT) X-Received: by 10.84.217.27 with SMTP id o27mr98159pli.339.1505860437389; Tue, 19 Sep 2017 15:33:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505860437; cv=none; d=google.com; s=arc-20160816; b=oKS14X1qiJlV5+fysuJXzmTJU2+t0nNTBAweN85dNUb0zbg4Hot4+T4XHtWR6O4iWb 904l0x02kF7rDimZsRKXJkpPbY8m1ADj3tZ+CDOd0a5J/fPRjSiN72za1+MJbc6kRC/K +0MC5ZobyzRbcOKko18oBtIy4OS8zF1ET+8wzkV7621me0fCOzn+PfQAaJhVcoC5Xw+Q NcyP0jphWciT56Eu+smUrE5t8Q/b6YGUzt8HpPHWnVVqxTG7GMNspvQVMp2ThcmG5kFH hjHzOytjwd+OSGq2BtXLtMs24aKbIs3QMpG8w8hq04tDff2QsYLsI6Uz3DK8tSGRIu/G lBEw== 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=QnufuqY2MfSRVWRFA1lwc1lGASp65+sGryeN0sqeYbY=; b=fR7ILWjudIfLMoZDSYHWfczaF7AAzD2fF3Zxsb3hUy0ihKOOelyXsH29UucyAQTqln cAiABPmicWzEiSFiC+u7KNceyQzQn0RVF2TRIBTeXfE4Sr0c86xzhC63a3jqR2VsdTZP 1hHxhYStT6Z9GQCXjreq3jc8PJJAr8ccOqyRS5etsiusAcWeZ7Z8IelREInZj2l33av0 OJ1SDrwSZ++kCnLQJa4T3ZyCNr6zREQJKAjDsU79EYgi9TCw6+4IGG2t6nOtgsKv1yyN opII46zl/zFOuNlNEIJB97/jSj6RGql4OpAJWMWZ99v23cFHYmQEl7m/+6F4AQzNrT0o iGJA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=icgv6W9W; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 i5si229453plt.633.2017.09.19.15.33.57; Tue, 19 Sep 2017 15:33:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=icgv6W9W; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 S1751873AbdISWdy (ORCPT + 26 others); Tue, 19 Sep 2017 18:33:54 -0400 Received: from mail-pf0-f174.google.com ([209.85.192.174]:47234 "EHLO mail-pf0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751709AbdISWcm (ORCPT ); Tue, 19 Sep 2017 18:32:42 -0400 Received: by mail-pf0-f174.google.com with SMTP id u12so543384pfl.4 for ; Tue, 19 Sep 2017 15:32:42 -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=QnufuqY2MfSRVWRFA1lwc1lGASp65+sGryeN0sqeYbY=; b=icgv6W9WdwKuHqCuhQaTVGwIX8KRICc4nWKqAgnpBbjVUwY08s6Y+dukdnh+/iS6il quB2A/xstEt3EdIk1Yfc9PXnYuMJ2Vlx6Le80UBBX1OYJDAZ7X9Ai7xNbVRYPuk1zpU0 39G2QmFKXN9fSi9nHThFpFp2M6c+bc5C0B198= 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=QnufuqY2MfSRVWRFA1lwc1lGASp65+sGryeN0sqeYbY=; b=Aqfxl61pQnMwZ/3tMCjNeerbdNDAx3/KHIzR9IOJHByuf9oI8ZDIWY4BXR5MkLVc97 7k3G8JYmXf3z8m+dWlPrYy8frpqFJayeSUmwWYgIiCuFeaz+Ckpqre8DKe3ImJghgqOL e/3qgSznfWe/51JO9fvDN7AoiZ670w+qG97QfK94cJnF/Yk57oQqmIVBBkhstLOOtzAK OOTov7BGR64r60s/K6kWd3X7Rqy9QAfpgoHe1qCgyREnIRZ2H3j4cMA0c6irKUpoH9cF RUZk2EadR8xl3h6dcgL15ps2oQCEM0yjYgl1Y/A5ZX3/d2HbHrgPgLkvHay+w5iSbkzm wMrQ== X-Gm-Message-State: AHPjjUgLu4RHnAd9ZJ3/8UO6T/aYQ77K8U/nFsBJxteySZOULG+pE01X QhIxu2NKhWs+SOHaJ0RkgmEhXg== X-Google-Smtp-Source: AOwi7QCKBXTHEXQx1KYpR2bunZv8eMWPFx2Jh2n1ispD+kkWJVH2gK9ZqZDBTnSibzzmaUoiW+vvnw== X-Received: by 10.99.42.11 with SMTP id q11mr117439pgq.7.1505860361784; Tue, 19 Sep 2017 15:32:41 -0700 (PDT) Received: from localhost (cpe-172-88-64-62.socal.res.rr.com. [172.88.64.62]) by smtp.gmail.com with ESMTPSA id b65sm4626960pfg.30.2017.09.19.15.32.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Sep 2017 15:32:41 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V10 3/7] PM / Domains: Catch missing genpd_set_performance_state() in masters Date: Tue, 19 Sep 2017 15:32:19 -0700 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch catches the cases where dev_get_performance_state() callback is implemented for a genpd, but none of its masters or their masters (and so on) have implemented genpd_set_performance_state() callback. The internal performance state routines don't return 0 anymore for success, rather they return count of the domains whose performance state is updated and the top level routine checks for that. A zero value there would indicate that the genpd_set_performance_state() callbacks are missing in the master hierarchy of the device. This adds very little burden on the API and can be pretty useful. Tested-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- Note that similar checks aren't present in other APIs in genpd, like genpd_power_on/off(). Maybe we should add some there as well? --- drivers/base/power/domain.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) -- 2.7.4 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6d05c91cf44f..7e00b817abc7 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -264,13 +264,13 @@ EXPORT_SYMBOL_GPL(dev_pm_genpd_has_performance_state); static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd, int state, int depth); -/* Returns -ve errors or 0 on success */ +/* Returns -ve errors or number of domains whose performance is set */ static int _genpd_set_performance_state(struct generic_pm_domain *genpd, int state, int depth) { struct generic_pm_domain *master; struct gpd_link *link; - int prev = genpd->performance_state, ret; + int prev = genpd->performance_state, ret, count = 0; /* Propagate to masters of genpd */ list_for_each_entry(link, &genpd->slave_links, slave_node) { @@ -280,19 +280,23 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd, link->performance_state = state; ret = _genpd_reeval_performance_state(master, state, depth + 1); - if (ret) + if (ret < 0) link->performance_state = prev; genpd_unlock(master); - if (ret) + if (ret < 0) goto err; + + count += ret; } if (genpd->genpd_set_performance_state) { ret = genpd->genpd_set_performance_state(genpd, state); if (ret) goto err; + + count++; } /* @@ -300,7 +304,7 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd, * with those. */ genpd->performance_state = state; - return 0; + return count; err: /* Encountered an error, lets rollback */ @@ -310,7 +314,7 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd, genpd_lock_nested(master, depth + 1); link->performance_state = prev; - if (_genpd_reeval_performance_state(master, prev, depth + 1)) { + if (_genpd_reeval_performance_state(master, prev, depth + 1) < 0) { pr_err("%s: Failed to roll back to %d performance state\n", master->name, prev); } @@ -345,7 +349,7 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd, * - The locks are always taken in bottom->up order, i.e. subdomain first, * followed by its masters. * - * Returns -ve errors or 0 on success. + * Returns -ve errors or number of domains whose performance is set. */ static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd, int state, int depth) @@ -354,9 +358,14 @@ static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd, struct pm_domain_data *pdd; struct gpd_link *link; - /* New requested state is same as Max requested state */ - if (state == genpd->performance_state) - return 0; + if (state == genpd->performance_state) { + /* + * New requested state is same as Max requested state, return 1 + * to distinguish from the case where none of the masters have + * set their genpd_set_performance_state() callback. + */ + return 1; + } /* New requested state is higher than Max requested state */ if (state > genpd->performance_state) @@ -444,7 +453,7 @@ int dev_pm_genpd_update_performance_state(struct device *dev, } ret = _genpd_reeval_performance_state(genpd, state, 0); - if (!ret) { + if (ret > 0) { /* * Since we are passing "state" to * _genpd_reeval_performance_state() as well, we don't need to @@ -453,6 +462,13 @@ int dev_pm_genpd_update_performance_state(struct device *dev, * state of master domain is updated. */ __genpd_dev_update_performance_state(dev, state); + ret = 0; + } else if (ret < 0) { + dev_err(dev, "Couldn't update performance state (%d)\n", ret); + } else { + WARN(1, "%s: None of %s and its masters have provided genpd_set_performance_state()\n", + __func__, genpd->name); + ret = -ENODEV; } unlock: @@ -471,7 +487,7 @@ static int _genpd_on_update_performance_state(struct generic_pm_domain *genpd, return 0; ret = _genpd_set_performance_state(genpd, prev, depth); - if (ret) { + if (ret < 0) { pr_err("%s: Failed to restore performance state to %d (%d)\n", genpd->name, prev, ret); } else { @@ -490,7 +506,7 @@ static void _genpd_off_update_performance_state(struct generic_pm_domain *genpd, return; ret = _genpd_set_performance_state(genpd, 0, depth); - if (ret) { + if (ret < 0) { pr_err("%s: Failed to set performance state to 0 (%d)\n", genpd->name, ret); } else { From patchwork Tue Sep 19 22:32:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 113067 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp33930qgf; Tue, 19 Sep 2017 15:32:53 -0700 (PDT) X-Received: by 10.98.66.220 with SMTP id h89mr126311pfd.270.1505860372980; Tue, 19 Sep 2017 15:32:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505860372; cv=none; d=google.com; s=arc-20160816; b=OHbqCvAd7bSe54jfqd2x/lhKVZ9jwvC56Le3/OFQG5ixKn2qJPBhDZN5PBkRAW2Evd eJkkrnl9bNpR6Ym/BQMaat8iFMRIwx4+0JFGhpQEEzgMBTUpPNliSntzPdx6JDTJhwso se6al/o8z7OyOYYEZSVNZilWonwuM2oVEOkV408rkhZSwynZs6U1NYf6xwkKM791Zcij QRJ2xEJFSnMxMb9vHouYN02kbdgLfWukI2sZxawj1R/Oyqiy0u5Nms1/L8SySyj5ttLn VMk0wdThOu+kyzUc5yCbJXtaWvpoNx+HyM5OAleh91lSlZomSn8VmunXwR8/5lNo0i+e 3i2g== 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=6PW0kyzPDmXgaloqMNG2aoKogf91kc/ifQlLjujXcbg=; b=pY8ZFqCEnE6NbZFvOdvCdr1N57p/O2Bj8KK36RSXE/tWfBUNCVYfWpJ0fjhSkEZTDz P4NXtglQf98pMpGIcsm2RvLVToVm95JB2YT4hxNElvi1sF65mYElqzQXVLM283YLFoL7 66iwv9KKHIP71qnhF/SBZvHMQcytCqhVB5Zcd3UBfmDVAntXbjd5m2cfRf42OAPujhf8 XrvBSwDsmKuV1GtF7XxfXd+Lorm7+WXW15OopmFce9xRFLZF8nFRa10o1k+mFdF3Qa6O JgrNln9NsOxAPGFVRkef2g9CcXyPQQTIL+C8W2+VejEuhzVHVWMFD1/LgcGOqZ+UHQrM cVow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jO28G81M; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 y7si231205plh.605.2017.09.19.15.32.52; Tue, 19 Sep 2017 15:32:52 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=jO28G81M; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 S1751797AbdISWct (ORCPT + 26 others); Tue, 19 Sep 2017 18:32:49 -0400 Received: from mail-pg0-f44.google.com ([74.125.83.44]:50477 "EHLO mail-pg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751747AbdISWcp (ORCPT ); Tue, 19 Sep 2017 18:32:45 -0400 Received: by mail-pg0-f44.google.com with SMTP id p5so606668pgn.7 for ; Tue, 19 Sep 2017 15:32:45 -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=6PW0kyzPDmXgaloqMNG2aoKogf91kc/ifQlLjujXcbg=; b=jO28G81MAy4SwGqxtZrpc0eVeoFyG2awqNeI9umJ01a5gcWp6R1ePZK5LBc68nWx7l hIg3MXzKxc7x+WnZaUcko7nWclU+QHcxIXCXgcHdRzL1ho/hIFSo3detnkM8rEYDtlW1 wfveD4OAz6PRMF6fiaLD3tNFS8Qfz4wVl4BqY= 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=6PW0kyzPDmXgaloqMNG2aoKogf91kc/ifQlLjujXcbg=; b=GUCnRo0c2TxLVog9EKyHXuNMXZqL0IXALH/1Ns+kkl/5+Gq4gaWBPwqyfTk7T6RMNn p/4iyn7s5fxv0xJs8WhO0xB+3vX/fkcZIrnvdzrPnT8oWM88lr2sQqyv7NuPupMt7hO8 lC8mx36uAar8Y/jDUWzakfiKEiz99EGX8bc9ROjzdBz0OMtkCAXP+nGqR7QAra0UEplm viCdYVAcrm3O18Z1+4krWy8NbUlmCJb1aWh/gJPuP/bGNuPYitfA2CtCPRKx9zzX5sZD rCTJ/QzaYQdCZu6EqGhoSipYbXpug/MdWh5+WH5VnKOrz1vu/9vyGg2kfoHOorMTymxG qb2A== X-Gm-Message-State: AHPjjUi1+tKvnlDCTiRBuo9wJmetbmFdXfw4K8UWRLLnkeLRDKplkIVh KOemvbWh0iceAi/Q2QVf3a9kpw== X-Google-Smtp-Source: AOwi7QDoVb2Z/IxAFMzHIfkJfkFb9AL8RncRXEZhzEoGRqouIgl8Zb0Y2FtBBrnGLgdGFjd361hxUw== X-Received: by 10.101.80.1 with SMTP id f1mr137321pgo.80.1505860364866; Tue, 19 Sep 2017 15:32:44 -0700 (PDT) Received: from localhost (cpe-172-88-64-62.socal.res.rr.com. [172.88.64.62]) by smtp.gmail.com with ESMTPSA id u8sm5437504pgq.52.2017.09.19.15.32.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Sep 2017 15:32:44 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V10 5/7] soc: qcom: rpmpd: Add support for get/set performance state Date: Tue, 19 Sep 2017 15:32:21 -0700 Message-Id: <678142c5519947b9f51a652e22fd293ac6766838.1505859768.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rajendra Nayak THIS IS TEST CODE, SHOULDN'T BE MERGED. With genpd now expecting powerdomain drivers supporting performance state to support get/set performance state callbacks, add support for it in the rpmpd driver. Not-signed-off-by: Rajendra Nayak Not-signed-off-by: Viresh Kumar --- drivers/soc/qcom/rpmpd.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) -- 2.7.4 diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index d34d9c363815..4e4f5cda9ce2 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -101,6 +101,20 @@ struct rpmpd_desc { size_t num_pds; }; +enum rpmpd_levels { + NONE, + LOWER, /* SVS2 */ + LOW, /* SVS */ + NOMINAL, /* NOMINAL */ + HIGH, /* Turbo */ + MAX_LEVEL, +}; + +struct rpmpd_freq_map { + struct rpmpd *pd; + unsigned long freq[MAX_LEVEL]; +}; + static DEFINE_MUTEX(rpmpd_lock); /* msm8996 RPM powerdomains */ @@ -126,6 +140,47 @@ static const struct rpmpd_desc msm8996_desc = { .num_pds = ARRAY_SIZE(msm8996_rpmpds), }; +enum msm8996_devices { + SDHCI, + UFS, + PCIE, + USB3, +}; + +static struct rpmpd_freq_map msm8996_rpmpd_freq_map[] = { + [SDHCI] = { + .pd = &msm8996_vddcx, + .freq[LOWER] = 19200000, + .freq[LOW] = 200000000, + .freq[NOMINAL] = 400000000, + }, + [UFS] = { + .pd = &msm8996_vddcx, + .freq[LOWER] = 19200000, + .freq[LOW] = 100000000, + .freq[NOMINAL] = 200000000, + .freq[HIGH] = 240000000, + }, + [PCIE] = { + .pd = &msm8996_vddcx, + .freq[LOWER] = 1011000, + }, + [USB3] = { + .pd = &msm8996_vddcx, + .freq[LOWER] = 60000000, + .freq[LOW] = 120000000, + .freq[NOMINAL] = 150000000, + }, +}; + +static const struct of_device_id rpmpd_performance_table[] = { + { .compatible = "qcom,sdhci-msm-v4", .data = (void *)SDHCI }, + { .compatible = "qcom,ufshc", .data = (void *)UFS }, + { .compatible = "qcom,pcie-msm8996", .data = (void *)PCIE }, + { .compatible = "qcom,dwc3", .data = (void *)USB3 }, + { } +}; + static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,rpmpd-msm8996", .data = &msm8996_desc }, { } @@ -230,6 +285,49 @@ static int rpmpd_power_off(struct generic_pm_domain *domain) return ret; } +static int rpmpd_set_performance(struct generic_pm_domain *domain, + unsigned int state) +{ + int ret = 0; + struct rpmpd *pd = domain_to_rpmpd(domain); + + mutex_lock(&rpmpd_lock); + + pd->corner = state; + + if (!pd->enabled && (pd->key != KEY_FLOOR_CORNER)) + goto out; + + ret = rpmpd_aggregate_corner(pd); + +out: + mutex_unlock(&rpmpd_lock); + + return ret; +} + + +static int rpmpd_get_performance(struct device *dev, unsigned long rate) +{ + int i; + unsigned long index; + const struct of_device_id *id; + + if (!rate) + return 0; + + id = of_match_device(rpmpd_performance_table, dev); + if (!id) + return -EINVAL; + + index = (unsigned long)id->data; + for (i = 0; i < MAX_LEVEL; i++) + if (msm8996_rpmpd_freq_map[index].freq[i] >= rate) + return i; + + return MAX_LEVEL; +} + static int rpmpd_probe(struct platform_device *pdev) { int i; @@ -267,6 +365,8 @@ static int rpmpd_probe(struct platform_device *pdev) rpmpds[i]->rpm = rpm; rpmpds[i]->pd.power_off = rpmpd_power_off; rpmpds[i]->pd.power_on = rpmpd_power_on; + rpmpds[i]->pd.genpd_set_performance_state = rpmpd_set_performance; + rpmpds[i]->pd.dev_get_performance_state = rpmpd_get_performance; pm_genpd_init(&rpmpds[i]->pd, NULL, true); data->domains[i] = &rpmpds[i]->pd; From patchwork Tue Sep 19 22:32:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 113068 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp34110qgf; Tue, 19 Sep 2017 15:33:09 -0700 (PDT) X-Received: by 10.159.198.74 with SMTP id y10mr106764plt.45.1505860389439; Tue, 19 Sep 2017 15:33:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505860389; cv=none; d=google.com; s=arc-20160816; b=gwyIkVgMh9cmpOfoSV6cbnAD2A9IEr03t89oa37h6OaJVKQawwd16vFYQ/NSJd/9AM hFjWjkZtyTra8a+Yj1rna3uBqFO8MuGskGyEeXgJvVAAu7KJCuG+HVu+0cHJ9Kc2o2V3 PFURuBpSXo1C6v2xXBbgfYIazsPPmBO/MJKBOwlqpubPyPnDHLGa66LzimoP5XRKrXcP QToQTEc42cyl7oR6D2rJLS+diaUyqaYaGpZ96oy293JnuXPGscRr1o86NqhJoNt+alNK txAlJjYDAxD4wzzjj0K1xfWA4DHE9C7VoIvVFGSV/twX3YN+mZQG0caBhLYF2iMc9M4m Lbxg== 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=sb2NA7EgCbClj7J2sUSx8EN3Q8urKhCHn6JapG2gyY8=; b=MWMWu6/nepGyhr2+QSdVnO+8m+y63CSEnRmfe8XiF7ja0GK66VPQ+ojlNhp1OvQXoY 1gJC7MD1QbKqFA5u4v8EKpOodSncEBhvksF6hQqAbsJP55zgXUUgcJ7l3ZhX0E1d3DOx ARa4iT6x0A03IedCA5bfaZsBrdes+v6NzflBZp/bUHieSFkTMAOus60cDiVo70VSJ4uv 7xzmVC20D++8iM/N830MA1W0oOA1kENGK+bwYEEfA9t56HdMcMOTvTIqfzne0nGskty2 +meA/5Il2su4QGzVTAwwNjfMV3B8EmDlg5tngf/NbVBdHT2Q5N+iBSNmyGuUbuJQnGX/ /cIQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WtnjFGrh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 y7si231205plh.605.2017.09.19.15.33.05; Tue, 19 Sep 2017 15:33:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=WtnjFGrh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 S1751812AbdISWdE (ORCPT + 26 others); Tue, 19 Sep 2017 18:33:04 -0400 Received: from mail-pg0-f49.google.com ([74.125.83.49]:53639 "EHLO mail-pg0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751772AbdISWcs (ORCPT ); Tue, 19 Sep 2017 18:32:48 -0400 Received: by mail-pg0-f49.google.com with SMTP id j70so600702pgc.10 for ; Tue, 19 Sep 2017 15:32:48 -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=sb2NA7EgCbClj7J2sUSx8EN3Q8urKhCHn6JapG2gyY8=; b=WtnjFGrhVskn6VXY+YOPDxYWknU+Ft4Ku7twHa/6UfbLvLgMrUBdgC2fKQsGqXP4xb 9g564ut4+tE7ArdHE0ys4Owl8TACviYhcmY5xrdyMWlfxXv3amEZ9Pi2ERU1dOh48GQ5 Cszae7mvksJbAr8k6EvTDIIbpAEP2gpu3qKJE= 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=sb2NA7EgCbClj7J2sUSx8EN3Q8urKhCHn6JapG2gyY8=; b=YpXyzEjQb1vWQ71V0ScdsQk0k4lU02XaMaJeuAwR2AVqM//OzlZja8FCyQdKQpcvck JZvZIN63IZXEQodC1xj1bYAMWHdQSOe+gOnnA5FZ+8651NBsqxgzV3iNB2Rol6VQri5T 7LpDFy5czGEcctenKCrN/KyrZ/1MDEcJdj3mYhpGUzUqWtgZwRR/5qi8ACuQDWTrBt/9 UVZ3tQozwJK+FpalYga5NzoGY7927v2XrSWYr/irg4gZ8FV8G1nGjpa+wsoZ/ZTKThpt GNBUyONZIMUc5sQPpG19OPjzO8c6Va9zeeCjxld+E+vC7Y8XGythqYThyNQOicCjQpiU 7zDw== X-Gm-Message-State: AHPjjUgWmDQVWEmpB5CCt5w/tAExKAo4Wu66ANFQYEoOQjCn0bXLQpL5 lBXqMkluVtsdXjbEHbM7JqKynQ== X-Google-Smtp-Source: AOwi7QDOgS4Q/BGFLVCCAKrwUT6RO0joZepw/cyQtwKATx1q7maFzITBjoFiT2SWQx9cWe+00CqzGA== X-Received: by 10.98.70.221 with SMTP id o90mr107095pfi.277.1505860367999; Tue, 19 Sep 2017 15:32:47 -0700 (PDT) Received: from localhost (cpe-172-88-64-62.socal.res.rr.com. [172.88.64.62]) by smtp.gmail.com with ESMTPSA id r90sm5520345pfb.183.2017.09.19.15.32.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Sep 2017 15:32:47 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V10 7/7] remoteproc: qcom: q6v5: Vote for proxy powerdomain performance state Date: Tue, 19 Sep 2017 15:32:23 -0700 Message-Id: <50dd4d69098783bd844a55a321beaa94d216242d.1505859768.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rajendra Nayak THIS IS TEST CODE, SHOULDN'T BE MERGED. This patch just demonstrates the usage of pm_genpd_update_performance_state() api in cases where users need to set performance state of a powerdomain without having to do it via the OPP framework. q6v5 remoteproc driver needs to proxy vote for performance states of multiple powerdomains (but we currently only demonstate how it can be done for one powerdomain, as there is no way to associate multiple powerdomains to a device at this time) while it loads the firmware, and then releases the vote, once the firmware is up and can vote for itself. This is not a functional patch since rpmpd driver only supports msm8996 and there is no msm8996 support in the q6v5 remoteproc driver at this point in mainline. This patch is not tested as well. Not-signed-off-by: Rajendra Nayak Not-signed-off-by: Viresh Kumar --- drivers/remoteproc/qcom_q6v5_pil.c | 20 +++++++++++++------- drivers/soc/qcom/rpmpd.c | 5 +++++ 2 files changed, 18 insertions(+), 7 deletions(-) -- 2.7.4 diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c index 2d3d5ac92c06..dcb865b13c5c 100644 --- a/drivers/remoteproc/qcom_q6v5_pil.c +++ b/drivers/remoteproc/qcom_q6v5_pil.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,8 @@ struct q6v5 { void *mpss_region; size_t mpss_size; + bool has_perf_state; + struct qcom_rproc_subdev smd_subdev; struct qcom_rproc_ssr ssr_subdev; }; @@ -604,11 +607,12 @@ static int q6v5_start(struct rproc *rproc) struct q6v5 *qproc = (struct q6v5 *)rproc->priv; int ret; - ret = q6v5_regulator_enable(qproc, qproc->proxy_regs, - qproc->proxy_reg_count); - if (ret) { - dev_err(qproc->dev, "failed to enable proxy supplies\n"); - return ret; + if (qproc->has_perf_state) { + ret = dev_pm_genpd_update_performance_state(qproc->dev, INT_MAX); + if (ret) { + dev_err(qproc->dev, "Failed to set performance state.\n"); + return ret; + } } ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks, @@ -672,8 +676,8 @@ static int q6v5_start(struct rproc *rproc) q6v5_clk_disable(qproc->dev, qproc->proxy_clks, qproc->proxy_clk_count); - q6v5_regulator_disable(qproc, qproc->proxy_regs, - qproc->proxy_reg_count); + if (qproc->has_perf_state) + dev_pm_genpd_update_performance_state(qproc->dev, 0); return 0; @@ -1046,6 +1050,8 @@ static int q6v5_probe(struct platform_device *pdev) if (ret) goto free_rproc; + qproc->has_perf_state = pm_genpd_has_performance_state(&qproc->dev); + return 0; free_rproc: diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 4e4f5cda9ce2..c1733da8a7c8 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -145,6 +145,7 @@ enum msm8996_devices { UFS, PCIE, USB3, + Q6V5_PIL, }; static struct rpmpd_freq_map msm8996_rpmpd_freq_map[] = { @@ -171,6 +172,10 @@ static struct rpmpd_freq_map msm8996_rpmpd_freq_map[] = { .freq[LOW] = 120000000, .freq[NOMINAL] = 150000000, }, + [Q6V5_PIL] = { + .pd = &msm8996_vddcx, + .freq[HIGH] = INT_MAX, + }, }; static const struct of_device_id rpmpd_performance_table[] = {