Re: [PATCH v2 2/4] powerpc: Add Power12 raw mode

Amit Machhiwal <[email protected]> Tue, 4 Aug 2026 00:40:10 +0530
Newsgroups org.ozlabs.lists.linuxppc-dev
Message-ID <[email protected]>
On 2026/08/03 09:27 PM, Mahesh Salgaonkar wrote:
> From: Nicholas Piggin <[email protected]>
> 
> Add CPU table entries for raw mode.
> 
> Signed-off-by: Nicholas Piggin <[email protected]>
> Signed-off-by: Ritesh Harjani (IBM) <[email protected]>
> Signed-off-by: Mahesh Salgaonkar <[email protected]>
> Tested-by: Praveen K Pandey <[email protected]>
> Reviewed-by: Nikhil Kumar Singh <[email protected]>
> ---
> Change in v2:
> - Added Reviewed-by from Nikhil
> ---
>  arch/powerpc/include/asm/cpu_setup.h      |  2 ++
>  arch/powerpc/include/asm/cputable.h       | 17 +++++++--
>  arch/powerpc/include/asm/mmu.h            |  1 +
>  arch/powerpc/include/asm/reg.h            |  5 ++-
>  arch/powerpc/include/asm/synch.h          |  6 +++-
>  arch/powerpc/include/uapi/asm/cputable.h  |  1 +
>  arch/powerpc/kernel/cpu_setup_power.c     | 43 +++++++++++++++++++++++
>  arch/powerpc/kernel/cpu_specs_book3s_64.h | 22 ++++++++++++
>  arch/powerpc/kernel/dt_cpu_ftrs.c         | 37 +++++++++++++++++++
>  arch/powerpc/kernel/setup-common.c        |  1 +
>  arch/powerpc/kvm/book3s_hv.c              |  9 +++--
>  arch/powerpc/mm/book3s64/hash_native.c    | 22 ++++++++----
>  arch/powerpc/mm/init_64.c                 |  4 ++-
>  13 files changed, 157 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/cpu_setup.h b/arch/powerpc/include/asm/cpu_setup.h
> index 30e2fe3895024..26d2c0e2c99c6 100644
> --- a/arch/powerpc/include/asm/cpu_setup.h
> +++ b/arch/powerpc/include/asm/cpu_setup.h
> @@ -9,10 +9,12 @@ void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec);
>  void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec);
>  void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec);
>  void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec);
> +void __setup_cpu_power12(unsigned long offset, struct cpu_spec *spec);
>  void __restore_cpu_power7(void);
>  void __restore_cpu_power8(void);
>  void __restore_cpu_power9(void);
>  void __restore_cpu_power10(void);
> +void __restore_cpu_power12(void);
>  
>  void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec *spec);
>  void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec *spec);
> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
> index ec16c12296da8..a3be81c47df3a 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -194,6 +194,7 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTR_DAWR1			LONG_ASM_CONST(0x0008000000000000)
>  #define CPU_FTR_DEXCR_NPHIE		LONG_ASM_CONST(0x0010000000000000)
>  #define CPU_FTR_P11_PVR			LONG_ASM_CONST(0x0020000000000000)
> +#define CPU_FTR_ARCH_32			LONG_ASM_CONST(0x0040000000000000)
>  
>  #ifndef __ASSEMBLER__
>  
> @@ -457,6 +458,18 @@ static inline void cpu_feature_keys_init(void) { }
>  
>  #define CPU_FTRS_POWER11	(CPU_FTRS_POWER10 | CPU_FTR_P11_PVR)
>  
> +#define CPU_FTRS_POWER12 (CPU_FTR_LWSYNC | \
> +	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
> +	    CPU_FTR_MMCRA | CPU_FTR_SMT | \
> +	    CPU_FTR_COHERENT_ICACHE | \
> +	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
> +	    CPU_FTR_DSCR | \
> +	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
> +	    CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
> +	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
> +	    CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | CPU_FTR_ARCH_32 | \
> +	    CPU_FTR_DAWR | CPU_FTR_DAWR1)
> +
>  #define CPU_FTRS_CELL	(CPU_FTR_LWSYNC | \
>  	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
>  	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> @@ -476,7 +489,7 @@ static inline void cpu_feature_keys_init(void) { }
>  	    (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
>  	     CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
>  	     CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | \
> -	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11)
> +	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11 | CPU_FTRS_POWER12)

