18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/linkage.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define M4IF_MCR0_OFFSET (0x008C) 118c2ecf20Sopenharmony_ci#define M4IF_MCR0_FDVFS (0x1 << 11) 128c2ecf20Sopenharmony_ci#define M4IF_MCR0_FDVACK (0x1 << 27) 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci .align 3 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * ==================== low level suspend ==================== 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * On entry 208c2ecf20Sopenharmony_ci * r0: pm_info structure address; 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * suspend ocram space layout: 238c2ecf20Sopenharmony_ci * ======================== high address ====================== 248c2ecf20Sopenharmony_ci * . 258c2ecf20Sopenharmony_ci * . 268c2ecf20Sopenharmony_ci * . 278c2ecf20Sopenharmony_ci * ^ 288c2ecf20Sopenharmony_ci * ^ 298c2ecf20Sopenharmony_ci * ^ 308c2ecf20Sopenharmony_ci * imx53_suspend code 318c2ecf20Sopenharmony_ci * PM_INFO structure(imx5_cpu_suspend_info) 328c2ecf20Sopenharmony_ci * ======================== low address ======================= 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* Offsets of members of struct imx5_cpu_suspend_info */ 368c2ecf20Sopenharmony_ci#define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 378c2ecf20Sopenharmony_ci#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 388c2ecf20Sopenharmony_ci#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 398c2ecf20Sopenharmony_ci#define SUSPEND_INFO_MX53_IO_STATE_OFFSET 0xc 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ciENTRY(imx53_suspend) 428c2ecf20Sopenharmony_ci stmfd sp!, {r4,r5,r6,r7} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci /* Save pad config */ 458c2ecf20Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] 468c2ecf20Sopenharmony_ci cmp r1, #0 478c2ecf20Sopenharmony_ci beq skip_pad_conf_1 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET 508c2ecf20Sopenharmony_ci ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci1: 538c2ecf20Sopenharmony_ci ldr r5, [r2], #12 /* IOMUXC register offset */ 548c2ecf20Sopenharmony_ci ldr r6, [r3, r5] /* current value */ 558c2ecf20Sopenharmony_ci str r6, [r2], #4 /* save area */ 568c2ecf20Sopenharmony_ci subs r1, r1, #1 578c2ecf20Sopenharmony_ci bne 1b 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ciskip_pad_conf_1: 608c2ecf20Sopenharmony_ci /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */ 618c2ecf20Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] 628c2ecf20Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 638c2ecf20Sopenharmony_ci orr r2, r2, #M4IF_MCR0_FDVFS 648c2ecf20Sopenharmony_ci str r2,[r1, #M4IF_MCR0_OFFSET] 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */ 678c2ecf20Sopenharmony_ciwait_sr_ack: 688c2ecf20Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 698c2ecf20Sopenharmony_ci ands r2, r2, #M4IF_MCR0_FDVACK 708c2ecf20Sopenharmony_ci beq wait_sr_ack 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* Set pad config */ 738c2ecf20Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] 748c2ecf20Sopenharmony_ci cmp r1, #0 758c2ecf20Sopenharmony_ci beq skip_pad_conf_2 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET 788c2ecf20Sopenharmony_ci ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci2: 818c2ecf20Sopenharmony_ci ldr r5, [r2], #4 /* IOMUXC register offset */ 828c2ecf20Sopenharmony_ci ldr r6, [r2], #4 /* clear */ 838c2ecf20Sopenharmony_ci ldr r7, [r3, r5] 848c2ecf20Sopenharmony_ci bic r7, r7, r6 858c2ecf20Sopenharmony_ci ldr r6, [r2], #8 /* set */ 868c2ecf20Sopenharmony_ci orr r7, r7, r6 878c2ecf20Sopenharmony_ci str r7, [r3, r5] 888c2ecf20Sopenharmony_ci subs r1, r1, #1 898c2ecf20Sopenharmony_ci bne 2b 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciskip_pad_conf_2: 928c2ecf20Sopenharmony_ci /* Zzz, enter stop mode */ 938c2ecf20Sopenharmony_ci wfi 948c2ecf20Sopenharmony_ci nop 958c2ecf20Sopenharmony_ci nop 968c2ecf20Sopenharmony_ci nop 978c2ecf20Sopenharmony_ci nop 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci /* Restore pad config */ 1008c2ecf20Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] 1018c2ecf20Sopenharmony_ci cmp r1, #0 1028c2ecf20Sopenharmony_ci beq skip_pad_conf_3 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET 1058c2ecf20Sopenharmony_ci ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci3: 1088c2ecf20Sopenharmony_ci ldr r5, [r2], #12 /* IOMUXC register offset */ 1098c2ecf20Sopenharmony_ci ldr r6, [r2], #4 /* saved value */ 1108c2ecf20Sopenharmony_ci str r6, [r3, r5] 1118c2ecf20Sopenharmony_ci subs r1, r1, #1 1128c2ecf20Sopenharmony_ci bne 3b 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ciskip_pad_conf_3: 1158c2ecf20Sopenharmony_ci /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */ 1168c2ecf20Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] 1178c2ecf20Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 1188c2ecf20Sopenharmony_ci bic r2, r2, #M4IF_MCR0_FDVFS 1198c2ecf20Sopenharmony_ci str r2,[r1, #M4IF_MCR0_OFFSET] 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */ 1228c2ecf20Sopenharmony_ciwait_ar_ack: 1238c2ecf20Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 1248c2ecf20Sopenharmony_ci ands r2, r2, #M4IF_MCR0_FDVACK 1258c2ecf20Sopenharmony_ci bne wait_ar_ack 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci /* Restore registers */ 1288c2ecf20Sopenharmony_ci ldmfd sp!, {r4,r5,r6,r7} 1298c2ecf20Sopenharmony_ci mov pc, lr 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ciENDPROC(imx53_suspend) 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ciENTRY(imx53_suspend_sz) 1348c2ecf20Sopenharmony_ci .word . - imx53_suspend 135