Thread (36 messages) 36 messages, 6 authors, 2021-12-06

Re: [RFC 06/19] devfreq: imx8m-ddrc: Add late system sleep PM ops

flat view

From: Abel Vesa <hidden>
Date: 2021-11-30 20:06:32
Also in: linux-devicetree, linux-pm, linux-serial, lkml

On 21-11-10 13:15:26, Martin Kepplinger wrote:
Am Montag, dem 13.09.2021 um 20:38 +0300 schrieb Abel Vesa:
quoted
Seems that, in order to be able to resume from suspend, the dram rate
needs to be the highest one available. Therefore, add the late system
suspend/resume PM ops which set the highest rate on suspend and the
latest one used before suspending on resume.
Hi Abel, wouldn't this mean that s2idle / freeze would be kind of
broken by this?
Nope. Only the DDR rate needs to be raised at 800M before suspending.
Everything else stays the same.
Does is make sense to test the lowest rate? How would I force that
here? (just for testing)
You can try, but it will surely freeze. See [1] what you need to change
for testing.
Also, you could think about splitting this series up a bit and do this
patch seperately onto mainline (before or after the other work).
Well, I sent as RFC until now. Seems there are no big issues with the
approach. So I'll split the patches between subsystems on the next
iteration.
thank you
                          martin

quoted
Signed-off-by: Abel Vesa <redacted>
---
 drivers/devfreq/imx8m-ddrc.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-
ddrc.c
index f18a5c3c1c03..f39741b4a0b0 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -72,6 +72,8 @@ struct imx8m_ddrc {
        struct clk *dram_alt;
        struct clk *dram_apb;
 
+       unsigned long suspend_rate;
+       unsigned long resume_rate;
        int freq_count;
        struct imx8m_ddrc_freq freq_table[IMX8M_DDRC_MAX_FREQ_COUNT];
 };
@@ -271,6 +273,22 @@ static int imx8m_ddrc_target(struct device *dev,
unsigned long *freq, u32 flags)
        return ret;
 }
 
+static int imx8m_ddrc_suspend(struct device *dev)
+{
+       struct imx8m_ddrc *priv = dev_get_drvdata(dev);
+
+       priv->resume_rate = clk_get_rate(priv->dram_core);
+
+       return imx8m_ddrc_target(dev, &priv->suspend_rate, 0);
+}
+
+static int imx8m_ddrc_resume(struct device *dev)
+{
+       struct imx8m_ddrc *priv = dev_get_drvdata(dev);
+
+       return imx8m_ddrc_target(dev, &priv->resume_rate, 0);
+}
+
 static int imx8m_ddrc_get_cur_freq(struct device *dev, unsigned long
*freq)
 {
        struct imx8m_ddrc *priv = dev_get_drvdata(dev);
@@ -324,6 +342,9 @@ static int imx8m_ddrc_init_freq_info(struct
device *dev)
 
                if (dev_pm_opp_add(dev, freq->rate * 250000, 0))
                        return -ENODEV;
+
+               if (index ==  0)
[1] Change this line to:
		    if (index == 1)

It will select the 166935483 freq for suspending.
quoted
+                       priv->suspend_rate = freq->rate * 250000;
        }
 
        return 0;
@@ -399,11 +420,16 @@ static const struct of_device_id
imx8m_ddrc_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, imx8m_ddrc_of_match);
 
+static const struct dev_pm_ops imx8m_ddrc_pm_ops = {
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(imx8m_ddrc_suspend,
imx8m_ddrc_resume)
+};
+
 static struct platform_driver imx8m_ddrc_platdrv = {
        .probe          = imx8m_ddrc_probe,
        .driver = {
                .name   = "imx8m-ddrc-devfreq",
-               .of_match_table = imx8m_ddrc_of_match,
+               .pm = &imx8m_ddrc_pm_ops,
+               .of_match_table = of_match_ptr(imx8m_ddrc_of_match),
        },
 };
 module_platform_driver(imx8m_ddrc_platdrv);
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help