Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -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__ */
+12 −3
Original line number Original line Diff line number Diff line
@@ -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");
+51 −15
Original line number Original line Diff line number Diff line
@@ -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: