root/arch/arm/mach-sa1100/sleep.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /*
   2  * SA11x0 Assembler Sleep/WakeUp Management Routines
   3  *
   4  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
   5  *
   6  * This program is free software; you can redistribute it and/or
   7  * modify it under the terms of the GNU General Public License.
   8  *
   9  * History:
  10  *
  11  * 2001-02-06: Cliff Brake         Initial code
  12  *
  13  * 2001-08-29:  Nicolas Pitre   Simplified.
  14  *
  15  * 2002-05-27:  Nicolas Pitre   Revisited, more cleanup and simplification.
  16  *                              Storage is on the stack now.
  17  */
  18 
  19 #include <linux/linkage.h>
  20 #include <asm/assembler.h>
  21 #include <mach/hardware.h>
  22 
  23                 .text
  24 /*
  25  * sa1100_finish_suspend()
  26  *
  27  * Causes sa11x0 to enter sleep state
  28  *
  29  * Must be aligned to a cacheline.
  30  */
  31         .balign 32
  32 ENTRY(sa1100_finish_suspend)
  33         @ disable clock switching
  34         mcr     p15, 0, r1, c15, c2, 2
  35 
  36         ldr     r6, =MDREFR
  37         ldr     r4, [r6]
  38         orr     r4, r4, #MDREFR_K1DB2
  39         ldr     r5, =PPCR
  40 
  41         @ Pre-load __loop_udelay into the I-cache
  42         mov     r0, #1
  43         bl      __loop_udelay
  44         mov     r0, r0
  45 
  46         @ The following must all exist in a single cache line to
  47         @ avoid accessing memory until this sequence is complete,
  48         @ otherwise we occasionally hang.
  49 
  50         @ Adjust memory timing before lowering CPU clock
  51         str     r4, [r6]
  52 
  53         @ delay 90us and set CPU PLL to lowest speed
  54         @ fixes resume problem on high speed SA1110
  55         mov     r0, #90
  56         bl      __loop_udelay
  57         mov     r1, #0
  58         str     r1, [r5]
  59         mov     r0, #90
  60         bl      __loop_udelay
  61 
  62         /*
  63          * SA1110 SDRAM controller workaround.  register values:
  64          *
  65          * r0  = &MSC0
  66          * r1  = &MSC1
  67          * r2  = &MSC2
  68          * r3  = MSC0 value
  69          * r4  = MSC1 value
  70          * r5  = MSC2 value
  71          * r6  = &MDREFR
  72          * r7  = first MDREFR value
  73          * r8  = second MDREFR value
  74          * r9  = &MDCNFG
  75          * r10 = MDCNFG value
  76          * r11 = third MDREFR value
  77          * r12 = &PMCR
  78          * r13 = PMCR value (1)
  79          */
  80 
  81         ldr     r0, =MSC0
  82         ldr     r1, =MSC1
  83         ldr     r2, =MSC2
  84 
  85         ldr     r3, [r0]
  86         bic     r3, r3, #FMsk(MSC_RT)
  87         bic     r3, r3, #FMsk(MSC_RT)<<16
  88 
  89         ldr     r4, [r1]
  90         bic     r4, r4, #FMsk(MSC_RT)
  91         bic     r4, r4, #FMsk(MSC_RT)<<16
  92 
  93         ldr     r5, [r2]
  94         bic     r5, r5, #FMsk(MSC_RT)
  95         bic     r5, r5, #FMsk(MSC_RT)<<16
  96 
  97         ldr     r7, [r6]
  98         bic     r7, r7, #0x0000FF00
  99         bic     r7, r7, #0x000000F0
 100         orr     r8, r7, #MDREFR_SLFRSH
 101 
 102         ldr     r9, =MDCNFG
 103         ldr     r10, [r9]
 104         bic     r10, r10, #(MDCNFG_DE0+MDCNFG_DE1)
 105         bic     r10, r10, #(MDCNFG_DE2+MDCNFG_DE3)
 106 
 107         bic     r11, r8, #MDREFR_SLFRSH
 108         bic     r11, r11, #MDREFR_E1PIN
 109 
 110         ldr     r12, =PMCR
 111 
 112         mov     r13, #PMCR_SF
 113 
 114         b       sa1110_sdram_controller_fix
 115 
 116         .align 5
 117 sa1110_sdram_controller_fix:
 118 
 119         @ Step 1 clear RT field of all MSCx registers
 120         str     r3, [r0]
 121         str     r4, [r1]
 122         str     r5, [r2]
 123 
 124         @ Step 2 clear DRI field in MDREFR
 125         str     r7, [r6]
 126 
 127         @ Step 3 set SLFRSH bit in MDREFR
 128         str     r8, [r6]
 129 
 130         @ Step 4 clear DE bis in MDCNFG
 131         str     r10, [r9]
 132 
 133         @ Step 5 clear DRAM refresh control register
 134         str     r11, [r6]
 135 
 136         @ Wow, now the hardware suspend request pins can be used, that makes them functional for
 137         @ about 7 ns out of the entire time that the CPU is running!
 138 
 139         @ Step 6 set force sleep bit in PMCR
 140 
 141         str     r13, [r12]
 142 
 143 20:     b       20b                     @ loop waiting for sleep

/* [<][>][^][v][top][bottom][index][help] */