162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Copyright (c) 2018 Chen-Yu Tsai 462306a36Sopenharmony_ci * Copyright (c) 2018 Bootlin 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Chen-Yu Tsai <wens@csie.org> 762306a36Sopenharmony_ci * Mylène Josserand <mylene.josserand@bootlin.com> 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * SMP support for sunxi based systems with Cortex A7/A15 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/linkage.h> 1462306a36Sopenharmony_ci#include <asm/assembler.h> 1562306a36Sopenharmony_ci#include <asm/cputype.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ciENTRY(sunxi_mc_smp_cluster_cache_enable) 1862306a36Sopenharmony_ci .arch armv7-a 1962306a36Sopenharmony_ci /* 2062306a36Sopenharmony_ci * Enable cluster-level coherency, in preparation for turning on the MMU. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Also enable regional clock gating and L2 data latency settings for 2362306a36Sopenharmony_ci * Cortex-A15. These settings are from the vendor kernel. 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci mrc p15, 0, r1, c0, c0, 0 2662306a36Sopenharmony_ci movw r2, #(ARM_CPU_PART_MASK & 0xffff) 2762306a36Sopenharmony_ci movt r2, #(ARM_CPU_PART_MASK >> 16) 2862306a36Sopenharmony_ci and r1, r1, r2 2962306a36Sopenharmony_ci movw r2, #(ARM_CPU_PART_CORTEX_A15 & 0xffff) 3062306a36Sopenharmony_ci movt r2, #(ARM_CPU_PART_CORTEX_A15 >> 16) 3162306a36Sopenharmony_ci cmp r1, r2 3262306a36Sopenharmony_ci bne not_a15 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci /* The following is Cortex-A15 specific */ 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci /* ACTLR2: Enable CPU regional clock gates */ 3762306a36Sopenharmony_ci mrc p15, 1, r1, c15, c0, 4 3862306a36Sopenharmony_ci orr r1, r1, #(0x1 << 31) 3962306a36Sopenharmony_ci mcr p15, 1, r1, c15, c0, 4 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci /* L2ACTLR */ 4262306a36Sopenharmony_ci mrc p15, 1, r1, c15, c0, 0 4362306a36Sopenharmony_ci /* Enable L2, GIC, and Timer regional clock gates */ 4462306a36Sopenharmony_ci orr r1, r1, #(0x1 << 26) 4562306a36Sopenharmony_ci /* Disable clean/evict from being pushed to external */ 4662306a36Sopenharmony_ci orr r1, r1, #(0x1<<3) 4762306a36Sopenharmony_ci mcr p15, 1, r1, c15, c0, 0 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci /* L2CTRL: L2 data RAM latency */ 5062306a36Sopenharmony_ci mrc p15, 1, r1, c9, c0, 2 5162306a36Sopenharmony_ci bic r1, r1, #(0x7 << 0) 5262306a36Sopenharmony_ci orr r1, r1, #(0x3 << 0) 5362306a36Sopenharmony_ci mcr p15, 1, r1, c9, c0, 2 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci /* End of Cortex-A15 specific setup */ 5662306a36Sopenharmony_ci not_a15: 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci /* Get value of sunxi_mc_smp_first_comer */ 5962306a36Sopenharmony_ci adr r1, first 6062306a36Sopenharmony_ci ldr r0, [r1] 6162306a36Sopenharmony_ci ldr r0, [r1, r0] 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci /* Skip cci_enable_port_for_self if not first comer */ 6462306a36Sopenharmony_ci cmp r0, #0 6562306a36Sopenharmony_ci bxeq lr 6662306a36Sopenharmony_ci b cci_enable_port_for_self 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci .align 2 6962306a36Sopenharmony_ci first: .word sunxi_mc_smp_first_comer - . 7062306a36Sopenharmony_ciENDPROC(sunxi_mc_smp_cluster_cache_enable) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciENTRY(sunxi_mc_smp_secondary_startup) 7362306a36Sopenharmony_ci bl sunxi_mc_smp_cluster_cache_enable 7462306a36Sopenharmony_ci bl secure_cntvoff_init 7562306a36Sopenharmony_ci b secondary_startup 7662306a36Sopenharmony_ciENDPROC(sunxi_mc_smp_secondary_startup) 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciENTRY(sunxi_mc_smp_resume) 7962306a36Sopenharmony_ci bl sunxi_mc_smp_cluster_cache_enable 8062306a36Sopenharmony_ci b cpu_resume 8162306a36Sopenharmony_ciENDPROC(sunxi_mc_smp_resume) 82