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>
This commit is contained in:
Siva Durga Prasad Paladugu 2019-01-08 21:47:26 +05:30 committed by Michal Simek
parent 6c8788f228
commit 4244f2b7e8
6 changed files with 161 additions and 3 deletions

View 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

View File

@ -6,3 +6,4 @@
obj-y += clk.o
obj-y += cpu.o
obj-$(CONFIG_SYS_MEM_RSVD_FOR_MMU) += mp.o

View 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)
{

View File

@ -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 @@ 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)

View File

@ -3,4 +3,9 @@
* Copyright 2016 - 2018 Xilinx, Inc.
*/
/* Empty file - for compilation */
enum {
TCM_LOCK,
TCM_SPLIT,
};
void tcm_init(u8 mode);

111
arch/arm/mach-versal/mp.c Normal file
View File

@ -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);
}