Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp1396848pxb; Thu, 14 Apr 2022 05:25:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzrKVKGEHKZh2inpEIeuDgNutN9oMV+IuSE5dGAkVtbwlund1Wtt2Tkt9g8rha4HPMJwX+n X-Received: by 2002:a17:902:ce8a:b0:158:7b10:980b with SMTP id f10-20020a170902ce8a00b001587b10980bmr15659418plg.122.1649939110004; Thu, 14 Apr 2022 05:25:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649939109; cv=none; d=google.com; s=arc-20160816; b=prDuyKvTrVCO9KIhsIaAIo0s5MZdIvSzGsOrpuMO16RYP+FGqtDghfogIcpmi2qinx B/8yVA391TkmJBe7WjXBMXvOWzLWF1Zz+EClq9+tqWvSdlAR+Gb7svAwzfa/accklcx8 hYTL/dRyHAqWehjxuPkw0cP1NdkAjZitbTJJaGoQ5VCHZc3wvOtDKK8G3Sn45D22EtcD MFzpTxDQEQ2fUAPjSlWd9SjqFo/sFT/0bZ4UdeHpJheuIqL5rIiC+ZbsUoy9JS4AqjXQ jQmcxadkobwlvIp8GgZFn0Pdn2dcw0hqwNurAQTqGo8dJ+4Zywu0BuhwePfbeyiDmoAB VPgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:date:cc:to:from:subject:message-id; bh=/2dTsyQnxBe5NifK8GnrpLIREzjjtBuKwEv6AQSR9mw=; b=xF5kg8165654W9dmM5vob9OqsXv3Sb8RCT1F9Jn+jXrSc3Rbj+2cV8f3k3JGppKm3H VG6zv9kTgGiO7Ui1o26Ox03CUNpjOA+Sonbu5vMbqgTkKyun02OMOx9bEy3lQEZ9EBDj puxwYGGKbJ7/Txs28Xi1nR/UAy82/kp4zwCsPEnU0KyEXFKdPlDlqW2er/SNL7aqvTw9 ADwdKsyOzfsv6VnhmiKRuj8XswNQy02QF67iyv6akdgCc6oj40V0HSKYxGPJlliQV6Cw y0BxPpGArknf4H+85BQMWz91Z4S4eciduAAG90BsNZJ+dM+igMK+8gzPNfYPIbqZdVt/ 5lfg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x13-20020a1709027c0d00b00154319ca2ddsi15722031pll.397.2022.04.14.05.24.56; Thu, 14 Apr 2022 05:25:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238283AbiDNFWD (ORCPT + 99 others); Thu, 14 Apr 2022 01:22:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232614AbiDNFWC (ORCPT ); Thu, 14 Apr 2022 01:22:02 -0400 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 302A2CE1; Wed, 13 Apr 2022 22:19:32 -0700 (PDT) X-UUID: abb50882470341829025300df91289dd-20220414 X-UUID: abb50882470341829025300df91289dd-20220414 Received: from mtkcas11.mediatek.inc [(172.21.101.40)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1264350114; Thu, 14 Apr 2022 13:19:26 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 14 Apr 2022 13:19:25 +0800 Received: from mtksdccf07 (172.21.84.99) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 14 Apr 2022 13:19:25 +0800 Message-ID: Subject: Re: [PATCH v2 2/2] PM / devfreq: mediatek: Introduce MediaTek CCI devfreq driver From: Johnson Wang To: AngeloGioacchino Del Regno , , , , CC: , , , , , , , Date: Thu, 14 Apr 2022 13:19:25 +0800 In-Reply-To: <7dde78c6-efc6-cc67-19ac-28f8640c2c8c@collabora.com> References: <20220408052150.22536-1-johnson.wang@mediatek.com> <20220408052150.22536-3-johnson.wang@mediatek.com> <7dde78c6-efc6-cc67-19ac-28f8640c2c8c@collabora.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.28.5-0ubuntu0.18.04.2 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-MTK: N X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 2022-04-08 at 13:51 +0200, AngeloGioacchino Del Regno wrote: > Il 08/04/22 07:21, Johnson Wang ha scritto: > > We introduce a devfreq driver for the MediaTek Cache Coherent > > Interconnect > > (CCI) used by some MediaTek SoCs. > > > > In this driver, we use the passive devfreq driver to get target > > frequencies > > and adjust voltages accordingly. In MT8183 and MT8186, the MediaTek > > CCI > > is supplied by the same regulators with the little core CPUs. > > > > Signed-off-by: Johnson Wang > > Signed-off-by: Jia-Wei Chang > > --- > > This patch depends on "devfreq-testing"[1]. > > [1] > > https://urldefense.com/v3/__https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git/log/?h=devfreq-testing__;!!CTRNKA9wMg0ARbw!zNCF7FI5uFmzlA1V1-Pp8ht2HtUk8_oRRDoqzzBcXm0Mo8JOOoVbPPqa5xg4WuYPnKNF$ > > > > --- > > drivers/devfreq/Kconfig | 10 + > > drivers/devfreq/Makefile | 1 + > > drivers/devfreq/mtk-cci-devfreq.c | 479 > > ++++++++++++++++++++++++++++++ > > 3 files changed, 490 insertions(+) > > create mode 100644 drivers/devfreq/mtk-cci-devfreq.c > > > > diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig > > index 87eb2b837e68..d985597f343f 100644 > > --- a/drivers/devfreq/Kconfig > > +++ b/drivers/devfreq/Kconfig > > @@ -120,6 +120,16 @@ config ARM_TEGRA_DEVFREQ > > It reads ACTMON counters of memory controllers and adjusts > > the > > operating frequencies and voltages with OPP support. > > > > +config ARM_MEDIATEK_CCI_DEVFREQ > > + tristate "MEDIATEK CCI DEVFREQ Driver" > > + depends on ARM_MEDIATEK_CPUFREQ > > + select DEVFREQ_GOV_PASSIVE > > + help > > + This adds a devfreq driver for MediaTek Cache Coherent > > Interconnect > > + which is shared the same regulators with the cpu cluster. It > > can track > > + buck voltages and update a proper CCI frequency. Use the > > notification > > + to get the regulator status. > > + > > config ARM_RK3399_DMC_DEVFREQ > > tristate "ARM RK3399 DMC DEVFREQ Driver" > > depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \ > > diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile > > index 0b6be92a25d9..bf40d04928d0 100644 > > --- a/drivers/devfreq/Makefile > > +++ b/drivers/devfreq/Makefile > > @@ -11,6 +11,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += > > governor_passive.o > > obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o > > obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o > > obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o > > +obj-$(CONFIG_ARM_MEDIATEK_CCI_DEVFREQ) += mtk-cci-devfreq.o > > obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o > > obj-$(CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ) += sun8i-a33-mbus.o > > obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o > > diff --git a/drivers/devfreq/mtk-cci-devfreq.c > > b/drivers/devfreq/mtk-cci-devfreq.c > > new file mode 100644 > > index 000000000000..53a28e2c88bd > > --- /dev/null > > +++ b/drivers/devfreq/mtk-cci-devfreq.c > > @@ -0,0 +1,479 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright (C) 2022 MediaTek Inc. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +struct mtk_ccifreq_platform_data { > > + int min_volt_shift; > > + int max_volt_shift; > > + int proc_max_volt; > > + int sram_min_volt; > > + int sram_max_volt; > > +}; > > + > > +struct mtk_ccifreq_drv { > > + struct device *cci_dev; > > + struct devfreq *devfreq; > > + struct regulator *proc_reg; > > + struct regulator *sram_reg; > > + struct clk *cci_clk; > > + struct clk *inter_clk; > > + int inter_voltage; > > + int old_voltage; > > + unsigned long old_freq; > > + bool need_voltage_tracking; > > + /* Avoid race condition for regulators between notify and > > policy */ > > + struct mutex reg_lock; > > + struct notifier_block opp_nb; > > + const struct mtk_ccifreq_platform_data *soc_data; > > +}; > > + > > +static int mtk_ccifreq_voltage_tracking(struct mtk_ccifreq_drv > > *drv, > > + int new_voltage) > > +{ > > + const struct mtk_ccifreq_platform_data *soc_data = drv- > > >soc_data; > > + struct device *dev = drv->cci_dev; > > + struct regulator *proc_reg = drv->proc_reg; > > + struct regulator *sram_reg = drv->sram_reg; > > + int old_voltage, old_vsram, new_vsram, vsram, voltage, ret; > > + > > + old_voltage = regulator_get_voltage(proc_reg); > > + if (old_voltage < 0) { > > + dev_err(dev, "invalid vproc value: %d\n", old_voltage); > > + return old_voltage; > > + } > > + > > + old_vsram = regulator_get_voltage(sram_reg); > > + if (old_vsram < 0) { > > + dev_err(dev, "invalid vsram value: %d\n", old_vsram); > > + return old_vsram; > > + } > > + > > + new_vsram = clamp(new_voltage + soc_data->min_volt_shift, > > + soc_data->sram_min_volt, soc_data- > > >sram_max_volt); > > + > > + do { > > + if (old_voltage <= new_voltage) { > > + vsram = clamp(old_voltage + soc_data- > > >max_volt_shift, > > + soc_data->sram_min_volt, > > new_vsram); > > + ret = regulator_set_voltage(sram_reg, vsram, > > + soc_data- > > >sram_max_volt); > > + if (ret) > > + return ret; > > + > > + if (vsram == soc_data->sram_max_volt || > > + new_vsram == soc_data->sram_min_volt) > > + voltage = new_voltage; > > + else > > + voltage = vsram - soc_data- > > >min_volt_shift; > > + > > + ret = regulator_set_voltage(proc_reg, voltage, > > + soc_data- > > >proc_max_volt); > > + if (ret) { > > + regulator_set_voltage(sram_reg, > > old_vsram, > > + soc_data- > > >sram_max_volt); > > + return ret; > > + } > > + } else if (old_voltage > new_voltage) { > > + voltage = max(new_voltage, > > + old_vsram - soc_data- > > >max_volt_shift); > > + ret = regulator_set_voltage(proc_reg, voltage, > > + soc_data- > > >proc_max_volt); > > + if (ret) > > + return ret; > > + > > + if (voltage == new_voltage) > > + vsram = new_vsram; > > + else > > + vsram = max(new_vsram, > > + voltage + soc_data- > > >min_volt_shift); > > + > > + ret = regulator_set_voltage(sram_reg, vsram, > > + soc_data- > > >sram_max_volt); > > + if (ret) { > > + regulator_set_voltage(proc_reg, > > old_voltage, > > + soc_data- > > >proc_max_volt); > > + return ret; > > + } > > + } > > + > > + old_voltage = voltage; > > + old_vsram = vsram; > > + } while (voltage != new_voltage || vsram != new_vsram); > > Hello Johnson, > > are you extremely sure that there will *always* be a way out of this > while loop? > > For safety purposes, I would set an iteration limit in order to avoid > getting > an infinite loop here. > Probably, something like twice or thrice the expected number of > iterations will > also be fine. > > P.S.: Krzysztof's review also contains exactly all the rest of what I > would > also say here (thanks!). > > Regards, > Angelo Hello Angelo, Thanks for your suggestion! Actually, we are going to add an iteration limit inside the while loop. BRs, Johnson Wang