Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1572430 > unrolled thread
| Started by | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| First post | 2017-02-02 15:50 +0100 |
| Last post | 2017-02-02 16:00 +0100 |
| Articles | 7 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH 00/13] ARM: at91; pm: cleanup Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 15:50 +0100
[PATCH 12/13] ARM: at91: pm: use C functions for standby Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 15:50 +0100
[PATCH 10/13] ARM: at91: pm: merge all at91sam9*_pm_init Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 15:50 +0100
[PATCH 01/13] ARM: at91: pm: cleanup headers Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100
[PATCH 04/13] ARM: at91: pm: use struct at91_pm_data in pm_suspend.S Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100
[PATCH 03/13] ARM: at91: pm: Move global variables into at91_pm_data Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100
[PATCH 02/13] ARM: at91: pm: move at91_ramc_read/write to pm.c Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2017-02-02 16:00 +0100
| From | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| Date | 2017-02-02 15:50 +0100 |
| Subject | [PATCH 00/13] ARM: at91; pm: cleanup |
| Message-ID | <t6qRX-5if-5@gated-at.bofh.it> |
Hi,
The following patch set is a cleanup of the AT91 PM code.
The main feautres is that it is now using a struct to pass arguments
between the C and the assembly code, allowing for more than 4 variables
to be passed.
It also removes instructions so it is actually faster.
The standby path is also faster now because it is only handled using C,
removing the need for a few comparisons before enabling DRAM self
refresh. This also allows to always propose standby, even when the sram
allocation failed.
Finally, the PM initialization functions are merge, removing the need
for separate paths on at91sam9*
Alexandre Belloni (13):
ARM: at91: pm: cleanup headers
ARM: at91: pm: move at91_ramc_read/write to pm.c
ARM: at91: pm: Move global variables into at91_pm_data
ARM: at91: pm: use struct at91_pm_data in pm_suspend.S
ARM: at91: pm: use struct members directly
ARM: at91: pm: simplify at91rm9200_standby
ARM: at91: pm: Workaround DDRSDRC self-refresh bug with LPDDR1
memories.
ARM: at91: pm: tie the memory controller type to the ramc id
ARM: at91: pm: tie the USB clock mask to the pmc
ARM: at91: pm: merge all at91sam9*_pm_init
ARM: at91: pm: remove at91_pm_set_standby
ARM: at91: pm: use C functions for standby
ARM: at91: pm: Allow PM even if SRAM allocation failed
arch/arm/mach-at91/Makefile | 33 ++++++
arch/arm/mach-at91/at91sam9.c | 45 +-------
arch/arm/mach-at91/generic.h | 8 +-
arch/arm/mach-at91/pm.c | 212 +++++++++++++++++------------------
arch/arm/mach-at91/pm.h | 27 ++---
arch/arm/mach-at91/pm_data-offsets.c | 12 ++
arch/arm/mach-at91/pm_suspend.S | 55 ++-------
7 files changed, 176 insertions(+), 216 deletions(-)
create mode 100644 arch/arm/mach-at91/pm_data-offsets.c
--
2.11.0
[toc] | [next] | [standalone]
| From | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| Date | 2017-02-02 15:50 +0100 |
| Subject | [PATCH 12/13] ARM: at91: pm: use C functions for standby |
| Message-ID | <t6qRY-5if-35@gated-at.bofh.it> |
| In reply to | #1572430 |
When going to standby, there is no point calling the assembly function
at91_pm_suspend_in_sram(). It does exactly the same operations as the C
standby functions.
This allows to remove a few loads and tests in the suspend/resume path.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/pm.c | 8 +++++---
arch/arm/mach-at91/pm.h | 4 +---
arch/arm/mach-at91/pm_data-offsets.c | 1 -
arch/arm/mach-at91/pm_suspend.S | 14 --------------
4 files changed, 6 insertions(+), 21 deletions(-)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 553bcfc5545e..1992ad8b1c3d 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -125,12 +125,13 @@ extern u32 at91_pm_suspend_in_sram_sz;
static void at91_pm_suspend(suspend_state_t state)
{
- pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0;
-
flush_cache_all();
outer_disable();
- at91_suspend_sram_fn(&pm_data);
+ if (state == PM_SUSPEND_MEM)
+ at91_suspend_sram_fn(&pm_data);
+ else
+ pm_data.standby();
outer_resume();
}
@@ -342,6 +343,7 @@ static __init void at91_dt_ramc(void)
ramc = of_id->data;
if (!standby)
standby = ramc->standby;
+ pm_data.standby = standby;
pm_data.memctrl = ramc->memctrl;
idx++;
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index fc0f7d048187..2317e39248b7 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -21,15 +21,13 @@
#define AT91_MEMCTRL_SDRAMC 1
#define AT91_MEMCTRL_DDRSDR 2
-#define AT91_PM_SLOW_CLOCK 0x01
-
#ifndef __ASSEMBLY__
struct at91_pm_data {
void __iomem *pmc;
void __iomem *ramc[2];
unsigned long uhp_udp_mask;
unsigned int memctrl;
- unsigned int mode;
+ void (*standby)(void);
};
#endif
diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
index 30302cb16df0..c4e6d648644f 100644
--- a/arch/arm/mach-at91/pm_data-offsets.c
+++ b/arch/arm/mach-at91/pm_data-offsets.c
@@ -8,6 +8,5 @@ int main(void)
DEFINE(PM_DATA_RAMC0, offsetof(struct at91_pm_data, ramc[0]));
DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1]));
DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl));
- DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode));
return 0;
}
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 3ee282c051e0..a8b32faaea5b 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -94,10 +94,6 @@ ENTRY(at91_pm_suspend_in_sram)
mov r0, #SRAMC_SELF_FRESH_ACTIVE
bl at91_sramc_self_refresh
- ldr r0, [pm_data, #PM_DATA_MODE]
- tst r0, #AT91_PM_SLOW_CLOCK
- beq skip_disable_main_clock
-
ldr pmc, [pm_data, #PM_DATA_PMC]
/* Save Master clock setting */
@@ -126,18 +122,9 @@ ENTRY(at91_pm_suspend_in_sram)
orr tmp1, tmp1, #AT91_PMC_KEY
str tmp1, [pmc, #AT91_CKGR_MOR]
-skip_disable_main_clock:
- ldr pmc, [pm_data, #PM_DATA_PMC]
-
/* Wait for interrupt */
at91_cpu_idle
- ldr r0, [pm_data, #PM_DATA_MODE]
- tst r0, #AT91_PM_SLOW_CLOCK
- beq skip_enable_main_clock
-
- ldr pmc, [pm_data, #PM_DATA_PMC]
-
/* Turn on the main oscillator */
ldr tmp1, [pmc, #AT91_CKGR_MOR]
orr tmp1, tmp1, #AT91_PMC_MOSCEN
@@ -166,7 +153,6 @@ skip_disable_main_clock:
wait_mckrdy
-skip_enable_main_clock:
/* Exit the self-refresh mode */
mov r0, #SRAMC_SELF_FRESH_EXIT
bl at91_sramc_self_refresh
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| Date | 2017-02-02 15:50 +0100 |
| Subject | [PATCH 10/13] ARM: at91: pm: merge all at91sam9*_pm_init |
| Message-ID | <t6qRY-5if-25@gated-at.bofh.it> |
| In reply to | #1572430 |
The PM initialization is now identical for all at91sam9. Merge the
functions.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/at91sam9.c | 45 +++----------------------------------------
arch/arm/mach-at91/generic.h | 8 ++------
arch/arm/mach-at91/pm.c | 14 +-------------
3 files changed, 6 insertions(+), 61 deletions(-)
diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
index ba28e9cc584d..c089bfd0dc2f 100644
--- a/arch/arm/mach-at91/at91sam9.c
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -52,7 +52,7 @@ static const struct at91_soc at91sam9_socs[] = {
{ /* sentinel */ },
};
-static void __init at91sam9_common_init(void)
+static void __init at91sam9_init(void)
{
struct soc_device *soc;
struct device *soc_dev = NULL;
@@ -62,12 +62,8 @@ static void __init at91sam9_common_init(void)
soc_dev = soc_device_to_device(soc);
of_platform_default_populate(NULL, NULL, soc_dev);
-}
-static void __init at91sam9_dt_device_init(void)
-{
- at91sam9_common_init();
- at91sam9260_pm_init();
+ at91sam9_pm_init();
}
static const char *const at91_dt_board_compat[] __initconst = {
@@ -77,41 +73,6 @@ static const char *const at91_dt_board_compat[] __initconst = {
DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
/* Maintainer: Atmel */
- .init_machine = at91sam9_dt_device_init,
+ .init_machine = at91sam9_init,
.dt_compat = at91_dt_board_compat,
MACHINE_END
-
-static void __init at91sam9g45_dt_device_init(void)
-{
- at91sam9_common_init();
- at91sam9g45_pm_init();
-}
-
-static const char *const at91sam9g45_board_compat[] __initconst = {
- "atmel,at91sam9g45",
- NULL
-};
-
-DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
- /* Maintainer: Atmel */
- .init_machine = at91sam9g45_dt_device_init,
- .dt_compat = at91sam9g45_board_compat,
-MACHINE_END
-
-static void __init at91sam9x5_dt_device_init(void)
-{
- at91sam9_common_init();
- at91sam9x5_pm_init();
-}
-
-static const char *const at91sam9x5_board_compat[] __initconst = {
- "atmel,at91sam9x5",
- "atmel,at91sam9n12",
- NULL
-};
-
-DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
- /* Maintainer: Atmel */
- .init_machine = at91sam9x5_dt_device_init,
- .dt_compat = at91sam9x5_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 28ca57a2060f..f1ead0f13c19 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -13,15 +13,11 @@
#ifdef CONFIG_PM
extern void __init at91rm9200_pm_init(void);
-extern void __init at91sam9260_pm_init(void);
-extern void __init at91sam9g45_pm_init(void);
-extern void __init at91sam9x5_pm_init(void);
+extern void __init at91sam9_pm_init(void);
extern void __init sama5_pm_init(void);
#else
static inline void __init at91rm9200_pm_init(void) { }
-static inline void __init at91sam9260_pm_init(void) { }
-static inline void __init at91sam9g45_pm_init(void) { }
-static inline void __init at91sam9x5_pm_init(void) { }
+static inline void __init at91sam9_pm_init(void) { }
static inline void __init sama5_pm_init(void) { }
#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index c0ef1742135c..009b57f3a62e 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -488,19 +488,7 @@ void __init at91rm9200_pm_init(void)
at91_pm_init(at91rm9200_idle);
}
-void __init at91sam9260_pm_init(void)
-{
- at91_dt_ramc();
- at91_pm_init(at91sam9_idle);
-}
-
-void __init at91sam9g45_pm_init(void)
-{
- at91_dt_ramc();
- at91_pm_init(at91sam9_idle);
-}
-
-void __init at91sam9x5_pm_init(void)
+void __init at91sam9_pm_init(void)
{
at91_dt_ramc();
at91_pm_init(at91sam9_idle);
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| Date | 2017-02-02 16:00 +0100 |
| Subject | [PATCH 01/13] ARM: at91: pm: cleanup headers |
| Message-ID | <t6r1D-5lK-1@gated-at.bofh.it> |
| In reply to | #1572430 |
Remove unnecessary header inclusions and reorder the remaining ones. Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> --- arch/arm/mach-at91/pm.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index b4332b727e9c..3d28d1957e41 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -10,28 +10,17 @@ * (at your option) any later version. */ -#include <linux/gpio.h> -#include <linux/suspend.h> -#include <linux/sched.h> -#include <linux/proc_fs.h> #include <linux/genalloc.h> -#include <linux/interrupt.h> -#include <linux/sysfs.h> -#include <linux/module.h> +#include <linux/io.h> +#include <linux/of_address.h> #include <linux/of.h> #include <linux/of_platform.h> -#include <linux/of_address.h> -#include <linux/platform_device.h> -#include <linux/platform_data/atmel.h> -#include <linux/io.h> +#include <linux/suspend.h> + #include <linux/clk/at91_pmc.h> -#include <asm/irq.h> -#include <linux/atomic.h> -#include <asm/mach/time.h> -#include <asm/mach/irq.h> -#include <asm/fncpy.h> #include <asm/cacheflush.h> +#include <asm/fncpy.h> #include <asm/system_misc.h> #include "generic.h" -- 2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| Date | 2017-02-02 16:00 +0100 |
| Subject | [PATCH 04/13] ARM: at91: pm: use struct at91_pm_data in pm_suspend.S |
| Message-ID | <t6r1D-5lK-7@gated-at.bofh.it> |
| In reply to | #1572430 |
The number of register we can safely pass to at91_pm_suspend_in_sram is
limited. Instead, pass the address to the at91_pm_data structure.
The offsets are automatically generated to avoid hardcoding them.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/Makefile | 33 +++++++++++++++
arch/arm/mach-at91/pm.c | 78 +++++++++++++++---------------------
arch/arm/mach-at91/pm.h | 16 +++++---
arch/arm/mach-at91/pm_data-offsets.c | 13 ++++++
arch/arm/mach-at91/pm_suspend.S | 29 ++++++--------
5 files changed, 102 insertions(+), 67 deletions(-)
create mode 100644 arch/arm/mach-at91/pm_data-offsets.c
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index c5bbf8bb8c0f..858ef14f961c 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -18,3 +18,36 @@ endif
ifeq ($(CONFIG_PM_DEBUG),y)
CFLAGS_pm.o += -DDEBUG
endif
+
+# Default sed regexp - multiline due to syntax constraints
+define sed-y
+ "/^->/{s:->#\(.*\):/* \1 */:; \
+ s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
+ s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+ s:->::; p;}"
+endef
+
+# Use filechk to avoid rebuilds when a header changes, but the resulting file
+# does not
+define filechk_offsets
+ (set -e; \
+ echo "#ifndef $2"; \
+ echo "#define $2"; \
+ echo "/*"; \
+ echo " * DO NOT MODIFY."; \
+ echo " *"; \
+ echo " * This file was generated by Kbuild"; \
+ echo " */"; \
+ echo ""; \
+ sed -ne $(sed-y); \
+ echo ""; \
+ echo "#endif" )
+endef
+
+arch/arm/mach-at91/pm_data-offsets.s: arch/arm/mach-at91/pm_data-offsets.c
+ $(call if_changed_dep,cc_s_c)
+
+include/generated/at91_pm_data-offsets.h: arch/arm/mach-at91/pm_data-offsets.s FORCE
+ $(call filechk,offsets,__PM_DATA_OFFSETS_H__)
+
+arch/arm/mach-at91/pm_suspend.o: include/generated/at91_pm_data-offsets.h
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 4253cd775738..90b78ad20a97 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -37,18 +37,13 @@ extern void at91_pinctrl_gpio_suspend(void);
extern void at91_pinctrl_gpio_resume(void);
#endif
-static struct {
- void __iomem *pmc;
- void __iomem *ramc[2];
- unsigned long uhp_udp_mask;
- int memctrl;
-} at91_pm_data;
+static struct at91_pm_data pm_data;
#define at91_ramc_read(id, field) \
- __raw_readl(at91_pm_data.ramc[id] + field)
+ __raw_readl(pm_data.ramc[id] + field)
#define at91_ramc_write(id, field, value) \
- __raw_writel(value, at91_pm_data.ramc[id] + field)
+ __raw_writel(value, pm_data.ramc[id] + field)
static int at91_pm_valid_state(suspend_state_t state)
{
@@ -84,10 +79,10 @@ static int at91_pm_verify_clocks(void)
unsigned long scsr;
int i;
- scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
+ scsr = readl(pm_data.pmc + AT91_PMC_SCSR);
/* USB must not be using PLLB */
- if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
+ if ((scsr & pm_data.uhp_udp_mask) != 0) {
pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
@@ -98,7 +93,7 @@ static int at91_pm_verify_clocks(void)
if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
continue;
- css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+ css = readl(pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
if (css != AT91_PMC_CSS_SLOW) {
pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
return 0;
@@ -124,25 +119,18 @@ int at91_suspend_entering_slow_clock(void)
}
EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
-static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
- void __iomem *ramc1, int memctrl);
-
-extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
- void __iomem *ramc1, int memctrl);
+static void (*at91_suspend_sram_fn)(struct at91_pm_data *);
+extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
extern u32 at91_pm_suspend_in_sram_sz;
static void at91_pm_suspend(suspend_state_t state)
{
- unsigned int pm_data = at91_pm_data.memctrl;
-
- pm_data |= (state == PM_SUSPEND_MEM) ?
- AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
+ pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0;
flush_cache_all();
outer_disable();
- at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
- at91_pm_data.ramc[1], pm_data);
+ at91_suspend_sram_fn(&pm_data);
outer_resume();
}
@@ -245,7 +233,7 @@ static void at91rm9200_standby(void)
" mcr p15, 0, %0, c7, c0, 4\n\t"
" str %5, [%1, %2]"
:
- : "r" (0), "r" (at91_pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
+ : "r" (0), "r" (pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
"r" (1), "r" (AT91_MC_SDRAMC_SRR),
"r" (lpr));
}
@@ -260,7 +248,7 @@ static void at91_ddr_standby(void)
u32 lpr0, lpr1 = 0;
u32 saved_lpr0, saved_lpr1 = 0;
- if (at91_pm_data.ramc[1]) {
+ if (pm_data.ramc[1]) {
saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -272,13 +260,13 @@ static void at91_ddr_standby(void)
/* self-refresh mode now */
at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
- if (at91_pm_data.ramc[1])
+ if (pm_data.ramc[1])
at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
cpu_do_idle();
at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
- if (at91_pm_data.ramc[1])
+ if (pm_data.ramc[1])
at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
}
@@ -290,7 +278,7 @@ static void at91sam9_sdram_standby(void)
u32 lpr0, lpr1 = 0;
u32 saved_lpr0, saved_lpr1 = 0;
- if (at91_pm_data.ramc[1]) {
+ if (pm_data.ramc[1]) {
saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -302,13 +290,13 @@ static void at91sam9_sdram_standby(void)
/* self-refresh mode now */
at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
- if (at91_pm_data.ramc[1])
+ if (pm_data.ramc[1])
at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
cpu_do_idle();
at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
- if (at91_pm_data.ramc[1])
+ if (pm_data.ramc[1])
at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
}
@@ -328,8 +316,8 @@ static __init void at91_dt_ramc(void)
const void *standby = NULL;
for_each_matching_node_and_match(np, ramc_ids, &of_id) {
- at91_pm_data.ramc[idx] = of_iomap(np, 0);
- if (!at91_pm_data.ramc[idx])
+ pm_data.ramc[idx] = of_iomap(np, 0);
+ if (!pm_data.ramc[idx])
panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
if (!standby)
@@ -355,12 +343,12 @@ static void at91rm9200_idle(void)
* Disable the processor clock. The processor will be automatically
* re-enabled by an interrupt or by a reset.
*/
- writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
+ writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
}
static void at91sam9_idle(void)
{
- writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
+ writel(AT91_PMC_PCK, pm_data.pmc + AT91_PMC_SCDR);
cpu_do_idle();
}
@@ -429,8 +417,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
platform_device_register(&at91_cpuidle_device);
pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
- at91_pm_data.pmc = of_iomap(pmc_np, 0);
- if (!at91_pm_data.pmc) {
+ pm_data.pmc = of_iomap(pmc_np, 0);
+ if (!pm_data.pmc) {
pr_err("AT91: PM not supported, PMC not found\n");
return;
}
@@ -455,8 +443,8 @@ void __init at91rm9200_pm_init(void)
*/
at91_ramc_write(0, AT91_MC_SDRAMC_LPR, 0);
- at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
- at91_pm_data.memctrl = AT91_MEMCTRL_MC;
+ pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
+ pm_data.memctrl = AT91_MEMCTRL_MC;
at91_pm_init(at91rm9200_idle);
}
@@ -464,31 +452,31 @@ void __init at91rm9200_pm_init(void)
void __init at91sam9260_pm_init(void)
{
at91_dt_ramc();
- at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
- at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
+ pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
at91_pm_init(at91sam9_idle);
}
void __init at91sam9g45_pm_init(void)
{
at91_dt_ramc();
- at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
- at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
+ pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
at91_pm_init(at91sam9_idle);
}
void __init at91sam9x5_pm_init(void)
{
at91_dt_ramc();
- at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
- at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
at91_pm_init(at91sam9_idle);
}
void __init sama5_pm_init(void)
{
at91_dt_ramc();
- at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
- at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
at91_pm_init(NULL);
}
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 8eed156ef19a..fc0f7d048187 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -21,12 +21,16 @@
#define AT91_MEMCTRL_SDRAMC 1
#define AT91_MEMCTRL_DDRSDR 2
-#define AT91_PM_MEMTYPE_MASK 0x0f
-
-#define AT91_PM_MODE_OFFSET 4
-#define AT91_PM_MODE_MASK 0x01
-#define AT91_PM_MODE(x) (((x) & AT91_PM_MODE_MASK) << AT91_PM_MODE_OFFSET)
-
#define AT91_PM_SLOW_CLOCK 0x01
+#ifndef __ASSEMBLY__
+struct at91_pm_data {
+ void __iomem *pmc;
+ void __iomem *ramc[2];
+ unsigned long uhp_udp_mask;
+ unsigned int memctrl;
+ unsigned int mode;
+};
+#endif
+
#endif
diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
new file mode 100644
index 000000000000..30302cb16df0
--- /dev/null
+++ b/arch/arm/mach-at91/pm_data-offsets.c
@@ -0,0 +1,13 @@
+#include <linux/stddef.h>
+#include <linux/kbuild.h>
+#include "pm.h"
+
+int main(void)
+{
+ DEFINE(PM_DATA_PMC, offsetof(struct at91_pm_data, pmc));
+ DEFINE(PM_DATA_RAMC0, offsetof(struct at91_pm_data, ramc[0]));
+ DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1]));
+ DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl));
+ DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode));
+ return 0;
+}
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index a25defda3d22..ed317657e760 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -14,6 +14,7 @@
#include <linux/linkage.h>
#include <linux/clk/at91_pmc.h>
#include "pm.h"
+#include "generated/at91_pm_data-offsets.h"
#define SRAMC_SELF_FRESH_ACTIVE 0x01
#define SRAMC_SELF_FRESH_EXIT 0x00
@@ -72,13 +73,9 @@ tmp2 .req r5
.arm
/*
- * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
- * void __iomem *ramc1, int memctrl)
+ * void at91_suspend_sram_fn(struct at91_pm_data*)
* @input param:
- * @r0: base address of AT91_PMC
- * @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
- * @r2: base address of second SDRAM Controller or 0 if not present
- * @r3: pm information
+ * @r0: base address of struct at91_pm_data
*/
/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
.align 3
@@ -90,16 +87,16 @@ ENTRY(at91_pm_suspend_in_sram)
mov tmp1, #0
mcr p15, 0, tmp1, c7, c10, 4
- str r0, .pmc_base
- str r1, .sramc_base
- str r2, .sramc1_base
-
- and r0, r3, #AT91_PM_MEMTYPE_MASK
- str r0, .memtype
-
- lsr r0, r3, #AT91_PM_MODE_OFFSET
- and r0, r0, #AT91_PM_MODE_MASK
- str r0, .pm_mode
+ ldr tmp1, [r0, #PM_DATA_PMC]
+ str tmp1, .pmc_base
+ ldr tmp1, [r0, #PM_DATA_RAMC0]
+ str tmp1, .sramc_base
+ ldr tmp1, [r0, #PM_DATA_RAMC1]
+ str tmp1, .sramc1_base
+ ldr tmp1, [r0, #PM_DATA_MEMCTRL]
+ str tmp1, .memtype
+ ldr tmp1, [r0, #PM_DATA_MODE]
+ str tmp1, .pm_mode
/* Active the self-refresh mode */
mov r0, #SRAMC_SELF_FRESH_ACTIVE
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| Date | 2017-02-02 16:00 +0100 |
| Subject | [PATCH 03/13] ARM: at91: pm: Move global variables into at91_pm_data |
| Message-ID | <t6r1E-5lK-35@gated-at.bofh.it> |
| In reply to | #1572430 |
Instead of having separate global variables to hold IP dresses, move them
to struct at91_pm_data.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/pm.c | 44 +++++++++++++++++++++-----------------------
1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ca141f9873f2..4253cd775738 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -26,8 +26,6 @@
#include "generic.h"
#include "pm.h"
-static void __iomem *pmc;
-
/*
* FIXME: this is needed to communicate between the pinctrl driver and
* the PM implementation in the machine. Possibly part of the PM
@@ -40,17 +38,17 @@ extern void at91_pinctrl_gpio_resume(void);
#endif
static struct {
+ void __iomem *pmc;
+ void __iomem *ramc[2];
unsigned long uhp_udp_mask;
int memctrl;
} at91_pm_data;
-void __iomem *at91_ramc_base[2];
#define at91_ramc_read(id, field) \
- __raw_readl(at91_ramc_base[id] + field)
+ __raw_readl(at91_pm_data.ramc[id] + field)
#define at91_ramc_write(id, field, value) \
- __raw_writel(value, at91_ramc_base[id] + field)
-
+ __raw_writel(value, at91_pm_data.ramc[id] + field)
static int at91_pm_valid_state(suspend_state_t state)
{
@@ -86,7 +84,7 @@ static int at91_pm_verify_clocks(void)
unsigned long scsr;
int i;
- scsr = readl(pmc + AT91_PMC_SCSR);
+ scsr = readl(at91_pm_data.pmc + AT91_PMC_SCSR);
/* USB must not be using PLLB */
if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
@@ -100,7 +98,7 @@ static int at91_pm_verify_clocks(void)
if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
continue;
- css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+ css = readl(at91_pm_data.pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
if (css != AT91_PMC_CSS_SLOW) {
pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
return 0;
@@ -143,8 +141,8 @@ static void at91_pm_suspend(suspend_state_t state)
flush_cache_all();
outer_disable();
- at91_suspend_sram_fn(pmc, at91_ramc_base[0],
- at91_ramc_base[1], pm_data);
+ at91_suspend_sram_fn(at91_pm_data.pmc, at91_pm_data.ramc[0],
+ at91_pm_data.ramc[1], pm_data);
outer_resume();
}
@@ -247,7 +245,7 @@ static void at91rm9200_standby(void)
" mcr p15, 0, %0, c7, c0, 4\n\t"
" str %5, [%1, %2]"
:
- : "r" (0), "r" (at91_ramc_base[0]), "r" (AT91_MC_SDRAMC_LPR),
+ : "r" (0), "r" (at91_pm_data.ramc[0]), "r" (AT91_MC_SDRAMC_LPR),
"r" (1), "r" (AT91_MC_SDRAMC_SRR),
"r" (lpr));
}
@@ -262,7 +260,7 @@ static void at91_ddr_standby(void)
u32 lpr0, lpr1 = 0;
u32 saved_lpr0, saved_lpr1 = 0;
- if (at91_ramc_base[1]) {
+ if (at91_pm_data.ramc[1]) {
saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
@@ -274,13 +272,13 @@ static void at91_ddr_standby(void)
/* self-refresh mode now */
at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
- if (at91_ramc_base[1])
+ if (at91_pm_data.ramc[1])
at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
cpu_do_idle();
at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
- if (at91_ramc_base[1])
+ if (at91_pm_data.ramc[1])
at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
}
@@ -292,7 +290,7 @@ static void at91sam9_sdram_standby(void)
u32 lpr0, lpr1 = 0;
u32 saved_lpr0, saved_lpr1 = 0;
- if (at91_ramc_base[1]) {
+ if (at91_pm_data.ramc[1]) {
saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
@@ -304,13 +302,13 @@ static void at91sam9_sdram_standby(void)
/* self-refresh mode now */
at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
- if (at91_ramc_base[1])
+ if (at91_pm_data.ramc[1])
at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
cpu_do_idle();
at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
- if (at91_ramc_base[1])
+ if (at91_pm_data.ramc[1])
at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
}
@@ -330,8 +328,8 @@ static __init void at91_dt_ramc(void)
const void *standby = NULL;
for_each_matching_node_and_match(np, ramc_ids, &of_id) {
- at91_ramc_base[idx] = of_iomap(np, 0);
- if (!at91_ramc_base[idx])
+ at91_pm_data.ramc[idx] = of_iomap(np, 0);
+ if (!at91_pm_data.ramc[idx])
panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
if (!standby)
@@ -357,12 +355,12 @@ static void at91rm9200_idle(void)
* Disable the processor clock. The processor will be automatically
* re-enabled by an interrupt or by a reset.
*/
- writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+ writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
}
static void at91sam9_idle(void)
{
- writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+ writel(AT91_PMC_PCK, at91_pm_data.pmc + AT91_PMC_SCDR);
cpu_do_idle();
}
@@ -431,8 +429,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
platform_device_register(&at91_cpuidle_device);
pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
- pmc = of_iomap(pmc_np, 0);
- if (!pmc) {
+ at91_pm_data.pmc = of_iomap(pmc_np, 0);
+ if (!at91_pm_data.pmc) {
pr_err("AT91: PM not supported, PMC not found\n");
return;
}
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Alexandre Belloni <alexandre.belloni@free-electrons.com> |
|---|---|
| Date | 2017-02-02 16:00 +0100 |
| Subject | [PATCH 02/13] ARM: at91: pm: move at91_ramc_read/write to pm.c |
| Message-ID | <t6r1E-5lK-39@gated-at.bofh.it> |
| In reply to | #1572430 |
Those macros are only used in pm.c, move them there so we can remove the
test on __ASSEMBLY__.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/pm.c | 6 ++++++
arch/arm/mach-at91/pm.h | 10 ----------
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 3d28d1957e41..ca141f9873f2 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -45,6 +45,12 @@ static struct {
} at91_pm_data;
void __iomem *at91_ramc_base[2];
+#define at91_ramc_read(id, field) \
+ __raw_readl(at91_ramc_base[id] + field)
+
+#define at91_ramc_write(id, field, value) \
+ __raw_writel(value, at91_ramc_base[id] + field)
+
static int at91_pm_valid_state(suspend_state_t state)
{
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 3fcf8810f14e..8eed156ef19a 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -17,16 +17,6 @@
#include <soc/at91/at91sam9_ddrsdr.h>
#include <soc/at91/at91sam9_sdramc.h>
-#ifndef __ASSEMBLY__
-extern void __iomem *at91_ramc_base[];
-
-#define at91_ramc_read(id, field) \
- __raw_readl(at91_ramc_base[id] + field)
-
-#define at91_ramc_write(id, field, value) \
- __raw_writel(value, at91_ramc_base[id] + field)
-#endif
-
#define AT91_MEMCTRL_MC 0
#define AT91_MEMCTRL_SDRAMC 1
#define AT91_MEMCTRL_DDRSDR 2
--
2.11.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web