Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * SA11x0 Assembler Sleep/WakeUp Management Routines
0003  *
0004  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public License.
0008  *
0009  * History:
0010  *
0011  * 2001-02-06: Cliff Brake         Initial code
0012  *
0013  * 2001-08-29:  Nicolas Pitre   Simplified.
0014  *
0015  * 2002-05-27:  Nicolas Pitre   Revisited, more cleanup and simplification.
0016  *              Storage is on the stack now.
0017  */
0018 
0019 #include <linux/linkage.h>
0020 #include <asm/assembler.h>
0021 #include <mach/hardware.h>
0022 
0023         .text
0024 /*
0025  * sa1100_finish_suspend()
0026  *
0027  * Causes sa11x0 to enter sleep state
0028  *
0029  * Must be aligned to a cacheline.
0030  */
0031     .balign 32
0032 ENTRY(sa1100_finish_suspend)
0033     @ disable clock switching
0034     mcr p15, 0, r1, c15, c2, 2
0035 
0036     ldr r6, =MDREFR
0037     ldr r4, [r6]
0038     orr     r4, r4, #MDREFR_K1DB2
0039     ldr r5, =PPCR
0040 
0041     @ Pre-load __loop_udelay into the I-cache
0042     mov r0, #1
0043     bl  __loop_udelay
0044     mov r0, r0
0045 
0046     @ The following must all exist in a single cache line to
0047     @ avoid accessing memory until this sequence is complete,
0048     @ otherwise we occasionally hang.
0049 
0050     @ Adjust memory timing before lowering CPU clock
0051     str     r4, [r6]
0052 
0053     @ delay 90us and set CPU PLL to lowest speed
0054     @ fixes resume problem on high speed SA1110
0055     mov r0, #90
0056     bl  __loop_udelay
0057     mov r1, #0
0058     str r1, [r5]
0059     mov r0, #90
0060     bl  __loop_udelay
0061 
0062     /*
0063      * SA1110 SDRAM controller workaround.  register values:
0064      *
0065      * r0  = &MSC0
0066      * r1  = &MSC1
0067      * r2  = &MSC2
0068      * r3  = MSC0 value
0069      * r4  = MSC1 value
0070      * r5  = MSC2 value
0071      * r6  = &MDREFR
0072      * r7  = first MDREFR value
0073      * r8  = second MDREFR value
0074      * r9  = &MDCNFG
0075      * r10 = MDCNFG value
0076      * r11 = third MDREFR value
0077      * r12 = &PMCR
0078      * r13 = PMCR value (1)
0079      */
0080 
0081     ldr r0, =MSC0
0082     ldr r1, =MSC1
0083     ldr r2, =MSC2
0084 
0085     ldr r3, [r0]
0086     bic r3, r3, #FMsk(MSC_RT)
0087     bic r3, r3, #FMsk(MSC_RT)<<16
0088 
0089     ldr r4, [r1]
0090     bic r4, r4, #FMsk(MSC_RT)
0091     bic r4, r4, #FMsk(MSC_RT)<<16
0092 
0093     ldr r5, [r2]
0094     bic r5, r5, #FMsk(MSC_RT)
0095     bic r5, r5, #FMsk(MSC_RT)<<16
0096 
0097     ldr r7, [r6]
0098     bic r7, r7, #0x0000FF00
0099     bic r7, r7, #0x000000F0
0100     orr r8, r7, #MDREFR_SLFRSH
0101 
0102     ldr r9, =MDCNFG
0103     ldr r10, [r9]
0104     bic r10, r10, #(MDCNFG_DE0+MDCNFG_DE1)
0105     bic r10, r10, #(MDCNFG_DE2+MDCNFG_DE3)
0106 
0107     bic r11, r8, #MDREFR_SLFRSH
0108     bic r11, r11, #MDREFR_E1PIN
0109 
0110     ldr r12, =PMCR
0111 
0112     mov r13, #PMCR_SF
0113 
0114     b   sa1110_sdram_controller_fix
0115 
0116     .align 5
0117 sa1110_sdram_controller_fix:
0118 
0119     @ Step 1 clear RT field of all MSCx registers
0120     str     r3, [r0]
0121     str r4, [r1]
0122     str r5, [r2]
0123 
0124     @ Step 2 clear DRI field in MDREFR
0125     str r7, [r6]
0126 
0127     @ Step 3 set SLFRSH bit in MDREFR
0128     str r8, [r6]
0129 
0130     @ Step 4 clear DE bis in MDCNFG
0131     str r10, [r9]
0132 
0133     @ Step 5 clear DRAM refresh control register
0134     str r11, [r6]
0135 
0136     @ Wow, now the hardware suspend request pins can be used, that makes them functional for
0137     @ about 7 ns out of the entire time that the CPU is running!
0138 
0139     @ Step 6 set force sleep bit in PMCR
0140 
0141     str r13, [r12]
0142 
0143 20: b   20b         @ loop waiting for sleep