arm64: versal: Add new Kconfig SYS_MEM_RSVD_FOR_MMU
This patch adds new config option which is used for
reserving a specific memory for MMU Table and in this
case we are using TCM for that purpose.
Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
diff --git a/arch/arm/mach-versal/Kconfig b/arch/arm/mach-versal/Kconfig
index 9cee97b..f291800 100644
--- a/arch/arm/mach-versal/Kconfig
+++ b/arch/arm/mach-versal/Kconfig
@@ -41,4 +41,11 @@
default 0x1000
depends on OF_BOARD
+config SYS_MEM_RSVD_FOR_MMU
+ bool "Reserve memory for MMU Table"
+ help
+ If defined this option is used to setup different space for
+ MMU table than the one which will be allocated during
+ relocation.
+
endif
diff --git a/arch/arm/mach-versal/Makefile b/arch/arm/mach-versal/Makefile
index c230239..ca12e29 100644
--- a/arch/arm/mach-versal/Makefile
+++ b/arch/arm/mach-versal/Makefile
@@ -6,3 +6,4 @@
obj-y += clk.o
obj-y += cpu.o
+obj-$(CONFIG_SYS_MEM_RSVD_FOR_MMU) += mp.o
diff --git a/arch/arm/mach-versal/cpu.c b/arch/arm/mach-versal/cpu.c
index 1fd3c24..70c1908 100644
--- a/arch/arm/mach-versal/cpu.c
+++ b/arch/arm/mach-versal/cpu.c
@@ -7,6 +7,10 @@
#include <common.h>
#include <asm/armv8/mmu.h>
#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
static struct mm_region versal_mem_map[] = {
{
@@ -68,6 +72,17 @@
return 0x14000;
}
+#if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU)
+int reserve_mmu(void)
+{
+ tcm_init(TCM_LOCK);
+ gd->arch.tlb_size = PGTABLE_SIZE;
+ gd->arch.tlb_addr = VERSAL_TCM_BASE_ADDR;
+
+ return 0;
+}
+#endif
+
#if defined(CONFIG_OF_BOARD)
void *board_fdt_blob_setup(void)
{
diff --git a/arch/arm/mach-versal/include/mach/hardware.h b/arch/arm/mach-versal/include/mach/hardware.h
index aad7426..23fbc3d 100644
--- a/arch/arm/mach-versal/include/mach/hardware.h
+++ b/arch/arm/mach-versal/include/mach/hardware.h
@@ -11,11 +11,15 @@
#define IOU_SWITCH_CTRL_DIVISOR0_SHIFT 8
struct crlapb_regs {
- u32 reserved0[69];
+ u32 reserved0[67];
+ u32 cpu_r5_ctrl;
+ u32 reserved;
u32 iou_switch_ctrl; /* 0x114 */
u32 reserved1[13];
u32 timestamp_ref_ctrl; /* 0x14c */
- u32 reserved2[126];
+ u32 reserved3[108];
+ u32 rst_cpu_r5;
+ u32 reserved2[17];
u32 rst_timestamp; /* 0x348 */
};
@@ -32,3 +36,18 @@
};
#define iou_scntr_secure ((struct iou_scntrs_regs *)VERSAL_IOU_SCNTR_SECURE)
+
+#define VERSAL_TCM_BASE_ADDR 0xFFE00000
+#define VERSAL_TCM_SIZE 0x40000
+
+#define VERSAL_RPU_BASEADDR 0xFF9A0000
+
+struct rpu_regs {
+ u32 rpu_glbl_ctrl;
+ u32 reserved0[63];
+ u32 rpu0_cfg; /* 0x100 */
+ u32 reserved1[63];
+ u32 rpu1_cfg; /* 0x200 */
+};
+
+#define rpu_base ((struct rpu_regs *)VERSAL_RPU_BASEADDR)
diff --git a/arch/arm/mach-versal/include/mach/sys_proto.h b/arch/arm/mach-versal/include/mach/sys_proto.h
index 677facb..1dc7bf6 100644
--- a/arch/arm/mach-versal/include/mach/sys_proto.h
+++ b/arch/arm/mach-versal/include/mach/sys_proto.h
@@ -3,4 +3,9 @@
* Copyright 2016 - 2018 Xilinx, Inc.
*/
-/* Empty file - for compilation */
+enum {
+ TCM_LOCK,
+ TCM_SPLIT,
+};
+
+void tcm_init(u8 mode);
diff --git a/arch/arm/mach-versal/mp.c b/arch/arm/mach-versal/mp.c
new file mode 100644
index 0000000..4b434b0
--- /dev/null
+++ b/arch/arm/mach-versal/mp.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2019 Xilinx, Inc.
+ * Siva Durga Prasad <siva.durga.paladugu@xilinx.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define HALT 0
+#define RELEASE 1
+
+#define VERSAL_RPU_CFG_CPU_HALT_MASK 0x01
+#define VERSAL_RPU_GLBL_CTRL_SPLIT_LOCK_MASK 0x08
+#define VERSAL_RPU_GLBL_CTRL_TCM_COMB_MASK 0x40
+#define VERSAL_RPU_GLBL_CTRL_SLCLAMP_MASK 0x10
+
+#define VERSAL_CRLAPB_RST_LPD_AMBA_RST_MASK 0x04
+#define VERSAL_CRLAPB_RST_LPD_R50_RST_MASK 0x01
+#define VERSAL_CRLAPB_RST_LPD_R51_RST_MASK 0x02
+#define VERSAL_CRL_RST_CPU_R5_RESET_PGE_MASK 0x10
+#define VERSAL_CRLAPB_CPU_R5_CTRL_CLKACT_MASK 0x1000000
+
+void set_r5_halt_mode(u8 halt, u8 mode)
+{
+ u32 tmp;
+
+ tmp = readl(&rpu_base->rpu0_cfg);
+ if (halt == HALT)
+ tmp &= ~VERSAL_RPU_CFG_CPU_HALT_MASK;
+ else
+ tmp |= VERSAL_RPU_CFG_CPU_HALT_MASK;
+ writel(tmp, &rpu_base->rpu0_cfg);
+
+ if (mode == TCM_LOCK) {
+ tmp = readl(&rpu_base->rpu1_cfg);
+ if (halt == HALT)
+ tmp &= ~VERSAL_RPU_CFG_CPU_HALT_MASK;
+ else
+ tmp |= VERSAL_RPU_CFG_CPU_HALT_MASK;
+ writel(tmp, &rpu_base->rpu1_cfg);
+ }
+}
+
+void set_r5_tcm_mode(u8 mode)
+{
+ u32 tmp;
+
+ tmp = readl(&rpu_base->rpu_glbl_ctrl);
+ if (mode == TCM_LOCK) {
+ tmp &= ~VERSAL_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
+ tmp |= VERSAL_RPU_GLBL_CTRL_TCM_COMB_MASK |
+ VERSAL_RPU_GLBL_CTRL_SLCLAMP_MASK;
+ } else {
+ tmp |= VERSAL_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
+ tmp &= ~(VERSAL_RPU_GLBL_CTRL_TCM_COMB_MASK |
+ VERSAL_RPU_GLBL_CTRL_SLCLAMP_MASK);
+ }
+
+ writel(tmp, &rpu_base->rpu_glbl_ctrl);
+}
+
+void release_r5_reset(u8 mode)
+{
+ u32 tmp;
+
+ tmp = readl(&crlapb_base->rst_cpu_r5);
+ tmp &= ~(VERSAL_CRLAPB_RST_LPD_AMBA_RST_MASK |
+ VERSAL_CRLAPB_RST_LPD_R50_RST_MASK |
+ VERSAL_CRL_RST_CPU_R5_RESET_PGE_MASK);
+
+ if (mode == TCM_LOCK)
+ tmp &= ~VERSAL_CRLAPB_RST_LPD_R51_RST_MASK;
+
+ writel(tmp, &crlapb_base->rst_cpu_r5);
+}
+
+void enable_clock_r5(void)
+{
+ u32 tmp;
+
+ tmp = readl(&crlapb_base->cpu_r5_ctrl);
+ tmp |= VERSAL_CRLAPB_CPU_R5_CTRL_CLKACT_MASK;
+ writel(tmp, &crlapb_base->cpu_r5_ctrl);
+}
+
+void initialize_tcm(bool mode)
+{
+ if (!mode) {
+ set_r5_tcm_mode(TCM_LOCK);
+ set_r5_halt_mode(HALT, TCM_LOCK);
+ enable_clock_r5();
+ release_r5_reset(TCM_LOCK);
+ } else {
+ set_r5_tcm_mode(TCM_SPLIT);
+ set_r5_halt_mode(HALT, TCM_SPLIT);
+ enable_clock_r5();
+ release_r5_reset(TCM_SPLIT);
+ }
+}
+
+void tcm_init(u8 mode)
+{
+ puts("WARNING: Initializing TCM overwrites TCM content\n");
+ initialize_tcm(mode);
+ memset((void *)VERSAL_TCM_BASE_ADDR, 0, VERSAL_TCM_SIZE);
+}