From: Dmitry Osipenko <digetx@gmail.com>
To: Chanwoo Choi <cw00.choi@samsung.com>,
Thierry Reding <thierry.reding@gmail.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
MyungJoo Ham <myungjoo.ham@samsung.com>,
Kyungmin Park <kyungmin.park@samsung.com>,
Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-pm@vger.kernel.org
Subject: Re: [PATCH v2 19/19] PM / devfreq: Introduce driver for NVIDIA Tegra20
Date: Wed, 17 Apr 2019 12:36:35 +0300 [thread overview]
Message-ID: <8a1fdb48-32cd-98a2-65f2-02330b554701@gmail.com> (raw)
In-Reply-To: <64324c9c-b5db-86ac-f97e-6c76049dcdc8@samsung.com>
17.04.2019 3:26, Chanwoo Choi пишет:
> Hi,
>
> On 19. 4. 17. 오전 1:11, Dmitry Osipenko wrote:
>> 16.04.2019 11:31, Chanwoo Choi пишет:
>>> Hi,
>>>
>>> On 19. 4. 15. 오후 11:55, Dmitry Osipenko wrote:
>>>> Add devfreq driver for NVIDIA Tegra20 SoC's. The driver periodically
>>>> reads out Memory Controller counters and adjusts memory frequency based
>>>> on the memory clients activity.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>> MAINTAINERS | 8 ++
>>>> drivers/devfreq/Kconfig | 10 ++
>>>> drivers/devfreq/Makefile | 1 +
>>>> drivers/devfreq/tegra20-devfreq.c | 177 ++++++++++++++++++++++++++++++
>>>> 4 files changed, 196 insertions(+)
>>>> create mode 100644 drivers/devfreq/tegra20-devfreq.c
>>>>
>>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>>> index 80b59db1b6e4..91f475ec4545 100644
>>>> --- a/MAINTAINERS
>>>> +++ b/MAINTAINERS
>>>> @@ -10056,6 +10056,14 @@ F: include/linux/memblock.h
>>>> F: mm/memblock.c
>>>> F: Documentation/core-api/boot-time-mm.rst
>>>>
>>>> +MEMORY FREQUENCY SCALING DRIVER FOR NVIDIA TEGRA20
>>>> +M: Dmitry Osipenko <digetx@gmail.com>
>>>> +L: linux-pm@vger.kernel.org
>>>> +L: linux-tegra@vger.kernel.org
>>>> +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
>>>> +S: Maintained
>>>> +F: drivers/devfreq/tegra20-devfreq.c
>>>> +
>>>> MEMORY MANAGEMENT
>>>> L: linux-mm@kvack.org
>>>> W: http://www.linux-mm.org
>>>> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
>>>> index bd6652863e7d..af4c86c4e0f6 100644
>>>> --- a/drivers/devfreq/Kconfig
>>>> +++ b/drivers/devfreq/Kconfig
>>>> @@ -100,6 +100,16 @@ config ARM_TEGRA_DEVFREQ
>>>> It reads ACTMON counters of memory controllers and adjusts the
>>>> operating frequencies and voltages with OPP support.
>>>>
>>>> +config ARM_TEGRA20_DEVFREQ
>>>> + tristate "NVIDIA Tegra20 DEVFREQ Driver"
>>>> + depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST
>>>> + select DEVFREQ_GOV_SIMPLE_ONDEMAND
>>>> + select PM_OPP
>>>> + help
>>>> + This adds the DEVFREQ driver for the Tegra20 family of SoCs.
>>>> + It reads Memory Controller counters and adjusts the operating
>>>> + frequencies and voltages with OPP support.
>>>> +
>>>> config ARM_RK3399_DMC_DEVFREQ
>>>> tristate "ARM RK3399 DMC DEVFREQ Driver"
>>>> depends on ARCH_ROCKCHIP
>>>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>>>> index 32b8d4d3f12c..6fcc5596b8b7 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_RK3399_DMC_DEVFREQ) += rk3399_dmc.o
>>>> obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra-devfreq.o
>>>> +obj-$(CONFIG_ARM_TEGRA20_DEVFREQ) += tegra20-devfreq.o
>>>>
>>>> # DEVFREQ Event Drivers
>>>> obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
>>>> diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
>>>> new file mode 100644
>>>> index 000000000000..18c9aad7a9d7
>>>> --- /dev/null
>>>> +++ b/drivers/devfreq/tegra20-devfreq.c
>>>> @@ -0,0 +1,177 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +/*
>>>> + * NVIDIA Tegra20 devfreq driver
>>>> + *
>>>> + * Author: Dmitry Osipenko <digetx@gmail.com>
>>>> + */
>>>
>>> It doesn't any "Copyright (c) 2019 ..." sentence.
>>
>> I'll add one in v3.
>>
>>>> +
>>>> +#include <linux/clk.h>
>>>> +#include <linux/devfreq.h>
>>>> +#include <linux/io.h>
>>>> +#include <linux/kernel.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/of_device.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/pm_opp.h>
>>>> +#include <linux/slab.h>
>>>> +
>>>> +#include <soc/tegra/mc.h>
>>>
>>> I can find the '<soc/tegra/mc.h>' header file
>>> on mainline branch. But mc.h is included in linux-next.git.
>>>
>>> If you don't share the patch related to mc.h,
>>> the kernel build will be failed when apply it the devfreq.git
>>> on final step. Actually, it should make the immutable branch
>>> between two related maintainers in order to remove the build fail.
>>
>> The '<soc/tegra/mc.h>' header file exists since v3.18 [0], seems you just missed something.
>>
>> [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/soc/tegra/mc.h?h=v3.18&id=8918465163171322c77a19d5258a95f56d89d2e4
>
> Sorry. It is my missing point. When I tried to find it,
> it is included in the mainline kernel.
>
>>
>>>> +
>>>> +#include "governor.h"
>>>> +
>>>> +#define MC_STAT_CONTROL 0x90
>>>> +#define MC_STAT_EMC_CLOCK_LIMIT 0xa0
>>>> +#define MC_STAT_EMC_CLOCKS 0xa4
>>>> +#define MC_STAT_EMC_CONTROL 0xa8
>>>> +#define MC_STAT_EMC_COUNT 0xb8
>>>> +
>>>> +#define EMC_GATHER_CLEAR (1 << 8)
>>>> +#define EMC_GATHER_ENABLE (3 << 8)
>>>> +
>>>> +struct tegra_devfreq {
>>>> + struct devfreq *devfreq;
>>>> + struct clk *clk;
>>>> + void __iomem *regs;
>>>> +};
>>>> +
>>>> +static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>>>> + u32 flags)
>>>> +{
>>>> + struct tegra_devfreq *tegra = dev_get_drvdata(dev);
>>>> + struct dev_pm_opp *opp;
>>>> + unsigned long rate;
>>>> + int err;
>>>> +
>>>> + opp = devfreq_recommended_opp(dev, freq, flags);
>>>> + if (IS_ERR(opp))
>>>> + return PTR_ERR(opp);
>>>> +
>>>> + rate = dev_pm_opp_get_freq(opp);
>>>> + dev_pm_opp_put(opp);
>>>> +
>>>> + err = clk_set_min_rate(tegra->clk, rate);
>>>> + if (err)
>>>> + return err;
>>>> +
>>>> + err = clk_set_rate(tegra->clk, 0);
>>>> + if (err)
>>>
>>> When fail happen, I think that you have to control
>>> the restoring sequence for previous operation like clk_set_min_rate().
>>
>> Okay, thanks.
>>
>>>> + return err;
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int tegra_devfreq_get_dev_status(struct device *dev,
>>>> + struct devfreq_dev_status *stat)
>>>> +{
>>>> + struct tegra_devfreq *tegra = dev_get_drvdata(dev);
>>>> +
>>>> + stat->busy_time = readl_relaxed(tegra->regs + MC_STAT_EMC_COUNT);
>>>> + stat->total_time = readl_relaxed(tegra->regs + MC_STAT_EMC_CLOCKS) / 8;
>>>> + stat->current_frequency = clk_get_rate(tegra->clk);
>>>> +
>>>> + writel_relaxed(EMC_GATHER_CLEAR, tegra->regs + MC_STAT_CONTROL);
>>>> + writel_relaxed(EMC_GATHER_ENABLE, tegra->regs + MC_STAT_CONTROL);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static struct devfreq_dev_profile tegra_devfreq_profile = {
>>>> + .polling_ms = 500,
>>>> + .target = tegra_devfreq_target,
>>>> + .get_dev_status = tegra_devfreq_get_dev_status,
>>>> +};
>>>> +
>>>> +static struct tegra_mc *tegra_get_memory_controller(void)
>>>> +{
>>>> + struct platform_device *pdev;
>>>> + struct device_node *np;
>>>> + struct tegra_mc *mc;
>>>> +
>>>> + np = of_find_compatible_node(NULL, NULL, "nvidia,tegra20-mc-gart");
>>>> + if (!np)
>>>> + return ERR_PTR(-ENOENT);
>>>> +
>>>> + pdev = of_find_device_by_node(np);
>>>> + of_node_put(np);
>>>> + if (!pdev)
>>>> + return ERR_PTR(-ENODEV);
>>>> +
>>>> + mc = platform_get_drvdata(pdev);
>>>> + if (!mc)
>>>> + return ERR_PTR(-EPROBE_DEFER);
>>>> +
>>>> + return mc;
>>>> +}
>>>> +
>>>> +static int tegra_devfeq_probe(struct platform_device *pdev)
>>>> +{
>>>> + struct tegra_devfreq *tegra;
>>>> + struct tegra_mc *mc;
>>>> + unsigned long max_rate;
>>>> + unsigned long rate;
>>>> + int err;
>>>> +
>>>> + mc = tegra_get_memory_controller();
>>>> + if (IS_ERR(mc)) {
>>>> + err = PTR_ERR(mc);
>>>> + dev_err(&pdev->dev, "failed to get mc: %d\n", err);
>>>
>>> How about using 'memory controller' instead of 'mc'?
>>> Because 'mc' is not standard expression.
>>
>> Sounds good, thanks.
>>
>>>> + return err;
>>>> + }
>>>> +
>>>> + tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
>>>> + if (!tegra)
>>>> + return -ENOMEM;
>>>> +
>>>> + tegra->clk = devm_clk_get(&pdev->dev, "emc");
>>>> + if (IS_ERR(tegra->clk)) {
>>>> + err = PTR_ERR(tegra->clk);
>>>> + dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
>>>> + return err;
>>>> + }
>>>
>>> Don't you need to enable the 'emc' clock'?
>>> Because this patch doesn't enable this clock.
>>
>> EMC is a system critical clock (marked as critical by the clock driver), it is guaranteed to be always enabled. I think it is fine to omit clock-enabling in this case.
>
> If you think don't need to enable it due to the critical clock,
> instead, please add the comment about that emc clock is critical.
> In my case, it looks like the strange use-case because this driver
> doesn't contain the any enable code for clock.
Okay, thank you for the review again.
[snip]
prev parent reply other threads:[~2019-04-17 9:38 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-15 14:54 [PATCH v2 00/19] NVIDIA Tegra devfreq improvements and Tegra20/30 support Dmitry Osipenko
2019-04-15 14:54 ` [PATCH v2 01/19] PM / devfreq: tegra: Fix kHz to Hz conversion Dmitry Osipenko
2019-04-16 1:45 ` Chanwoo Choi
2019-04-16 13:24 ` Dmitry Osipenko
2019-04-15 14:54 ` [PATCH v2 02/19] PM / devfreq: tegra: Replace readl-writel with relaxed versions Dmitry Osipenko
2019-04-17 1:02 ` Chanwoo Choi
2019-04-15 14:54 ` [PATCH v2 03/19] PM / devfreq: tegra: Don't ignore clk errors Dmitry Osipenko
2019-04-16 1:52 ` Chanwoo Choi
2019-04-16 13:42 ` Dmitry Osipenko
2019-04-15 14:54 ` [PATCH v2 04/19] PM / devfreq: tegra: Don't set EMC clock rate to maximum on probe Dmitry Osipenko
2019-04-16 1:59 ` Chanwoo Choi
2019-04-16 13:44 ` Dmitry Osipenko
2019-04-15 14:54 ` [PATCH v2 05/19] PM / devfreq: tegra: Replace write memory barrier with the read barrier Dmitry Osipenko
2019-04-16 8:00 ` Chanwoo Choi
2019-04-16 13:57 ` Dmitry Osipenko
2019-04-17 0:55 ` Chanwoo Choi
2019-04-15 14:54 ` [PATCH v2 06/19] PM / devfreq: tegra: Fix missed error checking on devfreq initialization failure Dmitry Osipenko
2019-04-16 2:32 ` Chanwoo Choi
2019-04-16 14:29 ` Dmitry Osipenko
2019-04-17 1:01 ` Chanwoo Choi
2019-04-15 14:54 ` [PATCH v2 07/19] PM / devfreq: tegra: Register clk notifier in the end of driver's probe Dmitry Osipenko
2019-04-15 14:54 ` [PATCH v2 08/19] PM / devfreq: tegra: Remove OPP entries on driver removal Dmitry Osipenko
2019-04-15 14:54 ` [PATCH v2 09/19] PM / devfreq: tegra: Change interrupt request order Dmitry Osipenko
2019-04-15 14:54 ` [PATCH v2 10/19] PM / devfreq: tegra: Drop primary interrupt handler Dmitry Osipenko
2019-04-16 5:56 ` Chanwoo Choi
2019-04-16 15:23 ` Dmitry Osipenko
2019-04-17 0:31 ` Chanwoo Choi
2019-04-15 14:54 ` [PATCH v2 11/19] PM / devfreq: tegra: De-initialize properly on driver's probe error Dmitry Osipenko
2019-04-16 6:21 ` Chanwoo Choi
2019-04-15 14:54 ` [PATCH v2 12/19] PM / devfreq: tegra: Avoid inconsistency of current frequency value Dmitry Osipenko
2019-04-16 7:15 ` Chanwoo Choi
2019-04-16 15:40 ` Dmitry Osipenko
2019-04-17 0:35 ` Chanwoo Choi
2019-04-15 14:54 ` [PATCH v2 13/19] PM / devfreq: tegra: Mark ACTMON's governor as immutable Dmitry Osipenko
2019-04-16 7:17 ` Chanwoo Choi
2019-04-15 14:55 ` [PATCH v2 14/19] PM / devfreq: tegra: Move governor registration to driver's probe Dmitry Osipenko
2019-04-16 7:30 ` Chanwoo Choi
2019-04-15 14:55 ` [PATCH v2 15/19] PM / devfreq: tegra: Synchronize IRQ after masking it in hardware Dmitry Osipenko
2019-04-16 7:41 ` Chanwoo Choi
2019-04-16 15:42 ` Dmitry Osipenko
2019-04-15 14:55 ` [PATCH v2 16/19] PM / devfreq: tegra: Reconfigure hardware on governor's restart Dmitry Osipenko
2019-04-15 14:55 ` [PATCH v2 17/19] PM / devfreq: tegra: Support Tegra30 Dmitry Osipenko
2019-04-16 7:48 ` Chanwoo Choi
2019-04-16 15:49 ` Dmitry Osipenko
2019-04-17 0:28 ` Chanwoo Choi
2019-04-15 14:55 ` [PATCH v2 18/19] PM / devfreq: tegra: Enable COMPILE_TEST for the driver Dmitry Osipenko
2019-04-16 7:43 ` Chanwoo Choi
2019-04-16 15:52 ` Dmitry Osipenko
2019-04-17 0:27 ` Chanwoo Choi
2019-04-15 14:55 ` [PATCH v2 19/19] PM / devfreq: Introduce driver for NVIDIA Tegra20 Dmitry Osipenko
2019-04-16 8:31 ` Chanwoo Choi
2019-04-16 16:11 ` Dmitry Osipenko
2019-04-17 0:26 ` Chanwoo Choi
2019-04-17 9:36 ` Dmitry Osipenko [this message]
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=8a1fdb48-32cd-98a2-65f2-02330b554701@gmail.com \
--to=digetx@gmail.com \
--cc=cw00.choi@samsung.com \
--cc=jonathanh@nvidia.com \
--cc=kyungmin.park@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=myungjoo.ham@samsung.com \
--cc=thierry.reding@gmail.com \
--cc=tomeu.vizoso@collabora.com \
/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
all inboxes | Powered by JetHome®