[Skiboot] [PATCH v4 1/6] Initial Power11 enablement

Mahesh Salgaonkar mahesh at linux.ibm.com
Fri Feb 21 05:25:27 AEDT 2025


Detect Power11 PVR and use P10 code path.

Signed-off-by: Mahesh Salgaonkar <mahesh at linux.ibm.com>
[adityag: Add Power11 chiptod device node]
[adityag: Fix the proc_gen checks in pir_to_thread_id and bmc sensor]
Signed-off-by: Aditya Gupta <adityag at linux.ibm.com>
Reviewed-by: Nicholas Piggin <npiggin at gmail.com>
---
Change in v4:
- Move psi.c and xscom.c hunks from patch 3/6 to this patch

Change in v3:
- Make proc_gen checks consistent all over.

Change in v2:
- Add Power11 chiptod device node
- Fix the proc_gen checks in pir_to_thread_id and bmc sensor
---
 asm/head.S                       | 12 ++++++---
 asm/misc.S                       |  4 ++-
 core/affinity.c                  |  2 +-
 core/chip.c                      |  8 +++---
 core/cpu.c                       | 18 +++++++++++++-
 core/direct-controls.c           | 18 +++++++-------
 core/fast-reboot.c               |  4 +--
 core/hmi.c                       | 12 ++++++---
 core/init.c                      | 10 ++++----
 core/mce.c                       |  2 +-
 hdata/fsp.c                      |  2 +-
 hdata/i2c.c                      |  5 ++--
 hdata/iohub.c                    |  3 ++-
 hdata/spira.c                    | 15 ++++++++++--
 hw/chiptod.c                     |  4 ++-
 hw/fsp/fsp-occ.c                 |  1 +
 hw/fsp/fsp-psi.c                 |  1 +
 hw/homer.c                       |  1 +
 hw/imc.c                         |  5 +++-
 hw/lpc.c                         |  7 ++++--
 hw/occ.c                         |  4 ++-
 hw/p8-i2c.c                      |  2 +-
 hw/phb4.c                        |  2 +-
 hw/phys-map.c                    |  3 +++
 hw/prd.c                         |  1 +
 hw/psi.c                         |  7 +++++-
 hw/sbe.c                         |  2 +-
 hw/slw.c                         |  7 +++---
 hw/vas.c                         |  2 +-
 hw/xive2.c                       |  4 +--
 hw/xscom.c                       | 42 ++++++++++++++++++++++++--------
 include/chip.h                   |  1 +
 include/phb4.h                   |  2 +-
 include/processor.h              |  6 +++++
 include/skiboot.h                |  1 +
 platforms/ibm-fsp/hostservices.c |  1 +
 36 files changed, 158 insertions(+), 63 deletions(-)

diff --git a/asm/head.S b/asm/head.S
index bf2a66ee30..5de3483004 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -324,7 +324,7 @@ boot_offset:
  *   r28 :  PVR
  *   r27 :  DTB pointer (or NULL)
  *   r26 :  PIR thread mask
- *   r25 :  P9/10 fused core flag
+ *   r25 :  P9/10/11 fused core flag
  */
 .global boot_entry
 boot_entry:
@@ -344,6 +344,8 @@ boot_entry:
 	beq 	3f
 	cmpwi	cr0,%r3,PVR_TYPE_P10
 	beq 	4f
+	cmpwi	cr0,%r3,PVR_TYPE_P11
+	beq 	4f
 	attn		/* Unsupported CPU type... what do we do ? */
 	b 	.	/* loop here, just in case attn is disabled */
 
@@ -357,7 +359,7 @@ boot_entry:
 	b   2f
 
 4:      /*
-	 * P10 fused core check (SPRC/SPRD method does not work).
+	 * P10/11 fused core check (SPRC/SPRD method does not work).
 	 * PVR bit 12 set = normal code
 	 */
 	andi.	%r3, %r28, 0x1000
@@ -743,6 +745,8 @@ init_shared_sprs:
 	beq	4f
 	cmpwi	cr0,%r3,PVR_TYPE_P10
 	beq	5f
+	cmpwi	cr0,%r3,PVR_TYPE_P11
+	beq	5f
 	/* Unsupported CPU type... what do we do ? */
 	b	9f
 
@@ -868,6 +872,8 @@ init_replicated_sprs:
 	beq	4f
 	cmpwi	cr0,%r3,PVR_TYPE_P10
 	beq	5f
+	cmpwi	cr0,%r3,PVR_TYPE_P11
+	beq	5f
 	/* Unsupported CPU type... what do we do ? */
 	b	9f
 
@@ -891,7 +897,7 @@ init_replicated_sprs:
 	LOAD_IMM64(%r3,0x0000000000000010)
 	mtspr	SPR_DSCR,%r3
 
-5:	/* P10 */
+5:	/* P10/11 */
 	/* LPCR: sane value */
 	LOAD_IMM64(%r3,0x0040000000000000)
 	mtspr	SPR_LPCR, %r3
diff --git a/asm/misc.S b/asm/misc.S
index ea43763228..8c2ed6f6ec 100644
--- a/asm/misc.S
+++ b/asm/misc.S
@@ -99,7 +99,7 @@ cleanup_local_tlb:
 	.global cleanup_global_tlb
 cleanup_global_tlb:
 
-	/* Only supported on P9, P10 for now */
+	/* Only supported on P9, P10, P11 for now */
 	mfspr	%r3,SPR_PVR
 	srdi	%r3,%r3,16
 	cmpwi	cr0,%r3,PVR_TYPE_P9
@@ -108,6 +108,8 @@ cleanup_global_tlb:
 	beq	cr0,1f
 	cmpwi	cr0,%r3,PVR_TYPE_P10
 	beq	cr0,1f
