blob: 30aa33abc3b32115aa39eecdbc8cc354ffa8540a [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*----------------------------------------------------------------------------*
2 * Copyright Statement: *
3 * *
4 * This software/firmware and related documentation ("MediaTek Software") *
5 * are protected under international and related jurisdictions'copyright laws *
6 * as unpublished works. The information contained herein is confidential and *
7 * proprietary to MediaTek Inc. Without the prior written permission of *
8 * MediaTek Inc., any reproduction, modification, use or disclosure of *
9 * MediaTek Software, and information contained herein, in whole or in part, *
10 * shall be strictly prohibited. *
11 * MediaTek Inc. Copyright (C) 2010. All rights reserved. *
12 * *
13 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND *
14 * AGREES TO THE FOLLOWING: *
15 * *
16 * 1)Any and all intellectual property rights (including without *
17 * limitation, patent, copyright, and trade secrets) in and to this *
18 * Software/firmware and related documentation ("MediaTek Software") shall *
19 * remain the exclusive property of MediaTek Inc. Any and all intellectual *
20 * property rights (including without limitation, patent, copyright, and *
21 * trade secrets) in and to any modifications and derivatives to MediaTek *
22 * Software, whoever made, shall also remain the exclusive property of *
23 * MediaTek Inc. Nothing herein shall be construed as any transfer of any *
24 * title to any intellectual property right in MediaTek Software to Receiver. *
25 * *
26 * 2)This MediaTek Software Receiver received from MediaTek Inc. and/or its *
27 * representatives is provided to Receiver on an "AS IS" basis only. *
28 * MediaTek Inc. expressly disclaims all warranties, expressed or implied, *
29 * including but not limited to any implied warranties of merchantability, *
30 * non-infringement and fitness for a particular purpose and any warranties *
31 * arising out of course of performance, course of dealing or usage of trade. *
32 * MediaTek Inc. does not provide any warranty whatsoever with respect to the *
33 * software of any third party which may be used by, incorporated in, or *
34 * supplied with the MediaTek Software, and Receiver agrees to look only to *
35 * such third parties for any warranty claim relating thereto. Receiver *
36 * expressly acknowledges that it is Receiver's sole responsibility to obtain *
37 * from any third party all proper licenses contained in or delivered with *
38 * MediaTek Software. MediaTek is not responsible for any MediaTek Software *
39 * releases made to Receiver's specifications or to conform to a particular *
40 * standard or open forum. *
41 * *
42 * 3)Receiver further acknowledge that Receiver may, either presently *
43 * and/or in the future, instruct MediaTek Inc. to assist it in the *
44 * development and the implementation, in accordance with Receiver's designs, *
45 * of certain softwares relating to Receiver's product(s) (the "Services"). *
46 * Except as may be otherwise agreed to in writing, no warranties of any *
47 * kind, whether express or implied, are given by MediaTek Inc. with respect *
48 * to the Services provided, and the Services are provided on an "AS IS" *
49 * basis. Receiver further acknowledges that the Services may contain errors *
50 * that testing is important and it is solely responsible for fully testing *
51 * the Services and/or derivatives thereof before they are used, sublicensed *
52 * or distributed. Should there be any third party action brought against *
53 * MediaTek Inc. arising out of or relating to the Services, Receiver agree *
54 * to fully indemnify and hold MediaTek Inc. harmless. If the parties *
55 * mutually agree to enter into or continue a business relationship or other *
56 * arrangement, the terms and conditions set forth herein shall remain *
57 * effective and, unless explicitly stated otherwise, shall prevail in the *
58 * event of a conflict in the terms in any agreements entered into between *
59 * the parties. *
60 * *
61 * 4)Receiver's sole and exclusive remedy and MediaTek Inc.'s entire and *
62 * cumulative liability with respect to MediaTek Software released hereunder *
63 * will be, at MediaTek Inc.'s sole discretion, to replace or revise the *
64 * MediaTek Software at issue. *
65 * *
66 * 5)The transaction contemplated hereunder shall be construed in *
67 * accordance with the laws of Singapore, excluding its conflict of laws *
68 * principles. Any disputes, controversies or claims arising thereof and *
69 * related thereto shall be settled via arbitration in Singapore, under the *
70 * then current rules of the International Chamber of Commerce (ICC). The *
71 * arbitration shall be conducted in English. The awards of the arbitration *
72 * shall be final and binding upon both parties and shall be entered and *
73 * enforceable in any court of competent jurisdiction. *
74 *---------------------------------------------------------------------------*/
75/*-----------------------------------------------------------------------------
76 *
77 * Description:
78 *
79 *---------------------------------------------------------------------------*/
80
81#include <assert.h>
82#include <printf.h>
83#include <memory.h>
84#include <platform/mt2731.h>
85#include <platform/mtk_drm.h>
86#include <reg.h>
87#include <emi.h>
88#include <emi_hw.h>
89#include <emi_mpu_mt.h>
90
91#ifdef DDR_RESERVE_MODE
92u32 g_ddr_reserve_enable;
93u32 g_ddr_reserve_success;
94u32 g_ddr_reserve_ready;
95u32 g_ddr_reserve_ta_err;
96#endif
97
98static int complex_mem_test(unsigned long start, unsigned int len);
99static int simple_mem_test(unsigned long start, unsigned int len);
100extern unsigned int set_emi_before_rank1_mem_test(void);
101extern void restore_emi_after_rank1_mem_test(void);
102
103// --------------------------------------------------------
104// init EMI
105// --------------------------------------------------------
106void mt_mem_init(void)
107{
108 int region, dgroup;
109
110#if CFG_FPGA_PLATFORM
111 return;
112#endif
113
114#ifdef LAST_DRAMC
115 dram_fatal_exception_detection_start();
116
117 if (check_last_dram_fatal_exception() != 0 || check_gating_err_in_dramc_latch() != 0) {
118#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
119 int ret;
120 printf("[save time for cal] dram fatal exception found -> clear calibration data\n");
121 ret = clean_dram_calibration_data();
122 SET_DATA_FORMATTED_STORAGE_API_ERR();
123 printf("[save time for cal] clean_dram_calibration_data done (ret=%d)\n", ret);
124#endif
125 }
126#endif
127
128 /* clear EMI MPU protect setting */
129 for (region = 0; region < EMI_MPU_REGION_NUM; region++) {
130 DRV_WriteReg32(EMI_MPU_SA(region), 0x0);
131 DRV_WriteReg32(EMI_MPU_EA(region), 0x0);
132 for (dgroup = EMI_MPU_DGROUP_NUM - 1; dgroup >= 0; dgroup--)
133 DRV_WriteReg32(EMI_MPU_APC(region, dgroup), 0x0);
134 }
135
136#ifdef DDR_RESERVE_MODE
137 unsigned int emi_cona;
138
139 if((g_ddr_reserve_enable==1) && (g_ddr_reserve_success==1)) {
140 /* EMI register dummy read: give clock to EMI APB register to avoid DRAM access hang */
141 emi_cona = *(volatile unsigned int *)(EMI_CONA);
142 printf("[DDR Reserve mode] EMI dummy read CONA = 0x%x\n", emi_cona);
143
144 /* disable transaction mask */
145 *(volatile unsigned int *) (IO_PHYS + 0x22D3FC) &= 0xFFFFFFFE;
146 *(volatile unsigned int *) (IO_PHYS + 0x2353FC) &= 0xFFFFFFFE;
147
148 /* disable EMI APB protect */
149 DRV_WriteReg32(EMI_MPU_CTRL, DRV_Reg32(EMI_MPU_CTRL)&0xFFFFFFFE);
150
151 if (g_ddr_reserve_ta_err != 0) {
152 printf("[DDR Reserve mode] TA2 ERR = %d -> overwrite tag.ddr_reserve_success to 0\n", g_ddr_reserve_ta_err);
153 }
154 } else /* normal boot */
155#endif
156 {
157 /* disable EMI APB protect */
158 printf("EMI_MPU_CTRL=%x 1st\n",DRV_Reg32(EMI_MPU_CTRL));
159 DRV_WriteReg32(EMI_MPU_CTRL, DRV_Reg32(EMI_MPU_CTRL)&0xFFFFFFFE);
160 printf("EMI_MPU_CTRL=%x 2nd\n",DRV_Reg32(EMI_MPU_CTRL));
161
162#ifdef DDR_RESERVE_MODE
163 /* force clear RGU control for DRAMC before calibration */
164 drm_release_rg_dramc_conf_iso();//Release DRAMC/PHY conf ISO
165 drm_release_rg_dramc_iso();//Release PHY IO ISO
166 drm_release_rg_dramc_sref();//Let DRAM Leave SR
167#endif
168
169 mt_set_emi();
170
171#if defined(LAST_DRAMC) & SUPPORT_SAVE_TIME_FOR_CALIBRATION
172 set_err_code_for_storage_api();
173#endif
174 }
175
176#ifdef DDR_RESERVE_MODE
177 g_ddr_reserve_ready = 0x9502;
178 /* Disable DDR-reserve mode in pre-loader stage then enable it again in kernel stage */
179 drm_dram_reserved(0);
180#endif
181
182#ifdef LAST_DRAMC
183 unsigned rk0_err = 0, rk1_err = 0;
184#endif
185 int i = 0;
186
187 /* MEM_TEST_START is kernel base addr */
188 if ((i = complex_mem_test(MEM_TEST_START, MEM_TEST_SIZE)) == 0) {
189 #if ARCH_ARM64
190 printf("[dramc] 1st complex mem test pass (start addr:0x%lx)\n", MEM_TEST_START);
191 #endif
192 } else {
193 #if ARCH_ARM64
194 printf("[dramc] 1st complex mem test fail :%x (start addr:0x%lx)\n", i, MEM_TEST_START);
195 #endif
196#ifdef LAST_DRAMC
197 rk0_err = 1;
198#else
199 ASSERT(0);
200#endif
201 }
202
203#if DUAL_RANK_ENABLE
204 if (get_dram_rank_nr() >= 2) {
205 /* need to test rank1 */
206 unsigned int rank1_start_address = MEM_TEST_START + set_emi_before_rank1_mem_test();
207
208#ifdef DDR_RESERVE_MODE
209 /* simple mem test to avoid memory corruption in DDR reserve mode */
210 if((g_ddr_reserve_enable==1) && (g_ddr_reserve_success==1)) {
211 i = simple_mem_test(rank1_start_address, MEM_TEST_SIZE);
212 } else
213#endif
214 i = complex_mem_test(rank1_start_address, MEM_TEST_SIZE);
215 restore_emi_after_rank1_mem_test();
216 if (i == 0) {
217 printf("[dramc] 2nd complex mem test pass (start addr:0x%x, 0x0 @Rank1)\n", rank1_start_address);
218 } else {
219 printf("[dramc] 2nd complex mem test fail :%x (start addr:0x%x, 0x0 @Rank1)\n", i, rank1_start_address);
220#ifdef LAST_DRAMC
221 rk1_err = 1;
222#else
223 ASSERT(0);
224#endif
225 }
226 }
227#endif
228
229#ifdef LAST_DRAMC
230 init_ta2_all_channel();
231 dram_fatal_set_cpu_rw_err((rk1_err << 1)|rk0_err);
232
233 /* TODO: TA2 test */
234
235 /* check gating error */
236 check_gating_error();
237
238 if (check_dram_fatal_exception() == 1) {
239 printf("[dramc] fatal dram exception found! reset system..\n");
240 while(1);
241 }
242 dram_fatal_exception_detection_end();
243#endif
244}
245
246// --------------------------------------------------------
247// do memory test
248// --------------------------------------------------------
249#define PATTERN1 0x5A5A5A5A
250#define PATTERN2 0xA5A5A5A5
251
252static int simple_mem_test(unsigned long start, unsigned int len)
253{
254 unsigned int *MEM32_BASE = (unsigned int *) start;
255 unsigned int i, orig_val, new_val;
256
257 for (i = 0; i < (len >> 2); ++i) {
258 orig_val = MEM32_BASE[i];
259 dsb();
260 MEM32_BASE[i] = PATTERN1;
261 dsb();
262 new_val = MEM32_BASE[i];
263 if (new_val != PATTERN1)
264 return -1;
265 dsb();
266 MEM32_BASE[i] = orig_val;
267 }
268
269 return 0;
270}
271
272static int complex_mem_test(unsigned long start, unsigned int len)
273{
274 unsigned char *MEM8_BASE = (unsigned char *) start;
275 unsigned short *MEM16_BASE = (unsigned short *) start;
276 unsigned int *MEM32_BASE = (unsigned int *) start;
277 unsigned int *MEM_BASE = (unsigned int *) start;
278 unsigned char pattern8;
279 unsigned short pattern16;
280 unsigned long i, j, size;
281 unsigned int value, pattern32;
282
283 return 0;
284 size = len >> 2;
285
286 /* === Verify the tied bits (tied high) === */
287 for (i = 0; i < size; i++)
288 {
289 MEM32_BASE[i] = 0;
290 }
291
292 for (i = 0; i < size; i++)
293 {
294 if (MEM32_BASE[i] != 0)
295 {
296 return -1;
297 }
298 else
299 {
300 MEM32_BASE[i] = 0xffffffff;
301 }
302 }
303
304 /* === Verify the tied bits (tied low) === */
305 for (i = 0; i < size; i++)
306 {
307 if (MEM32_BASE[i] != 0xffffffff)
308 {
309 return -2;
310 }
311 else
312 MEM32_BASE[i] = 0x00;
313 }
314
315 /* === Verify pattern 1 (0x00~0xff) === */
316 pattern8 = 0x00;
317 for (i = 0; i < len; i++)
318 MEM8_BASE[i] = pattern8++;
319 pattern8 = 0x00;
320 for (i = 0; i < len; i++)
321 {
322 if (MEM8_BASE[i] != pattern8++)
323 {
324 return -3;
325 }
326 }
327
328 /* === Verify pattern 2 (0x00~0xff) === */
329 pattern8 = 0x00;
330 for (i = j = 0; i < len; i += 2, j++)
331 {
332 if (MEM8_BASE[i] == pattern8)
333 MEM16_BASE[j] = pattern8;
334 if (MEM16_BASE[j] != pattern8)
335 {
336 return -4;
337 }
338 pattern8 += 2;
339 }
340
341 /* === Verify pattern 3 (0x00~0xffff) === */
342 pattern16 = 0x00;
343 for (i = 0; i < (len >> 1); i++)
344 MEM16_BASE[i] = pattern16++;
345 pattern16 = 0x00;
346 for (i = 0; i < (len >> 1); i++)
347 {
348 if (MEM16_BASE[i] != pattern16++)
349 {
350 return -5;
351 }
352 }
353
354 /* === Verify pattern 4 (0x00~0xffffffff) === */
355 pattern32 = 0x00;
356 for (i = 0; i < (len >> 2); i++)
357 MEM32_BASE[i] = pattern32++;
358 pattern32 = 0x00;
359 for (i = 0; i < (len >> 2); i++)
360 {
361 if (MEM32_BASE[i] != pattern32++)
362 {
363 return -6;
364 }
365 }
366
367 /* === Pattern 5: Filling memory range with 0x44332211 === */
368 for (i = 0; i < size; i++)
369 MEM32_BASE[i] = 0x44332211;
370
371 /* === Read Check then Fill Memory with a5a5a5a5 Pattern === */
372 for (i = 0; i < size; i++)
373 {
374 if (MEM32_BASE[i] != 0x44332211)
375 {
376 return -7;
377 }
378 else
379 {
380 MEM32_BASE[i] = 0xa5a5a5a5;
381 }
382 }
383
384 /* === Read Check then Fill Memory with 00 Byte Pattern at offset 0h === */
385 for (i = 0; i < size; i++)
386 {
387 if (MEM32_BASE[i] != 0xa5a5a5a5)
388 {
389 return -8;
390 }
391 else
392 {
393 MEM8_BASE[i * 4] = 0x00;
394 }
395 }
396
397 /* === Read Check then Fill Memory with 00 Byte Pattern at offset 2h === */
398 for (i = 0; i < size; i++)
399 {
400 if (MEM32_BASE[i] != 0xa5a5a500)
401 {
402 return -9;
403 }
404 else
405 {
406 MEM8_BASE[i * 4 + 2] = 0x00;
407 }
408 }
409
410 /* === Read Check then Fill Memory with 00 Byte Pattern at offset 1h === */
411 for (i = 0; i < size; i++)
412 {
413 if (MEM32_BASE[i] != 0xa500a500)
414 {
415 return -10;
416 }
417 else
418 {
419 MEM8_BASE[i * 4 + 1] = 0x00;
420 }
421 }
422
423 /* === Read Check then Fill Memory with 00 Byte Pattern at offset 3h === */
424 for (i = 0; i < size; i++)
425 {
426 if (MEM32_BASE[i] != 0xa5000000)
427 {
428 return -11;
429 }
430 else
431 {
432 MEM8_BASE[i * 4 + 3] = 0x00;
433 }
434 }
435
436 /* === Read Check then Fill Memory with ffff Word Pattern at offset 1h == */
437 for (i = 0; i < size; i++)
438 {
439 if (MEM32_BASE[i] != 0x00000000)
440 {
441 return -12;
442 }
443 else
444 {
445 MEM16_BASE[i * 2 + 1] = 0xffff;
446 }
447 }
448
449
450 /* === Read Check then Fill Memory with ffff Word Pattern at offset 0h == */
451 for (i = 0; i < size; i++)
452 {
453 if (MEM32_BASE[i] != 0xffff0000)
454 {
455 return -13;
456 }
457 else
458 {
459 MEM16_BASE[i * 2] = 0xffff;
460 }
461 }
462
463
464 /*=== Read Check === */
465 for (i = 0; i < size; i++)
466 {
467 if (MEM32_BASE[i] != 0xffffffff)
468 {
469 return -14;
470 }
471 }
472
473
474 /************************************************
475 * Additional verification
476 ************************************************/
477 /* === stage 1 => write 0 === */
478
479 for (i = 0; i < size; i++)
480 {
481 MEM_BASE[i] = PATTERN1;
482 }
483
484
485 /* === stage 2 => read 0, write 0xF === */
486 for (i = 0; i < size; i++)
487 {
488 value = MEM_BASE[i];
489
490 if (value != PATTERN1)
491 {
492 return -15;
493 }
494 MEM_BASE[i] = PATTERN2;
495 }
496
497
498 /* === stage 3 => read 0xF, write 0 === */
499 for (i = 0; i < size; i++)
500 {
501 value = MEM_BASE[i];
502 if (value != PATTERN2)
503 {
504 return -16;
505 }
506 MEM_BASE[i] = PATTERN1;
507 }
508
509
510 /* === stage 4 => read 0, write 0xF === */
511 for (i = 0; i < size; i++)
512 {
513 value = MEM_BASE[i];
514 if (value != PATTERN1)
515 {
516 return -17;
517 }
518 MEM_BASE[i] = PATTERN2;
519 }
520
521
522 /* === stage 5 => read 0xF, write 0 === */
523 for (i = 0; i < size; i++)
524 {
525 value = MEM_BASE[i];
526 if (value != PATTERN2)
527 {
528 return -18;
529 }
530 MEM_BASE[i] = PATTERN1;
531 }
532
533
534 /* === stage 6 => read 0 === */
535 for (i = 0; i < size; i++)
536 {
537 value = MEM_BASE[i];
538 if (value != PATTERN1)
539 {
540 return -19;
541 }
542 }
543
544
545 /* === 1/2/4-byte combination test === */
546 i = (unsigned long) MEM_BASE;
547
548 while (i < (unsigned long) MEM_BASE + (size << 2))
549 {
550 *((unsigned char *) i) = 0x78;
551 i += 1;
552 *((unsigned char *) i) = 0x56;
553 i += 1;
554 *((unsigned short *) i) = 0x1234;
555 i += 2;
556 *((unsigned int *) i) = 0x12345678;
557 i += 4;
558 *((unsigned short *) i) = 0x5678;
559 i += 2;
560 *((unsigned char *) i) = 0x34;
561 i += 1;
562 *((unsigned char *) i) = 0x12;
563 i += 1;
564 *((unsigned int *) i) = 0x12345678;
565 i += 4;
566 *((unsigned char *) i) = 0x78;
567 i += 1;
568 *((unsigned char *) i) = 0x56;
569 i += 1;
570 *((unsigned short *) i) = 0x1234;
571 i += 2;
572 *((unsigned int *) i) = 0x12345678;
573 i += 4;
574 *((unsigned short *) i) = 0x5678;
575 i += 2;
576 *((unsigned char *) i) = 0x34;
577 i += 1;
578 *((unsigned char *) i) = 0x12;
579 i += 1;
580 *((unsigned int *) i) = 0x12345678;
581 i += 4;
582 }
583 for (i = 0; i < size; i++)
584 {
585 value = MEM_BASE[i];
586 if (value != 0x12345678)
587 {
588 return -20;
589 }
590 }
591
592
593 /* === Verify pattern 1 (0x00~0xff) === */
594 pattern8 = 0x00;
595 MEM8_BASE[0] = pattern8;
596 for (i = 0; i < size * 4; i++)
597 {
598 unsigned char waddr8, raddr8;
599 waddr8 = i + 1;
600 raddr8 = i;
601 if (i < size * 4 - 1)
602 MEM8_BASE[waddr8] = pattern8 + 1;
603 if (MEM8_BASE[raddr8] != pattern8)
604 {
605 return -21;
606 }
607 pattern8++;
608 }
609
610
611 /* === Verify pattern 2 (0x00~0xffff) === */
612 pattern16 = 0x00;
613 MEM16_BASE[0] = pattern16;
614 for (i = 0; i < size * 2; i++)
615 {
616 if (i < size * 2 - 1)
617 MEM16_BASE[i + 1] = pattern16 + 1;
618 if (MEM16_BASE[i] != pattern16)
619 {
620 return -22;
621 }
622 pattern16++;
623 }
624
625
626 /* === Verify pattern 3 (0x00~0xffffffff) === */
627 pattern32 = 0x00;
628 MEM32_BASE[0] = pattern32;
629 for (i = 0; i < size; i++)
630 {
631 if (i < size - 1)
632 MEM32_BASE[i + 1] = pattern32 + 1;
633 if (MEM32_BASE[i] != pattern32)
634 {
635 return -23;
636 }
637 pattern32++;
638 }
639
640 return 0;
641}
642
643size_t mt_mem_size(void)
644{
645 /* [TODO] query dram size instead of hardcode */
646 size_t size;
647
648 size = 0x10000000;
649
650 dprintf(CRITICAL, "mt_mem_size %zx\n", size);
651
652 return size;
653}
654