1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun * 3*4882a593Smuzhiyun * Copyright (c) 2018 Chen-Yu Tsai 4*4882a593Smuzhiyun * Copyright (c) 2018 Bootlin 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Chen-Yu Tsai <wens@csie.org> 7*4882a593Smuzhiyun * Mylène Josserand <mylene.josserand@bootlin.com> 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * SMP support for sunxi based systems with Cortex A7/A15 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun */ 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun#include <linux/linkage.h> 14*4882a593Smuzhiyun#include <asm/assembler.h> 15*4882a593Smuzhiyun#include <asm/cputype.h> 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunENTRY(sunxi_mc_smp_cluster_cache_enable) 18*4882a593Smuzhiyun .arch armv7-a 19*4882a593Smuzhiyun /* 20*4882a593Smuzhiyun * Enable cluster-level coherency, in preparation for turning on the MMU. 21*4882a593Smuzhiyun * 22*4882a593Smuzhiyun * Also enable regional clock gating and L2 data latency settings for 23*4882a593Smuzhiyun * Cortex-A15. These settings are from the vendor kernel. 24*4882a593Smuzhiyun */ 25*4882a593Smuzhiyun mrc p15, 0, r1, c0, c0, 0 26*4882a593Smuzhiyun movw r2, #(ARM_CPU_PART_MASK & 0xffff) 27*4882a593Smuzhiyun movt r2, #(ARM_CPU_PART_MASK >> 16) 28*4882a593Smuzhiyun and r1, r1, r2 29*4882a593Smuzhiyun movw r2, #(ARM_CPU_PART_CORTEX_A15 & 0xffff) 30*4882a593Smuzhiyun movt r2, #(ARM_CPU_PART_CORTEX_A15 >> 16) 31*4882a593Smuzhiyun cmp r1, r2 32*4882a593Smuzhiyun bne not_a15 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun /* The following is Cortex-A15 specific */ 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun /* ACTLR2: Enable CPU regional clock gates */ 37*4882a593Smuzhiyun mrc p15, 1, r1, c15, c0, 4 38*4882a593Smuzhiyun orr r1, r1, #(0x1 << 31) 39*4882a593Smuzhiyun mcr p15, 1, r1, c15, c0, 4 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* L2ACTLR */ 42*4882a593Smuzhiyun mrc p15, 1, r1, c15, c0, 0 43*4882a593Smuzhiyun /* Enable L2, GIC, and Timer regional clock gates */ 44*4882a593Smuzhiyun orr r1, r1, #(0x1 << 26) 45*4882a593Smuzhiyun /* Disable clean/evict from being pushed to external */ 46*4882a593Smuzhiyun orr r1, r1, #(0x1<<3) 47*4882a593Smuzhiyun mcr p15, 1, r1, c15, c0, 0 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /* L2CTRL: L2 data RAM latency */ 50*4882a593Smuzhiyun mrc p15, 1, r1, c9, c0, 2 51*4882a593Smuzhiyun bic r1, r1, #(0x7 << 0) 52*4882a593Smuzhiyun orr r1, r1, #(0x3 << 0) 53*4882a593Smuzhiyun mcr p15, 1, r1, c9, c0, 2 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /* End of Cortex-A15 specific setup */ 56*4882a593Smuzhiyun not_a15: 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* Get value of sunxi_mc_smp_first_comer */ 59*4882a593Smuzhiyun adr r1, first 60*4882a593Smuzhiyun ldr r0, [r1] 61*4882a593Smuzhiyun ldr r0, [r1, r0] 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun /* Skip cci_enable_port_for_self if not first comer */ 64*4882a593Smuzhiyun cmp r0, #0 65*4882a593Smuzhiyun bxeq lr 66*4882a593Smuzhiyun b cci_enable_port_for_self 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun .align 2 69*4882a593Smuzhiyun first: .word sunxi_mc_smp_first_comer - . 70*4882a593SmuzhiyunENDPROC(sunxi_mc_smp_cluster_cache_enable) 71*4882a593Smuzhiyun 72*4882a593SmuzhiyunENTRY(sunxi_mc_smp_secondary_startup) 73*4882a593Smuzhiyun bl sunxi_mc_smp_cluster_cache_enable 74*4882a593Smuzhiyun bl secure_cntvoff_init 75*4882a593Smuzhiyun b secondary_startup 76*4882a593SmuzhiyunENDPROC(sunxi_mc_smp_secondary_startup) 77*4882a593Smuzhiyun 78*4882a593SmuzhiyunENTRY(sunxi_mc_smp_resume) 79*4882a593Smuzhiyun bl sunxi_mc_smp_cluster_cache_enable 80*4882a593Smuzhiyun b cpu_resume 81*4882a593SmuzhiyunENDPROC(sunxi_mc_smp_resume) 82