arm64: versal: Add new Kconfig SYS_MEM_RSVD_FOR_MMU
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Tue, 8 Jan 2019 16:17:26 +0000 (21:47 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 14 Feb 2019 13:31:09 +0000 (14:31 +0100)
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>
arch/arm/mach-versal/Kconfig
arch/arm/mach-versal/Makefile
arch/arm/mach-versal/cpu.c
arch/arm/mach-versal/include/mach/hardware.h
arch/arm/mach-versal/include/mach/sys_proto.h
arch/arm/mach-versal/mp.c [new file with mode: 0644]

index 9cee97b..f291800 100644 (file)
@@ -41,4 +41,11 @@ config VERSAL_OF_BOARD_DTB_ADDR
        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
index c230239..ca12e29 100644 (file)
@@ -6,3 +6,4 @@
 
 obj-y  += clk.o
 obj-y  += cpu.o
+obj-$(CONFIG_SYS_MEM_RSVD_FOR_MMU)     += mp.o
index 1fd3c24..70c1908 100644 (file)
@@ -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 @@ u64 get_page_table_size(void)
        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)
 {
index aad7426..23fbc3d 100644 (file)
 #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 @@ struct iou_scntrs_regs {
 };
 
 #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)
index 677facb..1dc7bf6 100644 (file)
@@ -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 (file)
index 0000000..4b434b0
--- /dev/null
@@ -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);
+}