root/arch/arm/mach-imx/suspend-imx53.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-or-later */
   2 /*
   3  * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
   4  */
   5 /*
   6  */
   7 
   8 #include <linux/linkage.h>
   9 
  10 #define M4IF_MCR0_OFFSET                        (0x008C)
  11 #define M4IF_MCR0_FDVFS                         (0x1 << 11)
  12 #define M4IF_MCR0_FDVACK                        (0x1 << 27)
  13 
  14         .align 3
  15 
  16 /*
  17  * ==================== low level suspend ====================
  18  *
  19  * On entry
  20  * r0: pm_info structure address;
  21  *
  22  * suspend ocram space layout:
  23  * ======================== high address ======================
  24  *                              .
  25  *                              .
  26  *                              .
  27  *                              ^
  28  *                              ^
  29  *                              ^
  30  *                      imx53_suspend code
  31  *              PM_INFO structure(imx53_suspend_info)
  32  * ======================== low address =======================
  33  */
  34 
  35 /* Offsets of members of struct imx53_suspend_info */
  36 #define SUSPEND_INFO_MX53_M4IF_V_OFFSET         0x0
  37 #define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET       0x4
  38 #define SUSPEND_INFO_MX53_IO_COUNT_OFFSET       0x8
  39 #define SUSPEND_INFO_MX53_IO_STATE_OFFSET       0xc
  40 
  41 ENTRY(imx53_suspend)
  42         stmfd   sp!, {r4,r5,r6,r7}
  43 
  44         /* Save pad config */
  45         ldr     r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
  46         cmp     r1, #0
  47         beq     skip_pad_conf_1
  48 
  49         add     r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
  50         ldr     r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
  51 
  52 1:
  53         ldr     r5, [r2], #12   /* IOMUXC register offset */
  54         ldr     r6, [r3, r5]    /* current value */
  55         str     r6, [r2], #4    /* save area */
  56         subs    r1, r1, #1
  57         bne     1b
  58 
  59 skip_pad_conf_1:
  60         /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */
  61         ldr     r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET]
  62         ldr     r2,[r1, #M4IF_MCR0_OFFSET]
  63         orr     r2, r2, #M4IF_MCR0_FDVFS
  64         str     r2,[r1, #M4IF_MCR0_OFFSET]
  65 
  66         /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */
  67 wait_sr_ack:
  68         ldr     r2,[r1, #M4IF_MCR0_OFFSET]
  69         ands    r2, r2, #M4IF_MCR0_FDVACK
  70         beq     wait_sr_ack
  71 
  72         /* Set pad config */
  73         ldr     r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
  74         cmp     r1, #0
  75         beq     skip_pad_conf_2
  76 
  77         add     r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
  78         ldr     r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
  79 
  80 2:
  81         ldr     r5, [r2], #4    /* IOMUXC register offset */
  82         ldr     r6, [r2], #4    /* clear */
  83         ldr     r7, [r3, r5]
  84         bic     r7, r7, r6
  85         ldr     r6, [r2], #8    /* set */
  86         orr     r7, r7, r6
  87         str     r7, [r3, r5]
  88         subs    r1, r1, #1
  89         bne     2b
  90 
  91 skip_pad_conf_2:
  92         /* Zzz, enter stop mode */
  93         wfi
  94         nop
  95         nop
  96         nop
  97         nop
  98 
  99         /* Restore pad config */
 100         ldr     r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
 101         cmp     r1, #0
 102         beq     skip_pad_conf_3
 103 
 104         add     r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
 105         ldr     r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
 106 
 107 3:
 108         ldr     r5, [r2], #12   /* IOMUXC register offset */
 109         ldr     r6, [r2], #4    /* saved value */
 110         str     r6, [r3, r5]
 111         subs    r1, r1, #1
 112         bne     3b
 113 
 114 skip_pad_conf_3:
 115         /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */
 116         ldr     r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET]
 117         ldr     r2,[r1, #M4IF_MCR0_OFFSET]
 118         bic     r2, r2, #M4IF_MCR0_FDVFS
 119         str     r2,[r1, #M4IF_MCR0_OFFSET]
 120 
 121         /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */
 122 wait_ar_ack:
 123         ldr     r2,[r1, #M4IF_MCR0_OFFSET]
 124         ands    r2, r2, #M4IF_MCR0_FDVACK
 125         bne     wait_ar_ack
 126 
 127         /* Restore registers */
 128         ldmfd   sp!, {r4,r5,r6,r7}
 129         mov     pc, lr
 130 
 131 ENDPROC(imx53_suspend)
 132 
 133 ENTRY(imx53_suspend_sz)
 134         .word   . - imx53_suspend

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