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 Kingstatic 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 Lellistatic 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 Kingstatic 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 Kingstatic 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 Pieralisistatic 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 Pieralisistatic 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 Boydstatic 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