diff options
Diffstat (limited to 'arch/arm/mach-at91/pm_slowclock.S')
-rw-r--r-- | arch/arm/mach-at91/pm_slowclock.S | 275 |
1 files changed, 141 insertions, 134 deletions
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 92dfb846139..db5452123f1 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -15,15 +15,7 @@ #include <linux/linkage.h> #include <mach/hardware.h> #include <mach/at91_pmc.h> - -#if defined(CONFIG_ARCH_AT91RM9200) -#include <mach/at91rm9200_mc.h> -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -#include <mach/at91sam9_ddrsdr.h> -#else -#include <mach/at91sam9_sdramc.h> -#endif +#include <mach/at91_ramc.h> #ifdef CONFIG_ARCH_AT91SAM9263 @@ -47,17 +39,23 @@ #define PLLALOCK_TIMEOUT 1000 #define PLLBLOCK_TIMEOUT 1000 +pmc .req r0 +sdramc .req r1 +ramc1 .req r2 +memctrl .req r3 +tmp1 .req r4 +tmp2 .req r5 /* * Wait until master clock is ready (after switching master clock source) */ .macro wait_mckrdy - mov r4, #MCKRDY_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #MCKRDY_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_MCKRDY + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MCKRDY beq 1b 2: .endm @@ -66,12 +64,12 @@ * Wait until master oscillator has stabilized. */ .macro wait_moscrdy - mov r4, #MOSCRDY_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #MOSCRDY_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_MOSCS + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MOSCS beq 1b 2: .endm @@ -80,12 +78,12 @@ * Wait until PLLA has locked. */ .macro wait_pllalock - mov r4, #PLLALOCK_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #PLLALOCK_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_LOCKA + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKA beq 1b 2: .endm @@ -94,80 +92,98 @@ * Wait until PLLB has locked. */ .macro wait_pllblock - mov r4, #PLLBLOCK_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #PLLBLOCK_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_LOCKB + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKB beq 1b 2: .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!, {r0 - r12, lr} + stmfd sp!, {r4 - r12, lr} /* * Register usage: - * R1 = Base address of AT91_PMC - * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) - * R3 = temporary register + * 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 = Base address of second RAM Controller or 0 if not present + * R5 = temporary register */ - ldr r1, .at91_va_base_pmc - ldr r2, .at91_va_base_sdramc - ldr r5, .at91_va_base_ramc1 /* Drain write buffer */ - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 + mov tmp1, #0 + mcr p15, 0, tmp1, c7, c10, 4 + + cmp memctrl, #AT91_MEMCTRL_MC + bne ddr_sr_enable -#ifdef CONFIG_ARCH_AT91RM9200 + /* + * at91rm9200 Memory controller + */ /* Put SDRAM in self-refresh mode */ - mov r3, #1 - str r3, [r2, #AT91_SDRAMC_SRR] -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) + mov tmp1, #1 + str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] + 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 */ - ldr r3, [r2, #AT91_DDRSDRC_LPR] - str r3, .saved_sam9_lpr - bic r3, #AT91_DDRSDRC_LPCB - orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH + 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 r5, #0 - ldrne r4, [r5, #AT91_DDRSDRC_LPR] - strne r4, .saved_sam9_lpr1 - bicne r4, #AT91_DDRSDRC_LPCB - orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH + cmp ramc1, #0 + ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + strne tmp2, .saved_sam9_lpr1 + bicne tmp2, #AT91_DDRSDRC_LPCB + orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH /* Enable DDRAM self-refresh mode */ - str r3, [r2, #AT91_DDRSDRC_LPR] - strne r4, [r5, #AT91_DDRSDRC_LPR] -#else + str tmp1, [sdramc, #AT91_DDRSDRC_LPR] + strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + + b sdr_sr_done + + /* + * SDRAMC Memory controller + */ +sdr_sr_enable: /* Enable SDRAM self-refresh mode */ - ldr r3, [r2, #AT91_SDRAMC_LPR] - str r3, .saved_sam9_lpr + ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] + str tmp1, .saved_sam9_lpr - bic r3, #AT91_SDRAMC_LPCB - orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH - str r3, [r2, #AT91_SDRAMC_LPR] -#endif + 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 r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] - str r3, .saved_mckr + ldr tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, .saved_mckr /* * Set the Master clock source to slow clock */ - bic r3, r3, #AT91_PMC_CSS - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + bic tmp1, tmp1, #AT91_PMC_CSS + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy @@ -177,61 +193,61 @@ ENTRY(at91_slow_clock) * * See AT91RM9200 errata #27 and #28 for details. */ - mov r3, #0 - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + mov tmp1, #0 + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy #endif /* Save PLLA setting and disable it */ - ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] - str r3, .saved_pllar + ldr tmp1, [pmc, #AT91_CKGR_PLLAR] + str tmp1, .saved_pllar - mov r3, #AT91_PMC_PLLCOUNT - orr r3, r3, #(1 << 29) /* bit 29 always set */ - str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + 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 r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] - str r3, .saved_pllbr + ldr tmp1, [pmc, #AT91_CKGR_PLLBR] + str tmp1, .saved_pllbr - mov r3, #AT91_PMC_PLLCOUNT - str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + mov tmp1, #AT91_PMC_PLLCOUNT + str tmp1, [pmc, #AT91_CKGR_PLLBR] /* Turn off the main oscillator */ - ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] - bic r3, r3, #AT91_PMC_MOSCEN - str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + ldr tmp1, [pmc, #AT91_CKGR_MOR] + bic tmp1, tmp1, #AT91_PMC_MOSCEN + str tmp1, [pmc, #AT91_CKGR_MOR] /* Wait for interrupt */ - mcr p15, 0, r0, c7, c0, 4 + mcr p15, 0, tmp1, c7, c0, 4 /* Turn on the main oscillator */ - ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] - orr r3, r3, #AT91_PMC_MOSCEN - str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + ldr tmp1, [pmc, #AT91_CKGR_MOR] + orr tmp1, tmp1, #AT91_PMC_MOSCEN + str tmp1, [pmc, #AT91_CKGR_MOR] wait_moscrdy /* Restore PLLB setting */ - ldr r3, .saved_pllbr - str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + ldr tmp1, .saved_pllbr + str tmp1, [pmc, #AT91_CKGR_PLLBR] - tst r3, #(AT91_PMC_MUL & 0xff0000) + tst tmp1, #(AT91_PMC_MUL & 0xff0000) bne 1f - tst r3, #(AT91_PMC_MUL & ~0xff0000) + tst tmp1, #(AT91_PMC_MUL & ~0xff0000) beq 2f 1: wait_pllblock 2: /* Restore PLLA setting */ - ldr r3, .saved_pllar - str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + ldr tmp1, .saved_pllar + str tmp1, [pmc, #AT91_CKGR_PLLAR] - tst r3, #(AT91_PMC_MUL & 0xff0000) + tst tmp1, #(AT91_PMC_MUL & 0xff0000) bne 3f - tst r3, #(AT91_PMC_MUL & ~0xff0000) + tst tmp1, #(AT91_PMC_MUL & ~0xff0000) beq 4f 3: wait_pllalock @@ -244,11 +260,11 @@ ENTRY(at91_slow_clock) * * See AT91RM9200 errata #27 and #28 for details. */ - ldr r3, .saved_mckr - tst r3, #AT91_PMC_PRES + ldr tmp1, .saved_mckr + tst tmp1, #AT91_PMC_PRES beq 2f - and r3, r3, #AT91_PMC_PRES - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + and tmp1, tmp1, #AT91_PMC_PRES + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy #endif @@ -256,32 +272,45 @@ ENTRY(at91_slow_clock) /* * Restore master clock setting */ -2: ldr r3, .saved_mckr - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] +2: ldr tmp1, .saved_mckr + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy -#ifdef CONFIG_ARCH_AT91RM9200 - /* Do nothing - self-refresh is automatically disabled. */ -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) + /* + * at91rm9200 Memory controller + * 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 */ - ldr r3, .saved_sam9_lpr - str r3, [r2, #AT91_DDRSDRC_LPR] + ldr tmp1, .saved_sam9_lpr + str tmp1, [sdramc, #AT91_DDRSDRC_LPR] /* if we use the second ram controller */ - cmp r5, #0 - ldrne r4, .saved_sam9_lpr1 - strne r4, [r5, #AT91_DDRSDRC_LPR] + cmp ramc1, #0 + ldrne tmp2, .saved_sam9_lpr1 + strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + + b ram_restored -#else + /* + * SDRAMC Memory controller + */ +sdr_en_restore: /* Restore LPR on AT91 with SDRAM */ - ldr r3, .saved_sam9_lpr - str r3, [r2, #AT91_SDRAMC_LPR] -#endif + ldr tmp1, .saved_sam9_lpr + str tmp1, [sdramc, #AT91_SDRAMC_LPR] +ram_restored: /* Restore registers, and return */ - ldmfd sp!, {r0 - r12, pc} + ldmfd sp!, {r4 - r12, pc} .saved_mckr: @@ -299,27 +328,5 @@ ENTRY(at91_slow_clock) .saved_sam9_lpr1: .word 0 -.at91_va_base_pmc: - .word AT91_VA_BASE_SYS + AT91_PMC - -#ifdef CONFIG_ARCH_AT91RM9200 -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 -#else -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_SDRAMC0 -#endif - -.at91_va_base_ramc1: -#if defined(CONFIG_ARCH_AT91SAM9G45) - .word AT91_VA_BASE_SYS + AT91_DDRSDRC1 -#else - .word 0 -#endif - ENTRY(at91_slow_clock_sz) .word .-at91_slow_clock |