From patchwork Mon Mar 25 19:57:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: dann frazier X-Patchwork-Id: 1064764 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44SlS20P1qz9sSt; Tue, 26 Mar 2019 06:58:10 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1h8VjQ-00066b-HQ; Mon, 25 Mar 2019 19:58:04 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1h8VjO-000656-4s for kernel-team@lists.ubuntu.com; Mon, 25 Mar 2019 19:58:02 +0000 Received: from mail-it1-f198.google.com ([209.85.166.198]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1h8VjN-0008Fn-Pr for kernel-team@lists.ubuntu.com; Mon, 25 Mar 2019 19:58:01 +0000 Received: by mail-it1-f198.google.com with SMTP id 190so9866974itv.3 for ; Mon, 25 Mar 2019 12:58:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FtmGLzlMvNJIAlM7xGXxcvfvcyIIbKclArJIDF4PYfQ=; b=FDRdclhQgcf6sP3DOiwbBvkNZLl4JGXU8K0mYwlt5V94ruomYWM5w8psSitGSCvdnI 5bcndhmzAptKvx1vO2Rihqk0JAE1U2+Ux2X3Qzf4jssmG0xuSQDXWgBOKOofh1HVJNpP FxIx0GrgQDldTCtv0qAmRvsRfe4q9EKcpd223SXU+5lrkvAHOl1ybvp8YbxxAGKb+ho2 UB2JEbp2bpG3OpZ5VDQf8GgW384Vt9RYwpX7iw4DfWB9u3e8+T6dG5O7hLtgyIJn7WyS GRxExbpmhEVxawn2XdwtErrOwSaYOCMObek9RSBdoJhS1kxAuyKMm585I54GoGYm35ea R0jw== X-Gm-Message-State: APjAAAUbYNskRks98EPo534wncXcNbvroU6Y8TvA1piZ5wMjOTkGryOM jsBQh7iLtXcKH0AM98jVk9waP3tUad7lOlrRH+pqBlFNv7u+gvTnGUa300nBalpf6Vs9ZON5xiV 1JRQWJ/QYNbg2I9PkSM90OcTi5myyWpocYo8OoXdTFw== X-Received: by 2002:a24:2855:: with SMTP id h82mr7696020ith.82.1553543880612; Mon, 25 Mar 2019 12:58:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqwYla5+jkRfpGikMQu8GZdkHV0zzegA5Zq00EKCBqFyL8zljjbWMjzcX1lzzPC7kTKN0aCDCQ== X-Received: by 2002:a24:2855:: with SMTP id h82mr7696012ith.82.1553543880360; Mon, 25 Mar 2019 12:58:00 -0700 (PDT) Received: from xps13.canonical.com (c-107-2-141-103.hsd1.co.comcast.net. [107.2.141.103]) by smtp.gmail.com with ESMTPSA id b1sm3072408ioj.82.2019.03.25.12.57.59 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 25 Mar 2019 12:57:59 -0700 (PDT) From: dann frazier To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/2][Disco] cpufreq / cppc: Work around for Hisilicon CPPC cpufreq Date: Mon, 25 Mar 2019 13:57:34 -0600 Message-Id: <20190325195734.14865-3-dann.frazier@canonical.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190325195734.14865-1-dann.frazier@canonical.com> References: <20190325195734.14865-1-dann.frazier@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Xiongfeng Wang BugLink: https://bugs.launchpad.net/bugs/1821620 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 [ rjw: Drop unnecessary braces ] Signed-off-by: Rafael J. Wysocki (cherry picked from commit 6c8d750f9784cef32a8cffdad74c8a351b4ca3a6) Signed-off-by: dann frazier --- drivers/cpufreq/cppc_cpufreq.c | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index fd25c21cee72f..2ae978d27e613 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -42,6 +42,66 @@ */ 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 +394,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 +449,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;