~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 68438c60eb818965d9c3ef965579b6bfd8836bba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
/*
 * arch/arm/cpu/armv8/common/firmware/plat/gxb/ddr/ddr.c
 *
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include <stdio.h>
#include "ddr_pctl_define.h"
#include "ddr_pub_define.h"
#include "dmc_define.h"
#include "mmc_define.h"
#include "sec_mmc_define.h"
#include <timer.h>
#include <asm/arch/ddr.h>
#include <asm/arch/secure_apb.h>
#include <pll.h>
#include <config.h>
#include <asm/arch/cpu.h>
#include <asm/arch/timing.h>
#include <memtest.h>
#include <asm/arch/watchdog.h>
#include <cache.h>
#include "timing.c"
#include "ddr_detect.c"

static ddr_set_t * p_ddr_set = &__ddr_setting;
static ddr_timing_t * p_ddr_timing = NULL;
static unsigned int ddr0_enabled;
static unsigned int ddr1_enabled;

unsigned int ddr_init(void){
	/*detect hot boot or cold boot*/
	//if(hot_boot()){
	//	serial_puts("hot boot, skip ddr init!\n");
	//	return 0;
	//}

	ddr_init_pll();
	ddr_pre_init();
	ddr_init_pctl();
	ddr_init_dmc();
	ddr_print_info();
#ifndef CONFIG_PXP_EMULATOR
//can not enable ddr test on pxp, for kernel and dtb already load in ddr
#ifdef CONFIG_SPL_DDR_DUMP
	if (CONFIG_SPL_DDR_DUMP_FLAG != readl(P_PREG_STICKY_REG0)) {
		ddr_test();
	}
#else
	ddr_test();
#endif
#endif
	return 0;
}

unsigned int ddr_init_pll(void){
	wr_reg(P_AM_ANALOG_TOP_REG1, rd_reg(P_AM_ANALOG_TOP_REG1) | (1<<0));
	wr_reg(P_HHI_MPLL_CNTL5, rd_reg(P_HHI_MPLL_CNTL5) | (1<<0));

	/* DDR PLL BANDGAP */
	wr_reg(AM_DDR_PLL_CNTL4, rd_reg(AM_DDR_PLL_CNTL4) & (~(1<<12)));
	wr_reg(AM_DDR_PLL_CNTL4, rd_reg(AM_DDR_PLL_CNTL4)|(1<<12));
	_udelay(10);

	/* set ddr pll reg */
	if ((p_ddr_set->ddr_clk >= CONFIG_DDR_CLK_LOW) && (p_ddr_set->ddr_clk < 750)) {
		//							OD			N					M
		p_ddr_set->ddr_pll_ctrl = (2 << 16) | (1 << 9) | ((((p_ddr_set->ddr_clk/6)*6)/12) << 0);
	}
	else if((p_ddr_set->ddr_clk >= 750) && (p_ddr_set->ddr_clk < CONFIG_DDR_CLK_HIGH)) {
		//							OD			N					M
		p_ddr_set->ddr_pll_ctrl = (1 << 16) | (1 << 9) | ((((p_ddr_set->ddr_clk/12)*12)/24) << 0);
	}

	/* if enabled, change ddr pll setting */
#ifdef CONFIG_CMD_DDR_TEST
	serial_puts("STICKY_REG0: 0x");
	serial_put_hex(rd_reg(P_PREG_STICKY_REG0), 32);
	serial_puts("\n");
	serial_puts("STICKY_REG1: 0x");
	serial_put_hex(rd_reg(P_PREG_STICKY_REG1), 32);
	serial_puts("\n");
	if ((rd_reg(P_PREG_STICKY_REG0)>>20) == 0xf13) {
		unsigned zqcr = rd_reg(P_PREG_STICKY_REG0) & 0xfffff;
		if (0 == zqcr)
			zqcr = p_ddr_set->t_pub_zq0pr;
		serial_puts("ZQCR: 0x");
		serial_put_hex(p_ddr_set->t_pub_zq0pr, 32);
		serial_puts(" -> 0x");
		serial_put_hex(zqcr, 32);
		serial_puts("\n");
		p_ddr_set->t_pub_zq0pr = zqcr;
		p_ddr_set->t_pub_zq1pr = zqcr;
		p_ddr_set->t_pub_zq2pr = zqcr;
		p_ddr_set->t_pub_zq3pr = zqcr;
		serial_puts("PLL : 0x");
		serial_put_hex(p_ddr_set->ddr_pll_ctrl, 32);
		serial_puts(" -> 0x");
		serial_put_hex(rd_reg(P_PREG_STICKY_REG1), 32);
		serial_puts("\n");
		p_ddr_set->ddr_pll_ctrl = rd_reg(P_PREG_STICKY_REG1);
		wr_reg(P_PREG_STICKY_REG0,0);
		wr_reg(P_PREG_STICKY_REG1,0);
	}
#endif

	/* ddr pll init */
	do {
		//wr_reg(AM_DDR_PLL_CNTL1, 0x1);
		wr_reg(AM_DDR_PLL_CNTL, (1<<29));
		wr_reg(AM_DDR_PLL_CNTL1, CFG_DDR_PLL_CNTL_1);
		wr_reg(AM_DDR_PLL_CNTL2, CFG_DDR_PLL_CNTL_2);
		wr_reg(AM_DDR_PLL_CNTL3, CFG_DDR_PLL_CNTL_3);
		wr_reg(AM_DDR_PLL_CNTL4, CFG_DDR_PLL_CNTL_4);
		wr_reg(AM_DDR_PLL_CNTL, ((1<<29) | (p_ddr_set->ddr_pll_ctrl)));
		wr_reg(AM_DDR_PLL_CNTL, rd_reg(AM_DDR_PLL_CNTL)&(~(1<<29)));
		_udelay(200);
	}while(pll_lock_check(AM_DDR_PLL_CNTL, "DDR PLL"));

	/* Enable the DDR DLL clock input from PLL */
	wr_reg(DDR_CLK_CNTL, 0xb0000000);
	wr_reg(DDR_CLK_CNTL, 0xb0000000);

	/* update ddr_clk */
	unsigned int ddr_pll = rd_reg(AM_DDR_PLL_CNTL)&(~(1<<29));
	unsigned int ddr_clk = 2*(((24 * (ddr_pll&0x1ff))/((ddr_pll>>9)&0x1f))>>((ddr_pll>>16)&0x3));
	p_ddr_set->ddr_clk = ddr_clk;

	return 0;
}