+	cmpwi	cr0,%r3,PVR_TYPE_P11
+	beq	cr0,1f
 	blr
 
 	/* Sync out previous updates */
diff --git a/core/affinity.c b/core/affinity.c
index 0209d3cd9e..16a6c04d47 100644
--- a/core/affinity.c
+++ b/core/affinity.c
@@ -111,7 +111,7 @@ void add_core_associativity(struct cpu_thread *cpu)
 		core_id = (cpu->pir >> 3) & 0xf;
 	else if (proc_gen == proc_gen_p9)
 		core_id = (cpu->pir >> 2) & 0x1f;
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		core_id = (cpu->pir >> 2) & 0x1f;
 	else
 		return;
diff --git a/core/chip.c b/core/chip.c
index e20370bdbe..078f658a29 100644
--- a/core/chip.c
+++ b/core/chip.c
@@ -13,7 +13,7 @@ enum proc_chip_quirks proc_chip_quirks;
 
 uint32_t pir_to_chip_id(uint32_t pir)
 {
-	if (proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		return P10_PIR2GCID(pir);
 	else if (proc_gen == proc_gen_p9)
 		return P9_PIR2GCID(pir);
@@ -25,7 +25,7 @@ uint32_t pir_to_chip_id(uint32_t pir)
 
 uint32_t pir_to_core_id(uint32_t pir)
 {
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		if (this_cpu()->is_fused_core)
 			return P10_PIRFUSED2NORMALCOREID(pir);
 		else
@@ -44,7 +44,7 @@ uint32_t pir_to_core_id(uint32_t pir)
 
 uint32_t pir_to_fused_core_id(uint32_t pir)
 {
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		if (this_cpu()->is_fused_core)
 			return P10_PIR2FUSEDCOREID(pir);
 		else
@@ -63,7 +63,7 @@ uint32_t pir_to_fused_core_id(uint32_t pir)
 
 uint32_t pir_to_thread_id(uint32_t pir)
 {
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		if (this_cpu()->is_fused_core)
 			return P10_PIRFUSED2NORMALTHREADID(pir);
 		else
diff --git a/core/cpu.c b/core/cpu.c
index 5713a512f7..d4ad195d29 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -103,7 +103,8 @@ static void cpu_send_ipi(struct cpu_thread *cpu)
 	if (proc_gen == proc_gen_p8) {
 		/* Poke IPI */
 		icp_kick_cpu(cpu);
-	} else if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10) {
+	} else if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 ||
+						proc_gen == proc_gen_p11) {
 		p9_dbell_send(cpu->pir);
 	}
 }
@@ -1057,6 +1058,13 @@ void init_boot_cpu(void)
 		hid0_attn = SPR_HID0_POWER10_ENABLE_ATTN;
 		hid0_icache = SPR_HID0_POWER10_FLUSH_ICACHE;
 		break;
+	case PVR_TYPE_P11:
+		proc_gen = proc_gen_p11;
+		radix_supported = true;
+		hid0_hile = SPR_HID0_POWER10_HILE;
+		hid0_attn = SPR_HID0_POWER10_ENABLE_ATTN;
+		hid0_icache = SPR_HID0_POWER10_FLUSH_ICACHE;
+		break;
 	default:
 		proc_gen = proc_gen_unknown;
 	}
@@ -1084,6 +1092,14 @@ void init_boot_cpu(void)
 		prlog(PR_INFO, "CPU: P10 generation processor"
 		      " (max %d threads/core)\n", cpu_threads_max);
 		break;
+	case proc_gen_p11:
+		if (is_fused_core(pvr))
+			cpu_threads_max = 8;
+		else
+			cpu_threads_max = 4;
+		prlog(PR_INFO, "CPU: Power11 generation processor"
+		      " (max %d threads/core)\n", cpu_thread_count);
+		break;
 	default:
 		prerror("CPU: Unknown PVR, assuming 1 thread\n");
 		cpu_threads_max = 1;
diff --git a/core/direct-controls.c b/core/direct-controls.c
index c3c6ae717a..2009581dde 100644
--- a/core/direct-controls.c
+++ b/core/direct-controls.c
@@ -861,7 +861,7 @@ int dctl_set_special_wakeup(struct cpu_thread *t)
 
 	lock(&c->dctl_lock);
 	if (c->special_wakeup_count == 0) {
-		if (proc_gen == proc_gen_p10)
+		if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 			rc = p10_core_set_special_wakeup(c);
 		else if (proc_gen == proc_gen_p9)
 			rc = p9_core_set_special_wakeup(c);
@@ -887,7 +887,7 @@ int dctl_clear_special_wakeup(struct cpu_thread *t)
 	if (!c->special_wakeup_count)
 		goto out;
 	if (c->special_wakeup_count == 1) {
-		if (proc_gen == proc_gen_p10)
+		if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 			rc = p10_core_clear_special_wakeup(c);
 		else if (proc_gen == proc_gen_p9)
 			rc = p9_core_clear_special_wakeup(c);
@@ -906,7 +906,7 @@ int dctl_core_is_gated(struct cpu_thread *t)
 {
 	struct cpu_thread *c = t->primary;
 
-	if (proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		return p10_core_is_gated(c);
 	else if (proc_gen == proc_gen_p9)
 		return p9_core_is_gated(c);
@@ -924,7 +924,7 @@ static int dctl_stop(struct cpu_thread *t)
 		unlock(&c->dctl_lock);
 		return OPAL_BUSY;
 	}
-	if (proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		rc = p10_stop_thread(t);
 	else if (proc_gen == proc_gen_p9)
 		rc = p9_stop_thread(t);
@@ -942,7 +942,7 @@ static int dctl_cont(struct cpu_thread *t)
 	struct cpu_thread *c = t->primary;
 	int rc;
 
-	if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p9)
+	if (proc_gen != proc_gen_p11 && proc_gen != proc_gen_p10 && proc_gen != proc_gen_p9)
 		return OPAL_UNSUPPORTED;
 
 	lock(&c->dctl_lock);
@@ -950,7 +950,7 @@ static int dctl_cont(struct cpu_thread *t)
 		unlock(&c->dctl_lock);
 		return OPAL_BUSY;
 	}
-	if (proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		rc = p10_cont_thread(t);
 	else /* (proc_gen == proc_gen_p9) */
 		rc = p9_cont_thread(t);
@@ -977,7 +977,7 @@ static int dctl_sreset(struct cpu_thread *t)
 		unlock(&c->dctl_lock);
 		return OPAL_BUSY;
 	}
-	if (proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		rc = p10_sreset_thread(t);
 	else if (proc_gen == proc_gen_p9)
 		rc = p9_sreset_thread(t);
@@ -1124,7 +1124,7 @@ int64_t opal_signal_system_reset(int cpu_nr)
 	struct cpu_thread *cpu;
 	int64_t ret;
 
-	if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10)
+	if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11)
 		return OPAL_UNSUPPORTED;
 
 	/*
@@ -1154,7 +1154,7 @@ void direct_controls_init(void)
 	if (chip_quirk(QUIRK_NO_DIRECT_CTL))
 		return;
 
-	if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10)
+	if (proc_gen != proc_gen_p9 && proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11)
 		return;
 
 	opal_register(OPAL_SIGNAL_SYSTEM_RESET, opal_signal_system_reset, 1);
diff --git a/core/fast-reboot.c b/core/fast-reboot.c
index 7f08c29633..2f3d5aa554 100644
--- a/core/fast-reboot.c
+++ b/core/fast-reboot.c
@@ -263,7 +263,7 @@ static void cleanup_cpu_state(void)
 
 	if (proc_gen == proc_gen_p9)
 		xive_cpu_reset();
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		xive2_cpu_reset();
 
 	/* Per core cleanup */
@@ -388,7 +388,7 @@ void __noreturn fast_reboot_entry(void)
 
 	if (proc_gen == proc_gen_p9)
 		xive_reset();
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		xive2_reset();
 
 	/* Let the CPU layer do some last minute global cleanups */
diff --git a/core/hmi.c b/core/hmi.c
index 728d3637ef..f5f161f740 100644
--- a/core/hmi.c
+++ b/core/hmi.c
@@ -404,6 +404,7 @@ static int setup_scom_addresses(void)
 		nx_pbi_fir = P9_NX_PBI_FIR;
 		return 1;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		malf_alert_scom = P10_MALFUNC_ALERT;
 		nx_status_reg = P10_NX_STATUS_REG;
 		nx_dma_engine_fir = P10_NX_DMA_ENGINE_FIR;
@@ -460,6 +461,7 @@ static int read_core_fir(uint32_t chip_id, uint32_t core_id, uint64_t *core_fir)
 			XSCOM_ADDR_P9_EC(core_id, P9_CORE_FIR), core_fir);
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		rc = xscom_read(chip_id,
 			XSCOM_ADDR_P10_EC(core_id, P10_CORE_FIR), core_fir);
 		break;
@@ -479,6 +481,7 @@ static int read_core_wof(uint32_t chip_id, uint32_t core_id, uint64_t *core_wof)
 			XSCOM_ADDR_P9_EC(core_id, P9_CORE_WOF), core_wof);
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		rc = xscom_read(chip_id,
 			XSCOM_ADDR_P10_EC(core_id, P10_CORE_WOF), core_wof);
 		break;