Line exceeds 80 columns. Please wrap CPU_FTRS_POWER12 onto its own line.
Same applies to the #else variant below.

>  #else
>  #define CPU_FTRS_POSSIBLE	\
>  	    (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
> @@ -484,7 +497,7 @@ static inline void cpu_feature_keys_init(void) { }
>  	     CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
>  	     CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
>  	     CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | \
> -	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11)
> +	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11 | CPU_FTRS_POWER12)
>  #endif /* CONFIG_CPU_LITTLE_ENDIAN */
>  #endif
>  #else
> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
> index 5f9c5d436e171..4fd7f81a29304 100644
> --- a/arch/powerpc/include/asm/mmu.h
> +++ b/arch/powerpc/include/asm/mmu.h
> @@ -133,6 +133,7 @@
>  #define MMU_FTRS_POWER9		MMU_FTRS_POWER6
>  #define MMU_FTRS_POWER10	MMU_FTRS_POWER6
>  #define MMU_FTRS_POWER11	MMU_FTRS_POWER6
> +#define MMU_FTRS_POWER12	MMU_FTRS_POWER6
>  #define MMU_FTRS_CELL		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
>  				MMU_FTR_CI_LARGE_PAGE
>  #define MMU_FTRS_PA6T		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 3449dd2b577d4..4460b666c603e 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -492,11 +492,12 @@
>   * determine both the compatibility level which we want to emulate and the
>   * compatibility level which the host is capable of emulating.
>   */
> +#define   PCR_ARCH_31   0x20		/* Architecture 3.1 */
>  #define   PCR_ARCH_300	0x10		/* Architecture 3.00 */
>  #define   PCR_ARCH_207	0x8		/* Architecture 2.07 */
>  #define   PCR_ARCH_206	0x4		/* Architecture 2.06 */
>  #define   PCR_ARCH_205	0x2		/* Architecture 2.05 */
> -#define   PCR_LOW_BITS	(PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | PCR_ARCH_300)
> +#define   PCR_LOW_BITS	(PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | PCR_ARCH_300 | PCR_ARCH_31)
>  #define   PCR_MASK	~(PCR_HIGH_BITS | PCR_LOW_BITS)	/* PCR Reserved Bits */
>  #define	SPRN_HEIR	0x153	/* Hypervisor Emulated Instruction Register */
>  #define SPRN_TLBINDEXR	0x154	/* P7 TLB control register */
> @@ -1344,6 +1345,7 @@
>  #define PVR_POWER9	0x004E
>  #define PVR_POWER10	0x0080
>  #define PVR_POWER11	0x0082
> +#define PVR_POWER12	0x0083
>  #define PVR_BE		0x0070
>  #define PVR_PA6T	0x0090
>  
> @@ -1356,6 +1358,7 @@
>  #define PVR_ARCH_300	0x0f000005
>  #define PVR_ARCH_31	0x0f000006
>  #define PVR_ARCH_31_P11	0x0f000007
> +#define PVR_ARCH_32	0x0f000008
>  
>  /* Macros for setting and retrieving special purpose registers */
>  #ifndef __ASSEMBLER__
> diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h
> index 0d3ccb34adfb2..d0e9765dee287 100644
> --- a/arch/powerpc/include/asm/synch.h
> +++ b/arch/powerpc/include/asm/synch.h
> @@ -37,8 +37,12 @@ static inline void ppc_after_tlbiel_barrier(void)
>  	 * accelerators mapped will use tlbie (which does invalidate the copy)
>  	 * to invalidate translations. It's not possible to limit POWER10 this
>  	 * way due to local copy-paste.
> +	 *
> +	 * POWER12 does not need it.
>  	 */
> -	asm volatile(ASM_FTR_IFSET(PPC_CP_ABORT, "", %0) : : "i" (CPU_FTR_ARCH_31) : "memory");
> +	asm volatile(ASM_FTR_IF(PPC_CP_ABORT, "", %0, %1) :
> +		: "i" (CPU_FTR_ARCH_31|CPU_FTR_ARCH_32), "i" (CPU_FTR_ARCH_31)
> +		: "memory");
>  }
>  #endif /* __ASSEMBLER__ */
>  
> diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h
> index 731b97dc2d150..bc9bd225f5876 100644
> --- a/arch/powerpc/include/uapi/asm/cputable.h
> +++ b/arch/powerpc/include/uapi/asm/cputable.h
> @@ -52,6 +52,7 @@
>  #define PPC_FEATURE2_HTM_NO_SUSPEND	0x00080000 /* TM w/out suspended state */
>  #define PPC_FEATURE2_ARCH_3_1		0x00040000 /* ISA 3.1 */
>  #define PPC_FEATURE2_MMA		0x00020000 /* Matrix Multiply Assist */
> +#define PPC_FEATURE2_ARCH_3_2		0x00010000 /* ISA 3.2 */
>  
>  /*
>   * IMPORTANT!
> diff --git a/arch/powerpc/kernel/cpu_setup_power.c b/arch/powerpc/kernel/cpu_setup_power.c
> index 98bd4e6c17705..5de704ac031d8 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.c
> +++ b/arch/powerpc/kernel/cpu_setup_power.c
> @@ -286,3 +286,46 @@ void __restore_cpu_power10(void)
>  	init_HFSCR();
>  	init_PMU_HV();
>  }
> +
> +void __setup_cpu_power12(unsigned long offset, struct cpu_spec *t)
> +{
> +	init_FSCR_power10();
> +	init_PMU();
> +	init_PMU_ISA31();
> +
> +	if (!init_hvmode_206(t))
> +		return;
> +
> +	mtspr(SPRN_PSSCR, 0);
> +	mtspr(SPRN_LPID, 0);
> +	mtspr(SPRN_PID, 0);
> +	mtspr(SPRN_AMOR, ~0);
> +	mtspr(SPRN_PCR, PCR_MASK);
> +	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\

The '\' continuation is unnecessary inside a function body — the
enclosing parentheses are sufficient for the compiler. While this
pattern exists in the upstream __setup_cpu_power10 and
__restore_cpu_power10 functions,  please consider not perpetuating it in
the new Power12 functions. Simply drop the '\'.

checkpatch.pl does report this:

  WARNING: Avoid unnecessary line continuations
  #201: FILE: arch/powerpc/kernel/cpu_setup_power.c:304:
  +	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
  
  WARNING: Avoid unnecessary line continuations
  #224: FILE: arch/powerpc/kernel/cpu_setup_power.c:327:
  +	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\

Thanks,
Amit

> +			 LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
> +	init_HFSCR();
> +	init_PMU_HV();
> +}
> +
> +void __restore_cpu_power12(void)
> +{
> +	u64 msr;
> +
> +	init_FSCR_power10();
> +	init_PMU();
> +	init_PMU_ISA31();
> +
> +	msr = mfmsr();
> +	if (!(msr & MSR_HV))
> +		return;
> +
> +	mtspr(SPRN_PSSCR, 0);
> +	mtspr(SPRN_LPID, 0);
> +	mtspr(SPRN_PID, 0);
> +	mtspr(SPRN_AMOR, ~0);
> +	mtspr(SPRN_PCR, PCR_MASK);
> +	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\

Ditto.

> +			 LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
> +	init_HFSCR();
> +	init_PMU_HV();
> +}
> diff --git a/arch/powerpc/kernel/cpu_specs_book3s_64.h b/arch/powerpc/kernel/cpu_specs_book3s_64.h
> index 98d4274a1b6bf..7619dd157646f 100644
> --- a/arch/powerpc/kernel/cpu_specs_book3s_64.h
> +++ b/arch/powerpc/kernel/cpu_specs_book3s_64.h
> @@ -63,6 +63,11 @@
>  #define COMMON_USER_POWER11	COMMON_USER_POWER10
>  #define COMMON_USER2_POWER11	COMMON_USER2_POWER10
>  
> +#define COMMON_USER_POWER12	COMMON_USER_POWER10
> +#define COMMON_USER2_POWER12	(COMMON_USER2_POWER10 | \
> +				 PPC_FEATURE2_ARCH_3_2)
> +
> +
>  static struct cpu_spec cpu_specs[] __initdata = {
>  	{	/* PPC970 */
>  		.pvr_mask		= 0xffff0000,
> @@ -485,6 +490,23 @@ static struct cpu_spec cpu_specs[] __initdata = {
>  		.machine_check_early	= __machine_check_early_realmode_p10,
>  		.platform		= "power11",
>  	},
> +	{	/* Power12 */
> +		.pvr_mask		= 0xffff0000,
> +		.pvr_value		= 0x00830000,
> +		.cpu_name		= "Power12 (raw)",
> +		.cpu_features		= CPU_FTRS_POWER12,
> +		.cpu_user_features	= COMMON_USER_POWER12,
> +		.cpu_user_features2	= COMMON_USER2_POWER12,
> +		.mmu_features		= MMU_FTRS_POWER12,
> +		.icache_bsize		= 128,
> +		.dcache_bsize		= 128,
> +		.num_pmcs		= 6,
> +		.pmc_type		= PPC_PMC_IBM,
> +		.cpu_setup		= __setup_cpu_power12,
> +		.cpu_restore		= __restore_cpu_power12,
> +		.machine_check_early	= __machine_check_early_realmode_p10,
> +		.platform		= "power12",
> +	},
>  	{	/* Cell Broadband Engine */
>  		.pvr_mask		= 0xffff0000,
>  		.pvr_value		= 0x00700000,
> diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
> index e5853daa6a486..b369e8cda12ee 100644
> --- a/arch/powerpc/kernel/dt_cpu_ftrs.c
> +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
> @@ -26,6 +26,7 @@
>  /* Device-tree visible constants follow */
>  #define ISA_V3_0B       3000
>  #define ISA_V3_1        3100
> +#define ISA_V3_2        3200
>  
>  #define USABLE_PR               (1U << 0)
>  #define USABLE_OS               (1U << 1)
> @@ -466,6 +467,35 @@ static int __init feat_enable_mce_power11(struct dt_cpu_feature *f)
>  	return 1;
>  }
>  
> +static void init_pmu_power12(void)
> +{
> +	init_pmu_power10();
> +}
> +
> +static int __init feat_enable_pmu_power12(struct dt_cpu_feature *f)
> +{
> +	hfscr_pmu_enable();
> +
> +	init_pmu_power12();
> +	init_pmu_registers = init_pmu_power12;
> +
> +	cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
> +	cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
> +
> +	cur_cpu_spec->num_pmcs          = 6;
> +	cur_cpu_spec->pmc_type          = PPC_PMC_IBM;
> +
> +	return 1;
> +}
> +
> +static int __init feat_enable_mce_power12(struct dt_cpu_feature *f)
> +{
> +	cur_cpu_spec->platform = "power12";
> +	cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10;
> +
> +	return 1;
> +}
> +
>  static int __init feat_enable_tm(struct dt_cpu_feature *f)
>  {
>  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> @@ -657,9 +687,11 @@ static struct dt_cpu_feature_match __initdata
>  	{"machine-check-power9", feat_enable_mce_power9, 0},
>  	{"machine-check-power10", feat_enable_mce_power10, 0},
>  	{"machine-check-power11", feat_enable_mce_power11, 0},
> +	{"machine-check-power12", feat_enable_mce_power12, 0},
>  	{"performance-monitor-power9", feat_enable_pmu_power9, 0},
>  	{"performance-monitor-power10", feat_enable_pmu_power10, 0},
>  	{"performance-monitor-power11", feat_enable_pmu_power10, 0},
> +	{"performance-monitor-power12", feat_enable_pmu_power12, 0},
>  	{"event-based-branch-v3", feat_enable, 0},
>  	{"random-number-generator", feat_enable, 0},
>  	{"system-call-vectored", feat_disable, 0},
> @@ -714,6 +746,11 @@ static void __init cpufeatures_setup_start(u32 isa)
>  		if (PVR_VER(mfspr(SPRN_PVR)) >= PVR_POWER11)
>  			cur_cpu_spec->cpu_features |= CPU_FTR_P11_PVR;
>  	}
> +
> +	if (isa >= ISA_V3_2) {
> +		cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_32;
> +		cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_2;
> +	}
>  }
>  
>  static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> index 67c545f61f0d7..4afaba19b5867 100644
> --- a/arch/powerpc/kernel/setup-common.c
> +++ b/arch/powerpc/kernel/setup-common.c
> @@ -304,6 +304,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
>  				break;
>  			case 0x004e: /* POWER9 bits 12-15 give chip type */
>  			case 0x0080: /* POWER10 bit 12 gives SMT8/4 */
> +			case 0x0083: /* POWER12 bit 12 gives SMT8/4 */
>  				maj = (pvr >> 8) & 0x0F;
>  				min = pvr & 0xFF;
>  				break;
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 61dbeea317f3b..6ad4e3d0b5a08 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -388,7 +388,7 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr)
>  }
>  
>  /* Dummy value used in computing PCR value below */
> -#define PCR_ARCH_31    (PCR_ARCH_300 << 1)
> +#define PCR_ARCH_32	(PCR_ARCH_31 << 1)
>  
>  static inline unsigned long map_pcr_to_cap(unsigned long pcr)
>  {
> @@ -417,7 +417,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
>  	struct kvmppc_vcore *vc = vcpu->arch.vcore;
>  
>  	/* We can (emulate) our own architecture version and anything older */
> -	if (cpu_has_feature(CPU_FTR_P11_PVR) || cpu_has_feature(CPU_FTR_ARCH_31))
> +	if (cpu_has_feature(CPU_FTR_ARCH_32))
> +		host_pcr_bit = PCR_ARCH_32;
> +	else if (cpu_has_feature(CPU_FTR_P11_PVR) || cpu_has_feature(CPU_FTR_ARCH_31))
>  		host_pcr_bit = PCR_ARCH_31;
>  	else if (cpu_has_feature(CPU_FTR_ARCH_300))
>  		host_pcr_bit = PCR_ARCH_300;
> @@ -449,6 +451,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
>  		case PVR_ARCH_31_P11:
>  			guest_pcr_bit = PCR_ARCH_31;
>  			break;
> +		case PVR_ARCH_32:
> +			guest_pcr_bit = PCR_ARCH_32;
> +			break;
>  		default:
>  			return -EINVAL;
>  		}
> diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c
> index e9e2dd70c0605..ab2a80e59011c 100644
> --- a/arch/powerpc/mm/book3s64/hash_native.c
> +++ b/arch/powerpc/mm/book3s64/hash_native.c
> @@ -184,9 +184,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize)
>  		va |= ssize << 8;
>  		sllp = get_sllp_encoding(apsize);
>  		va |= sllp << 5;
> -		asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 0), %1)
> -			     : : "r" (va), "i" (CPU_FTR_ARCH_206)
> -			     : "memory");
> +
> +		if (cpu_has_feature(CPU_FTR_ARCH_32)) {
> +			asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : "r"(va), "r"(0) : "memory");
> +		} else {
> +			asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 0), %1)
> +				     : : "r" (va), "i" (CPU_FTR_ARCH_206)
> +				     : "memory");
> +		}
>  		break;
>  	default:
>  		/* We need 14 to 14 + i bits of va */
> @@ -203,9 +208,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize)
>  		 */
>  		va |= (vpn & 0xfe);
>  		va |= 1; /* L */
> -		asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 1), %1)
> -			     : : "r" (va), "i" (CPU_FTR_ARCH_206)
> -			     : "memory");
> +
> +		if (cpu_has_feature(CPU_FTR_ARCH_32)) {
> +			asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : "r"(va), "r"(0) : "memory");
> +		} else {
> +			asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 1), %1)
> +				     : : "r" (va), "i" (CPU_FTR_ARCH_206)
> +				     : "memory");
> +		}
>  		break;
>  	}
>  	trace_tlbie(0, 1, va, 0, 0, 0, 0);
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 64f0df5bb5cdc..0e777d7dc3326 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -628,7 +628,9 @@ void __init mmu_early_init_devtree(void)
>  
>  	of_scan_flat_dt(dt_scan_mmu_pid_width, NULL);
>  	if (hvmode && !mmu_lpid_bits) {
> -		if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
> +		if (early_cpu_has_feature(CPU_FTR_ARCH_32))
> +			mmu_lpid_bits = 16; /* POWER12 */
> +		else if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
>  			mmu_lpid_bits = 12; /* POWER8-10 */
>  		else
>  			mmu_lpid_bits = 10; /* POWER7 */
> -- 
> 2.55.0
> 
>