1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2019 Xilinx, Inc.
4  * Siva Durga Prasad Paladugu <siva.durga.prasad.paladugu@amd.com>
5  */
6 
7 #include <config.h>
8 #include <linux/string.h>
9 #include <asm/io.h>
10 #include <asm/arch/hardware.h>
11 #include <asm/arch/sys_proto.h>
12 
13 #define HALT		0
14 #define RELEASE		1
15 
16 #define VERSAL_RPU_CFG_CPU_HALT_MASK		0x01
17 #define VERSAL_RPU_GLBL_CTRL_SPLIT_LOCK_MASK	0x08
18 #define VERSAL_RPU_GLBL_CTRL_TCM_COMB_MASK	0x40
19 #define VERSAL_RPU_GLBL_CTRL_SLCLAMP_MASK	0x10
20 
21 #define VERSAL_CRLAPB_RST_LPD_AMBA_RST_MASK	0x04
22 #define VERSAL_CRLAPB_RST_LPD_R50_RST_MASK	0x01
23 #define VERSAL_CRLAPB_RST_LPD_R51_RST_MASK	0x02
24 #define VERSAL_CRL_RST_CPU_R5_RESET_PGE_MASK	0x10
25 #define VERSAL_CRLAPB_CPU_R5_CTRL_CLKACT_MASK	0x1000000
26 
set_r5_halt_mode(u8 halt,enum tcm_mode mode)27 static void set_r5_halt_mode(u8 halt, enum tcm_mode mode)
28 {
29 	u32 tmp;
30 
31 	tmp = readl(&rpu_base->rpu0_cfg);
32 	if (halt == HALT)
33 		tmp &= ~VERSAL_RPU_CFG_CPU_HALT_MASK;
34 	else
35 		tmp |= VERSAL_RPU_CFG_CPU_HALT_MASK;
36 	writel(tmp, &rpu_base->rpu0_cfg);
37 
38 	if (mode == TCM_LOCK) {
39 		tmp = readl(&rpu_base->rpu1_cfg);
40 		if (halt == HALT)
41 			tmp &= ~VERSAL_RPU_CFG_CPU_HALT_MASK;
42 		else
43 			tmp |= VERSAL_RPU_CFG_CPU_HALT_MASK;
44 		writel(tmp, &rpu_base->rpu1_cfg);
45 	}
46 }
47 
set_r5_tcm_mode(enum tcm_mode mode)48 static void set_r5_tcm_mode(enum tcm_mode mode)
49 {
50 	u32 tmp;
51 
52 	tmp = readl(&rpu_base->rpu_glbl_ctrl);
53 	if (mode == TCM_LOCK) {
54 		tmp &= ~VERSAL_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
55 		tmp |= VERSAL_RPU_GLBL_CTRL_TCM_COMB_MASK |
56 		       VERSAL_RPU_GLBL_CTRL_SLCLAMP_MASK;
57 	} else {
58 		tmp |= VERSAL_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
59 		tmp &= ~(VERSAL_RPU_GLBL_CTRL_TCM_COMB_MASK |
60 		       VERSAL_RPU_GLBL_CTRL_SLCLAMP_MASK);
61 	}
62 
63 	writel(tmp, &rpu_base->rpu_glbl_ctrl);
64 }
65 
release_r5_reset(enum tcm_mode mode)66 static void release_r5_reset(enum tcm_mode mode)
67 {
68 	u32 tmp;
69 
70 	tmp = readl(&crlapb_base->rst_cpu_r5);
71 	tmp &= ~(VERSAL_CRLAPB_RST_LPD_AMBA_RST_MASK |
72 	       VERSAL_CRLAPB_RST_LPD_R50_RST_MASK |
73 	       VERSAL_CRL_RST_CPU_R5_RESET_PGE_MASK);
74 
75 	if (mode == TCM_LOCK)
76 		tmp &= ~VERSAL_CRLAPB_RST_LPD_R51_RST_MASK;
77 
78 	writel(tmp, &crlapb_base->rst_cpu_r5);
79 }
80 
enable_clock_r5(void)81 static void enable_clock_r5(void)
82 {
83 	u32 tmp;
84 
85 	tmp = readl(&crlapb_base->cpu_r5_ctrl);
86 	tmp |= VERSAL_CRLAPB_CPU_R5_CTRL_CLKACT_MASK;
87 	writel(tmp, &crlapb_base->cpu_r5_ctrl);
88 }
89 
initialize_tcm(enum tcm_mode mode)90 void initialize_tcm(enum tcm_mode mode)
91 {
92 	if (mode == TCM_LOCK) {
93 		set_r5_tcm_mode(TCM_LOCK);
94 		set_r5_halt_mode(HALT, TCM_LOCK);
95 		enable_clock_r5();
96 		release_r5_reset(TCM_LOCK);
97 	} else {
98 		set_r5_tcm_mode(TCM_SPLIT);
99 		set_r5_halt_mode(HALT, TCM_SPLIT);
100 		enable_clock_r5();
101 		release_r5_reset(TCM_SPLIT);
102 	}
103 }
104 
tcm_init(enum tcm_mode mode)105 void tcm_init(enum tcm_mode mode)
106 {
107 	puts("WARNING: Initializing TCM overwrites TCM content\n");
108 	initialize_tcm(mode);
109 	memset((void *)VERSAL_TCM_BASE_ADDR, 0, VERSAL_TCM_SIZE);
110 }
111