| /* |
| * Copyright (C) 2015 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 teh 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. |
| */ |
| |
| #include <linux/linkage.h> |
| |
| #define PM_INFO_PM_INFO_SIZE_OFFSET 0x0 |
| #define PM_INFO_TTBR_OFFSET 0x4 |
| #define PM_INFO_MMDC_V_OFFSET 0x8 |
| #define PM_INFO_IOMUXC_V_OFFSET 0xc |
| #define PM_INFO_CCM_V_OFFSET 0x10 |
| #define PM_INFO_L2_V_OFFSET 0x14 |
| #define PM_INFO_ANATOP_V_OFFSET 0x18 |
| #define PM_INFO_IO_NUM_OFFSET 0x1c |
| #define PM_INFO_IO_VAL_OFFSET 0x20 |
| |
| #define MX6Q_MMDC_MAPSR 0x404 |
| #define MX6Q_MMDC_MPDGCTRL0 0x83c |
| |
| .global mx6sl_lpm_wfi_start |
| .global mx6sl_lpm_wfi_end |
| |
| .macro pll_do_wait_lock |
| 1: |
| ldr r7, [r10, r8] |
| ands r7, #0x80000000 |
| beq 1b |
| |
| .endm |
| |
| .macro ccm_do_wait |
| 2: |
| ldr r7, [r10, #0x48] |
| cmp r7, #0x0 |
| bne 2b |
| |
| .endm |
| |
| .macro ccm_enter_idle |
| |
| ldr r10, [r0, #PM_INFO_CCM_V_OFFSET] |
| /* |
| * if in audio_bus_freq_mode, skip to |
| * audio_mode low power setting. |
| */ |
| cmp r1, #0x1 |
| beq audio_mode |
| /* |
| * Now set DDR rate to 1MHz. |
| * DDR is from bypassed PLL2 on periph2_clk2 path. |
| * Set the periph2_clk2_podf to divide by 8. |
| */ |
| ldr r6, [r10, #0x14] |
| orr r6, r6, #0x07 |
| str r6, [r10, #0x14] |
| |
| /* Now set MMDC PODF to divide by 3. */ |
| ldr r6, [r10, #0x14] |
| bic r6, r6, #0x38 |
| orr r6, r6, #0x10 |
| str r6, [r10, #0x14] |
| |
| ccm_do_wait |
| |
| /* Set the AHB to 3MHz. AXI to 3MHz. */ |
| ldr r6, [r10, #0x14] |
| /*r12 stores the origin AHB podf value */ |
| mov r12, r6 |
| orr r6, r6, #0x1c00 |
| orr r6, r6, #0x70000 |
| str r6, [r10, #0x14] |
| |
| ccm_do_wait |
| |
| /* Now set ARM to 24MHz. |
| * Move ARM to be sourced from step_clk |
| * after setting step_clk to 24MHz. |
| */ |
| ldr r6, [r10, #0x0c] |
| bic r6, r6, #0x100 |
| str r6, [r10, #0xc] |
| /*Now pll1_sw_clk to step_clk */ |
| ldr r6, [r10, #0x0c] |
| orr r6, r6, #0x4 |
| str r6, [r10, #0x0c] |
| |
| /* Bypass PLL1 and power it down */ |
| ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET] |
| ldr r6, =(1 << 16) |
| orr r6, r6, #0x1000 |
| str r6, [r10, #0x04] |
| |
| /* |
| * Set the ARM PODF to divide by 8. |
| * IPG is at 1.5MHz here, we need ARM to |
| * run at the 12:5 ratio (WAIT mode issue). |
| */ |
| ldr r10, [r0, #PM_INFO_CCM_V_OFFSET] |
| ldr r11, [r10, #0x10] |
| ldr r6, =0x07 |
| str r6, [r10, #0x10] |
| |
| ccm_do_wait |
| |
| b ccm_idle_done |
| |
| audio_mode: |
| /* |
| * MMDC is sourced from pll2_200M. |
| * Set the mmdc_podf to div by 8 |
| */ |
| ldr r10, [r0, #PM_INFO_CCM_V_OFFSET] |
| ldr r6, [r10, #0x14] |
| orr r6, r6, #0x38 |
| str r6, [r10, #0x14] |
| |
| ccm_do_wait |
| |
| /* |
| * ARM is sourced from pll2_pfd2_400M here. |
| * switch ARM to bypassed PLL1 |
| */ |
| ldr r10, [r0, #PM_INFO_CCM_V_OFFSET] |
| ldr r6, [r10, #0x0c] |
| bic r6, r6, #0x4 |
| str r6, [r10, #0xc] |
| |
| /* |
| * set the arm_podf to divide by 3 |
| * as IPG is at 4MHz, we cannot run |
| * arm clk above 9.6MHz when system |
| * enter WAIT mode |
| */ |
| ldr r11, [r10, #0x10] |
| ldr r6, =0x2 |
| str r6, [r10, #0x10] |
| |
| ccm_do_wait |
| |
| ccm_idle_done: |
| |
| .endm |
| |
| .macro ccm_exit_idle |
| |
| /* |
| * If in audio_bus_freq_mode, skip to |
| * audio_mode ccm restore. |
| */ |
| cmp r1, #0x1 |
| beq audio_ccm_restore |
| |
| ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET] |
| /* Power up PLL1 and un-bypass it. */ |
| ldr r6, =(1 << 12) |
| str r6, [r10, #0x08] |
| |
| /* Wait for PLL1 to relock */ |
| ldr r8, =0x0 |
| pll_do_wait_lock |
| |
| ldr r6, =(1 << 16) |
| str r6, [r10, #0x08] |
| |
| ldr r10, [r0, #PM_INFO_CCM_V_OFFSET] |
| /* Set PLL1_sw_clk back to PLL1 */ |
| ldr r6, [r10, #0x0c] |
| bic r6, r6, #0x4 |
| str r6, [r10, #0x0c] |
| |
| /* Restore AHB/AXI back */ |
| str r12, [r10, #0x14] |
| |
| ccm_do_wait |
| |
| /* restore mmdc back to 24MHz*/ |
| ldr r6, [r10, #0x14] |
| bic r6, r6, #0x3f |
| str r6, [r10, #0x14] |
| |
| ccm_do_wait |
| b ccm_exit_done |
| |
| audio_ccm_restore: |
| /* move arm clk back to pll2_pfd2_400M */ |
| ldr r6, [r10, #0xc] |
| orr r6, r6, #0x4 |
| str r6, [r10, #0xc] |
| |
| /* restore mmdc podf */ |
| ldr r10, [r0, #PM_INFO_CCM_V_OFFSET] |
| ldr r6, [r10, #0x14] |
| bic r6, r6, #0x38 |
| orr r6, #0x8 |
| str r6, [r10, #0x14] |
| |
| ccm_do_wait |
| |
| ccm_exit_done: |
| |
| .endm |
| |
| .macro check_pll_state |
| |
| ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET] |
| /* |
| * Check whether any PLL is enabled, as only when |
| * there is no PLLs enabled, 2p5 can be off and |
| * only enable the weak one. PLL1 will be powered |
| * down late, so no need to check PLL1 state. |
| */ |
| |
| /* sys PLL2 */ |
| ldr r6, [r10, #0x30] |
| ands r6, r6, #(1 << 31) |
| bne 1f |
| |
| /* usb PLL3 */ |
| ldr r6, [r10, #0x10] |
| ands r6, r6, #(1 << 31) |
| bne 1f |
| |
| /* audio PLL4 */ |
| ldr r6, [r10, #0x70] |
| ands r6, r6, #(1 << 31) |
| bne 1f |
| |
| /* video PLL5 */ |
| ldr r6, [r10, #0xa0] |
| ands r6, r6, #(1 << 31) |
| bne 1f |
| |
| /* enet PLL6 */ |
| ldr r6, [r10, #0xe0] |
| ands r6, r6, #(1 << 31) |
| bne 1f |
| |
| /* usb host PLL7 */ |
| ldr r6, [r10, #0x20] |
| ands r6, r6, #(1 << 31) |
| bne 1f |
| |
| ldr r4, =0x1 |
| b check_done |
| 1: |
| ldr r4, =0x0 |
| |
| check_done: |
| .endm |
| |
| .macro anatop_enter_idle |
| |
| ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET] |
| cmp r4, #0x0 |
| beq anatop_enter_done |
| |
| /* Disable 1p1 brown out. */ |
| ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET] |
| ldr r6, [r10, #0x110] |
| bic r6, r6, #0x2 |
| str r6, [r10, #0x110] |
| /* |
| * Set the OSC bias current to -37.5% |
| * to drop the power on VDDHIGH. |
| */ |
| ldr r6, [r10, #0x150] |
| orr r6, r6, #0xc000 |
| str r6, [r10, #0x150] |
| |
| /* |
| * if the usb VBUS wakeup is enabled, skip |
| * disable main 2p5. |
| */ |
| cmp r2, #0x1 |
| beq anatop_enter_done |
| |
| /* Enable the week 2p5 */ |
| ldr r6, [r10, #0x130] |
| orr r6, r6, #0x40000 |
| str r6, [r10, #0x130] |
| |
| /* Disable main 2p5. */ |
| ldr r6, [r10, #0x130] |
| bic r6, r6, #0x1 |
| str r6, [r10, #0x130] |
| |
| /* |
| * Cannot diable regular bandgap |
| * in LDO-enable mode. The bandgap |
| * is required for ARM-LDO to regulate |
| * the voltage. |
| */ |
| ldr r6, [r10, #0x140] |
| and r6, r6, #0x1f |
| cmp r6, #0x1f |
| bne anatop_enter_done |
| |
| /* Enable low power bandgap */ |
| ldr r6, [r10, #0x260] |
| orr r6, r6, #0x20 |
| str r6, [r10, #0x260] |
| |
| /* |
| * Turn off the bias current |
| * from the regular bandgap. |
| */ |
| ldr r6, [r10, #0x260] |
| orr r6, r6, #0x80 |
| str r6, [r10, #0x260] |
| |
| /* |
| * Clear the REFTTOP+SELFBIASOFF, |
| * self_bais circuit of the band gap. |
| * Per RM, should be cleared when |
| * band gap is powered down. |
| */ |
| ldr r6, [r10, #0x150] |
| bic r6, r6, #0x8 |
| str r6, [r10, #0x150] |
| |
| /* Power down the regular bandgap */ |
| ldr r6, [r10, #0x150] |
| orr r6, r6, #0x1 |
| str r6, [r10, #0x150] |
| anatop_enter_done: |
| |
| .endm |
| |
| .macro anatop_exit_idle |
| |
| ldr r10, [r0, #PM_INFO_ANATOP_V_OFFSET] |
| cmp r4, #0x0 |
| beq skip_anatop_restore |
| |
| cmp r2, #0x1 |
| beq ldo2p5_not_disabled |
| /* |
| * Regular bandgap will not be disabled |
| * in LDO-enabled mode as it is required |
| * for ARM-LDO to reguulate the voltage. |
| */ |
| ldr r6, [r10, #0x140] |
| and r6, r6, #0x1f |
| cmp r6, #0x1f |
| bne skip_bandgap_restore |
| |
| /* Power up the regular bandgap */ |
| ldr r6, [r10, #0x150] |
| bic r6, r6, #0x1 |
| str r6, [r10, #0x150] |
| |
| /* wait for bandgap stable */ |
| 3: |
| ldr r6, [r10, #0x150] |
| and r6, r6, #0x80 |
| cmp r6, #0x80 |
| bne 3b |
| |
| /* now disable bandgap self-bias circuit */ |
| ldr r6, [r10, #0x150] |
| orr r6, r6, #0x8 |
| str r6, [r10, #0x150] |
| |
| /* Turn on the bias current |
| * from the regular bandgap. |
| */ |
| ldr r6, [r10, #0x260] |
| bic r6, r6, #0x80 |
| str r6, [r10, #0x260] |
| |
| /* Disable the low power bandgap */ |
| ldr r6, [r10, #0x260] |
| bic r6, r6, #0x20 |
| str r6, [r10, #0x260] |
| |
| skip_bandgap_restore: |
| /* Enable main 2p5. */ |
| ldr r6, [r10, #0x130] |
| orr r6, r6, #0x1 |
| str r6, [r10, #0x130] |
| |
| /* Ensure the 2p5 is up */ |
| 5: |
| ldr r6, [r10, #0x130] |
| and r6, r6, #0x20000 |
| cmp r6, #0x20000 |
| bne 5b |
| |
| /* Disable the weak 2p5 */ |
| ldr r6, [r10, #0x130] |
| bic r6, r6, #0x40000 |
| str r6, [r10, #0x130] |
| |
| ldo2p5_not_disabled: |
| /* |
| * Set the OSC bias current to max |
| * value for normal operation. |
| */ |
| ldr r6, [r10, #0x150] |
| bic r6, r6, #0xc000 |
| str r6, [r10, #0x150] |
| |
| /* Enable 1p1 brown out, */ |
| ldr r6, [r10, #0x110] |
| orr r6, r6, #0x2 |
| str r6, [r10, #0x110] |
| |
| skip_anatop_restore: |
| |
| .endm |
| |
| .macro disable_l1_dcache |
| |
| /* disable d-cache */ |
| mrc p15, 0, r7, c1, c0, 0 |
| bic r7, r7, #(1 << 2) |
| mcr p15, 0, r7, c1, c0, 0 |
| |
| dsb |
| isb |
| |
| .endm |
| |
| .macro mmdc_enter_dvfs_mode |
| |
| /* disable automatic power saving. */ |
| ldr r7, [r10, #MX6Q_MMDC_MAPSR] |
| orr r7, r7, #0x1 |
| str r7, [r10, #MX6Q_MMDC_MAPSR] |
| |
| /* disable power down timer */ |
| ldr r7, [r10, #0x04] |
| bic r7, r7, #0xff00 |
| str r7, [r10, #0x04] |
| |
| /* Make the DDR explicitly enter self-refresh. */ |
| ldr r7, [r10, #MX6Q_MMDC_MAPSR] |
| orr r7, r7, #(1 << 21) |
| str r7, [r10, #MX6Q_MMDC_MAPSR] |
| |
| poll_dvfs_set: |
| ldr r7, [r10, #MX6Q_MMDC_MAPSR] |
| ands r7, r7, #(1 << 25) |
| beq poll_dvfs_set |
| |
| /* set SBS step-by step mode */ |
| ldr r7, [r10, #0x410] |
| orr r7, r7, #0x100 |
| str r7, [r10, #0x410] |
| |
| .endm |
| |
| .macro resume_mmdc |
| /* restore MMDC IO */ |
| ldr r10, [r0, #PM_INFO_IOMUXC_V_OFFSET] |
| |
| ldr r6, [r0, #PM_INFO_IO_NUM_OFFSET] |
| ldr r7, =PM_INFO_IO_VAL_OFFSET |
| add r7, r7, r0 |
| 6: |
| ldr r8, [r7], #0x4 |
| ldr r9, [r7], #0x4 |
| str r9, [r10, r8] |
| subs r6, r6, #0x1 |
| bne 6b |
| |
| /* |
| * Need to reset the FIFO to avoid MMDC lockup |
| * caused because of floating/changing the |
| * configuration of many DDR IO pads. |
| */ |
| ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET] |
| /* reset read FIFO, RST_RD_FIFO */ |
| ldr r7, =MX6Q_MMDC_MPDGCTRL0 |
| ldr r6, [r10, r7] |
| orr r6, r6, #(1 << 31) |
| str r6, [r10, r7] |
| 7: |
| ldr r6, [r10, r7] |
| ands r6, r6, #(1 << 31) |
| bne 7b |
| |
| /* reset FIFO a second time */ |
| ldr r7, =MX6Q_MMDC_MPDGCTRL0 |
| ldr r6, [r10, r7] |
| orr r6, r6, #(1 << 31) |
| str r6, [r10, r7] |
| 8: |
| ldr r6, [r10, r7] |
| ands r6, r6, #(1 <<31) |
| bne 8b |
| |
| ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET] |
| /* Let DDR out of self-refresh */ |
| ldr r7, [r10, #MX6Q_MMDC_MAPSR] |
| bic r7, r7, #(1 << 21) |
| str r7, [r10, #MX6Q_MMDC_MAPSR] |
| 9: |
| ldr r7, [r10, #MX6Q_MMDC_MAPSR] |
| ands r7, r7, #(1 << 25) |
| bne 9b |
| |
| /* enable power down timer */ |
| ldr r7, [r10, #0x04] |
| orr r7, r7, #0x5500 |
| str r7, [r10, #0x04] |
| |
| /* enable DDR auto power saving */ |
| ldr r7, [r10, #MX6Q_MMDC_MAPSR] |
| bic r7, r7, #0x1 |
| str r7, [r10, #MX6Q_MMDC_MAPSR] |
| |
| /* Clear SBS - unblock DDR accesses */ |
| ldr r7, [r10, #0x410] |
| bic r7, r7, #0x100 |
| str r7, [r10, #0x410] |
| |
| .endm |
| |
| .macro tlb_set_to_ocram |
| |
| /* save ttbr */ |
| mrc p15, 0, r7, c2, c0, 1 |
| str r7, [r0, #PM_INFO_TTBR_OFFSET] |
| |
| /* |
| * 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 the IRAM page table. |
| * 3. Disable page table walks in TTBR0 (PD0 = 1) |
| * 4. Set TTBR0.N=1, implying 0-2G is transslated by TTBR0 |
| * and 2-4G is translated by TTBR1. |
| */ |
| |
| ldr r6, =iram_tlb_phys_addr |
| ldr r7, [r6] |
| |
| /* 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 |
| |
| dsb |
| isb |
| |
| /* store the IRAM table in TTBR1 */ |
| mcr p15, 0, r7, 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 |
| |
| .endm |
| |
| .macro tlb_back_to_ddr |
| |
| /* Restore the 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 |
| /* Flush the TLB */ |
| ldr r6, =0x0 |
| mcr p15, 0, r6, c8, c3, 0 |
| |
| dsb |
| isb |
| |
| /* 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 |
| /* Restore ttbr */ |
| ldr r7, [r0, #PM_INFO_TTBR_OFFSET] |
| mcr p15, 0, r7, c2, c0, 1 |
| |
| .endm |
| |
| .extern iram_tlb_phys_addr |
| |
| /* |
| * imx6sl_low_power_wfi code |
| * r0: wfi code base address |
| * r1: audio_bus_freq mode stat |
| * r2: vbus_ldo status |
| * r4: used for store the PLLs state |
| * r11: used for saving the ARM_PODF origin value |
| * r12: used for saving AHB_PODF origin value |
| */ |
| .align 3 |
| ENTRY(imx6sl_low_power_idle) |
| |
| mx6sl_lpm_wfi_start: |
| push {r4-r12} |
| |
| tlb_set_to_ocram |
| disable_l1_dcache |
| |
| #ifdef CONFIG_CACHE_L2X0 |
| /* sync L2 */ |
| ldr r10, [r0, #PM_INFO_L2_V_OFFSET] |
| /* Wait for background operations to complete. */ |
| wait_for_l2_idle: |
| ldr r6, [r10, #0x730] |
| cmp r6, #0x0 |
| bne wait_for_l2_idle |
| |
| mov r6, #0x0 |
| str r6, [r10, #0x730] |
| /* disable L2 */ |
| str r6, [r10, #0x100] |
| |
| dsb |
| isb |
| #endif |
| |
| /* make sure MMDC in self-refresh */ |
| ldr r10, [r0, #PM_INFO_MMDC_V_OFFSET] |
| mmdc_enter_dvfs_mode |
| /* save DDR IO settings and set to LPM mode*/ |
| ldr r10, [r0, #PM_INFO_IOMUXC_V_OFFSET] |
| ldr r6, =0x0 |
| ldr r7, [r0, #PM_INFO_IO_NUM_OFFSET] |
| ldr r8, =PM_INFO_IO_VAL_OFFSET |
| add r8, r8, r0 |
| |
| /* imx6sl's last 3 IOs need special setting */ |
| sub r7, r7, #0x3 |
| save_and_set_mmdc_io_lpm: |
| ldr r9, [r8], #0x4 |
| ldr r5, [r10, r9] |
| str r6, [r10, r9] |
| str r5, [r8], #0x4 |
| subs r7, r7, #0x1 |
| bne save_and_set_mmdc_io_lpm |
| ldr r6, =0x1000 |
| ldr r9, [r8], #0x4 |
| ldr r5, [r10, r9] |
| str r5, [r8], #0x4 |
| str r6, [r10, r9] |
| ldr r9, [r8], #0x4 |
| ldr r5, [r10, r9] |
| str r6, [r10, r9] |
| str r5, [r8], #0x4 |
| ldr r6, =0x80000 |
| ldr r9, [r8], #0x4 |
| ldr r5, [r10, r9] |
| str r6, [r10, r9] |
| str r5, [r8], #0x4 |
| |
| |
| /* check the PLLs lock state */ |
| check_pll_state |
| |
| ccm_enter_idle |
| /* if in audio low power mode, no |
| * need to do anatop setting. |
| */ |
| cmp r1, #0x1 |
| beq do_wfi |
| anatop_enter_idle |
| do_wfi: |
| wfi |
| /* |
| * Add these nops so that the |
| * prefetcher will not try to get |
| * any instrutions from DDR. |
| * The prefetch depth is about 23 |
| * on A9, so adding 25 nops. |
| */ |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| nop |
| nop |
| nop |
| nop |
| nop |
| |
| /* |
| * restore the ARM PODF first to speed |
| * up the restore procedure |
| */ |
| ldr r10, [r0, #PM_INFO_CCM_V_OFFSET] |
| /* Restore arm_clk_podf */ |
| str r11, [r10, #0x10] |
| ccm_do_wait |
| |
| /* |
| * if in audio low power mode, skip |
| * restore the anatop setting. |
| */ |
| cmp r1, #0x1 |
| beq skip_analog_restore |
| anatop_exit_idle |
| |
| skip_analog_restore: |
| ccm_exit_idle |
| resume_mmdc |
| |
| /* enable d-cache */ |
| mrc p15, 0, r7, c1, c0, 0 |
| orr r7, r7, #(1 << 2) |
| mcr p15, 0, r7, c1, c0, 0 |
| |
| #ifdef CONFIG_CACHE_L2X0 |
| ldr r10, [r0, #PM_INFO_L2_V_OFFSET] |
| mov r7, #0x1 |
| /* enable L2 */ |
| str r7, [r10, #0x100] |
| #endif |
| tlb_back_to_ddr |
| |
| /* Restore register */ |
| pop {r4 - r12} |
| mov pc, lr |
| |
| /* |
| * Add ltorg here to ensure that all |
| * literals are stored here and are |
| * within the text space. |
| */ |
| .ltorg |
| mx6sl_lpm_wfi_end: |