All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Alexandre Belloni <alexandre.belloni@free-electrons.com>,
	Sebastian Reichel <sre@kernel.org>
Subject: [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories
Date: Thu,  6 Apr 2017 10:38:45 +0200	[thread overview]
Message-ID: <20170406083605.797902629@linuxfoundation.org> (raw)
In-Reply-To: <20170406083604.362636628@linuxfoundation.org>

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", },

  parent reply	other threads:[~2017-04-06  9:36 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-06  8:38 [PATCH 4.4 00/26] 4.4.60-stable review Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 01/26] libceph: force GFP_NOIO for socket allocations Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 02/26] xen/setup: Dont relocate p2m over existing one Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 03/26] scsi: mpt3sas: fix hang on ata passthrough commands Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 04/26] scsi: sg: check length passed to SG_NEXT_CMD_LEN Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 05/26] scsi: libsas: fix ata xfer length Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 06/26] ALSA: seq: Fix race during FIFO resize Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 07/26] ALSA: hda - fix a problem for lineout on a Dell AIO machine Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 08/26] ASoC: atmel-classd: fix audio clock rate Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 09/26] ACPI: Fix incompatibility with mcount-based function graph tracing Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 10/26] ACPI: Do not create a platform_device for IOAPIC/IOxAPIC Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 11/26] tty/serial: atmel: fix race condition (TX+DMA) Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 12/26] tty/serial: atmel: fix TX path in atmel_console_write() Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 13/26] USB: fix linked-list corruption in rh_call_control() Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 16/26] mm, hugetlb: use pte_present() instead of pmd_present() in follow_huge_pmd() Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 17/26] MIPS: Lantiq: Fix cascaded IRQ setup Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 22/26] KVM: kvm_io_bus_unregister_dev() should never fail Greg Kroah-Hartman
2017-04-06  8:38 ` Greg Kroah-Hartman [this message]
2017-04-06 17:45   ` [PATCH 4.4 23/26] power: reset: at91-poweroff: timely shutdown LPDDR memories Ben Hutchings
2017-04-06 18:13     ` Alexandre Belloni
2017-04-06 18:22       ` Ben Hutchings
2017-04-06  8:38 ` [PATCH 4.4 24/26] blk: improve order of bio handling in generic_make_request() Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 25/26] blk: Ensure users for current->bio_list can see the full list Greg Kroah-Hartman
2017-04-06 18:17   ` Ben Hutchings
2017-04-07  8:33     ` Jinpu Wang
2017-04-07 12:45       ` Ben Hutchings
2017-04-07 13:03         ` Jinpu Wang
2017-04-07 13:37           ` Ben Hutchings
2017-04-08  7:52             ` Greg Kroah-Hartman
2017-04-06  8:38 ` [PATCH 4.4 26/26] padata: avoid race in reordering Greg Kroah-Hartman
2017-04-06 17:47 ` [PATCH 4.4 00/26] 4.4.60-stable review Shuah Khan
2017-04-06 21:53 ` Guenter Roeck

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=20170406083605.797902629@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=alexandre.belloni@free-electrons.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sre@kernel.org \
    --cc=stable@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.