Linux Audio

Check our new training course

Loading...
  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