blob: f751368820436a36176ac8666806c83f15ac35a8 [file] [log] [blame]
/*
* Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/linkage.h>
#include <asm/hardware/cache-l2x0.h>
#include "hardware.h"
#define MX6Q_SRC_GPR1 0x20
#define MX6Q_SRC_GPR2 0x24
#define MX6Q_MMDC_MAPSR 0x404
#define MX6Q_MMDC_MPDGCTRL0 0x83c
#define MX6Q_GPC_IMR1 0x08
#define MX6Q_GPC_IMR2 0x0c
#define MX6Q_GPC_IMR3 0x10
#define MX6Q_GPC_IMR4 0x14
#define MX6Q_CCM_CCR 0x0
#define MX6Q_ANATOP_CORE 0x140
#define MX6Q_ANATOP_MISC0 0x150
.globl imx6_suspend_start
.globl imx6_suspend_end
.align 3
.macro reset_fifo
/* reset read FIFO, RST_RD_FIFO */
ldr r7, =MX6Q_MMDC_MPDGCTRL0
ldr r6, [r8, r7]
orr r6, r6, #(1 << 31)
str r6, [r8, r7]
2:
ldr r6, [r8, r7]
and r6, r6, #(1 << 31)
cmp r6, #0
bne 2b
/* reset FIFO a second time */
ldr r6, [r8, r7]
orr r6, r6, #(1 << 31)
str r6, [r8, r7]
3:
ldr r6, [r8, r7]
and r6, r6, #(1 << 31)
cmp r6, #0
bne 3b
.endm
.macro imx6sx_ddr_io_save
ldr r4, [r8, #0x2ec] /* DRAM_DQM0 */
ldr r5, [r8, #0x2f0] /* DRAM_DQM1 */
ldr r6, [r8, #0x2f4] /* DRAM_DQM2 */
ldr r7, [r8, #0x2f8] /* DRAM_DQM3 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x300] /* DRAM_CAS */
ldr r5, [r8, #0x2fc] /* DRAM_RAS */
ldr r6, [r8, #0x32c] /* DRAM_SDCLK_0 */
ldr r7, [r8, #0x5f4] /* GPR_ADDDS */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x5f8] /* DDRMODE_CTL */
ldr r5, [r8, #0x608] /* DDRMODE */
ldr r6, [r8, #0x310] /* DRAM_SODT0*/
ldr r7, [r8, #0x314] /* DRAM_SODT1*/
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x330] /* DRAM_SDQS0 */
ldr r5, [r8, #0x334] /* DRAM_SDQS1 */
ldr r6, [r8, #0x338] /* DRAM_SDQS2 */
ldr r7, [r8, #0x33c] /* DRAM_SDQS3 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x60c] /* GPR_B0DS */
ldr r5, [r8, #0x610] /* GPR_B1DS */
ldr r6, [r8, #0x61c] /* GPR_B2DS */
ldr r7, [r8, #0x620] /* GPR_B3DS */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x324] /* DRAM_SDCKE0 */
ldr r5, [r8, #0x328] /* DRAM_SDCKE1 */
ldr r6, [r8, #0x340] /* DRAM_RESET */
stmfd r10!, {r4-r6}
.endm
.macro imx6sx_mmdc_save
ldr r4, [r8, #0x85c]
ldr r5, [r8, #0x800]
ldr r6, [r8, #0x890]
ldr r7, [r8, #0x8b8]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x81c]
ldr r5, [r8, #0x820]
ldr r6, [r8, #0x824]
ldr r7, [r8, #0x828]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x82c]
ldr r5, [r8, #0x830]
ldr r6, [r8, #0x834]
ldr r7, [r8, #0x838]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x848]
ldr r5, [r8, #0x850]
ldr r6, [r8, #0x8c0]
ldr r7, [r8, #0x83c]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x840]
ldr r5, [r8, #0x8b8]
ldr r6, [r8, #0x00c]
ldr r7, [r8, #0x004]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x010]
ldr r5, [r8, #0x014]
ldr r6, [r8, #0x018]
ldr r7, [r8, #0x02c]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x030]
ldr r5, [r8, #0x038]
ldr r6, [r8, #0x008]
ldr r7, [r8, #0x040]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x000]
ldr r5, [r8, #0x020]
ldr r6, [r8, #0x818]
ldr r7, [r8, #0x800]
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x004]
stmfd r10!, {r4}
.endm
.macro imx6sx_ddr_io_restore
ldmea r10!, {r4-r7}
str r4, [r8, #0x2ec] /* DRAM_DQM0 */
str r5, [r8, #0x2f0] /* DRAM_DQM1 */
str r6, [r8, #0x2f4] /* DRAM_DQM2 */
str r7, [r8, #0x2f8] /* DRAM_DQM3 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x300] /* DRAM_CAS */
str r5, [r8, #0x2fc] /* DRAM_RAS */
str r6, [r8, #0x32c] /* DRAM_SDCLK_0 */
str r7, [r8, #0x5f4] /* GPR_ADDDS */
ldmea r10!, {r4-r7}
str r4, [r8, #0x5f8] /* DDRMODE_CTL */
str r5, [r8, #0x608] /* DDRMODE */
str r6, [r8, #0x310] /* DRAM_SODT0*/
str r7, [r8, #0x314] /* DRAM_SODT1*/
ldmea r10!, {r4-r7}
str r4, [r8, #0x330] /* DRAM_SDQS0 */
str r5, [r8, #0x334] /* DRAM_SDQS1 */
str r6, [r8, #0x338] /* DRAM_SDQS2 */
str r7, [r8, #0x33c] /* DRAM_SDQS3 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x60c] /* GPR_B0DS */
str r5, [r8, #0x610] /* GPR_B1DS */
str r6, [r8, #0x61c] /* GPR_B2DS */
str r7, [r8, #0x620] /* GPR_B3DS */
ldmea r10!, {r4-r6}
str r4, [r8, #0x324] /* DRAM_SDCKE0 */
str r5, [r8, #0x328] /* DRAM_SDCKE1 */
str r6, [r8, #0x340] /* DRAM_RESET */
.endm
.macro imx6sx_mmdc_restore
ldr r7, =0x4000
add r8, r8, r7
ldr r4, [r8, #0x8] /* DRAM_RESET_BYPASS */
bic r4, r4, #(0x1 << 27)
str r4, [r8, #0x8]
ldr r4, [r8, #0x8] /* DRAM_CKE_BYPASS */
bic r4, r4, #(0x1 << 31)
str r4, [r8, #0x8]
.endm
.macro imx6sx_mmdc_restore_dsm
ldr r4, =0x8000
str r4, [r8, #0x01c]
ldmea r10!, {r4-r7}
str r4, [r8, #0x85c]
str r5, [r8, #0x800]
str r6, [r8, #0x890]
ldr r7, =0x800
str r7, [r8, #0x8b8]
ldmea r10!, {r4-r7}
str r4, [r8, #0x81c]
str r5, [r8, #0x820]
str r6, [r8, #0x824]
str r7, [r8, #0x828]
ldmea r10!, {r4-r7}
str r4, [r8, #0x82c]
str r5, [r8, #0x830]
str r6, [r8, #0x834]
str r7, [r8, #0x838]
ldmea r10!, {r4-r7}
str r4, [r8, #0x848]
str r5, [r8, #0x850]
str r6, [r8, #0x8c0]
str r7, [r8, #0x83c]
ldmea r10!, {r4-r7}
str r4, [r8, #0x840]
ldr r5, =0x800
str r5, [r8, #0x8b8]
str r6, [r8, #0x00c]
str r7, [r8, #0x004]
ldmea r10!, {r4-r7}
str r4, [r8, #0x010]
str r5, [r8, #0x014]
str r6, [r8, #0x018]
str r7, [r8, #0x02c]
ldmea r10!, {r4-r7}
str r4, [r8, #0x030]
str r5, [r8, #0x038]
str r6, [r8, #0x008]
str r7, [r8, #0x040]
ldmea r10!, {r4-r7}
str r4, [r8, #0x000]
str r5, [r8, #0x020]
str r6, [r8, #0x818]
str r7, [r8, #0x800]
ldmea r10!, {r4}
str r4, [r8, #0x004]
ldr r4, =0x0
str r4, [r8, #0x01c]
/* make the DDR explicitly enter self-refresh. */
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
orr r7, r7, #(1 << 20)
str r7, [r8, #MX6Q_MMDC_MAPSR]
4:
ldr r7, [r8, #0x404]
ands r7, r7, #(1 << 24)
beq 4b
ldr r7, =0x4000
add r11, r11, r7
ldr r4, [r11, #0x8] /* DRAM_RESET_BYPASS */
bic r4, r4, #(0x1 << 27)
str r4, [r11, #0x8]
ldr r4, [r11, #0x8] /* DRAM_CKE_BYPASS */
bic r4, r4, #(0x1 << 31)
str r4, [r11, #0x8]
/* make the DDR explicitly exit self-refresh. */
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
bic r7, r7, #(1 << 20)
str r7, [r8, #MX6Q_MMDC_MAPSR]
5:
ldr r7, [r8, #0x404]
ands r7, r7, #(1 << 24)
bne 5b
ldr r4, =0x0
str r4, [r8, #0x1c]
.endm
.macro imx6sx_ddr_io_set_lpm
mov r10, #0
str r10, [r8, #0x2ec] /* DRAM_DQM0 */
str r10, [r8, #0x2f0] /* DRAM_DQM1 */
str r10, [r8, #0x2f4] /* DRAM_DQM2 */
str r10, [r8, #0x2f8] /* DRAM_DQM3 */
str r10, [r8, #0x300] /* DRAM_CAS */
str r10, [r8, #0x2fc] /* DRAM_RAS */
str r10, [r8, #0x32c] /* DRAM_SDCLK_0 */
str r10, [r8, #0x5f4] /* GPR_ADDDS */
str r10, [r8, #0x5f8] /* DDRMODE_CTL */
str r10, [r8, #0x608] /* DDRMODE */
str r10, [r8, #0x310] /* DRAM_SODT0*/
str r10, [r8, #0x314] /* DRAM_SODT1*/
str r10, [r8, #0x330] /* DRAM_SDQS0 */
str r10, [r8, #0x334] /* DRAM_SDQS1 */
str r10, [r8, #0x338] /* DRAM_SDQS2 */
str r10, [r8, #0x33c] /* DRAM_SDQS3 */
str r10, [r8, #0x60c] /* GPR_B0DS */
str r10, [r8, #0x610] /* GPR_B1DS */
str r10, [r8, #0x61c] /* GPR_B2DS */
str r10, [r8, #0x620] /* GPR_B3DS */
mov r10, #0x80000
str r10, [r8, #0x340] /* DRAM_RESET */
mov r10, #0x1000
str r10, [r8, #0x324] /* DRAM_SDCKE0 */
str r10, [r8, #0x328] /* DRAM_SDCKE1 */
.endm
.macro imx6sx_mmdc_set_lpm
ldr r7, =0x4000
add r11, r8, r7
ldr r4, [r11, #0x8] /* DRAM_RESET */
orr r4, r4, #(0x1 << 28)
str r4, [r11, #0x8]
ldr r4, [r11, #0x8] /* DRAM_RESET_BYPASS */
orr r4, r4, #(0x1 << 27)
str r4, [r11, #0x8]
ldr r4, [r11, #0x8] /* DRAM_CKE_BYPASS */
orr r4, r4, #(0x1 << 31)
str r4, [r11, #0x8]
.endm
.macro imx6sl_ddr_io_save
ldr r4, [r8, #0x30c] /* DRAM_DQM0 */
ldr r5, [r8, #0x310] /* DRAM_DQM1 */
ldr r6, [r8, #0x314] /* DRAM_DQM2 */
ldr r7, [r8, #0x318] /* DRAM_DQM3 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x5c4] /* GPR_B0DS */
ldr r5, [r8, #0x5cc] /* GPR_B1DS */
ldr r6, [r8, #0x5d4] /* GPR_B2DS */
ldr r7, [r8, #0x5d8] /* GPR_B3DS */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x300] /* DRAM_CAS */
ldr r5, [r8, #0x31c] /* DRAM_RAS */
ldr r6, [r8, #0x338] /* DRAM_SDCLK_0 */
ldr r7, [r8, #0x5ac] /* GPR_ADDS*/
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x5b0] /* DDRMODE_CTL */
ldr r5, [r8, #0x5c0] /* DDRMODE */
ldr r6, [r8, #0x33c] /* DRAM_SODT0*/
ldr r7, [r8, #0x340] /* DRAM_SODT1*/
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x330] /* DRAM_SDCKE0 */
ldr r5, [r8, #0x334] /* DRAM_SDCKE1 */
ldr r6, [r8, #0x320] /* DRAM_RESET */
stmfd r10!, {r4-r6}
.endm
.macro imx6sl_ddr_io_restore
ldmea r10!, {r4-r7}
str r4, [r8, #0x30c] /* DRAM_DQM0 */
str r5, [r8, #0x310] /* DRAM_DQM1 */
str r6, [r8, #0x314] /* DRAM_DQM2 */
str r7, [r8, #0x318] /* DRAM_DQM3 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x5c4] /* GPR_B0DS */
str r5, [r8, #0x5cc] /* GPR_B1DS */
str r6, [r8, #0x5d4] /* GPR_B2DS */
str r7, [r8, #0x5d8] /* GPR_B3DS */
ldmea r10!, {r4-r7}
str r4, [r8, #0x300] /* DRAM_CAS */
str r5, [r8, #0x31c] /* DRAM_RAS */
str r6, [r8, #0x338] /* DRAM_SDCLK_0 */
str r7, [r8, #0x5ac] /* GPR_ADDS*/
ldmea r10!, {r4-r7}
str r4, [r8, #0x5b0] /* DDRMODE_CTL */
str r5, [r8, #0x5c0] /* DDRMODE */
str r6, [r8, #0x33c] /* DRAM_SODT0*/
str r7, [r8, #0x340] /* DRAM_SODT1*/
ldmea r10!, {r4-r6}
str r4, [r8, #0x330] /* DRAM_SDCKE0 */
str r5, [r8, #0x334] /* DRAM_SDCKE1 */
str r6, [r8, #0x320] /* DRAM_RESET */
.endm
.macro imx6sl_ddr_io_set_lpm
mov r10, #0
str r10, [r8, #0x30c] /* DRAM_DQM0 */
str r10, [r8, #0x310] /* DRAM_DQM1 */
str r10, [r8, #0x314] /* DRAM_DQM2 */
str r10, [r8, #0x318] /* DRAM_DQM3 */
str r10, [r8, #0x5c4] /* GPR_B0DS */
str r10, [r8, #0x5cc] /* GPR_B1DS */
str r10, [r8, #0x5d4] /* GPR_B2DS */
str r10, [r8, #0x5d8] /* GPR_B3DS */
str r10, [r8, #0x300] /* DRAM_CAS */
str r10, [r8, #0x31c] /* DRAM_RAS */
str r10, [r8, #0x338] /* DRAM_SDCLK_0 */
str r10, [r8, #0x5ac] /* GPR_ADDS*/
str r10, [r8, #0x5b0] /* DDRMODE_CTL */
str r10, [r8, #0x5c0] /* DDRMODE */
str r10, [r8, #0x33c] /* DRAM_SODT0*/
str r10, [r8, #0x340] /* DRAM_SODT1*/
mov r10, #0x80000
str r10, [r8, #0x320] /* DRAM_RESET */
mov r10, #0x1000
str r10, [r8, #0x330] /* DRAM_SDCKE0 */
str r10, [r8, #0x334] /* DRAM_SDCKE1 */
.endm
.macro imx6dl_ddr_io_save
ldr r4, [r8, #0x470] /* DRAM_DQM0 */
ldr r5, [r8, #0x474] /* DRAM_DQM1 */
ldr r6, [r8, #0x478] /* DRAM_DQM2 */
ldr r7, [r8, #0x47c] /* DRAM_DQM3 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x480] /* DRAM_DQM4 */
ldr r5, [r8, #0x484] /* DRAM_DQM5 */
ldr r6, [r8, #0x488] /* DRAM_DQM6 */
ldr r7, [r8, #0x48c] /* DRAM_DQM7 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x464] /* DRAM_CAS */
ldr r5, [r8, #0x490] /* DRAM_RAS */
ldr r6, [r8, #0x4ac] /* DRAM_SDCLK_0 */
ldr r7, [r8, #0x4b0] /* DRAM_SDCLK_1 */
stmfd r10!, {r4-r7}
ldr r5, [r8, #0x750] /* DDRMODE_CTL */
ldr r6, [r8, #0x760] /* DDRMODE */
stmfd r10!, {r5-r6}
ldr r4, [r8, #0x4bc] /* DRAM_SDQS0 */
ldr r5, [r8, #0x4c0] /* DRAM_SDQS1 */
ldr r6, [r8, #0x4c4] /* DRAM_SDQS2 */
ldr r7, [r8, #0x4c8] /* DRAM_SDQS3 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x4cc] /* DRAM_SDQS4 */
ldr r5, [r8, #0x4d0] /* DRAM_SDQS5 */
ldr r6, [r8, #0x4d4] /* DRAM_SDQS6 */
ldr r7, [r8, #0x4d8] /* DRAM_SDQS7 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x764] /* GPR_B0DS */
ldr r5, [r8, #0x770] /* GPR_B1DS */
ldr r6, [r8, #0x778] /* GPR_B2DS */
ldr r7, [r8, #0x77c] /* GPR_B3DS */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x780] /* GPR_B4DS */
ldr r5, [r8, #0x784] /* GPR_B5DS */
ldr r6, [r8, #0x78c] /* GPR_B6DS */
ldr r7, [r8, #0x748] /* GPR_B7DS */
stmfd r10!, {r4-r7}
ldr r5, [r8, #0x74c] /* GPR_ADDS*/
ldr r6, [r8, #0x4b4] /* DRAM_SODT0*/
ldr r7, [r8, #0x4b8] /* DRAM_SODT1*/
stmfd r10!, {r5-r7}
.endm
.macro imx6dl_ddr_io_restore
ldmea r10!, {r4-r7}
str r4, [r8, #0x470] /* DRAM_DQM0 */
str r5, [r8, #0x474] /* DRAM_DQM1 */
str r6, [r8, #0x478] /* DRAM_DQM2 */
str r7, [r8, #0x47c] /* DRAM_DQM3 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x480] /* DRAM_DQM4 */
str r5, [r8, #0x484] /* DRAM_DQM5 */
str r6, [r8, #0x488] /* DRAM_DQM6 */
str r7, [r8, #0x48c] /* DRAM_DQM7 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x464] /* DRAM_CAS */
str r5, [r8, #0x490] /* DRAM_RAS */
str r6, [r8, #0x4ac] /* DRAM_SDCLK_0 */
str r7, [r8, #0x4b0] /* DRAM_SDCLK_1 */
ldmea r10!, {r5-r6}
str r5, [r8, #0x750] /* DDRMODE_CTL */
str r6, [r8, #0x760] /* DDRMODE */
ldmea r10!, {r4-r7}
str r4, [r8, #0x4bc] /* DRAM_SDQS0 */
str r5, [r8, #0x4c0] /* DRAM_SDQS1 */
str r6, [r8, #0x4c4] /* DRAM_SDQS2 */
str r7, [r8, #0x4c8] /* DRAM_SDQS3 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x4cc] /* DRAM_SDQS4 */
str r5, [r8, #0x4d0] /* DRAM_SDQS5 */
str r6, [r8, #0x4d4] /* DRAM_SDQS6 */
str r7, [r8, #0x4d8] /* DRAM_SDQS7 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x764] /* GPR_B0DS */
str r5, [r8, #0x770] /* GPR_B1DS */
str r6, [r8, #0x778] /* GPR_B2DS */
str r7, [r8, #0x77c] /* GPR_B3DS */
ldmea r10!, {r4-r7}
str r4, [r8, #0x780] /* GPR_B4DS */
str r5, [r8, #0x784] /* GPR_B5DS */
str r6, [r8, #0x78c] /* GPR_B6DS */
str r7, [r8, #0x748] /* GPR_B7DS */
ldmea r10!, {r5-r7}
str r5, [r8, #0x74c] /* GPR_ADDS*/
str r6, [r8, #0x4b4] /* DRAM_SODT0*/
str r7, [r8, #0x4b8] /* DRAM_SODT1*/
.endm
.macro imx6dl_ddr_io_set_lpm
mov r10, #0
str r10, [r8, #0x470] /* DRAM_DQM0 */
str r10, [r8, #0x474] /* DRAM_DQM1 */
str r10, [r8, #0x478] /* DRAM_DQM2 */
str r10, [r8, #0x47c] /* DRAM_DQM3 */
str r10, [r8, #0x480] /* DRAM_DQM4 */
str r10, [r8, #0x484] /* DRAM_DQM5 */
str r10, [r8, #0x488] /* DRAM_DQM6 */
str r10, [r8, #0x48c] /* DRAM_DQM7 */
str r10, [r8, #0x464] /* DRAM_CAS */
str r10, [r8, #0x490] /* DRAM_RAS */
str r10, [r8, #0x4ac] /* DRAM_SDCLK_0 */
str r10, [r8, #0x4b0] /* DRAM_SDCLK_1 */
str r10, [r8, #0x750] /* DDRMODE_CTL */
str r10, [r8, #0x760] /* DDRMODE */
str r10, [r8, #0x4bc] /* DRAM_SDQS0 */
str r10, [r8, #0x4c0] /* DRAM_SDQS1 */
str r10, [r8, #0x4c4] /* DRAM_SDQS2 */
str r10, [r8, #0x4c8] /* DRAM_SDQS3 */
str r10, [r8, #0x4cc] /* DRAM_SDQS4 */
str r10, [r8, #0x4d0] /* DRAM_SDQS5 */
str r10, [r8, #0x4d4] /* DRAM_SDQS6 */
str r10, [r8, #0x4d8] /* DRAM_SDQS7 */
str r10, [r8, #0x764] /* GPR_B0DS */
str r10, [r8, #0x770] /* GPR_B1DS */
str r10, [r8, #0x778] /* GPR_B2DS */
str r10, [r8, #0x77c] /* GPR_B3DS */
str r10, [r8, #0x780] /* GPR_B4DS */
str r10, [r8, #0x784] /* GPR_B5DS */
str r10, [r8, #0x78c] /* GPR_B6DS */
str r10, [r8, #0x748] /* GPR_B7DS */
str r10, [r8, #0x74c] /* GPR_ADDS*/
str r10, [r8, #0x4b4] /* DRAM_SODT0*/
str r10, [r8, #0x4b8] /* DRAM_SODT1*/
.endm
.macro imx6dq_ddr_io_save
ldr r4, [r8, #0x5ac] /* DRAM_DQM0 */
ldr r5, [r8, #0x5b4] /* DRAM_DQM1 */
ldr r6, [r8, #0x528] /* DRAM_DQM2 */
ldr r7, [r8, #0x520] /* DRAM_DQM3 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x514] /* DRAM_DQM4 */
ldr r5, [r8, #0x510] /* DRAM_DQM5 */
ldr r6, [r8, #0x5bc] /* DRAM_DQM6 */
ldr r7, [r8, #0x5c4] /* DRAM_DQM7 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x56c] /* DRAM_CAS */
ldr r5, [r8, #0x578] /* DRAM_RAS */
ldr r6, [r8, #0x588] /* DRAM_SDCLK_0 */
ldr r7, [r8, #0x594] /* DRAM_SDCLK_1 */
stmfd r10!, {r4-r7}
ldr r5, [r8, #0x750] /* DDRMODE_CTL */
ldr r6, [r8, #0x774] /* DDRMODE */
stmfd r10!, {r5-r6}
ldr r4, [r8, #0x5a8] /* DRAM_SDQS0 */
ldr r5, [r8, #0x5b0] /* DRAM_SDQS1 */
ldr r6, [r8, #0x524] /* DRAM_SDQS2 */
ldr r7, [r8, #0x51c] /* DRAM_SDQS3 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x518] /* DRAM_SDQS4 */
ldr r5, [r8, #0x50c] /* DRAM_SDQS5 */
ldr r6, [r8, #0x5b8] /* DRAM_SDQS6 */
ldr r7, [r8, #0x5c0] /* DRAM_SDQS7 */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x784] /* GPR_B0DS */
ldr r5, [r8, #0x788] /* GPR_B1DS */
ldr r6, [r8, #0x794] /* GPR_B2DS */
ldr r7, [r8, #0x79c] /* GPR_B3DS */
stmfd r10!, {r4-r7}
ldr r4, [r8, #0x7a0] /* GPR_B4DS */
ldr r5, [r8, #0x7a4] /* GPR_B5DS */
ldr r6, [r8, #0x7a8] /* GPR_B6DS */
ldr r7, [r8, #0x748] /* GPR_B7DS */
stmfd r10!, {r4-r7}
ldr r5, [r8, #0x74c] /* GPR_ADDS*/
ldr r6, [r8, #0x59c] /* DRAM_SODT0*/
ldr r7, [r8, #0x5a0] /* DRAM_SODT1*/
stmfd r10!, {r5-r7}
.endm
.macro imx6dq_ddr_io_restore
ldmea r10!, {r4-r7}
str r4, [r8, #0x5ac] /* DRAM_DQM0 */
str r5, [r8, #0x5b4] /* DRAM_DQM1 */
str r6, [r8, #0x528] /* DRAM_DQM2 */
str r7, [r8, #0x520] /* DRAM_DQM3 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x514] /* DRAM_DQM4 */
str r5, [r8, #0x510] /* DRAM_DQM5 */
str r6, [r8, #0x5bc] /* DRAM_DQM6 */
str r7, [r8, #0x5c4] /* DRAM_DQM7 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x56c] /* DRAM_CAS */
str r5, [r8, #0x578] /* DRAM_RAS */
str r6, [r8, #0x588] /* DRAM_SDCLK_0 */
str r7, [r8, #0x594] /* DRAM_SDCLK_1 */
ldmea r10!, {r5-r6}
str r5, [r8, #0x750] /* DDRMODE_CTL */
str r6, [r8, #0x774] /* DDRMODE */
ldmea r10!, {r4-r7}
str r4, [r8, #0x5a8] /* DRAM_SDQS0 */
str r5, [r8, #0x5b0] /* DRAM_SDQS1 */
str r6, [r8, #0x524] /* DRAM_SDQS2 */
str r7, [r8, #0x51c] /* DRAM_SDQS3 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x518] /* DRAM_SDQS4 */
str r5, [r8, #0x50c] /* DRAM_SDQS5 */
str r6, [r8, #0x5b8] /* DRAM_SDQS6 */
str r7, [r8, #0x5c0] /* DRAM_SDQS7 */
ldmea r10!, {r4-r7}
str r4, [r8, #0x784] /* GPR_B0DS */
str r5, [r8, #0x788] /* GPR_B1DS */
str r6, [r8, #0x794] /* GPR_B2DS */
str r7, [r8, #0x79c] /* GPR_B3DS */
ldmea r10!, {r4-r7}
str r4, [r8, #0x7a0] /* GPR_B4DS */
str r5, [r8, #0x7a4] /* GPR_B5DS */
str r6, [r8, #0x7a8] /* GPR_B6DS */
str r7, [r8, #0x748] /* GPR_B7DS */
ldmea r10!, {r5-r7}
str r5, [r8, #0x74c] /* GPR_ADDS*/
str r6, [r8, #0x59c] /* DRAM_SODT0*/
str r7, [r8, #0x5a0] /* DRAM_SODT1*/
.endm
.macro imx6dq_ddr_io_set_lpm
mov r10, #0
str r10, [r8, #0x5ac] /* DRAM_DQM0 */
str r10, [r8, #0x5b4] /* DRAM_DQM1 */
str r10, [r8, #0x528] /* DRAM_DQM2 */
str r10, [r8, #0x520] /* DRAM_DQM3 */
str r10, [r8, #0x514] /* DRAM_DQM4 */
str r10, [r8, #0x510] /* DRAM_DQM5 */
str r10, [r8, #0x5bc] /* DRAM_DQM6 */
str r10, [r8, #0x5c4] /* DRAM_DQM7 */
str r10, [r8, #0x56c] /* DRAM_CAS */
str r10, [r8, #0x578] /* DRAM_RAS */
str r10, [r8, #0x588] /* DRAM_SDCLK_0 */
str r10, [r8, #0x594] /* DRAM_SDCLK_1 */
str r10, [r8, #0x750] /* DDRMODE_CTL */
str r10, [r8, #0x774] /* DDRMODE */
str r10, [r8, #0x5a8] /* DRAM_SDQS0 */
str r10, [r8, #0x5b0] /* DRAM_SDQS1 */
str r10, [r8, #0x524] /* DRAM_SDQS2 */
str r10, [r8, #0x51c] /* DRAM_SDQS3 */
str r10, [r8, #0x518] /* DRAM_SDQS4 */
str r10, [r8, #0x50c] /* DRAM_SDQS5 */
str r10, [r8, #0x5b8] /* DRAM_SDQS6 */
str r10, [r8, #0x5c0] /* DRAM_SDQS7 */
str r10, [r8, #0x784] /* GPR_B0DS */
str r10, [r8, #0x788] /* GPR_B1DS */
str r10, [r8, #0x794] /* GPR_B2DS */
str r10, [r8, #0x79c] /* GPR_B3DS */
str r10, [r8, #0x7a0] /* GPR_B4DS */
str r10, [r8, #0x7a4] /* GPR_B5DS */
str r10, [r8, #0x7a8] /* GPR_B6DS */
str r10, [r8, #0x748] /* GPR_B7DS */
str r10, [r8, #0x74c] /* GPR_ADDS*/
str r10, [r8, #0x59c] /* DRAM_SODT0*/
str r10, [r8, #0x5a0] /* DRAM_SODT1*/
.endm
.macro sync_l2_cache
/* sync L2 cache to drain L2's buffers to DRAM. */
#ifdef CONFIG_CACHE_L2X0
ldr r8, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
mov r5, #0x0
str r5, [r8, #L2X0_CACHE_SYNC]
1:
ldr r5, [r8, #L2X0_CACHE_SYNC]
ands r5, r5, #0x1
bne 1b
#endif
.endm
.macro reset_read_fifo
/* reset read FIFO, RST_RD_FIFO */
ldr r7, =MX6Q_MMDC_MPDGCTRL0
ldr r6, [r8, r7]
orr r6, r6, #(1 << 31)
str r6, [r8, r7]
2:
ldr r6, [r8, r7]
and r6, r6, #(1 << 31)
cmp r6, #0
bne 2b
/* reset FIFO a second time */
ldr r6, [r8, r7]
orr r6, r6, #(1 << 31)
str r6, [r8, r7]
3:
ldr r6, [r8, r7]
and r6, r6, #(1 << 31)
cmp r6, #0
bne 3b
.endm
ENTRY(imx6_suspend)
imx6_suspend_start:
push {r4-r12}
/*
* counting the resume address in iram
* to set it in SRC register.
*/
ldr r4, =imx6_suspend
ldr r5, =resume
sub r5, r5, r4
add r9, r1, r5
/*
* make sure TLB contain the addr we want,
* as we will access after DDR IO floated.
*/
ldr r8, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
ldr r7, [r8, #MX6Q_ANATOP_CORE]
ldr r8, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
ldr r7, [r8, #0x0]
ldr r8, =IMX_IO_P2V(MX6Q_GPC_BASE_ADDR)
ldr r7, [r8, #0x0]
/* use r8 to store the IO address */
ldr r8, =IMX_IO_P2V(MX6Q_SRC_BASE_ADDR)
/*
* read previous resume address from SRC
* register, which is v7_cpu_resume, this
* is for the jump when we finish DDR IO
* restore.
*/
ldr r7,=total_suspend_size
ldr r7, [r7]
add r10, r0, r7
ldr r5, [r8, #MX6Q_SRC_GPR1]
stmfd r10!, {r5}
/* save cpu type */
stmfd r10!, {r2}
str r9, [r8, #MX6Q_SRC_GPR1]
add r3, r1, r7
str r3, [r8, #MX6Q_SRC_GPR2]
cmp r2, #MXC_CPU_IMX6SX
bne rdc_save_done
/*
* i.MX6SX RDC needs PCIe and eim clk to be enabled
* if Mega/Fast off, it is better to check cpu type
* and whether Mega/Fast is off in this suspend flow,
* but we need to add cpu type check for 3 places which
* will increase code size, so here we just do it
* for all cases, as when STOP mode is entered, CCM
* hardware will gate all clocks, so it will NOT impact
* any function or power.
*/
ldr r8, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
ldr r4, [r8, #0x78]
ldr r5, [r8, #0x80]
stmfd r10!, {r4-r5}
orr r4, r4, #0x3
str r4, [r8, #0x78]
orr r5, r5, #0xc00
str r5, [r8, #0x80]
rdc_save_done:
ldr r8, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
cmp r2, #MXC_CPU_IMX6Q
bne dl_io_dsm_save
imx6dq_ddr_io_save
b ddr_io_save_dsm_done
dl_io_dsm_save:
cmp r2, #MXC_CPU_IMX6DL
bne sl_io_save
imx6dl_ddr_io_save
b ddr_io_save_dsm_done
sl_io_save:
cmp r2, #MXC_CPU_IMX6SL
bne sx_io_save
imx6sl_ddr_io_save
b ddr_io_save_dsm_done
sx_io_save:
ldr r8, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
imx6sx_ddr_io_save
ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
imx6sx_mmdc_save
ddr_io_save_dsm_done:
/* need to sync L2 cache before DSM. */
sync_l2_cache
/*
* To ensure no page table walks occur in DDR, we
* have a another page table stored in IRAM that only
* contains entries pointing to IRAM, AIPS1 and AIPS2.
* We need to set the TTBR1 to the new IRAM TLB.
* Do the following steps:
* 1. Flush the Branch Target Address Cache (BTAC)
* 2. Set TTBR1 to point to IRAM page table.
* 3. Disable page table walks in TTBR0 (PD0 = 1)
* 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
* and 2-4G is translated by TTBR1.
*/
/* Disable Branch Prediction, Z bit in SCTLR. */
mrc p15, 0, r6, c1, c0, 0
bic r6, r6, #0x800
mcr p15, 0, r6, c1, c0, 0
/* Flush the BTAC. */
ldr r6, =0x0
mcr p15, 0, r6, c7, c1, 6
ldr r6, =iram_tlb_phys_addr
ldr r6, [r6]
dsb
isb
/* Store the IRAM table in TTBR1 */
mcr p15, 0, r6, c2, c0, 1
/* Read TTBCR and set PD0=1, N = 1 */
mrc p15, 0, r6, c2, c0, 2
orr r6, r6, #0x11
mcr p15, 0, r6, c2, c0, 2
dsb
isb
/* flush the TLB */
ldr r6, =0x0
mcr p15, 0, r6, c8, c3, 0
/* Disable L1 data cache. */
mrc p15, 0, r6, c1, c0, 0
bic r6, r6, #0x4
mcr p15, 0, r6, c1, c0, 0
dsb
isb
#ifdef CONFIG_CACHE_L2X0
ldr r8, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
mov r6, #0x0
str r6, [r8, #0x100]
dsb
isb
#endif
ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
/*
* put DDR explicitly into self-refresh and
* disable Automatic power savings.
*/
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
orr r7, r7, #0x01
str r7, [r8, #MX6Q_MMDC_MAPSR]
/* make the DDR explicitly enter self-refresh. */
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
orr r7, r7, #(1 << 21)
str r7, [r8, #MX6Q_MMDC_MAPSR]
poll_dvfs_set_1:
ldr r7, [r8, #0x404]
ands r7, r7, #(1 << 25)
beq poll_dvfs_set_1
ldr r8, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
cmp r2, #MXC_CPU_IMX6Q
bne dl_io_dsm_set_lpm
imx6dq_ddr_io_set_lpm
b ddr_io_set_lpm_dsm_done
dl_io_dsm_set_lpm:
cmp r2, #MXC_CPU_IMX6DL
bne sl_io_dsm_set_lpm
imx6dl_ddr_io_set_lpm
b ddr_io_set_lpm_dsm_done
sl_io_dsm_set_lpm:
cmp r2, #MXC_CPU_IMX6SL
bne sx_io_dsm_set_lpm
imx6sl_ddr_io_set_lpm
b ddr_io_set_lpm_dsm_done
sx_io_dsm_set_lpm:
imx6sx_ddr_io_set_lpm
imx6sx_mmdc_set_lpm
ddr_io_set_lpm_dsm_done:
/*
* mask all GPC interrupts before
* enabling the RBC counters to
* avoid the counter starting too
* early if an interupt is already
* pending.
*/
ldr r8, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
/* save CCM base in r9 */
mov r9, r8
ldr r8, =IMX_IO_P2V(MX6Q_GPC_BASE_ADDR)
ldr r4, [r8, #MX6Q_GPC_IMR1]
ldr r5, [r8, #MX6Q_GPC_IMR2]
ldr r6, [r8, #MX6Q_GPC_IMR3]
ldr r7, [r8, #MX6Q_GPC_IMR4]
ldr r3, =0xffffffff
str r3, [r8, #MX6Q_GPC_IMR1]
str r3, [r8, #MX6Q_GPC_IMR2]
str r3, [r8, #MX6Q_GPC_IMR3]
str r3, [r8, #MX6Q_GPC_IMR4]
/*
* enable the RBC bypass counter here
* to hold off the interrupts. RBC counter
* = 32 (1ms), Minimum RBC delay should be
* 400us for the analog LDOs to power down.
*/
ldr r3, [r9, #MX6Q_CCM_CCR]
bic r3, r3, #(0x3f << 21)
orr r3, r3, #(0x20 << 21)
str r3, [r9, #MX6Q_CCM_CCR]
/* enable the counter. */
ldr r3, [r9, #MX6Q_CCM_CCR]
orr r3, r3, #(0x1 << 27)
str r3, [r9, #MX6Q_CCM_CCR]
/* unmask all the GPC interrupts. */
str r4, [r8, #MX6Q_GPC_IMR1]
str r5, [r8, #MX6Q_GPC_IMR2]
str r6, [r8, #MX6Q_GPC_IMR3]
str r7, [r8, #MX6Q_GPC_IMR4]
/*
* now delay for a short while (3usec)
* ARM is at 1GHz at this point
* so a short loop should be enough.
* this delay is required to ensure that
* the RBC counter can start counting in
* case an interrupt is already pending
* or in case an interrupt arrives just
* as ARM is about to assert DSM_request.
*/
ldr r4, =2000
rbc_loop:
sub r4, r4, #0x1
cmp r4, #0x0
bne rbc_loop
/*
* if internal ldo(VDDARM) bypassed,analog bypass
* it for DSM(0x1e) and restore it when resume(0x1f).
*/
ldr r8, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
ldr r7, [r8, #MX6Q_ANATOP_CORE]
and r7, r7, #0x1f
cmp r7, #0x1f
bne ldo_check_done1
ldo_analog_bypass:
ldr r7, [r8, #MX6Q_ANATOP_CORE]
bic r7, r7, #0x1f
orr r7, r7, #0x1e
str r7, [r8, #MX6Q_ANATOP_CORE]
ldo_check_done1:
/*
* Enable the bandgap selfbias circuit required
* for bandgap to startup.
*/
ldr r7, [r8, #MX6Q_ANATOP_MISC0]
bic r7, r7, #0x8
str r7, [r8, #MX6Q_ANATOP_MISC0]
/* Zzz, enter stop mode */
wfi
nop
nop
nop
nop
/*
* We did not power down, disable bandgap
* self-bias circuit.
*/
ldr r8, =IMX_IO_P2V(MX6Q_ANATOP_BASE_ADDR)
ldr r7, [r8, #MX6Q_ANATOP_MISC0]
orr r7, r7, #0x8
str r7, [r8, #MX6Q_ANATOP_MISC0]
/*
* run to here means there is pending
* wakeup source, system should auto
* resume, we need to restore DDR IO first
*/
/* restore it with 0x1f if use ldo bypass mode.*/
ldr r7, [r8, #MX6Q_ANATOP_CORE]
and r7, r7, #0x1f
cmp r7, #0x1e
bne ldo_check_done2
ldo_bypass_restore:
ldr r7, [r8, #MX6Q_ANATOP_CORE]
orr r7, r7, #0x1f
str r7, [r8, #MX6Q_ANATOP_CORE]
ldo_check_done2:
adrl r7, imx6_suspend_end
add r10, r7, #MX6_SUSPEND_IRAM_DATA_SIZE
/* skip the lr saved in iram */
sub r10, r10, #0x4
/* skip the cpu type saved in iram */
sub r10, r10, #0x4
cmp r2, #MXC_CPU_IMX6SX
bne rdc_restore_done
/* restore CCM CCGR clk for RDC */
ldmea r10!, {r4-r5}
ldr r8, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
str r4, [r8, #0x78]
str r5, [r8, #0x80]
rdc_restore_done:
ldr r8, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
cmp r2, #MXC_CPU_IMX6Q
bne dl_io_restore
imx6dq_ddr_io_restore
b ddr_io_restore_done
dl_io_restore:
cmp r2, #MXC_CPU_IMX6DL
bne sl_io_restore
imx6dl_ddr_io_restore
b ddr_io_restore_done
sl_io_restore:
cmp r2, #MXC_CPU_IMX6SL
bne sx_io_restore
imx6sl_ddr_io_restore
ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
reset_fifo
b ddr_io_restore_done
sx_io_restore:
ldr r8, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
imx6sx_ddr_io_restore
ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
reset_fifo
imx6sx_mmdc_restore
ddr_io_restore_done:
ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
/* let DDR out of self-refresh. */
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
bic r7, r7, #(1 << 21)
str r7, [r8, #MX6Q_MMDC_MAPSR]
poll_dvfs_clear_2:
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
ands r7, r7, #(1 << 25)
bne poll_dvfs_clear_2
/* enable DDR auto power saving */
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
bic r7, r7, #0x1
str r7, [r8, #MX6Q_MMDC_MAPSR]
#ifdef CONFIG_CACHE_L2X0
/* Enable L2. */
ldr r8, =IMX_IO_P2V(MX6Q_L2_BASE_ADDR)
ldr r7, =0x1
str r7, [r8, #0x100]
#endif
/* Enable L1 data cache. */
mrc p15, 0, r6, c1, c0, 0
orr r6, r6, #0x4
mcr p15, 0, r6, c1, c0, 0
/* Restore TTBCR */
dsb
isb
/* Read TTBCR and set PD0=0, N = 0 */
mrc p15, 0, r6, c2, c0, 2
bic r6, r6, #0x11
mcr p15, 0, r6, c2, c0, 2
dsb
isb
/* flush the TLB */
ldr r6, =0x0
mcr p15, 0, r6, c8, c3, 0
/* Enable Branch Prediction, Z bit in SCTLR. */
mrc p15, 0, r6, c1, c0, 0
orr r6, r6, #0x800
mcr p15, 0, r6, c1, c0, 0
/* Flush the Branch Target Address Cache (BTAC) */
ldr r6, =0x0
mcr p15, 0, r6, c7, c1, 6
pop {r4-r12}
/* return to suspend finish */
mov pc, lr
resume:
/* invalidate L1 I-cache first */
mov r1, #0x0
mcr p15, 0, r1, c7, c5, 0
mcr p15, 0, r1, c7, c5, 0
mcr p15, 0, r1, c7, c5, 6
/* enable the Icache and branch prediction */
mov r1, #0x1800
mcr p15, 0, r1, c1, c0, 0
isb
/*
* We did power down. Ensure bandgap is stable.
*/
ldr r8, =MX6Q_ANATOP_BASE_ADDR
bg_not_stable:
ldr r7, [r8, #MX6Q_ANATOP_MISC0]
and r7, r7, #0x80
cmp r7, #0x80
bne bg_not_stable
/* Now disable bandgap self-bias circuit. */
ldr r7, [r8, #MX6Q_ANATOP_MISC0]
orr r7, r7, #0x8
str r7, [r8, #MX6Q_ANATOP_MISC0]
/* restore it with 0x1f if use ldo bypass mode.*/
ldr r7, [r8, #MX6Q_ANATOP_CORE]
and r7, r7, #0x1f
cmp r7, #0x1e
bne ldo_check_done3
ldr r7, [r8, #MX6Q_ANATOP_CORE]
orr r7, r7, #0x1f
str r7, [r8, #MX6Q_ANATOP_CORE]
ldo_check_done3:
ldr r5, =MX6Q_SRC_BASE_ADDR
ldr r10, [r5, #MX6Q_SRC_GPR2]
ldmea r10!, {lr}
/* get cpu tpye */
ldmea r10!, {r2}
cmp r2, #MXC_CPU_IMX6SX
bne rdc_dsm_restore_done
/* restore CCM CCGR clk for RDC */
ldmea r10!, {r4-r5}
ldr r8, =MX6Q_CCM_BASE_ADDR
str r4, [r8, #0x78]
str r5, [r8, #0x80]
rdc_dsm_restore_done:
/* clear core0's entry and parameter */
ldr r8, =MX6Q_SRC_BASE_ADDR
mov r7, #0
str r7, [r8, #MX6Q_SRC_GPR1]
str r7, [r8, #MX6Q_SRC_GPR2]
ldr r8, =MX6Q_IOMUXC_BASE_ADDR
cmp r2, #MXC_CPU_IMX6Q
bne dl_io_dsm_restore
imx6dq_ddr_io_restore
b ddr_io_restore_dsm_done
dl_io_dsm_restore:
cmp r2, #MXC_CPU_IMX6DL
bne sl_io_dsm_restore
imx6dl_ddr_io_restore
b ddr_io_restore_dsm_done
sl_io_dsm_restore:
cmp r2, #MXC_CPU_IMX6SL
bne sx_io_dsm_restore
imx6sl_ddr_io_restore
ldr r8, =MX6Q_MMDC_P0_BASE_ADDR
reset_fifo
b ddr_io_restore_dsm_done
sx_io_dsm_restore:
ldr r8, =MX6Q_IOMUXC_BASE_ADDR
imx6sx_ddr_io_restore
/* check whether M/F mix is powered off */
ldr r8, =MX6Q_GPC_BASE_ADDR
ldr r7, [r8, #0x220]
ands r7, #0x1
bne mega_fast_off
ldr r8, =MX6Q_IOMUXC_BASE_ADDR
imx6sx_mmdc_restore
ldr r8, =MX6Q_MMDC_P0_BASE_ADDR
reset_fifo
b ddr_io_restore_dsm_done
mega_fast_off:
ldr r8, =MX6Q_MMDC_P0_BASE_ADDR
ldr r11, =MX6Q_IOMUXC_BASE_ADDR
imx6sx_mmdc_restore_dsm
reset_fifo
ddr_io_restore_dsm_done:
ldr r8, =MX6Q_MMDC_P0_BASE_ADDR
/* let DDR out of self-refresh */
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
bic r7, r7, #(1 << 21)
str r7, [r8, #MX6Q_MMDC_MAPSR]
poll_dvfs_clear_1:
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
ands r7, r7, #(1 << 25)
bne poll_dvfs_clear_1
/* enable DDR auto power saving */
ldr r7, [r8, #MX6Q_MMDC_MAPSR]
bic r7, r7, #0x1
str r7, [r8, #MX6Q_MMDC_MAPSR]
mov pc, lr
/*
* Add ltorg here to ensure that all
* literals are stored here and are
* within the text space.
*/
.ltorg
imx6_suspend_end: