aboutsummaryrefslogtreecommitdiff
path: root/hw/centaur.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-06-23 14:25:53 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-07-06 17:06:54 +1000
commit1576ba971a28578a67c71b78df130110a10cd2f7 (patch)
tree585ca01c60afbc4ce4fb06e3343547c26f8d1ac2 /hw/centaur.c
parentf4d57b7bfbcc731e917de12e6a3dd1b8a1d941b4 (diff)
downloadskiboot-1576ba971a28578a67c71b78df130110a10cd2f7.zip
skiboot-1576ba971a28578a67c71b78df130110a10cd2f7.tar.gz
skiboot-1576ba971a28578a67c71b78df130110a10cd2f7.tar.bz2
centaur: Add API to enable/disable the sensor cache
The i2c driver will need to use them to avoid conflicts between i2c accesses initiated by the host and by the sensor cache. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/centaur.c')
-rw-r--r--hw/centaur.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/hw/centaur.c b/hw/centaur.c
index 6504e92..24d2836 100644
--- a/hw/centaur.c
+++ b/hw/centaur.c
@@ -21,6 +21,7 @@
#include <centaur.h>
#include <lock.h>
#include <fsi-master.h>
+#include <timebase.h>
/*
* Centaur chip IDs are using the XSCOM "partID" encoding
@@ -52,6 +53,12 @@
#define FSI_STATUS_ABORT 0x00100000
#define FSI_STATUS_ERRORS 0x00007000
+/* Some Centaur XSCOMs we care about */
+#define SCAC_CONFIG_REG 0x020115ce
+#define SCAC_CONFIG_SET 0x020115cf
+#define SCAC_CONFIG_CLR 0x020115d0
+#define SCAC_ENABLE_MSK PPC_BIT(0)
+
static int64_t centaur_fsiscom_complete(struct centaur_chip *centaur)
{
int64_t rc;
@@ -296,6 +303,58 @@ static bool centaur_add(uint32_t part_id, uint32_t mchip, uint32_t meng,
return true;
}
+/* Returns how long to wait for logic to stop in TB ticks or a negative
+ * value on error
+ */
+int64_t centaur_disable_sensor_cache(uint32_t part_id)
+{
+ struct centaur_chip *centaur = get_centaur(part_id);
+ int64_t rc = 0;
+ uint64_t ctrl;
+
+ if (!centaur)
+ return false;
+
+ lock(&centaur->lock);
+ centaur->scache_disable_count++;
+ if (centaur->scache_disable_count == 1) {
+ centaur->scache_was_enabled = false;
+ rc = centaur_fsiscom_read(centaur, SCAC_CONFIG_REG, &ctrl);
+ if (rc)
+ goto bail;
+ centaur->scache_was_enabled = !!(ctrl & SCAC_ENABLE_MSK);
+ rc = centaur_fsiscom_write(centaur, SCAC_CONFIG_CLR, SCAC_ENABLE_MSK);
+ if (rc)
+ goto bail;
+ rc = msecs_to_tb(30);
+ }
+ bail:
+ unlock(&centaur->lock);
+ return rc;
+}
+
+int64_t centaur_enable_sensor_cache(uint32_t part_id)
+{
+ struct centaur_chip *centaur = get_centaur(part_id);
+ int64_t rc = 0;
+
+ if (!centaur)
+ return false;
+
+ lock(&centaur->lock);
+ if (centaur->scache_disable_count == 0) {
+ prerror("CENTAUR: Cache count going negative !\n");
+ backtrace();
+ goto bail;
+ }
+ centaur->scache_disable_count--;
+ if (centaur->scache_disable_count == 0 && centaur->scache_was_enabled)
+ rc = centaur_fsiscom_write(centaur, SCAC_CONFIG_SET, SCAC_ENABLE_MSK);
+ bail:
+ unlock(&centaur->lock);
+ return rc;
+}
+
void centaur_init(void)
{
struct dt_node *cn;