From patchwork Wed Oct 11 07:24:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 115513 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp437820qgn; Wed, 11 Oct 2017 00:24:55 -0700 (PDT) X-Received: by 10.84.179.195 with SMTP id b61mr7101977plc.19.1507706695883; Wed, 11 Oct 2017 00:24:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507706695; cv=none; d=google.com; s=arc-20160816; b=z7ol8VMqhnxpmpgIoDqtDfRg3EmKgTSpCzrneeLo8yqvuFrzhVzL0bP0qe//SkbHgI AwNvOs5zuUPZKvdVhXFw972wBF29Jl4h9oMPfeQUfJg8JIFT41ilkWgxqTRq6iD+AEiH 6t9+4tMlkP9om1CYA103hQAR4AU4ydOfrF4vET52G53Tt1H9vCvBclgF6pf9eZ1yVp8R yw0j9cx3kJ4XIf4O19VrXpGmGpcPdWHJLJVxPCAZt7w4MWg8hx5AhxqkKZuX6Oaz3ztE 4FTjUYp0X/w+lNg5oKzTKVM+zjc2F0qnuBMVKHr5GBQVuOSLiLdCHwPRHMxjvPTwarmV 8Yag== 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=lMyUreTDTbPYt90cGCGGL2qUcAX2xEfepHl0DcxjOTQ=; b=zh3yKZoWAaNFll/7Xl5532ZeMuclJEcRXwD7hziTwj5Y8mx4qnZvlO5HaFC1QWMD4M +jf6FGBA6VtNG0JJ4hwUJE3wAY+cB6Rvru/vIIhSHOJsW25zFG9rh3fUpWoPFs+8SkoZ D+gxXOaJc/RD89DdNvYPUnOpd7rO6ser8ips5yfBkSz8WUcIFoRh0BL5v7MA2/z7jRLc OfDkuFtZ9gtEjQq9SWzbX6PIQz5FmHG1xtCTEXTyJmzR4T899V4VULi9DcIdxN8Ksheo aZQiAhSHOtA94F1R76rDJP7tpz8EgaSp+qjJK0AIE0bG27xYxYiPHO8RX+f/lrsoKHnp 9C0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QaEfc35W; 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 f124si9594938pgc.694.2017.10.11.00.24.55; Wed, 11 Oct 2017 00:24:55 -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=QaEfc35W; 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 S1756763AbdJKHYw (ORCPT + 12 others); Wed, 11 Oct 2017 03:24:52 -0400 Received: from mail-pg0-f46.google.com ([74.125.83.46]:55908 "EHLO mail-pg0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756679AbdJKHYu (ORCPT ); Wed, 11 Oct 2017 03:24:50 -0400 Received: by mail-pg0-f46.google.com with SMTP id b11so554382pgn.12 for ; Wed, 11 Oct 2017 00:24:50 -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=lMyUreTDTbPYt90cGCGGL2qUcAX2xEfepHl0DcxjOTQ=; b=QaEfc35WTZ0SEGmxUKT/wUS0f6t/+22+xyYB5mwNkVfx7tUv/9GJ8mRYkeMLAhjtam djrKYbqSe8vkLuSQRLE7VdJic3+QORltDeME3D3X7DDEsvbaavReWMgnp2exe+ZomgTm SFyzcU8qQFyFkEV6Xhbhc8AOeGMXFuBUrvOsI= 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=lMyUreTDTbPYt90cGCGGL2qUcAX2xEfepHl0DcxjOTQ=; b=NDRm6Oqm+4kk4J4vsaMKEbjxBPdVtqXwEDO+jYdfe0+SKKJJ/BBGI5pfGFSEuqJiHQ NY+UIRItsDzmwuQ+j2WDhVfRry+1miHEO0hwlSIsFHIToCHI+0RkYH9knkr06p+U0+pk kDrsciLzfXeCMJ+OKpXYTcU2K4aNWEpCSqH9GqNtHeDZlYLxx638+X+tFlh0rcJ393V6 mC0yO8AYFZrbEiHUdhuCc3b6P20HZ89XURWkt7ngJrnxjdWXaG7Ma3Q40G+4t1uaMp3V Bs+0CGZ7P/stYEdZOuYazbF8Y+otm4xWKIcw2GJKiy+BzRQvAkfB5K0y0U86R6xCnBX8 87rA== X-Gm-Message-State: AMCzsaU3EUyOcYhAzblDCJuaML4bL0cq96f5IbAAyN90tUPi8e9Uh3NM 2L650PNMSE+aMnu6UKHgEVfChw== X-Google-Smtp-Source: AOwi7QDSl+ycgtABfCkwCpFLJqk9PR3fpcPslTQrYdcVOS+blWy+X4g0juRfw6ZTypB182e/qZgm1A== X-Received: by 10.84.199.170 with SMTP id r39mr12519453pld.356.1507706689894; Wed, 11 Oct 2017 00:24:49 -0700 (PDT) Received: from localhost ([122.172.169.205]) by smtp.gmail.com with ESMTPSA id 62sm6290574pfw.129.2017.10.11.00.24.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 00:24:49 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , 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 V11 1/7] PM / Domains: Add support to select performance-state of domains Date: Wed, 11 Oct 2017 12:54:13 +0530 Message-Id: <431a7a5803b4a552dfe2a71700e19b904c6d16dc.1507703370.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.15.0.rc1.236.g92ea95045093 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 Some platforms have the capability to configure the performance state of PM domains. This patch enhances the genpd core to support such platforms. The performance levels (within the genpd core) are identified by positive integer values, a lower value represents lower performance state. This patch adds a new genpd API, which is called by user drivers (like OPP framework): - int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state); This updates the performance state constraint of the device on its PM domain. On success, the genpd will have its performance state set to a value which is >= "state" passed to this routine. The genpd core calls the genpd->genpd_set_performance_state() callback, if implemented, else -ENODEV is returned to the caller. The PM domain drivers need to implement the following callback if they want to support performance states. - int (*genpd_set_performance_state)(struct generic_pm_domain *genpd, unsigned int state); This is called internally by the genpd core on several occasions. The genpd core passes the genpd pointer and the aggregate of the performance states of the devices supported by that genpd to this callback. This callback must update the performance state of the genpd in a platform dependent way. The power domains can avoid supplying above callback, if they don't support setting performance-states. A TODO comment is also added to _genpd_reeval_performance_state(). This feature will be required once we have hardware that needs to propagate the performance state changes to master domains. Tested-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 179 +++++++++++++++++++++++++++++++++++++++++++- include/linux/pm_domain.h | 13 ++++ 2 files changed, 190 insertions(+), 2 deletions(-) -- 2.7.4 Acked-by: Ulf Hansson diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index a6e4c8d7d837..b8360bc6a8eb 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -237,6 +237,169 @@ static void genpd_update_accounting(struct generic_pm_domain *genpd) static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {} #endif +/* Returns negative errors or 0 on success */ +static int _genpd_set_performance_state(struct generic_pm_domain *genpd, + int state) +{ + int ret; + + ret = genpd->genpd_set_performance_state(genpd, state); + if (!ret) + genpd->performance_state = state; + + return ret; +} + +/* + * Re-evaluate performance state of a genpd. Finds the highest requested + * performance state by the devices within the genpd and then change genpd's + * performance state (if required). + * + * @genpd: PM domain whose state needs to be reevaluated. + * @state: Newly requested performance state of the device for which this + * routine is called. + * + * Returns negative errors or 0 on success. + */ +static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd, + int state) +{ + struct generic_pm_domain_data *pd_data; + struct pm_domain_data *pdd; + + /* 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; + } + + /* + * TODO: Traverse all subdomains of the genpd. This will be + * required once we have hardware that needs to propagate the + * performance state changes. + */ + +update_state: + return _genpd_set_performance_state(genpd, state); +} + +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_set_performance_state- Set performance state of device's power + * domain. + * + * @dev: Device for which the performance-state needs to be adjusted. + * @state: Target performance state of the device. 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). + * + * 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_set_performance_state(struct device *dev, unsigned int state) +{ + struct generic_pm_domain *genpd; + int ret; + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -ENODEV; + + genpd_lock(genpd); + + if (!genpd->genpd_set_performance_state) { + ret = -ENODEV; + goto unlock; + } + + if (!genpd_status_on(genpd)) { + ret = -EBUSY; + goto unlock; + } + + ret = _genpd_reeval_performance_state(genpd, state); + if (!ret) { + /* + * Since we are passing "state" as well to + * _genpd_reeval_performance_state(), 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_set_performance_state); + +static int _genpd_on_update_performance_state(struct generic_pm_domain *genpd) +{ + int ret, prev = genpd->prev_performance_state; + + if (likely(!prev)) + return 0; + + ret = _genpd_set_performance_state(genpd, prev); + 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 ret, state = genpd->performance_state; + + if (likely(!state)) + return; + + ret = _genpd_set_performance_state(genpd, 0); + 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 +551,8 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, return ret; } + _genpd_off_update_performance_state(genpd); + genpd->status = GPD_STATE_POWER_OFF; genpd_update_accounting(genpd); @@ -437,15 +602,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); 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); err: list_for_each_entry_continue_reverse(link, &genpd->slave_links, @@ -803,6 +974,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); + genpd->status = GPD_STATE_POWER_OFF; list_for_each_entry(link, &genpd->slave_links, slave_node) { @@ -848,7 +1021,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)) + if (_genpd_power_on(genpd, false)) + _genpd_off_update_performance_state(genpd); genpd->status = GPD_STATE_ACTIVE; } diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 84f423d5633e..81d923f058fd 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -64,8 +64,12 @@ 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 (*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; @@ -121,6 +125,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 +153,8 @@ 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 int dev_pm_genpd_set_performance_state(struct device *dev, + unsigned int state); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; @@ -188,6 +195,12 @@ static inline int pm_genpd_remove(struct generic_pm_domain *genpd) return -ENOTSUPP; } +static inline int dev_pm_genpd_set_performance_state(struct device *dev, + unsigned int state) +{ + 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 Wed Oct 11 07:24:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 115514 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp437894qgn; Wed, 11 Oct 2017 00:25:01 -0700 (PDT) X-Received: by 10.98.16.81 with SMTP id y78mr15511295pfi.114.1507706701099; Wed, 11 Oct 2017 00:25:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507706701; cv=none; d=google.com; s=arc-20160816; b=xrLIGamJsADdAM2cTjPi20GEvHDL3nXG3kOlOdUd+dthOshT/nmOSh74bBGwSNg3bb LV3hXIwmIGfi1Ywul8fo+t42CLCpkRSNzZfk/9vZt+81dPTnP6yKHQsB/ns6GOrEe0kD NtF4rt/iRLpx6DiiwK35sQ5jm1bYz6MZau9BbjgEZSvTPz6Huq6aDWbmZ5Y6WIII4V2X baaW+tXseGueP5gDapAb7aPgyzx81hhHaY+kYsSudmNumBDJDnkf+0RSoivtoICr+4G+ hGOGUAwarA4tnlEczRhinm8LqnLimKxlrWHR9xi/dZSvUcltb6LTuEToutxCy4V5GDXa EZLg== 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=+EvDB4S+S/4HK7dx6TlIznzXvikzDBuTdFNyAbtvn9o=; b=nM3hj8yVHnwaYERtP6d/2WOLjm9tKgY65Y3vbVCNMWoAtxTU27t6k71cdFc/7UAx3A bVWp5Iu8CixlKJl5EqpRsaftF3EzplFOUPlRej7J5VpLQ8XxmIFAma6KCnmUYyUEziPR qw823YiO9XrF/t8bzADn2/E/61KR26Qk8v8veP2gAtHv4rPMSj9zGoT2RgKxrXL8N8gk oljGQkc39Q3AuVjmQQ7B4HLvYuGGWgfJ8dJbpqSKlQpdQBBZ1eajGiRYcoMWQb7FNzqq UCljKRIyJ8kVc6kj+Vdl8TUmxx5LSXX9UlDRmk1zI8AkkSe0j//V8GcFwPcwszdk/UyA ah3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JMCHrRET; 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 o82si4750361pfj.249.2017.10.11.00.25.00; Wed, 11 Oct 2017 00:25:01 -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=JMCHrRET; 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 S1757043AbdJKHY6 (ORCPT + 12 others); Wed, 11 Oct 2017 03:24:58 -0400 Received: from mail-pg0-f45.google.com ([74.125.83.45]:55914 "EHLO mail-pg0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756638AbdJKHYz (ORCPT ); Wed, 11 Oct 2017 03:24:55 -0400 Received: by mail-pg0-f45.google.com with SMTP id b11so554486pgn.12 for ; Wed, 11 Oct 2017 00:24:55 -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=+EvDB4S+S/4HK7dx6TlIznzXvikzDBuTdFNyAbtvn9o=; b=JMCHrRETAQS+dmrX1zfmtFLqgBdmAMdVQy5wai0tntyMUWjd57Mv+ByB9YxwEqTkto QGOganD+a+BOUjtwO0kw8/riAvwrCHi8Ppk/C6Xj/yrRWGr0+yzaBn+d4PQavWGkBS1+ vn33QC4cNJ5AY8yXIEDjDUwXioHYCCyJa2ocE= 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=+EvDB4S+S/4HK7dx6TlIznzXvikzDBuTdFNyAbtvn9o=; b=Vcd8xrity36ZLWc+Oh5HVhOzLE+DhQcypTSW+9aHcJPXi59kM5jD0MTlaVYXS4fzNA XBIAQRW75y6di6wxJd0yDmCtx8QCD/H/25KjvPyxzK63Z4uOxdO2DvQ7dwv9lIOuFpvZ XNYqKJzc0vcXne9/VQld+1jQBpuzt5LdfvI9vOpF0Q/Og9bwYMkcJAjp/Yy4ELiD6xwO 9BpRARHPngIgdW33Lg1KhYyygSoP4XzFvQIzoy4creJaqFDhXFUby/QcM8rD2k7BpXYp LM1PVMlokC5hDVMY9JU3uxu27msA+r8SKUEWCRh72lnsSJJafxl8MsPHSJ+ulgPVru3A WzgA== X-Gm-Message-State: AMCzsaWMHcQTvRVm32kM2WIFykUu+pPwwYSs5MjVz/J6PC77HeA9hraI VPf6XF0vu5IEZqVtg+qEF0omQg== X-Google-Smtp-Source: AOwi7QDCdgITpuJCR+Vne2DbvDw8Whc0GyvahoSXLTl26qVG0v6oJZCpRNZ+f/eusROp8n//vWAVtA== X-Received: by 10.84.129.229 with SMTP id b92mr14936598plb.362.1507706695157; Wed, 11 Oct 2017 00:24:55 -0700 (PDT) Received: from localhost ([122.172.169.205]) by smtp.gmail.com with ESMTPSA id 66sm21082623pgh.31.2017.10.11.00.24.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 00:24:54 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , 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 V11 3/7] OPP: Add dev_pm_opp_{un}register_get_pstate_helper() Date: Wed, 11 Oct 2017 12:54:15 +0530 Message-Id: <0e5c4f9e8c51ac8b1226932dbcb30e31610a3ed3.1507703370.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.15.0.rc1.236.g92ea95045093 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 This adds the dev_pm_opp_{un}register_get_pstate_helper() helper routines which will be used to set the get_pstate() callback for a device. This callback will be later called internally by the OPP core to get performance state corresponding to an OPP. This is required temporarily until the time we have proper DT bindings to include the performance state information. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/opp/opp.h | 2 ++ include/linux/pm_opp.h | 10 +++++++ 3 files changed, 90 insertions(+) -- 2.7.4 diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 0ce8069d6843..92fa94a6dcc1 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1036,6 +1036,9 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, return ret; } + if (opp_table->get_pstate) + new_opp->pstate = opp_table->get_pstate(dev, new_opp->rate); + list_add(&new_opp->node, head); mutex_unlock(&opp_table->lock); @@ -1548,6 +1551,81 @@ void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper); /** + * dev_pm_opp_register_get_pstate_helper() - Register get_pstate() helper. + * @dev: Device for which the helper is getting registered. + * @get_pstate: Helper. + * + * TODO: Remove this callback after the same information is available via Device + * Tree. + * + * This allows a platform to initialize the performance states of individual + * OPPs for its devices, until we get similar information directly from DT. + * + * This must be called before the OPPs are initialized for the device. + */ +struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev, + int (*get_pstate)(struct device *dev, unsigned long rate)) +{ + struct opp_table *opp_table; + int ret; + + if (!get_pstate) + return ERR_PTR(-EINVAL); + + opp_table = dev_pm_opp_get_opp_table(dev); + if (!opp_table) + return ERR_PTR(-ENOMEM); + + /* This should be called before OPPs are initialized */ + if (WARN_ON(!list_empty(&opp_table->opp_list))) { + ret = -EBUSY; + goto err; + } + + /* Already have genpd_performance_state set */ + if (WARN_ON(opp_table->genpd_performance_state)) { + ret = -EBUSY; + goto err; + } + + opp_table->genpd_performance_state = true; + opp_table->get_pstate = get_pstate; + + return opp_table; + +err: + dev_pm_opp_put_opp_table(opp_table); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(dev_pm_opp_register_get_pstate_helper); + +/** + * dev_pm_opp_unregister_get_pstate_helper() - Releases resources blocked for + * get_pstate() helper + * @opp_table: OPP table returned from dev_pm_opp_register_get_pstate_helper(). + * + * Release resources blocked for platform specific get_pstate() helper. + */ +void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table) +{ + if (!opp_table->genpd_performance_state) { + pr_err("%s: Doesn't have performance states set\n", + __func__); + return; + } + + /* Make sure there are no concurrent readers while updating opp_table */ + WARN_ON(!list_empty(&opp_table->opp_list)); + + opp_table->genpd_performance_state = false; + opp_table->get_pstate = NULL; + + dev_pm_opp_put_opp_table(opp_table); +} +EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_get_pstate_helper); + +/** * dev_pm_opp_add() - Add an OPP table from a table definitions * @dev: device for which we do this operation * @freq: Frequency in Hz for this OPP diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index e8f767ab5814..4d00061648a3 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -140,6 +140,7 @@ enum opp_table_access { * @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 + * @get_pstate: Platform specific get_pstate callback * @dentry: debugfs dentry pointer of the real device directory (not links). * @dentry_name: Name of the real dentry. * @@ -177,6 +178,7 @@ struct opp_table { int (*set_opp)(struct dev_pm_set_opp_data *data); struct dev_pm_set_opp_data *set_opp_data; + int (*get_pstate)(struct device *dev, unsigned long rate); #ifdef CONFIG_DEBUG_FS struct dentry *dentry; diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 849d21dc4ca7..6c2d2e88f066 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -125,6 +125,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name); void dev_pm_opp_put_clkname(struct opp_table *opp_table); struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); +struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev, int (*get_pstate)(struct device *dev, unsigned long rate)); +void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table); int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); @@ -245,6 +247,14 @@ static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {} +static inline struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev, + int (*get_pstate)(struct device *dev, unsigned long rate)) +{ + return ERR_PTR(-ENOTSUPP); +} + +static inline void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table) {} + static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name) { return ERR_PTR(-ENOTSUPP); From patchwork Wed Oct 11 07:24:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 115518 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp438654qgn; Wed, 11 Oct 2017 00:26:10 -0700 (PDT) X-Received: by 10.99.100.70 with SMTP id y67mr14673307pgb.161.1507706770275; Wed, 11 Oct 2017 00:26:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507706770; cv=none; d=google.com; s=arc-20160816; b=C08U9pA9YpssW29hn/F+vcndX19tTOkV1LZu9PNmwm54cNazhpnXx0/1H4IYyr6RMi v9GLTbIloRUmrzFJmpyJEqknLwQEgOY0k1FTIU2n4qsGGB0aI8WRWHZK8tVJKS+p0p7j svi/KoIDja16Vyh5SsTCcZJ/wWkKpY87SJUY4Im5G73HLulVs2gpZqHEE9f/eipmtefo JPWjg6BiMBwAP61D37oiNMqc0e7+xGE3AHJn0Oc93NOCjRHZDtfL6whl0mWDPbX7YFyD eYXBtKduFAQO7+chElQefmxyfu/moT0eusYXU+w65yM8S+1btLqrqZTsg437TDij3rg/ ezkQ== 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=fYuCyIeG/EsPqN7nwQg6LhoVny+f3iBsz7/KCUqKBWs=; b=cGh9NPevHWNdn7E2j6Qil7ZOznJ6czxMrkl2xdZizmzl6k1mJUuUZLfo+9LPS1bseo 5GSGHjBl3ckt/xqUVlS/Srhu0eeSmBWq2e7oUJdDY5D9yzDVZgv5MNtuS752dd7szETR vKwrQkQeVC4vd6u0YRfXKhm2ELPKktaniqlJyaFtz9Sdesvq5xHYwTOseezRhmsbRdVn +L0F5EUDillyfECYb/L0EsokDSTmgDas63ZxC8f0XX2HrwW0WWZpuSpj4t5d2/wPwHwt qGe/B9+oQfwv3RSlzd5H2pu3MDUxseFeqANYNgTi+6TT1xTp60zBcOFF89WNzJZFmlGo xwvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QCiKUqGL; 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 d128si9735969pgc.0.2017.10.11.00.26.10; Wed, 11 Oct 2017 00:26:10 -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=QCiKUqGL; 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 S1757278AbdJKH0I (ORCPT + 12 others); Wed, 11 Oct 2017 03:26:08 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:43562 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757036AbdJKHY6 (ORCPT ); Wed, 11 Oct 2017 03:24:58 -0400 Received: by mail-pf0-f181.google.com with SMTP id a8so238462pfc.0 for ; Wed, 11 Oct 2017 00:24:58 -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=fYuCyIeG/EsPqN7nwQg6LhoVny+f3iBsz7/KCUqKBWs=; b=QCiKUqGLvkYNB2aXPD1r0jE7PRb7d2eMA+wasdb36mqGFgphZZaT16Ho39Rw1crI7C AJ81V2xsB/YWUL0bBAVeqAMTL6LuoGxNKwJeRsuoOk3bFc43QdUy8bMMU6ENXfGz3eYo DLk1K90rG70hkLRMlC9PF5TRZTB5TH2XHb0PY= 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=fYuCyIeG/EsPqN7nwQg6LhoVny+f3iBsz7/KCUqKBWs=; b=RdvxNx9BiE6nJzqoAfcGrmIR2Fr6bb88QrBnsfJHim50j54M3XN741ASCagTD464ci 8oYxLGjMytmyd5mnmmJQEVrIBX8JmLtSREigolvPcj3XxOmDUu39OtzSls0pNbhK2PEe ZtH9iRtt02Yoye7dMqsGl1PAK5SHgWFDy8mjymfwRU7iUhghts4CdsQTGb3TU2LfvsRx 48JEyzqCWo9lcLqa/w+nCaOkODeO9k70I4oU8AGn+5SUWIWxcquOlQ6IzHVkjHf+hEez JRBHT5ab/fl12c/JpLjz3nfd7LJV9V6A1dMggWD3rgXwfY+x6eujjwqIaJf9vUvaMMZO db5Q== X-Gm-Message-State: AMCzsaVRcDWJYZdNF6Qw/Ao0thFl6obFRhoGTubdN8KLf+gSc0QEgNwC +nctB00yNcfzbGLU4SI9u8vdHw== X-Google-Smtp-Source: AOwi7QBfigL4l+r9nMw2JB7+vmGYsRNRPxG29Uu2kbpHM6pS8IVa0D3rz2FqQ0SsFYuEwmQgzawT7g== X-Received: by 10.98.95.1 with SMTP id t1mr15726903pfb.217.1507706697782; Wed, 11 Oct 2017 00:24:57 -0700 (PDT) Received: from localhost ([122.172.169.205]) by smtp.gmail.com with ESMTPSA id c22sm7472797pfe.177.2017.10.11.00.24.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 00:24:57 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , 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 V11 4/7] soc: qcom: rpmpd: Add driver to model cx/mx power domains Date: Wed, 11 Oct 2017 12:54:16 +0530 Message-Id: X-Mailer: git-send-email 2.15.0.rc1.236.g92ea95045093 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: Rajendra Nayak NOT FOR MERGE. The cx/mx power domains just pass the performance state set by the consumers to the RPM (Remote Power manager) which then takes care of setting the appropriate voltage on the corresponding rails to meet the performance needs. Add data for all power domains on msm8996. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- .../devicetree/bindings/power/qcom,rpmpd.txt | 9 + arch/arm64/boot/dts/qcom/msm8996.dtsi | 5 + drivers/soc/qcom/Kconfig | 9 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/rpmpd.c | 307 +++++++++++++++++++++ 5 files changed, 331 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmpd.txt create mode 100644 drivers/soc/qcom/rpmpd.c -- 2.7.4 diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.txt b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt new file mode 100644 index 000000000000..1b8b3b849e47 --- /dev/null +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt @@ -0,0 +1,9 @@ +Qualcomm RPM Power domains + +* For RPM power domains, we communicate a performance state to RPM +which then translates it into a corresponding voltage on a rail. + +Required Properties: + - compatible: Should be one of the following: + * qcom,rpmpd-msm8996: RPM Powerdomain for the msm8996 family of SoC. + - power-domain-cells: number of cells in power domain specifier must be 1. diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 887b61c872dd..0be1db559d61 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -496,6 +496,11 @@ status = "disabled"; }; + rpmpd: qcom,rpmpd { + compatible = "qcom,rpmpd-msm8996", "qcom,rpmpd"; + #power-domain-cells = <1>; + }; + sdhc2: sdhci@74a4900 { status = "disabled"; compatible = "qcom,sdhci-msm-v4"; diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index b00bccddcd3b..48bc7c358dd7 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -35,6 +35,15 @@ config QCOM_PM modes. It interface with various system drivers to put the cores in low power modes. +config QCOM_RPMPD + tristate "Qualcomm RPM Power domain driver" + depends on MFD_QCOM_RPM && QCOM_SMD_RPM + help + QCOM RPM power domain driver to support power domain with + performance states. The driver communicates a performance state + value to RPM which then translates it into corresponding voltage + for the voltage rail. + config QCOM_SMEM tristate "Qualcomm Shared Memory Manager (SMEM)" depends on ARCH_QCOM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index f151de41eb93..3fa9af1e2c93 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o obj-$(CONFIG_QCOM_SMP2P) += smp2p.o obj-$(CONFIG_QCOM_SMSM) += smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o +obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c new file mode 100644 index 000000000000..0958d7693c4f --- /dev/null +++ b/drivers/soc/qcom/rpmpd.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define domain_to_rpmpd(domain) container_of(domain, struct rpmpd, pd) + +/* Resource types */ +#define RPMPD_SMPA 0x61706d73 +#define RPMPD_LDOA 0x616f646c + +/* Operation Keys */ +#define KEY_CORNER 0x6e726f63 /* corn */ +#define KEY_ENABLE 0x6e657773 /* swen */ +#define KEY_FLOOR_CORNER 0x636676 /* vfc */ + +#define DEFINE_RPMPD_CORN_SMPA(_platform, _name, _active, r_id) \ + static struct rpmpd _platform##_##_active; \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .peer = &_platform##_##_active, \ + .res_type = RPMPD_SMPA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + }; \ + static struct rpmpd _platform##_##_active = { \ + .pd = { .name = #_active, }, \ + .peer = &_platform##_##_name, \ + .active_only = true, \ + .res_type = RPMPD_SMPA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + } + +#define DEFINE_RPMPD_CORN_LDOA(_platform, _name, r_id) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = RPMPD_LDOA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + } + +#define DEFINE_RPMPD_VFC(_platform, _name, r_id, r_type) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = r_type, \ + .res_id = r_id, \ + .key = KEY_FLOOR_CORNER, \ + } + +#define DEFINE_RPMPD_VFC_SMPA(_platform, _name, r_id) \ + DEFINE_RPMPD_VFC(_platform, _name, r_id, RPMPD_SMPA) + +#define DEFINE_RPMPD_VFC_LDOA(_platform, _name, r_id) \ + DEFINE_RPMPD_VFC(_platform, _name, r_id, RPMPD_LDOA) + +struct rpmpd_req { + __le32 key; + __le32 nbytes; + __le32 value; +}; + +struct rpmpd { + struct generic_pm_domain pd; + struct rpmpd *peer; + const bool active_only; + unsigned long corner; + bool enabled; + const char *res_name; + const int res_type; + const int res_id; + struct qcom_smd_rpm *rpm; + __le32 key; +}; + +struct rpmpd_desc { + struct rpmpd **rpmpds; + size_t num_pds; +}; + +static DEFINE_MUTEX(rpmpd_lock); + +/* msm8996 RPM powerdomains */ +DEFINE_RPMPD_CORN_SMPA(msm8996, vddcx, vddcx_ao, 1); +DEFINE_RPMPD_CORN_SMPA(msm8996, vddmx, vddmx_ao, 2); +DEFINE_RPMPD_CORN_LDOA(msm8996, vddsscx, 26); + +DEFINE_RPMPD_VFC_SMPA(msm8996, vddcx_vfc, 1); +DEFINE_RPMPD_VFC_LDOA(msm8996, vddsscx_vfc, 26); + +static struct rpmpd *msm8996_rpmpds[] = { + [0] = &msm8996_vddcx, + [1] = &msm8996_vddcx_ao, + [2] = &msm8996_vddcx_vfc, + [3] = &msm8996_vddmx, + [4] = &msm8996_vddmx_ao, + [5] = &msm8996_vddsscx, + [6] = &msm8996_vddsscx_vfc, +}; + +static const struct rpmpd_desc msm8996_desc = { + .rpmpds = msm8996_rpmpds, + .num_pds = ARRAY_SIZE(msm8996_rpmpds), +}; + +static const struct of_device_id rpmpd_match_table[] = { + { .compatible = "qcom,rpmpd-msm8996", .data = &msm8996_desc }, + { } +}; +MODULE_DEVICE_TABLE(of, rpmpd_match_table); + +static int rpmpd_send_enable(struct rpmpd *pd, bool enable) +{ + struct rpmpd_req req = { + .key = KEY_ENABLE, + .nbytes = cpu_to_le32(sizeof(u32)), + .value = cpu_to_le32(enable), + }; + + return qcom_rpm_smd_write(pd->rpm, QCOM_RPM_ACTIVE_STATE, pd->res_type, + pd->res_id, &req, sizeof(req)); +} + +static int rpmpd_send_corner(struct rpmpd *pd, int state, unsigned int corner) +{ + struct rpmpd_req req = { + .key = pd->key, + .nbytes = cpu_to_le32(sizeof(u32)), + .value = cpu_to_le32(corner), + }; + + return qcom_rpm_smd_write(pd->rpm, state, pd->res_type, pd->res_id, + &req, sizeof(req)); +}; + +static void to_active_sleep(struct rpmpd *pd, unsigned long corner, + unsigned long *active, unsigned long *sleep) +{ + *active = corner; + + if (pd->active_only) + *sleep = 0; + else + *sleep = *active; +} + +static int rpmpd_aggregate_corner(struct rpmpd *pd) +{ + int ret; + struct rpmpd *peer = pd->peer; + unsigned long active_corner, sleep_corner; + unsigned long this_corner = 0, this_sleep_corner = 0; + unsigned long peer_corner = 0, peer_sleep_corner = 0; + + to_active_sleep(pd, pd->corner, &this_corner, &this_sleep_corner); + + if (peer && peer->enabled) + to_active_sleep(peer, peer->corner, &peer_corner, + &peer_sleep_corner); + + active_corner = max(this_corner, peer_corner); + + ret = rpmpd_send_corner(pd, QCOM_RPM_ACTIVE_STATE, active_corner); + if (ret) + return ret; + + sleep_corner = max(this_sleep_corner, peer_sleep_corner); + + return rpmpd_send_corner(pd, QCOM_RPM_SLEEP_STATE, sleep_corner); +} + +static int rpmpd_power_on(struct generic_pm_domain *domain) +{ + int ret; + struct rpmpd *pd = domain_to_rpmpd(domain); + + mutex_lock(&rpmpd_lock); + + ret = rpmpd_send_enable(pd, true); + if (ret) + goto out; + + pd->enabled = true; + + if (pd->corner) + ret = rpmpd_aggregate_corner(pd); + +out: + mutex_unlock(&rpmpd_lock); + + return ret; +} + +static int rpmpd_power_off(struct generic_pm_domain *domain) +{ + int ret; + struct rpmpd *pd = domain_to_rpmpd(domain); + + mutex_lock(&rpmpd_lock); + + ret = rpmpd_send_enable(pd, false); + if (!ret) + pd->enabled = false; + + mutex_unlock(&rpmpd_lock); + + return ret; +} + +static int rpmpd_probe(struct platform_device *pdev) +{ + int i; + size_t num; + struct genpd_onecell_data *data; + struct qcom_smd_rpm *rpm; + struct rpmpd **rpmpds; + const struct rpmpd_desc *desc; + + rpm = dev_get_drvdata(pdev->dev.parent); + if (!rpm) { + dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n"); + return -ENODEV; + } + + desc = of_device_get_match_data(&pdev->dev); + if (!desc) + return -EINVAL; + + rpmpds = desc->rpmpds; + num = desc->num_pds; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->domains = devm_kcalloc(&pdev->dev, num, sizeof(*data->domains), + GFP_KERNEL); + data->num_domains = num; + + for (i = 0; i < num; i++) { + if (!rpmpds[i]) + continue; + + rpmpds[i]->rpm = rpm; + rpmpds[i]->pd.power_off = rpmpd_power_off; + rpmpds[i]->pd.power_on = rpmpd_power_on; + pm_genpd_init(&rpmpds[i]->pd, NULL, true); + + data->domains[i] = &rpmpds[i]->pd; + } + + return of_genpd_add_provider_onecell(pdev->dev.of_node, data); +} + +static int rpmpd_remove(struct platform_device *pdev) +{ + of_genpd_del_provider(pdev->dev.of_node); + return 0; +} + +static struct platform_driver rpmpd_driver = { + .driver = { + .name = "qcom-rpmpd", + .of_match_table = rpmpd_match_table, + }, + .probe = rpmpd_probe, + .remove = rpmpd_remove, +}; + +static int __init rpmpd_init(void) +{ + return platform_driver_register(&rpmpd_driver); +} +core_initcall(rpmpd_init); + +static void __exit rpmpd_exit(void) +{ + platform_driver_unregister(&rpmpd_driver); +} +module_exit(rpmpd_exit); + +MODULE_DESCRIPTION("Qualcomm RPM Power Domain Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:qcom-rpmpd"); From patchwork Wed Oct 11 07:24: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: 115517 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp438427qgn; Wed, 11 Oct 2017 00:25:50 -0700 (PDT) X-Received: by 10.101.70.76 with SMTP id k12mr14674686pgr.19.1507706750295; Wed, 11 Oct 2017 00:25:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507706750; cv=none; d=google.com; s=arc-20160816; b=UyNZS+kplTOnE69McAwLntptsO2mL3aEB5g7Lu1TnuPdWxJ01c1lT5wb96tXIh9Cuy jsCFDbLk+SjPshha1OXNc2J/4D1KwboUSCR3K6xgA9k7ZYzPaerWOWgq/k56kpuDhzrE hJcL0+FfyYTniJZ6lPo+cC3I9+eJrDjpD+MfhN0DqSsr9JC7+1AiI2E43KhvBaZ+rsWK nNjDrvFsOeWwpAmanarBI3jVR1VZ6GRjW2xMhFI92Kj6EkJcW8eyNVQSjh7iOwJzxmhF p7geH+s58AzMRoPBhZPbRcv2fNvw4g7E/AWnv11sl6NBsPVaD5916gfU91DevFqMKEff VrIA== 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=Hdt5aCKJmcsbnAos6SAKj3IrMUdKUHergXtUJ6NC99s=; b=DjOBigmOA5kLAEw2u+suTpdL7yEuX3nfBxcyQTnwglFmEj667J56gZbrs5KLgvdnZq aKFy7ul83rmslIfroqsfHQmTthZe5LOk6PwE7hJXM5lEIazN8dtqw4BQwpSM6u3PgiVN FORSdSYzM2yPORrohaxeP1upqiRTa0y1NAQTJXK1dB7+GDXk1Rs+SCus5Lk9dOKh6rt0 2eP6oINWfXJo20V/lzz21rUPsEUFZYLurHdNhMAtCU7fvQM1+VCDAUAnDHNqcLuPNXTm 3RFIzPhWmsDtqzOD1b11kzaSICRX6STpgkQ6m2ho1OCiRLysiYgH5hLoawDq5/PQ1tNt oRxg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=W/X7qlLe; 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 y9si11066262pli.234.2017.10.11.00.25.50; Wed, 11 Oct 2017 00:25:50 -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=W/X7qlLe; 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 S1757272AbdJKHZs (ORCPT + 12 others); Wed, 11 Oct 2017 03:25:48 -0400 Received: from mail-pg0-f52.google.com ([74.125.83.52]:44147 "EHLO mail-pg0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757076AbdJKHZB (ORCPT ); Wed, 11 Oct 2017 03:25:01 -0400 Received: by mail-pg0-f52.google.com with SMTP id j3so553747pga.1 for ; Wed, 11 Oct 2017 00:25:00 -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=Hdt5aCKJmcsbnAos6SAKj3IrMUdKUHergXtUJ6NC99s=; b=W/X7qlLej8TJPaza4tKeXcgeljfRfwnf7GdYYLC7Zc4YpBDrX217rp5s0sjGe0SUD3 So3SWHw/6XwfHbQ3W+QJ2Lox0oL6289GPv/FuhNaSjBM/xHnBOMiKONJ37ScoQskpuyL 1wHKmbRLeWDKoi7GNyXcAWnUkMU+Wrr2QEEfo= 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=Hdt5aCKJmcsbnAos6SAKj3IrMUdKUHergXtUJ6NC99s=; b=lwbRa9tEYK4tJJyqHACDs7OBDgfNKpt76Gk4GJ+jb/Ll0A1PJC3Usv6eLM5JzMjunX rz7dvQVSExVIbvg4gqAY3YDgW0ztLLT0cWwh3I42fjyXIAekR7HO49ujHpIRrAELg5Zh 64L9slfOK+vNfPhnKUH1unTGwPsepFv7VPgyYZPehgAu97T7Z/x2jUN/jt31HCaKRlYr Xzhuaw751RyxV4tuuVo8SQjR0ar0SEjxvOwuyHOFr4IayP+osZjUtsiZyLdy6iYSEe1U 3L8NlMBGM02hz6V6yMaLGFa9axLFD4/N6b5jvoIaSRWGWN4QO2WYv7Yo40tK3ke0cI2J /quA== X-Gm-Message-State: AMCzsaXhNukwDvQ8i0caX7s5egNiYwUNWTqRs7WZvAWqr2oVEuIrEZFm V6giol5dYrtcQs7cmHSbM3iNPQ== X-Google-Smtp-Source: AOwi7QCUbdC4HqGqaeBVzVeExt5aOhc0KrnrbBqu2yE1d1ryrTGkxzva6XOy+mVJA3TRH2jg8TvKtQ== X-Received: by 10.98.53.1 with SMTP id c1mr99266pfa.248.1507706700323; Wed, 11 Oct 2017 00:25:00 -0700 (PDT) Received: from localhost ([122.172.169.205]) by smtp.gmail.com with ESMTPSA id n27sm23664402pfi.11.2017.10.11.00.24.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 00:24:59 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , 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 V11 5/7] soc: qcom: rpmpd: Add support for set performance state Date: Wed, 11 Oct 2017 12:54:17 +0530 Message-Id: <5122d00c2f3c0ba076fd7879a4cc397183ccfab2.1507703370.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.15.0.rc1.236.g92ea95045093 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: Rajendra Nayak NOT FOR MERGE. With genpd now expecting power domain drivers supporting performance state to support set performance state callbacks, add support for it in the rpmpd driver. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/soc/qcom/rpmpd.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) -- 2.7.4 diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 0958d7693c4f..34d2eb4e75bf 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -230,6 +230,28 @@ 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_probe(struct platform_device *pdev) { int i; @@ -267,6 +289,7 @@ 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; pm_genpd_init(&rpmpds[i]->pd, NULL, true); data->domains[i] = &rpmpds[i]->pd; From patchwork Wed Oct 11 07:24: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: 115516 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp438024qgn; Wed, 11 Oct 2017 00:25:12 -0700 (PDT) X-Received: by 10.98.149.71 with SMTP id p68mr15606875pfd.311.1507706712052; Wed, 11 Oct 2017 00:25:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507706712; cv=none; d=google.com; s=arc-20160816; b=cTFCaZzy2xRL/1R1UIWCjwxS70dTIEtWjKmO2sIs7mMVL7DebGKfaL6shDzS+QrKqg Q8OCtKMbL9Xckh8al+jlxfB6yxBDA4UuuVZSVfnH3rXYacIID/fEQvzR64t3Fh1zZr0f z3pU9nCcaNMInkhzd8ziQfFMGhcQ6cZNKG2Ckvm/wethfJ+KaUUzurKY9BgcUxEZFT7G 1GlofrAjpfBTo1lzlzket0aOrY7OBMb7p7dRbmD+LuxBSWnMPO914/6ryE7m9fZglsb/ e0uGaZ4pH7AVq4sUlxwUFgrsCtvhn8+6qj4u2W9+233ubf7O0Jwz0cqj5TZYTfPrc4Wn jBHg== 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=6UTvsNuKNJke67K2/BEw7Efrt6XPwSnvLvYOXizjmxM=; b=bj4YhLsxWkKVbAsew9acV/uujJE0COf6pU4nZY3Oi3r96qeOKC1GWD90/u6rBoO+nA bXiXP69JUKtcmdNzLMaxqS3CP5PPOcz8qn855bUW/Sz6RXCGxZJRomyDia8UgNVYG16t LXoIkkMuto5Y2a8p0xBkoo1lvFQZZgTUp4wmTSNMXw8Vbg1lir8XWxWSnUt8n3A75SDI V/I97jys8DJIgqKWpJguHOsmQAbXhSBVi7NcNSqvPX/timBIH7fCooejVPzihH7dW8yk 89tvt3C51syfr/x9tFyiDvopZYPtdKdGN1GE2zZ2NqyGfoIAO9Cmnt3XTX+jwVAyLgL+ LGVg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KA1RwsWo; 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 x3si10400989plb.636.2017.10.11.00.25.11; Wed, 11 Oct 2017 00:25:12 -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=KA1RwsWo; 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 S1756733AbdJKHZJ (ORCPT + 12 others); Wed, 11 Oct 2017 03:25:09 -0400 Received: from mail-pf0-f175.google.com ([209.85.192.175]:54539 "EHLO mail-pf0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757125AbdJKHZG (ORCPT ); Wed, 11 Oct 2017 03:25:06 -0400 Received: by mail-pf0-f175.google.com with SMTP id m28so678096pfi.11 for ; Wed, 11 Oct 2017 00:25:06 -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=6UTvsNuKNJke67K2/BEw7Efrt6XPwSnvLvYOXizjmxM=; b=KA1RwsWo8MH8LmvbWLV9dD6T+D7gh3fu86KpjiOpBK+WaOLmDGnQuQnsYjKHC1zkH9 VlPpR2L3NssjxIllY22APoNMVg/fZv/jbqUgkzu9PFKmm/OO7V8sCF91PjB9P+WYkooF NFK9fLjeAxU9hlh5twMSNU49s8NS0n0BbzZD0= 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=6UTvsNuKNJke67K2/BEw7Efrt6XPwSnvLvYOXizjmxM=; b=a+ytkBsp+c6ZlvWbzq06JWSOjHoSd440K88XVjMsuvpdDeh8zdp31f/y0Q80NaunGi FDCRqzhDzehqWc7F4sjFggkybINbE+ICIeXulMlSxAJ/328n8/oX5n9gUTO4colenQlc dBRDozCnjgxlZjncWANI2ygVETyo+mR2rlpCA8vGQZwi+7hYfBRYsK5InCFQrz56/3a/ m/aEcG5mQAzajBGIY0YHwnszku9Rq73FhLl+8BpVcpukUVdBVWWINCmPzoIbWRWoCp9W sEAefVg0fFdAkPvZ714UC+QsQW+X3H45z6YXM4Q2Ohtb1oGBf4urHZBG6e3N6Sw6dryq pO8A== X-Gm-Message-State: AMCzsaXZZMnHzD8eKZTzqmIX3+m9LPOWLab/aYYzasJn7M7XEZbLiDsJ 8bNFEaxikB9XHCOc7R/5Vp7FHQ== X-Google-Smtp-Source: AOwi7QA3QRm0e962FO2UTjUNgH1rlaHEywHLaz6P6Cgo9xMcUGnvCNz/NV61OZWa8/lRipqV3aQNKw== X-Received: by 10.159.207.139 with SMTP id z11mr14212528plo.335.1507706705676; Wed, 11 Oct 2017 00:25:05 -0700 (PDT) Received: from localhost ([122.172.169.205]) by smtp.gmail.com with ESMTPSA id l5sm15582249pfi.165.2017.10.11.00.25.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 00:25:05 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , 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 V11 7/7] mmc: sdhci-msm: Adapt the driver to use OPPs to set clocks/performance state Date: Wed, 11 Oct 2017 12:54:19 +0530 Message-Id: <765602ccad2b6bfca4cb8766bc0849bb7753c835.1507703370.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.15.0.rc1.236.g92ea95045093 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: Rajendra Nayak NOT FOR MERGE. SDHCI driver needs to set a performance state along with scaling its clocks. Modify the driver to use the newly introducded powerdomain performance state based OPPs to scale clocks as well as set an appropriate powerdomain performance state. The patch also adds OPPs for sdhci device on msm8996. The changes have to be validated by populating similar OPP tables on all other devices which use the sdhci driver. This is for now validated only on msm8996 and with missing OPP tables for other devices is known to break those platforms. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 34 ++++++++++++++++++++++++++++++ drivers/clk/qcom/gcc-msm8996.c | 8 +++---- drivers/mmc/host/sdhci-msm.c | 39 ++++++++++++++++++++++++++--------- 3 files changed, 67 insertions(+), 14 deletions(-) -- 2.7.4 diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 0be1db559d61..71183c009c58 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -515,8 +515,42 @@ <&gcc GCC_SDCC2_APPS_CLK>, <&xo_board>; bus-width = <4>; + power-domains = <&rpmpd 0>; + operating-points-v2 = <&sdhc_opp_table>; }; + sdhc_opp_table: opp_table { + compatible = "operating-points-v2"; + + opp@400000 { + opp-hz = /bits/ 64 <400000>; + }; + + opp@20000000 { + opp-hz = /bits/ 64 <20000000>; + }; + + opp@25000000 { + opp-hz = /bits/ 64 <25000000>; + }; + + opp@50000000 { + opp-hz = /bits/ 64 <50000000>; + }; + + opp@96000000 { + opp-hz = /bits/ 64 <96000000>; + }; + + opp@192000000 { + opp-hz = /bits/ 64 <192000000>; + }; + + opp@384000000 { + opp-hz = /bits/ 64 <384000000>; + }; + }; + msmgpio: pinctrl@1010000 { compatible = "qcom,msm8996-pinctrl"; reg = <0x01010000 0x300000>; diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 7ddec886fcd3..38034692f5aa 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -460,7 +460,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = { .name = "sdcc1_apps_clk_src", .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div, .num_parents = 4, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_ops, }, }; @@ -505,7 +505,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .name = "sdcc2_apps_clk_src", .parent_names = gcc_xo_gpll0_gpll4, .num_parents = 3, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_ops, }, }; @@ -519,7 +519,7 @@ static struct clk_rcg2 sdcc3_apps_clk_src = { .name = "sdcc3_apps_clk_src", .parent_names = gcc_xo_gpll0_gpll4, .num_parents = 3, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_ops, }, }; @@ -543,7 +543,7 @@ static struct clk_rcg2 sdcc4_apps_clk_src = { .name = "sdcc4_apps_clk_src", .parent_names = gcc_xo_gpll0, .num_parents = 2, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_ops, }, }; diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index fc73e56eb1e2..cbc5a12af772 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "sdhci-pltfm.h" @@ -131,6 +132,7 @@ struct sdhci_msm_host { struct clk *pclk; /* SDHC peripheral bus clock */ struct clk *bus_clk; /* SDHC bus voter clock */ struct clk *xo_clk; /* TCXO clk needed for FLL feature of cm_dll*/ + struct opp_table *opp_table; unsigned long clk_rate; struct mmc_host *mmc; bool use_14lpp_dll_reset; @@ -140,7 +142,7 @@ struct sdhci_msm_host { bool use_cdclp533; }; -static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, +static long unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, unsigned int clock) { struct mmc_ios ios = host->mmc->ios; @@ -165,16 +167,22 @@ static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host, struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); struct mmc_ios curr_ios = host->mmc->ios; int rc; + struct device *dev = &msm_host->pdev->dev; + struct dev_pm_opp *opp; + long unsigned int freq; + + freq = msm_get_clock_rate_for_bus_mode(host, clock); + opp = dev_pm_opp_find_freq_floor(dev, &freq); + if (IS_ERR(opp)) + pr_err("%s: failed to find OPP for %u at timing %d\n", + mmc_hostname(host->mmc), clock, curr_ios.timing); + + rc = dev_pm_opp_set_rate(dev, freq); + if (rc) + pr_err("%s: error in setting opp\n", __func__); + + msm_host->clk_rate = freq; - clock = msm_get_clock_rate_for_bus_mode(host, clock); - rc = clk_set_rate(msm_host->clk, clock); - if (rc) { - pr_err("%s: Failed to set clock at rate %u at timing %d\n", - mmc_hostname(host->mmc), clock, - curr_ios.timing); - return; - } - msm_host->clk_rate = clock; pr_debug("%s: Setting clock at rate %lu at timing %d\n", mmc_hostname(host->mmc), clk_get_rate(msm_host->clk), curr_ios.timing); @@ -1268,6 +1276,13 @@ static int sdhci_msm_probe(struct platform_device *pdev) goto clk_disable; } + /* Set up the OPP table */ + msm_host->opp_table = dev_pm_opp_set_clkname(&pdev->dev, "core"); + + ret = dev_pm_opp_of_add_table(&pdev->dev); + if (ret) + dev_warn(&pdev->dev, "%s: No OPP table specified\n", __func__); + pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); @@ -1289,6 +1304,8 @@ static int sdhci_msm_probe(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); + dev_pm_opp_of_remove_table(&pdev->dev); + dev_pm_opp_put_clkname(msm_host->opp_table); clk_disable: clk_disable_unprepare(msm_host->clk); pclk_disable: @@ -1314,6 +1331,8 @@ static int sdhci_msm_remove(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); + dev_pm_opp_of_remove_table(&pdev->dev); + dev_pm_opp_put_clkname(msm_host->opp_table); clk_disable_unprepare(msm_host->clk); clk_disable_unprepare(msm_host->pclk);