diff options
-rw-r--r-- | hw/npu-opal.c | 3 | ||||
-rw-r--r-- | hw/pau.c | 36 | ||||
-rw-r--r-- | include/pau-regs.h | 8 | ||||
-rw-r--r-- | include/pau.h | 2 |
4 files changed, 49 insertions, 0 deletions
diff --git a/hw/npu-opal.c b/hw/npu-opal.c index cf13690..2e455dc 100644 --- a/hw/npu-opal.c +++ b/hw/npu-opal.c @@ -52,6 +52,9 @@ static int64_t opal_npu_map_lpar(uint64_t phb_id, uint64_t bdf, uint64_t lparid, if (phb->phb_type == phb_type_npu_v2) return npu2_map_lpar(phb, bdf, lparid, lpcr); + if (phb->phb_type == phb_type_pau_opencapi) + return pau_opencapi_map_atsd_lpar(phb, bdf, lparid, lpcr); + return OPAL_PARAMETER; } opal_call(OPAL_NPU_MAP_LPAR, opal_npu_map_lpar, 4); @@ -268,6 +268,29 @@ static void pau_device_detect_fixup(struct pau_dev *dev) dt_add_property_strings(dn, "ibm,pau-link-type", "unknown"); } +int64_t pau_opencapi_map_atsd_lpar(struct phb *phb, uint64_t __unused bdf, + uint64_t lparid, uint64_t __unused lpcr) +{ + struct pau_dev *dev = pau_phb_to_opencapi_dev(phb); + struct pau *pau = dev->pau; + uint64_t val; + + if (lparid >= PAU_XTS_ATSD_MAX) + return OPAL_PARAMETER; + + lock(&pau->lock); + + /* We need to allocate an ATSD per link */ + val = SETFIELD(PAU_XTS_ATSD_HYP_LPARID, 0ull, lparid); + if (!lparid) + val |= PAU_XTS_ATSD_HYP_MSR_HV; + + pau_write(pau, PAU_XTS_ATSD_HYP(lparid), val); + + unlock(&pau->lock); + return OPAL_SUCCESS; +} + int64_t pau_opencapi_spa_setup(struct phb *phb, uint32_t __unused bdfn, uint64_t addr, uint64_t PE_mask) { @@ -1442,6 +1465,18 @@ static void pau_opencapi_create_phb(struct pau_dev *dev) pau_opencapi_create_phb_slot(dev); } +static void pau_dt_add_mmio_atsd(struct pau_dev *dev) +{ + struct dt_node *dn = dev->phb.dt_node; + struct pau *pau = dev->pau; + uint64_t mmio_atsd[PAU_XTS_ATSD_MAX]; + + for (uint32_t i = 0; i < PAU_XTS_ATSD_MAX; i++) + mmio_atsd[i] = pau->regs[0] + PAU_XTS_ATSD_LAUNCH(i); + + dt_add_property(dn, "ibm,mmio-atsd", mmio_atsd, sizeof(mmio_atsd)); +} + static void pau_opencapi_dt_add_mmio_window(struct pau_dev *dev) { struct dt_node *dn = dev->phb.dt_node; @@ -1508,6 +1543,7 @@ static void pau_opencapi_dt_add_props(struct pau_dev *dev) dt_add_property_cells(dn, "ibm,opal-num-pes", PAU_MAX_PE_NUM); dt_add_property_cells(dn, "ibm,opal-reserved-pe", PAU_RESERVED_PE_NUM); + pau_dt_add_mmio_atsd(dev); pau_opencapi_dt_add_mmio_window(dev); pau_opencapi_dt_add_hotpluggable(dev); } diff --git a/include/pau-regs.h b/include/pau-regs.h index 57c2d72..da83ad4 100644 --- a/include/pau-regs.h +++ b/include/pau-regs.h @@ -37,6 +37,7 @@ #define PAU_BLOCK_XSL PAU_BLOCK(4, 0xE) #define PAU_BLOCK_PAU_XTS PAU_BLOCK(7, 1) #define PAU_BLOCK_PAU_MISC PAU_BLOCK(7, 2) +#define PAU_BLOCK_PAU_XTS_ATSD(n) PAU_BLOCK(8, (n)) /* * CQ_SM block registers @@ -176,6 +177,9 @@ #define PAU_XTS_CFG2_XSL2_ENA PPC_BIT(55) #define PAU_XTS_CFG3 (PAU_BLOCK_PAU_XTS + 0x068) #define PAU_XTS_CFG3_MMIOSD_OCAPI PPC_BIT(5) +#define PAU_XTS_ATSD_HYP(n) (PAU_BLOCK_PAU_XTS + 0x100 + (n) * 8) +#define PAU_XTS_ATSD_HYP_MSR_HV PPC_BIT(51) +#define PAU_XTS_ATSD_HYP_LPARID PPC_BITMASK(52, 63) /* MISC block registers */ #define PAU_MISC_OPTICAL_IO_CONFIG (PAU_BLOCK_PAU_MISC + 0x018) @@ -204,4 +208,8 @@ #define PAU_MISC_INT_2_CONFIG_XFAULT_2_5(n) PPC_BIT(0 + (n)) #define PAU_MISC_INT_2_CONFIG_XFAULT_0_1(n) PPC_BIT(54 + (n)) +/* PAU_XTS_ATSD block registers */ +#define PAU_XTS_ATSD_LAUNCH(n) (PAU_BLOCK_PAU_XTS_ATSD(n) + 0x000) +#define PAU_XTS_ATSD_MAX 16 + #endif /* __PAU_REGS_H */ diff --git a/include/pau.h b/include/pau.h index 894007d..a70058f 100644 --- a/include/pau.h +++ b/include/pau.h @@ -200,6 +200,8 @@ static inline uint64_t pau_read(struct pau *pau, uint64_t reg) } void pau_opencapi_dump_scoms(struct pau *pau); +int64_t pau_opencapi_map_atsd_lpar(struct phb *phb, uint64_t __unused bdf, + uint64_t lparid, uint64_t __unused lpcr); int64_t pau_opencapi_spa_setup(struct phb *phb, uint32_t __unused bdfn, uint64_t addr, uint64_t PE_mask); int64_t pau_opencapi_spa_clear_cache(struct phb *phb, |