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