Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1617806 > unrolled thread

[PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories

Started byGreg Kroah-Hartman <gregkh@linuxfoundation.org>
First post2017-04-06 11:40 +0200
Last post2017-04-06 20:30 +0200
Articles 4 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-04-06 11:40 +0200
    Re: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown  LPDDR memories Ben Hutchings <ben.hutchings@codethink.co.uk> - 2017-04-06 19:50 +0200
      Re: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown  LPDDR memories Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-04-06 20:20 +0200
        Re: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown  LPDDR memories Ben Hutchings <ben.hutchings@codethink.co.uk> - 2017-04-06 20:30 +0200

#1617806 — [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories

FromGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Date2017-04-06 11:40 +0200
Subject[PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories
Message-ID<ttc3x-6L0-51@gated-at.bofh.it>
4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alexandre Belloni <alexandre.belloni@free-electrons.com>

commit 0b0408745e7ff24757cbfd571d69026c0ddb803c upstream.

LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the
proper power off sequence is used before shutting down the platform.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/power/reset/at91-poweroff.c |   54 +++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

--- a/drivers/power/reset/at91-poweroff.c
+++ b/drivers/power/reset/at91-poweroff.c
@@ -14,9 +14,12 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/printk.h>
 
+#include <soc/at91/at91sam9_ddrsdr.h>
+
 #define AT91_SHDW_CR	0x00		/* Shut Down Control Register */
 #define AT91_SHDW_SHDW		BIT(0)			/* Shut Down command */
 #define AT91_SHDW_KEY		(0xa5 << 24)		/* KEY Password */
@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[]
 
 static void __iomem *at91_shdwc_base;
 static struct clk *sclk;
+static void __iomem *mpddrc_base;
 
 static void __init at91_wakeup_status(void)
 {
@@ -73,6 +77,29 @@ static void at91_poweroff(void)
 	writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
 }
 
+static void at91_lpddr_poweroff(void)
+{
+	asm volatile(
+		/* Align to cache lines */
+		".balign 32\n\t"
+
+		/* Ensure AT91_SHDW_CR is in the TLB by reading it */
+		"	ldr	r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
+
+		/* Power down SDRAM0 */
+		"	str	%1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
+		/* Shutdown CPU */
+		"	str	%3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
+
+		"	b	.\n\t"
+		:
+		: "r" (mpddrc_base),
+		  "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
+		  "r" (at91_shdwc_base),
+		  "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
+		: "r0");
+}
+
 static int at91_poweroff_get_wakeup_mode(struct device_node *np)
 {
 	const char *pm;
@@ -124,6 +151,8 @@ static void at91_poweroff_dt_set_wakeup_
 static int __init at91_poweroff_probe(struct platform_device *pdev)
 {
 	struct resource *res;
+	struct device_node *np;
+	u32 ddr_type;
 	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -150,12 +179,30 @@ static int __init at91_poweroff_probe(st
 
 	pm_power_off = at91_poweroff;
 
+	np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
+	if (!np)
+		return 0;
+
+	mpddrc_base = of_iomap(np, 0);
+	of_node_put(np);
+
+	if (!mpddrc_base)
+		return 0;
+
+	ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
+	if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
+	    (ddr_type == AT91_DDRSDRC_MD_LPDDR3))
+		pm_power_off = at91_lpddr_poweroff;
+	else
+		iounmap(mpddrc_base);
+
 	return 0;
 }
 
 static int __exit at91_poweroff_remove(struct platform_device *pdev)
 {
-	if (pm_power_off == at91_poweroff)
+	if (pm_power_off == at91_poweroff ||
+	    pm_power_off == at91_lpddr_poweroff)
 		pm_power_off = NULL;
 
 	clk_disable_unprepare(sclk);
@@ -163,6 +210,11 @@ static int __exit at91_poweroff_remove(s
 	return 0;
 }
 
+static const struct of_device_id at91_ramc_of_match[] = {
+	{ .compatible = "atmel,sama5d3-ddramc", },
+	{ /* sentinel */ }
+};
+
 static const struct of_device_id at91_poweroff_of_match[] = {
 	{ .compatible = "atmel,at91sam9260-shdwc", },
 	{ .compatible = "atmel,at91sam9rl-shdwc", },

[toc] | [next] | [standalone]


#1618221 — Re: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories

FromBen Hutchings <ben.hutchings@codethink.co.uk>
Date2017-04-06 19:50 +0200
SubjectRe: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories
Message-ID<ttjHI-3XQ-11@gated-at.bofh.it>
In reply to#1617806
On Thu, 2017-04-06 at 10:38 +0200, Greg Kroah-Hartman wrote:
> 4.4-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> 
> commit 0b0408745e7ff24757cbfd571d69026c0ddb803c upstream.
> 
> LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the
> proper power off sequence is used before shutting down the platform.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Signed-off-by: Sebastian Reichel <sre@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[...] 
> +static void at91_lpddr_poweroff(void)
> +{
> +	asm volatile(
> +		/* Align to cache lines */
> +		".balign 32\n\t"
> +
> +		/* Ensure AT91_SHDW_CR is in the TLB by reading it */
> +		"	ldr	r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"

This clobbers r6...

> +		/* Power down SDRAM0 */
> +		"	str	%1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
> +		/* Shutdown CPU */
> +		"	str	%3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
> +
> +		"	b	.\n\t"
> +		:
> +		: "r" (mpddrc_base),
> +		  "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
> +		  "r" (at91_shdwc_base),
> +		  "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
> +		: "r0");
[...]

...but the clobber list has r0.

Ben.

-- 
Ben Hutchings
Software Developer, Codethink Ltd.

[toc] | [prev] | [next] | [standalone]


#1618251 — Re: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2017-04-06 20:20 +0200
SubjectRe: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories
Message-ID<ttkaJ-4pu-9@gated-at.bofh.it>
In reply to#1618221
On 06/04/2017 at 18:45:39 +0100, Ben Hutchings wrote:
> On Thu, 2017-04-06 at 10:38 +0200, Greg Kroah-Hartman wrote:
> > 4.4-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> > 
> > commit 0b0408745e7ff24757cbfd571d69026c0ddb803c upstream.
> > 
> > LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the
> > proper power off sequence is used before shutting down the platform.
> > 
> > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> > Signed-off-by: Sebastian Reichel <sre@kernel.org>
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> [...] 
> > +static void at91_lpddr_poweroff(void)
> > +{
> > +	asm volatile(
> > +		/* Align to cache lines */
> > +		".balign 32\n\t"
> > +
> > +		/* Ensure AT91_SHDW_CR is in the TLB by reading it */
> > +		"	ldr	r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
> 
> This clobbers r6...
> 
> > +		/* Power down SDRAM0 */
> > +		"	str	%1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
> > +		/* Shutdown CPU */
> > +		"	str	%3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
> > +
> > +		"	b	.\n\t"
> > +		:
> > +		: "r" (mpddrc_base),
> > +		  "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
> > +		  "r" (at91_shdwc_base),
> > +		  "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
> > +		: "r0");
> [...]
> 
> ...but the clobber list has r0.
> 

Indeed. However, It doesn't matter much as nothing can possibly run
afterwards.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[toc] | [prev] | [next] | [standalone]


#1618254 — Re: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories

FromBen Hutchings <ben.hutchings@codethink.co.uk>
Date2017-04-06 20:30 +0200
SubjectRe: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories
Message-ID<ttkkp-4sU-5@gated-at.bofh.it>
In reply to#1618251
On Thu, 2017-04-06 at 20:13 +0200, Alexandre Belloni wrote:
> On 06/04/2017 at 18:45:39 +0100, Ben Hutchings wrote:
> > On Thu, 2017-04-06 at 10:38 +0200, Greg Kroah-Hartman wrote:
> > > 4.4-stable review patch.  If anyone has any objections, please let me know.
> > > 
> > > ------------------
> > > 
> > > From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> > > 
> > > commit 0b0408745e7ff24757cbfd571d69026c0ddb803c upstream.
> > > 
> > > LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the
> > > proper power off sequence is used before shutting down the platform.
> > > 
> > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> > > Signed-off-by: Sebastian Reichel <sre@kernel.org>
> > > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > [...] 
> > > +static void at91_lpddr_poweroff(void)
> > > +{
> > > +	asm volatile(
> > > +		/* Align to cache lines */
> > > +		".balign 32\n\t"
> > > +
> > > +		/* Ensure AT91_SHDW_CR is in the TLB by reading it */
> > > +		"	ldr	r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
> > 
> > This clobbers r6...
> > 
> > > +		/* Power down SDRAM0 */
> > > +		"	str	%1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
> > > +		/* Shutdown CPU */
> > > +		"	str	%3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
> > > +
> > > +		"	b	.\n\t"
> > > +		:
> > > +		: "r" (mpddrc_base),
> > > +		  "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
> > > +		  "r" (at91_shdwc_base),
> > > +		  "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
> > > +		: "r0");
> > [...]
> > 
> > ...but the clobber list has r0.
> > 
> 
> Indeed. However, It doesn't matter much as nothing can possibly run
> afterwards.

It does matter because the compiler can use r6 for one of the inputs.

Ben.

-- 
Ben Hutchings
Software Developer, Codethink Ltd.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web