diff options
author | Christophe Lombard <clombard@linux.vnet.ibm.com> | 2021-10-14 17:56:53 +0200 |
---|---|---|
committer | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2021-10-19 12:26:01 +0530 |
commit | 8baea29fdeaa5eab26c1ca6e3b88e18a3387be96 (patch) | |
tree | 47cc663b979d4efa98ea7481e498d0dd74326c06 /include/pau.h | |
parent | faea2419754c0a455b6cf32a5fa58c72fa75083b (diff) | |
download | skiboot-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.h | 79 |
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 */ |