linux/arch/arm/mach-imx/suspend-imx53.S
<<
>>
Prefs
   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(imx5_cpu_suspend_info)
  32 * ======================== low address =======================
  33 */
  34
  35/* Offsets of members of struct imx5_cpu_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
  41ENTRY(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
  521:
  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
  59skip_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 */
  67wait_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
  802:
  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
  91skip_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
 1073:
 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
 114skip_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 */
 122wait_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
 131ENDPROC(imx53_suspend)
 132
 133ENTRY(imx53_suspend_sz)
 134        .word   . - imx53_suspend
 135