Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * arch/arm/mach-tegra/sleep.S
0004  *
0005  * Copyright (c) 2010-2011, NVIDIA Corporation.
0006  * Copyright (c) 2011, Google, Inc.
0007  *
0008  * Author: Colin Cross <ccross@android.com>
0009  *         Gary King <gking@nvidia.com>
0010  */
0011 
0012 #include <linux/linkage.h>
0013 
0014 #include <asm/assembler.h>
0015 #include <asm/cache.h>
0016 #include <asm/cp15.h>
0017 #include <asm/hardware/cache-l2x0.h>
0018 
0019 #include "iomap.h"
0020 #include "sleep.h"
0021 
0022 #define CLK_RESET_CCLK_BURST    0x20
0023 #define CLK_RESET_CCLK_DIVIDER  0x24
0024 
0025 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
0026 /*
0027  * tegra_disable_clean_inv_dcache
0028  *
0029  * disable, clean & invalidate the D-cache
0030  *
0031  * Corrupted registers: r1-r3, r6, r8, r9-r11
0032  */
0033 ENTRY(tegra_disable_clean_inv_dcache)
0034     stmfd   sp!, {r0, r4-r5, r7, r9-r11, lr}
0035     dmb                 @ ensure ordering
0036 
0037     /* Disable the D-cache */
0038     mrc p15, 0, r2, c1, c0, 0
0039     tst r2, #CR_C           @ see tegra_sleep_cpu()
0040     bic r2, r2, #CR_C
0041     mcrne   p15, 0, r2, c1, c0, 0
0042     isb
0043 
0044     /* Flush the D-cache */
0045     cmp r0, #TEGRA_FLUSH_CACHE_ALL
0046     blne    v7_flush_dcache_louis
0047     bleq    v7_flush_dcache_all
0048 
0049     /* Trun off coherency */
0050     exit_smp r4, r5
0051 
0052     ldmfd   sp!, {r0, r4-r5, r7, r9-r11, pc}
0053 ENDPROC(tegra_disable_clean_inv_dcache)
0054 #endif
0055 
0056 #ifdef CONFIG_PM_SLEEP
0057 /*
0058  * tegra_init_l2_for_a15
0059  *
0060  * set up the correct L2 cache data RAM latency
0061  */
0062 ENTRY(tegra_init_l2_for_a15)
0063     mrc p15, 0, r0, c0, c0, 5
0064     ubfx    r0, r0, #8, #4
0065     tst r0, #1              @ only need for cluster 0
0066     bne _exit_init_l2_a15
0067 
0068     mrc p15, 0x1, r0, c9, c0, 2
0069     and r0, r0, #7
0070     cmp r0, #2
0071     bicne   r0, r0, #7
0072     orrne   r0, r0, #2
0073     mcrne   p15, 0x1, r0, c9, c0, 2
0074 _exit_init_l2_a15:
0075 
0076     ret lr
0077 ENDPROC(tegra_init_l2_for_a15)
0078 
0079 /*
0080  * tegra_sleep_cpu_finish(unsigned long v2p)
0081  *
0082  * enters suspend in LP2 by turning off the mmu and jumping to
0083  * tegra?_tear_down_cpu
0084  */
0085 ENTRY(tegra_sleep_cpu_finish)
0086     mov r4, r0
0087     /* Flush and disable the L1 data cache */
0088     mov r0, #TEGRA_FLUSH_CACHE_ALL
0089     bl  tegra_disable_clean_inv_dcache
0090 
0091     mov r0, r4
0092     mov32   r6, tegra_tear_down_cpu
0093     ldr r1, [r6]
0094     add r1, r1, r0
0095 
0096     mov32   r3, tegra_shut_off_mmu
0097     add r3, r3, r0
0098     mov r0, r1
0099 
0100     ret r3
0101 ENDPROC(tegra_sleep_cpu_finish)
0102 
0103 /*
0104  * tegra_shut_off_mmu
0105  *
0106  * r0 = physical address to jump to with mmu off
0107  *
0108  * called with VA=PA mapping
0109  * turns off MMU, icache, dcache and branch prediction
0110  */
0111     .align  L1_CACHE_SHIFT
0112     .pushsection    .idmap.text, "ax"
0113 ENTRY(tegra_shut_off_mmu)
0114     mrc p15, 0, r3, c1, c0, 0
0115     movw    r2, #CR_I | CR_Z | CR_C | CR_M
0116     bic r3, r3, r2
0117     dsb
0118     mcr p15, 0, r3, c1, c0, 0
0119     isb
0120 #ifdef CONFIG_CACHE_L2X0
0121     /* Disable L2 cache */
0122     check_cpu_part_num 0xc09, r9, r10
0123     retne   r0
0124 
0125     mov32   r2, TEGRA_ARM_PERIF_BASE + 0x3000
0126     ldr r3, [r2, #L2X0_CTRL]
0127     tst r3, #L2X0_CTRL_EN       @ see tegra_sleep_cpu()
0128     mov r3, #0
0129     strne   r3, [r2, #L2X0_CTRL]
0130 #endif
0131     ret r0
0132 ENDPROC(tegra_shut_off_mmu)
0133     .popsection
0134 
0135 /*
0136  * tegra_switch_cpu_to_pllp
0137  *
0138  * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp
0139  */
0140 ENTRY(tegra_switch_cpu_to_pllp)
0141     /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
0142     mov32   r5, TEGRA_CLK_RESET_BASE
0143     mov r0, #(2 << 28)          @ burst policy = run mode
0144     orr r0, r0, #(4 << 4)       @ use PLLP in run mode burst
0145     str r0, [r5, #CLK_RESET_CCLK_BURST]
0146     mov r0, #0
0147     str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
0148     ret lr
0149 ENDPROC(tegra_switch_cpu_to_pllp)
0150 #endif