* [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1
@ 2015-03-09 3:47 Wenyou Yang
2015-03-09 3:48 ` [PATCH v2.0 1/6] pm: at91: pm_slowclock: create the procedure to handle the sdram self-refresh Wenyou Yang
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Wenyou Yang @ 2015-03-09 3:47 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
The patch series purpose is to improve the AT91 pm code.
Create a procedure to handle the sdram self-fresh mode.
The standby mode uses same sram function as the suspend to memory mode,
It is based on the branch, at91-4.0-fixes
git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
+ [PATCH] ARM: AT91: pm cleanup for 4.1
Chang log for v2.0
- reserve the at91_xxx_standby() for at91_cpuidle_device.
- rebase
Wenyou Yang (6):
pm: at91: pm_slowclock: create the procedure to handle the sdram
self-refresh
pm: at91: move the copying the sram function to the sram
initializationi phase
pm: at91: standby mode uses the same sram function as suspend to
memory mode
pm: at91: rename file name: pm_slowclock.S -->pm_suspend.S
pm: at91: rename function name:
at91_slow_clock()-->at91_pm_suspend_sram_fn
pm: at91: remove unused void (*at91_pm_standby)(void)
arch/arm/mach-at91/Makefile | 2 +-
arch/arm/mach-at91/pm.c | 121 +++++++------
arch/arm/mach-at91/pm.h | 10 ++
arch/arm/mach-at91/pm_slowclock.S | 296 -------------------------------
arch/arm/mach-at91/pm_suspend.S | 349 +++++++++++++++++++++++++++++++++++++
5 files changed, 420 insertions(+), 358 deletions(-)
delete mode 100644 arch/arm/mach-at91/pm_slowclock.S
create mode 100644 arch/arm/mach-at91/pm_suspend.S
--
1.7.9.5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2.0 1/6] pm: at91: pm_slowclock: create the procedure to handle the sdram self-refresh
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
@ 2015-03-09 3:48 ` Wenyou Yang
2015-03-09 3:49 ` [PATCH v2.0 2/6] pm: at91: move the copying the sram function to the sram initializationi phase Wenyou Yang
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Wenyou Yang @ 2015-03-09 3:48 UTC (permalink / raw)
To: linux-arm-kernel
To decrease the duplicated code, create the procedure
to contain both activing and exiting the sdram self-refresh mode.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
arch/arm/mach-at91/pm_slowclock.S | 240 +++++++++++++++++++++----------------
1 file changed, 137 insertions(+), 103 deletions(-)
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index ae86fca..517e344 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -16,10 +16,10 @@
#include <mach/hardware.h>
#include <mach/at91_ramc.h>
+#define SRAMC_SELF_FRESH_ACTIVE 0x01
+#define SRAMC_SELF_FRESH_EXIT 0x00
+
pmc .req r0
-sdramc .req r1
-ramc1 .req r2
-memctrl .req r3
tmp1 .req r4
tmp2 .req r5
@@ -82,78 +82,17 @@ ENTRY(at91_slow_clock)
mov tmp1, #0
mcr p15, 0, tmp1, c7, c10, 4
- cmp memctrl, #AT91_MEMCTRL_MC
- bne ddr_sr_enable
+ str r0, .pmc_base
+ str r1, .sramc_base
+ str r2, .sramc1_base
+ str r3, .memtype
- /*
- * at91rm9200 Memory controller
- */
- /* Put SDRAM in self-refresh mode */
- mov tmp1, #1
- str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
- b sdr_sr_done
+ /* Active the self-refresh mode */
+ mov r0, #SRAMC_SELF_FRESH_ACTIVE
+ bl at91_sramc_self_refresh
- /*
- * DDRSDR Memory controller
- */
-ddr_sr_enable:
- cmp memctrl, #AT91_MEMCTRL_DDRSDR
- bne sdr_sr_enable
+ ldr pmc, .pmc_base
- /* LPDDR1 --> force DDR2 mode during self-refresh */
- ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR]
- str tmp1, .saved_sam9_mdr
- bic tmp1, tmp1, #~AT91_DDRSDRC_MD
- cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
- ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
- biceq tmp1, tmp1, #AT91_DDRSDRC_MD
- orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
- streq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
-
- /* prepare for DDRAM self-refresh mode */
- ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
- str tmp1, .saved_sam9_lpr
- bic tmp1, #AT91_DDRSDRC_LPCB
- orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
-
- /* figure out if we use the second ram controller */
- cmp ramc1, #0
- beq ddr_no_2nd_ctrl
-
- ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
- str tmp2, .saved_sam9_mdr1
- bic tmp2, tmp2, #~AT91_DDRSDRC_MD
- cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
- ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
- biceq tmp2, tmp2, #AT91_DDRSDRC_MD
- orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
- streq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
-
- ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR]
- str tmp2, .saved_sam9_lpr1
- bic tmp2, #AT91_DDRSDRC_LPCB
- orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
-
- /* Enable DDRAM self-refresh mode */
- str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
-ddr_no_2nd_ctrl:
- str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
-
- b sdr_sr_done
-
- /*
- * SDRAMC Memory controller
- */
-sdr_sr_enable:
- /* Enable SDRAM self-refresh mode */
- ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
- str tmp1, .saved_sam9_lpr
-
- bic tmp1, #AT91_SDRAMC_LPCB
- orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
- str tmp1, [sdramc, #AT91_SDRAMC_LPR]
-
-sdr_sr_done:
/* Save Master clock setting */
ldr tmp1, [pmc, #AT91_PMC_MCKR]
str tmp1, .saved_mckr
@@ -225,70 +164,165 @@ sdr_sr_done:
/*
* Restore master clock setting
*/
-2: ldr tmp1, .saved_mckr
+ ldr tmp1, .saved_mckr
str tmp1, [pmc, #AT91_PMC_MCKR]
wait_mckrdy
+ /* Exit the self-refresh mode */
+ mov r0, #SRAMC_SELF_FRESH_EXIT
+ bl at91_sramc_self_refresh
+
+ /* Restore registers, and return */
+ ldmfd sp!, {r4 - r12, pc}
+ENDPROC(at91_slow_clock)
+
+/*
+ * void at91_sramc_self_refresh(unsigned int is_active)
+ *
+ * @input param:
+ * @r0: 1 - active self-refresh mode
+ * 0 - exit self-refresh mode
+ * register usage:
+ * @r1: memory type
+ * @r2: base address of the sram controller
+ */
+
+ENTRY(at91_sramc_self_refresh)
+ ldr r1, .memtype
+ ldr r2, .sramc_base
+
+ cmp r1, #AT91_MEMCTRL_MC
+ bne ddrc_sf
+
/*
* at91rm9200 Memory controller
- * Do nothing - self-refresh is automatically disabled.
*/
- cmp memctrl, #AT91_MEMCTRL_MC
- beq ram_restored
+
+ /*
+ * For exiting the self-refresh mode, do nothing,
+ * automatically exit the self-refresh mode.
+ */
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq exit_sramc_sf
+
+ /* Active SDRAM self-refresh mode */
+ mov r3, #1
+ str r3, [r2, #AT91RM9200_SDRAMC_SRR]
+ b exit_sramc_sf
+
+ddrc_sf:
+ cmp r1, #AT91_MEMCTRL_DDRSDR
+ bne sdramc_sf
/*
- * DDRSDR Memory controller
+ * DDR Memory controller
*/
- cmp memctrl, #AT91_MEMCTRL_DDRSDR
- bne sdr_en_restore
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq ddrc_exit_sf
+
+ /* LPDDR1 --> force DDR2 mode during self-refresh */
+ ldr r3, [r2, #AT91_DDRSDRC_MDR]
+ str r3, .saved_sam9_mdr
+ bic r3, r3, #~AT91_DDRSDRC_MD
+ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+ ldreq r3, [r2, #AT91_DDRSDRC_MDR]
+ biceq r3, r3, #AT91_DDRSDRC_MD
+ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
+ streq r3, [r2, #AT91_DDRSDRC_MDR]
+
+ /* Active DDRC self-refresh mode */
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr
+ bic r3, r3, #AT91_DDRSDRC_LPCB
+ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+ /* If using the 2nd ddr controller */
+ ldr r2, .sramc1_base
+ cmp r2, #0
+ beq no_2nd_ddrc
+
+ ldr r3, [r2, #AT91_DDRSDRC_MDR]
+ str r3, .saved_sam9_mdr1
+ bic r3, r3, #~AT91_DDRSDRC_MD
+ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+ ldreq r3, [r2, #AT91_DDRSDRC_MDR]
+ biceq r3, r3, #AT91_DDRSDRC_MD
+ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
+ streq r3, [r2, #AT91_DDRSDRC_MDR]
+
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr1
+ bic r3, r3, #AT91_DDRSDRC_LPCB
+ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+ /* Active DDRC self-refresh mode */
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+no_2nd_ddrc:
+ b exit_sramc_sf
+
+ddrc_exit_sf:
/* Restore MDR in case of LPDDR1 */
- ldr tmp1, .saved_sam9_mdr
- str tmp1, [sdramc, #AT91_DDRSDRC_MDR]
+ ldr r3, .saved_sam9_mdr
+ str r3, [r2, #AT91_DDRSDRC_MDR]
/* Restore LPR on AT91 with DDRAM */
- ldr tmp1, .saved_sam9_lpr
- str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_DDRSDRC_LPR]
- /* if we use the second ram controller */
- cmp ramc1, #0
- ldrne tmp2, .saved_sam9_mdr1
- strne tmp2, [ramc1, #AT91_DDRSDRC_MDR]
- ldrne tmp2, .saved_sam9_lpr1
- strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
+ /* If using the 2nd ddr controller */
+ ldr r2, .sramc1_base
+ cmp r2, #0
+ ldrne r3, .saved_sam9_mdr1
+ strne r3, [r2, #AT91_DDRSDRC_MDR]
+ ldrne r3, .saved_sam9_lpr1
+ strne r3, [r2, #AT91_DDRSDRC_LPR]
- b ram_restored
+ b exit_sramc_sf
/*
* SDRAMC Memory controller
*/
-sdr_en_restore:
- /* Restore LPR on AT91 with SDRAM */
- ldr tmp1, .saved_sam9_lpr
- str tmp1, [sdramc, #AT91_SDRAMC_LPR]
+sdramc_sf:
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq sdramc_exit_sf
-ram_restored:
- /* Restore registers, and return */
- ldmfd sp!, {r4 - r12, pc}
+ /* Active SDRAMC self-refresh mode */
+ ldr r3, [r2, #AT91_SDRAMC_LPR]
+ str r3, .saved_sam9_lpr
+
+ bic r3, r3, #AT91_SDRAMC_LPCB
+ orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_SDRAMC_LPR]
+
+sdramc_exit_sf:
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_SDRAMC_LPR]
+exit_sramc_sf:
+ mov pc, lr
+ENDPROC(at91_sramc_self_refresh)
+.pmc_base:
+ .word 0
+.sramc_base:
+ .word 0
+.sramc1_base:
+ .word 0
+.memtype:
+ .word 0
.saved_mckr:
.word 0
-
.saved_pllar:
.word 0
-
.saved_pllbr:
.word 0
-
.saved_sam9_lpr:
.word 0
-
.saved_sam9_lpr1:
.word 0
-
.saved_sam9_mdr:
.word 0
-
.saved_sam9_mdr1:
.word 0
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2.0 2/6] pm: at91: move the copying the sram function to the sram initializationi phase
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
2015-03-09 3:48 ` [PATCH v2.0 1/6] pm: at91: pm_slowclock: create the procedure to handle the sdram self-refresh Wenyou Yang
@ 2015-03-09 3:49 ` Wenyou Yang
2015-03-09 3:49 ` [PATCH v2.0 3/6] pm: at91: standby mode uses same sram function as suspend to memory mode Wenyou Yang
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Wenyou Yang @ 2015-03-09 3:49 UTC (permalink / raw)
To: linux-arm-kernel
To decrease the suspend time, move copying the sram function to the sram
initialization phase, instead of every time go to suspend.
In the meanwhile, substitute fncpy() for memcpy().
If there is no sram allocated for PM, the PM is not supported.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/pm.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ea4d888..7cb3a33 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -29,6 +29,7 @@
#include <linux/atomic.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
+#include <asm/fncpy.h>
#include <mach/cpu.h>
#include <mach/hardware.h>
@@ -149,9 +150,6 @@ static int at91_pm_enter(suspend_state_t state)
* turning off the main oscillator; reverse on wakeup.
*/
if (slow_clock) {
- /* copy slow_clock handler to SRAM, and call it */
- memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
-
slow_clock(at91_pmc_base, at91_ramc_base[0],
at91_ramc_base[1],
at91_pm_data.memctrl);
@@ -295,6 +293,13 @@ static void __init at91_pm_sram_init(void)
sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false);
+ if (!slow_clock) {
+ pr_warn("SRAM: Could not map\n");
+ return;
+ }
+
+ /* Copy the slow_clock handler to SRAM */
+ slow_clock = fncpy(slow_clock, &at91_slow_clock, at91_slow_clock_sz);
}
static void __init at91_pm_init(void)
@@ -304,7 +309,10 @@ static void __init at91_pm_init(void)
if (at91_cpuidle_device.dev.platform_data)
platform_device_register(&at91_cpuidle_device);
- suspend_set_ops(&at91_pm_ops);
+ if (slow_clock)
+ suspend_set_ops(&at91_pm_ops);
+ else
+ pr_info("AT91: PM not supported, due to no SRAM allocated\n");
}
void __init at91rm9200_pm_init(void)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2.0 3/6] pm: at91: standby mode uses same sram function as suspend to memory mode
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
2015-03-09 3:48 ` [PATCH v2.0 1/6] pm: at91: pm_slowclock: create the procedure to handle the sdram self-refresh Wenyou Yang
2015-03-09 3:49 ` [PATCH v2.0 2/6] pm: at91: move the copying the sram function to the sram initializationi phase Wenyou Yang
@ 2015-03-09 3:49 ` Wenyou Yang
2015-03-09 3:50 ` [PATCH v2.0 4/6] pm: at91: rename file name: pm_slowclock.S -->pm_suspend.S Wenyou Yang
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Wenyou Yang @ 2015-03-09 3:49 UTC (permalink / raw)
To: linux-arm-kernel
To simply the PM code, the suspend to standby mode uses same sram function
as the suspend to memory mode, running in the internal SRAM, instead of the
respective code for each mode.
For the suspend to standby mode, the master clock doesn't switch to the slow
clock, and PLLA and the main oscillator doesn't turn off as well.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
arch/arm/mach-at91/pm.c | 85 +++++++++++++++++--------------------
arch/arm/mach-at91/pm.h | 10 +++++
arch/arm/mach-at91/pm_slowclock.S | 25 ++++++++++-
3 files changed, 73 insertions(+), 47 deletions(-)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 7cb3a33..3fc5e12 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -128,62 +128,55 @@ extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl);
extern u32 at91_slow_clock_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;
+
+ slow_clock(at91_pmc_base, at91_ramc_base[0],
+ at91_ramc_base[1], pm_data);
+}
+
static int at91_pm_enter(suspend_state_t state)
{
at91_pinctrl_gpio_suspend();
switch (state) {
+ /*
+ * Suspend-to-RAM is like STANDBY plus slow clock mode, so
+ * drivers must suspend more deeply, the master clock switches
+ * to the clk32k and turns off the main oscillator
+ */
+ case PM_SUSPEND_MEM:
/*
- * Suspend-to-RAM is like STANDBY plus slow clock mode, so
- * drivers must suspend more deeply: only the master clock
- * controller may be using the main oscillator.
+ * Ensure that clocks are in a valid state.
*/
- case PM_SUSPEND_MEM:
- /*
- * Ensure that clocks are in a valid state.
- */
- if (!at91_pm_verify_clocks())
- goto error;
-
- /*
- * Enter slow clock mode by switching over to clk32k and
- * turning off the main oscillator; reverse on wakeup.
- */
- if (slow_clock) {
- slow_clock(at91_pmc_base, at91_ramc_base[0],
- at91_ramc_base[1],
- at91_pm_data.memctrl);
- break;
- } else {
- pr_info("AT91: PM - no slow clock mode enabled ...\n");
- /* FALLTHROUGH leaving master clock alone */
- }
+ if (!at91_pm_verify_clocks())
+ goto error;
- /*
- * STANDBY mode has *all* drivers suspended; ignores irqs not
- * marked as 'wakeup' event sources; and reduces DRAM power.
- * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and
- * nothing fancy done with main or cpu clocks.
- */
- case PM_SUSPEND_STANDBY:
- /*
- * NOTE: the Wait-for-Interrupt instruction needs to be
- * in icache so no SDRAM accesses are needed until the
- * wakeup IRQ occurs and self-refresh is terminated.
- * For ARM 926 based chips, this requirement is weaker
- * as at91sam9 can access a RAM in self-refresh mode.
- */
- if (at91_pm_standby)
- at91_pm_standby();
- break;
+ at91_pm_suspend(state);
- case PM_SUSPEND_ON:
- cpu_do_idle();
- break;
+ break;
- default:
- pr_debug("AT91: PM - bogus suspend state %d\n", state);
- goto error;
+ /*
+ * STANDBY mode has *all* drivers suspended; ignores irqs not
+ * marked as 'wakeup' event sources; and reduces DRAM power.
+ * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and
+ * nothing fancy done with main or cpu clocks.
+ */
+ case PM_SUSPEND_STANDBY:
+ at91_pm_suspend(state);
+ break;
+
+ case PM_SUSPEND_ON:
+ cpu_do_idle();
+ break;
+
+ default:
+ pr_debug("AT91: PM - bogus suspend state %d\n", state);
+ goto error;
}
error:
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 86a9d0b..dcacfa1 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -15,6 +15,14 @@
#include <mach/at91_ramc.h>
+#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
+
/*
* The AT91RM9200 goes into self-refresh mode with this command, and will
* terminate self-refresh automatically on the next SDRAM access.
@@ -25,6 +33,7 @@
* still in self-refresh is "not recommended", but seems to work.
*/
+#ifndef __ASSEMBLY__
static inline void at91rm9200_standby(void)
{
u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR);
@@ -106,3 +115,4 @@ static inline void at91sam9_sdram_standby(void)
}
#endif
+#endif
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 517e344..b0939c8 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -15,6 +15,7 @@
#include <linux/clk/at91_pmc.h>
#include <mach/hardware.h>
#include <mach/at91_ramc.h>
+#include "pm.h"
#define SRAMC_SELF_FRESH_ACTIVE 0x01
#define SRAMC_SELF_FRESH_EXIT 0x00
@@ -85,12 +86,22 @@ ENTRY(at91_slow_clock)
str r0, .pmc_base
str r1, .sramc_base
str r2, .sramc1_base
- str r3, .memtype
+
+ 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
/* Active the self-refresh mode */
mov r0, #SRAMC_SELF_FRESH_ACTIVE
bl at91_sramc_self_refresh
+ ldr r0, .pm_mode
+ tst r0, #AT91_PM_SLOW_CLOCK
+ beq skip_disable_main_clock
+
ldr pmc, .pmc_base
/* Save Master clock setting */
@@ -126,9 +137,18 @@ ENTRY(at91_slow_clock)
orr tmp1, tmp1, #AT91_PMC_KEY
str tmp1, [pmc, #AT91_CKGR_MOR]
+skip_disable_main_clock:
+ ldr pmc, .pmc_base
+
/* Wait for interrupt */
mcr p15, 0, tmp1, c7, c0, 4
+ ldr r0, .pm_mode
+ tst r0, #AT91_PM_SLOW_CLOCK
+ beq skip_enable_main_clock
+
+ ldr pmc, .pmc_base
+
/* Turn on the main oscillator */
ldr tmp1, [pmc, #AT91_CKGR_MOR]
orr tmp1, tmp1, #AT91_PMC_MOSCEN
@@ -169,6 +189,7 @@ ENTRY(at91_slow_clock)
wait_mckrdy
+skip_enable_main_clock:
/* Exit the self-refresh mode */
mov r0, #SRAMC_SELF_FRESH_EXIT
bl at91_sramc_self_refresh
@@ -311,6 +332,8 @@ ENDPROC(at91_sramc_self_refresh)
.word 0
.memtype:
.word 0
+.pm_mode:
+ .word 0
.saved_mckr:
.word 0
.saved_pllar:
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2.0 4/6] pm: at91: rename file name: pm_slowclock.S -->pm_suspend.S
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
` (2 preceding siblings ...)
2015-03-09 3:49 ` [PATCH v2.0 3/6] pm: at91: standby mode uses same sram function as suspend to memory mode Wenyou Yang
@ 2015-03-09 3:50 ` Wenyou Yang
2015-03-09 3:51 ` [PATCH v2.0 5/6] pm: at91: rename function name: at91_slow_clock()-->at91_pm_suspend_sram_fn Wenyou Yang
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Wenyou Yang @ 2015-03-09 3:50 UTC (permalink / raw)
To: linux-arm-kernel
Because the sram function is used for both suspend to memory and the suspend
to standby mode, renaming is more elegant.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/Makefile | 2 +-
arch/arm/mach-at91/pm_slowclock.S | 353 -------------------------------------
arch/arm/mach-at91/pm_suspend.S | 353 +++++++++++++++++++++++++++++++++++++
3 files changed, 354 insertions(+), 354 deletions(-)
delete mode 100644 arch/arm/mach-at91/pm_slowclock.S
create mode 100644 arch/arm/mach-at91/pm_suspend.S
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 103c256..7df8c854 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_SOC_SAMA5) += sama5.o
# Power Management
obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += pm_slowclock.o
+obj-$(CONFIG_PM) += pm_suspend.o
ifeq ($(CONFIG_PM_DEBUG),y)
CFLAGS_pm.o += -DDEBUG
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
deleted file mode 100644
index b0939c8..0000000
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * arch/arm/mach-at91/pm_slow_clock.S
- *
- * Copyright (C) 2006 Savin Zlobec
- *
- * AT91SAM9 support:
- * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/linkage.h>
-#include <linux/clk/at91_pmc.h>
-#include <mach/hardware.h>
-#include <mach/at91_ramc.h>
-#include "pm.h"
-
-#define SRAMC_SELF_FRESH_ACTIVE 0x01
-#define SRAMC_SELF_FRESH_EXIT 0x00
-
-pmc .req r0
-tmp1 .req r4
-tmp2 .req r5
-
-/*
- * Wait until master clock is ready (after switching master clock source)
- */
- .macro wait_mckrdy
-1: ldr tmp1, [pmc, #AT91_PMC_SR]
- tst tmp1, #AT91_PMC_MCKRDY
- beq 1b
- .endm
-
-/*
- * Wait until master oscillator has stabilized.
- */
- .macro wait_moscrdy
-1: ldr tmp1, [pmc, #AT91_PMC_SR]
- tst tmp1, #AT91_PMC_MOSCS
- beq 1b
- .endm
-
-/*
- * Wait until PLLA has locked.
- */
- .macro wait_pllalock
-1: ldr tmp1, [pmc, #AT91_PMC_SR]
- tst tmp1, #AT91_PMC_LOCKA
- beq 1b
- .endm
-
-/*
- * Wait until PLLB has locked.
- */
- .macro wait_pllblock
-1: ldr tmp1, [pmc, #AT91_PMC_SR]
- tst tmp1, #AT91_PMC_LOCKB
- beq 1b
- .endm
-
- .text
-
-/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
- * void __iomem *ramc1, int memctrl)
- */
-ENTRY(at91_slow_clock)
- /* Save registers on stack */
- stmfd sp!, {r4 - r12, lr}
-
- /*
- * Register usage:
- * R0 = Base address of AT91_PMC
- * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
- * R2 = Base address of second RAM Controller or 0 if not present
- * R3 = Memory controller
- * R4 = temporary register
- * R5 = temporary register
- */
-
- /* Drain write buffer */
- 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
-
- /* Active the self-refresh mode */
- mov r0, #SRAMC_SELF_FRESH_ACTIVE
- bl at91_sramc_self_refresh
-
- ldr r0, .pm_mode
- tst r0, #AT91_PM_SLOW_CLOCK
- beq skip_disable_main_clock
-
- ldr pmc, .pmc_base
-
- /* Save Master clock setting */
- ldr tmp1, [pmc, #AT91_PMC_MCKR]
- str tmp1, .saved_mckr
-
- /*
- * Set the Master clock source to slow clock
- */
- bic tmp1, tmp1, #AT91_PMC_CSS
- str tmp1, [pmc, #AT91_PMC_MCKR]
-
- wait_mckrdy
-
- /* Save PLLA setting and disable it */
- ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
- str tmp1, .saved_pllar
-
- mov tmp1, #AT91_PMC_PLLCOUNT
- orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
- str tmp1, [pmc, #AT91_CKGR_PLLAR]
-
- /* Save PLLB setting and disable it */
- ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
- str tmp1, .saved_pllbr
-
- mov tmp1, #AT91_PMC_PLLCOUNT
- str tmp1, [pmc, #AT91_CKGR_PLLBR]
-
- /* Turn off the main oscillator */
- ldr tmp1, [pmc, #AT91_CKGR_MOR]
- bic tmp1, tmp1, #AT91_PMC_MOSCEN
- orr tmp1, tmp1, #AT91_PMC_KEY
- str tmp1, [pmc, #AT91_CKGR_MOR]
-
-skip_disable_main_clock:
- ldr pmc, .pmc_base
-
- /* Wait for interrupt */
- mcr p15, 0, tmp1, c7, c0, 4
-
- ldr r0, .pm_mode
- tst r0, #AT91_PM_SLOW_CLOCK
- beq skip_enable_main_clock
-
- ldr pmc, .pmc_base
-
- /* Turn on the main oscillator */
- ldr tmp1, [pmc, #AT91_CKGR_MOR]
- orr tmp1, tmp1, #AT91_PMC_MOSCEN
- orr tmp1, tmp1, #AT91_PMC_KEY
- str tmp1, [pmc, #AT91_CKGR_MOR]
-
- wait_moscrdy
-
- /* Restore PLLB setting */
- ldr tmp1, .saved_pllbr
- str tmp1, [pmc, #AT91_CKGR_PLLBR]
-
- tst tmp1, #(AT91_PMC_MUL & 0xff0000)
- bne 1f
- tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
- beq 2f
-1:
- wait_pllblock
-2:
-
- /* Restore PLLA setting */
- ldr tmp1, .saved_pllar
- str tmp1, [pmc, #AT91_CKGR_PLLAR]
-
- tst tmp1, #(AT91_PMC_MUL & 0xff0000)
- bne 3f
- tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
- beq 4f
-3:
- wait_pllalock
-4:
-
- /*
- * Restore master clock setting
- */
- ldr tmp1, .saved_mckr
- str tmp1, [pmc, #AT91_PMC_MCKR]
-
- wait_mckrdy
-
-skip_enable_main_clock:
- /* Exit the self-refresh mode */
- mov r0, #SRAMC_SELF_FRESH_EXIT
- bl at91_sramc_self_refresh
-
- /* Restore registers, and return */
- ldmfd sp!, {r4 - r12, pc}
-ENDPROC(at91_slow_clock)
-
-/*
- * void at91_sramc_self_refresh(unsigned int is_active)
- *
- * @input param:
- * @r0: 1 - active self-refresh mode
- * 0 - exit self-refresh mode
- * register usage:
- * @r1: memory type
- * @r2: base address of the sram controller
- */
-
-ENTRY(at91_sramc_self_refresh)
- ldr r1, .memtype
- ldr r2, .sramc_base
-
- cmp r1, #AT91_MEMCTRL_MC
- bne ddrc_sf
-
- /*
- * at91rm9200 Memory controller
- */
-
- /*
- * For exiting the self-refresh mode, do nothing,
- * automatically exit the self-refresh mode.
- */
- tst r0, #SRAMC_SELF_FRESH_ACTIVE
- beq exit_sramc_sf
-
- /* Active SDRAM self-refresh mode */
- mov r3, #1
- str r3, [r2, #AT91RM9200_SDRAMC_SRR]
- b exit_sramc_sf
-
-ddrc_sf:
- cmp r1, #AT91_MEMCTRL_DDRSDR
- bne sdramc_sf
-
- /*
- * DDR Memory controller
- */
- tst r0, #SRAMC_SELF_FRESH_ACTIVE
- beq ddrc_exit_sf
-
- /* LPDDR1 --> force DDR2 mode during self-refresh */
- ldr r3, [r2, #AT91_DDRSDRC_MDR]
- str r3, .saved_sam9_mdr
- bic r3, r3, #~AT91_DDRSDRC_MD
- cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
- ldreq r3, [r2, #AT91_DDRSDRC_MDR]
- biceq r3, r3, #AT91_DDRSDRC_MD
- orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
- streq r3, [r2, #AT91_DDRSDRC_MDR]
-
- /* Active DDRC self-refresh mode */
- ldr r3, [r2, #AT91_DDRSDRC_LPR]
- str r3, .saved_sam9_lpr
- bic r3, r3, #AT91_DDRSDRC_LPCB
- orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
- str r3, [r2, #AT91_DDRSDRC_LPR]
-
- /* If using the 2nd ddr controller */
- ldr r2, .sramc1_base
- cmp r2, #0
- beq no_2nd_ddrc
-
- ldr r3, [r2, #AT91_DDRSDRC_MDR]
- str r3, .saved_sam9_mdr1
- bic r3, r3, #~AT91_DDRSDRC_MD
- cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
- ldreq r3, [r2, #AT91_DDRSDRC_MDR]
- biceq r3, r3, #AT91_DDRSDRC_MD
- orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
- streq r3, [r2, #AT91_DDRSDRC_MDR]
-
- ldr r3, [r2, #AT91_DDRSDRC_LPR]
- str r3, .saved_sam9_lpr1
- bic r3, r3, #AT91_DDRSDRC_LPCB
- orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
-
- /* Active DDRC self-refresh mode */
- str r3, [r2, #AT91_DDRSDRC_LPR]
-no_2nd_ddrc:
- b exit_sramc_sf
-
-ddrc_exit_sf:
- /* Restore MDR in case of LPDDR1 */
- ldr r3, .saved_sam9_mdr
- str r3, [r2, #AT91_DDRSDRC_MDR]
- /* Restore LPR on AT91 with DDRAM */
- ldr r3, .saved_sam9_lpr
- str r3, [r2, #AT91_DDRSDRC_LPR]
-
- /* If using the 2nd ddr controller */
- ldr r2, .sramc1_base
- cmp r2, #0
- ldrne r3, .saved_sam9_mdr1
- strne r3, [r2, #AT91_DDRSDRC_MDR]
- ldrne r3, .saved_sam9_lpr1
- strne r3, [r2, #AT91_DDRSDRC_LPR]
-
- b exit_sramc_sf
-
- /*
- * SDRAMC Memory controller
- */
-sdramc_sf:
- tst r0, #SRAMC_SELF_FRESH_ACTIVE
- beq sdramc_exit_sf
-
- /* Active SDRAMC self-refresh mode */
- ldr r3, [r2, #AT91_SDRAMC_LPR]
- str r3, .saved_sam9_lpr
-
- bic r3, r3, #AT91_SDRAMC_LPCB
- orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
- str r3, [r2, #AT91_SDRAMC_LPR]
-
-sdramc_exit_sf:
- ldr r3, .saved_sam9_lpr
- str r3, [r2, #AT91_SDRAMC_LPR]
-
-exit_sramc_sf:
- mov pc, lr
-ENDPROC(at91_sramc_self_refresh)
-
-.pmc_base:
- .word 0
-.sramc_base:
- .word 0
-.sramc1_base:
- .word 0
-.memtype:
- .word 0
-.pm_mode:
- .word 0
-.saved_mckr:
- .word 0
-.saved_pllar:
- .word 0
-.saved_pllbr:
- .word 0
-.saved_sam9_lpr:
- .word 0
-.saved_sam9_lpr1:
- .word 0
-.saved_sam9_mdr:
- .word 0
-.saved_sam9_mdr1:
- .word 0
-
-ENTRY(at91_slow_clock_sz)
- .word .-at91_slow_clock
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
new file mode 100644
index 0000000..a2bd1dc
--- /dev/null
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -0,0 +1,353 @@
+/*
+ * arch/arm/mach-at91/pm_suspend.S
+ *
+ * Copyright (C) 2006 Savin Zlobec
+ *
+ * AT91SAM9 support:
+ * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/linkage.h>
+#include <linux/clk/at91_pmc.h>
+#include <mach/hardware.h>
+#include <mach/at91_ramc.h>
+#include "pm.h"
+
+#define SRAMC_SELF_FRESH_ACTIVE 0x01
+#define SRAMC_SELF_FRESH_EXIT 0x00
+
+pmc .req r0
+tmp1 .req r4
+tmp2 .req r5
+
+/*
+ * Wait until master clock is ready (after switching master clock source)
+ */
+ .macro wait_mckrdy
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+ tst tmp1, #AT91_PMC_MCKRDY
+ beq 1b
+ .endm
+
+/*
+ * Wait until master oscillator has stabilized.
+ */
+ .macro wait_moscrdy
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+ tst tmp1, #AT91_PMC_MOSCS
+ beq 1b
+ .endm
+
+/*
+ * Wait until PLLA has locked.
+ */
+ .macro wait_pllalock
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+ tst tmp1, #AT91_PMC_LOCKA
+ beq 1b
+ .endm
+
+/*
+ * Wait until PLLB has locked.
+ */
+ .macro wait_pllblock
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+ tst tmp1, #AT91_PMC_LOCKB
+ beq 1b
+ .endm
+
+ .text
+
+/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
+ * void __iomem *ramc1, int memctrl)
+ */
+ENTRY(at91_slow_clock)
+ /* Save registers on stack */
+ stmfd sp!, {r4 - r12, lr}
+
+ /*
+ * Register usage:
+ * R0 = Base address of AT91_PMC
+ * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
+ * R2 = Base address of second RAM Controller or 0 if not present
+ * R3 = Memory controller
+ * R4 = temporary register
+ * R5 = temporary register
+ */
+
+ /* Drain write buffer */
+ 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
+
+ /* Active the self-refresh mode */
+ mov r0, #SRAMC_SELF_FRESH_ACTIVE
+ bl at91_sramc_self_refresh
+
+ ldr r0, .pm_mode
+ tst r0, #AT91_PM_SLOW_CLOCK
+ beq skip_disable_main_clock
+
+ ldr pmc, .pmc_base
+
+ /* Save Master clock setting */
+ ldr tmp1, [pmc, #AT91_PMC_MCKR]
+ str tmp1, .saved_mckr
+
+ /*
+ * Set the Master clock source to slow clock
+ */
+ bic tmp1, tmp1, #AT91_PMC_CSS
+ str tmp1, [pmc, #AT91_PMC_MCKR]
+
+ wait_mckrdy
+
+ /* Save PLLA setting and disable it */
+ ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
+ str tmp1, .saved_pllar
+
+ mov tmp1, #AT91_PMC_PLLCOUNT
+ orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
+ str tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+ /* Save PLLB setting and disable it */
+ ldr tmp1, [pmc, #AT91_CKGR_PLLBR]
+ str tmp1, .saved_pllbr
+
+ mov tmp1, #AT91_PMC_PLLCOUNT
+ str tmp1, [pmc, #AT91_CKGR_PLLBR]
+
+ /* Turn off the main oscillator */
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
+ bic tmp1, tmp1, #AT91_PMC_MOSCEN
+ orr tmp1, tmp1, #AT91_PMC_KEY
+ str tmp1, [pmc, #AT91_CKGR_MOR]
+
+skip_disable_main_clock:
+ ldr pmc, .pmc_base
+
+ /* Wait for interrupt */
+ mcr p15, 0, tmp1, c7, c0, 4
+
+ ldr r0, .pm_mode
+ tst r0, #AT91_PM_SLOW_CLOCK
+ beq skip_enable_main_clock
+
+ ldr pmc, .pmc_base
+
+ /* Turn on the main oscillator */
+ ldr tmp1, [pmc, #AT91_CKGR_MOR]
+ orr tmp1, tmp1, #AT91_PMC_MOSCEN
+ orr tmp1, tmp1, #AT91_PMC_KEY
+ str tmp1, [pmc, #AT91_CKGR_MOR]
+
+ wait_moscrdy
+
+ /* Restore PLLB setting */
+ ldr tmp1, .saved_pllbr
+ str tmp1, [pmc, #AT91_CKGR_PLLBR]
+
+ tst tmp1, #(AT91_PMC_MUL & 0xff0000)
+ bne 1f
+ tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
+ beq 2f
+1:
+ wait_pllblock
+2:
+
+ /* Restore PLLA setting */
+ ldr tmp1, .saved_pllar
+ str tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+ tst tmp1, #(AT91_PMC_MUL & 0xff0000)
+ bne 3f
+ tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
+ beq 4f
+3:
+ wait_pllalock
+4:
+
+ /*
+ * Restore master clock setting
+ */
+ ldr tmp1, .saved_mckr
+ str tmp1, [pmc, #AT91_PMC_MCKR]
+
+ wait_mckrdy
+
+skip_enable_main_clock:
+ /* Exit the self-refresh mode */
+ mov r0, #SRAMC_SELF_FRESH_EXIT
+ bl at91_sramc_self_refresh
+
+ /* Restore registers, and return */
+ ldmfd sp!, {r4 - r12, pc}
+ENDPROC(at91_slow_clock)
+
+/*
+ * void at91_sramc_self_refresh(unsigned int is_active)
+ *
+ * @input param:
+ * @r0: 1 - active self-refresh mode
+ * 0 - exit self-refresh mode
+ * register usage:
+ * @r1: memory type
+ * @r2: base address of the sram controller
+ */
+
+ENTRY(at91_sramc_self_refresh)
+ ldr r1, .memtype
+ ldr r2, .sramc_base
+
+ cmp r1, #AT91_MEMCTRL_MC
+ bne ddrc_sf
+
+ /*
+ * at91rm9200 Memory controller
+ */
+
+ /*
+ * For exiting the self-refresh mode, do nothing,
+ * automatically exit the self-refresh mode.
+ */
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq exit_sramc_sf
+
+ /* Active SDRAM self-refresh mode */
+ mov r3, #1
+ str r3, [r2, #AT91RM9200_SDRAMC_SRR]
+ b exit_sramc_sf
+
+ddrc_sf:
+ cmp r1, #AT91_MEMCTRL_DDRSDR
+ bne sdramc_sf
+
+ /*
+ * DDR Memory controller
+ */
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq ddrc_exit_sf
+
+ /* LPDDR1 --> force DDR2 mode during self-refresh */
+ ldr r3, [r2, #AT91_DDRSDRC_MDR]
+ str r3, .saved_sam9_mdr
+ bic r3, r3, #~AT91_DDRSDRC_MD
+ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+ ldreq r3, [r2, #AT91_DDRSDRC_MDR]
+ biceq r3, r3, #AT91_DDRSDRC_MD
+ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
+ streq r3, [r2, #AT91_DDRSDRC_MDR]
+
+ /* Active DDRC self-refresh mode */
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr
+ bic r3, r3, #AT91_DDRSDRC_LPCB
+ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+ /* If using the 2nd ddr controller */
+ ldr r2, .sramc1_base
+ cmp r2, #0
+ beq no_2nd_ddrc
+
+ ldr r3, [r2, #AT91_DDRSDRC_MDR]
+ str r3, .saved_sam9_mdr1
+ bic r3, r3, #~AT91_DDRSDRC_MD
+ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+ ldreq r3, [r2, #AT91_DDRSDRC_MDR]
+ biceq r3, r3, #AT91_DDRSDRC_MD
+ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
+ streq r3, [r2, #AT91_DDRSDRC_MDR]
+
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr1
+ bic r3, r3, #AT91_DDRSDRC_LPCB
+ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+ /* Active DDRC self-refresh mode */
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+no_2nd_ddrc:
+ b exit_sramc_sf
+
+ddrc_exit_sf:
+ /* Restore MDR in case of LPDDR1 */
+ ldr r3, .saved_sam9_mdr
+ str r3, [r2, #AT91_DDRSDRC_MDR]
+ /* Restore LPR on AT91 with DDRAM */
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+ /* If using the 2nd ddr controller */
+ ldr r2, .sramc1_base
+ cmp r2, #0
+ ldrne r3, .saved_sam9_mdr1
+ strne r3, [r2, #AT91_DDRSDRC_MDR]
+ ldrne r3, .saved_sam9_lpr1
+ strne r3, [r2, #AT91_DDRSDRC_LPR]
+
+ b exit_sramc_sf
+
+ /*
+ * SDRAMC Memory controller
+ */
+sdramc_sf:
+ tst r0, #SRAMC_SELF_FRESH_ACTIVE
+ beq sdramc_exit_sf
+
+ /* Active SDRAMC self-refresh mode */
+ ldr r3, [r2, #AT91_SDRAMC_LPR]
+ str r3, .saved_sam9_lpr
+
+ bic r3, r3, #AT91_SDRAMC_LPCB
+ orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_SDRAMC_LPR]
+
+sdramc_exit_sf:
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_SDRAMC_LPR]
+
+exit_sramc_sf:
+ mov pc, lr
+ENDPROC(at91_sramc_self_refresh)
+
+.pmc_base:
+ .word 0
+.sramc_base:
+ .word 0
+.sramc1_base:
+ .word 0
+.memtype:
+ .word 0
+.pm_mode:
+ .word 0
+.saved_mckr:
+ .word 0
+.saved_pllar:
+ .word 0
+.saved_pllbr:
+ .word 0
+.saved_sam9_lpr:
+ .word 0
+.saved_sam9_lpr1:
+ .word 0
+.saved_sam9_mdr:
+ .word 0
+.saved_sam9_mdr1:
+ .word 0
+
+ENTRY(at91_slow_clock_sz)
+ .word .-at91_slow_clock
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2.0 5/6] pm: at91: rename function name: at91_slow_clock()-->at91_pm_suspend_sram_fn
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
` (3 preceding siblings ...)
2015-03-09 3:50 ` [PATCH v2.0 4/6] pm: at91: rename file name: pm_slowclock.S -->pm_suspend.S Wenyou Yang
@ 2015-03-09 3:51 ` Wenyou Yang
2015-03-09 3:51 ` [PATCH v2.0 6/6] pm: at91: remove unused void (*at91_pm_standby)(void) Wenyou Yang
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Wenyou Yang @ 2015-03-09 3:51 UTC (permalink / raw)
To: linux-arm-kernel
As the file name is renamed, rename the file name at91_slow_clock()
--> at91_pm_suspend_sram_fn, rename the function handler's name at the same time.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/arm/mach-at91/pm.c | 27 ++++++++++++++-------------
arch/arm/mach-at91/pm_suspend.S | 26 +++++++++++---------------
2 files changed, 25 insertions(+), 28 deletions(-)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 3fc5e12..a008e9c 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -120,13 +120,12 @@ int at91_suspend_entering_slow_clock(void)
}
EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
-
-static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0,
+static void (*at91_suspend_sram_fn)(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl);
-extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
+extern void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl);
-extern u32 at91_slow_clock_sz;
+extern u32 at91_pm_suspend_in_sram_sz;
static void at91_pm_suspend(suspend_state_t state)
{
@@ -135,8 +134,8 @@ static void at91_pm_suspend(suspend_state_t state)
pm_data |= (state == PM_SUSPEND_MEM) ?
AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
- slow_clock(at91_pmc_base, at91_ramc_base[0],
- at91_ramc_base[1], pm_data);
+ at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0],
+ at91_ramc_base[1], pm_data);
}
static int at91_pm_enter(suspend_state_t state)
@@ -278,21 +277,23 @@ static void __init at91_pm_sram_init(void)
return;
}
- sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz);
+ sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz);
if (!sram_base) {
- pr_warn("%s: unable to alloc ocram!\n", __func__);
+ pr_warn("%s: unable to alloc sram!\n", __func__);
return;
}
sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
- slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false);
- if (!slow_clock) {
+ at91_suspend_sram_fn = __arm_ioremap_exec(sram_pbase,
+ at91_pm_suspend_in_sram_sz, false);
+ if (!at91_suspend_sram_fn) {
pr_warn("SRAM: Could not map\n");
return;
}
- /* Copy the slow_clock handler to SRAM */
- slow_clock = fncpy(slow_clock, &at91_slow_clock, at91_slow_clock_sz);
+ /* Copy the pm suspend handler to SRAM */
+ at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn,
+ &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
}
static void __init at91_pm_init(void)
@@ -302,7 +303,7 @@ static void __init at91_pm_init(void)
if (at91_cpuidle_device.dev.platform_data)
platform_device_register(&at91_cpuidle_device);
- if (slow_clock)
+ if (at91_suspend_sram_fn)
suspend_set_ops(&at91_pm_ops);
else
pr_info("AT91: PM not supported, due to no SRAM allocated\n");
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index a2bd1dc..0c520c3 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -62,23 +62,19 @@ tmp2 .req r5
.text
-/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
+/*
+ * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
* void __iomem *ramc1, int memctrl)
+ * @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
*/
-ENTRY(at91_slow_clock)
+ENTRY(at91_pm_suspend_in_sram)
/* Save registers on stack */
stmfd sp!, {r4 - r12, lr}
- /*
- * Register usage:
- * R0 = Base address of AT91_PMC
- * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
- * R2 = Base address of second RAM Controller or 0 if not present
- * R3 = Memory controller
- * R4 = temporary register
- * R5 = temporary register
- */
-
/* Drain write buffer */
mov tmp1, #0
mcr p15, 0, tmp1, c7, c10, 4
@@ -196,7 +192,7 @@ skip_enable_main_clock:
/* Restore registers, and return */
ldmfd sp!, {r4 - r12, pc}
-ENDPROC(at91_slow_clock)
+ENDPROC(at91_pm_suspend_in_sram)
/*
* void at91_sramc_self_refresh(unsigned int is_active)
@@ -349,5 +345,5 @@ ENDPROC(at91_sramc_self_refresh)
.saved_sam9_mdr1:
.word 0
-ENTRY(at91_slow_clock_sz)
- .word .-at91_slow_clock
+ENTRY(at91_pm_suspend_in_sram_sz)
+ .word .-at91_pm_suspend_in_sram
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2.0 6/6] pm: at91: remove unused void (*at91_pm_standby)(void)
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
` (4 preceding siblings ...)
2015-03-09 3:51 ` [PATCH v2.0 5/6] pm: at91: rename function name: at91_slow_clock()-->at91_pm_suspend_sram_fn Wenyou Yang
@ 2015-03-09 3:51 ` Wenyou Yang
2015-03-12 18:58 ` [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Sylvain Rochet
2015-03-13 10:05 ` Nicolas Ferre
7 siblings, 0 replies; 10+ messages in thread
From: Wenyou Yang @ 2015-03-09 3:51 UTC (permalink / raw)
To: linux-arm-kernel
Because the standby mode use the same sram function as the suspend to memory
mode, void (*at91_pm_standby)(void) doesn't need, remove it.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
arch/arm/mach-at91/pm.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a008e9c..9fb868d 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -42,7 +42,6 @@ static struct {
int memctrl;
} at91_pm_data;
-static void (*at91_pm_standby)(void);
void __iomem *at91_ramc_base[2];
static int at91_pm_valid_state(suspend_state_t state)
@@ -207,10 +206,8 @@ static struct platform_device at91_cpuidle_device = {
static void at91_pm_set_standby(void (*at91_standby)(void))
{
- if (at91_standby) {
+ if (at91_standby)
at91_cpuidle_device.dev.platform_data = at91_standby;
- at91_pm_standby = at91_standby;
- }
}
static const struct of_device_id ramc_ids[] __initconst = {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
` (5 preceding siblings ...)
2015-03-09 3:51 ` [PATCH v2.0 6/6] pm: at91: remove unused void (*at91_pm_standby)(void) Wenyou Yang
@ 2015-03-12 18:58 ` Sylvain Rochet
2015-03-13 10:05 ` Nicolas Ferre
7 siblings, 0 replies; 10+ messages in thread
From: Sylvain Rochet @ 2015-03-12 18:58 UTC (permalink / raw)
To: linux-arm-kernel
Hello Wenyou,
On Mon, Mar 09, 2015 at 11:47:37AM +0800, Wenyou Yang wrote:
> Hi,
>
> The patch series purpose is to improve the AT91 pm code.
> Create a procedure to handle the sdram self-fresh mode.
> The standby mode uses same sram function as the suspend to memory mode,
To the whole series:
Tested-by: Sylvain Rochet <sylvain.rochet@finsecur.com>
Sylvain
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
` (6 preceding siblings ...)
2015-03-12 18:58 ` [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Sylvain Rochet
@ 2015-03-13 10:05 ` Nicolas Ferre
2015-03-16 2:54 ` Yang, Wenyou
7 siblings, 1 reply; 10+ messages in thread
From: Nicolas Ferre @ 2015-03-13 10:05 UTC (permalink / raw)
To: linux-arm-kernel
Le 09/03/2015 04:47, Wenyou Yang a ?crit :
> Hi,
>
> The patch series purpose is to improve the AT91 pm code.
> Create a procedure to handle the sdram self-fresh mode.
> The standby mode uses same sram function as the suspend to memory mode,
>
> It is based on the branch, at91-4.0-fixes
> git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
> + [PATCH] ARM: AT91: pm cleanup for 4.1
>
> Chang log for v2.0
> - reserve the at91_xxx_standby() for at91_cpuidle_device.
> - rebase
>
> Wenyou Yang (6):
> pm: at91: pm_slowclock: create the procedure to handle the sdram
> self-refresh
> pm: at91: move the copying the sram function to the sram
> initializationi phase
> pm: at91: standby mode uses the same sram function as suspend to
> memory mode
> pm: at91: rename file name: pm_slowclock.S -->pm_suspend.S
> pm: at91: rename function name:
> at91_slow_clock()-->at91_pm_suspend_sram_fn
> pm: at91: remove unused void (*at91_pm_standby)(void)
Whole series:
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
And stacked on top of at91-4.1-cleanup
Thanks.
BTW, I had to rework the commit subject as all AT91 patches must begin
with: "ARM: at91". So I reworked them as "ARM: at91/pm:"
Bye,
> arch/arm/mach-at91/Makefile | 2 +-
> arch/arm/mach-at91/pm.c | 121 +++++++------
> arch/arm/mach-at91/pm.h | 10 ++
> arch/arm/mach-at91/pm_slowclock.S | 296 -------------------------------
> arch/arm/mach-at91/pm_suspend.S | 349 +++++++++++++++++++++++++++++++++++++
> 5 files changed, 420 insertions(+), 358 deletions(-)
> delete mode 100644 arch/arm/mach-at91/pm_slowclock.S
> create mode 100644 arch/arm/mach-at91/pm_suspend.S
>
--
Nicolas Ferre
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1
2015-03-13 10:05 ` Nicolas Ferre
@ 2015-03-16 2:54 ` Yang, Wenyou
0 siblings, 0 replies; 10+ messages in thread
From: Yang, Wenyou @ 2015-03-16 2:54 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Ferre, Nicolas
> Sent: 2015?3?13? 18:06
> To: Yang, Wenyou; linux at arm.linux.org.uk
> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> alexandre.belloni at free-electrons.com; sylvain.rochet at finsecur.com;
> peda at axentia.se; sergei.shtylyov at cogentembedded.com; linux at maxim.org.za
> Subject: Re: [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1
>
> Le 09/03/2015 04:47, Wenyou Yang a ?crit :
> > Hi,
> >
> > The patch series purpose is to improve the AT91 pm code.
> > Create a procedure to handle the sdram self-fresh mode.
> > The standby mode uses same sram function as the suspend to memory
> > mode,
> >
> > It is based on the branch, at91-4.0-fixes
> > git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
> > + [PATCH] ARM: AT91: pm cleanup for 4.1
> >
> > Chang log for v2.0
> > - reserve the at91_xxx_standby() for at91_cpuidle_device.
> > - rebase
> >
> > Wenyou Yang (6):
> > pm: at91: pm_slowclock: create the procedure to handle the sdram
> > self-refresh
> > pm: at91: move the copying the sram function to the sram
> > initializationi phase
> > pm: at91: standby mode uses the same sram function as suspend to
> > memory mode
> > pm: at91: rename file name: pm_slowclock.S -->pm_suspend.S
> > pm: at91: rename function name:
> > at91_slow_clock()-->at91_pm_suspend_sram_fn
> > pm: at91: remove unused void (*at91_pm_standby)(void)
>
> Whole series:
> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
>
> And stacked on top of at91-4.1-cleanup
>
> Thanks.
>
> BTW, I had to rework the commit subject as all AT91 patches must begin
> with: "ARM: at91". So I reworked them as "ARM: at91/pm:"
Thank you so much, lesson learned.
>
> Bye,
>
> > arch/arm/mach-at91/Makefile | 2 +-
> > arch/arm/mach-at91/pm.c | 121 +++++++------
> > arch/arm/mach-at91/pm.h | 10 ++
> > arch/arm/mach-at91/pm_slowclock.S | 296 -------------------------------
> > arch/arm/mach-at91/pm_suspend.S | 349
> +++++++++++++++++++++++++++++++++++++
> > 5 files changed, 420 insertions(+), 358 deletions(-) delete mode
> > 100644 arch/arm/mach-at91/pm_slowclock.S create mode 100644
> > arch/arm/mach-at91/pm_suspend.S
> >
>
>
> --
> Nicolas Ferre
Best Regards,
Wenyou Yang
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-03-16 2:54 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-09 3:47 [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Wenyou Yang
2015-03-09 3:48 ` [PATCH v2.0 1/6] pm: at91: pm_slowclock: create the procedure to handle the sdram self-refresh Wenyou Yang
2015-03-09 3:49 ` [PATCH v2.0 2/6] pm: at91: move the copying the sram function to the sram initializationi phase Wenyou Yang
2015-03-09 3:49 ` [PATCH v2.0 3/6] pm: at91: standby mode uses same sram function as suspend to memory mode Wenyou Yang
2015-03-09 3:50 ` [PATCH v2.0 4/6] pm: at91: rename file name: pm_slowclock.S -->pm_suspend.S Wenyou Yang
2015-03-09 3:51 ` [PATCH v2.0 5/6] pm: at91: rename function name: at91_slow_clock()-->at91_pm_suspend_sram_fn Wenyou Yang
2015-03-09 3:51 ` [PATCH v2.0 6/6] pm: at91: remove unused void (*at91_pm_standby)(void) Wenyou Yang
2015-03-12 18:58 ` [PATCH v2.0 0/6] ARM: AT91: pm improvement for 4.1 Sylvain Rochet
2015-03-13 10:05 ` Nicolas Ferre
2015-03-16 2:54 ` Yang, Wenyou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).