@@ -541,7 +544,7 @@ static bool decode_core_fir(struct cpu_thread *cpu,
 			loc ? loc : "Not Available",
 			cpu->chip_id, core_id, core_fir);
 
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		for (i = 0; i < ARRAY_SIZE(p10_core_fir_bits); i++) {
 			if (core_fir & PPC_BIT(p10_core_fir_bits[i].bit))
 				prlog(PR_INFO, "    %s\n", p10_core_fir_bits[i].reason);
@@ -949,7 +952,7 @@ static void decode_malfunction(struct OpalHMIEvent *hmi_evt, uint64_t *out_flags
 			xscom_write(this_cpu()->chip_id, malf_alert_scom,
 								~PPC_BIT(i));
 			find_capp_checkstop_reason(i, hmi_evt, &flags);
-			if (proc_gen != proc_gen_p10)
+			if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11)
 				find_nx_checkstop_reason(i, hmi_evt, &flags);
 			find_npu_checkstop_reason(i, hmi_evt, &flags);
 		}
@@ -1413,7 +1416,7 @@ static int handle_hmi_exception(uint64_t hmer, struct OpalHMIEvent *hmi_evt,
 					if (core_wof & PPC_BIT(p9_recoverable_bits[i].bit))
 						prlog(PR_DEBUG, "    %s\n", p9_recoverable_bits[i].reason);
 				}
-			} else if (proc_gen == proc_gen_p10) {
+			} else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 				for (i = 0; i < ARRAY_SIZE(p10_core_fir_bits); i++) {
 					if (core_wof & PPC_BIT(p10_core_fir_bits[i].bit))
 						prlog(PR_DEBUG, "    %s\n", p10_core_fir_bits[i].reason);
@@ -1508,7 +1511,8 @@ static int handle_hmi_exception(uint64_t hmer, struct OpalHMIEvent *hmi_evt,
 				queue_hmi_event(hmi_evt, recover, out_flags);
 		}
 	}