void ddr_print_info(void){
	if (p_ddr_set->ddr_size_detect)
		ddr_size_detect(p_ddr_set);

	unsigned int dmc_reg = rd_reg(DMC_DDR_CTRL);
	unsigned char ddr_2t_mode = 0;
	unsigned char ddr_chl = DDR_USE_2_CHANNEL(p_ddr_set->ddr_channel_set);

	/* 0:1t, 1:2t, 2:f2t(force) */
	ddr_2t_mode = ((rd_reg(DDR0_PCTL_MCFG) >> 3) & 0x1);
	if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC)
		ddr_2t_mode = 2;

	for (int i=0; i<=ddr_chl; i++) {
		/* ddr info */
		serial_puts("DDR");
		serial_put_dec(i);
		serial_puts(": ");
		serial_put_dec(1 << (((dmc_reg>>(3*i)) & 0x7)+7));
		serial_puts("MB");
		if (p_ddr_set->ddr_size_detect)
			serial_puts("(auto)");
		serial_puts(" @ ");
		serial_put_dec(p_ddr_set->ddr_clk);
		serial_puts("MHz(");
		serial_puts(((ddr_2t_mode==2)?"F1T":((ddr_2t_mode==1)?"2T":"1T")));
		serial_puts(")-");
		serial_put_dec(p_ddr_set->ddr_timing_ind);
		serial_puts("\n");
	}

	/* write ddr size to reg */
	wr_reg(SEC_AO_SEC_GP_CFG0, ((rd_reg(SEC_AO_SEC_GP_CFG0) & 0x0000ffff) | ((p_ddr_set->ddr_size) << 16)));
}

unsigned int ddr_init_dmc(void){
	unsigned int ddr0_size = 0, ddr1_size = 0;
	unsigned int ddr0_size_reg = 0, ddr1_size_reg = 0;
//	unsigned int i=0, j=0, convert_reg_size = 6;

	/* transfer correct dmc ctrl setting */
	unsigned int ddr_one_chl = DDR_USE_1_CHANNEL(p_ddr_set->ddr_channel_set);
	ddr0_size = (p_ddr_set->ddr_size)>>(7-ddr_one_chl);
	ddr1_size = ddr_one_chl?0x7:((p_ddr_set->ddr_size)>>7);
	ddr1_size_reg=ddr_one_chl?0x5:0x0;
	while (!((ddr0_size>>=1)&0x1))
		ddr0_size_reg++;
	while (!((ddr1_size>>=1)&0x1))
		ddr1_size_reg++;

	p_ddr_set->ddr_dmc_ctrl &= (~0x3f); //clear ddr capacity reg bits
	p_ddr_set->ddr_dmc_ctrl |= ((ddr0_size_reg)|(ddr1_size_reg<<3));

	wr_reg(DMC_DDR_CTRL, p_ddr_set->ddr_dmc_ctrl);
	if ((p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC)||
		(p_ddr_set->ddr_channel_set == CONFIG_DDR0_ONLY_16BIT))//jiaxing find use 16bit channel 0 only must write map0-4?
	{
		//CONIFG DDR PHY comamnd address map to 32bits linear address.
	   //DDR0 ROW 14:0.   DDR1 ROW 13:0.   COL 9:0.
		wr_reg( DDR0_ADDRMAP_0, ( 0 | 5 << 5 | 6 << 10 | 7 << 15 | 8 << 20 | 9 << 25 ));
		wr_reg( DDR0_ADDRMAP_1, ( 13| 30<< 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 ));
		//wr_reg( DDR0_ADDRMAP_1, ( 0| 0 << 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 ));
		wr_reg( DDR0_ADDRMAP_2, ( 16| 17 << 5 | 18 << 10 | 19 << 15 | 20 << 20 | 21 << 25 ));
		wr_reg( DDR0_ADDRMAP_3, ( 22| 23 << 5 | 24 << 10 | 25 << 15 | 26 << 20 | 27 << 25 ));
		wr_reg( DDR0_ADDRMAP_4, ( 29| 14 << 5 | 15 << 10 | 28 << 15 | 0 << 20 | 0 << 25 ));

		wr_reg( DDR1_ADDRMAP_0, ( 0 | 5 << 5 | 6 << 10 | 7 << 15 | 8 << 20 | 9 << 25 ));
		wr_reg( DDR1_ADDRMAP_1, ( 13| 30<< 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 ));
		//wr_reg( DDR1_ADDRMAP_1, ( 13| 0 << 5 | 0 << 10 | 10 << 15 | 11 << 20 | 12 << 25 ));
		wr_reg( DDR1_ADDRMAP_2, ( 16| 17 << 5 | 18 << 10 | 19 << 15 | 20 << 20 | 21 << 25 ));
		wr_reg( DDR1_ADDRMAP_3, ( 22| 23 << 5 | 24 << 10 | 25 << 15 | 26 << 20 | 27 << 25 ));
		wr_reg( DDR1_ADDRMAP_4, ( 29| 14 << 5 | 15 << 10 | 28 << 15 | 0 << 20 | 0 << 25 ));
	}
	else if(p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME){
		//wr_reg( DDR0_ADDRMAP_1, ( 11| 0 << 5 | 0 << 10 | 0 << 15 | 15 << 20 | 16 << 25 ));
		wr_reg( DDR0_ADDRMAP_1, ( 11| 31 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ));
		wr_reg( DDR0_ADDRMAP_4, ( 30| 12 << 5 | 13 << 10 | 29 << 15 | 0 << 20 | 0 << 25 ));
	}
	else if(p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_DIFF){
		//wr_reg( DDR0_ADDRMAP_1, ( 11| 0 << 5 | 0 << 10 | 0 << 15 | 15 << 20 | 16 << 25 ));
		wr_reg( DDR0_ADDRMAP_1, ( 11| 31 << 5 | 0 << 10 | 14 << 15 | 15 << 20 | 16 << 25 ));
		wr_reg( DDR0_ADDRMAP_4, ( 0| 12 << 5 | 13 << 10 | 29 << 15 | 0 << 20 | 30 << 25 ));
	}

	wr_reg(DMC_PCTL_LP_CTRL, 0x440620);
	//wr_reg(DDR0_APD_CTRL, 0x45);
	wr_reg(DDR0_APD_CTRL, (0x20<<8)|(0x20));
	wr_reg(DDR0_CLK_CTRL, 0x5);

	//  disable AXI port0 (CPU) IRQ/FIQ security control.
	wr_reg(DMC_AXI0_QOS_CTRL1, 0x11);

	//CONFIG DMC security register to enable the all reqeust can access all DDR region.
	wr_reg(DMC_SEC_RANGE_CTRL, 0x0 );
	wr_reg(DMC_SEC_CTRL, 0x80000000 );
	wr_reg(DMC_SEC_AXI_PORT_CTRL, 0x55555555);
	wr_reg(DMC_DEV_SEC_READ_CTRL, 0x55555555 );
	wr_reg(DMC_DEV_SEC_WRITE_CTRL, 0x55555555 );
	wr_reg(DMC_GE2D_SEC_CTRL, 0x15);
	wr_reg(DMC_PARSER_SEC_CTRL, 0x5);
	wr_reg(DMC_VPU_SEC_CFG, 0xffffffff);
	wr_reg(DMC_VPU_SEC_WRITE_CTRL, 0x55555555 );
	wr_reg(DMC_VPU_SEC_READ_CTRL, 0x55555555 );
	wr_reg(DMC_VDEC_SEC_CFG, 0xffffffff);
	wr_reg(DMC_VDEC_SEC_WRITE_CTRL, 0x55555555 );
	wr_reg(DMC_VDEC_SEC_READ_CTRL, 0x55555555 );
	wr_reg(DMC_HCODEC_SEC_CFG, 0xffffffff);
	wr_reg(DMC_HCODEC_SEC_WRITE_CTRL, 0x55555555 );
	wr_reg(DMC_HCODEC_SEC_READ_CTRL, 0x55555555 );
	wr_reg(DMC_HEVC_SEC_CFG, 0xffffffff);
	wr_reg(DMC_HEVC_SEC_WRITE_CTRL, 0x55555555 );
	wr_reg(DMC_HEVC_SEC_READ_CTRL, 0x55555555 );

	//// ENABLE THE DC_REQS.
	wr_reg(DMC_REQ_CTRL, 0xFFFF);

	// SCRATCH1
	wr_reg(0xC1107d40, 0xbaadf00d);

	// PUT SOME CODE HERE TO TRY TO STOP BUS TRAFFIC
	__asm__ volatile("NOP");
	__asm__ volatile("DMB SY");
	__asm__ volatile("ISB");

	//  REMAP THE ADDRESS SPACE BY WRITING TO NIC400 REMAP REGISTER
	//wr_reg(0xC1300000, 0x00000001);
	//__asm__ volatile("ISB");
	//__asm__ volatile("DMB SY");

	return 0;
}

