18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci *
38c2ecf20Sopenharmony_ci * Copyright (c) 2018 Chen-Yu Tsai
48c2ecf20Sopenharmony_ci * Copyright (c) 2018 Bootlin
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Chen-Yu Tsai <wens@csie.org>
78c2ecf20Sopenharmony_ci * Mylène Josserand <mylene.josserand@bootlin.com>
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * SMP support for sunxi based systems with Cortex A7/A15
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/linkage.h>
148c2ecf20Sopenharmony_ci#include <asm/assembler.h>
158c2ecf20Sopenharmony_ci#include <asm/cputype.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciENTRY(sunxi_mc_smp_cluster_cache_enable)
188c2ecf20Sopenharmony_ci	.arch	armv7-a
198c2ecf20Sopenharmony_ci	/*
208c2ecf20Sopenharmony_ci	 * Enable cluster-level coherency, in preparation for turning on the MMU.
218c2ecf20Sopenharmony_ci	 *
228c2ecf20Sopenharmony_ci	 * Also enable regional clock gating and L2 data latency settings for
238c2ecf20Sopenharmony_ci	 * Cortex-A15. These settings are from the vendor kernel.
248c2ecf20Sopenharmony_ci	 */
258c2ecf20Sopenharmony_ci	mrc	p15, 0, r1, c0, c0, 0
268c2ecf20Sopenharmony_ci	movw	r2, #(ARM_CPU_PART_MASK & 0xffff)
278c2ecf20Sopenharmony_ci	movt	r2, #(ARM_CPU_PART_MASK >> 16)
288c2ecf20Sopenharmony_ci	and	r1, r1, r2
298c2ecf20Sopenharmony_ci	movw	r2, #(ARM_CPU_PART_CORTEX_A15 & 0xffff)
308c2ecf20Sopenharmony_ci	movt	r2, #(ARM_CPU_PART_CORTEX_A15 >> 16)
318c2ecf20Sopenharmony_ci	cmp	r1, r2
328c2ecf20Sopenharmony_ci	bne	not_a15
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	/* The following is Cortex-A15 specific */
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	/* ACTLR2: Enable CPU regional clock gates */
378c2ecf20Sopenharmony_ci	mrc p15, 1, r1, c15, c0, 4
388c2ecf20Sopenharmony_ci	orr r1, r1, #(0x1 << 31)
398c2ecf20Sopenharmony_ci	mcr p15, 1, r1, c15, c0, 4
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	/* L2ACTLR */
428c2ecf20Sopenharmony_ci	mrc p15, 1, r1, c15, c0, 0
438c2ecf20Sopenharmony_ci	/* Enable L2, GIC, and Timer regional clock gates */
448c2ecf20Sopenharmony_ci	orr r1, r1, #(0x1 << 26)
458c2ecf20Sopenharmony_ci	/* Disable clean/evict from being pushed to external */
468c2ecf20Sopenharmony_ci	orr r1, r1, #(0x1<<3)
478c2ecf20Sopenharmony_ci	mcr p15, 1, r1, c15, c0, 0
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	/* L2CTRL: L2 data RAM latency */
508c2ecf20Sopenharmony_ci	mrc p15, 1, r1, c9, c0, 2
518c2ecf20Sopenharmony_ci	bic r1, r1, #(0x7 << 0)
528c2ecf20Sopenharmony_ci	orr r1, r1, #(0x3 << 0)
538c2ecf20Sopenharmony_ci	mcr p15, 1, r1, c9, c0, 2
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	/* End of Cortex-A15 specific setup */
568c2ecf20Sopenharmony_ci	not_a15:
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	/* Get value of sunxi_mc_smp_first_comer */
598c2ecf20Sopenharmony_ci	adr	r1, first
608c2ecf20Sopenharmony_ci	ldr	r0, [r1]
618c2ecf20Sopenharmony_ci	ldr	r0, [r1, r0]
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	/* Skip cci_enable_port_for_self if not first comer */
648c2ecf20Sopenharmony_ci	cmp	r0, #0
658c2ecf20Sopenharmony_ci	bxeq	lr
668c2ecf20Sopenharmony_ci	b	cci_enable_port_for_self
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	.align 2
698c2ecf20Sopenharmony_ci	first: .word sunxi_mc_smp_first_comer - .
708c2ecf20Sopenharmony_ciENDPROC(sunxi_mc_smp_cluster_cache_enable)
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ciENTRY(sunxi_mc_smp_secondary_startup)
738c2ecf20Sopenharmony_ci	bl	sunxi_mc_smp_cluster_cache_enable
748c2ecf20Sopenharmony_ci	bl	secure_cntvoff_init
758c2ecf20Sopenharmony_ci	b	secondary_startup
768c2ecf20Sopenharmony_ciENDPROC(sunxi_mc_smp_secondary_startup)
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ciENTRY(sunxi_mc_smp_resume)
798c2ecf20Sopenharmony_ci	bl	sunxi_mc_smp_cluster_cache_enable
808c2ecf20Sopenharmony_ci	b	cpu_resume
818c2ecf20Sopenharmony_ciENDPROC(sunxi_mc_smp_resume)
82