-	if ((proc_gen == proc_gen_p10) && (hmer & SPR_HMER_P10_TRIG_FIR_HMI)) {
+	if ((proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
+		&& (hmer & SPR_HMER_P10_TRIG_FIR_HMI)) {
 		handled |= SPR_HMER_P10_TRIG_FIR_HMI;
 		hmer &= ~SPR_HMER_P10_TRIG_FIR_HMI;
 
diff --git a/core/init.c b/core/init.c
index 2d8a54595e..8e49bb966a 100644
--- a/core/init.c
+++ b/core/init.c
@@ -1005,7 +1005,7 @@ static void mask_pc_system_xstop(void)
         uint32_t chip_id, core_id;
         int rc;
 
-	if (proc_gen != proc_gen_p10)
+	if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11)
                 return;
 
 	if (chip_quirk(QUIRK_MAMBO_CALLOUTS) || chip_quirk(QUIRK_AWAN))
@@ -1046,7 +1046,7 @@ static void probe_lpar_per_core(void)
 
 	if (proc_gen == proc_gen_p9)
 		addr = XSCOM_ADDR_P9_EC(core_id, P9_CORE_THREAD_STATE);
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		addr = XSCOM_ADDR_P10_EC(core_id, P10_EC_CORE_THREAD_STATE);
 	else
 		return;
@@ -1243,7 +1243,7 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
 
 	/* Initialize the rest of the cpu thread structs */
 	init_all_cpus();
-	if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		cpu_set_ipi_enable(true);
 
         /* Once all CPU are up apply this workaround */
@@ -1274,7 +1274,7 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
 	/* On P9 and P10, initialize XIVE */
 	if (proc_gen == proc_gen_p9)
 		init_xive();
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		xive2_init();
 
 	/* Grab centaurs from device-tree if present (only on FSP-less) */
@@ -1483,7 +1483,7 @@ void __noreturn __secondary_cpu_entry(void)
 	/* Some XIVE setup */
 	if (proc_gen == proc_gen_p9)
 		xive_cpu_callin(cpu);
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		xive2_cpu_callin(cpu);
 
 	/* Wait for work to do */
diff --git a/core/mce.c b/core/mce.c
index 47674abcb2..2c9915cc29 100644
--- a/core/mce.c
+++ b/core/mce.c
@@ -301,7 +301,7 @@ void decode_mce(uint64_t srr0, uint64_t srr1,
 
 	if (proc_gen == proc_gen_p9) {
 		decode_mce_p9(srr0, srr1, dsisr, dar, type, error_str, address);
-	} else if (proc_gen == proc_gen_p10) {
+	} else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		decode_mce_p10(srr0, srr1, dsisr, dar, type, error_str, address);
 	} else {
 		*error_str = "unknown error (processor not supported)";
diff --git a/hdata/fsp.c b/hdata/fsp.c
index 66b351b42d..b3629ef43b 100644
--- a/hdata/fsp.c
+++ b/hdata/fsp.c
@@ -371,7 +371,7 @@ static void bmc_create_node(const struct HDIF_common_hdr *sp)
 	dt_add_property_cells(bmc_node, "#size-cells", 0);
 
 	/* Add sensor info under /bmc */
-	if (proc_gen < proc_gen_p10)
+	if (proc_gen < proc_gen_p11)
 		add_ipmi_sensors(bmc_node);
 
 	sp_impl = HDIF_get_idata(sp, SPSS_IDATA_SP_IMPL, &size);
diff --git a/hdata/i2c.c b/hdata/i2c.c
index 235aae8a86..dfe5f5afc4 100644
--- a/hdata/i2c.c
+++ b/hdata/i2c.c
@@ -251,7 +251,7 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
 	 * This code makes a few assumptions about XSCOM addrs, etc
 	 * and will need updating for new processors
 	 */
-	assert(proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10);
+	assert(proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11);
 
 	/*
 	 * Emit an error if we get a newer version. This is an interim measure
@@ -303,7 +303,8 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
 		 * i2cm@<addr> nodes.
 		 */
 		if (dev->i2cm_engine >= 4 &&
-			(proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10))
+			(proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 ||
+							proc_gen == proc_gen_p11))
 			continue;
 
 		bus = p8_i2c_add_port_node(xscom, dev->i2cm_engine, dev->i2cm_port,
diff --git a/hdata/iohub.c b/hdata/iohub.c
index d1074241b6..40712bc94d 100644
--- a/hdata/iohub.c
+++ b/hdata/iohub.c
@@ -858,7 +858,8 @@ static void io_parse_fru(const void *sp_iohubs)
 		io_parse_slots(sp_iohubs, chip_id);
 	}
 
-	if (proc_gen == proc_gen_p8 || proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p8 || proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10
+		|| proc_gen == proc_gen_p11)
 		io_add_p8_cec_vpd(sp_iohubs);
 }
 
diff --git a/hdata/spira.c b/hdata/spira.c
index d9325a0b44..b008df66ce 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -277,6 +277,7 @@ static struct dt_node *add_xscom_node(uint64_t base,
 		addr = base | (((uint64_t)hw_id) << 42);
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 	default:
 		/* Use Primary topology table index for xscom address */
 		addr = base | (((uint64_t)cinfo->topology_id_table[cinfo->primary_topology_loc]) << 44);
@@ -310,6 +311,10 @@ static struct dt_node *add_xscom_node(uint64_t base,
 		dt_add_property_strings(node, "compatible",
 					"ibm,xscom", "ibm,power10-xscom");
 		break;
+	case proc_gen_p11:
+		dt_add_property_strings(node, "compatible",
+					"ibm,xscom", "ibm,power11-xscom");
+		break;
 	default:
 		dt_add_property_strings(node, "compatible", "ibm,xscom");
 	}
@@ -399,6 +404,7 @@ static void add_psihb_node(struct dt_node *np)
 		psi_comp = "ibm,power9-psihb-x";
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		psi_scom = 0x3011d00;
 		psi_slen = 0x100;
 		psi_comp = "ibm,power10-psihb-x";
@@ -432,6 +438,7 @@ static void add_xive_node(struct dt_node *np)
 		comp = "ibm,power9-xive-x";
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		scom = 0x2010800;
 		slen = 0x400;
 		comp = "ibm,power10-xive-x";
@@ -745,6 +752,9 @@ static void add_chiptod_node(unsigned int chip_id, int flags)
 	case proc_gen_p10:
 		compat_str = "ibm,power10-chiptod";
 		break;
+	case proc_gen_p11:
+		compat_str = "ibm,power11-chiptod";
+		break;
 	default:
 		return;
 	}
@@ -856,6 +866,7 @@ static void add_nx_node(u32 gcid)
 		break;
 	case proc_gen_p9:
 	case proc_gen_p10:
+	case proc_gen_p11:
 		/* POWER9 NX is not software compatible with P8 NX */
 		dt_add_property_strings(nx, "compatible", "ibm,power9-nx");
 		break;
@@ -903,7 +914,7 @@ static void add_nmmu(void)
 	if (proc_gen < proc_gen_p9)
 		return;
 
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		scom1 = 0x2010c40;
 		scom2 = 0x3010c40;
 	} else