unsigned int ddr_init_pctl(void){
	ddr0_enabled = !(((p_ddr_set->ddr_dmc_ctrl) >> 7) & 0x1); //check if ddr1 only enabled
	ddr1_enabled = !(((p_ddr_set->ddr_dmc_ctrl) >> 6) & 0x1); //check if ddr0 only enabled

	// RELEASE THE DDR DLL RESET PIN.
	wr_reg(DMC_SOFT_RST, 0xFFFFFFFF);
	wr_reg(DMC_SOFT_RST1, 0xFFFFFFFF);

	// ENABLE UPCTL AND PUB CLOCK AND RESET.
	//@@@ enable UPCTL and PUB clock and reset.
	wr_reg(DMC_PCTL_LP_CTRL, 0x550620);
	wr_reg(DDR0_SOFT_RESET, 0xf);

	// INITIALIZATION PHY.
	// FOR SIMULATION TO REDUCE THE INIT TIME.
	//wr_reg(DDR0_PUB_PTR0, p_ddr_set->t_pub_ptr[0]);
	//wr_reg(DDR0_PUB_PTR1, p_ddr_set->t_pub_ptr[1]);
	//wr_reg(DDR0_PUB_PTR3, p_ddr_set->t_pub_ptr[3]);
	//wr_reg(DDR0_PUB_PTR4, p_ddr_set->t_pub_ptr[4]);

	wr_reg(DDR0_PUB_IOVCR0, 0x49494949);
	wr_reg(DDR0_PUB_IOVCR1, 0x49494949);

	// CONFIGURE DDR PHY PUBL REGISTERS.
	wr_reg(DDR0_PUB_ODTCR, p_ddr_set->t_pub_odtcr);

	// PROGRAM PUB MRX REGISTERS.
	wr_reg(DDR0_PUB_MR0, p_ddr_set->t_pub_mr[0]);
	wr_reg(DDR0_PUB_MR1, p_ddr_set->t_pub_mr[1]);
	wr_reg(DDR0_PUB_MR2, p_ddr_set->t_pub_mr[2]);
	wr_reg(DDR0_PUB_MR3, p_ddr_set->t_pub_mr[3]);

	// PROGRAM DDR SDRAM TIMING PARAMETER.
	wr_reg(DDR0_PUB_DTPR0, p_ddr_set->t_pub_dtpr[0]);
	wr_reg(DDR0_PUB_DTPR1, p_ddr_set->t_pub_dtpr[1]);
	//wr_reg(DDR0_PUB_PGCR0, p_ddr_set->t_pub_pgcr0); //Jiaxing debug low freq issue
	wr_reg(DDR0_PUB_PGCR1, p_ddr_set->t_pub_pgcr1);
	wr_reg(DDR0_PUB_PGCR2, p_ddr_set->t_pub_pgcr2);
	//wr_reg(DDR0_PUB_PGCR2, 0x00f05f97);
	wr_reg(DDR0_PUB_PGCR3, p_ddr_set->t_pub_pgcr3);
	wr_reg(DDR0_PUB_DXCCR, p_ddr_set->t_pub_dxccr);

	wr_reg(DDR0_PUB_DTPR2, p_ddr_set->t_pub_dtpr[2]);
	wr_reg(DDR0_PUB_DTPR3, p_ddr_set->t_pub_dtpr[3]);
	wr_reg(DDR0_PUB_DTCR, p_ddr_set->t_pub_dtcr); //use mpr |(1<<6)

	//DDR0_DLL_LOCK_WAIT
	wait_set(DDR0_PUB_PGSR0, 0);

	//wr_reg(DDR0_PUB_DTCR, 0x430030c7);
	//wr_reg(DDR0_PUB_DTPR3, 0x2010a902); //tmp disable
	wr_reg(DDR0_PUB_ACIOCR1, 0);
	wr_reg(DDR0_PUB_ACIOCR2, 0);
	wr_reg(DDR0_PUB_ACIOCR3, 0);
	wr_reg(DDR0_PUB_ACIOCR4, 0);
	wr_reg(DDR0_PUB_ACIOCR5, 0);
	wr_reg(DDR0_PUB_DX0GCR1, 0);
	wr_reg(DDR0_PUB_DX0GCR2, 0);
	wr_reg(DDR0_PUB_DX0GCR3, (0x1<<10)|(0x2<<12)); //power down dm recevier
	wr_reg(DDR0_PUB_DX1GCR1, 0);
	wr_reg(DDR0_PUB_DX1GCR2, 0);
	wr_reg(DDR0_PUB_DX1GCR3, (0x1<<10)|(0x2<<12));//power down dm recevier
	wr_reg(DDR0_PUB_DX2GCR1, 0);
	wr_reg(DDR0_PUB_DX2GCR2, 0);
	wr_reg(DDR0_PUB_DX2GCR3, (0x1<<10)|(0x2<<12));//power down dm recevier
	wr_reg(DDR0_PUB_DX3GCR1, 0);
	wr_reg(DDR0_PUB_DX3GCR2, 0);
	wr_reg(DDR0_PUB_DX3GCR3, (0x1<<10)|(0x2<<12));//power down dm recevier

	//   2:0   011: DDR0_ MODE.   100:   LPDDR2 MODE.
	//   3:    8 BANK.
	//   7;    MPR FOR DATA TRAINING.
	wr_reg(DDR0_PUB_DCR, p_ddr_set->t_pub_dcr); //use mpr |(1<<7)

	wr_reg(DDR0_PUB_DTAR0, p_ddr_set->t_pub_dtar);
	wr_reg(DDR0_PUB_DTAR1, (0X8 | p_ddr_set->t_pub_dtar));
	wr_reg(DDR0_PUB_DTAR2, (0X10 | p_ddr_set->t_pub_dtar));
	wr_reg(DDR0_PUB_DTAR3, (0X18 | p_ddr_set->t_pub_dtar));

	//// DDR PHY INITIALIZATION
#ifdef CONFIG_PXP_EMULATOR
	wr_reg(DDR0_PUB_PIR, 0X581);
#endif
	wr_reg(DDR0_PUB_DSGCR, p_ddr_set->t_pub_dsgcr);

	//DDR0_SDRAM_INIT_WAIT :
	wait_set(DDR0_PUB_PGSR0, 0);

	if (ddr0_enabled) {
		// configure DDR0 IP.
		wr_reg(DDR0_PCTL_TOGCNT1U, p_ddr_set->t_pctl0_1us_pck);
		wr_reg(DDR0_PCTL_TOGCNT100N, p_ddr_set->t_pctl0_100ns_pck);
		wr_reg(DDR0_PCTL_TINIT, p_ddr_set->t_pctl0_init_us); //20
		wr_reg(DDR0_PCTL_TRSTH, p_ddr_set->t_pctl0_rsth_us); //50
		wr_reg(DDR0_PCTL_MCFG, (p_ddr_set->t_pctl0_mcfg)|((p_ddr_set->ddr_2t_mode)?(1<<3):(0<<3)));
		if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC)
			wr_reg(DDR0_PCTL_MCFG1, ((p_ddr_set->t_pctl0_mcfg1)&0xFFFFFF00));
		else
			wr_reg(DDR0_PCTL_MCFG1, p_ddr_set->t_pctl0_mcfg1);
	}

	if (ddr1_enabled) {
		// configure DDR1 IP.
		wr_reg(DDR1_PCTL_TOGCNT1U, p_ddr_set->t_pctl0_1us_pck);
		wr_reg(DDR1_PCTL_TOGCNT100N, p_ddr_set->t_pctl0_100ns_pck);
		wr_reg(DDR1_PCTL_TINIT, p_ddr_set->t_pctl0_init_us); //20
		wr_reg(DDR1_PCTL_TRSTH, p_ddr_set->t_pctl0_rsth_us); //50
		wr_reg(DDR1_PCTL_MCFG, (p_ddr_set->t_pctl0_mcfg)|((p_ddr_set->ddr_2t_mode)?(1<<3):(0<<3)));
		//wr_reg(DDR1_PCTL_MCFG1, p_ddr_set->t_pctl0_mcfg1);
		if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC)
			wr_reg(DDR1_PCTL_MCFG1, ((p_ddr_set->t_pctl0_mcfg1)&0xFFFFFF00));
		else
			wr_reg(DDR1_PCTL_MCFG1, p_ddr_set->t_pctl0_mcfg1);
	}

	_udelay(500);

	// MONITOR DFI INITIALIZATION STATUS.
	if (ddr0_enabled) {
		wait_set(DDR0_PCTL_DFISTSTAT0, 0);
		wr_reg(DDR0_PCTL_POWCTL, 1);
		//DDR0_POWER_UP_WAIT
		wait_set(DDR0_PCTL_POWSTAT, 0);
	}
	if (ddr1_enabled) {
		wait_set(DDR1_PCTL_DFISTSTAT0, 0);
		wr_reg(DDR1_PCTL_POWCTL, 1);
		//DDR0_POWER_UP_WAIT
		wait_set(DDR1_PCTL_POWSTAT, 0);
	}

	if (ddr0_enabled) {
		wr_reg(DDR0_PCTL_TRFC, p_ddr_timing->cfg_ddr_rfc);
		wr_reg(DDR0_PCTL_TREFI_MEM_DDR3, p_ddr_timing->cfg_ddr_refi_mddr3);
		wr_reg(DDR0_PCTL_TMRD, p_ddr_timing->cfg_ddr_mrd);
		wr_reg(DDR0_PCTL_TRP, p_ddr_timing->cfg_ddr_rp);
		wr_reg(DDR0_PCTL_TAL, p_ddr_timing->cfg_ddr_al);
		wr_reg(DDR0_PCTL_TCWL, p_ddr_timing->cfg_ddr_cwl);
		wr_reg(DDR0_PCTL_TCL, p_ddr_timing->cfg_ddr_cl);
		wr_reg(DDR0_PCTL_TRAS, p_ddr_timing->cfg_ddr_ras);
		wr_reg(DDR0_PCTL_TRC, p_ddr_timing->cfg_ddr_rc);
		wr_reg(DDR0_PCTL_TRCD, p_ddr_timing->cfg_ddr_rcd);
		wr_reg(DDR0_PCTL_TRRD, p_ddr_timing->cfg_ddr_rrd);
		wr_reg(DDR0_PCTL_TRTP, p_ddr_timing->cfg_ddr_rtp);
		wr_reg(DDR0_PCTL_TWR, p_ddr_timing->cfg_ddr_wr);
		wr_reg(DDR0_PCTL_TWTR, p_ddr_timing->cfg_ddr_wtr);
		wr_reg(DDR0_PCTL_TEXSR, p_ddr_timing->cfg_ddr_exsr);
		wr_reg(DDR0_PCTL_TXP, p_ddr_timing->cfg_ddr_xp);
		wr_reg(DDR0_PCTL_TDQS, p_ddr_timing->cfg_ddr_dqs);
		wr_reg(DDR0_PCTL_TRTW, p_ddr_timing->cfg_ddr_rtw);
		wr_reg(DDR0_PCTL_TCKSRE, p_ddr_timing->cfg_ddr_cksre);
		wr_reg(DDR0_PCTL_TCKSRX, p_ddr_timing->cfg_ddr_cksrx);
		wr_reg(DDR0_PCTL_TMOD, p_ddr_timing->cfg_ddr_mod);
		wr_reg(DDR0_PCTL_TCKE, p_ddr_timing->cfg_ddr_cke);
		wr_reg(DDR0_PCTL_TCKESR, p_ddr_timing->cfg_ddr_cke+1);
		wr_reg(DDR0_PCTL_TZQCS, p_ddr_timing->cfg_ddr_zqcs);
		wr_reg(DDR0_PCTL_TZQCL, p_ddr_timing->cfg_ddr_zqcl);
		wr_reg(DDR0_PCTL_TXPDLL, p_ddr_timing->cfg_ddr_xpdll);
		wr_reg(DDR0_PCTL_TZQCSI, p_ddr_timing->cfg_ddr_zqcsi);
	}

	if (ddr1_enabled) {
		wr_reg(DDR1_PCTL_TRFC, p_ddr_timing->cfg_ddr_rfc);
		wr_reg(DDR1_PCTL_TREFI_MEM_DDR3, p_ddr_timing->cfg_ddr_refi_mddr3);
		wr_reg(DDR1_PCTL_TMRD, p_ddr_timing->cfg_ddr_mrd);
		wr_reg(DDR1_PCTL_TRP, p_ddr_timing->cfg_ddr_rp);
		wr_reg(DDR1_PCTL_TAL, p_ddr_timing->cfg_ddr_al);
		wr_reg(DDR1_PCTL_TCWL, p_ddr_timing->cfg_ddr_cwl);
		wr_reg(DDR1_PCTL_TCL, p_ddr_timing->cfg_ddr_cl);
		wr_reg(DDR1_PCTL_TRAS, p_ddr_timing->cfg_ddr_ras);
		wr_reg(DDR1_PCTL_TRC, p_ddr_timing->cfg_ddr_rc);
		wr_reg(DDR1_PCTL_TRCD, p_ddr_timing->cfg_ddr_rcd);
		wr_reg(DDR1_PCTL_TRRD, p_ddr_timing->cfg_ddr_rrd);
		wr_reg(DDR1_PCTL_TRTP, p_ddr_timing->cfg_ddr_rtp);
		wr_reg(DDR1_PCTL_TWR, p_ddr_timing->cfg_ddr_wr);
		wr_reg(DDR1_PCTL_TWTR, p_ddr_timing->cfg_ddr_wtr);
		wr_reg(DDR1_PCTL_TEXSR, p_ddr_timing->cfg_ddr_exsr);
		wr_reg(DDR1_PCTL_TXP, p_ddr_timing->cfg_ddr_xp);
		wr_reg(DDR1_PCTL_TDQS, p_ddr_timing->cfg_ddr_dqs);
		wr_reg(DDR1_PCTL_TRTW, p_ddr_timing->cfg_ddr_rtw);
		wr_reg(DDR1_PCTL_TCKSRE, p_ddr_timing->cfg_ddr_cksre);
		wr_reg(DDR1_PCTL_TCKSRX, p_ddr_timing->cfg_ddr_cksrx);
		wr_reg(DDR1_PCTL_TMOD, p_ddr_timing->cfg_ddr_mod);
		wr_reg(DDR1_PCTL_TCKE, p_ddr_timing->cfg_ddr_cke);
		wr_reg(DDR1_PCTL_TCKESR, p_ddr_timing->cfg_ddr_cke+1);
		wr_reg(DDR1_PCTL_TZQCS, p_ddr_timing->cfg_ddr_zqcs);
		wr_reg(DDR1_PCTL_TZQCL, p_ddr_timing->cfg_ddr_zqcl);
		wr_reg(DDR1_PCTL_TXPDLL, p_ddr_timing->cfg_ddr_xpdll);
		wr_reg(DDR1_PCTL_TZQCSI, p_ddr_timing->cfg_ddr_zqcsi);
	}

	if (ddr0_enabled) {
		wr_reg(DDR0_PCTL_SCFG, p_ddr_set->t_pctl0_scfg);
		wr_reg(DDR0_PCTL_SCTL, p_ddr_set->t_pctl0_sctl);
	}

	if (ddr1_enabled) {
		wr_reg(DDR1_PCTL_SCFG, p_ddr_set->t_pctl0_scfg);
		wr_reg(DDR1_PCTL_SCTL, p_ddr_set->t_pctl0_sctl);
	}

	// SCRATCH1
	wr_reg(0xC1107d40, 0xdeadbeef);

	// NEW HIU
	wr_reg(0xC883c010, 0x88776655);

	//DDR0_STAT_CONFIG_WAIT
	if (ddr0_enabled)
		wait_set(DDR0_PCTL_STAT, 0);
	if (ddr1_enabled)
		wait_set(DDR1_PCTL_STAT, 0);

	if (ddr0_enabled) {
		wr_reg(DDR0_PCTL_PPCFG, p_ddr_set->t_pctl0_ppcfg); /* 16bit or 32bit mode */
		wr_reg(DDR0_PCTL_DFISTCFG0, p_ddr_set->t_pctl0_dfistcfg0);
		wr_reg(DDR0_PCTL_DFISTCFG1, p_ddr_set->t_pctl0_dfistcfg1);
		wr_reg(DDR0_PCTL_DFITCTRLDELAY, p_ddr_set->t_pctl0_dfitctrldelay);
		wr_reg(DDR0_PCTL_DFITPHYWRDATA, p_ddr_set->t_pctl0_dfitphywrdata);
		wr_reg(DDR0_PCTL_DFITPHYWRLAT, p_ddr_set->t_pctl0_dfitphywrlta);
		wr_reg(DDR0_PCTL_DFITRDDATAEN, p_ddr_set->t_pctl0_dfitrddataen);
		wr_reg(DDR0_PCTL_DFITPHYRDLAT, p_ddr_set->t_pctl0_dfitphyrdlat);
		wr_reg(DDR0_PCTL_DFITDRAMCLKDIS, p_ddr_set->t_pctl0_dfitdramclkdis);
		wr_reg(DDR0_PCTL_DFITDRAMCLKEN, p_ddr_set->t_pctl0_dfitdramclken);
		wr_reg(DDR0_PCTL_DFILPCFG0, p_ddr_set->t_pctl0_dfilpcfg0);
		wr_reg(DDR0_PCTL_DFITPHYUPDTYPE1, p_ddr_set->t_pctl0_dfitphyupdtype1);
		wr_reg(DDR0_PCTL_DFITCTRLUPDMIN, p_ddr_set->t_pctl0_dfitctrlupdmin);
		wr_reg(DDR0_PCTL_DFIODTCFG, p_ddr_set->t_pctl0_dfiodtcfg);
		wr_reg(DDR0_PCTL_DFIODTCFG1, p_ddr_set->t_pctl0_dfiodtcfg1);
		wr_reg(DDR0_PCTL_CMDTSTATEN, p_ddr_set->t_pctl0_cmdtstaten);
	}

	if (ddr1_enabled) {
		wr_reg(DDR1_PCTL_PPCFG, p_ddr_set->t_pctl0_ppcfg); /* 16bit or 32bit mode */
		wr_reg(DDR1_PCTL_DFISTCFG0, p_ddr_set->t_pctl0_dfistcfg0);
		wr_reg(DDR1_PCTL_DFISTCFG1, p_ddr_set->t_pctl0_dfistcfg1);
		wr_reg(DDR1_PCTL_DFITCTRLDELAY, p_ddr_set->t_pctl0_dfitctrldelay);
		wr_reg(DDR1_PCTL_DFITPHYWRDATA, p_ddr_set->t_pctl0_dfitphywrdata);
		wr_reg(DDR1_PCTL_DFITPHYWRLAT, p_ddr_set->t_pctl0_dfitphywrlta);
		wr_reg(DDR1_PCTL_DFITRDDATAEN, p_ddr_set->t_pctl0_dfitrddataen);
		wr_reg(DDR1_PCTL_DFITPHYRDLAT, p_ddr_set->t_pctl0_dfitphyrdlat);
		wr_reg(DDR1_PCTL_DFITDRAMCLKDIS, p_ddr_set->t_pctl0_dfitdramclkdis);
		wr_reg(DDR1_PCTL_DFITDRAMCLKEN, p_ddr_set->t_pctl0_dfitdramclken);
		wr_reg(DDR1_PCTL_DFILPCFG0, p_ddr_set->t_pctl0_dfilpcfg0);
		wr_reg(DDR1_PCTL_DFITPHYUPDTYPE1, p_ddr_set->t_pctl0_dfitphyupdtype1);
		wr_reg(DDR1_PCTL_DFITCTRLUPDMIN, p_ddr_set->t_pctl0_dfitctrlupdmin);
		wr_reg(DDR1_PCTL_DFIODTCFG, p_ddr_set->t_pctl0_dfiodtcfg);
		wr_reg(DDR1_PCTL_DFIODTCFG1, p_ddr_set->t_pctl0_dfiodtcfg1);
		wr_reg(DDR1_PCTL_CMDTSTATEN, p_ddr_set->t_pctl0_cmdtstaten);
	}

