ARM: at91/pm_slowclock: add runtime detection of memory contoller
This will allow to have all SoC in one kernel image. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
This commit is contained in:
committed by
Nicolas Ferre
parent
f363c407b4
commit
fb7e197bec
@@ -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)
|
|||||||
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)
|
|||||||
* 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 @@
|
|||||||
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
|
|||||||
|
|
||||||
.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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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:
|
||||||
|
Reference in New Issue
Block a user