162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/linkage.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define M4IF_MCR0_OFFSET (0x008C) 1162306a36Sopenharmony_ci#define M4IF_MCR0_FDVFS (0x1 << 11) 1262306a36Sopenharmony_ci#define M4IF_MCR0_FDVACK (0x1 << 27) 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci .align 3 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * ==================== low level suspend ==================== 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * On entry 2062306a36Sopenharmony_ci * r0: pm_info structure address; 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * suspend ocram space layout: 2362306a36Sopenharmony_ci * ======================== high address ====================== 2462306a36Sopenharmony_ci * . 2562306a36Sopenharmony_ci * . 2662306a36Sopenharmony_ci * . 2762306a36Sopenharmony_ci * ^ 2862306a36Sopenharmony_ci * ^ 2962306a36Sopenharmony_ci * ^ 3062306a36Sopenharmony_ci * imx53_suspend code 3162306a36Sopenharmony_ci * PM_INFO structure(imx5_cpu_suspend_info) 3262306a36Sopenharmony_ci * ======================== low address ======================= 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* Offsets of members of struct imx5_cpu_suspend_info */ 3662306a36Sopenharmony_ci#define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 3762306a36Sopenharmony_ci#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 3862306a36Sopenharmony_ci#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 3962306a36Sopenharmony_ci#define SUSPEND_INFO_MX53_IO_STATE_OFFSET 0xc 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciENTRY(imx53_suspend) 4262306a36Sopenharmony_ci stmfd sp!, {r4,r5,r6,r7} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* Save pad config */ 4562306a36Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] 4662306a36Sopenharmony_ci cmp r1, #0 4762306a36Sopenharmony_ci beq skip_pad_conf_1 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET 5062306a36Sopenharmony_ci ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci1: 5362306a36Sopenharmony_ci ldr r5, [r2], #12 /* IOMUXC register offset */ 5462306a36Sopenharmony_ci ldr r6, [r3, r5] /* current value */ 5562306a36Sopenharmony_ci str r6, [r2], #4 /* save area */ 5662306a36Sopenharmony_ci subs r1, r1, #1 5762306a36Sopenharmony_ci bne 1b 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ciskip_pad_conf_1: 6062306a36Sopenharmony_ci /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */ 6162306a36Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] 6262306a36Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 6362306a36Sopenharmony_ci orr r2, r2, #M4IF_MCR0_FDVFS 6462306a36Sopenharmony_ci str r2,[r1, #M4IF_MCR0_OFFSET] 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */ 6762306a36Sopenharmony_ciwait_sr_ack: 6862306a36Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 6962306a36Sopenharmony_ci ands r2, r2, #M4IF_MCR0_FDVACK 7062306a36Sopenharmony_ci beq wait_sr_ack 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* Set pad config */ 7362306a36Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] 7462306a36Sopenharmony_ci cmp r1, #0 7562306a36Sopenharmony_ci beq skip_pad_conf_2 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET 7862306a36Sopenharmony_ci ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci2: 8162306a36Sopenharmony_ci ldr r5, [r2], #4 /* IOMUXC register offset */ 8262306a36Sopenharmony_ci ldr r6, [r2], #4 /* clear */ 8362306a36Sopenharmony_ci ldr r7, [r3, r5] 8462306a36Sopenharmony_ci bic r7, r7, r6 8562306a36Sopenharmony_ci ldr r6, [r2], #8 /* set */ 8662306a36Sopenharmony_ci orr r7, r7, r6 8762306a36Sopenharmony_ci str r7, [r3, r5] 8862306a36Sopenharmony_ci subs r1, r1, #1 8962306a36Sopenharmony_ci bne 2b 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ciskip_pad_conf_2: 9262306a36Sopenharmony_ci /* Zzz, enter stop mode */ 9362306a36Sopenharmony_ci wfi 9462306a36Sopenharmony_ci nop 9562306a36Sopenharmony_ci nop 9662306a36Sopenharmony_ci nop 9762306a36Sopenharmony_ci nop 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci /* Restore pad config */ 10062306a36Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] 10162306a36Sopenharmony_ci cmp r1, #0 10262306a36Sopenharmony_ci beq skip_pad_conf_3 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET 10562306a36Sopenharmony_ci ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci3: 10862306a36Sopenharmony_ci ldr r5, [r2], #12 /* IOMUXC register offset */ 10962306a36Sopenharmony_ci ldr r6, [r2], #4 /* saved value */ 11062306a36Sopenharmony_ci str r6, [r3, r5] 11162306a36Sopenharmony_ci subs r1, r1, #1 11262306a36Sopenharmony_ci bne 3b 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ciskip_pad_conf_3: 11562306a36Sopenharmony_ci /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */ 11662306a36Sopenharmony_ci ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] 11762306a36Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 11862306a36Sopenharmony_ci bic r2, r2, #M4IF_MCR0_FDVFS 11962306a36Sopenharmony_ci str r2,[r1, #M4IF_MCR0_OFFSET] 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */ 12262306a36Sopenharmony_ciwait_ar_ack: 12362306a36Sopenharmony_ci ldr r2,[r1, #M4IF_MCR0_OFFSET] 12462306a36Sopenharmony_ci ands r2, r2, #M4IF_MCR0_FDVACK 12562306a36Sopenharmony_ci bne wait_ar_ack 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci /* Restore registers */ 12862306a36Sopenharmony_ci ldmfd sp!, {r4,r5,r6,r7} 12962306a36Sopenharmony_ci mov pc, lr 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ciENDPROC(imx53_suspend) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ciENTRY(imx53_suspend_sz) 13462306a36Sopenharmony_ci .word . - imx53_suspend 135