From patchwork Thu Dec 15 01:06:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Prakash, Prashanth" X-Patchwork-Id: 9475277 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 AA182607EE for ; Thu, 15 Dec 2016 01:06:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9BFA5286AA for ; Thu, 15 Dec 2016 01:06:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 90B4B286D0; Thu, 15 Dec 2016 01:06:45 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 19753286AA for ; Thu, 15 Dec 2016 01:06:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934440AbcLOBGo (ORCPT ); Wed, 14 Dec 2016 20:06:44 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:44582 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933869AbcLOBGn (ORCPT ); Wed, 14 Dec 2016 20:06:43 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 4FAED6159E; Thu, 15 Dec 2016 01:06:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1481764002; bh=ISbVmbqfbi3VmpHctAA5iszwv6gk7gj+mcO7hmSQ1sw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QWRVaI6j1S3Y9EwnVEvZUEGtZ3j5PuimYBb/4y4CgeqGH7GqAS++X2Fv8wNj88gFr MusR5He6q8e/VdfV2LdrDSskSeoU9H2/UBMOdLWqrlILC27aWqw8cjsR1TG+M93hiH JGSpxi0Oya/fuWyiVP2t42sgPNWJjS4bo6teHwEg= Received: from pprakash-lnx.qualcomm.com (unknown [129.46.15.3]) (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 EB56B6159E; Thu, 15 Dec 2016 01:06:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1481764001; bh=ISbVmbqfbi3VmpHctAA5iszwv6gk7gj+mcO7hmSQ1sw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=blt3mTLhQP0vDXmieEJ1NNoctxlUFXDc+1Cs9A+k7FtUTsFEEtvW0dGDZ8tI/r9xH +dRyHpzCI7bbA4UtDFwHpbIc8LhcZALbX1Ye4rj7s3dft9hLyTTPrf7lnIZ/vQoi88 P9nnxDTL/JnXWhwcKB8Lfvohz0u8jwOCVi72WGKQ= DMARC-Filter: OpenDMARC Filter v1.3.1 smtp.codeaurora.org EB56B6159E Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=pass smtp.mailfrom=pprakash@codeaurora.org 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 1/2] ACPI / CPPC: read all perf caps in a single cppc read command Date: Wed, 14 Dec 2016 18:06:33 -0700 Message-Id: <1481763994-28146-2-git-send-email-pprakash@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1481763994-28146-1-git-send-email-pprakash@codeaurora.org> References: <1481763994-28146-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 CPPC performance capabilities do not change during runtime, so we can read perf caps for all CPUs in a single CPPC read command and cache them locally. Signed-off-by: Prashanth Prakash --- drivers/acpi/cppc_acpi.c | 103 +++++++++++++++++++++++++++++++++-------------- include/acpi/cppc_acpi.h | 1 + 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 3ca0729..45f021a 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -92,6 +92,12 @@ struct cppc_pcc_data { */ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); +/* + * The cppc_perf_caps structure contains the performance capabilities + * as described in section 8.4.7.1 of ACPI 6.1 spec + */ +static DEFINE_PER_CPU(struct cppc_perf_caps, cpc_perf_caps); + /* pcc mapped address + header size + offset within PCC subspace */ #define GET_PCC_VADDR(offs) (pcc_data.pcc_comm_addr + 0x8 + (offs)) @@ -971,49 +977,84 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) */ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) { - struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); - struct cpc_register_resource *highest_reg, *lowest_reg, *ref_perf, - *nom_perf; - u64 high, low, nom; - int ret = 0, regs_in_pcc = 0; + static bool initialized; + int ret = 0, i; + bool regs_in_pcc = false; + struct cppc_perf_caps *caps; - if (!cpc_desc) { - pr_debug("No CPC descriptor for CPU:%d\n", cpunum); - return -ENODEV; + if (initialized) { + caps = &per_cpu(cpc_perf_caps, cpunum); + + if (!caps->highest_perf || !caps->lowest_perf || + !caps->nominal_perf || !caps->lowest_non_linear_perf) + return -EFAULT; + + memcpy(perf_caps, caps, sizeof(struct cppc_perf_caps)); + return 0; } - highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; - lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; - ref_perf = &cpc_desc->cpc_regs[REFERENCE_PERF]; - nom_perf = &cpc_desc->cpc_regs[NOMINAL_PERF]; + /* Perf caps don't change over time, so read all of them at once */ + for_each_possible_cpu(i) { + struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, i); + struct cpc_register_resource *highest_reg, *lowest_reg, + *nom_reg, *lowest_non_linear_reg; + u64 perf; - /* Are any of the regs PCC ?*/ - if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || - CPC_IN_PCC(ref_perf) || CPC_IN_PCC(nom_perf)) { - regs_in_pcc = 1; - down_write(&pcc_data.pcc_lock); - /* Ring doorbell once to update PCC subspace */ - if (send_pcc_cmd(CMD_READ) < 0) { - ret = -EIO; - goto out_err; + if (!cpc_desc) { + pr_debug("No CPC descriptor for CPU:%d\n", i); + continue; + } + + highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; + lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; + lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; + nom_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; + + /* Are any of the regs in PCC ?*/ + if (!regs_in_pcc) { + regs_in_pcc = CPC_IN_PCC(highest_reg) || + CPC_IN_PCC(lowest_reg) || + CPC_IN_PCC(lowest_non_linear_reg) || + CPC_IN_PCC(nom_reg); + if (regs_in_pcc) { + down_write(&pcc_data.pcc_lock); + /* Skip if another CPU has completed init */ + if (initialized) + goto out; + + /* Ring doorbell once to update PCC subspace */ + if (send_pcc_cmd(CMD_READ) < 0) { + ret = -EIO; + goto out; + } + } } - } - cpc_read(cpunum, highest_reg, &high); - perf_caps->highest_perf = high; + caps = &per_cpu(cpc_perf_caps, i); - cpc_read(cpunum, lowest_reg, &low); - perf_caps->lowest_perf = low; + cpc_read(i, highest_reg, &perf); + caps->highest_perf = perf; - cpc_read(cpunum, nom_perf, &nom); - perf_caps->nominal_perf = nom; + cpc_read(i, lowest_reg, &perf); + caps->lowest_perf = perf; - if (!high || !low || !nom) - ret = -EFAULT; + cpc_read(i, nom_reg, &perf); + caps->nominal_perf = perf; -out_err: + cpc_read(i, lowest_non_linear_reg, &perf); + caps->lowest_non_linear_perf = perf; + } + + initialized = true; + +out: if (regs_in_pcc) up_write(&pcc_data.pcc_lock); + + /* Copy over the per cpu data to perf_caps if init ws successful */ + if (!ret) + ret = cppc_get_perf_caps(cpunum, perf_caps); + return ret; } EXPORT_SYMBOL_GPL(cppc_get_perf_caps); diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 427a7c3..3f64660 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -103,6 +103,7 @@ struct cppc_perf_caps { u32 highest_perf; u32 nominal_perf; u32 lowest_perf; + u32 lowest_non_linear_perf; }; struct cppc_perf_ctrls {