From: andrew-sh.cheng <andrew-sh.cheng@mediatek.com>
To: Guenter Roeck <linux@roeck-us.net>
Cc: Mark Rutland <mark.rutland@arm.com>,
devicetree@vger.kernel.org, srv_heupstream@mediatek.com,
linux-pm@vger.kernel.org, Viresh Kumar <viresh.kumar@linaro.org>,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
linux-kernel@vger.kernel.org,
Chanwoo Choi <cw00.choi@samsung.com>,
Kyungmin Park <kyungmin.park@samsung.com>,
Rob Herring <robh+dt@kernel.org>,
linux-mediatek@lists.infradead.org,
MyungJoo Ham <myungjoo.ham@samsung.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
fan.chen@mediatek.com, linux-arm-kernel@lists.infradead.org
Subject: Re: [v2,4/4] devfreq: add mediatek cci devfreq
Date: Sat, 13 Apr 2019 15:07:24 +0800 [thread overview]
Message-ID: <1555139244.22373.2.camel@mtksdaap41> (raw)
In-Reply-To: <20190408172220.GA28972@roeck-us.net>
On Mon, 2019-04-08 at 10:22 -0700, Guenter Roeck wrote:
> On Fri, Mar 29, 2019 at 02:46:12PM +0800, Andrew-sh Cheng wrote:
> > This adds a devfreq driver for the Cache Coherent Interconnect (CCI)
> > of the Mediatek MT8183.
> >
> > On the MT8183 the CCI is supplied by the same regulator as the LITTLE
> > cores. The driver is notified when the regulator voltage changes
> > (driven by cpufreq) and adjusts the CCI frequency to the maximum
> > possible value.
> >
> > Signed-off-by: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
> > ---
> > drivers/devfreq/Kconfig | 10 ++
> > drivers/devfreq/Makefile | 1 +
> > drivers/devfreq/mt8183-cci-devfreq.c | 235 +++++++++++++++++++++++++++++++++++
> > 3 files changed, 246 insertions(+)
> > create mode 100644 drivers/devfreq/mt8183-cci-devfreq.c
> >
> > diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> > index 6a172d3..da2f8ec 100644
> > --- a/drivers/devfreq/Kconfig
> > +++ b/drivers/devfreq/Kconfig
> > @@ -91,6 +91,16 @@ config ARM_EXYNOS_BUS_DEVFREQ
> > and adjusts the operating frequencies and voltages with OPP support.
> > This does not yet operate with optimal voltages.
> >
> > +config ARM_MT8183_CCI_DEVFREQ
> > + tristate "MT8183 CCI DEVFREQ Driver"
> > + depends on ARM_MEDIATEK_CPUFREQ
> > + help
> > + This adds a devfreq driver for Cache Coherent Interconnect
> > + of Mediatek MT8183, which is shared the same regulator
> > + with cpu cluster.
> > + It can track buck voltage and update a proper cci frequency.
> > + Use notification to get regulator status.
> > +
> > config ARM_TEGRA_DEVFREQ
> > tristate "Tegra DEVFREQ Driver"
> > depends on ARCH_TEGRA_124_SOC
> > diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
> > index 32b8d4d..817dde7 100644
> > --- a/drivers/devfreq/Makefile
> > +++ b/drivers/devfreq/Makefile
> > @@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o
> >
> > # DEVFREQ Drivers
> > obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o
> > +obj-$(CONFIG_ARM_MT8183_CCI_DEVFREQ) += mt8183-cci-devfreq.o
> > obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o
> > obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra-devfreq.o
> >
> > diff --git a/drivers/devfreq/mt8183-cci-devfreq.c b/drivers/devfreq/mt8183-cci-devfreq.c
> > new file mode 100644
> > index 0000000..af82d2e
> > --- /dev/null
> > +++ b/drivers/devfreq/mt8183-cci-devfreq.c
> > @@ -0,0 +1,235 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019 MediaTek Inc.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/devfreq.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regulator/consumer.h>
> > +
> > +#include "governor.h"
> > +
> > +struct cci_devfreq {
> > + struct devfreq *devfreq;
> > + struct regulator *proc_reg;
> > + unsigned long proc_reg_uV;
> > + struct clk *cci_clk;
> > + struct notifier_block nb;
> > +};
> > +
> > +static int cci_devfreq_regulator_notifier(struct notifier_block *nb,
> > + unsigned long val, void *data)
> > +{
> > + struct cci_devfreq *cci_df =
> > + container_of(nb, struct cci_devfreq, nb);
> > +
> > + /* deal with reduce frequency */
> > + if (val & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) {
> > + struct pre_voltage_change_data *pvc_data = data;
> > +
> > + if (pvc_data->min_uV < pvc_data->old_uV) {
> > + cci_df->proc_reg_uV =
> > + (unsigned long)(pvc_data->min_uV);
> > + mutex_lock(&cci_df->devfreq->lock);
> > + update_devfreq(cci_df->devfreq);
> > + mutex_unlock(&cci_df->devfreq->lock);
> > + }
> > + }
> > +
> > + if ((val & REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE) &&
> > + ((unsigned long)data > cci_df->proc_reg_uV)) {
> > + cci_df->proc_reg_uV = (unsigned long)data;
> > + mutex_lock(&cci_df->devfreq->lock);
> > + update_devfreq(cci_df->devfreq);
> > + mutex_unlock(&cci_df->devfreq->lock);
> > + }
> > +
> > + /* deal with increase frequency */
> > + if ((val & REGULATOR_EVENT_VOLTAGE_CHANGE) &&
> > + (cci_df->proc_reg_uV < (unsigned long)data)) {
> > + cci_df->proc_reg_uV = (unsigned long)data;
> > + mutex_lock(&cci_df->devfreq->lock);
> > + update_devfreq(cci_df->devfreq);
> > + mutex_unlock(&cci_df->devfreq->lock);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_cci_governor_get_target(struct devfreq *devfreq,
> > + unsigned long *freq)
> > +{
> > + struct cci_devfreq *cci_df;
> > + struct dev_pm_opp *opp;
> > +
> > + cci_df = dev_get_drvdata(devfreq->dev.parent);
> > +
> > + /* find available frequency */
> > + opp = dev_pm_opp_find_max_freq_by_volt(devfreq->dev.parent,
> > + cci_df->proc_reg_uV);
> > + *freq = dev_pm_opp_get_freq(opp);
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_cci_governor_event_handler(struct devfreq *devfreq,
> > + unsigned int event, void *data)
> > +{
> > + struct cci_devfreq *cci_df;
> > + struct notifier_block *nb;
> > +
> > + cci_df = dev_get_drvdata(devfreq->dev.parent);
> > + nb = &cci_df->nb;
> > +
> > + switch (event) {
> > + case DEVFREQ_GOV_START:
> > + case DEVFREQ_GOV_RESUME:
> > + nb->notifier_call = cci_devfreq_regulator_notifier;
> > + regulator_register_notifier(cci_df->proc_reg,
> > + nb);
> > + break;
> > +
> > + case DEVFREQ_GOV_STOP:
> > + case DEVFREQ_GOV_SUSPEND:
> > + regulator_unregister_notifier(cci_df->proc_reg,
> > + nb);
> > +
> > + break;
> > +
> > + default:
> > + break;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static struct devfreq_governor mtk_cci_devfreq_governor = {
> > + .name = "mtk_cci_vmon",
> > + .get_target_freq = mtk_cci_governor_get_target,
> > + .event_handler = mtk_cci_governor_event_handler,
> > +};
> > +
> > +static int mtk_cci_devfreq_target(struct device *dev, unsigned long *freq,
> > + u32 flags)
> > +{
> > + struct cci_devfreq *cci_df = dev_get_drvdata(dev);
> > +
> > + if (!cci_df)
> > + return -EINVAL;
> > +
> > + clk_set_rate(cci_df->cci_clk, *freq);
> > +
> > + return 0;
> > +}
> > +
> > +static struct devfreq_dev_profile cci_devfreq_profile = {
> > + .target = mtk_cci_devfreq_target,
> > +};
> > +
> > +static int mtk_cci_devfreq_probe(struct platform_device *pdev)
> > +{
> > + struct device *cci_dev = &pdev->dev;
> > + struct cci_devfreq *cci_df;
> > + int ret;
> > +
> > + cci_df = devm_kzalloc(cci_dev, sizeof(*cci_df), GFP_KERNEL);
> > + if (!cci_df)
> > + return -ENOMEM;
> > +
> > + cci_df->cci_clk = clk_get(cci_dev, "cci_clock");
>
> Should use devm_clk_get().
I will change it on next patch.
>
> > + ret = PTR_ERR_OR_ZERO(cci_df->cci_clk);
> > + if (ret) {
> > + if (ret != -EPROBE_DEFER)
> > + dev_err(cci_dev, "failed to get clock for CCI: %d\n",
> > + ret);
> > +
> > + return ret;
> > + }
> > +
> > + cci_df->proc_reg = regulator_get_optional(cci_dev, "proc");
>
> Should use devm_regulator_get_optional().
I will change it on next patch.
>
> > + ret = PTR_ERR_OR_ZERO(cci_df->proc_reg);
> > + if (ret) {
> > + if (ret != -EPROBE_DEFER)
> > + dev_err(cci_dev, "failed to get regulator for CCI: %d\n",
> > + ret);
> > +
> > + goto err_put_clk;
> > + }
> > +
> > + ret = dev_pm_opp_of_add_table(&pdev->dev);
> > + if (ret) {
> > + dev_err(cci_dev, "Fail to init CCI OPP table\n");
>
> No error code display here ? Not that it really matters, but it is
> inconsistent with the other error messages.
I will add it on next patch.
>
> > + goto err_put_reg;
> > + }
> > +
> > + platform_set_drvdata(pdev, cci_df);
> > +
> > + cci_df->devfreq = devm_devfreq_add_device(cci_dev,
> > + &cci_devfreq_profile,
> > + "mtk_cci_vmon",
> > + NULL);
> > + if (IS_ERR(cci_df->devfreq)) {
>
> ret = PTR_ERR(cci_df->devfreq);
>
> > + dev_err(cci_dev, "cannot create cci devfreq device\n", ret);
>
> dev_err(cci_dev, "cannot create cci devfreq device: %d\n", ret);
>
> Something like
> dev_pm_opp_of_remove_table(...);
> seems to be missing here.
I will fix this, and add dev_pm_opp_of_remove_table(...) when error
occur.
>
> > + goto err_put_reg;
> > + }
> > +
> > + return 0;
> > +
> > +err_put_reg:
> > + regulator_put(cci_df->proc_reg);
> > +err_put_clk:
> > + clk_put(cci_df->cci_clk);
>
> Can be dropped when using devm_ functions above.
I will remove these code.
>
> > +
> > + return ret;
> > +}
> > +
> > +static const struct of_device_id mediatek_cci_devfreq_of_match[] = {
> > + { .compatible = "mediatek,mt8183-cci" },
> > + { },
> > +};
> > +MODULE_DEVICE_TABLE(of, mediatek_cci_devfreq_of_match);
> > +
> > +static struct platform_driver cci_devfreq_driver = {
> > + .probe = mtk_cci_devfreq_probe,
> > + .driver = {
> > + .name = "mediatek-cci-devfreq",
> > + .of_match_table = mediatek_cci_devfreq_of_match,
>
> If the driver depends on OF, that should be stated in the Kconfig file.
> Otherwise, of_match_ptr() should be used, and mediatek_cci_devfreq_of_match
> should be tagged with __maybe_unused (or made conditional with #ifdef).
I will fix this on next patch.
>
> > + },
> > +};
> > +
> > +static int __init mtk_cci_devfreq_init(void)
> > +{
> > + int ret;
> > +
> > + ret = devfreq_add_governor(&mtk_cci_devfreq_governor);
> > + if (ret) {
> > + pr_err("%s: failed to add governor: %d\n", __func__, ret);
> > + return ret;
> > + }
> > +
> > + ret = platform_driver_register(&cci_devfreq_driver);
> > + if (ret)
> > + devfreq_remove_governor(&mtk_cci_devfreq_governor);
> > +
> > + return ret;
> > +}
> > +module_init(mtk_cci_devfreq_init)
> > +
> > +static void __exit mtk_cci_devfreq_exit(void)
> > +{
> > + int ret;
> > +
> > + ret = devfreq_remove_governor(&mtk_cci_devfreq_governor);
> > + if (ret)
> > + pr_err("%s: failed to remove governor: %d\n", __func__, ret);
> > +
> > + platform_driver_unregister(&cci_devfreq_driver);
> > +}
> > +module_exit(mtk_cci_devfreq_exit)
> > +
> > +MODULE_DESCRIPTION("Mediatek CCI devfreq driver");
> > +MODULE_AUTHOR("Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>");
> > +MODULE_LICENSE("GPL v2");
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-04-13 7:07 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-29 6:46 [PATCH v2 0/4] Add cpufreq and cci devfreq for mt8183 Andrew-sh.Cheng
2019-03-29 6:46 ` [PATCH v2 1/4] cpufreq: mediatek: add mt8183 cpufreq support Andrew-sh.Cheng
2019-03-31 0:06 ` Nicolas Boichat
2019-04-13 2:33 ` andrew-sh.cheng
2019-03-29 6:46 ` [PATCH v2 2/4] opp: add API which get max freq by voltage Andrew-sh.Cheng
2019-04-03 4:32 ` Nicolas Boichat
2019-04-13 4:39 ` andrew-sh.cheng
2019-04-10 6:29 ` Viresh Kumar
2022-06-02 6:54 ` Viresh Kumar
2019-03-29 6:46 ` [PATCH v2 3/4] dt-bindings: devfreq: add compatible for mt8183 cci devfreq Andrew-sh.Cheng
2019-04-16 9:08 ` Chanwoo Choi
2019-05-08 9:27 ` andrew-sh.cheng
2019-03-29 6:46 ` [PATCH v2 4/4] devfreq: add mediatek " Andrew-sh.Cheng
2019-04-08 17:22 ` [v2,4/4] " Guenter Roeck
2019-04-13 7:07 ` andrew-sh.cheng [this message]
2019-04-16 9:05 ` [PATCH v2 4/4] " Chanwoo Choi
2019-05-10 9:24 ` andrew-sh.cheng
[not found] ` <CGME20190329064632epcas2p4d10ea099bfea4ad682d7312a75bfbe68@epcms1p8>
2019-04-01 2:30 ` [PATCH v2 2/4] opp: add API which get max freq by voltage MyungJoo Ham
2019-04-13 3:36 ` andrew-sh.cheng
[not found] ` <CGME20190329064636epcas1p13633ae078ef83ceda0b8189df1399753@epcms1p1>
2019-04-01 4:18 ` [PATCH v2 4/4] devfreq: add mediatek cci devfreq MyungJoo Ham
2019-04-13 5:54 ` andrew-sh.cheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1555139244.22373.2.camel@mtksdaap41 \
--to=andrew-sh.cheng@mediatek.com \
--cc=cw00.choi@samsung.com \
--cc=devicetree@vger.kernel.org \
--cc=fan.chen@mediatek.com \
--cc=kyungmin.park@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=mark.rutland@arm.com \
--cc=matthias.bgg@gmail.com \
--cc=myungjoo.ham@samsung.com \
--cc=rjw@rjwysocki.net \
--cc=robh+dt@kernel.org \
--cc=srv_heupstream@mediatek.com \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).