^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * arch/arm/mach-tegra/sleep.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2010-2011, NVIDIA Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2011, Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author: Colin Cross <ccross@android.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Gary King <gking@nvidia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/assembler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/cp15.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/hardware/cache-l2x0.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "iomap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "sleep.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define CLK_RESET_CCLK_BURST 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define CLK_RESET_CCLK_DIVIDER 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * tegra_disable_clean_inv_dcache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * disable, clean & invalidate the D-cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Corrupted registers: r1-r3, r6, r8, r9-r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ENTRY(tegra_disable_clean_inv_dcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) stmfd sp!, {r0, r4-r5, r7, r9-r11, lr}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) dmb @ ensure ordering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Disable the D-cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) mrc p15, 0, r2, c1, c0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) tst r2, #CR_C @ see tegra_sleep_cpu()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bic r2, r2, #CR_C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) mcrne p15, 0, r2, c1, c0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) isb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Flush the D-cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) cmp r0, #TEGRA_FLUSH_CACHE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) blne v7_flush_dcache_louis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) bleq v7_flush_dcache_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Trun off coherency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) exit_smp r4, r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ENDPROC(tegra_disable_clean_inv_dcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * tegra_init_l2_for_a15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * set up the correct L2 cache data RAM latency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ENTRY(tegra_init_l2_for_a15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mrc p15, 0, r0, c0, c0, 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ubfx r0, r0, #8, #4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) tst r0, #1 @ only need for cluster 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) bne _exit_init_l2_a15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mrc p15, 0x1, r0, c9, c0, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) and r0, r0, #7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) cmp r0, #2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bicne r0, r0, #7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) orrne r0, r0, #2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) mcrne p15, 0x1, r0, c9, c0, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) _exit_init_l2_a15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ENDPROC(tegra_init_l2_for_a15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * tegra_sleep_cpu_finish(unsigned long v2p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * enters suspend in LP2 by turning off the mmu and jumping to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * tegra?_tear_down_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ENTRY(tegra_sleep_cpu_finish)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mov r4, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Flush and disable the L1 data cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mov r0, #TEGRA_FLUSH_CACHE_ALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) bl tegra_disable_clean_inv_dcache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mov r0, r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) mov32 r6, tegra_tear_down_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ldr r1, [r6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) add r1, r1, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) mov32 r3, tegra_shut_off_mmu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) add r3, r3, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mov r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ret r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ENDPROC(tegra_sleep_cpu_finish)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * tegra_shut_off_mmu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * r0 = physical address to jump to with mmu off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * called with VA=PA mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * turns off MMU, icache, dcache and branch prediction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .align L1_CACHE_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .pushsection .idmap.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ENTRY(tegra_shut_off_mmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mrc p15, 0, r3, c1, c0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) movw r2, #CR_I | CR_Z | CR_C | CR_M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) bic r3, r3, r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mcr p15, 0, r3, c1, c0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) isb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #ifdef CONFIG_CACHE_L2X0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* Disable L2 cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) check_cpu_part_num 0xc09, r9, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) retne r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mov32 r2, TEGRA_ARM_PERIF_BASE + 0x3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ldr r3, [r2, #L2X0_CTRL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) tst r3, #L2X0_CTRL_EN @ see tegra_sleep_cpu()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mov r3, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) strne r3, [r2, #L2X0_CTRL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ret r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ENDPROC(tegra_shut_off_mmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * tegra_switch_cpu_to_pllp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ENTRY(tegra_switch_cpu_to_pllp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mov32 r5, TEGRA_CLK_RESET_BASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mov r0, #(2 << 28) @ burst policy = run mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) orr r0, r0, #(4 << 4) @ use PLLP in run mode burst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) str r0, [r5, #CLK_RESET_CCLK_BURST]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ENDPROC(tegra_switch_cpu_to_pllp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif