Commit fb7e197b authored by Jean-Christophe PLAGNIOL-VILLARD's avatar Jean-Christophe PLAGNIOL-VILLARD Committed by Nicolas Ferre

ARM: at91/pm_slowclock: add runtime detection of memory contoller

This will allow to have all SoC in one kernel image.
Signed-off-by: default avatarJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
parent f363c407
...@@ -21,11 +21,12 @@ extern void __iomem *at91_ramc_base[]; ...@@ -21,11 +21,12 @@ extern void __iomem *at91_ramc_base[];
.extern at91_ramc_base .extern at91_ramc_base
#endif #endif
#ifdef CONFIG_ARCH_AT91RM9200 #define AT91_MEMCTRL_MC 0
#include <mach/at91rm9200_mc.h> #define AT91_MEMCTRL_SDRAMC 1
#else #define AT91_MEMCTRL_DDRSDR 2
#include <mach/at91rm9200_sdramc.h>
#include <mach/at91sam9_ddrsdr.h> #include <mach/at91sam9_ddrsdr.h>
#include <mach/at91sam9_sdramc.h> #include <mach/at91sam9_sdramc.h>
#endif
#endif /* __AT91_RAMC_H__ */ #endif /* __AT91_RAMC_H__ */
...@@ -188,10 +188,12 @@ int at91_suspend_entering_slow_clock(void) ...@@ -188,10 +188,12 @@ int at91_suspend_entering_slow_clock(void)
EXPORT_SYMBOL(at91_suspend_entering_slow_clock); EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1); static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl);
#ifdef CONFIG_AT91_SLOW_CLOCK #ifdef CONFIG_AT91_SLOW_CLOCK
extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, void __iomem *ramc1); extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
void __iomem *ramc1, int memctrl);
extern u32 at91_slow_clock_sz; extern u32 at91_slow_clock_sz;
#endif #endif
...@@ -241,11 +243,18 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -241,11 +243,18 @@ static int at91_pm_enter(suspend_state_t state)
* turning off the main oscillator; reverse on wakeup. * turning off the main oscillator; reverse on wakeup.
*/ */
if (slow_clock) { if (slow_clock) {
int memctrl = AT91_MEMCTRL_SDRAMC;
if (cpu_is_at91rm9200())
memctrl = AT91_MEMCTRL_MC;
else if (cpu_is_at91sam9g45())
memctrl = AT91_MEMCTRL_DDRSDR;
#ifdef CONFIG_AT91_SLOW_CLOCK #ifdef CONFIG_AT91_SLOW_CLOCK
/* copy slow_clock handler to SRAM, and call it */ /* copy slow_clock handler to SRAM, and call it */
memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
#endif #endif
slow_clock(at91_pmc_base, at91_ramc_base[0], at91_ramc_base[1]); slow_clock(at91_pmc_base, at91_ramc_base[0],
at91_ramc_base[1], memctrl);
break; break;
} else { } else {
pr_info("AT91: PM - no slow clock mode enabled ...\n"); pr_info("AT91: PM - no slow clock mode enabled ...\n");
......
...@@ -42,8 +42,9 @@ ...@@ -42,8 +42,9 @@
pmc .req r0 pmc .req r0
sdramc .req r1 sdramc .req r1
ramc1 .req r2 ramc1 .req r2
tmp1 .req r3 memctrl .req r3
tmp2 .req r4 tmp1 .req r4
tmp2 .req r5
/* /*
* Wait until master clock is ready (after switching master clock source) * Wait until master clock is ready (after switching master clock source)
...@@ -103,29 +104,44 @@ tmp2 .req r4 ...@@ -103,29 +104,44 @@ tmp2 .req r4
.text .text
/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, void __iomem *ramc1) */ /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
* void __iomem *ramc1, int memctrl)
*/
ENTRY(at91_slow_clock) ENTRY(at91_slow_clock)
/* Save registers on stack */ /* Save registers on stack */
stmfd sp!, {r3 - r12, lr} stmfd sp!, {r4 - r12, lr}
/* /*
* Register usage: * Register usage:
* R0 = Base address of AT91_PMC * R0 = Base address of AT91_PMC
* R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
* R2 = Base address of second RAM Controller or 0 if not present * R2 = Base address of second RAM Controller or 0 if not present
* R3 = temporary register * R3 = Memory controller
* R4 = temporary register * R4 = temporary register
* R5 = temporary register
*/ */
/* Drain write buffer */ /* Drain write buffer */
mov tmp1, #0 mov tmp1, #0
mcr p15, 0, tmp1, c7, c10, 4 mcr p15, 0, tmp1, c7, c10, 4
#ifdef CONFIG_ARCH_AT91RM9200 cmp memctrl, #AT91_MEMCTRL_MC
bne ddr_sr_enable
/*
* at91rm9200 Memory controller
*/
/* Put SDRAM in self-refresh mode */ /* Put SDRAM in self-refresh mode */
mov tmp1, #1 mov tmp1, #1
str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
#elif defined(CONFIG_ARCH_AT91SAM9G45) b sdr_sr_done
/*
* DDRSDR Memory controller
*/
ddr_sr_enable:
cmp memctrl, #AT91_MEMCTRL_DDRSDR
bne sdr_sr_enable
/* prepare for DDRAM self-refresh mode */ /* prepare for DDRAM self-refresh mode */
ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
...@@ -143,7 +159,13 @@ ENTRY(at91_slow_clock) ...@@ -143,7 +159,13 @@ ENTRY(at91_slow_clock)
/* Enable DDRAM self-refresh mode */ /* Enable DDRAM self-refresh mode */
str tmp1, [sdramc, #AT91_DDRSDRC_LPR] str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
#else
b sdr_sr_done
/*
* SDRAMC Memory controller
*/
sdr_sr_enable:
/* Enable SDRAM self-refresh mode */ /* Enable SDRAM self-refresh mode */
ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
str tmp1, .saved_sam9_lpr str tmp1, .saved_sam9_lpr
...@@ -151,8 +173,8 @@ ENTRY(at91_slow_clock) ...@@ -151,8 +173,8 @@ ENTRY(at91_slow_clock)
bic tmp1, #AT91_SDRAMC_LPCB bic tmp1, #AT91_SDRAMC_LPCB
orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
str tmp1, [sdramc, #AT91_SDRAMC_LPR] str tmp1, [sdramc, #AT91_SDRAMC_LPR]
#endif
sdr_sr_done:
/* Save Master clock setting */ /* Save Master clock setting */
ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)] ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
str tmp1, .saved_mckr str tmp1, .saved_mckr
...@@ -255,9 +277,18 @@ ENTRY(at91_slow_clock) ...@@ -255,9 +277,18 @@ ENTRY(at91_slow_clock)
wait_mckrdy wait_mckrdy
#ifdef CONFIG_ARCH_AT91RM9200 /*
/* Do nothing - self-refresh is automatically disabled. */ * at91rm9200 Memory controller
#elif defined(CONFIG_ARCH_AT91SAM9G45) * Do nothing - self-refresh is automatically disabled.
*/
cmp memctrl, #AT91_MEMCTRL_MC
beq ram_restored
/*
* DDRSDR Memory controller
*/
cmp memctrl, #AT91_MEMCTRL_DDRSDR
bne sdr_en_restore
/* Restore LPR on AT91 with DDRAM */ /* Restore LPR on AT91 with DDRAM */
ldr tmp1, .saved_sam9_lpr ldr tmp1, .saved_sam9_lpr
str tmp1, [sdramc, #AT91_DDRSDRC_LPR] str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
...@@ -267,14 +298,19 @@ ENTRY(at91_slow_clock) ...@@ -267,14 +298,19 @@ ENTRY(at91_slow_clock)
ldrne tmp2, .saved_sam9_lpr1 ldrne tmp2, .saved_sam9_lpr1
strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
#else b ram_restored
/*
* SDRAMC Memory controller
*/
sdr_en_restore:
/* Restore LPR on AT91 with SDRAM */ /* Restore LPR on AT91 with SDRAM */
ldr tmp1, .saved_sam9_lpr ldr tmp1, .saved_sam9_lpr
str tmp1, [sdramc, #AT91_SDRAMC_LPR] str tmp1, [sdramc, #AT91_SDRAMC_LPR]
#endif
ram_restored:
/* Restore registers, and return */ /* Restore registers, and return */
ldmfd sp!, {r3 - r12, pc} ldmfd sp!, {r4 - r12, pc}
.saved_mckr: .saved_mckr:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment