xref: /linux/arch/arm/include/asm/smp_plat.h (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2e616c591SRussell King /*
3e616c591SRussell King  * ARM specific SMP header, this contains our implementation
4e616c591SRussell King  * details.
5e616c591SRussell King  */
6e616c591SRussell King #ifndef __ASMARM_SMP_PLAT_H
7e616c591SRussell King #define __ASMARM_SMP_PLAT_H
8e616c591SRussell King 
97f124aafSLorenzo Pieralisi #include <linux/cpumask.h>
107f124aafSLorenzo Pieralisi #include <linux/err.h>
117f124aafSLorenzo Pieralisi 
12eba1c718SJuri Lelli #include <asm/cpu.h>
13e616c591SRussell King #include <asm/cputype.h>
14e616c591SRussell King 
15f00ec48fSRussell King /*
16f00ec48fSRussell King  * Return true if we are running on a SMP platform
17f00ec48fSRussell King  */
is_smp(void)18f00ec48fSRussell King static inline bool is_smp(void)
19f00ec48fSRussell King {
20f00ec48fSRussell King #ifndef CONFIG_SMP
21f00ec48fSRussell King 	return false;
22f00ec48fSRussell King #elif defined(CONFIG_SMP_ON_UP)
23f00ec48fSRussell King 	extern unsigned int smp_on_up;
24f00ec48fSRussell King 	return !!smp_on_up;
25f00ec48fSRussell King #else
26f00ec48fSRussell King 	return true;
27f00ec48fSRussell King #endif
28f00ec48fSRussell King }
29f00ec48fSRussell King 
30eba1c718SJuri Lelli /**
31eba1c718SJuri Lelli  * smp_cpuid_part() - return part id for a given cpu
32eba1c718SJuri Lelli  * @cpu:	logical cpu id.
33eba1c718SJuri Lelli  *
34eba1c718SJuri Lelli  * Return: part id of logical cpu passed as argument.
35eba1c718SJuri Lelli  */
smp_cpuid_part(int cpu)36eba1c718SJuri Lelli static inline unsigned int smp_cpuid_part(int cpu)
37eba1c718SJuri Lelli {
38eba1c718SJuri Lelli 	struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpu);
39eba1c718SJuri Lelli 
40eba1c718SJuri Lelli 	return is_smp() ? cpu_info->cpuid & ARM_CPU_PART_MASK :
41eba1c718SJuri Lelli 			  read_cpuid_part();
42eba1c718SJuri Lelli }
43eba1c718SJuri Lelli 
44e616c591SRussell King /* all SMP configurations have the extended CPUID registers */
455c709e69SWill Deacon #ifndef CONFIG_MMU
465c709e69SWill Deacon #define tlb_ops_need_broadcast()	0
475c709e69SWill Deacon #else
tlb_ops_need_broadcast(void)48e616c591SRussell King static inline int tlb_ops_need_broadcast(void)
49e616c591SRussell King {
507511db9dSTony Lindgren 	if (!is_smp())
517511db9dSTony Lindgren 		return 0;
527511db9dSTony Lindgren 
53e616c591SRussell King 	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
54e616c591SRussell King }
555c709e69SWill Deacon #endif
56e616c591SRussell King 
5785848dd7SCatalin Marinas #if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
5885848dd7SCatalin Marinas #define cache_ops_need_broadcast()	0
5985848dd7SCatalin Marinas #else
cache_ops_need_broadcast(void)602ef7f3dbSRussell King static inline int cache_ops_need_broadcast(void)
612ef7f3dbSRussell King {
627511db9dSTony Lindgren 	if (!is_smp())
637511db9dSTony Lindgren 		return 0;
647511db9dSTony Lindgren 
652ef7f3dbSRussell King 	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
662ef7f3dbSRussell King }
6785848dd7SCatalin Marinas #endif
682ef7f3dbSRussell King 
69eb50439bSWill Deacon /*
70eb50439bSWill Deacon  * Logical CPU mapping.
71eb50439bSWill Deacon  */
7218d7f152SLorenzo Pieralisi extern u32 __cpu_logical_map[];
73eb50439bSWill Deacon #define cpu_logical_map(cpu)	__cpu_logical_map[cpu]
747f124aafSLorenzo Pieralisi /*
757f124aafSLorenzo Pieralisi  * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
767f124aafSLorenzo Pieralisi  *  - mpidr: MPIDR[23:0] to be used for the look-up
777f124aafSLorenzo Pieralisi  *
787f124aafSLorenzo Pieralisi  * Returns the cpu logical index or -EINVAL on look-up error
797f124aafSLorenzo Pieralisi  */
get_logical_index(u32 mpidr)807f124aafSLorenzo Pieralisi static inline int get_logical_index(u32 mpidr)
817f124aafSLorenzo Pieralisi {
827f124aafSLorenzo Pieralisi 	int cpu;
837f124aafSLorenzo Pieralisi 	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
847f124aafSLorenzo Pieralisi 		if (cpu_logical_map(cpu) == mpidr)
857f124aafSLorenzo Pieralisi 			return cpu;
867f124aafSLorenzo Pieralisi 	return -EINVAL;
877f124aafSLorenzo Pieralisi }
88eb50439bSWill Deacon 
897604537bSLorenzo Pieralisi /*
907604537bSLorenzo Pieralisi  * NOTE ! Assembly code relies on the following
917604537bSLorenzo Pieralisi  * structure memory layout in order to carry out load
927604537bSLorenzo Pieralisi  * multiple from its base address. For more
937604537bSLorenzo Pieralisi  * information check arch/arm/kernel/sleep.S
947604537bSLorenzo Pieralisi  */
958cf72172SLorenzo Pieralisi struct mpidr_hash {
967604537bSLorenzo Pieralisi 	u32	mask; /* used by sleep.S */
977604537bSLorenzo Pieralisi 	u32	shift_aff[3]; /* used by sleep.S */
988cf72172SLorenzo Pieralisi 	u32	bits;
998cf72172SLorenzo Pieralisi };
1008cf72172SLorenzo Pieralisi 
1018cf72172SLorenzo Pieralisi extern struct mpidr_hash mpidr_hash;
1028cf72172SLorenzo Pieralisi 
mpidr_hash_size(void)1038cf72172SLorenzo Pieralisi static inline u32 mpidr_hash_size(void)
1048cf72172SLorenzo Pieralisi {
1058cf72172SLorenzo Pieralisi 	return 1 << mpidr_hash.bits;
1068cf72172SLorenzo Pieralisi }
1072103f6cbSStephen Warren 
108fee3fd4fSGeert Uytterhoeven extern int platform_can_secondary_boot(void);
1092103f6cbSStephen Warren extern int platform_can_cpu_hotplug(void);
1102103f6cbSStephen Warren 
111787047eeSStephen Boyd #ifdef CONFIG_HOTPLUG_CPU
112787047eeSStephen Boyd extern int platform_can_hotplug_cpu(unsigned int cpu);
113787047eeSStephen Boyd #else
platform_can_hotplug_cpu(unsigned int cpu)114787047eeSStephen Boyd static inline int platform_can_hotplug_cpu(unsigned int cpu)
115787047eeSStephen Boyd {
116787047eeSStephen Boyd 	return 0;
117787047eeSStephen Boyd }
118787047eeSStephen Boyd #endif
119787047eeSStephen Boyd 
120e616c591SRussell King #endif
121