From patchwork Tue Aug 16 20:39:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Prakash, Prashanth" X-Patchwork-Id: 9284713 X-Patchwork-Delegate: rjw@sisk.pl Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BC8AC60574 for ; Tue, 16 Aug 2016 20:41:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF7182877D for ; Tue, 16 Aug 2016 20:41:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A3CED28795; Tue, 16 Aug 2016 20:41:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 17C9F2877D for ; Tue, 16 Aug 2016 20:41:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753735AbcHPUli (ORCPT ); Tue, 16 Aug 2016 16:41:38 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:54891 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753334AbcHPUj4 (ORCPT ); Tue, 16 Aug 2016 16:39:56 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id ACA5D61D8A; Tue, 16 Aug 2016 20:39:55 +0000 (UTC) Received: from pprakash-lnx.qualcomm.com (unknown [129.46.15.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: pprakash@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 6C4AC61DA8; Tue, 16 Aug 2016 20:39:54 +0000 (UTC) From: Prashanth Prakash To: linux-acpi@vger.kernel.org Cc: rjw@rjwysocki.net, alexey.klimov@arm.com, hotran@apm.com, cov@codeaurora.org, Prashanth Prakash Subject: [PATCH V3 4/7] ACPI/CPPC: set a non-zero value for transition_latency Date: Tue, 16 Aug 2016 14:39:41 -0600 Message-Id: <1471379984-15712-5-git-send-email-pprakash@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1471379984-15712-1-git-send-email-pprakash@codeaurora.org> References: <1471379984-15712-1-git-send-email-pprakash@codeaurora.org> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Compute the expected transition latency for frequency transitions using the values from the PCCT tables when the desired perf register is in PCC. Cc: "Rafael J. Wysocki" Signed-off-by: Prashanth Prakash Reviewed-by: Alexey Klimov --- drivers/acpi/cppc_acpi.c | 46 ++++++++++++++++++++++++++++++++++++++++-- drivers/cpufreq/cppc_cpufreq.c | 1 + include/acpi/cppc_acpi.h | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 5623fca..6c54a8f 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -85,7 +85,7 @@ static void __iomem *pcc_comm_addr; static int pcc_subspace_idx = -1; static bool pcc_channel_acquired; static ktime_t deadline; -static unsigned int pcc_mpar, pcc_mrtt; +static unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; /* pcc mapped address + header size + offset within PCC subspace */ #define GET_PCC_VADDR(offs) (pcc_comm_addr + 0x8 + (offs)) @@ -473,7 +473,6 @@ static int register_pcc_channel(int pcc_subspace_idx) return -ENODEV; } - /* * cppc_ss->latency is just a Nominal value. In reality * the remote processor could be much slower to reply. @@ -483,6 +482,7 @@ static int register_pcc_channel(int pcc_subspace_idx) deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); pcc_mrtt = cppc_ss->min_turnaround_time; pcc_mpar = cppc_ss->max_access_rate; + pcc_nominal = cppc_ss->latency; pcc_comm_addr = acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length); if (!pcc_comm_addr) { @@ -1048,3 +1048,45 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) return ret; } EXPORT_SYMBOL_GPL(cppc_set_perf); + +/** + * cppc_get_transition_latency - returns frequency transition latency in ns + * + * ACPI CPPC does not explicitly specifiy how a platform can specify the + * transition latency for perfromance change requests. The closest we have + * is the timing information from the PCCT tables which provides the info + * on the number and frequency of PCC commands the platform can handle. + */ +unsigned int cppc_get_transition_latency(int cpu_num) +{ + /* + * Expected transition latency is based on the PCCT timing values + * Below are definition from ACPI spec: + * pcc_nominal- Expected latency to process a command, in microseconds + * pcc_mpar - The maximum number of periodic requests that the subspace + * channel can support, reported in commands per minute. 0 + * indicates no limitation. + * pcc_mrtt - The minimum amount of time that OSPM must wait after the + * completion of a command before issuing the next command, + * in microseconds. + */ + unsigned int latency_ns = 0; + struct cpc_desc *cpc_desc; + struct cpc_register_resource *desired_reg; + + cpc_desc = per_cpu(cpc_desc_ptr, cpu_num); + if (!cpc_desc) + return CPUFREQ_ETERNAL; + + desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; + if (!CPC_IN_PCC(desired_reg)) + return CPUFREQ_ETERNAL; + + if (pcc_mpar) + latency_ns = 60 * (1000 * 1000 * 1000 / pcc_mpar); + + latency_ns = max(latency_ns, (pcc_nominal + pcc_mrtt) * 1000); + + return latency_ns; +} +EXPORT_SYMBOL_GPL(cppc_get_transition_latency); diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 8882b8e..e6a3359 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -98,6 +98,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->max = cpu->perf_caps.highest_perf; policy->cpuinfo.min_freq = policy->min; policy->cpuinfo.max_freq = policy->max; + policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num); policy->shared_type = cpu->shared_type; if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index d2101bc..42cbeb9 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -131,5 +131,6 @@ extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); extern int acpi_get_psd_map(struct cpudata **); +extern unsigned int cppc_get_transition_latency(int cpu); #endif /* _CPPC_ACPI_H*/