#ifndef CONFIG_PXP_EMULATOR
	wr_reg(DDR0_PUB_ZQ0PR, p_ddr_set->t_pub_zq0pr);
	wr_reg(DDR0_PUB_ZQ1PR, p_ddr_set->t_pub_zq1pr);
	wr_reg(DDR0_PUB_ZQ2PR, p_ddr_set->t_pub_zq2pr);
	wr_reg(DDR0_PUB_ZQ3PR, p_ddr_set->t_pub_zq3pr);

	wr_reg(DDR0_PUB_PIR, 3);
	wait_set(DDR0_PUB_PGSR0, 0);
	wr_reg(DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))|(1<<2)|(1<<27)); //jiaxing debug must force update
	_udelay(10);
	wr_reg(DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))&(~((1<<2)|(1<<27))));
	_udelay(30);
	if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_ONLY_16BIT)
	{
		wr_reg(DDR0_PUB_DX2GCR0, (0xfffffffe&rd_reg(DDR0_PUB_DX2GCR0)));
		wr_reg(DDR0_PUB_DX3GCR0, (0xfffffffe&rd_reg(DDR0_PUB_DX3GCR0)));
	}

#ifdef CONFIG_DDR_CMD_BDL_TUNE
	wr_reg(DDR0_PUB_ACLCDLR, DDR_AC_LCDLR);  //ck0
	wr_reg(DDR0_PUB_ACBDLR0, DDR_CK0_BDL);  //ck0
	wr_reg(DDR0_PUB_ACBDLR1, (DDR_WE_BDL<<16)|(DDR_CAS_BDL<<8)|(DDR_RAS_BDL)); //ras cas we
	wr_reg(DDR0_PUB_ACBDLR2, ((DDR_ACPDD_BDL<<24)|(DDR_BA2_BDL<<16)|(DDR_BA1_BDL<<8)|(DDR_BA0_BDL))); //ba0 ba1 ba2
	wr_reg(DDR0_PUB_ACBDLR3, ((DDR_CS1_BDL<<8)|(DDR_CS0_BDL)));  //cs0 cs1
	wr_reg(DDR0_PUB_ACBDLR4, ((DDR_ODT1_BDL<<8)|(DDR_ODT0_BDL))); //odt0 odt1
	wr_reg(DDR0_PUB_ACBDLR5, ((DDR_CKE1_BDL<<8)|(DDR_CKE0_BDL)));  //cke0 cke1
	wr_reg(DDR0_PUB_ACBDLR6, ((DDR_A3_BDL<<24)|(DDR_A2_BDL<<16)|(DDR_A1_BDL<<8)|(DDR_A0_BDL))); //a0 a1 a2 a3
	wr_reg(DDR0_PUB_ACBDLR7, ((DDR_A7_BDL<<24)|(DDR_A6_BDL<<16)|(DDR_A5_BDL<<8)|(DDR_A4_BDL))); //a4 a5 a6 a7
	wr_reg(DDR0_PUB_ACBDLR8, ((DDR_A11_BDL<<24)|(DDR_A10_BDL<<16)|(DDR_A9_BDL<<8)|(DDR_A8_BDL)));  //a8 a9 a10 a11
	wr_reg(DDR0_PUB_ACBDLR9, ((DDR_A15_BDL<<24)|(DDR_A14_BDL<<16)|(DDR_A13_BDL<<8)|(DDR_A12_BDL)));  //a12 a13 a14 a15
