diff options
author | Anson Huang <b20788@freescale.com> | 2014-06-13 14:35:24 +0800 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-08-27 18:28:57 -0500 |
commit | 7beced60440f90e8949f826ce323e6adc02742d8 (patch) | |
tree | 2eee68f9015efc93c5a778ce81d5625372efb580 /arch/arm/mach-imx/suspend-imx6.S | |
parent | 0ab7b6489d0dc253cd5c4b8b8a00d8e3f13fb34a (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.S | 247 |
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 |