@@ -918,7 +929,7 @@ static void add_nmmu(void)
 		 * P10 has a second nMMU, a.k.a "south" nMMU.
 		 * It exists only on P1 and P3
 		 */
-		if (proc_gen == proc_gen_p10) {
+		if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 
 			chip_id = __dt_get_chip_id(xscom);
 			if (chip_id != 2 && chip_id != 6)
diff --git a/hw/chiptod.c b/hw/chiptod.c
index e3941e296d..5159cde311 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -1026,7 +1026,7 @@ static void fixup_tod_reg_value(struct chiptod_tod_regs *treg_entry)
 {
 	int32_t chip_id = this_cpu()->chip_id;
 
-	if (proc_gen != proc_gen_p10)
+	if (proc_gen != proc_gen_p10 && proc_gen != proc_gen_p11)
 		return;
 
 	if (treg_entry->xscom_addr == TOD_SLAVE_PATH_CTRL)
@@ -1719,6 +1719,8 @@ static bool chiptod_probe(void)
 				chiptod_type = chiptod_p9;
 			if (dt_node_is_compatible(np, "ibm,power10-chiptod"))
 				chiptod_type = chiptod_p10;
+			if (dt_node_is_compatible(np, "ibm,power11-chiptod"))
+				chiptod_type = chiptod_p10;
 		}
 
 		if (dt_has_node_property(np, "secondary", NULL))
diff --git a/hw/fsp/fsp-occ.c b/hw/fsp/fsp-occ.c
index 58926f4088..a0fe57bff9 100644
--- a/hw/fsp/fsp-occ.c
+++ b/hw/fsp/fsp-occ.c
@@ -317,6 +317,7 @@ static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id)
 		break;
 	case proc_gen_p9:
 	case proc_gen_p10:
+	case proc_gen_p11:
 		last_seq_id = seq_id;
 		chip = next_chip(NULL);
 		prd_fsp_occ_reset(chip->id);
diff --git a/hw/fsp/fsp-psi.c b/hw/fsp/fsp-psi.c
index 38f130dd79..ce37ca53d1 100644
--- a/hw/fsp/fsp-psi.c
+++ b/hw/fsp/fsp-psi.c
@@ -38,6 +38,7 @@ void psi_init_for_fsp(struct psi *psi)
 	case proc_gen_p8:
 	case proc_gen_p9:
 	case proc_gen_p10:
+	case proc_gen_p11:
 		out_be64(psi->regs + PSIHB_TAR, PSI_TCE_TABLE_BASE |
 			 PSIHB_TAR_256K_ENTRIES);
 		break;
diff --git a/hw/homer.c b/hw/homer.c
index 3ff6ed1ae9..fc5f4fb490 100644
--- a/hw/homer.c
+++ b/hw/homer.c
@@ -201,6 +201,7 @@ void homer_init(void)
 		bar_occ_common = P9_BAR_OCC_COMMON;
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		pba_bar0 = P10_PBA_BAR0;
 		pba_barmask0 = P10_PBA_BARMASK0;
 		bar_homer = P10_BAR_HOMER;
diff --git a/hw/imc.c b/hw/imc.c
index a794cc28f6..4ab2b51b06 100644
--- a/hw/imc.c
+++ b/hw/imc.c
@@ -481,7 +481,7 @@ static void disable_unavailable_units(struct dt_node *dev)
 				dt_free(target);
 			}
 		}
-	} else if (proc_gen == proc_gen_p10) {
+	} else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		int val;
 		char name[8];
 
@@ -761,6 +761,7 @@ static int setup_imc_scoms(void)
 						IMC_TRACE_BUFF_SIZE);
 		return 0;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		CORE_IMC_EVENT_MASK_ADDR = CORE_IMC_EVENT_MASK_ADDR_P10;
 		TRACE_IMC_ADDR = TRACE_IMC_ADDR_P10;
 		pdbar_scom_index = pdbar_scom_index_p10;
@@ -933,6 +934,7 @@ static uint32_t get_imc_scom_addr_for_core(int core, uint64_t addr)
 		scom_addr = XSCOM_ADDR_P9_EC(core, addr);
 		return scom_addr;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		scom_addr = XSCOM_ADDR_P10_EC(core, addr);
 		return scom_addr;
 	default:
