18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * ARM specific SMP header, this contains our implementation
48c2ecf20Sopenharmony_ci * details.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci#ifndef __ASMARM_SMP_PLAT_H
78c2ecf20Sopenharmony_ci#define __ASMARM_SMP_PLAT_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/cpumask.h>
108c2ecf20Sopenharmony_ci#include <linux/err.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <asm/cpu.h>
138c2ecf20Sopenharmony_ci#include <asm/cputype.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/*
168c2ecf20Sopenharmony_ci * Return true if we are running on a SMP platform
178c2ecf20Sopenharmony_ci */
188c2ecf20Sopenharmony_cistatic inline bool is_smp(void)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci#ifndef CONFIG_SMP
218c2ecf20Sopenharmony_ci	return false;
228c2ecf20Sopenharmony_ci#elif defined(CONFIG_SMP_ON_UP)
238c2ecf20Sopenharmony_ci	extern unsigned int smp_on_up;
248c2ecf20Sopenharmony_ci	return !!smp_on_up;
258c2ecf20Sopenharmony_ci#else
268c2ecf20Sopenharmony_ci	return true;
278c2ecf20Sopenharmony_ci#endif
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/**
318c2ecf20Sopenharmony_ci * smp_cpuid_part() - return part id for a given cpu
328c2ecf20Sopenharmony_ci * @cpu:	logical cpu id.
338c2ecf20Sopenharmony_ci *
348c2ecf20Sopenharmony_ci * Return: part id of logical cpu passed as argument.
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_cistatic inline unsigned int smp_cpuid_part(int cpu)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpu);
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	return is_smp() ? cpu_info->cpuid & ARM_CPU_PART_MASK :
418c2ecf20Sopenharmony_ci			  read_cpuid_part();
428c2ecf20Sopenharmony_ci}
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci/* all SMP configurations have the extended CPUID registers */
458c2ecf20Sopenharmony_ci#ifndef CONFIG_MMU
468c2ecf20Sopenharmony_ci#define tlb_ops_need_broadcast()	0
478c2ecf20Sopenharmony_ci#else
488c2ecf20Sopenharmony_cistatic inline int tlb_ops_need_broadcast(void)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	if (!is_smp())
518c2ecf20Sopenharmony_ci		return 0;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci#endif
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
588c2ecf20Sopenharmony_ci#define cache_ops_need_broadcast()	0
598c2ecf20Sopenharmony_ci#else
608c2ecf20Sopenharmony_cistatic inline int cache_ops_need_broadcast(void)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	if (!is_smp())
638c2ecf20Sopenharmony_ci		return 0;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ci#endif
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/*
708c2ecf20Sopenharmony_ci * Logical CPU mapping.
718c2ecf20Sopenharmony_ci */
728c2ecf20Sopenharmony_ciextern u32 __cpu_logical_map[];
738c2ecf20Sopenharmony_ci#define cpu_logical_map(cpu)	__cpu_logical_map[cpu]
748c2ecf20Sopenharmony_ci/*
758c2ecf20Sopenharmony_ci * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
768c2ecf20Sopenharmony_ci *  - mpidr: MPIDR[23:0] to be used for the look-up
778c2ecf20Sopenharmony_ci *
788c2ecf20Sopenharmony_ci * Returns the cpu logical index or -EINVAL on look-up error
798c2ecf20Sopenharmony_ci */
808c2ecf20Sopenharmony_cistatic inline int get_logical_index(u32 mpidr)
818c2ecf20Sopenharmony_ci{
828c2ecf20Sopenharmony_ci	int cpu;
838c2ecf20Sopenharmony_ci	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
848c2ecf20Sopenharmony_ci		if (cpu_logical_map(cpu) == mpidr)
858c2ecf20Sopenharmony_ci			return cpu;
868c2ecf20Sopenharmony_ci	return -EINVAL;
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/*
908c2ecf20Sopenharmony_ci * NOTE ! Assembly code relies on the following
918c2ecf20Sopenharmony_ci * structure memory layout in order to carry out load
928c2ecf20Sopenharmony_ci * multiple from its base address. For more
938c2ecf20Sopenharmony_ci * information check arch/arm/kernel/sleep.S
948c2ecf20Sopenharmony_ci */
958c2ecf20Sopenharmony_cistruct mpidr_hash {
968c2ecf20Sopenharmony_ci	u32	mask; /* used by sleep.S */
978c2ecf20Sopenharmony_ci	u32	shift_aff[3]; /* used by sleep.S */
988c2ecf20Sopenharmony_ci	u32	bits;
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciextern struct mpidr_hash mpidr_hash;
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic inline u32 mpidr_hash_size(void)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	return 1 << mpidr_hash.bits;
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ciextern int platform_can_secondary_boot(void);
1098c2ecf20Sopenharmony_ciextern int platform_can_cpu_hotplug(void);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci#ifdef CONFIG_HOTPLUG_CPU
1128c2ecf20Sopenharmony_ciextern int platform_can_hotplug_cpu(unsigned int cpu);
1138c2ecf20Sopenharmony_ci#else
1148c2ecf20Sopenharmony_cistatic inline int platform_can_hotplug_cpu(unsigned int cpu)
1158c2ecf20Sopenharmony_ci{
1168c2ecf20Sopenharmony_ci	return 0;
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci#endif
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci#endif
121