xref: /optee_os/core/arch/arm/plat-rcar/core_pos_a64.S (revision cb95166abdfa0cccd070a7dda9b6cdafcfd9d04c)
1/* SPDX-License-Identifier: BSD-2-Clause */
2/*
3 * Copyright (c) 2015, Linaro Limited
4 * Copyright (c) 2019, Arm Limited. All rights reserved.
5 * Copyright (c) 2020, Marek Vasut
6 */
7
8#include <asm.S>
9#include <arm.h>
10#include <arm64_macros.S>
11#include <platform_config.h>
12#include "rcar.h"
13
14FUNC get_core_pos_mpidr , :
15	/*
16	 * Shift MPIDR value if it's not already shifted.
17	 * Using logical shift ensures AFF0 to be filled with zeroes.
18	 * This part is necessary even if CFG_CORE_THREAD_SHIFT is 0 because
19	 * MT bit can be set on single threaded systems where all the AFF0
20	 * values are zeroes.
21	 */
22	tst	x0, #MPIDR_MT_MASK
23	lsl	x3, x0, #MPIDR_AFFINITY_BITS
24	csel	x3, x3, x0, eq
25
26	/*
27	 * At this point the MPIDR layout is always shifted so it looks
28	 * as follows AFF2 -> cluster, AFF1 -> core, AFF0 -> thread
29	 */
30	/* Calculate CorePos = (ClusterId * (cores/cluster)) + CoreId */
31	ubfx	x0, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
32	ubfx	x1, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
33
34	/*
35	 * R-Car M3W/M3W+ have 6 cores, but internally cluster 0 has two
36	 * cores (0, 1) and cluster 1 has four cores (4, 5, 6, 7). Other
37	 * R-Car SoCs either have two full clusters (4xCA57 + 4xCA53) or
38	 * they have one cluster.
39	 *
40	 * The code below normalizes the M3W/M3W+ core enumeration such
41	 * that cluster 0 returns core IDs {0, 1} and cluster 1 returns
42	 * core IDs {2, 3, 4, 5}. This is achieved by calculating the
43	 * core ID as CorePos = CoreId + (ClusterId << (IsM3W ? 1 : 0))
44	 */
45
46	adr_l	x2, rcar_prr_value
47	ldr	w3, [x2]
48	cmp	w3, wzr
49	bne	1f
50
51	/* Load PRR PRODUCT into x3 */
52	mov	x2, #PRR_BASE
53	ldr	w3, [x2, #PRR_OFFSET]
54	/*
55	 * Cache the PRR register value. PRR value does not change at runtime.
56	 * This function is first called with MMU disabled, so it is possible
57	 * to read the PRR register via its physical address, but once MMU is
58	 * enabled, this is no longer possible as the virtual address is not
59	 * available here, so in that case, use the cached value of the PRR.
60	 */
61	adr_l	x2, rcar_prr_value
62	str	w3, [x2]
63
641:	mov	w2, #PRR_PRODUCT_M3W
65	and	w3, w3, #PRR_PRODUCT_MASK
66	cmp	w2, w3
67	beq	2f	/* if (!IsM3W) { x1 <<= 2; } else { x1 <<= 1} */
68	lsl	x1, x1, #1
692:	lsl	x1, x1, #1
70	add	x0, x0, x1
71
72	ret
73END_FUNC get_core_pos_mpidr
74