[Skiboot] [PATCH 02/13] hw/npu2: Merge implementations of BAR accessor functions
Andrew Donnellan
andrew.donnellan at au1.ibm.com
Wed Dec 12 17:58:45 AEDT 2018
Move npu2_{get,read,write}_bar() to common code. Get rid of the OpenCAPI
write_bar() function. Fix the OpenCAPI code to use the NVLink-style BAR
accessor functions and struct npu2_bar.
While we're there, fix a trivial bug in npu2_read_bar() when reading PHY
BARs - the global MMIO BAR is stack 0, not stack 2. I don't think we ever
read that BAR, so this has never been a problem.
Signed-off-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
---
hw/npu2-common.c | 77 ++++++++++++++++++++++++++++++++-
hw/npu2-opencapi.c | 109 ++++++++++++++++------------------------------
hw/npu2.c | 78 +---------------------------------
include/npu2.h | 4 ++-
4 files changed, 120 insertions(+), 148 deletions(-)
diff --git a/hw/npu2-common.c b/hw/npu2-common.c
index 6e6b12f0d1ae..3446acb45bea 100644
--- a/hw/npu2-common.c
+++ b/hw/npu2-common.c
@@ -22,6 +22,7 @@
#include <bitutils.h>
#include <nvram.h>
#include <i2c.h>
+#include <phys-map.h>
/*
* We use the indirect method because it uses the same addresses as
@@ -97,6 +98,82 @@ void npu2_write_mask_4b(struct npu2 *p, uint64_t reg, uint32_t val, uint32_t mas
(uint64_t)new_val << 32);
}
+void npu2_get_bar(uint32_t gcid, struct npu2_bar *bar)
+{
+ phys_map_get(gcid, bar->type, bar->index, &bar->base, &bar->size);
+}
+
+void npu2_read_bar(struct npu2 *p, struct npu2_bar *bar)
+{
+ uint64_t reg, val;
+
+ reg = NPU2_REG_OFFSET(0, NPU2_BLOCK_SM_0, bar->reg);
+ val = npu2_read(p, reg);
+
+ switch (NPU2_REG(bar->reg)) {
+ case NPU2_PHY_BAR:
+ bar->base = GETFIELD(NPU2_PHY_BAR_ADDR, val) << 21;
+ bar->enabled = GETFIELD(NPU2_PHY_BAR_ENABLE, val);
+
+ if (NPU2_REG_STACK(reg) == NPU2_STACK_STCK_0)
+ /* This is the global MMIO BAR */
+ bar->size = 0x1000000;
+ else
+ bar->size = 0x200000;
+ break;
+ case NPU2_NTL0_BAR:
+ case NPU2_NTL1_BAR:
+ bar->base = GETFIELD(NPU2_NTL_BAR_ADDR, val) << 16;
+ bar->enabled = GETFIELD(NPU2_NTL_BAR_ENABLE, val);
+ bar->size = 0x10000 << GETFIELD(NPU2_NTL_BAR_SIZE, val);
+ break;
+ case NPU2_GENID_BAR:
+ bar->base = GETFIELD(NPU2_GENID_BAR_ADDR, val) << 16;
+ bar->enabled = GETFIELD(NPU2_GENID_BAR_ENABLE, val);
+ bar->size = 0x20000;
+ break;
+ default:
+ bar->base = 0ul;
+ bar->enabled = false;
+ bar->size = 0;
+ break;
+ }
+}
+
+void npu2_write_bar(struct npu2 *p, struct npu2_bar *bar, uint32_t gcid,
+ uint32_t scom)
+{
+ uint64_t reg, val;
+ int block;
+
+ switch (NPU2_REG(bar->reg)) {
+ case NPU2_PHY_BAR:
+ val = SETFIELD(NPU2_PHY_BAR_ADDR, 0ul, bar->base >> 21);
+ val = SETFIELD(NPU2_PHY_BAR_ENABLE, val, bar->enabled);
+ break;
+ case NPU2_NTL0_BAR:
+ case NPU2_NTL1_BAR:
+ val = SETFIELD(NPU2_NTL_BAR_ADDR, 0ul, bar->base >> 16);
+ val = SETFIELD(NPU2_NTL_BAR_ENABLE, val, bar->enabled);
+ val = SETFIELD(NPU2_NTL_BAR_SIZE, val, ilog2(bar->size >> 16));
+ break;
+ case NPU2_GENID_BAR:
+ val = SETFIELD(NPU2_GENID_BAR_ADDR, 0ul, bar->base >> 16);
+ val = SETFIELD(NPU2_GENID_BAR_ENABLE, val, bar->enabled);
+ break;
+ default:
+ val = 0ul;
+ }
+
+ for (block = NPU2_BLOCK_SM_0; block <= NPU2_BLOCK_SM_3; block++) {
+ reg = NPU2_REG_OFFSET(0, block, bar->reg);
+ if (p)
+ npu2_write(p, reg, val);
+ else
+ npu2_scom_write(gcid, scom, reg, NPU2_MISC_DA_LEN_8B, val);
+ }
+}
+
static bool _i2c_presence_detect(struct npu2_dev *dev)
{
uint8_t state, data;
diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c
index b160a41741b9..88e4eb1974a2 100644
--- a/hw/npu2-opencapi.c
+++ b/hw/npu2-opencapi.c
@@ -730,63 +730,29 @@ static void address_translation_config(uint32_t gcid, uint32_t scom_base,
}
}
-/* TODO: Merge this with NVLink implementation - we don't use the npu2_bar
- * wrapper for the PHY BARs yet */
-static void write_bar(uint32_t gcid, uint32_t scom_base, uint64_t reg,
- uint64_t addr, uint64_t size)
-{
- uint64_t val;
- int block;
- switch (NPU2_REG(reg)) {
- case NPU2_PHY_BAR:
- val = SETFIELD(NPU2_PHY_BAR_ADDR, 0ul, addr >> 21);
- val = SETFIELD(NPU2_PHY_BAR_ENABLE, val, 1);
- break;
- case NPU2_NTL0_BAR:
- case NPU2_NTL1_BAR:
- val = SETFIELD(NPU2_NTL_BAR_ADDR, 0ul, addr >> 16);
- val = SETFIELD(NPU2_NTL_BAR_SIZE, val, ilog2(size >> 16));
- val = SETFIELD(NPU2_NTL_BAR_ENABLE, val, 1);
- break;
- case NPU2_GENID_BAR:
- val = SETFIELD(NPU2_GENID_BAR_ADDR, 0ul, addr >> 16);
- val = SETFIELD(NPU2_GENID_BAR_ENABLE, val, 1);
- break;
- default:
- val = 0ul;
- }
-
- for (block = NPU2_BLOCK_SM_0; block <= NPU2_BLOCK_SM_3; block++) {
- npu2_scom_write(gcid, scom_base, NPU2_REG_OFFSET(0, block, reg),
- NPU2_MISC_DA_LEN_8B, val);
- prlog(PR_DEBUG, "OCAPI: Setting BAR %llx to %llx\n",
- NPU2_REG_OFFSET(0, block, reg), val);
- }
-}
-
static void setup_global_mmio_bar(uint32_t gcid, uint32_t scom_base,
uint64_t reg[])
{
- uint64_t addr, size;
-
- prlog(PR_DEBUG, "OCAPI: patching up PHY0 bar, %s\n", __func__);
- phys_map_get(gcid, NPU_PHY, 0, &addr, &size);
- write_bar(gcid, scom_base,
- NPU2_REG_OFFSET(NPU2_STACK_STCK_2, 0, NPU2_PHY_BAR),
- addr, size);
- prlog(PR_DEBUG, "OCAPI: patching up PHY1 bar, %s\n", __func__);
- phys_map_get(gcid, NPU_PHY, 1, &addr, &size);
- write_bar(gcid, scom_base,
- NPU2_REG_OFFSET(NPU2_STACK_STCK_1, 0, NPU2_PHY_BAR),
- addr, size);
-
- prlog(PR_DEBUG, "OCAPI: setup global mmio, %s\n", __func__);
- phys_map_get(gcid, NPU_REGS, 0, &addr, &size);
- write_bar(gcid, scom_base,
- NPU2_REG_OFFSET(NPU2_STACK_STCK_0, 0, NPU2_PHY_BAR),
- addr, size);
- reg[0] = addr;
- reg[1] = size;
+ struct npu2_bar *bar;
+ struct npu2_bar phy_bars[] = {
+ { .type = NPU_PHY, .index = 0,
+ .reg = NPU2_REG_OFFSET(NPU2_STACK_STCK_2, 0, NPU2_PHY_BAR),
+ .enabled = true },
+ { .type = NPU_PHY, .index = 1,
+ .reg = NPU2_REG_OFFSET(NPU2_STACK_STCK_1, 0, NPU2_PHY_BAR),
+ .enabled = true },
+ { .type = NPU_REGS, .index = 0,
+ .reg = NPU2_REG_OFFSET(NPU2_STACK_STCK_0, 0, NPU2_PHY_BAR),
+ .enabled = true },
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(phy_bars); i++) {
+ bar = &phy_bars[i];
+ npu2_get_bar(gcid, bar);
+ npu2_write_bar(NULL, bar, gcid, scom_base);
+ }
+ reg[0] = phy_bars[2].base;
+ reg[1] = phy_bars[2].size;
}
/* Procedure 13.1.3.8 - AFU MMIO Range BARs */
@@ -803,15 +769,18 @@ static void setup_afu_mmio_bars(uint32_t gcid, uint32_t scom_base,
prlog(PR_DEBUG, "OCAPI: %s: Setup AFU MMIO BARs\n", __func__);
phys_map_get(gcid, NPU_OCAPI_MMIO, dev->brick_index, &addr, &size);
-
- prlog(PR_DEBUG, "OCAPI: AFU MMIO set to %llx, size %llx\n", addr, size);
- write_bar(gcid, scom_base, NPU2_REG_OFFSET(stack, 0, offset), addr,
- size);
- dev->bars[0].base = addr;
- dev->bars[0].size = size;
-
- reg = SETFIELD(NPU2_CQ_CTL_MISC_MMIOPA_ADDR, 0ull, addr >> 16);
- reg = SETFIELD(NPU2_CQ_CTL_MISC_MMIOPA_SIZE, reg, ilog2(size >> 16));
+ dev->bars[0].type = NPU_OCAPI_MMIO;
+ dev->bars[0].index = dev->brick_index;
+ dev->bars[0].reg = NPU2_REG_OFFSET(stack, 0, offset);
+ dev->bars[0].enabled = true;
+ npu2_get_bar(gcid, &dev->bars[0]);
+
+ prlog(PR_DEBUG, "OCAPI: AFU MMIO set to %llx, size %llx\n",
+ dev->bars[0].base, dev->bars[0].size);
+ npu2_write_bar(NULL, &dev->bars[0], gcid, scom_base);
+
+ reg = SETFIELD(NPU2_CQ_CTL_MISC_MMIOPA_ADDR, 0ull, dev->bars[0].base >> 16);
+ reg = SETFIELD(NPU2_CQ_CTL_MISC_MMIOPA_SIZE, reg, ilog2(dev->bars[0].size >> 16));
prlog(PR_DEBUG, "OCAPI: PA translation %llx\n", reg);
npu2_scom_write(gcid, scom_base,
NPU2_REG_OFFSET(stack, NPU2_BLOCK_CTL,
@@ -825,15 +794,15 @@ static void setup_afu_config_bars(uint32_t gcid, uint32_t scom_base,
{
uint64_t stack = index_to_stack(dev->brick_index);
int stack_num = stack - NPU2_STACK_STCK_0;
- uint64_t addr, size;
prlog(PR_DEBUG, "OCAPI: %s: Setup AFU Config BARs\n", __func__);
- phys_map_get(gcid, NPU_GENID, stack_num, &addr, &size);
- prlog(PR_DEBUG, "OCAPI: Assigning GENID BAR: %016llx\n", addr);
- write_bar(gcid, scom_base, NPU2_REG_OFFSET(stack, 0, NPU2_GENID_BAR),
- addr, size);
- dev->bars[1].base = addr;
- dev->bars[1].size = size;
+ dev->bars[1].type = NPU_GENID;
+ dev->bars[1].index = stack_num;
+ dev->bars[1].reg = NPU2_REG_OFFSET(stack, 0, NPU2_GENID_BAR);
+ dev->bars[1].enabled = true;
+ npu2_get_bar(gcid, &dev->bars[1]);
+ prlog(PR_DEBUG, "OCAPI: Assigning GENID BAR: %016llx\n", dev->bars[1].base);
+ npu2_write_bar(NULL, &dev->bars[1], gcid, scom_base);
}
static void otl_enabletx(uint32_t gcid, uint32_t scom_base,
diff --git a/hw/npu2.c b/hw/npu2.c
index ba5575cf3097..6b0880682427 100644
--- a/hw/npu2.c
+++ b/hw/npu2.c
@@ -106,84 +106,6 @@ static struct npu2_dev *npu2_bdf_to_dev(struct npu2 *p,
return NULL;
}
-static inline void npu2_get_bar(uint32_t gcid, struct npu2_bar *bar)
-{
- phys_map_get(gcid, bar->type, bar->index, &bar->base, &bar->size);
-}
-
-static void npu2_read_bar(struct npu2 *p, struct npu2_bar *bar)
-{
- uint64_t reg, val;
-
- reg = NPU2_REG_OFFSET(0, NPU2_BLOCK_SM_0, bar->reg);
- val = npu2_read(p, reg);
-
- switch (NPU2_REG(bar->reg)) {
- case NPU2_PHY_BAR:
- bar->base = GETFIELD(NPU2_PHY_BAR_ADDR, val) << 21;
- bar->enabled = GETFIELD(NPU2_PHY_BAR_ENABLE, val);
-
- if (NPU2_REG_STACK(reg) == NPU2_STACK_STCK_2)
- /* This is the global MMIO BAR */
- bar->size = 0x1000000;
- else
- bar->size = 0x200000;
- break;
- case NPU2_NTL0_BAR:
- case NPU2_NTL1_BAR:
- bar->base = GETFIELD(NPU2_NTL_BAR_ADDR, val) << 16;
- bar->enabled = GETFIELD(NPU2_NTL_BAR_ENABLE, val);
- bar->size = 0x10000 << GETFIELD(NPU2_NTL_BAR_SIZE, val);
- break;
- case NPU2_GENID_BAR:
- bar->base = GETFIELD(NPU2_GENID_BAR_ADDR, val) << 16;
- bar->enabled = GETFIELD(NPU2_GENID_BAR_ENABLE, val);
- bar->size = 0x20000;
- break;
- default:
- bar->base = 0ul;
- bar->enabled = false;
- bar->size = 0;
- break;
- }
-}
-
-static void npu2_write_bar(struct npu2 *p,
- struct npu2_bar *bar,
- uint32_t gcid,
- uint32_t scom)
-{
- uint64_t reg, val;
- int block;
-
- switch (NPU2_REG(bar->reg)) {
- case NPU2_PHY_BAR:
- val = SETFIELD(NPU2_PHY_BAR_ADDR, 0ul, bar->base >> 21);
- val = SETFIELD(NPU2_PHY_BAR_ENABLE, val, bar->enabled);
- break;
- case NPU2_NTL0_BAR:
- case NPU2_NTL1_BAR:
- val = SETFIELD(NPU2_NTL_BAR_ADDR, 0ul, bar->base >> 16);
- val = SETFIELD(NPU2_NTL_BAR_ENABLE, val, bar->enabled);
- val = SETFIELD(NPU2_NTL_BAR_SIZE, val, 1);
- break;
- case NPU2_GENID_BAR:
- val = SETFIELD(NPU2_GENID_BAR_ADDR, 0ul, bar->base >> 16);
- val = SETFIELD(NPU2_GENID_BAR_ENABLE, val, bar->enabled);
- break;
- default:
- val = 0ul;
- }
-
- for (block = NPU2_BLOCK_SM_0; block <= NPU2_BLOCK_SM_3; block++) {
- reg = NPU2_REG_OFFSET(0, block, bar->reg);
- if (p)
- npu2_write(p, reg, val);
- else
- npu2_scom_write(gcid, scom, reg, NPU2_MISC_DA_LEN_8B, val);
- }
-}
-
/* Trap for PCI command (0x4) to enable or disable device's BARs */
static int64_t npu2_cfg_write_cmd(void *dev,
struct pci_cfg_reg_filter *pcrf __unused,
diff --git a/include/npu2.h b/include/npu2.h
index da5a5597feb0..c5c5b43843c3 100644
--- a/include/npu2.h
+++ b/include/npu2.h
@@ -210,6 +210,10 @@ void npu2_write(struct npu2 *p, uint64_t reg, uint64_t val);
uint64_t npu2_read(struct npu2 *p, uint64_t reg);
void npu2_write_mask(struct npu2 *p, uint64_t reg, uint64_t val, uint64_t mask);
void npu2_write_mask_4b(struct npu2 *p, uint64_t reg, uint32_t val, uint32_t mask);
+void npu2_get_bar(uint32_t gcid, struct npu2_bar *bar);
+void npu2_read_bar(struct npu2 *p, struct npu2_bar *bar);
+void npu2_write_bar(struct npu2 *p, struct npu2_bar *bar, uint32_t gcid,
+ uint32_t scom);
int64_t npu2_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf,
uint32_t offset, uint32_t len, uint32_t *data,
bool write);
--
git-series 0.9.1
More information about the Skiboot
mailing list