From patchwork Tue Sep 19 22:32:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 113069 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp34481qgf; Tue, 19 Sep 2017 15:33:37 -0700 (PDT) X-Received: by 10.99.96.140 with SMTP id u134mr135659pgb.264.1505860417726; Tue, 19 Sep 2017 15:33:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505860417; cv=none; d=google.com; s=arc-20160816; b=rW3o/ds5ypCs4q2wheG3GVOOOy8lV81KXcUvB2Z2YIB1AsiKmjytdxQ8zDr5aNvtgg UVWvaJbP5CAJnuGnGItrBF7ATlk8jAjkCpk9QZ9jL39e9aKeIkIXdC+nYR3exnwPS4xn /yQfUr5r/ir8phEU+Xz+qUK9womitWfolJlRZ+vnETm4lVZ7xqYfKHY6I7MDn7vtCRQi lPekTAJoo+62uwYxJLO3Y+z62tn9UhZLl8YrTPwv+NoB1TyTCPDRM8KaF8g17JCZk8WU DRMXgK/LHLEW9WH6XlnHzGdIX0uFEl1um8pF5iHQw3pwhphhZRqggUwAIOt+QieVKf29 7lJQ== 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=WVS2XISvE0//YMyTEl+xi8lZ2llXNUJp9NpX2SwBy9s=; b=W94mLZtcWEud5sNcPjR6z+mTdv2HFZEab3ZxsHTcTJbEfQQlaSvmitBM1JyFzYcdfT 0xklzScdMwYFApQ+Eqqiyd484BkIcS+1vKCoIZIxt0t3NzcI4Xr9IjdkpF9vtCZqqgVY 0797kYhJfjVk3xr3rCZTlalb/so8Q4GnCaH6uyMOs7xDTiajZR7EZTridi99BD1MnBLb d8AQvY86vGN9bJFsy8/C+AsF+o3gdedWJai3Jb6ppnfPbslF90mmQx+sCqbzQWgmm0Eq qjJdnX9Fg/yQGVmfFdOKv1VjcaVnrZh/mhzbib8LeeSqSzytZzSaYGgXBp+6FOhWj3aN /3Jg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B8beK8cs; 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 m14si1969339pgs.783.2017.09.19.15.33.37; Tue, 19 Sep 2017 15:33:37 -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=B8beK8cs; 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 S1751678AbdISWdg (ORCPT + 12 others); Tue, 19 Sep 2017 18:33:36 -0400 Received: from mail-pg0-f42.google.com ([74.125.83.42]:47624 "EHLO mail-pg0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751738AbdISWco (ORCPT ); Tue, 19 Sep 2017 18:32:44 -0400 Received: by mail-pg0-f42.google.com with SMTP id d8so610318pgt.4 for ; Tue, 19 Sep 2017 15:32:44 -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=WVS2XISvE0//YMyTEl+xi8lZ2llXNUJp9NpX2SwBy9s=; b=B8beK8csCSWvEmo24UNbriUQdmx3O8+/axoXMEZtIA755Fbvaja/7QyHL9K8+qUZlS MUPnwXerMR4JVl3QUBFwoEd2+2mmlEbiBGYpjC6OfIXIl/GT6P1evVDtcNYCIjNl/syo lzPZY7DCHSNHMcc33NIljNF92JkfPrCw+h2g8= 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=WVS2XISvE0//YMyTEl+xi8lZ2llXNUJp9NpX2SwBy9s=; b=WXahXQo2oGE8ubMy7WgDICFqYftOslJpg8LJi9PP3RSeFrsvytehRwCDu52Ts/tyPG T7vSBnqLjmwmuGVrptS61CoGLViHZr8RiyIb4uImxiIJ/s0x01eEXtEJ24+A2qWmbhqU p/lTh3KrkBE+Nb22/+JOvEokqF3Hric4odtPWXqlUrthf/h9wz67Wf9GLW3CmXQuCc9x lNpUIkosIT4jbkt+6i8dw8G74jzw82opxz8afXQrj0q82NlrwfwV8+o9iG5jbPlQEs/c wnS1tOBG864SwThKwVSV+Fe81ifwT54xZhULU9szictVwsgga8n0e4ZZeGr2BKr1Pxt0 MJfw== X-Gm-Message-State: AHPjjUg7FEDwrjRuSRGlz9d0H7d/o4zR2abapj5Wejh5Jw0ti34IMOrY aDZPZ+76wnIjCBtWpdahIxWK9Q== X-Google-Smtp-Source: AOwi7QAremMrchaZjYi9gwUYK7/5/aaetlbSnb1fIgefXDyUKwGfEcOsg7i0dpCuDb8dOnXpcbjwWA== X-Received: by 10.99.117.81 with SMTP id f17mr131010pgn.314.1505860363354; Tue, 19 Sep 2017 15:32:43 -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 x19sm6846136pfa.16.2017.09.19.15.32.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Sep 2017 15:32:42 -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 4/7] soc: qcom: rpmpd: Add a powerdomain driver to model cx/mx powerdomains Date: Tue, 19 Sep 2017 15:32:20 -0700 Message-Id: <5bab3b8f9601bc76c73e0c4154a0f5dcfba0cffc.1505859768.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.4 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 THIS IS TEST CODE, SHOULDN'T BE MERGED. The cx/mx powerdomains 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 powerdomains on msm8996. Not-signed-off-by: Rajendra Nayak Not-signed-off-by: Viresh Kumar --- .../devicetree/bindings/power/qcom,rpmpd.txt | 10 + 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, 332 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..8b48ce57a563 --- /dev/null +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt @@ -0,0 +1,10 @@ +Qualcomm RPM Powerdomains + +* For RPM powerdomains, 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..38ff424bdebe 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 Powerdomain driver" + depends on MFD_QCOM_RPM && QCOM_SMD_RPM + help + QCOM RPM powerdomain driver to support powerdomain 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..d34d9c363815 --- /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 Tue Sep 19 22:32:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 113066 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp33917qgf; Tue, 19 Sep 2017 15:32:52 -0700 (PDT) X-Received: by 10.98.69.137 with SMTP id n9mr135835pfi.164.1505860372630; 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=WUGusdZP1i0lexd9ZxTqD9kBQAKLLXUsfgnVhWGZ7rXLlrqHDbGBKVI9x4a2/meNMC 2LAgBlTnW+TW4pM50PD/Y/Yv2H+e81VyJ63OWlwK3n5PQkZ4qc46B7yCgszgxj5AtoAr KZeeO7FgvpHScNMjs4BFgRobdWg41/VFqI2fZ1MuouPgXbzu0XDj28BjCCQYFMahbigX Lt5ljs5WocmTwG6QyH58HiSsSmu65pmzqhNKP8Icm7ZfUtbSL0bHVT2KWe69fqxOI7tV isEufK+lffHyK28Ca5+0+oeWyf9DQ8rI/4z02TPk1JISveGX9AThzaRSG/rtyzN9eo2J fmUw== 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=Ms17HxLEqyX7GMSEfKAhb+YPLu4N4CxXpKYoZfW9Ojo=; b=nAHsLqYP5P++XWOPcmCyM5oyttTSBKxOGMjZ1DpalKniIUjnE+JGHchcWdqGHboYmO rMfopDHShiHdUeonUhbk1dD5mL4PvWJXSz6aMiA9IylZdmJW8oRSIZCzm5hymH74KEVq 3BMjXAB7sgpjo5JnaHTotdexJTQw+alJuhG3S1NSags/G3MZZfxqb2+h9bDEY31W/m2b CpHSRaSrNhUmZjRmqqN0EA0r68OEaA/KLrdrKKISXxnfIknmNEhA6aZ94U2R/DlwM2fm trls1dYz0C/vOVMN0I2Px8K02jxQlFsGQWbs+AGRvk6GOivyr/TMjWv8IGvlE0ZGGK8G tlog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=U2PHAVk/; 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 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-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=U2PHAVk/; 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 S1751747AbdISWct (ORCPT + 12 others); Tue, 19 Sep 2017 18:32:49 -0400 Received: from mail-pg0-f54.google.com ([74.125.83.54]:53637 "EHLO mail-pg0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751710AbdISWcr (ORCPT ); Tue, 19 Sep 2017 18:32:47 -0400 Received: by mail-pg0-f54.google.com with SMTP id j70so600673pgc.10 for ; Tue, 19 Sep 2017 15:32:46 -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=Ms17HxLEqyX7GMSEfKAhb+YPLu4N4CxXpKYoZfW9Ojo=; b=U2PHAVk/li09quNGXzFU6OdpkcqRI+aJMRGJY4kwjw7MfrdJw8b5Uvv20Xujk9Wo/2 I1gf3wOv4ESyMU/rFcrazR+4v7DMnxsFbK2I79+VDmrlkWdBdRnwhgZMyPfUoZJFNcDn 96AxXQz2MZ31kftZVoOnHvMEN0vAQzcMugWFA= 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=Ms17HxLEqyX7GMSEfKAhb+YPLu4N4CxXpKYoZfW9Ojo=; b=UmC1Zdgd4o1Kg0LlqEvyK8+1omTvBB30Mc2tSYaIak0Ien6B+ClRMNW2cqZgp47NBh 2ZBvFMEBBpOHkZ4nip1tGIbMGImpV4oJQNlc2VTHo0FYLAEFIY7hS8AZsoveiRzHqIW1 rwF9yTqBv81t17yadX8TToAfY1jb+WBPWfvu8pE4rbu+Zm3PWIFCo+n1CrUjZIjLJn3d eNeSxzTq9sb/fxGuy1tdSx6tm7u74bgmFv1qEU7U+RjSBthuvNdnvXgjf7/qA4TNr3aa 9fGvSiTqwp/ZZEs6TDiD8z0ZntSLpN79M+wg/op5OHMVrbr3JVwJLXyd+lhlTO3K/1Kf zlvg== X-Gm-Message-State: AHPjjUjsBX62zhSxhCIDFnFvY00dmlER/dTSzNNe3wFsdZz1zrgigpYz nNELJpUPP/1n8jA5b2WQV90HtA== X-Google-Smtp-Source: AOwi7QDtx2Y3rZKKCSZzdLMur+Yxhxztm1o3IBHAoUUAmHWLZ7335ygHJmg0tpruUmkcU2LEaT9oiw== X-Received: by 10.101.85.4 with SMTP id f4mr138372pgr.10.1505860366433; Tue, 19 Sep 2017 15:32:46 -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 u77sm5406901pfk.87.2017.09.19.15.32.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Sep 2017 15:32:45 -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 6/7] mmc: sdhci-msm: Adapt the driver to use OPPs to set clocks/performance state Date: Tue, 19 Sep 2017 15:32:22 -0700 Message-Id: X-Mailer: git-send-email 2.7.4 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 THIS IS TEST CODE, SHOULDN'T BE MERGED. 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. Not-signed-off-by: Rajendra Nayak Not-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);