#endif

	wr_reg(DDR0_PUB_PIR, (DDR_PIR | PUB_PIR_INIT));
	do {
		_udelay(20);
	} while(DDR_PGSR0_CHECK());
#endif

	if ((p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK0_ONLY) || \
		(p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME))
	{
		unsigned int i=0, j=0;
		i=(rd_reg(DDR0_PUB_DX2LCDLR0));
		wr_reg(DDR0_PUB_DX2LCDLR0,((i>>8)|(i&(0xffffff00))));
		i=(((rd_reg(DDR0_PUB_DX2GTR))>>3)&((7<<0)));
		j=(((rd_reg(DDR0_PUB_DX2GTR))>>14)&((3<<0)));
		wr_reg(DDR0_PUB_DX2GTR,i|(i<<3)|(j<<12)|(j<<14));
		i=(rd_reg(DDR0_PUB_DX2LCDLR2));
		wr_reg(DDR0_PUB_DX2LCDLR2,((i>>8)|(i&(0xffffff00))));
		i=(rd_reg(DDR0_PUB_DX3LCDLR0));
		wr_reg(DDR0_PUB_DX3LCDLR0,((i>>8)|(i&(0xffffff00))));
		i=(((rd_reg(DDR0_PUB_DX3GTR))>>3)&((7<<0)));
		j=(((rd_reg(DDR0_PUB_DX3GTR))>>14)&((3<<0)));
		wr_reg(DDR0_PUB_DX3GTR,i|(i<<3)|(j<<12)|(j<<14));
		i=(rd_reg(DDR0_PUB_DX3LCDLR2));
		wr_reg(DDR0_PUB_DX3LCDLR2,((i>>8)|(i&(0xffffff00))));
		i=(rd_reg(DDR0_PUB_DX0LCDLR0));
		wr_reg(DDR0_PUB_DX0LCDLR0,((i<<8)|(i&(0xffff00ff))));
		i=(((rd_reg(DDR0_PUB_DX0GTR))<<0)&((7<<0)));
		j=(((rd_reg(DDR0_PUB_DX0GTR))>>12)&((3<<0)));
		wr_reg(DDR0_PUB_DX0GTR,i|(i<<3)|(j<<12)|(j<<14));
		i=(rd_reg(DDR0_PUB_DX0LCDLR2));
		wr_reg(DDR0_PUB_DX0LCDLR2,((i<<8)|(i&(0xffff00ff))));
		i=(rd_reg(DDR0_PUB_DX1LCDLR0));
		wr_reg(DDR0_PUB_DX1LCDLR0,((i<<8)|(i&(0xffff00ff))));
		i=(((rd_reg(DDR0_PUB_DX1GTR))<<0)&((7<<0)));
		j=(((rd_reg(DDR0_PUB_DX1GTR))>>12)&((3<<0)));
		wr_reg(DDR0_PUB_DX1GTR,i|(i<<3)|(j<<12)|(j<<14));
		i=(rd_reg(DDR0_PUB_DX1LCDLR2));
		wr_reg(DDR0_PUB_DX1LCDLR2,((i<<8)|(i&(0xffff00ff))));
	}
	if ((p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK0_ONLY) || \
		(p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME) || \
		(p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_DIFF)) {
		//wr_reg(DDR0_PUB_PGCR2,((((1<<28))|p_ddr_set->t_pub_pgcr2)));
		wr_reg(DDR0_PUB_PGCR2,(((~(1<<28))&p_ddr_set->t_pub_pgcr2)));
	}

	if ((p_ddr_set->ddr_2t_mode) && \
		(p_ddr_set->ddr_channel_set != CONFIG_DDR01_SHARE_AC) && \
		(((p_ddr_set->t_pub_dcr)&0x7)== 0x3)) {
		//jiaxing mark----must place after training ,because training is 1t mode  ,if delay too much training will not ok
		wr_reg(DDR0_PUB_ACLCDLR, 0x1f);  //delay cmd/address 2t signle not effect cs cke odt
		//wr_reg(DDR0_PUB_ACBDLR0, 0x10);  //ck0
		/*
		wr_reg(DDR0_PUB_ACBDLR1, (0x18<<16)|(0x18<<8)|(0x18)); //ras cas we
		wr_reg(DDR0_PUB_ACBDLR2, ((0x18<<16)|(0x18<<8)|(0x18))); //ba0 ba1 ba2
		//wr_reg(DDR0_PUB_ACBDLR3, ((0<<8)|(0)));  //cs0 cs1
		//wr_reg(DDR0_PUB_ACBDLR4, ((0<<8)|(0))); //odt0 odt1
		//wr_reg(DDR0_PUB_ACBDLR5, ((0<<8)|(0)));  //cke0 cke1
		wr_reg(DDR0_PUB_ACBDLR6, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18))); //a0 a1 a2 a3
		wr_reg(DDR0_PUB_ACBDLR7, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18))); //a4 a5 a6 a7
		wr_reg(DDR0_PUB_ACBDLR8, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18)));  //a8 a9 a10 a11
		wr_reg(DDR0_PUB_ACBDLR9, ((0x18<<24)|(0x18<<16)|(0x18<<8)|(0x18)));  //a12 a13 a14 a15
		*/
	}
	//DDR0_CMD_TIMER_WAIT
	if (ddr0_enabled)
		wait_set(DDR0_PCTL_CMDTSTAT, 0);
	if (ddr1_enabled)
		wait_set(DDR1_PCTL_CMDTSTAT, 0);

	////APB_WR(PCTL_PCTL_SCTL, 2); // INIT: 0, CFG: 1, GO: 2, SLEEP: 3, WAKEUP: 4
	if (ddr0_enabled)
		wr_reg(DDR0_PCTL_SCTL, UPCTL_CMD_GO);
	if (ddr1_enabled)
		wr_reg(DDR1_PCTL_SCTL, UPCTL_CMD_GO);

	////WHILE ((APB_RD(DDR0_PCTL_STAT) & 0x7 ) != 3 ) {}
	//DDR0_STAT_GO_WAIT:
	if (ddr0_enabled)
		wait_equal(DDR0_PCTL_STAT, UPCTL_STAT_ACCESS);
	if (ddr1_enabled)
		wait_equal(DDR1_PCTL_STAT, UPCTL_STAT_ACCESS);

	wr_reg( DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))|(1<<2));
	wr_reg( DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))&(~(1<<2)));

/* power down zq for power saving */
#ifdef CONFIG_DDR_ZQ_POWER_DOWN
	wr_reg( DDR0_PUB_ZQCR,(rd_reg(DDR0_PUB_ZQCR))|(1<<2));
#endif

/* power down phy vref for power saving */
#ifdef CONFIG_DDR_POWER_DOWN_PHY_VREF
	wr_reg(DDR0_PUB_IOVCR0, 0);
	wr_reg(DDR0_PUB_IOVCR1, 0);
#endif

	//// ENABLE THE DMC AUTO REFRESH FUNCTION
	if (ddr0_enabled) {
		wr_reg(DMC_REFR_CTRL1, 0X8800191|(0x3<<2)|(0x1<<0));
		rd_reg(DDR0_PCTL_MCFG);
	}
	if (ddr1_enabled) {
		wr_reg(DMC_REFR_CTRL1, 0X8800191|(0x3<<2)|(0x1<<1));
		rd_reg(DDR1_PCTL_MCFG);
	}
	wr_reg(DMC_REFR_CTRL2, 0X20100000|(p_ddr_set->ddr_clk/20)|(39<<8));

	return 0;
}

void ddr_pre_init(void){
	/* find match ddr timing */
	if ((p_ddr_set->ddr_clk >= CONFIG_DDR_CLK_LOW) && (p_ddr_set->ddr_clk < 533)) {
		p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_7;
	}
	else if ((p_ddr_set->ddr_clk >= 533) && (p_ddr_set->ddr_clk < 667)) {
		p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_9;
	}
	else if ((p_ddr_set->ddr_clk >= 667) && (p_ddr_set->ddr_clk < 800)) {
		p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_11;
	}
	else if ((p_ddr_set->ddr_clk >= 800) && (p_ddr_set->ddr_clk < 933)) {
		p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_13;
	}
	else if ((p_ddr_set->ddr_clk >= 933) && (p_ddr_set->ddr_clk < CONFIG_DDR_CLK_HIGH)) {
		p_ddr_set->ddr_timing_ind = CONFIG_DDR_TIMMING_DDR3_14;
	}
	else {
		serial_puts("DDR clk setting error! Reset...\n");
		reset_system();
	}

	p_ddr_set->t_pctl0_1us_pck = (p_ddr_set->ddr_clk / 2);
	p_ddr_set->t_pctl0_100ns_pck = (p_ddr_set->ddr_clk / 20);

	/* get match timing config */
	unsigned loop;
	for (loop = 0; loop < (sizeof(__ddr_timming)/sizeof(ddr_timing_t)); loop++) {
		if (__ddr_timming[loop].identifier == p_ddr_set->ddr_timing_ind) {
			p_ddr_timing = &__ddr_timming[loop];
			break;
		}
	}
	if (NULL == p_ddr_timing) {
		serial_puts("Can't find ddr timing setting! Reset...\n");
		reset_system();
	}

	unsigned int ddr_dual_rank_sel = 0;
	unsigned int ddr_chl_set = 0;

	//BIT22. 1:RANK1 IS SAME AS RANK0
	//BIT21. 0:SEC RANK DISABLE, 1:SEC RANK ENABLE
	//BIT20. SHARE AC MODE, 0:DISABLE, 1:ENABLE
	if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK0_ONLY) {
		serial_puts("DDR channel setting: DDR0 Rank0 only\n");
		ddr_chl_set = ((0x2 << 20)		| //b'010: BIT22, BIT21, BIT20
					(0 << 16)			| //BIT[17:16], DDR0_DDR1 DATA WIDTH, 0:32BIT, 1:16BIT
					(1 << 6));			  //b'00:DDR0_DDR1, b'01: DDR0_ONLY, b'10:DDR1_ONLY
		ddr_dual_rank_sel = 0; //SET PGCR2[28], RANK0 AND RANK1 USE SAME RANK SELECT SIGNAL
		p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1);
		p_ddr_set->t_pctl0_dfiodtcfg = 0x0808;
	}
	else if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_SAME) {
		serial_puts("DDR channel setting: DDR0 Rank0+1 same\n");
		ddr_chl_set = ((0x4 << 20) | (0 << 16) | (1 << 6));
		ddr_dual_rank_sel = 1;
		p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1);
		p_ddr_set->t_pctl0_dfiodtcfg = 0x08;
	}
	else if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_RANK01_DIFF) {
		serial_puts("DDR channel setting: DDR0 Rank0+1 diff\n");
		ddr_chl_set = ((0x2 << 20) | (0 << 16) | (1 << 6));
		ddr_dual_rank_sel = 0;
		p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1);
		p_ddr_set->t_pctl0_dfiodtcfg = 0x08;
	}
	else if (p_ddr_set->ddr_channel_set == CONFIG_DDR0_ONLY_16BIT) {
		serial_puts("DDR channel setting: ONLY DDR0 16bit mode\n");
		ddr_chl_set = ((0x2 << 20) | (3 << 16) | (1 << 6));
		ddr_dual_rank_sel = 0;
		//p_ddr_set->t_pctl0_ppcfg = (0xF0 << 1);
		p_ddr_set->t_pctl0_ppcfg =(0x1fc | 1 );
		p_ddr_set->t_pctl0_dfiodtcfg = 0x08;
	}
	else if (p_ddr_set->ddr_channel_set == CONFIG_DDR01_SHARE_AC) {
		serial_puts("DDR channel setting: DDR0+1 share ac\n");
		ddr_chl_set = ((0x1 << 20) | (3 << 16) | (0 << 6));
		ddr_dual_rank_sel = 1;
		p_ddr_set->t_pctl0_ppcfg = (0x1fc | 1 );
		p_ddr_set->t_pctl0_dfiodtcfg = 0x08;
		p_ddr_set->ddr_dmc_ctrl	|= (5 << 8);
		p_ddr_set->ddr_2t_mode = 1;
	}
	p_ddr_set->ddr_dmc_ctrl	|= (ddr_chl_set |
							(0x5 << 3)		| //set to max size
							(0x5 << 0));	//set to max size
	/* config t_pub_pgcr2[28] share-ac-dual */
	p_ddr_set->t_pub_pgcr2 |= (ddr_dual_rank_sel << 28);

	/* update pctl timing */
	int tmp_val = 0;
	tmp_val =( p_ddr_timing->cfg_ddr_cwl + p_ddr_timing->cfg_ddr_al);
	tmp_val = (tmp_val - ((tmp_val%2) ? 3:4))/2;
	p_ddr_set->t_pctl0_dfitphywrlta=tmp_val;

	tmp_val = p_ddr_timing->cfg_ddr_cl + p_ddr_timing->cfg_ddr_al;
	tmp_val = (tmp_val - ((tmp_val%2) ? 3:4))/2;
	p_ddr_set->t_pctl0_dfitrddataen=tmp_val;

	//p_ddr_set->t_pctl0_dfitphyrdlat=16;
	if ((p_ddr_timing->cfg_ddr_cl+p_ddr_timing->cfg_ddr_al)%2) {
		p_ddr_set->t_pctl0_dfitphyrdlat=14;
	}

	/* update pub mr */
	p_ddr_set->t_pub_mr[0] = ((((p_ddr_timing->cfg_ddr_cl - 4) & 0x8)>>1)		|
						(((p_ddr_timing->cfg_ddr_cl - 4) & 0x7) <<  4)		|
						((((p_ddr_timing->cfg_ddr_wr <= 8)?(p_ddr_timing->cfg_ddr_wr - 4):(p_ddr_timing->cfg_ddr_wr>>1)) & 7) << 9) |
						(0x0) | (0x0 << 3) | (0x0 << 7) | (0x0 << 8) | (0x6 << 9) | (1 << 12)),
	p_ddr_set->t_pub_mr[1] = ( ((p_ddr_set->ddr_drv<<1)|((p_ddr_set->ddr_odt&1)<<2) |
						(((p_ddr_set->ddr_odt&2)>>1)<<6)				|
						(((p_ddr_set->ddr_odt&4)>>2)<<9)				|
						(1<<7) 									|
						((p_ddr_timing->cfg_ddr_al ? ((p_ddr_timing->cfg_ddr_cl - p_ddr_timing->cfg_ddr_al)&3): 0) << 3 ))),
	p_ddr_set->t_pub_mr[2] = ((1<<6)	|
					(((p_ddr_timing->cfg_ddr_cwl-5)&0x7)<<3)),
	p_ddr_set->t_pub_mr[3] = 0x0,
	/* update pub dtpr */
	p_ddr_set->t_pub_dtpr[0] = (p_ddr_timing->cfg_ddr_rtp			|
								(p_ddr_timing->cfg_ddr_wtr << 4)		|
								(p_ddr_timing->cfg_ddr_rp << 8)		|
								(p_ddr_timing->cfg_ddr_ras << 16)		|
								(p_ddr_timing->cfg_ddr_rrd << 22)		|
								(p_ddr_timing->cfg_ddr_rcd << 26));
	p_ddr_set->t_pub_dtpr[1] = ((p_ddr_timing->cfg_ddr_mod << 2)	|
								(p_ddr_timing->cfg_ddr_faw << 5)		|
								(p_ddr_timing->cfg_ddr_rfc << 11)		|
								(p_ddr_timing->cfg_ddr_wlmrd << 20)	|
								(p_ddr_timing->cfg_ddr_wlo << 26)		|
								(0 << 30) ); //TAOND
	p_ddr_set->t_pub_dtpr[2] = (p_ddr_timing->cfg_ddr_xs			|
								(p_ddr_timing->cfg_ddr_xp << 10)		|
								(p_ddr_timing->cfg_ddr_dllk << 19)	|
								(0 << 29)				| //TRTODT ADDITIONAL
								(0 << 30)				| //TRTW ADDITIONAL
								(0 << 31 )); //TCCD ADDITIONAL
	p_ddr_set->t_pub_dtpr[3] = (0 | (0 << 3)			|
								(p_ddr_timing->cfg_ddr_rc << 6)		|
								(p_ddr_timing->cfg_ddr_cke << 13)		|
								(p_ddr_timing->cfg_ddr_mrd << 18)		|
								(0 << 29)); //tAOFDx
	p_ddr_set->t_pctl0_mcfg = ((p_ddr_set->t_pctl0_mcfg)&(~(0x3<<18)))	|
								(((((p_ddr_timing->cfg_ddr_faw+p_ddr_timing->cfg_ddr_rrd-1)/p_ddr_timing->cfg_ddr_rrd)-4)&0x3)<<18);
	p_ddr_set->t_pctl0_mcfg1 |= ((((p_ddr_timing->cfg_ddr_faw%p_ddr_timing->cfg_ddr_rrd)?(p_ddr_timing->cfg_ddr_rrd-(p_ddr_timing->cfg_ddr_faw%p_ddr_timing->cfg_ddr_rrd)):0)&0x7)<<8);
}

