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