aboutsummaryrefslogtreecommitdiff
path: root/include/pau.h
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.vnet.ibm.com>2021-10-14 17:56:53 +0200
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2021-10-19 12:26:01 +0530
commit8baea29fdeaa5eab26c1ca6e3b88e18a3387be96 (patch)
tree47cc663b979d4efa98ea7481e498d0dd74326c06 /include/pau.h
parentfaea2419754c0a455b6cf32a5fa58c72fa75083b (diff)
downloadskiboot-8baea29fdeaa5eab26c1ca6e3b88e18a3387be96.zip
skiboot-8baea29fdeaa5eab26c1ca6e3b88e18a3387be96.tar.gz
skiboot-8baea29fdeaa5eab26c1ca6e3b88e18a3387be96.tar.bz2
pau: assign bars
Configure early PAU Global MMIO BAR registers to allow PAU MMIO register accesses. This is done for each PAU. Enable the Powerbus interface is mandatory for MMIO accesses. For each OpenCAPI device, configure the bar registers to access to the AFU MMIO and to the AFU Config Addr/Data registers. AFU Config/Data registers = GENID_ADDR (from phy_map file) + 320K (= 0x50000) Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Reviewed-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'include/pau.h')
-rw-r--r--include/pau.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/include/pau.h b/include/pau.h
index e946e0f..be8ed26 100644
--- a/include/pau.h
+++ b/include/pau.h
@@ -19,11 +19,21 @@ enum pau_dev_type {
PAU_DEV_TYPE_ANY = INT_MAX
};
+/* Used to expose a hardware BAR (or logical slice of it) outside skiboot */
+struct pau_bar {
+ uint64_t addr;
+ uint64_t size;
+ uint64_t cfg;
+};
+
struct pau_dev {
enum pau_dev_type type;
uint32_t index;
struct dt_node *dn;
+ struct pau_bar ntl_bar;
+ struct pau_bar genid_bar;
+
/* Associated I2C information */
uint8_t i2c_bus_id;
@@ -44,6 +54,7 @@ struct pau {
/* Global MMIO window (all PAU regs) */
uint64_t regs[2];
+ bool mmio_access;
struct lock lock;
@@ -94,4 +105,72 @@ static inline int pau_get_phb_index(unsigned int pau_index,
return PAU_PHB_INDEX_BASE + pau_index * 2 + link_index;
}
+/*
+ * We use the indirect method because it uses the same addresses as
+ * the MMIO offsets (PAU RING)
+ */
+static inline void pau_scom_sel(struct pau *pau, uint64_t reg,
+ uint64_t size)
+{
+ uint64_t val;
+
+ val = SETFIELD(PAU_MISC_DA_ADDR, 0ull, reg);
+ val = SETFIELD(PAU_MISC_DA_LEN, val, size);
+ xscom_write(pau->chip_id,
+ pau->xscom_base + PAU_MISC_SCOM_IND_SCOM_ADDR,
+ val);
+}
+
+static inline void pau_scom_write(struct pau *pau, uint64_t reg,
+ uint64_t size,
+ uint64_t val)
+{
+ pau_scom_sel(pau, reg, size);
+ xscom_write(pau->chip_id,
+ pau->xscom_base + PAU_MISC_SCOM_IND_SCOM_DATA,
+ val);
+}
+
+static inline uint64_t pau_scom_read(struct pau *pau, uint64_t reg,
+ uint64_t size)
+{
+ uint64_t val;
+
+ pau_scom_sel(pau, reg, size);
+ xscom_read(pau->chip_id,
+ pau->xscom_base + PAU_MISC_SCOM_IND_SCOM_DATA,
+ &val);
+
+ return val;
+}
+
+static inline void pau_write(struct pau *pau, uint64_t reg,
+ uint64_t val)
+{
+ void *mmio = (void *)pau->regs[0];
+
+ if (pau->mmio_access)
+ out_be64(mmio + reg, val);
+ else
+ pau_scom_write(pau, reg, PAU_MISC_DA_LEN_8B, val);
+
+ /* CQ_SM writes should be mirrored in all four blocks */
+ if (PAU_REG_BLOCK(reg) != PAU_BLOCK_CQ_SM(0))
+ return;
+
+ for (uint32_t i = 1; i < 4; i++)
+ pau_write(pau, PAU_BLOCK_CQ_SM(i) + PAU_REG_OFFSET(reg),
+ val);
+}
+
+static inline uint64_t pau_read(struct pau *pau, uint64_t reg)
+{
+ void *mmio = (void *)pau->regs[0];
+
+ if (pau->mmio_access)
+ return in_be64(mmio + reg);
+
+ return pau_scom_read(pau, reg, PAU_MISC_DA_LEN_8B);
+}
+
#endif /* __PAU_H */