Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp1216445imj; Sun, 17 Feb 2019 00:25:43 -0800 (PST) X-Google-Smtp-Source: AHgI3IbFFDL2A+/VbxFtk9omLPWMS8XorSMBlXOtqNVeCXKZDyRK80gye6HYw0WuUFJ8Lh0EQWWS X-Received: by 2002:a17:902:27a8:: with SMTP id d37mr19349688plb.182.1550391943676; Sun, 17 Feb 2019 00:25:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550391943; cv=none; d=google.com; s=arc-20160816; b=KeGOF0eabHjr8VVGF/8DohN6HNgYlloIA3KTRc1PyCVbu45ukPIHImc8vpSthbV71M ZMA9jh/uLMMMu6Lg8tmbsGuR6A+qAEQhSJDFRSptqtv8oQHWUB1eXsdg9mb39tkYs929 3ugb05hU9KDogCKpYHaQmDsgJl2TPV6BXp2x9PU3+JgKxf0N+pNEKkS24Z5LbySOTtdu sFGMOH/R1b83BPaJIOQyDAO0WlMG+AzucZBJPcLf2cTtbx5ABo+AIKZeu11ttHHgpGuK 2WDr6tp1uqzxc4mhDQyHlnDkhj10yzANEn13QGxr6fFNL7GZ1gHmDLqcnhee5l1zXnbI B7HQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=iojqUrXb+tcFdXrtwRqSfC0cSq0NHlQsVsM1uJvtIxM=; b=VHCDL6fmmvHF2g+13T7r+oh+Xv2eQhvFOZTBhgYH+3zSgiYgFNmiaiVY3Iln+Fh9/w zTw2iok9Ndzi4ngZimKe934v/pBfHgxiFd9a0LgodrNDnE7YgoQFEAxdoNUW8a06xPjH BMr1U/A5FQwhudUH3TQNUXoYrOAXmt9QyThfh2ATKbrrbaO9TDBo5Q7YNbn5LIcBrwyS MpLO/K/3R9N66gMh0fnfpPGItlB7h0z1ONhTMIXk9seUens2V+HuxPle9lJ6B8rze6ad a5Uk1mL9F7u5128Aba3HFF4+LkRtVc3Kv3rZJjNX9gq8sLLiUChwxvJ92Wppks0ToRbP I5cA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u26si6941760pfh.113.2019.02.17.00.25.27; Sun, 17 Feb 2019 00:25:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730076AbfBQDzX (ORCPT + 99 others); Sat, 16 Feb 2019 22:55:23 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:3751 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727723AbfBQDzS (ORCPT ); Sat, 16 Feb 2019 22:55:18 -0500 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 83BDC6C44685C937A2C7; Sun, 17 Feb 2019 11:55:15 +0800 (CST) Received: from linux-ibm.site (10.175.102.37) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.408.0; Sun, 17 Feb 2019 11:55:08 +0800 From: Xiongfeng Wang To: , , , , , CC: , , , , Subject: [PATCH v3 2/2] cpufreq / cppc: Work around for Hisilicon CPPC cpufreq Date: Sun, 17 Feb 2019 11:54:15 +0800 Message-ID: <1550375655-58007-3-git-send-email-wangxiongfeng2@huawei.com> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1550375655-58007-1-git-send-email-wangxiongfeng2@huawei.com> References: <1550375655-58007-1-git-send-email-wangxiongfeng2@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.102.37] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hisilicon chips do not support delivered performance counter register and reference performance counter register. But the platform can calculate the real performance using its own method. We reuse the desired performance register to store the real performance calculated by the platform. After the platform finished the frequency adjust, it gets the real performance and writes it into desired performance register. Os can use it to calculate the real frequency. Signed-off-by: Xiongfeng Wang --- drivers/cpufreq/cppc_cpufreq.c | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index fd25c21c..efc0298 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -42,6 +42,67 @@ */ static struct cppc_cpudata **all_cpu_data; +struct cppc_workaround_oem_info { + char oem_id[ACPI_OEM_ID_SIZE +1]; + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; + u32 oem_revision; +}; + +static bool apply_hisi_workaround; + +static struct cppc_workaround_oem_info wa_info[] = { + { + .oem_id = "HISI ", + .oem_table_id = "HIP07 ", + .oem_revision = 0, + }, { + .oem_id = "HISI ", + .oem_table_id = "HIP08 ", + .oem_revision = 0, + } +}; + +static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu, + unsigned int perf); + +/* + * HISI platform does not support delivered performance counter and + * reference performance counter. It can calculate the performance using the + * platform specific mechanism. We reuse the desired performance register to + * store the real performance calculated by the platform. + */ +static unsigned int hisi_cppc_cpufreq_get_rate(unsigned int cpunum) +{ + struct cppc_cpudata *cpudata = all_cpu_data[cpunum]; + u64 desired_perf; + int ret; + + ret = cppc_get_desired_perf(cpunum, &desired_perf); + if (ret < 0) + return -EIO; + + return cppc_cpufreq_perf_to_khz(cpudata, desired_perf); +} + +static void cppc_check_hisi_workaround(void) +{ + struct acpi_table_header *tbl; + acpi_status status = AE_OK; + int i; + + status = acpi_get_table(ACPI_SIG_PCCT, 0, &tbl); + if (ACPI_FAILURE(status) || !tbl) + return; + + for (i = 0; i < ARRAY_SIZE(wa_info); i++) { + if (!memcmp(wa_info[i].oem_id, tbl->oem_id, ACPI_OEM_ID_SIZE) && + !memcmp(wa_info[i].oem_table_id, tbl->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) && + wa_info[i].oem_revision == tbl->oem_revision) { + apply_hisi_workaround = true; + } + } +} + /* Callback function used to retrieve the max frequency from DMI */ static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private) { @@ -334,6 +395,9 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum) struct cppc_cpudata *cpu = all_cpu_data[cpunum]; int ret; + if (apply_hisi_workaround) + return hisi_cppc_cpufreq_get_rate(cpunum); + ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t0); if (ret) return ret; @@ -386,6 +450,8 @@ static int __init cppc_cpufreq_init(void) goto out; } + cppc_check_hisi_workaround(); + ret = cpufreq_register_driver(&cppc_cpufreq_driver); if (ret) goto out; -- 1.7.12.4