marvell: drivers: Add L3/system cache management drivers
authorKonstantin Porotchkin <[email protected]>
Mon, 26 Feb 2018 14:04:25 +0000 (16:04 +0200)
committerKonstantin Porotchkin <[email protected]>
Wed, 18 Jul 2018 15:48:30 +0000 (18:48 +0300)
Add LLC (L3) cache management drivers for Marvell SoCs
AP806, AP807 and AP810

Change-Id: Ic70710f9bc5b6b48395d62212df7011e2fbb5894
Signed-off-by: Hanna Hawa <[email protected]>
Signed-off-by: Konstantin Porotchkin <[email protected]>
drivers/marvell/cache_llc.c [new file with mode: 0644]
include/drivers/marvell/cache_llc.h [new file with mode: 0644]

diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c
new file mode 100644 (file)
index 0000000..e13e6ce
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* LLC driver is the Last Level Cache (L3C) driver
+ * for Marvell SoCs in AP806, AP807, and AP810
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <cache_llc.h>
+#include <ccu.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+
+#define CCU_HTC_CR(ap_index)           (MVEBU_CCU_BASE(ap_index) + 0x200)
+#define CCU_SET_POC_OFFSET             5
+
+extern void ca72_l2_enable_unique_clean(void);
+
+void llc_cache_sync(int ap_index)
+{
+       mmio_write_32(LLC_SYNC(ap_index), 0);
+       /* Atomic write, no need to wait */
+}
+
+void llc_flush_all(int ap_index)
+{
+       mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK);
+       llc_cache_sync(ap_index);
+}
+
+void llc_clean_all(int ap_index)
+{
+       mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK);
+       llc_cache_sync(ap_index);
+}
+
+void llc_inv_all(int ap_index)
+{
+       mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK);
+       llc_cache_sync(ap_index);
+}
+
+void llc_disable(int ap_index)
+{
+       llc_flush_all(ap_index);
+       mmio_write_32(LLC_CTRL(ap_index), 0);
+       dsbishst();
+}
+
+void llc_enable(int ap_index, int excl_mode)
+{
+       uint32_t val;
+
+       dsbsy();
+       llc_inv_all(ap_index);
+       dsbsy();
+
+       val = LLC_CTRL_EN;
+       if (excl_mode)
+               val |= LLC_EXCLUSIVE_EN;
+
+       mmio_write_32(LLC_CTRL(ap_index), val);
+       dsbsy();
+}
+
+int llc_is_exclusive(int ap_index)
+{
+       uint32_t reg;
+
+       reg = mmio_read_32(LLC_CTRL(ap_index));
+
+       if ((reg & (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) ==
+                  (LLC_CTRL_EN | LLC_EXCLUSIVE_EN))
+               return 1;
+
+       return 0;
+}
+
+void llc_runtime_enable(int ap_index)
+{
+       uint32_t reg;
+
+       reg = mmio_read_32(LLC_CTRL(ap_index));
+       if (reg & LLC_CTRL_EN)
+               return;
+
+       INFO("Enabling LLC\n");
+
+       /*
+        * Enable L2 UniqueClean evictions with data
+        *  Note: this configuration assumes that LLC is configured
+        *        in exclusive mode.
+        *        Later on in the code this assumption will be validated
+        */
+       ca72_l2_enable_unique_clean();
+       llc_enable(ap_index, 1);
+
+       /* Set point of coherency to DDR.
+        * This is required by units which have SW cache coherency
+        */
+       reg = mmio_read_32(CCU_HTC_CR(ap_index));
+       reg |= (0x1 << CCU_SET_POC_OFFSET);
+       mmio_write_32(CCU_HTC_CR(ap_index), reg);
+}
diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h
new file mode 100644 (file)
index 0000000..9e41793
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* LLC driver is the Last Level Cache (L3C) driver
+ * for Marvell SoCs in AP806, AP807, and AP810
+ */
+
+#ifndef _CACHE_LLC_H_
+#define _CACHE_LLC_H_
+
+#define LLC_CTRL(ap)                   (MVEBU_LLC_BASE(ap) + 0x100)
+#define LLC_SYNC(ap)                   (MVEBU_LLC_BASE(ap) + 0x700)
+#define L2X0_INV_WAY(ap)               (MVEBU_LLC_BASE(ap) + 0x77C)
+#define L2X0_CLEAN_WAY(ap)             (MVEBU_LLC_BASE(ap) + 0x7BC)
+#define L2X0_CLEAN_INV_WAY(ap)         (MVEBU_LLC_BASE(ap) + 0x7FC)
+#define LLC_TC0_LOCK(ap)               (MVEBU_LLC_BASE(ap) + 0x920)
+
+#define MASTER_LLC_CTRL                        LLC_CTRL(MVEBU_AP0)
+#define MASTER_L2X0_INV_WAY            L2X0_INV_WAY(MVEBU_AP0)
+#define MASTER_LLC_TC0_LOCK            LLC_TC0_LOCK(MVEBU_AP0)
+
+#define LLC_CTRL_EN                    1
+#define LLC_EXCLUSIVE_EN               0x100
+#define LLC_WAY_MASK                   0xFFFFFFFF
+
+#ifndef __ASSEMBLY__
+void llc_cache_sync(int ap_index);
+void llc_flush_all(int ap_index);
+void llc_clean_all(int ap_index);
+void llc_inv_all(int ap_index);
+void llc_disable(int ap_index);
+void llc_enable(int ap_index, int excl_mode);
+int llc_is_exclusive(int ap_index);
+void llc_runtime_enable(int ap_index);
+#endif
+
+#endif /* _CACHE_LLC_H_ */
+