From: dinguyen@opensource.altera.com (Dinh Nguyen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/2] socfpga: support suspend to ram
Date: Fri, 26 Sep 2014 09:56:12 -0500 [thread overview]
Message-ID: <54257E8C.8000102@opensource.altera.com> (raw)
In-Reply-To: <1411590449-9794-3-git-send-email-atull@opensource.altera.com>
On 09/24/2014 03:27 PM, atull at opensource.altera.com wrote:
> From: Alan Tull <atull@opensource.altera.com>
>
> Add code that requests that the sdr controller go into
> self-refresh mode. This code is run from ocram.
>
> This patch assumes that u-boot has already configured sdr:
> sdr.ctrlcfg.lowpwreq.selfrfshmask = 3
> sdr.ctrlcfg.lowpwrtiming.clkdisablecycles = 8
> sdr.ctrlcfg.dramtiming4.selfrfshexit = 512
>
> How to suspend to ram:
> $ echo enabled > \
> /sys/devices/soc/ffc02000.serial0/tty/ttyS0/power/wakeup
>
> $ echo -n mem > /sys/power/state
>
> Signed-off-by: Alan Tull <atull@opensource.altera.com>
> ---
> arch/arm/mach-socfpga/Makefile | 1 +
> arch/arm/mach-socfpga/core.h | 4 +
> arch/arm/mach-socfpga/pm.c | 141 ++++++++++++++++++++++++++++++++
> arch/arm/mach-socfpga/self-refresh.S | 148 ++++++++++++++++++++++++++++++++++
> arch/arm/mach-socfpga/socfpga.c | 10 +++
> 5 files changed, 304 insertions(+)
> create mode 100644 arch/arm/mach-socfpga/pm.c
> create mode 100644 arch/arm/mach-socfpga/self-refresh.S
>
> diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
> index 6dd7a93..0591927 100644
> --- a/arch/arm/mach-socfpga/Makefile
> +++ b/arch/arm/mach-socfpga/Makefile
> @@ -4,3 +4,4 @@
>
> obj-y := socfpga.o
> obj-$(CONFIG_SMP) += headsmp.o platsmp.o
> +obj-$(CONFIG_SUSPEND) += pm.o self-refresh.o
> diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
> index c4a0929..cc1a2fb 100644
> --- a/arch/arm/mach-socfpga/core.h
> +++ b/arch/arm/mach-socfpga/core.h
> @@ -38,6 +38,7 @@ extern void socfpga_sysmgr_init(void);
>
> extern void __iomem *sys_manager_base_addr;
> extern void __iomem *rst_manager_base_addr;
> +extern void __iomem *sdr_ctl_base_addr;
>
> extern struct smp_operations socfpga_smp_ops;
> extern char secondary_trampoline, secondary_trampoline_end;
> @@ -46,4 +47,7 @@ extern unsigned long cpu1start_addr;
>
> #define SOCFPGA_SCU_VIRT_BASE 0xfffec000
>
> +u32 socfpga_sdram_self_refresh(u32 sdr_base, u32 scu_base);
> +extern unsigned int socfpga_sdram_self_refresh_sz;
> +
> #endif
> diff --git a/arch/arm/mach-socfpga/pm.c b/arch/arm/mach-socfpga/pm.c
> new file mode 100644
> index 0000000..02c3719
> --- /dev/null
> +++ b/arch/arm/mach-socfpga/pm.c
> @@ -0,0 +1,141 @@
> +/*
> + * arch/arm/mach-socfpga/pm.c
> + *
> + * Copyright (C) 2014 Altera Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/of_platform.h>
> +#include <linux/suspend.h>
> +#include <asm/suspend.h>
> +#include <asm/fncpy.h>
> +#include "core.h"
> +
> +/* Pointer to function copied to ocram */
> +static u32 (*socfpga_sdram_self_refresh_in_ocram)(u32 sdr_base, u32 scu_base);
> +
> +/* Round up a pointer address to fix aligment for fncpy() */
> +static void *fncpy_align(void *ptr)
> +{
> + u32 value = (u32)ptr;
> +
> + if ((value & (FNCPY_ALIGN - 1)) != 0)
> + value = ((value & ~(FNCPY_ALIGN - 1)) + FNCPY_ALIGN);
> +
> + return (void *)value;
> +}
> +
> +static void *socfpga_init_ocram_exec(void)
> +{
> + struct device_node *np;
> + const __be32 *prop;
> + u32 ocram_hwaddr, len;
> + void __iomem *iomem_exec_ocram;
> + size_t size;
> +
> + np = of_find_compatible_node(NULL, NULL, "mmio-sram");
> + if (!np) {
> + pr_err("SOCFPGA: Unable to find mmio-sram in dtb\n");
> + return 0;
> + }
> +
> + /* Determine the OCRAM address and size */
> + prop = of_get_property(np, "reg", &size);
> + ocram_hwaddr = be32_to_cpup(prop++);
> + len = be32_to_cpup(prop);
> +
> + if (!prop || size < sizeof(*prop)) {
> + pr_err("SOCFPGA: Unable to find OCRAM mapping in dtb\n");
> + return 0;
> + }
> +
> + iomem_exec_ocram = __arm_ioremap_exec(ocram_hwaddr, len, 0);
The call to __arm_ioremap_exec can fail. Also, this doesn't seem right,
what if a good chunk of OCRAM has been used by some other driver in the
system? From what I've seen, OCRAM should be using the generic allocator
framework.
> +
> + /* Fix alignment to work with fncpy */
> + iomem_exec_ocram = fncpy_align(iomem_exec_ocram);
> +
> + return iomem_exec_ocram;
> +}
> +
> +static int socfpga_setup_ocram_self_refresh(void)
> +{
> + void *ocram_addr;
> +
> + /* Configure ocram and make it executable */
> + ocram_addr = socfpga_init_ocram_exec();
> + WARN(!ocram_addr, "Unable to initialize ocram for pm");
> + if (!ocram_addr)
> + return -EFAULT;
> +
> + /* Copy the code that puts DDR in self refresh to ocram */
> + socfpga_sdram_self_refresh_in_ocram =
> + (void *)fncpy((void *)ocram_addr,
> + &socfpga_sdram_self_refresh,
> + socfpga_sdram_self_refresh_sz);
> +
> + WARN(!socfpga_sdram_self_refresh_in_ocram,
> + "could not copy function to ocram");
> + if (!socfpga_sdram_self_refresh_in_ocram)
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static int socfpga_pm_suspend(unsigned long arg)
> +{
> + u32 ret;
> +
> + ret = socfpga_sdram_self_refresh_in_ocram((u32)sdr_ctl_base_addr,
> + (u32)socfpga_scu_base_addr);
What if sdr_ctl_base_addr is not valid?
BR,
Dinh
WARNING: multiple messages have this Message-ID (diff)
From: Dinh Nguyen <dinguyen@opensource.altera.com>
To: <atull@opensource.altera.com>, <linux@arm.linux.org.uk>
Cc: <linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <delicious.quinoa@gmail.com>,
<yvanderv@opensource.altera.com>
Subject: Re: [PATCH 2/2] socfpga: support suspend to ram
Date: Fri, 26 Sep 2014 09:56:12 -0500 [thread overview]
Message-ID: <54257E8C.8000102@opensource.altera.com> (raw)
In-Reply-To: <1411590449-9794-3-git-send-email-atull@opensource.altera.com>
On 09/24/2014 03:27 PM, atull@opensource.altera.com wrote:
> From: Alan Tull <atull@opensource.altera.com>
>
> Add code that requests that the sdr controller go into
> self-refresh mode. This code is run from ocram.
>
> This patch assumes that u-boot has already configured sdr:
> sdr.ctrlcfg.lowpwreq.selfrfshmask = 3
> sdr.ctrlcfg.lowpwrtiming.clkdisablecycles = 8
> sdr.ctrlcfg.dramtiming4.selfrfshexit = 512
>
> How to suspend to ram:
> $ echo enabled > \
> /sys/devices/soc/ffc02000.serial0/tty/ttyS0/power/wakeup
>
> $ echo -n mem > /sys/power/state
>
> Signed-off-by: Alan Tull <atull@opensource.altera.com>
> ---
> arch/arm/mach-socfpga/Makefile | 1 +
> arch/arm/mach-socfpga/core.h | 4 +
> arch/arm/mach-socfpga/pm.c | 141 ++++++++++++++++++++++++++++++++
> arch/arm/mach-socfpga/self-refresh.S | 148 ++++++++++++++++++++++++++++++++++
> arch/arm/mach-socfpga/socfpga.c | 10 +++
> 5 files changed, 304 insertions(+)
> create mode 100644 arch/arm/mach-socfpga/pm.c
> create mode 100644 arch/arm/mach-socfpga/self-refresh.S
>
> diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
> index 6dd7a93..0591927 100644
> --- a/arch/arm/mach-socfpga/Makefile
> +++ b/arch/arm/mach-socfpga/Makefile
> @@ -4,3 +4,4 @@
>
> obj-y := socfpga.o
> obj-$(CONFIG_SMP) += headsmp.o platsmp.o
> +obj-$(CONFIG_SUSPEND) += pm.o self-refresh.o
> diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
> index c4a0929..cc1a2fb 100644
> --- a/arch/arm/mach-socfpga/core.h
> +++ b/arch/arm/mach-socfpga/core.h
> @@ -38,6 +38,7 @@ extern void socfpga_sysmgr_init(void);
>
> extern void __iomem *sys_manager_base_addr;
> extern void __iomem *rst_manager_base_addr;
> +extern void __iomem *sdr_ctl_base_addr;
>
> extern struct smp_operations socfpga_smp_ops;
> extern char secondary_trampoline, secondary_trampoline_end;
> @@ -46,4 +47,7 @@ extern unsigned long cpu1start_addr;
>
> #define SOCFPGA_SCU_VIRT_BASE 0xfffec000
>
> +u32 socfpga_sdram_self_refresh(u32 sdr_base, u32 scu_base);
> +extern unsigned int socfpga_sdram_self_refresh_sz;
> +
> #endif
> diff --git a/arch/arm/mach-socfpga/pm.c b/arch/arm/mach-socfpga/pm.c
> new file mode 100644
> index 0000000..02c3719
> --- /dev/null
> +++ b/arch/arm/mach-socfpga/pm.c
> @@ -0,0 +1,141 @@
> +/*
> + * arch/arm/mach-socfpga/pm.c
> + *
> + * Copyright (C) 2014 Altera Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/of_platform.h>
> +#include <linux/suspend.h>
> +#include <asm/suspend.h>
> +#include <asm/fncpy.h>
> +#include "core.h"
> +
> +/* Pointer to function copied to ocram */
> +static u32 (*socfpga_sdram_self_refresh_in_ocram)(u32 sdr_base, u32 scu_base);
> +
> +/* Round up a pointer address to fix aligment for fncpy() */
> +static void *fncpy_align(void *ptr)
> +{
> + u32 value = (u32)ptr;
> +
> + if ((value & (FNCPY_ALIGN - 1)) != 0)
> + value = ((value & ~(FNCPY_ALIGN - 1)) + FNCPY_ALIGN);
> +
> + return (void *)value;
> +}
> +
> +static void *socfpga_init_ocram_exec(void)
> +{
> + struct device_node *np;
> + const __be32 *prop;
> + u32 ocram_hwaddr, len;
> + void __iomem *iomem_exec_ocram;
> + size_t size;
> +
> + np = of_find_compatible_node(NULL, NULL, "mmio-sram");
> + if (!np) {
> + pr_err("SOCFPGA: Unable to find mmio-sram in dtb\n");
> + return 0;
> + }
> +
> + /* Determine the OCRAM address and size */
> + prop = of_get_property(np, "reg", &size);
> + ocram_hwaddr = be32_to_cpup(prop++);
> + len = be32_to_cpup(prop);
> +
> + if (!prop || size < sizeof(*prop)) {
> + pr_err("SOCFPGA: Unable to find OCRAM mapping in dtb\n");
> + return 0;
> + }
> +
> + iomem_exec_ocram = __arm_ioremap_exec(ocram_hwaddr, len, 0);
The call to __arm_ioremap_exec can fail. Also, this doesn't seem right,
what if a good chunk of OCRAM has been used by some other driver in the
system? From what I've seen, OCRAM should be using the generic allocator
framework.
> +
> + /* Fix alignment to work with fncpy */
> + iomem_exec_ocram = fncpy_align(iomem_exec_ocram);
> +
> + return iomem_exec_ocram;
> +}
> +
> +static int socfpga_setup_ocram_self_refresh(void)
> +{
> + void *ocram_addr;
> +
> + /* Configure ocram and make it executable */
> + ocram_addr = socfpga_init_ocram_exec();
> + WARN(!ocram_addr, "Unable to initialize ocram for pm");
> + if (!ocram_addr)
> + return -EFAULT;
> +
> + /* Copy the code that puts DDR in self refresh to ocram */
> + socfpga_sdram_self_refresh_in_ocram =
> + (void *)fncpy((void *)ocram_addr,
> + &socfpga_sdram_self_refresh,
> + socfpga_sdram_self_refresh_sz);
> +
> + WARN(!socfpga_sdram_self_refresh_in_ocram,
> + "could not copy function to ocram");
> + if (!socfpga_sdram_self_refresh_in_ocram)
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static int socfpga_pm_suspend(unsigned long arg)
> +{
> + u32 ret;
> +
> + ret = socfpga_sdram_self_refresh_in_ocram((u32)sdr_ctl_base_addr,
> + (u32)socfpga_scu_base_addr);
What if sdr_ctl_base_addr is not valid?
BR,
Dinh
next prev parent reply other threads:[~2014-09-26 14:56 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-24 20:27 [PATCH 0/2] socfpga: fix hotplug/add suspend to ram atull at opensource.altera.com
2014-09-24 20:27 ` atull
2014-09-24 20:27 ` [PATCH 1/2] socfpga: hotplug: put cpu1 in wfi atull at opensource.altera.com
2014-09-24 20:27 ` atull
2014-09-24 21:28 ` Russell King - ARM Linux
2014-09-24 21:28 ` Russell King - ARM Linux
2014-09-25 15:06 ` atull
2014-09-25 15:06 ` atull
2014-10-01 13:35 ` Pavel Machek
2014-10-01 13:35 ` Pavel Machek
2014-10-01 14:17 ` atull
2014-10-01 14:17 ` atull
2014-10-01 15:04 ` Pavel Machek
2014-10-01 15:04 ` Pavel Machek
2014-10-01 16:07 ` Dinh Nguyen
2014-10-01 16:07 ` Dinh Nguyen
2014-10-01 23:16 ` Pavel Machek
2014-10-01 23:16 ` Pavel Machek
2014-10-02 11:36 ` Dinh Nguyen
2014-10-02 11:36 ` Dinh Nguyen
2014-10-02 12:18 ` Arnd Bergmann
2014-10-02 12:18 ` Arnd Bergmann
2014-10-02 21:03 ` atull
2014-10-02 21:03 ` atull
2014-09-24 20:27 ` [PATCH 2/2] socfpga: support suspend to ram atull at opensource.altera.com
2014-09-24 20:27 ` atull
2014-09-25 8:25 ` Steffen Trumtrar
2014-09-25 8:25 ` Steffen Trumtrar
2014-09-25 17:10 ` atull
2014-09-25 17:10 ` atull
2014-09-26 14:56 ` Dinh Nguyen [this message]
2014-09-26 14:56 ` Dinh Nguyen
2014-09-26 20:23 ` atull
2014-09-26 20:23 ` atull
2014-10-01 13:49 ` Pavel Machek
2014-10-01 13:49 ` Pavel Machek
2014-10-01 19:24 ` atull
2014-10-01 19:24 ` atull
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=54257E8C.8000102@opensource.altera.com \
--to=dinguyen@opensource.altera.com \
--cc=linux-arm-kernel@lists.infradead.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.