void ddr_test(void){
	if (memTestDataBus((volatile unsigned int *)(uint64_t) \
		(p_ddr_set->ddr_base_addr + p_ddr_set->ddr_start_offset))) {
		serial_puts("DataBus test failed!!!\n");
		reset_system();
	}
	else
		serial_puts("DataBus test pass!\n");
	if (memTestAddressBus((volatile unsigned int *)(uint64_t) \
		(p_ddr_set->ddr_base_addr + p_ddr_set->ddr_start_offset), \
		((p_ddr_set->ddr_size << 20) - p_ddr_set->ddr_start_offset))) {
		serial_puts("AddrBus test failed!!!\n");
		reset_system();
	}
	else
		serial_puts("AddrBus test pass!\n");
#if MEM_TEST_DEVICE
	if (p_ddr_set->ddr_full_test) {
		extern void watchdog_disable(void);
		//disable_mmu_el1();
		watchdog_disable();
		if (memTestDevice((volatile unsigned int *)(uint64_t) \
			(p_ddr_set->ddr_base_addr + p_ddr_set->ddr_start_offset), \
			((p_ddr_set->ddr_size << 20) - p_ddr_set->ddr_start_offset))) {
			serial_puts("Device test failed!!!\n");
			reset_system();
		}
		else
			serial_puts("Device test pass!\n");
	}
#endif// #if MEM_TEST_DEVICE
}

#if 0
unsigned int hot_boot(void){
	if (((rd_reg(SCRATCH0) >> 24) & 0xFF) == 0x11) {
		/*hot boot*/
		return 0;
	}
	else{
		return 1;
	}
}
#endif