summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/suspend-imx6.S
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2014-06-13 14:35:24 +0800
committerNitin Garg <nitin.garg@freescale.com>2014-08-27 18:28:57 -0500
commit7beced60440f90e8949f826ce323e6adc02742d8 (patch)
tree2eee68f9015efc93c5a778ce81d5625372efb580 /arch/arm/mach-imx/suspend-imx6.S
parent0ab7b6489d0dc253cd5c4b8b8a00d8e3f13fb34a (diff)
ENGR00318259-2 ARM: imx: support mega fast domain power off in DSM
Add mega fast domain power off feature in DSM, it can save about 0.72mW power; If there is any module in Mega/Fast domain enabled as wakeup source, then Mega/Fast domain's power will be kept on in DSM. Signed-off-by: Anson Huang <b20788@freescale.com>
Diffstat (limited to 'arch/arm/mach-imx/suspend-imx6.S')
-rw-r--r--arch/arm/mach-imx/suspend-imx6.S247
1 files changed, 207 insertions, 40 deletions
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index da9bd589f5ea..7cd6a8cbd39c 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -36,6 +36,31 @@
.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 */
@@ -70,6 +95,50 @@
.endm
+ .macro imx6sx_mmdc_save
+
+ ldr r4, [r8, #0x800]
+ ldr r5, [r8, #0x80c]
+ ldr r6, [r8, #0x810]
+ ldr r7, [r8, #0x83c]
+ stmfd r10!, {r4-r7}
+
+ ldr r4, [r8, #0x840]
+ ldr r5, [r8, #0x848]
+ ldr r6, [r8, #0x850]
+ ldr r7, [r8, #0x81c]
+ stmfd r10!, {r4-r7}
+
+ ldr r4, [r8, #0x820]
+ ldr r5, [r8, #0x824]
+ ldr r6, [r8, #0x828]
+ ldr r7, [r8, #0x8b8]
+ stmfd r10!, {r4-r7}
+
+ ldr r4, [r8, #0x004]
+ ldr r5, [r8, #0x008]
+ ldr r6, [r8, #0x00c]
+ ldr r7, [r8, #0x010]
+ stmfd r10!, {r4-r7}
+
+ ldr r4, [r8, #0x014]
+ ldr r5, [r8, #0x018]
+ ldr r6, [r8, #0x01c]
+ ldr r7, [r8, #0x02c]
+ stmfd r10!, {r4-r7}
+
+ ldr r4, [r8, #0x030]
+ ldr r5, [r8, #0x040]
+ ldr r6, [r8, #0x000]
+ ldr r7, [r8, #0x020]
+ stmfd r10!, {r4-r7}
+
+ ldr r4, [r8, #0x818]
+ ldr r5, [r8, #0x01c]
+ stmfd r10!, {r4-r5}
+
+ .endm
+
.macro imx6sx_ddr_io_restore
ldmea r10!, {r4-r7}
@@ -104,6 +173,103 @@
.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
+
+ ldmea r10!, {r4-r7}
+ str r4, [r8, #0x800]
+ str r5, [r8, #0x80c]
+ str r6, [r8, #0x810]
+ str r7, [r8, #0x83c]
+
+ ldmea r10!, {r4-r7}
+ str r4, [r8, #0x840]
+ str r5, [r8, #0x848]
+ str r6, [r8, #0x850]
+ str r7, [r8, #0x81c]
+
+ ldmea r10!, {r4-r7}
+ str r4, [r8, #0x820]
+ str r5, [r8, #0x824]
+ str r6, [r8, #0x828]
+ str r7, [r8, #0x8b8]
+
+ ldmea r10!, {r4-r7}
+ str r4, [r8, #0x004]
+ str r5, [r8, #0x008]
+ str r6, [r8, #0x00c]
+ str r7, [r8, #0x010]
+
+ ldmea r10!, {r4-r7}
+ str r4, [r8, #0x014]
+ str r5, [r8, #0x018]
+ str r6, [r8, #0x01c]
+ str r7, [r8, #0x02c]
+
+ ldmea r10!, {r4-r7}
+ bic r4, #0xff00
+ bic r4, #0xff
+ orr r4, #0x0200
+ orr r4, #0x02
+ str r4, [r8, #0x030]
+ str r5, [r8, #0x040]
+ str r6, [r8, #0x000]
+ /* make sure MMDC is ready */
+ ldr r4, =0x8033
+ str r4, [r8, #0x01c]
+ str r7, [r8, #0x020]
+
+ ldmea r10!, {r4-r5}
+ str r4, [r8, #0x818]
+ str r5, [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
@@ -134,6 +300,25 @@
.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 */
@@ -625,7 +810,10 @@ sl_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. */
@@ -726,6 +914,7 @@ sl_io_dsm_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:
/*
@@ -852,29 +1041,12 @@ sl_io_restore:
bne sx_io_restore
imx6sl_ddr_io_restore
ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
- /* reset read FIFO, RST_RD_FIFO */
- ldr r7, =MX6Q_MMDC_MPDGCTRL0
- ldr r6, [r8, r7]
- orr r6, r6, #(1 << 31)
- str r6, [r8, r7]
-fifo_reset1_wait:
- ldr r6, [r8, r7]
- and r6, r6, #(1 << 31)
- cmp r6, #0
- bne fifo_reset1_wait
-
- /* reset FIFO a second time */
- ldr r6, [r8, r7]
- orr r6, r6, #(1 << 31)
- str r6, [r8, r7]
-fifo_reset2_wait:
- ldr r6, [r8, r7]
- and r6, r6, #(1 << 31)
- cmp r6, #0
- bne fifo_reset2_wait
+ reset_fifo
b ddr_io_restore_done
sx_io_restore:
+ ldr r8, =IMX_IO_P2V(MX6Q_IOMUXC_BASE_ADDR)
imx6sx_ddr_io_restore
+ imx6sx_mmdc_restore
ddr_io_restore_done:
ldr r8, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
@@ -983,29 +1155,24 @@ sl_io_dsm_restore:
bne sx_io_dsm_restore
imx6sl_ddr_io_restore
ldr r8, =MX6Q_MMDC_P0_BASE_ADDR
- /* reset read FIFO, RST_RD_FIFO */
- ldr r7, =MX6Q_MMDC_MPDGCTRL0
- ldr r6, [r8, r7]
- orr r6, r6, #(1 << 31)
- str r6, [r8, r7]
-dsm_fifo_reset1_wait:
- ldr r6, [r8, r7]
- and r6, r6, #(1 << 31)
- cmp r6, #0
- bne dsm_fifo_reset1_wait
-
- /* reset FIFO a second time */
- ldr r6, [r8, r7]
- orr r6, r6, #(1 << 31)
- str r6, [r8, r7]
-dsm_fifo_reset2_wait:
- ldr r6, [r8, r7]
- and r6, r6, #(1 << 31)
- cmp r6, #0
- bne dsm_fifo_reset2_wait
+ 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
+ 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