aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2017-08-04 14:15:19 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-08-04 17:13:10 +1000
commite3f7d42c77bfc3b899d3d636b372e1292b790656 (patch)
tree85448dddb6c16bc11c4a48c9ddd76a9fa30e6a2a
parent1c974200eb5e9c81e841733e99848885f917b108 (diff)
downloadskiboot-e3f7d42c77bfc3b899d3d636b372e1292b790656.zip
skiboot-e3f7d42c77bfc3b899d3d636b372e1292b790656.tar.gz
skiboot-e3f7d42c77bfc3b899d3d636b372e1292b790656.tar.bz2
xscom: Add xscom_write_mask() function
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> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--hw/xscom.c15
-rw-r--r--include/xscom.h2
2 files changed, 16 insertions, 1 deletions
diff --git a/hw/xscom.c b/hw/xscom.c
index a739b3c..ea3c3fb 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -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);
diff --git a/include/xscom.h b/include/xscom.h
index 743a47b..5a5d0b9 100644
--- a/include/xscom.h
+++ b/include/xscom.h
@@ -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);