
On Thu, Sep 12, 2019 at 12:12 PM Ley Foon Tan ley.foon.tan@intel.com wrote:
Add Cache Coherency Unit (CCU) support for Agilex. CCU is to ensures consistency of shared data between multi masters in the system.
Wouldn't this better fit into drivers/cache instead of adding yet more arch code?
Regards, Simon
Software need to initialize CCU's directories and coherency agent interfaces in CCU IP.
Signed-off-by: Ley Foon Tan ley.foon.tan@intel.com Reviewed-by: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com
arch/arm/mach-socfpga/Makefile | 3 + arch/arm/mach-socfpga/ccu_agilex.c | 99 +++++++++++++++++++ .../mach-socfpga/include/mach/ccu_agilex.h | 67 +++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 arch/arm/mach-socfpga/ccu_agilex.c create mode 100644 arch/arm/mach-socfpga/include/mach/ccu_agilex.h
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index a403b46b47..6f39dc06ed 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -58,6 +58,9 @@ ifdef CONFIG_TARGET_SOCFPGA_STRATIX10 obj-y += firewall.o obj-y += spl_s10.o endif +ifdef CONFIG_TARGET_SOCFPGA_AGILEX +obj-y += ccu_agilex.o +endif endif
ifdef CONFIG_TARGET_SOCFPGA_GEN5 diff --git a/arch/arm/mach-socfpga/ccu_agilex.c b/arch/arm/mach-socfpga/ccu_agilex.c new file mode 100644 index 0000000000..f27a48b523 --- /dev/null +++ b/arch/arm/mach-socfpga/ccu_agilex.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2019 Intel Corporation <www.intel.com>
- */
+#include <asm/io.h> +#include <wait_bit.h> +#include <asm/arch/ccu_agilex.h>
+static void ccu_init_dirs(void) +{
ulong i, f;
int ret;
u32 num_of_dirs;
u32 num_of_snoop_filters;
u32 reg;
num_of_dirs = CSUIDR_NUMDIRUS_GET(readl(CCU_REG_ADDR(CSUIDR)));
num_of_snoop_filters =
CSIDR_NUMSFS_GET(readl(CCU_REG_ADDR(CSIDR))) + 1;
/* Initialize each snoop filter in each directory */
for (f = 0; f < num_of_snoop_filters; f++) {
reg = f << DIRUSFMCR_SFID_SHIFT;
for (i = 0; i < num_of_dirs; i++) {
/* Initialize all entries */
writel(reg, CCU_DIR_REG_ADDR(i, DIRUSFMCR));
/* Poll snoop filter maintenance operation active
* bit become 0.
*/
ret = wait_for_bit_le32((const void *)
CCU_DIR_REG_ADDR(i, DIRUSFMAR),
BIT(0), false, 1000, false);
if (ret) {
puts("CCU: Directory initialization failed!\n");
hang();
}
/* Enable snoop filter, a bit per snoop filter */
setbits_le32((ulong)CCU_DIR_REG_ADDR(i, DIRUSFER),
BIT(f));
}
}
+}
+void ccu_init_coh_agent_intf(void) +{
u32 num_of_coh_agent_intf;
u32 num_of_dirs;
u32 reg;
u32 type;
u32 i, dir;
num_of_coh_agent_intf =
CSUIDR_NUMCAIUS_GET(readl(CCU_REG_ADDR(CSUIDR)));
num_of_dirs = CSUIDR_NUMDIRUS_GET(readl(CCU_REG_ADDR(CSUIDR)));
for (i = 0; i < num_of_coh_agent_intf; i++) {
reg = readl((ulong)CCU_CAIU_REG_ADDR(i, CAIUIDR));
if (CAIUIDR_CA_GET(reg)) {
/* Caching agent bit is enabled, enable caching agent
* snoop in each directory
*/
for (dir = 0; dir < num_of_dirs; dir++) {
setbits_le32((ulong)
CCU_DIR_REG_ADDR(dir, DIRUCASER0),
BIT(i));
}
}
type = CAIUIDR_TYPE_GET(reg);
if (type == CAIUIDR_TYPE_ACE_CAI_DVM_SUPPORT ||
type == CAIUIDR_TYPE_ACELITE_CAI_DVM_SUPPORT) {
/* DVM support is enabled, enable ACE DVM snoop*/
setbits_le32((ulong)(CCU_REG_ADDR(CSADSER0)),
BIT(i));
}
}
+}
+static void ocram_bypass_firewall(void) +{
clrbits_le32((ulong)(COH_CPU0_BYPASS_REG_ADDR(OCRAM_BLK_CGF_01_REG)),
OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
clrbits_le32((ulong)(COH_CPU0_BYPASS_REG_ADDR(OCRAM_BLK_CGF_02_REG)),
OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
clrbits_le32((ulong)(COH_CPU0_BYPASS_REG_ADDR(OCRAM_BLK_CGF_03_REG)),
OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
clrbits_le32((ulong)(COH_CPU0_BYPASS_REG_ADDR(OCRAM_BLK_CGF_04_REG)),
OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
+}
+void ccu_init(void) +{
ccu_init_dirs();
ccu_init_coh_agent_intf();
ocram_bypass_firewall();
+} diff --git a/arch/arm/mach-socfpga/include/mach/ccu_agilex.h b/arch/arm/mach-socfpga/include/mach/ccu_agilex.h new file mode 100644 index 0000000000..4e5373e0ad --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/ccu_agilex.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- Copyright (C) 2019 Intel Corporation <www.intel.com>
- */
+#ifndef _CCU_AGILEX_H_ +#define _CCU_AGILEX_H_
+/* Directory */ +#define DIRUSFER 0x80010 +#define DIRUCASER0 0x80040 +#define DIRUMRHER 0x80070 +#define DIRUSFMCR 0x80080 +#define DIRUSFMAR 0x80084
+#define DIRUSFMCR_SFID_SHIFT 16
+/* Coherent cache agent interface */ +#define CAIUIDR 0x00ffc
+#define CAIUIDR_CA_GET(v) (((v) & 0x00008000) >> 15) +#define CAIUIDR_TYPE_GET(v) (((v) & 0x000f0000) >> 16) +#define CAIUIDR_TYPE_ACE_CAI_DVM_SUPPORT 0 +#define CAIUIDR_TYPE_ACELITE_CAI_DVM_SUPPORT 1
+/* Coherent subsystem */ +#define CSADSER0 0xff040 +#define CSUIDR 0xffff8 +#define CSIDR 0xffffc
+#define CSUIDR_NUMCAIUS_GET(v) (((v) & 0x0000007f) >> 0) +#define CSUIDR_NUMDIRUS_GET(v) (((v) & 0x003f0000) >> 16) +#define CSUIDR_NUMCMIUS_GET(v) (((v) & 0x3f000000) >> 24)
+#define CSIDR_NUMSFS_GET(v) (((v) & 0x007c0000) >> 18)
+#define DIR_REG_OFF 0x1000 +#define CAIU_REG_OFF 0x1000 +#define COHMEM_REG_OFF 0x1000
+#define CCU_REG_ADDR(reg) \
(SOCFPGA_CCU_ADDRESS + (reg))
+#define CCU_DIR_REG_ADDR(dir, reg) \
(CCU_REG_ADDR(reg) + ((dir) * DIR_REG_OFF))
+#define CCU_CAIU_REG_ADDR(caiu, reg) \
(CCU_REG_ADDR(reg) + ((caiu) * CAIU_REG_OFF))
+/* Coherent CPU BYPASS OCRAM */ +#define COH_CPU0_BYPASS_OC_BASE (SOCFPGA_CCU_ADDRESS + 0x100200)
+#define OCRAM_BLK_CGF_01_REG 0x4 +#define OCRAM_BLK_CGF_02_REG 0x8 +#define OCRAM_BLK_CGF_03_REG 0xc +#define OCRAM_BLK_CGF_04_REG 0x10 +#define OCRAM_SECURE_REGIONS 4
+#define OCRAM_PRIVILEGED_MASK BIT(29) +#define OCRAM_SECURE_MASK BIT(30)
+#define COH_CPU0_BYPASS_REG_ADDR(reg) \
(COH_CPU0_BYPASS_OC_BASE + (reg))
+void ccu_init(void);
+#endif /* _CCU_AGILEX_H_ */
2.19.0