Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp1697218imj; Thu, 14 Feb 2019 10:28:58 -0800 (PST) X-Google-Smtp-Source: AHgI3Ia76T76R5KFqFIrsU9uAukkPB1oeu4/B6SKVR0mvLuMjXdUeTCCx3uwMucVQpnTUnqMoy+M X-Received: by 2002:a65:6684:: with SMTP id b4mr1197140pgw.55.1550168938142; Thu, 14 Feb 2019 10:28:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550168938; cv=none; d=google.com; s=arc-20160816; b=nrb43AzCXBJJ5My7u//bolvqzV6V6nzmDNPV5wu0C3ruAGKasKw7pGhs/+9CbfGjJf 5Ls1yxZGUx74XKayAXEl8zmuz9eY2nx6wCK1PCKhwAEGow4IG03guhYuhT7HpwX+ieEL j8/tL3IazqWTgQwvgvNkb80DVCnj4tl2Rle1qLHcshHEZHeqP/h3pxyBpstgV6DcexIN xvDdAkPDlJnMVOHYv75PyZDtBkrkXXOgQlzTKxX7mDMgRWFyvU6Ietq7MSIdLtnhRxQ8 3MqZP223SP5QR738b/WSRSEp0y91aZng30D8g+e5io8OA2CzZHj3J5u5iTUe1+FyS6w+ 8FnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version; bh=4XoVfC9xFl1utiQR/0Z9FxzmWijbTYASyvpir0lmcRc=; b=Cz2z1V1h0phZvu5sOvhUAUTPv3SG8EInbPOS8zYjlx0m3lL29tnJlgRM9FJ4p6NFYl ygQubaT1IdrpIpeRoKjWxR7jc3U43ga3Ug5YH5OfOGEf2LkD43atAUxQyiY9mmf12Nfb +bxn7dTGDFr8uFR//u+IaCntNRsYDw5Whg/kGzV6ZQzkrthAGCORTGyQ81KShLmWfyTR ZQsSeNUUgBxLWe1/2CLUWts7dmktSK5RIlvLaoDt+LrNGJ/XDWdaJjQTrdPCerPj1omI G8sp8M6DmJu6p3T9tcAw1GzhoeCr6kwcjnXsIapvxKZdxizeXOEmopHCGs34a/NK+bbo Ov5w== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t18si3098677plr.50.2019.02.14.10.28.42; Thu, 14 Feb 2019 10:28:58 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2395487AbfBNK7E (ORCPT + 99 others); Thu, 14 Feb 2019 05:59:04 -0500 Received: from mail-ot1-f66.google.com ([209.85.210.66]:45576 "EHLO mail-ot1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730148AbfBNK7D (ORCPT ); Thu, 14 Feb 2019 05:59:03 -0500 Received: by mail-ot1-f66.google.com with SMTP id 32so9698514ota.12; Thu, 14 Feb 2019 02:59:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4XoVfC9xFl1utiQR/0Z9FxzmWijbTYASyvpir0lmcRc=; b=dmQC0GKYWJYHwMpRfeclbtSK5ySD95GXETFNTPmq6PVr1f476HvRNM9YwW1rgdSTo+ GtGHMk+o13AKKWzB0VrG0Vw/VXZnIL2JVWcdwqT14aGCYvN8nMokKQIw+CL9SawT9r3W PbuvKreIbshqHQPas1OcvaxqLG6RGGu82uM8iWfww0ue1hAMZPjR9ceMA4KQDOthJ9r/ lSfnyG7i8wMwyQWGNqyoR3OnumalMvIlPE4cDqWMylpCUjgVTBTUySHP/Y3Nlevibze3 YTwvfbzg+sEJb1a3THi96+N1KywzEETcfq8YgSO5yzc4iYXq4dZNbA/86pLUQ4OdyplX VY4w== X-Gm-Message-State: AHQUAubqPBIo0YcSXlm9DJj/vlnXDuz69j3l3Tuj+3GJ0OqORqCzqS7P SS2tuDucwst1DxUmvDisFOqxSz5A1RAYm6jAxPQ= X-Received: by 2002:aca:f4d3:: with SMTP id s202mr1911937oih.178.1550141942347; Thu, 14 Feb 2019 02:59:02 -0800 (PST) MIME-Version: 1.0 References: <1550130368-60513-1-git-send-email-wangxiongfeng2@huawei.com> <1550130368-60513-3-git-send-email-wangxiongfeng2@huawei.com> In-Reply-To: <1550130368-60513-3-git-send-email-wangxiongfeng2@huawei.com> From: "Rafael J. Wysocki" Date: Thu, 14 Feb 2019 11:58:51 +0100 Message-ID: Subject: Re: [PATCH v2 2/2] cpufreq / cppc: Work around for Hisilicon CPPC cpufreq To: Xiongfeng Wang Cc: Viresh Kumar , "Rafael J. Wysocki" , gcherianv@gmail.com, Prashanth Prakash , George Cherian , Robert Moore , ACPI Devel Maling List , Linux Kernel Mailing List , Hanjun Guo , John Garry Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. > + > 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; > --