162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2013 Samsung Electronics Co., Ltd. 462306a36Sopenharmony_ci * http://www.samsung.com 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Exynos low-level resume code 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/linkage.h> 1062306a36Sopenharmony_ci#include <asm/asm-offsets.h> 1162306a36Sopenharmony_ci#include <asm/hardware/cache-l2x0.h> 1262306a36Sopenharmony_ci#include "smc.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define CPU_MASK 0xff0ffff0 1562306a36Sopenharmony_ci#define CPU_CORTEX_A9 0x410fc090 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci .text 1862306a36Sopenharmony_ci .align 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci /* 2162306a36Sopenharmony_ci * sleep magic, to allow the bootloader to check for an valid 2262306a36Sopenharmony_ci * image to resume to. Must be the first word before the 2362306a36Sopenharmony_ci * exynos_cpu_resume entry. 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci .word 0x2bedf00d 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci /* 2962306a36Sopenharmony_ci * exynos_cpu_resume 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * resume code entry for bootloader to call 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ciENTRY(exynos_cpu_resume) 3562306a36Sopenharmony_ci#ifdef CONFIG_CACHE_L2X0 3662306a36Sopenharmony_ci mrc p15, 0, r0, c0, c0, 0 3762306a36Sopenharmony_ci ldr r1, =CPU_MASK 3862306a36Sopenharmony_ci and r0, r0, r1 3962306a36Sopenharmony_ci ldr r1, =CPU_CORTEX_A9 4062306a36Sopenharmony_ci cmp r0, r1 4162306a36Sopenharmony_ci bleq l2c310_early_resume 4262306a36Sopenharmony_ci#endif 4362306a36Sopenharmony_ci b cpu_resume 4462306a36Sopenharmony_ciENDPROC(exynos_cpu_resume) 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci .align 4762306a36Sopenharmony_ci .arch armv7-a 4862306a36Sopenharmony_ci .arch_extension sec 4962306a36Sopenharmony_ciENTRY(exynos_cpu_resume_ns) 5062306a36Sopenharmony_ci mrc p15, 0, r0, c0, c0, 0 5162306a36Sopenharmony_ci ldr r1, =CPU_MASK 5262306a36Sopenharmony_ci and r0, r0, r1 5362306a36Sopenharmony_ci ldr r1, =CPU_CORTEX_A9 5462306a36Sopenharmony_ci cmp r0, r1 5562306a36Sopenharmony_ci bne skip_cp15 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci adr r0, _cp15_save_power 5862306a36Sopenharmony_ci ldr r1, [r0] 5962306a36Sopenharmony_ci ldr r1, [r0, r1] 6062306a36Sopenharmony_ci adr r0, _cp15_save_diag 6162306a36Sopenharmony_ci ldr r2, [r0] 6262306a36Sopenharmony_ci ldr r2, [r0, r2] 6362306a36Sopenharmony_ci mov r0, #SMC_CMD_C15RESUME 6462306a36Sopenharmony_ci dsb 6562306a36Sopenharmony_ci smc #0 6662306a36Sopenharmony_ci#ifdef CONFIG_CACHE_L2X0 6762306a36Sopenharmony_ci adr r0, 1f 6862306a36Sopenharmony_ci ldr r2, [r0] 6962306a36Sopenharmony_ci add r0, r2, r0 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci /* Check that the address has been initialised. */ 7262306a36Sopenharmony_ci ldr r1, [r0, #L2X0_R_PHY_BASE] 7362306a36Sopenharmony_ci teq r1, #0 7462306a36Sopenharmony_ci beq skip_l2x0 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci /* Check if controller has been enabled. */ 7762306a36Sopenharmony_ci ldr r2, [r1, #L2X0_CTRL] 7862306a36Sopenharmony_ci tst r2, #0x1 7962306a36Sopenharmony_ci bne skip_l2x0 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci ldr r1, [r0, #L2X0_R_TAG_LATENCY] 8262306a36Sopenharmony_ci ldr r2, [r0, #L2X0_R_DATA_LATENCY] 8362306a36Sopenharmony_ci ldr r3, [r0, #L2X0_R_PREFETCH_CTRL] 8462306a36Sopenharmony_ci mov r0, #SMC_CMD_L2X0SETUP1 8562306a36Sopenharmony_ci smc #0 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci /* Reload saved regs pointer because smc corrupts registers. */ 8862306a36Sopenharmony_ci adr r0, 1f 8962306a36Sopenharmony_ci ldr r2, [r0] 9062306a36Sopenharmony_ci add r0, r2, r0 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci ldr r1, [r0, #L2X0_R_PWR_CTRL] 9362306a36Sopenharmony_ci ldr r2, [r0, #L2X0_R_AUX_CTRL] 9462306a36Sopenharmony_ci mov r0, #SMC_CMD_L2X0SETUP2 9562306a36Sopenharmony_ci smc #0 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci mov r0, #SMC_CMD_L2X0INVALL 9862306a36Sopenharmony_ci smc #0 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci mov r1, #1 10162306a36Sopenharmony_ci mov r0, #SMC_CMD_L2X0CTRL 10262306a36Sopenharmony_ci smc #0 10362306a36Sopenharmony_ciskip_l2x0: 10462306a36Sopenharmony_ci#endif /* CONFIG_CACHE_L2X0 */ 10562306a36Sopenharmony_ciskip_cp15: 10662306a36Sopenharmony_ci b cpu_resume 10762306a36Sopenharmony_ciENDPROC(exynos_cpu_resume_ns) 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci .align 11062306a36Sopenharmony_ci_cp15_save_power: 11162306a36Sopenharmony_ci .long cp15_save_power - . 11262306a36Sopenharmony_ci_cp15_save_diag: 11362306a36Sopenharmony_ci .long cp15_save_diag - . 11462306a36Sopenharmony_ci#ifdef CONFIG_CACHE_L2X0 11562306a36Sopenharmony_ci1: .long l2x0_saved_regs - . 11662306a36Sopenharmony_ci#endif /* CONFIG_CACHE_L2X0 */ 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci .data 11962306a36Sopenharmony_ci .align 2 12062306a36Sopenharmony_ci .globl cp15_save_diag 12162306a36Sopenharmony_cicp15_save_diag: 12262306a36Sopenharmony_ci .long 0 @ cp15 diagnostic 12362306a36Sopenharmony_ci .globl cp15_save_power 12462306a36Sopenharmony_cicp15_save_power: 12562306a36Sopenharmony_ci .long 0 @ cp15 power control 126