aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/npu-opal.c35
-rw-r--r--hw/npu2-opencapi.c18
-rw-r--r--hw/pau.c93
-rw-r--r--hw/phys-map.c7
-rw-r--r--include/npu2.h3
-rw-r--r--include/pau-regs.h8
-rw-r--r--include/pau.h4
7 files changed, 152 insertions, 16 deletions
diff --git a/hw/npu-opal.c b/hw/npu-opal.c
index 2e455dc..1b66857 100644
--- a/hw/npu-opal.c
+++ b/hw/npu-opal.c
@@ -239,3 +239,38 @@ static int64_t opal_npu_tl_set(uint64_t phb_id, uint32_t bdfn,
return OPAL_PARAMETER;
}
opal_call(OPAL_NPU_TL_SET, opal_npu_tl_set, 5);
+
+static int64_t opal_npu_mem_alloc(uint64_t phb_id, uint32_t bdfn,
+ uint64_t size, uint64_t *bar)
+{
+ struct phb *phb = pci_get_phb(phb_id);
+
+ if (!phb)
+ return OPAL_PARAMETER;
+
+ if (phb->phb_type == phb_type_npu_v2_opencapi)
+ return npu2_opencapi_mem_alloc(phb, bdfn, size, bar);
+
+ if (phb->phb_type == phb_type_pau_opencapi)
+ return pau_opencapi_mem_alloc(phb, bdfn, size, bar);
+
+ return OPAL_PARAMETER;
+}
+opal_call(OPAL_NPU_MEM_ALLOC, opal_npu_mem_alloc, 4);
+
+static int64_t opal_npu_mem_release(uint64_t phb_id, uint32_t bdfn)
+{
+ struct phb *phb = pci_get_phb(phb_id);;
+
+ if (!phb)
+ return OPAL_PARAMETER;
+
+ if (phb->phb_type == phb_type_npu_v2_opencapi)
+ return npu2_opencapi_mem_release(phb, bdfn);
+
+ if (phb->phb_type == phb_type_pau_opencapi)
+ return pau_opencapi_mem_release(phb, bdfn);
+
+ return OPAL_PARAMETER;
+}
+opal_call(OPAL_NPU_MEM_RELEASE, opal_npu_mem_release, 2);
diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c
index 272f924..8e7bcca 100644
--- a/hw/npu2-opencapi.c
+++ b/hw/npu2-opencapi.c
@@ -2295,18 +2295,13 @@ out:
return rc;
}
-static int64_t opal_npu_mem_alloc(uint64_t phb_id, uint32_t __unused bdfn,
- uint64_t size, __be64 *__bar)
+int64_t npu2_opencapi_mem_alloc(struct phb *phb, uint32_t __unused bdfn,
+ uint64_t size, uint64_t *__bar)
{
- struct phb *phb = pci_get_phb(phb_id);
struct npu2_dev *dev;
uint64_t bar;
int64_t rc;
-
- if (!phb || phb->phb_type != phb_type_npu_v2_opencapi)
- return OPAL_PARAMETER;
-
dev = phb_to_npu2_dev_ocapi(phb);
if (!dev)
return OPAL_PARAMETER;
@@ -2320,21 +2315,14 @@ static int64_t opal_npu_mem_alloc(uint64_t phb_id, uint32_t __unused bdfn,
return rc;
}
-opal_call(OPAL_NPU_MEM_ALLOC, opal_npu_mem_alloc, 4);
-static int64_t opal_npu_mem_release(uint64_t phb_id, uint32_t __unused bdfn)
+int64_t npu2_opencapi_mem_release(struct phb *phb, uint32_t __unused bdfn)
{
- struct phb *phb = pci_get_phb(phb_id);
struct npu2_dev *dev;
-
- if (!phb || phb->phb_type != phb_type_npu_v2_opencapi)
- return OPAL_PARAMETER;
-
dev = phb_to_npu2_dev_ocapi(phb);
if (!dev)
return OPAL_PARAMETER;
return release_mem_bar(dev);
}
-opal_call(OPAL_NPU_MEM_RELEASE, opal_npu_mem_release, 2);
diff --git a/hw/pau.c b/hw/pau.c
index 9f6a709..a34d6da 100644
--- a/hw/pau.c
+++ b/hw/pau.c
@@ -442,6 +442,99 @@ int64_t pau_opencapi_tl_set(struct phb *phb, uint32_t __unused bdfn,
return OPAL_SUCCESS;
}
+static int64_t pau_opencapi_afu_memory_bars(struct pau_dev *dev,
+ uint64_t size,
+ uint64_t *bar)
+{
+ struct pau *pau = dev->pau;
+ uint64_t addr, psize;
+ uint64_t reg, val;
+
+ PAUDEVDBG(dev, "Setup AFU Memory BARs\n");
+
+ if (dev->memory_bar.enable) {
+ PAUDEVERR(dev, "AFU memory allocation failed - BAR already in use\n");
+ return OPAL_RESOURCE;
+ }
+
+ phys_map_get(pau->chip_id, OCAPI_MEM,
+ dev->index,
+ &addr, &psize);
+
+ if (size > psize) {
+ PAUDEVERR(dev, "Invalid AFU memory BAR allocation size "
+ "requested: 0x%llx bytes (limit 0x%llx)\n",
+ size, psize);
+ return OPAL_PARAMETER;
+ }
+
+ if (size < (1 << 30))
+ size = 1 << 30;
+
+ dev->memory_bar.enable = true;
+ dev->memory_bar.addr = addr;
+ dev->memory_bar.size = size;
+
+ reg = PAU_GPU_MEM_BAR(dev->index);
+ val = PAU_GPU_MEM_BAR_ENABLE |
+ PAU_GPU_MEM_BAR_POISON;
+ val = SETFIELD(PAU_GPU_MEM_BAR_ADDR, val, addr >> 30);
+ if (!is_pow2(size))
+ size = 1ull << (ilog2(size) + 1);
+
+ size = (size >> 30) - 1;
+ val = SETFIELD(PAU_GPU_MEM_BAR_SIZE, val, size);
+ pau_write(pau, reg, val);
+
+ reg = PAU_CTL_MISC_GPU_MEM_BAR(dev->index);
+ pau_write(pau, reg, val);
+
+ reg = PAU_XSL_GPU_MEM_BAR(dev->index);
+ pau_write(pau, reg, val);
+
+ *bar = addr;
+ return OPAL_SUCCESS;
+}
+
+int64_t pau_opencapi_mem_alloc(struct phb *phb, uint32_t __unused bdfn,
+ uint64_t size, uint64_t *bar)
+{
+ struct pau_dev *dev = pau_phb_to_opencapi_dev(phb);
+ int64_t rc;
+
+ if (!dev)
+ return OPAL_PARAMETER;
+
+ if (!opal_addr_valid(bar))
+ return OPAL_PARAMETER;
+
+ lock(&dev->pau->lock);
+ rc = pau_opencapi_afu_memory_bars(dev, size, bar);
+
+ unlock(&dev->pau->lock);
+ return rc;
+}
+
+int64_t pau_opencapi_mem_release(struct phb *phb, uint32_t __unused bdfn)
+{
+ struct pau_dev *dev = pau_phb_to_opencapi_dev(phb);
+
+ if (!dev)
+ return OPAL_PARAMETER;
+
+ lock(&dev->pau->lock);
+ pau_write(dev->pau, PAU_GPU_MEM_BAR(dev->index), 0ull);
+ pau_write(dev->pau, PAU_CTL_MISC_GPU_MEM_BAR(dev->index), 0ull);
+ pau_write(dev->pau, PAU_XSL_GPU_MEM_BAR(dev->index), 0ull);
+
+ dev->memory_bar.enable = false;
+ dev->memory_bar.addr = 0ull;
+ dev->memory_bar.size = 0ull;
+ unlock(&dev->pau->lock);
+
+ return OPAL_SUCCESS;
+}
+
#define CQ_CTL_STATUS_TIMEOUT 10 /* milliseconds */
static int pau_opencapi_set_fence_control(struct pau_dev *dev,
diff --git a/hw/phys-map.c b/hw/phys-map.c
index 711d626..cfce4ab 100644
--- a/hw/phys-map.c
+++ b/hw/phys-map.c
@@ -30,7 +30,12 @@ static const struct phys_map_entry phys_map_table_p10[] = {
/* System memory upto 4TB minus GPU memory */
{ SYSTEM_MEM, 0, 0x0000000000000000ull, 0x0000034000000000ull },
- /* TODO: Figure out GPU memory */
+ /* Configure OpenCapi memory as before with the old chips.
+ * Keep in mind that we would need to rework this by allocating
+ * a new topology id.
+ */
+ { OCAPI_MEM, 0, 0x0002000000000000ull, 0x0000040000000000ull },
+ { OCAPI_MEM, 1, 0x0002040000000000ull, 0x0000040000000000ull },
/* 0 TB offset @ MMIO 0x0006000000000000ull */
{ PHB5_64BIT_MMIO, 0, 0x0006000000000000ull, 0x0000004000000000ull },
diff --git a/include/npu2.h b/include/npu2.h
index a12bf98..b302108 100644
--- a/include/npu2.h
+++ b/include/npu2.h
@@ -277,5 +277,8 @@ int64_t npu2_opencapi_spa_clear_cache(struct phb *phb, uint32_t __unused bdfn,
uint64_t PE_handle);
int64_t npu2_opencapi_tl_set(struct phb *phb, uint32_t __unused bdfn,
long capabilities, char *rate);
+int64_t npu2_opencapi_mem_alloc(struct phb *phb, uint32_t __unused bdfn,
+ uint64_t size, uint64_t *bar);
+int64_t npu2_opencapi_mem_release(struct phb *phb, uint32_t __unused bdfn);
#endif /* __NPU2_H */
diff --git a/include/pau-regs.h b/include/pau-regs.h
index da83ad4..45c3603 100644
--- a/include/pau-regs.h
+++ b/include/pau-regs.h
@@ -64,6 +64,12 @@
#define PAU_SNP_MISC_CFG0_ENABLE_PBUS PPC_BIT(2)
#define PAU_SNP_MISC_CFG0_OCAPI_MODE PPC_BITMASK(32, 36)
#define PAU_SNP_MISC_CFG0_OCAPI_C2 PPC_BITMASK(45, 49)
+#define PAU_GPU_MEM_BAR(brk) (PAU_BLOCK_CQ_SM(0) + 0x190 + (brk) * 8)
+#define PAU_GPU_MEM_BAR_ENABLE PPC_BIT(0)
+#define PAU_GPU_MEM_BAR_ADDR_MASK PPC_BITMASK(1, 35)
+#define PAU_GPU_MEM_BAR_ADDR PPC_BITMASK(1, 21)
+#define PAU_GPU_MEM_BAR_SIZE PPC_BITMASK(22, 35)
+#define PAU_GPU_MEM_BAR_POISON PPC_BIT(45)
#define PAU_NTL_BAR(brk) (PAU_BLOCK_CQ_SM(0) + 0x1b8 + (brk) * 8)
#define PAU_NTL_BAR_ENABLE PPC_BIT(0)
#define PAU_NTL_BAR_ADDR PPC_BITMASK(3, 35)
@@ -88,6 +94,7 @@
#define PAU_CTL_MISC_CFG2_OCAPI_MEM_OS_BIT PPC_BITMASK(25, 29)
#define PAU_CTL_MISC_STATUS(brk) (PAU_BLOCK_CQ_CTL + 0x060 + (brk) * 8)
#define PAU_CTL_MISC_STATUS_AM_FENCED(brk) (PPC_BITMASK(41, 42) << ((brk)*32))
+#define PAU_CTL_MISC_GPU_MEM_BAR(brk) (PAU_BLOCK_CQ_CTL + 0x070 + (brk) * 8)
#define PAU_CTL_MISC_MMIOPA_CONFIG(brk) (PAU_BLOCK_CQ_CTL + 0x098 + (brk) * 8)
#define PAU_CTL_MISC_MMIOPA_CONFIG_BAR_ADDR PPC_BITMASK(1, 35)
#define PAU_CTL_MISC_MMIOPA_CONFIG_BAR_SIZE PPC_BITMASK(39, 43)
@@ -159,6 +166,7 @@
/* XSL block registers */
#define PAU_XSL_OSL_SPAP_AN(brk) (PAU_BLOCK_XSL + 0x000 + (brk) * 8)
#define PAU_XSL_OSL_SPAP_AN_EN PPC_BIT(63)
+#define PAU_XSL_GPU_MEM_BAR(brk) (PAU_BLOCK_XSL + 0x0D0 + (brk) * 8)
#define PAU_XSL_WRAP_CFG (PAU_BLOCK_XSL + 0x100)
#define PAU_XSL_WRAP_CFG_CLOCK_ENABLE PPC_BIT(0)
#define PAU_XSL_OSL_XLATE_CFG(brk) (PAU_BLOCK_XSL + 0x040 + (brk) * 8)
diff --git a/include/pau.h b/include/pau.h
index a70058f..4a6087c 100644
--- a/include/pau.h
+++ b/include/pau.h
@@ -45,6 +45,7 @@ struct pau_dev {
struct pau_bar ntl_bar;
struct pau_bar genid_bar;
+ struct pau_bar memory_bar;
/* Associated I2C information */
uint8_t i2c_bus_id;
@@ -209,6 +210,9 @@ int64_t pau_opencapi_spa_clear_cache(struct phb *phb,
uint64_t PE_handle);
int64_t pau_opencapi_tl_set(struct phb *phb, uint32_t __unused bdfn,
long capabilities, char *rate_buf);
+int64_t pau_opencapi_mem_alloc(struct phb *phb, uint32_t __unused bdfn,
+ uint64_t size, uint64_t *bar);
+int64_t pau_opencapi_mem_release(struct phb *phb, uint32_t __unused bdfn);
/* PHY */
int pau_dev_phy_reset(struct pau_dev *dev);