1/*
2 * Copyright (c) 2022, Mediatek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <assert_macros.S>
10#include <cpu_macros.S>
11#if CONFIG_MTK_MCUSYS
12#include <mcucfg.h>
13#endif
14#include <platform_def.h>
15	/*
16	 * Declare as weak function so that can be
17	 * overwritten by platform helpers
18	 */
19	.weak platform_mem_init
20	.weak plat_core_pos_by_mpidr
21	.weak plat_my_core_pos
22	.weak plat_mediatek_calc_core_pos
23	.global plat_mpidr_by_core_pos
24	.global plat_reset_handler
25
26	/* -----------------------------------------------------
27	 * unsigned long plat_mpidr_by_core_pos(uint32_t cpuid)
28	 * This function calcuate mpidr by cpu pos if cpu
29	 * topology is linear.
30	 *
31	 * Clobbers: x0-x1
32	 * -----------------------------------------------------
33	 */
34func plat_mpidr_by_core_pos
35	lsl x0, x0, #MPIDR_AFF1_SHIFT
36	mrs x1, mpidr_el1
37	and x1, x1, #MPIDR_MT_MASK
38	orr x0, x0, x1
39	ret
40endfunc plat_mpidr_by_core_pos
41
42	/* -----------------------------------------------------
43	 *  unsigned int plat_my_core_pos(void)
44	 *  This function uses the plat_arm_calc_core_pos()
45	 *  definition to get the index of the calling CPU.
46	 * -----------------------------------------------------
47	 */
48func plat_my_core_pos
49	mrs	x0, mpidr_el1
50	b plat_mediatek_calc_core_pos
51endfunc plat_my_core_pos
52
53	/* -----------------------------------------------------
54	 * int plat_mediatek_calc_core_pos(u_register_t mpidr);
55	 *
56	 * In ARMv8.2, AFF2 is cluster id, AFF1 is core id and
57	 * AFF0 is thread id. There is only one cluster in ARMv8.2
58	 * and one thread in current implementation.
59	 *
60	 * With this function: CorePos = CoreID (AFF1)
61	 * we do it with x0 = (x0 >> 8) & 0xff
62	 * -----------------------------------------------------
63	 */
64func plat_mediatek_calc_core_pos
65	b plat_core_pos_by_mpidr
66endfunc plat_mediatek_calc_core_pos
67
68	/* ------------------------------------------------------
69	 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
70	 *
71	 * This function implements a part of the critical
72	 * interface between the psci generic layer and the
73	 * platform that allows the former to query the platform
74	 * to convert an MPIDR to a unique linear index.
75	 *
76	 * Clobbers: x0-x1
77	 * ------------------------------------------------------
78	 */
79func plat_core_pos_by_mpidr
80	mov	x1, #MPIDR_AFFLVL_MASK
81	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
82	ret
83endfunc plat_core_pos_by_mpidr
84
85	/* --------------------------------------------------------
86	 * void platform_mem_init (void);
87	 *
88	 * Any memory init, relocation to be done before the
89	 * platform boots. Called very early in the boot process.
90	 * --------------------------------------------------------
91	 */
92func platform_mem_init
93	ret
94endfunc platform_mem_init
95
96func plat_reset_handler
97#if CONFIG_MTK_MCUSYS
98	mov	x10, x30
99	bl	plat_my_core_pos
100	mov	x30, x10
101	mov     w1, #0x1
102	lsl     w1, w1, w0
103	ldr	x0, =CPC_MCUSYS_CPU_ON_SW_HINT_SET
104	str     w1, [x0]
105	dsb     sy
106#endif
107
108#if CONFIG_MTK_ECC
109	mov x10, x30
110	/* enable sequence of ecc for cpus */
111	bl disable_core_ecc
112	bl ft_ecc_clear_per_core
113	bl enable_core_ecc
114	mov x30, x10
115#endif
116
117	ret
118endfunc plat_reset_handler
119