blob: d2a7f305ccc73be9e313f671ecf83ce4aeb54828 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Michal Simek58f865f2015-04-15 13:36:40 +02002/*
3 * (C) Copyright 2014 - 2015 Xilinx, Inc.
Michal Simeka8c94362023-07-10 14:35:49 +02004 * Michal Simek <michal.simek@amd.com>
Michal Simek58f865f2015-04-15 13:36:40 +02005 */
6
Tom Rinidec7ea02024-05-20 13:35:03 -06007#include <config.h>
Simon Glass970b61e2019-11-14 12:57:09 -07008#include <cpu_func.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060010#include <vsprintf.h>
Michal Simeka7acb532023-06-23 14:51:57 +020011#include <zynqmp_firmware.h>
Michal Simek58f865f2015-04-15 13:36:40 +020012#include <asm/arch/hardware.h>
13#include <asm/arch/sys_proto.h>
14#include <asm/io.h>
Padmarao Begari384e25b2024-09-30 10:08:13 +053015#include <linux/bitfield.h>
Simon Glassdbd79542020-05-10 11:40:11 -060016#include <linux/delay.h>
Padmarao Begari384e25b2024-09-30 10:08:13 +053017#include <linux/errno.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060018#include <linux/string.h>
Michal Simek58f865f2015-04-15 13:36:40 +020019
Michal Simek58f865f2015-04-15 13:36:40 +020020#define HALT 0
21#define RELEASE 1
22
23#define ZYNQMP_BOOTADDR_HIGH_MASK 0xFFFFFFFF
24#define ZYNQMP_R5_HIVEC_ADDR 0xFFFF0000
25#define ZYNQMP_R5_LOVEC_ADDR 0x0
26#define ZYNQMP_RPU_CFG_CPU_HALT_MASK 0x01
27#define ZYNQMP_RPU_CFG_HIVEC_MASK 0x04
28#define ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK 0x08
29#define ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK 0x40
30#define ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK 0x10
31
32#define ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK 0x04
33#define ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK 0x01
34#define ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK 0x02
35#define ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK 0x1000000
36
Ashok Reddy Somab43d3cf2023-04-05 15:06:45 +020037#define ZYNQMP_R5_0_TCM_START_ADDR 0xFFE00000
38#define ZYNQMP_R5_1_TCM_START_ADDR 0xFFE90000
Michal Simek58f865f2015-04-15 13:36:40 +020039#define ZYNQMP_TCM_BOTH_SIZE 0x40000
40
41#define ZYNQMP_CORE_APU0 0
42#define ZYNQMP_CORE_APU3 3
Ashok Reddy Soma86d212e2021-04-15 05:12:15 -060043#define ZYNQMP_CORE_RPU0 4
44#define ZYNQMP_CORE_RPU1 5
Michal Simek58f865f2015-04-15 13:36:40 +020045
46#define ZYNQMP_MAX_CORES 6
47
Lukas Funkec6f90582022-10-28 14:15:47 +020048#define ZYNQMP_RPU0_USE_MASK BIT(1)
49#define ZYNQMP_RPU1_USE_MASK BIT(2)
50
Michal Simek58f865f2015-04-15 13:36:40 +020051int is_core_valid(unsigned int core)
52{
53 if (core < ZYNQMP_MAX_CORES)
54 return 1;
55
56 return 0;
57}
58
Michal Simek1669e182018-06-13 08:56:31 +020059int cpu_reset(u32 nr)
Michal Simek58f865f2015-04-15 13:36:40 +020060{
61 puts("Feature is not implemented.\n");
62 return 0;
63}
64
Marek Vasut70112232025-02-06 22:29:36 +010065static void set_r5_halt_mode(u32 nr, u8 halt, enum tcm_mode mode)
Michal Simek58f865f2015-04-15 13:36:40 +020066{
67 u32 tmp;
68
Marek Vasut70112232025-02-06 22:29:36 +010069 if (mode == TCM_LOCK || nr == ZYNQMP_CORE_RPU0) {
Ashok Reddy Soma86d212e2021-04-15 05:12:15 -060070 tmp = readl(&rpu_base->rpu0_cfg);
71 if (halt == HALT)
72 tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK;
73 else
74 tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK;
75 writel(tmp, &rpu_base->rpu0_cfg);
76 }
Michal Simek58f865f2015-04-15 13:36:40 +020077
Marek Vasut70112232025-02-06 22:29:36 +010078 if (mode == TCM_LOCK || nr == ZYNQMP_CORE_RPU1) {
Michal Simek58f865f2015-04-15 13:36:40 +020079 tmp = readl(&rpu_base->rpu1_cfg);
80 if (halt == HALT)
81 tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK;
82 else
83 tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK;
84 writel(tmp, &rpu_base->rpu1_cfg);
85 }
86}
87
Marek Vasut70112232025-02-06 22:29:36 +010088static void set_r5_tcm_mode(enum tcm_mode mode)
Michal Simek58f865f2015-04-15 13:36:40 +020089{
90 u32 tmp;
91
92 tmp = readl(&rpu_base->rpu_glbl_ctrl);
Marek Vasut70112232025-02-06 22:29:36 +010093 if (mode == TCM_LOCK) {
Michal Simek58f865f2015-04-15 13:36:40 +020094 tmp &= ~ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
95 tmp |= ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK |
96 ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK;
97 } else {
98 tmp |= ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
99 tmp &= ~(ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK |
100 ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK);
101 }
102
103 writel(tmp, &rpu_base->rpu_glbl_ctrl);
104}
105
Marek Vasut70112232025-02-06 22:29:36 +0100106static void set_r5_reset(u32 nr, enum tcm_mode mode)
Michal Simek58f865f2015-04-15 13:36:40 +0200107{
108 u32 tmp;
109
110 tmp = readl(&crlapb_base->rst_lpd_top);
Marek Vasut70112232025-02-06 22:29:36 +0100111 if (mode == TCM_LOCK) {
Ashok Reddy Soma86d212e2021-04-15 05:12:15 -0600112 tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK |
Neal Fragerd929bbf2022-05-04 09:12:26 +0200113 ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK |
Ashok Reddy Soma86d212e2021-04-15 05:12:15 -0600114 ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK);
Neal Fragerd929bbf2022-05-04 09:12:26 +0200115 } else {
116 if (nr == ZYNQMP_CORE_RPU0) {
117 tmp |= ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK;
118 if (tmp & ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK)
119 tmp |= ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK;
120 } else {
121 tmp |= ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK;
122 if (tmp & ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK)
123 tmp |= ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK;
124 }
125 }
Michal Simek58f865f2015-04-15 13:36:40 +0200126
127 writel(tmp, &crlapb_base->rst_lpd_top);
128}
129
Marek Vasut70112232025-02-06 22:29:36 +0100130static void release_r5_reset(u32 nr, enum tcm_mode mode)
Michal Simek58f865f2015-04-15 13:36:40 +0200131{
132 u32 tmp;
133
134 tmp = readl(&crlapb_base->rst_lpd_top);
Marek Vasut70112232025-02-06 22:29:36 +0100135 if (mode == TCM_LOCK || nr == ZYNQMP_CORE_RPU0)
Ashok Reddy Soma86d212e2021-04-15 05:12:15 -0600136 tmp &= ~(ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK |
137 ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK);
Michal Simek58f865f2015-04-15 13:36:40 +0200138
Marek Vasut70112232025-02-06 22:29:36 +0100139 if (mode == TCM_LOCK || nr == ZYNQMP_CORE_RPU1)
Ashok Reddy Soma86d212e2021-04-15 05:12:15 -0600140 tmp &= ~(ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK |
141 ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK);
Michal Simek58f865f2015-04-15 13:36:40 +0200142
143 writel(tmp, &crlapb_base->rst_lpd_top);
144}
145
146static void enable_clock_r5(void)
147{
148 u32 tmp;
149
150 tmp = readl(&crlapb_base->cpu_r5_ctrl);
151 tmp |= ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK;
152 writel(tmp, &crlapb_base->cpu_r5_ctrl);
153
154 /* Give some delay for clock
Robert P. J. Day8d56db92016-07-15 13:44:45 -0400155 * to propagate */
Michal Simek58f865f2015-04-15 13:36:40 +0200156 udelay(0x500);
157}
158
Neal Fragerd929bbf2022-05-04 09:12:26 +0200159static int check_r5_mode(void)
160{
161 u32 tmp;
162
163 tmp = readl(&rpu_base->rpu_glbl_ctrl);
164 if (tmp & ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK)
Marek Vasut70112232025-02-06 22:29:36 +0100165 return TCM_SPLIT;
Neal Fragerd929bbf2022-05-04 09:12:26 +0200166
Marek Vasut70112232025-02-06 22:29:36 +0100167 return TCM_LOCK;
Neal Fragerd929bbf2022-05-04 09:12:26 +0200168}
169
Michal Simek1669e182018-06-13 08:56:31 +0200170int cpu_disable(u32 nr)
Michal Simek58f865f2015-04-15 13:36:40 +0200171{
Venkatesh Yadav Abbarapuae8bc3d2022-10-04 11:04:54 +0530172 if (nr <= ZYNQMP_CORE_APU3) {
Michal Simek58f865f2015-04-15 13:36:40 +0200173 u32 val = readl(&crfapb_base->rst_fpd_apu);
174 val |= 1 << nr;
175 writel(val, &crfapb_base->rst_fpd_apu);
176 } else {
Neal Fragerd929bbf2022-05-04 09:12:26 +0200177 set_r5_reset(nr, check_r5_mode());
Michal Simek58f865f2015-04-15 13:36:40 +0200178 }
179
180 return 0;
181}
182
Michal Simek1669e182018-06-13 08:56:31 +0200183int cpu_status(u32 nr)
Michal Simek58f865f2015-04-15 13:36:40 +0200184{
Venkatesh Yadav Abbarapuae8bc3d2022-10-04 11:04:54 +0530185 if (nr <= ZYNQMP_CORE_APU3) {
Michal Simek58f865f2015-04-15 13:36:40 +0200186 u32 addr_low = readl(((u8 *)&apu_base->rvbar_addr0_l) + nr * 8);
187 u32 addr_high = readl(((u8 *)&apu_base->rvbar_addr0_h) +
188 nr * 8);
189 u32 val = readl(&crfapb_base->rst_fpd_apu);
190 val &= 1 << nr;
191 printf("APU CPU%d %s - starting address HI: %x, LOW: %x\n",
192 nr, val ? "OFF" : "ON" , addr_high, addr_low);
193 } else {
194 u32 val = readl(&crlapb_base->rst_lpd_top);
195 val &= 1 << (nr - 4);
196 printf("RPU CPU%d %s\n", nr - 4, val ? "OFF" : "ON");
197 }
198
199 return 0;
200}
201
202static void set_r5_start(u8 high)
203{
204 u32 tmp;
205
206 tmp = readl(&rpu_base->rpu0_cfg);
207 if (high)
208 tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK;
209 else
210 tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK;
211 writel(tmp, &rpu_base->rpu0_cfg);
212
213 tmp = readl(&rpu_base->rpu1_cfg);
214 if (high)
215 tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK;
216 else
217 tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK;
218 writel(tmp, &rpu_base->rpu1_cfg);
219}
220
Ashok Reddy Somab43d3cf2023-04-05 15:06:45 +0200221static void write_tcm_boot_trampoline(u32 nr, u32 boot_addr)
Michal Simekf5005ce2015-05-22 13:28:23 +0200222{
223 if (boot_addr) {
Ashok Reddy Somab43d3cf2023-04-05 15:06:45 +0200224 u64 tcm_start_addr = ZYNQMP_R5_0_TCM_START_ADDR;
225
226 if (nr == ZYNQMP_CORE_RPU1)
227 tcm_start_addr = ZYNQMP_R5_1_TCM_START_ADDR;
228
Michal Simekf5005ce2015-05-22 13:28:23 +0200229 /*
230 * Boot trampoline is simple ASM code below.
231 *
232 * b over;
233 * label:
234 * .word 0
235 * over: ldr r0, =label
236 * ldr r1, [r0]
237 * bx r1
238 */
239 debug("Write boot trampoline for %x\n", boot_addr);
Ashok Reddy Somab43d3cf2023-04-05 15:06:45 +0200240 writel(0xea000000, tcm_start_addr);
241 writel(boot_addr, tcm_start_addr + 0x4);
242 writel(0xe59f0004, tcm_start_addr + 0x8);
243 writel(0xe5901000, tcm_start_addr + 0xc);
244 writel(0xe12fff11, tcm_start_addr + 0x10);
245 writel(0x00000004, tcm_start_addr + 0x14);
Michal Simekf5005ce2015-05-22 13:28:23 +0200246 }
247}
248
Marek Vasut70112232025-02-06 22:29:36 +0100249void initialize_tcm(enum tcm_mode mode)
Siva Durga Prasad Paladugu5e2a9072017-07-13 19:01:09 +0530250{
Marek Vasut70112232025-02-06 22:29:36 +0100251 if (mode == TCM_LOCK) {
252 set_r5_tcm_mode(TCM_LOCK);
253 set_r5_halt_mode(ZYNQMP_CORE_RPU0, HALT, TCM_LOCK);
Siva Durga Prasad Paladugu5e2a9072017-07-13 19:01:09 +0530254 enable_clock_r5();
Marek Vasut70112232025-02-06 22:29:36 +0100255 release_r5_reset(ZYNQMP_CORE_RPU0, TCM_LOCK);
Siva Durga Prasad Paladugu5e2a9072017-07-13 19:01:09 +0530256 } else {
Marek Vasut70112232025-02-06 22:29:36 +0100257 set_r5_tcm_mode(TCM_SPLIT);
258 set_r5_halt_mode(ZYNQMP_CORE_RPU0, HALT, TCM_SPLIT);
259 set_r5_halt_mode(ZYNQMP_CORE_RPU1, HALT, TCM_SPLIT);
Siva Durga Prasad Paladugu5e2a9072017-07-13 19:01:09 +0530260 enable_clock_r5();
Marek Vasut70112232025-02-06 22:29:36 +0100261 release_r5_reset(ZYNQMP_CORE_RPU0, TCM_SPLIT);
262 release_r5_reset(ZYNQMP_CORE_RPU1, TCM_SPLIT);
Siva Durga Prasad Paladugu5e2a9072017-07-13 19:01:09 +0530263 }
Lukas Funkec6f90582022-10-28 14:15:47 +0200264}
265
Marek Vasut70112232025-02-06 22:29:36 +0100266int check_tcm_mode(enum tcm_mode mode)
Padmarao Begari384e25b2024-09-30 10:08:13 +0530267{
268 u32 tmp, cpu_state;
Marek Vasut70112232025-02-06 22:29:36 +0100269 enum tcm_mode mode_prev;
Padmarao Begari384e25b2024-09-30 10:08:13 +0530270
271 tmp = readl(&rpu_base->rpu_glbl_ctrl);
272 mode_prev = FIELD_GET(ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK, tmp);
273
274 tmp = readl(&crlapb_base->rst_lpd_top);
275 cpu_state = FIELD_GET(ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK |
276 ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK, tmp);
277 cpu_state = cpu_state ? false : true;
278
Marek Vasut70112232025-02-06 22:29:36 +0100279 if ((mode_prev == TCM_SPLIT && mode == TCM_LOCK) && cpu_state)
Padmarao Begari384e25b2024-09-30 10:08:13 +0530280 return -EACCES;
281
282 if (mode_prev == mode)
283 return -EAGAIN;
284
285 return 0;
286}
287
Marek Vasut70112232025-02-06 22:29:36 +0100288static void mark_r5_used(u32 nr, enum tcm_mode mode)
Lukas Funkec6f90582022-10-28 14:15:47 +0200289{
290 u32 mask = 0;
291
Marek Vasut70112232025-02-06 22:29:36 +0100292 if (mode == TCM_LOCK) {
Lukas Funkec6f90582022-10-28 14:15:47 +0200293 mask = ZYNQMP_RPU0_USE_MASK | ZYNQMP_RPU1_USE_MASK;
294 } else {
295 switch (nr) {
296 case ZYNQMP_CORE_RPU0:
297 mask = ZYNQMP_RPU0_USE_MASK;
298 break;
299 case ZYNQMP_CORE_RPU1:
300 mask = ZYNQMP_RPU1_USE_MASK;
301 break;
302 default:
303 return;
304 }
305 }
306 zynqmp_mmio_write((ulong)&pmu_base->gen_storage4, mask, mask);
Siva Durga Prasad Paladugu5e2a9072017-07-13 19:01:09 +0530307}
308
Simon Glassed38aef2020-05-10 11:40:03 -0600309int cpu_release(u32 nr, int argc, char *const argv[])
Michal Simek58f865f2015-04-15 13:36:40 +0200310{
Venkatesh Yadav Abbarapuae8bc3d2022-10-04 11:04:54 +0530311 if (nr <= ZYNQMP_CORE_APU3) {
Michal Simek58f865f2015-04-15 13:36:40 +0200312 u64 boot_addr = simple_strtoull(argv[0], NULL, 16);
313 /* HIGH */
314 writel((u32)(boot_addr >> 32),
315 ((u8 *)&apu_base->rvbar_addr0_h) + nr * 8);
316 /* LOW */
317 writel((u32)(boot_addr & ZYNQMP_BOOTADDR_HIGH_MASK),
318 ((u8 *)&apu_base->rvbar_addr0_l) + nr * 8);
319
320 u32 val = readl(&crfapb_base->rst_fpd_apu);
321 val &= ~(1 << nr);
322 writel(val, &crfapb_base->rst_fpd_apu);
323 } else {
324 if (argc != 2) {
325 printf("Invalid number of arguments to release.\n");
326 printf("<addr> <mode>-Start addr lockstep or split\n");
327 return 1;
328 }
329
Simon Glass3ff49ec2021-07-24 09:03:29 -0600330 u32 boot_addr = hextoul(argv[0], NULL);
Michal Simekf5005ce2015-05-22 13:28:23 +0200331 u32 boot_addr_uniq = 0;
Michal Simek58f865f2015-04-15 13:36:40 +0200332 if (!(boot_addr == ZYNQMP_R5_LOVEC_ADDR ||
333 boot_addr == ZYNQMP_R5_HIVEC_ADDR)) {
Michal Simekf5005ce2015-05-22 13:28:23 +0200334 printf("Using TCM jump trampoline for address 0x%x\n",
335 boot_addr);
336 /* Save boot address for later usage */
337 boot_addr_uniq = boot_addr;
338 /*
339 * R5 needs to start from LOVEC at TCM
340 * OCM will be probably occupied by ATF
341 */
342 boot_addr = ZYNQMP_R5_LOVEC_ADDR;
Michal Simek58f865f2015-04-15 13:36:40 +0200343 }
344
Siva Durga Prasad Paladugue0a1f1e2017-08-01 16:24:52 +0530345 /*
346 * Since we don't know where the user may have loaded the image
347 * for an R5 we have to flush all the data cache to ensure
348 * the R5 sees it.
349 */
350 flush_dcache_all();
351
Padmarao Begari9ec525f2024-11-04 17:57:50 +0530352 if (!strcmp(argv[1], "lockstep") || !strcmp(argv[1], "0")) {
Venkatesh Yadav Abbarapu5824c172023-06-08 08:51:52 +0530353 if (nr != ZYNQMP_CORE_RPU0) {
354 printf("Lockstep mode should run on ZYNQMP_CORE_RPU0\n");
355 return 1;
356 }
Michal Simek58f865f2015-04-15 13:36:40 +0200357 printf("R5 lockstep mode\n");
Marek Vasut70112232025-02-06 22:29:36 +0100358 set_r5_reset(nr, TCM_LOCK);
359 set_r5_tcm_mode(TCM_LOCK);
360 set_r5_halt_mode(nr, HALT, TCM_LOCK);
Michal Simek08adc902015-05-22 13:26:33 +0200361 set_r5_start(boot_addr);
Michal Simek58f865f2015-04-15 13:36:40 +0200362 enable_clock_r5();
Marek Vasut70112232025-02-06 22:29:36 +0100363 release_r5_reset(nr, TCM_LOCK);
Siva Durga Prasad Paladugue0a1f1e2017-08-01 16:24:52 +0530364 dcache_disable();
Ashok Reddy Somab43d3cf2023-04-05 15:06:45 +0200365 write_tcm_boot_trampoline(nr, boot_addr_uniq);
Siva Durga Prasad Paladugue0a1f1e2017-08-01 16:24:52 +0530366 dcache_enable();
Marek Vasut70112232025-02-06 22:29:36 +0100367 set_r5_halt_mode(nr, RELEASE, TCM_LOCK);
368 mark_r5_used(nr, TCM_LOCK);
Padmarao Begari9ec525f2024-11-04 17:57:50 +0530369 } else if (!strcmp(argv[1], "split") || !strcmp(argv[1], "1")) {
Michal Simek58f865f2015-04-15 13:36:40 +0200370 printf("R5 split mode\n");
Marek Vasut70112232025-02-06 22:29:36 +0100371 set_r5_reset(nr, TCM_SPLIT);
372 set_r5_tcm_mode(TCM_SPLIT);
373 set_r5_halt_mode(nr, HALT, TCM_SPLIT);
Siva Durga Prasad Paladugue0a1f1e2017-08-01 16:24:52 +0530374 set_r5_start(boot_addr);
Michal Simek58f865f2015-04-15 13:36:40 +0200375 enable_clock_r5();
Marek Vasut70112232025-02-06 22:29:36 +0100376 release_r5_reset(nr, TCM_SPLIT);
Siva Durga Prasad Paladugue0a1f1e2017-08-01 16:24:52 +0530377 dcache_disable();
Ashok Reddy Somab43d3cf2023-04-05 15:06:45 +0200378 write_tcm_boot_trampoline(nr, boot_addr_uniq);
Siva Durga Prasad Paladugue0a1f1e2017-08-01 16:24:52 +0530379 dcache_enable();
Marek Vasut70112232025-02-06 22:29:36 +0100380 set_r5_halt_mode(nr, RELEASE, TCM_SPLIT);
381 mark_r5_used(nr, TCM_SPLIT);
Michal Simek58f865f2015-04-15 13:36:40 +0200382 } else {
383 printf("Unsupported mode\n");
384 return 1;
385 }
386 }
387
388 return 0;
389}