1/* 2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 3 * http://www.samsung.com 4 * 5 * Exynos low-level resume code 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18#include <linux/linkage.h> 19#include <asm/asm-offsets.h> 20#include <asm/hardware/cache-l2x0.h> 21#include "smc.h" 22 23#define CPU_MASK 0xff0ffff0 24#define CPU_CORTEX_A9 0x410fc090 25 26 /* 27 * The following code is located into the .data section. This is to 28 * allow l2x0_regs_phys to be accessed with a relative load while we 29 * can't rely on any MMU translation. We could have put l2x0_regs_phys 30 * in the .text section as well, but some setups might insist on it to 31 * be truly read-only. (Reference from: arch/arm/kernel/sleep.S) 32 */ 33 .data 34 .align 35 36 /* 37 * sleep magic, to allow the bootloader to check for an valid 38 * image to resume to. Must be the first word before the 39 * exynos_cpu_resume entry. 40 */ 41 42 .word 0x2bedf00d 43 44 /* 45 * exynos_cpu_resume 46 * 47 * resume code entry for bootloader to call 48 */ 49 50ENTRY(exynos_cpu_resume) 51#ifdef CONFIG_CACHE_L2X0 52 mrc p15, 0, r0, c0, c0, 0 53 ldr r1, =CPU_MASK 54 and r0, r0, r1 55 ldr r1, =CPU_CORTEX_A9 56 cmp r0, r1 57 bleq l2c310_early_resume 58#endif 59 b cpu_resume 60ENDPROC(exynos_cpu_resume) 61 62 .align 63 64ENTRY(exynos_cpu_resume_ns) 65 mrc p15, 0, r0, c0, c0, 0 66 ldr r1, =CPU_MASK 67 and r0, r0, r1 68 ldr r1, =CPU_CORTEX_A9 69 cmp r0, r1 70 bne skip_cp15 71 72 adr r0, cp15_save_power 73 ldr r1, [r0] 74 adr r0, cp15_save_diag 75 ldr r2, [r0] 76 mov r0, #SMC_CMD_C15RESUME 77 dsb 78 smc #0 79#ifdef CONFIG_CACHE_L2X0 80 adr r0, 1f 81 ldr r2, [r0] 82 add r0, r2, r0 83 84 /* Check that the address has been initialised. */ 85 ldr r1, [r0, #L2X0_R_PHY_BASE] 86 teq r1, #0 87 beq skip_l2x0 88 89 /* Check if controller has been enabled. */ 90 ldr r2, [r1, #L2X0_CTRL] 91 tst r2, #0x1 92 bne skip_l2x0 93 94 ldr r1, [r0, #L2X0_R_TAG_LATENCY] 95 ldr r2, [r0, #L2X0_R_DATA_LATENCY] 96 ldr r3, [r0, #L2X0_R_PREFETCH_CTRL] 97 mov r0, #SMC_CMD_L2X0SETUP1 98 smc #0 99 100 /* Reload saved regs pointer because smc corrupts registers. */ 101 adr r0, 1f 102 ldr r2, [r0] 103 add r0, r2, r0 104 105 ldr r1, [r0, #L2X0_R_PWR_CTRL] 106 ldr r2, [r0, #L2X0_R_AUX_CTRL] 107 mov r0, #SMC_CMD_L2X0SETUP2 108 smc #0 109 110 mov r0, #SMC_CMD_L2X0INVALL 111 smc #0 112 113 mov r1, #1 114 mov r0, #SMC_CMD_L2X0CTRL 115 smc #0 116skip_l2x0: 117#endif /* CONFIG_CACHE_L2X0 */ 118skip_cp15: 119 b cpu_resume 120ENDPROC(exynos_cpu_resume_ns) 121 .globl cp15_save_diag 122cp15_save_diag: 123 .long 0 @ cp15 diagnostic 124 .globl cp15_save_power 125cp15_save_power: 126 .long 0 @ cp15 power control 127 128#ifdef CONFIG_CACHE_L2X0 129 .align 1301: .long l2x0_saved_regs - . 131#endif /* CONFIG_CACHE_L2X0 */ 132