@@ -950,6 +952,7 @@ static uint32_t get_imc_scom_addr_for_quad(int core, uint64_t addr)
 		scom_addr = XSCOM_ADDR_P9_EQ(core, addr);
 		return scom_addr;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		scom_addr = XSCOM_ADDR_P10_EQ(core, addr);
 		return scom_addr;
 	default:
diff --git a/hw/lpc.c b/hw/lpc.c
index 398528084b..8225682b36 100644
--- a/hw/lpc.c
+++ b/hw/lpc.c
@@ -1006,7 +1006,8 @@ void lpc_finalize_interrupts(void)
 		    (chip->type == PROC_CHIP_P9_NIMBUS ||
 		     chip->type == PROC_CHIP_P9_CUMULUS ||
 		     chip->type == PROC_CHIP_P9P ||
-		     chip->type == PROC_CHIP_P10))
+		     chip->type == PROC_CHIP_P10 ||
+		     chip->type == PROC_CHIP_P11))
 			lpc_create_int_map(chip->lpc, chip->psi->node);
 	}
 }
@@ -1051,6 +1052,7 @@ static void lpc_init_interrupts_one(struct proc_chip *chip)
 	case PROC_CHIP_P9_CUMULUS:
 	case PROC_CHIP_P9P:
 	case PROC_CHIP_P10:
+	case PROC_CHIP_P11:
 		/* On P9, we additionally setup the routing. */
 		lpc->has_serirq = true;
 		for (i = 0; i < LPC_NUM_SERIRQ; i++) {
@@ -1469,7 +1471,8 @@ void lpc_register_client(uint32_t chip_id, const struct lpc_client *clt,
 		chip->type == PROC_CHIP_P9_NIMBUS ||
 		chip->type == PROC_CHIP_P9_CUMULUS ||
 		chip->type == PROC_CHIP_P9P ||
-		chip->type == PROC_CHIP_P10;
+		chip->type == PROC_CHIP_P10 ||
+		chip->type == PROC_CHIP_P11;
 
 	if (policy != IRQ_ATTR_TARGET_OPAL && !has_routes) {
 		prerror("Chip doesn't support OS interrupt policy\n");
diff --git a/hw/occ.c b/hw/occ.c
index 5161532e62..89cc4f1f6e 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -1982,6 +1982,7 @@ void occ_pstates_init(void)
 		break;
 	case proc_gen_p9:
 	case proc_gen_p10:
+	case proc_gen_p11:
 		homer_opal_data_offset = P9_HOMER_OPAL_DATA_OFFSET;
 		break;
 	default:
@@ -2044,7 +2045,7 @@ void occ_pstates_init(void)
 	} else if (proc_gen == proc_gen_p9) {
 		freq_domain_mask = P9_PIR_QUAD_MASK;
 		domain_runs_at = FREQ_MAX_IN_DOMAIN;
-	} else if (proc_gen == proc_gen_p10) {
+	} else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		freq_domain_mask = P10_PIR_CHIP_MASK;
 		domain_runs_at = FREQ_MAX_IN_DOMAIN;
 	} else {
@@ -2219,6 +2220,7 @@ void occ_send_dummy_interrupt(void)
 			    OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY);
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		xscom_write(psi->chip_id, P9_OCB_OCI_OCCMISC_OR,
 			    OCB_OCI_OCIMISC_IRQ |
 			    OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY);
diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c
index 45815858e9..4b534f68b5 100644
--- a/hw/p8-i2c.c
+++ b/hw/p8-i2c.c
@@ -1587,7 +1587,7 @@ void p8_i2c_init(void)
 	/* setup the handshake reg */
 	if (proc_gen <= proc_gen_p9)
 		occflg = 0x6C08A;
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		occflg = 0x6C0AC;
 	else
 		return;
diff --git a/hw/phb4.c b/hw/phb4.c
index 5292a923b0..60d0796294 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -147,7 +147,7 @@ static inline bool is_phb4(void)
 
 static inline bool is_phb5(void)
 {
-	return (proc_gen == proc_gen_p10);
+	return (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11);
 }
 
 /* PQ offloading on the XIVE IC. */
diff --git a/hw/phys-map.c b/hw/phys-map.c
index cfce4ab529..196a222c35 100644
--- a/hw/phys-map.c
+++ b/hw/phys-map.c
@@ -486,6 +486,9 @@ void phys_map_init(unsigned long pvr)
 	} else if (proc_gen == proc_gen_p10) {
 		name = "p10";
 		phys_map = &phys_map_p10;
+	} else if (proc_gen == proc_gen_p11) {
+		name = "p11";
+		phys_map = &phys_map_p10;
 	}
 
 	prlog(PR_DEBUG, "Assigning physical memory map table for %s\n", name);
diff --git a/hw/prd.c b/hw/prd.c
index 45d765457f..51bf836906 100644
--- a/hw/prd.c
+++ b/hw/prd.c
@@ -741,6 +741,7 @@ void prd_init(void)
 		prd_ipoll_mask = PRD_P9_IPOLL_MASK;
 		break;
 	case proc_gen_p10: /* IPOLL regs are the same for p9 and p10 */
+	case proc_gen_p11: /* IPOLL regs are the same for p9 and p10/11 */
 		prd_ipoll_mask_reg = PRD_P9_IPOLL_REG_MASK;
 		prd_ipoll_status_reg = PRD_P9_IPOLL_REG_STATUS;
 		prd_ipoll_mask = PRD_P9_IPOLL_MASK;
