@@ -577,6 +577,21 @@ int _xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val, bool take_loc
}
opal_call(OPAL_XSCOM_WRITE, xscom_write, 3);
+/*
+ * Perform a xscom read-modify-write.
+ */
+int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask)
+{
+ int rc;
+ uint64_t old_val;
+
+ rc = xscom_read(partid, pcb_addr, &old_val);
+ if (rc)
+ return rc;
+ val = (old_val & ~mask) | (val & mask);
+ return xscom_write(partid, pcb_addr, val);
+}
+
int xscom_readme(uint64_t pcb_addr, uint64_t *val)
{
return xscom_read(this_cpu()->chip_id, pcb_addr, val);
@@ -230,7 +230,7 @@ static inline int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val)
static inline int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) {
return _xscom_write(partid, pcb_addr, val, true);
}
-
+extern int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask);
/* This chip SCOM access */
extern int xscom_readme(uint64_t pcb_addr, uint64_t *val);
It is common for xscom registers to only contain specific bit fields that need to be modified without altering the rest of the register. This adds a convenience function to perform xscom read-modify-write operations under a mask. Signed-off-by: Alistair Popple <alistair@popple.id.au> --- hw/xscom.c | 15 +++++++++++++++ include/xscom.h | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-)