1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2022 NXP
4  */
5 
6 #include <common.h>
7 #include <log.h>
8 #include <asm/io.h>
9 #include <asm/types.h>
10 #include <asm/arch/imx-regs.h>
11 #include <asm/arch/sys_proto.h>
12 #include <div64.h>
13 #include <asm/mach-imx/s400_api.h>
14 #include <asm/mach-imx/mu_hal.h>
15 
16 #define DID_NUM 16
17 #define MBC_MAX_NUM 4
18 #define MRC_MAX_NUM 2
19 #define MBC_NUM(HWCFG) (((HWCFG) >> 16) & 0xF)
20 #define MRC_NUM(HWCFG) (((HWCFG) >> 24) & 0x1F)
21 
22 struct mbc_mem_dom {
23 	u32 mem_glbcfg[4];
24 	u32 nse_blk_index;
25 	u32 nse_blk_set;
26 	u32 nse_blk_clr;
27 	u32 nsr_blk_clr_all;
28 	u32 memn_glbac[8];
29 	/* The upper only existed in the beginning of each MBC */
30 	u32 mem0_blk_cfg_w[64];
31 	u32 mem0_blk_nse_w[16];
32 	u32 mem1_blk_cfg_w[8];
33 	u32 mem1_blk_nse_w[2];
34 	u32 mem2_blk_cfg_w[8];
35 	u32 mem2_blk_nse_w[2];
36 	u32 mem3_blk_cfg_w[8];
37 	u32 mem3_blk_nse_w[2];/*0x1F0, 0x1F4 */
38 	u32 reserved[2];
39 };
40 
41 struct mrc_rgn_dom {
42 	u32 mrc_glbcfg[4];
43 	u32 nse_rgn_indirect;
44 	u32 nse_rgn_set;
45 	u32 nse_rgn_clr;
46 	u32 nse_rgn_clr_all;
47 	u32 memn_glbac[8];
48 	/* The upper only existed in the beginning of each MRC */
49 	u32 rgn_desc_words[16][2]; /* 16  regions at max, 2 words per region */
50 	u32	rgn_nse;
51 	u32 reserved2[15];
52 };
53 
54 struct mda_inst {
55 	u32 mda_w[8];
56 };
57 
58 struct trdc_mgr {
59 	u32 trdc_cr;
60 	u32 res0[59];
61 	u32 trdc_hwcfg0;
62 	u32 trdc_hwcfg1;
63 	u32 res1[450];
64 	struct mda_inst mda[8];
65 	u32 res2[15808];
66 };
67 
68 struct trdc_mbc {
69 	struct mbc_mem_dom mem_dom[DID_NUM];
70 };
71 
72 struct trdc_mrc {
73 	struct mrc_rgn_dom mrc_dom[DID_NUM];
74 };
75 
trdc_mda_set_cpu(ulong trdc_reg,u32 mda_inst,u32 mda_reg,u8 sa,u8 dids,u8 did,u8 pe,u8 pidm,u8 pid)76 int trdc_mda_set_cpu(ulong trdc_reg, u32 mda_inst, u32 mda_reg, u8 sa, u8 dids,
77 		     u8 did, u8 pe, u8 pidm, u8 pid)
78 {
79 	struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
80 	u32 *mda_w = &trdc_base->mda[mda_inst].mda_w[mda_reg];
81 	u32 val = readl(mda_w);
82 
83 	if (val & BIT(29)) /* non-cpu */
84 		return -EINVAL;
85 
86 	val = BIT(31) | ((pid & 0x3f) << 16) | ((pidm & 0x3f) << 8) |
87 		((pe & 0x3) << 6) | ((sa & 0x3) << 14) | ((dids & 0x3) << 4) |
88 		(did & 0xf);
89 
90 	writel(val, mda_w);
91 
92 	return 0;
93 }
94 
trdc_mda_set_noncpu(ulong trdc_reg,u32 mda_inst,u32 mda_reg,bool did_bypass,u8 sa,u8 pa,u8 did)95 int trdc_mda_set_noncpu(ulong trdc_reg, u32 mda_inst, u32 mda_reg,
96 			bool did_bypass, u8 sa, u8 pa, u8 did)
97 {
98 	struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
99 	u32 *mda_w = &trdc_base->mda[mda_inst].mda_w[mda_reg];
100 	u32 val = readl(mda_w);
101 
102 	if (!(val & BIT(29))) /* cpu */
103 		return -EINVAL;
104 
105 	val = BIT(31) | ((sa & 0x3) << 6) | ((pa & 0x3) << 4) | (did & 0xf);
106 	if (did_bypass)
107 		val |= BIT(8);
108 
109 	writel(val, mda_w);
110 
111 	return 0;
112 }
113 
trdc_get_mbc_base(ulong trdc_reg,u32 mbc_x)114 static ulong trdc_get_mbc_base(ulong trdc_reg, u32 mbc_x)
115 {
116 	struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
117 	u32 mbc_num = MBC_NUM(trdc_base->trdc_hwcfg0);
118 
119 	if (mbc_x >= mbc_num)
120 		return 0;
121 
122 	return trdc_reg + 0x10000 + 0x2000 * mbc_x;
123 }
124 
trdc_get_mrc_base(ulong trdc_reg,u32 mrc_x)125 static ulong trdc_get_mrc_base(ulong trdc_reg, u32 mrc_x)
126 {
127 	struct trdc_mgr *trdc_base = (struct trdc_mgr *)trdc_reg;
128 	u32 mbc_num = MBC_NUM(trdc_base->trdc_hwcfg0);
129 	u32 mrc_num = MRC_NUM(trdc_base->trdc_hwcfg0);
130 
131 	if (mrc_x >= mrc_num)
132 		return 0;
133 
134 	return trdc_reg + 0x10000 + 0x2000 * mbc_num + 0x1000 * mrc_x;
135 }
136 
trdc_mbc_set_control(ulong trdc_reg,u32 mbc_x,u32 glbac_id,u32 glbac_val)137 int trdc_mbc_set_control(ulong trdc_reg, u32 mbc_x, u32 glbac_id, u32 glbac_val)
138 {
139 	struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
140 	struct mbc_mem_dom *mbc_dom;
141 
142 	if (mbc_base == 0 || glbac_id >= 8)
143 		return -EINVAL;
144 
145 	/* only first dom has the glbac */
146 	mbc_dom = &mbc_base->mem_dom[0];
147 
148 	debug("mbc 0x%lx\n", (ulong)mbc_dom);
149 
150 	writel(glbac_val, &mbc_dom->memn_glbac[glbac_id]);
151 
152 	return 0;
153 }
154 
trdc_mbc_blk_config(ulong trdc_reg,u32 mbc_x,u32 dom_x,u32 mem_x,u32 blk_x,bool sec_access,u32 glbac_id)155 int trdc_mbc_blk_config(ulong trdc_reg, u32 mbc_x, u32 dom_x, u32 mem_x,
156 			u32 blk_x, bool sec_access, u32 glbac_id)
157 {
158 	struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
159 	struct mbc_mem_dom *mbc_dom;
160 	u32 *cfg_w, *nse_w;
161 	u32 index, offset, val;
162 
163 	if (mbc_base == 0 || glbac_id >= 8)
164 		return -EINVAL;
165 
166 	mbc_dom = &mbc_base->mem_dom[dom_x];
167 
168 	debug("mbc 0x%lx\n", (ulong)mbc_dom);
169 
170 	switch (mem_x) {
171 	case 0:
172 		cfg_w = &mbc_dom->mem0_blk_cfg_w[blk_x / 8];
173 		nse_w = &mbc_dom->mem0_blk_nse_w[blk_x / 32];
174 		break;
175 	case 1:
176 		cfg_w = &mbc_dom->mem1_blk_cfg_w[blk_x / 8];
177 		nse_w = &mbc_dom->mem1_blk_nse_w[blk_x / 32];
178 		break;
179 	case 2:
180 		cfg_w = &mbc_dom->mem2_blk_cfg_w[blk_x / 8];
181 		nse_w = &mbc_dom->mem2_blk_nse_w[blk_x / 32];
182 		break;
183 	case 3:
184 		cfg_w = &mbc_dom->mem3_blk_cfg_w[blk_x / 8];
185 		nse_w = &mbc_dom->mem3_blk_nse_w[blk_x / 32];
186 		break;
187 	default:
188 		return -EINVAL;
189 	};
190 
191 	index = blk_x % 8;
192 	offset = index * 4;
193 
194 	val = readl((void __iomem *)cfg_w);
195 
196 	val &= ~(0xFU << offset);
197 
198 	/* MBC0-3
199 	 *  Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it.
200 	 *  So select MBC0_MEMN_GLBAC0
201 	 */
202 	if (sec_access) {
203 		val |= ((0x0 | (glbac_id & 0x7)) << offset);
204 		writel(val, (void __iomem *)cfg_w);
205 	} else {
206 		val |= ((0x8 | (glbac_id & 0x7)) << offset); /* nse bit set */
207 		writel(val, (void __iomem *)cfg_w);
208 	}
209 
210 	return 0;
211 }
212 
trdc_mrc_set_control(ulong trdc_reg,u32 mrc_x,u32 glbac_id,u32 glbac_val)213 int trdc_mrc_set_control(ulong trdc_reg, u32 mrc_x, u32 glbac_id, u32 glbac_val)
214 {
215 	struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
216 	struct mrc_rgn_dom *mrc_dom;
217 
218 	if (mrc_base == 0 || glbac_id >= 8)
219 		return -EINVAL;
220 
221 	/* only first dom has the glbac */
222 	mrc_dom = &mrc_base->mrc_dom[0];
223 
224 	debug("mrc_dom 0x%lx\n", (ulong)mrc_dom);
225 
226 	writel(glbac_val, &mrc_dom->memn_glbac[glbac_id]);
227 
228 	return 0;
229 }
230 
trdc_mrc_region_config(ulong trdc_reg,u32 mrc_x,u32 dom_x,u32 addr_start,u32 addr_end,bool sec_access,u32 glbac_id)231 int trdc_mrc_region_config(ulong trdc_reg, u32 mrc_x, u32 dom_x, u32 addr_start,
232 			   u32 addr_end, bool sec_access, u32 glbac_id)
233 {
234 	struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
235 	struct mrc_rgn_dom *mrc_dom;
236 	u32 *desc_w;
237 	u32 start, end;
238 	u32 i, free = 8;
239 	bool vld, hit = false;
240 
241 	if (mrc_base == 0 || glbac_id >= 8)
242 		return -EINVAL;
243 
244 	mrc_dom = &mrc_base->mrc_dom[dom_x];
245 
246 	addr_start &= ~0x3fff;
247 	addr_end &= ~0x3fff;
248 
249 	debug("mrc_dom 0x%lx\n", (ulong)mrc_dom);
250 
251 	for (i = 0; i < 8; i++) {
252 		desc_w = &mrc_dom->rgn_desc_words[i][0];
253 
254 		debug("desc_w 0x%lx\n", (ulong)desc_w);
255 
256 		start = readl((void __iomem *)desc_w) & (~0x3fff);
257 		end = readl((void __iomem *)(desc_w + 1));
258 		vld = end & 0x1;
259 		end = end & (~0x3fff);
260 
261 		if (start == 0 && end == 0 && !vld && free >= 8)
262 			free = i;
263 
264 		/* Check all the region descriptors, even overlap */
265 		if (addr_start >= end || addr_end <= start || !vld)
266 			continue;
267 
268 		/* MRC0,1
269 		 *  Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it.
270 		 *  So select MRCx_MEMN_GLBAC0
271 		 */
272 		if (sec_access) {
273 			writel(start | (glbac_id & 0x7), (void __iomem *)desc_w);
274 			writel(end | 0x1, (void __iomem *)(desc_w + 1));
275 		} else {
276 			writel(start | (glbac_id & 0x7), (void __iomem *)desc_w);
277 			writel(end | 0x1 | 0x10, (void __iomem *)(desc_w + 1));
278 		}
279 
280 		if (addr_start >= start && addr_end <= end)
281 			hit = true;
282 	}
283 
284 	if (!hit) {
285 		if (free >= 8)
286 			return -EFAULT;
287 
288 		desc_w = &mrc_dom->rgn_desc_words[free][0];
289 
290 		debug("free desc_w 0x%lx\n", (ulong)desc_w);
291 		debug("[0x%x] [0x%x]\n", addr_start | (glbac_id & 0x7), addr_end | 0x1);
292 
293 		if (sec_access) {
294 			writel(addr_start | (glbac_id & 0x7), (void __iomem *)desc_w);
295 			writel(addr_end | 0x1, (void __iomem *)(desc_w + 1));
296 		} else {
297 			writel(addr_start | (glbac_id & 0x7), (void __iomem *)desc_w);
298 			writel((addr_end | 0x1 | 0x10), (void __iomem *)(desc_w + 1));
299 		}
300 	}
301 
302 	return 0;
303 }
304 
trdc_mrc_enabled(ulong trdc_base)305 bool trdc_mrc_enabled(ulong trdc_base)
306 {
307 	return (!!(readl((void __iomem *)trdc_base) & 0x8000));
308 }
309 
trdc_mbc_enabled(ulong trdc_base)310 bool trdc_mbc_enabled(ulong trdc_base)
311 {
312 	return (!!(readl((void __iomem *)trdc_base) & 0x4000));
313 }
314 
release_rdc(u8 xrdc)315 int release_rdc(u8 xrdc)
316 {
317 	ulong s_mu_base = 0x47520000UL;
318 	struct sentinel_msg msg;
319 	int ret;
320 	u32 rdc_id;
321 
322 	switch (xrdc) {
323 	case 0:
324 		rdc_id = 0x74;
325 		break;
326 	case 1:
327 		rdc_id = 0x78;
328 		break;
329 	case 2:
330 		rdc_id = 0x82;
331 		break;
332 	case 3:
333 		rdc_id = 0x86;
334 		break;
335 	default:
336 		return -EINVAL;
337 	}
338 
339 	msg.version = AHAB_VERSION;
340 	msg.tag = AHAB_CMD_TAG;
341 	msg.size = 2;
342 	msg.command = ELE_RELEASE_RDC_REQ;
343 	msg.data[0] = (rdc_id << 8) | 0x2; /* A55 */
344 
345 	mu_hal_init(s_mu_base);
346 	mu_hal_sendmsg(s_mu_base, 0, *((u32 *)&msg));
347 	mu_hal_sendmsg(s_mu_base, 1, msg.data[0]);
348 
349 	ret = mu_hal_receivemsg(s_mu_base, 0, (u32 *)&msg);
350 	if (!ret) {
351 		ret = mu_hal_receivemsg(s_mu_base, 1, &msg.data[0]);
352 		if (!ret) {
353 			if ((msg.data[0] & 0xff) == 0xd6)
354 				return 0;
355 		}
356 
357 		return -EIO;
358 	}
359 
360 	return ret;
361 }
362 
trdc_early_init(void)363 void trdc_early_init(void)
364 {
365 	int ret = 0, i;
366 
367 	ret |= release_rdc(0);
368 	ret |= release_rdc(2);
369 	ret |= release_rdc(1);
370 	ret |= release_rdc(3);
371 
372 	if (!ret) {
373 		/* Set OCRAM to RWX for secure, when OEM_CLOSE, the image is RX only */
374 		trdc_mbc_set_control(0x49010000, 3, 0, 0x7700);
375 
376 		for (i = 0; i < 40; i++)
377 			trdc_mbc_blk_config(0x49010000, 3, 3, 0, i, true, 0);
378 
379 		for (i = 0; i < 40; i++)
380 			trdc_mbc_blk_config(0x49010000, 3, 3, 1, i, true, 0);
381 
382 		for (i = 0; i < 40; i++)
383 			trdc_mbc_blk_config(0x49010000, 3, 0, 0, i, true, 0);
384 
385 		for (i = 0; i < 40; i++)
386 			trdc_mbc_blk_config(0x49010000, 3, 0, 1, i, true, 0);
387 	}
388 }
389 
trdc_init(void)390 void trdc_init(void)
391 {
392 	/* TRDC mega */
393 	if (trdc_mrc_enabled(0x49010000)) {
394 		/* DDR */
395 		trdc_mrc_set_control(0x49010000, 0, 0, 0x7777);
396 
397 		/* S400*/
398 		trdc_mrc_region_config(0x49010000, 0, 0, 0x80000000, 0xFFFFFFFF, false, 0);
399 
400 		/* MTR */
401 		trdc_mrc_region_config(0x49010000, 0, 1, 0x80000000, 0xFFFFFFFF, false, 0);
402 
403 		/* M33 */
404 		trdc_mrc_region_config(0x49010000, 0, 2, 0x80000000, 0xFFFFFFFF, false, 0);
405 
406 		/* A55*/
407 		trdc_mrc_region_config(0x49010000, 0, 3, 0x80000000, 0xFFFFFFFF, false, 0);
408 
409 		/* For USDHC1 to DDR, USDHC1 is default force to non-secure */
410 		trdc_mrc_region_config(0x49010000, 0, 5, 0x80000000, 0xFFFFFFFF, false, 0);
411 
412 		/* For USDHC2 to DDR, USDHC2 is default force to non-secure */
413 		trdc_mrc_region_config(0x49010000, 0, 6, 0x80000000, 0xFFFFFFFF, false, 0);
414 
415 		/* eDMA */
416 		trdc_mrc_region_config(0x49010000, 0, 7, 0x80000000, 0xFFFFFFFF, false, 0);
417 
418 		/*CoreSight, TestPort*/
419 		trdc_mrc_region_config(0x49010000, 0, 8, 0x80000000, 0xFFFFFFFF, false, 0);
420 
421 		/* DAP */
422 		trdc_mrc_region_config(0x49010000, 0, 9, 0x80000000, 0xFFFFFFFF, false, 0);
423 
424 		/*SoC masters */
425 		trdc_mrc_region_config(0x49010000, 0, 10, 0x80000000, 0xFFFFFFFF, false, 0);
426 
427 		/*USB*/
428 		trdc_mrc_region_config(0x49010000, 0, 11, 0x80000000, 0xFFFFFFFF, false, 0);
429 	}
430 }
431 
432 #if DEBUG
trdc_mbc_control_dump(ulong trdc_reg,u32 mbc_x,u32 glbac_id)433 int trdc_mbc_control_dump(ulong trdc_reg, u32 mbc_x, u32 glbac_id)
434 {
435 	struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
436 	struct mbc_mem_dom *mbc_dom;
437 
438 	if (mbc_base == 0 || glbac_id >= 8)
439 		return -EINVAL;
440 
441 	/* only first dom has the glbac */
442 	mbc_dom = &mbc_base->mem_dom[0];
443 
444 	printf("mbc_dom %u glbac %u: 0x%x\n",
445 	       mbc_x, glbac_id, readl(&mbc_dom->memn_glbac[glbac_id]));
446 
447 	return 0;
448 }
449 
trdc_mbc_mem_dump(ulong trdc_reg,u32 mbc_x,u32 dom_x,u32 mem_x,u32 word)450 int trdc_mbc_mem_dump(ulong trdc_reg, u32 mbc_x, u32 dom_x, u32 mem_x, u32 word)
451 {
452 	struct trdc_mbc *mbc_base = (struct trdc_mbc *)trdc_get_mbc_base(trdc_reg, mbc_x);
453 	struct mbc_mem_dom *mbc_dom;
454 	u32 *cfg_w;
455 
456 	if (mbc_base == 0)
457 		return -EINVAL;
458 
459 	mbc_dom = &mbc_base->mem_dom[dom_x];
460 
461 	switch (mem_x) {
462 	case 0:
463 		cfg_w = &mbc_dom->mem0_blk_cfg_w[word];
464 		break;
465 	case 1:
466 		cfg_w = &mbc_dom->mem1_blk_cfg_w[word];
467 		break;
468 	case 2:
469 		cfg_w = &mbc_dom->mem2_blk_cfg_w[word];
470 		break;
471 	case 3:
472 		cfg_w = &mbc_dom->mem3_blk_cfg_w[word];
473 		break;
474 	default:
475 		return -EINVAL;
476 	};
477 
478 	printf("mbc_dom %u dom %u mem %u word %u: 0x%x\n",
479 	       mbc_x, dom_x, mem_x, word, readl((void __iomem *)cfg_w));
480 
481 	return 0;
482 }
483 
trdc_mrc_control_dump(ulong trdc_reg,u32 mrc_x,u32 glbac_id)484 int trdc_mrc_control_dump(ulong trdc_reg, u32 mrc_x, u32 glbac_id)
485 {
486 	struct trdc_mrc *mrc_base = (struct trdc_mrc *)trdc_get_mrc_base(trdc_reg, mrc_x);
487 	struct mrc_rgn_dom *mrc_dom;
488 
489 	if (mrc_base == 0 || glbac_id >= 8)
490 		return -EINVAL;
491 
492 	/* only first dom has the glbac */
493 	mrc_dom = &mrc_base->mrc_dom[0];
494 
495 	printf("mrc_dom %u glbac %u: 0x%x\n",
496 	       mrc_x, glbac_id, readl(&mrc_dom->memn_glbac[glbac_id]));
497 
498 	return 0;
499 }
500 
trdc_dump(void)501 void trdc_dump(void)
502 {
503 	u32 i;
504 
505 	printf("TRDC AONMIX MBC\n");
506 
507 	trdc_mbc_control_dump(0x44270000, 0, 0);
508 	trdc_mbc_control_dump(0x44270000, 1, 0);
509 
510 	for (i = 0; i < 11; i++)
511 		trdc_mbc_mem_dump(0x44270000, 0, 3, 0, i);
512 	for (i = 0; i < 1; i++)
513 		trdc_mbc_mem_dump(0x44270000, 0, 3, 1, i);
514 
515 	for (i = 0; i < 4; i++)
516 		trdc_mbc_mem_dump(0x44270000, 1, 3, 0, i);
517 	for (i = 0; i < 4; i++)
518 		trdc_mbc_mem_dump(0x44270000, 1, 3, 1, i);
519 
520 	printf("TRDC WAKEUP MBC\n");
521 
522 	trdc_mbc_control_dump(0x42460000, 0, 0);
523 	trdc_mbc_control_dump(0x42460000, 1, 0);
524 
525 	for (i = 0; i < 15; i++)
526 		trdc_mbc_mem_dump(0x42460000, 0, 3, 0, i);
527 
528 	trdc_mbc_mem_dump(0x42460000, 0, 3, 1, 0);
529 	trdc_mbc_mem_dump(0x42460000, 0, 3, 2, 0);
530 
531 	for (i = 0; i < 2; i++)
532 		trdc_mbc_mem_dump(0x42460000, 1, 3, 0, i);
533 
534 	trdc_mbc_mem_dump(0x42460000, 1, 3, 1, 0);
535 	trdc_mbc_mem_dump(0x42460000, 1, 3, 2, 0);
536 	trdc_mbc_mem_dump(0x42460000, 1, 3, 3, 0);
537 
538 	printf("TRDC NICMIX MBC\n");
539 
540 	trdc_mbc_control_dump(0x49010000, 0, 0);
541 	trdc_mbc_control_dump(0x49010000, 1, 0);
542 	trdc_mbc_control_dump(0x49010000, 2, 0);
543 	trdc_mbc_control_dump(0x49010000, 3, 0);
544 
545 	for (i = 0; i < 7; i++)
546 		trdc_mbc_mem_dump(0x49010000, 0, 3, 0, i);
547 
548 	for (i = 0; i < 2; i++)
549 		trdc_mbc_mem_dump(0x49010000, 0, 3, 1, i);
550 
551 	for (i = 0; i < 5; i++)
552 		trdc_mbc_mem_dump(0x49010000, 0, 3, 2, i);
553 
554 	for (i = 0; i < 6; i++)
555 		trdc_mbc_mem_dump(0x49010000, 0, 3, 3, i);
556 
557 	for (i = 0; i < 1; i++)
558 		trdc_mbc_mem_dump(0x49010000, 1, 3, 0, i);
559 
560 	for (i = 0; i < 1; i++)
561 		trdc_mbc_mem_dump(0x49010000, 1, 3, 1, i);
562 
563 	for (i = 0; i < 3; i++)
564 		trdc_mbc_mem_dump(0x49010000, 1, 3, 2, i);
565 
566 	for (i = 0; i < 3; i++)
567 		trdc_mbc_mem_dump(0x49010000, 1, 3, 3, i);
568 
569 	for (i = 0; i < 2; i++)
570 		trdc_mbc_mem_dump(0x49010000, 2, 3, 0, i);
571 
572 	for (i = 0; i < 2; i++)
573 		trdc_mbc_mem_dump(0x49010000, 2, 3, 1, i);
574 
575 	for (i = 0; i < 5; i++)
576 		trdc_mbc_mem_dump(0x49010000, 3, 3, 0, i);
577 
578 	for (i = 0; i < 5; i++)
579 		trdc_mbc_mem_dump(0x49010000, 3, 3, 1, i);
580 }
581 #endif
582