Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp81273imj; Thu, 14 Feb 2019 15:48:20 -0800 (PST) X-Google-Smtp-Source: AHgI3IZV0UK3YST1CqnUQof/3lkLE1UCGu8sT+NigbD8zWMRn8ygJ8GVbEVXRu+vWNXAiTAOh4QM X-Received: by 2002:a62:931a:: with SMTP id b26mr7050538pfe.65.1550188100633; Thu, 14 Feb 2019 15:48:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550188100; cv=none; d=google.com; s=arc-20160816; b=Io9ZtfjpXdB6qb6YPtsIZYOvdQ6HHwL3rG0Lw+OIFYzwcXHq4VxzXl4ZtgolTDAe+f cr4d1Vae6SlJt7DveLph2UxAQkJbfut7fprNjF0jNvQFzh6ZHboz4OehwtablW/RaU9/ SKhZogST3fXdsuhl6oPKdFJVmejCVb8sLaagc/ZaYlhCXk73pcuOfYuaKn4oMHwrj5T1 5/62TINhG8AhVaFt/p0Bdp9fam/bJjBvHdmb8fABn6wBnXYNuTW3D6BAZ7EOL6CvXxHs oQIBjdcK90GSBPFg5QWz1Ni8V8dw/51t3SNWZZQ4pICGpe7PtdY8svlX4fHHSZbVslQz j0Sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=FZS0P2mRkSAKCbWBgDyqVWML9OBLqBtVA/y3S4LuK5A=; b=siemlxwzCoXWFa4WjcxpaTsLWThJ7CWhltP/NsXtcY9kMjg7b8Z92vSSGJT4bmzVDT tjd4yD5D+iPq+U49l9swFlE3moT3yRO0cjWwi8dsgq6kPji7Ox2n9Q1y6a5J/QoZaybe KtD/M1ic1v+Uzy7pFVj9H/cWLKgrvhGefgw3bpmnWNnK80A/Lrc3S+iSyO2mguBg9ZbG awSSfuuCvs2QPGJDh41jVhbIp8YEVfo/XckiZJtUzfKCmtoKuyBvAeuKlhiGHhz8jw+g /f4DxpJHK4P7oezbtt4NvAtzqU0eV+SnCvCnQTN1U21DPz8fX0H9GtVaBOlRol9g3yA5 lZ1w== 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 d11si3872380pla.335.2019.02.14.15.48.05; Thu, 14 Feb 2019 15:48:20 -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 S1733158AbfBNN66 (ORCPT + 99 others); Thu, 14 Feb 2019 08:58:58 -0500 Received: from szxga06-in.huawei.com ([45.249.212.32]:33166 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726924AbfBNN66 (ORCPT ); Thu, 14 Feb 2019 08:58:58 -0500 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 7B17DED6FA612E3667D8; Thu, 14 Feb 2019 21:58:30 +0800 (CST) Received: from [127.0.0.1] (10.184.52.56) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.408.0; Thu, 14 Feb 2019 21:58:23 +0800 Subject: Re: [PATCH v2 2/2] cpufreq / cppc: Work around for Hisilicon CPPC cpufreq To: "Rafael J. Wysocki" CC: Viresh Kumar , , "Prashanth Prakash" , George Cherian , Robert Moore , "ACPI Devel Maling List" , Linux Kernel Mailing List , Hanjun Guo , John Garry References: <1550130368-60513-1-git-send-email-wangxiongfeng2@huawei.com> <1550130368-60513-3-git-send-email-wangxiongfeng2@huawei.com> From: Xiongfeng Wang Message-ID: <86a1eddc-01aa-f32a-9bef-c18c7649149b@huawei.com> Date: Thu, 14 Feb 2019 21:58:21 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.184.52.56] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2019/2/14 18:58, Rafael J. Wysocki wrote: > On Thu, Feb 14, 2019 at 8:46 AM Xiongfeng Wang > wrote: >> >> 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. This patch provide >> a workaround for this problem, and other platforms can also use this >> workaround framework. 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 | 70 ++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 70 insertions(+) >> >> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c >> index fd25c21c..da96fec 100644 >> --- a/drivers/cpufreq/cppc_cpufreq.c >> +++ b/drivers/cpufreq/cppc_cpufreq.c >> @@ -33,6 +33,16 @@ >> /* Offest in the DMI processor structure for the max frequency */ >> #define DMI_PROCESSOR_MAX_SPEED 0x14 >> >> +struct cppc_workaround_info { >> + char oem_id[ACPI_OEM_ID_SIZE +1]; >> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; >> + u32 oem_revision; >> + unsigned int (*get_rate)(unsigned int cpu); >> +}; >> + >> +/* CPPC workaround for get_rate callback */ >> +unsigned int (*cppc_wa_get_rate)(unsigned int cpu); >> + > > First off, please don't split the workaround material into two parts. > IOW, the other new function added below can go here just fine IMO. > >> /* >> * These structs contain information parsed from per CPU >> * ACPI _CPC structures. >> @@ -334,6 +344,9 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum) >> struct cppc_cpudata *cpu = all_cpu_data[cpunum]; >> int ret; >> >> + if (cppc_wa_get_rate) >> + return cppc_wa_get_rate(cpunum); > > Second, what is the value of using the function pointer above? > > All we need for now is a flag to indicate whether or not to call > hisi_cppc_cpufreq_get_rate() here and return its return value. How about adding a pointer of 'struct cppc_workaround_info' to indicate whether we have found a matches workaround ? If I use a flag, I will need another variable to indicate which item of the workaround array 'wa_info' to use. Thanks, Xiongfeng > >> + >> ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t0); >> if (ret) >> return ret; >> @@ -357,6 +370,61 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum) >> .name = "cppc_cpufreq", >> }; >> >> +/* >> + * 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 struct cppc_workaround_info wa_info[] = { >> + { >> + .oem_id = "HISI ", >> + .oem_table_id = "HIP07 ", >> + .oem_revision = 0, >> + .get_rate = hisi_cppc_cpufreq_get_rate, >> + }, { >> + .oem_id = "HISI ", >> + .oem_table_id = "HIP08 ", >> + .oem_revision = 0, >> + .get_rate = hisi_cppc_cpufreq_get_rate, >> + } >> +}; >> + >> +static int cppc_check_workaround(void) > > And this function can be a void one. > > >> +{ >> + 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 -EINVAL; >> + >> + 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) { >> + cppc_wa_get_rate = wa_info[i].get_rate; >> + return 0; >> + } >> + } >> + >> + return -ENODEV; >> +} >> + >> static int __init cppc_cpufreq_init(void) >> { >> int i, ret = 0; >> @@ -386,6 +454,8 @@ static int __init cppc_cpufreq_init(void) >> goto out; >> } >> >> + cppc_check_workaround(); >> + >> ret = cpufreq_register_driver(&cppc_cpufreq_driver); >> if (ret) >> goto out; >> -- > > . >