[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <594adc1e-4345-33ae-c79f-ad6f00964587@gmail.com>
Date: Sat, 29 Jun 2019 16:28:53 +0300
From: Dmitry Osipenko <digetx@...il.com>
To: Sowjanya Komatineni <skomatineni@...dia.com>,
thierry.reding@...il.com, jonathanh@...dia.com, tglx@...utronix.de,
jason@...edaemon.net, marc.zyngier@....com,
linus.walleij@...aro.org, stefan@...er.ch, mark.rutland@....com
Cc: pdeschrijver@...dia.com, pgaikwad@...dia.com, sboyd@...nel.org,
linux-clk@...r.kernel.org, linux-gpio@...r.kernel.org,
jckuo@...dia.com, josephl@...dia.com, talho@...dia.com,
linux-tegra@...r.kernel.org, linux-kernel@...r.kernel.org,
mperttunen@...dia.com, spatra@...dia.com, robh+dt@...nel.org,
devicetree@...r.kernel.org
Subject: Re: [PATCH V5 08/18] clk: tegra: Add suspend resume support for DFLL
28.06.2019 5:12, Sowjanya Komatineni пишет:
> This patch creates APIs for supporting Tegra210 clock driver to
> perform DFLL suspend and resume operation.
>
> During suspend, DFLL mode is saved and on resume Tegra210 clock driver
> invokes DFLL resume API to re-initialize DFLL to enable target device
> clock in open loop mode or closed loop mode.
>
> Acked-by: Thierry Reding <treding@...dia.com>
> Signed-off-by: Sowjanya Komatineni <skomatineni@...dia.com>
> ---
> drivers/clk/tegra/clk-dfll.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/tegra/clk-dfll.h | 2 ++
> 2 files changed, 80 insertions(+)
>
> diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
> index f8688c2ddf1a..a1f37cf99b00 100644
> --- a/drivers/clk/tegra/clk-dfll.c
> +++ b/drivers/clk/tegra/clk-dfll.c
> @@ -277,6 +277,7 @@ struct tegra_dfll {
> unsigned long dvco_rate_min;
>
> enum dfll_ctrl_mode mode;
> + enum dfll_ctrl_mode resume_mode;
> enum dfll_tune_range tune_range;
> struct dentry *debugfs_dir;
> struct clk_hw dfll_clk_hw;
> @@ -1864,6 +1865,83 @@ static int dfll_fetch_common_params(struct tegra_dfll *td)
> }
>
> /*
> + * tegra_dfll_suspend
> + * @pdev: DFLL instance
> + *
> + * dfll controls clock/voltage to other devices, including CPU. Therefore,
> + * dfll driver pm suspend callback does not stop cl-dvfs operations.
> + */
> +void tegra_dfll_suspend(struct platform_device *pdev)
> +{
> + struct tegra_dfll *td = dev_get_drvdata(&pdev->dev);
> +
> + if (!td)
> + return;
> +
> + if (td->mode <= DFLL_DISABLED)
> + return;
> +
> + td->resume_mode = td->mode;
> + switch (td->mode) {
> + case DFLL_CLOSED_LOOP:
> + dfll_set_mode(td, DFLL_CLOSED_LOOP);
> + dfll_set_frequency_request(td, &td->last_req);
> +
> + dfll_unlock(td);
> + break;
> + default:
> + break;
> + }
> +}
> +
> +/**
> + * tegra_dfll_resume - reprogram the DFLL after context-loss
> + * @pdev: DFLL instance
> + *
> + * Re-initialize and enable target device clock in open loop mode. Called
> + * directly from SoC clock resume syscore operation. Closed loop will be
> + * re-entered in platform syscore ops as well after CPU clock source is
> + * switched to DFLL in open loop.
> + */
> +void tegra_dfll_resume(struct platform_device *pdev, bool on_dfll)
> +{
> + struct tegra_dfll *td = dev_get_drvdata(&pdev->dev);
> +
> + if (!td)
> + return;
> +
> + if (on_dfll) {
> + if (td->resume_mode == DFLL_CLOSED_LOOP)
> + dfll_lock(td);
> + td->resume_mode = DFLL_DISABLED;
> + return;
> + }
> +
> + reset_control_deassert(td->dvco_rst);
> +
> + pm_runtime_get(td->dev);
pm_runtime_get_sync()?
Otherwise looks like you're risking a lot here because pm_runtime_get() is an
asynchronous request.
> + /* Re-init DFLL */
> + dfll_init_out_if(td);
> + dfll_set_default_params(td);
> + dfll_set_open_loop_config(td);
> +
> + pm_runtime_put(td->dev);
> +
> + /* Restore last request and mode up to open loop */
> + switch (td->resume_mode) {
> + case DFLL_CLOSED_LOOP:
> + case DFLL_OPEN_LOOP:
> + dfll_set_mode(td, DFLL_OPEN_LOOP);
> + if (td->pmu_if == TEGRA_DFLL_PMU_I2C)
> + dfll_i2c_set_output_enabled(td, false);
> + break;
> + default:
> + break;
> + }
> +}
Powered by blists - more mailing lists