diff --git a/hw/psi.c b/hw/psi.c
index 23b2061b90..50c12e94d3 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -266,7 +266,7 @@ static void psi_spurious_fsp_irq(struct psi *psi)
 
 	prlog(PR_NOTICE, "PSI: Spurious interrupt, attempting clear\n");
 
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		reg = PSIHB_XSCOM_P10_HBCSR_CLR;
 		bit = PSIHB_XSCOM_P10_HBSCR_FSP_IRQ;
 	} else if (proc_gen == proc_gen_p9) {
@@ -569,6 +569,7 @@ static void psi_p9_mask_unhandled_irq(struct irq_source *is, uint32_t isn)
 		xive_source_mask(is, isn);
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		xive2_source_mask(is, isn);
 		return;
 	default:
@@ -854,6 +855,7 @@ static void psi_init_interrupts(struct psi *psi)
 		psi_init_p9_interrupts(psi);
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		psi_init_p10_interrupts(psi);
 		break;
 	default:
@@ -934,6 +936,7 @@ static void psi_create_mm_dtnode(struct psi *psi)
 		break;
 	case proc_gen_p9:
 	case proc_gen_p10:
+	case proc_gen_p11:
 		dt_add_property_strings(np, "compatible", "ibm,psi",
 					"ibm,power9-psi");
 		psi_create_p9_int_map(psi, np);
@@ -1039,6 +1042,8 @@ static bool psi_init_psihb(struct dt_node *psihb)
 		psi = psi_probe_p9(chip, base);
 	else if (dt_node_is_compatible(psihb, "ibm,power10-psihb-x"))
 		psi = psi_probe_p10(chip, base);
+	else if (dt_node_is_compatible(psihb, "ibm,power11-psihb-x"))
+		psi = psi_probe_p10(chip, base);
 	else {
 		prerror("PSI: Unknown processor type\n");
 		return false;
diff --git a/hw/sbe.c b/hw/sbe.c
index 56927bf600..21e0f3aeb5 100644
--- a/hw/sbe.c
+++ b/hw/sbe.c
@@ -19,7 +19,7 @@ void sbe_update_timer_expiry(uint64_t target)
 {
 	assert(sbe_has_timer);
 
-	if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p9 || proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		p9_sbe_update_timer_expiry(target);
 
 #ifdef CONFIG_P8
diff --git a/hw/slw.c b/hw/slw.c
index 67b9422efb..feb98dd860 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -621,7 +621,7 @@ void add_cpu_idle_state_properties(void)
 				states = power9_cpu_idle_states;
 				nr_states = ARRAY_SIZE(power9_cpu_idle_states);
 			}
-		} else if (chip->type == PROC_CHIP_P10) {
+		} else if (chip->type == PROC_CHIP_P10 || chip->type == PROC_CHIP_P11) {
 			states = power10_cpu_idle_states;
 			nr_states = ARRAY_SIZE(power10_cpu_idle_states);
 		} else {
@@ -652,7 +652,8 @@ void add_cpu_idle_state_properties(void)
 					slw_late_init_p9(chip);
 					xive_late_init();
 					nx_p9_rng_late_init();
-				} else if (chip->type == PROC_CHIP_P10) {
+				} else if (chip->type == PROC_CHIP_P10 ||
+					   chip->type == PROC_CHIP_P11) {
 					slw_late_init_p10(chip);
 					xive2_late_init();
 				}
@@ -935,7 +936,7 @@ void slw_init(void)
 			if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT)
 				slw_late_init_p9(chip);
 		}
-	} else if (proc_gen == proc_gen_p10) {
+	} else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		for_each_chip(chip) {
 			slw_init_chip_p10(chip);
 			if(slw_image_check_p9(chip))
diff --git a/hw/vas.c b/hw/vas.c
index aa3ae3348b..592f7b1cb7 100644
--- a/hw/vas.c
+++ b/hw/vas.c
@@ -615,7 +615,7 @@ void vas_init(void)
 
 	if (proc_gen == proc_gen_p9)
 		compat = "ibm,power9-vas-x";
-	else if (proc_gen == proc_gen_p10)
+	else if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		compat = "ibm,power10-vas-x";
 	else
 		return;
diff --git a/hw/xive2.c b/hw/xive2.c
index d20e3c5ea4..45115666fa 100644
--- a/hw/xive2.c
+++ b/hw/xive2.c
@@ -2760,11 +2760,11 @@ static void xive_set_quirks(struct xive *x, struct proc_chip *chip __unused)
 	uint64_t quirks = 0;
 
 	/* This extension is dropped for P10 */
-	if (proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		quirks |= XIVE_QUIRK_THREADID_7BITS;
 
 	/* Broken check on invalid priority when reduced priorities is in use */
-	if (proc_gen == proc_gen_p10)
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 		quirks |= XIVE_QUIRK_BROKEN_PRIO_CHECK;
 
 	xive_dbg(x, "setting XIVE quirks to %016llx\n", quirks);
diff --git a/hw/xscom.c b/hw/xscom.c
index 285f7df129..2c0733df8a 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -94,7 +94,7 @@ static void xscom_reset(uint32_t gcid, bool need_delay)
 	mtspr(SPR_HMER, HMER_CLR_MASK);
 
 	/* Setup local and target scom addresses */
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		recv_status_reg = 0x00090018;
 		log_reg = 0x0090012;
 		err_reg = 0x0090013;
@@ -825,7 +825,7 @@ int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id)
 	 * something up
 	 */
 	if (chip_quirk(QUIRK_NO_F000F)) {
-		if (proc_gen == proc_gen_p10)
+		if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11)
 			val = 0x220DA04980000000UL; /* P10 DD2.0 */
 		else if (proc_gen == proc_gen_p9)
 			val = 0x203D104980000000UL; /* P9 Nimbus DD2.3 */
@@ -841,11 +841,26 @@ int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id)
 	return rc;
 }
 
