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