+static inline int8_t get_proc_gen_num(void)
+{
+	switch (proc_gen) {
+	case proc_gen_p9:
+		return 9;
+	case proc_gen_p10:
+		return 10;
+	case proc_gen_p11:
+		return 11;
+	default:
+		return -1;
+	}
+}
+
 /* The recipe comes from the p10_getecid hardware procedure */
 static uint8_t xscom_get_ec_rev(struct proc_chip *chip)
 {
 	uint64_t ecid2 = 0;
 	int8_t rev;
+	int8_t proc_gen_num;
 	const int8_t *table;
 	/*                             0   1   2   3   4   5   6   7 */
 	const int8_t p9table[8] =     {0,  1, -1,  2, -1, -1, -1,  3};
@@ -860,6 +875,7 @@ static uint8_t xscom_get_ec_rev(struct proc_chip *chip)
 		table = p9table;
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		if (chip->ec_level < 0x20)
 			table = p10dd1table;
 		else
@@ -875,11 +891,13 @@ static uint8_t xscom_get_ec_rev(struct proc_chip *chip)
 	if (rev < 0)
 		return 0;
 
-	prlog(PR_INFO, "P%d DD%i.%i%d detected\n",
-			proc_gen == proc_gen_p9 ? 9 : 10,
-			0xf & (chip->ec_level >> 4),
-			chip->ec_level & 0xf,
-			rev);
+	proc_gen_num = get_proc_gen_num();
+	if (proc_gen_num < 0)
+		prlog(PR_INFO, "Unknown Power processor detected\n");
+	else
+		prlog(PR_INFO, "P%d DD%i.%i%d detected\n", proc_gen_num,
+				0xf & (chip->ec_level >> 4),
+				chip->ec_level & 0xf, rev);
 
 	return rev;
 }
@@ -923,8 +941,12 @@ static void xscom_init_chip_info(struct proc_chip *chip)
 		assert(proc_gen == proc_gen_p9);
 		break;
 	case 0xda:
-		chip->type = PROC_CHIP_P10;
-		assert(proc_gen == proc_gen_p10);
+		/* CFAM chip id for p10 and p11 is same. */
+		assert(proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11);
+		if (proc_gen == proc_gen_p10)
+			chip->type = PROC_CHIP_P10;
+		else
+			chip->type = PROC_CHIP_P11;
 		break;
 	default:
 		printf("CHIP: Unknown chip type 0x%02x !!!\n",
@@ -975,7 +997,7 @@ void xscom_init(void)
 		const char *chip_name;
 		static const char *chip_names[] = {
 			"UNKNOWN", "P8E", "P8", "P8NVL", "P9N", "P9C", "P9P",
-			"P10",
+			"P10", "P11",
 		};
 
 		chip = get_chip(gcid);
diff --git a/include/chip.h b/include/chip.h
index 92e0265459..0ada720f50 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -172,6 +172,7 @@ enum proc_chip_type {
 	PROC_CHIP_P9_CUMULUS,
 	PROC_CHIP_P9P,
 	PROC_CHIP_P10,
+	PROC_CHIP_P11,
 };
 
 /* Simulator quirks */
diff --git a/include/phb4.h b/include/phb4.h
index 29864d28e7..b3eb042f05 100644
--- a/include/phb4.h
+++ b/include/phb4.h
@@ -252,7 +252,7 @@ static inline void phb4_set_err_pending(struct phb4 *p, bool pending)
 
 static inline int phb4_get_opal_id(unsigned int chip_id, unsigned int index)
 {
-	if (proc_gen == proc_gen_p10) {
+	if (proc_gen == proc_gen_p10 || proc_gen == proc_gen_p11) {
 		return chip_id * MAX_PHBS_PER_CHIP_P10 + index;
 	} else {
 		if (PVR_TYPE(mfspr(SPR_PVR)) == PVR_TYPE_P9)
diff --git a/include/processor.h b/include/processor.h
index 5e5bd9a531..1c913fe7d4 100644
--- a/include/processor.h
+++ b/include/processor.h
@@ -211,6 +211,7 @@
 #define PVR_TYPE_P9	0x004e
 #define PVR_TYPE_P9P	0x004f /* Axone */
 #define PVR_TYPE_P10	0x0080
+#define PVR_TYPE_P11	0x0082
 
 #ifdef __ASSEMBLY__
 
@@ -269,6 +270,11 @@ static inline bool is_fused_core(uint32_t version)
 			return false;
 		else
 			return true;
+	} else if (PVR_TYPE(version) == PVR_TYPE_P11) {
+		if (PVR_CHIP_TYPE(version) & 0x01)
+			return false;
+		else
+			return true;
 	} else
 		return false;
 }
diff --git a/include/skiboot.h b/include/skiboot.h
index 88857f8f92..3c6d37d6de 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -101,6 +101,7 @@ enum proc_gen {
 	proc_gen_p8,
 	proc_gen_p9,
 	proc_gen_p10,
+	proc_gen_p11,
 };
 extern enum proc_gen proc_gen;
 
diff --git a/platforms/ibm-fsp/hostservices.c b/platforms/ibm-fsp/hostservices.c
index 1aab668d04..c552a2608e 100644
--- a/platforms/ibm-fsp/hostservices.c
+++ b/platforms/ibm-fsp/hostservices.c
@@ -639,6 +639,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
 		i_core <<= 2;
 		break;
 	case proc_gen_p10:
+	case proc_gen_p11:
 		i_core &= SPR_PIR_P10_MASK;
 		i_core <<= 2;
 		break;
-- 
2.48.1



More information about the Skiboot mailing list