1 /******************************************************************************
2 David.Jia 2007.10.29 share_version_union
4 TCC -fpu None -O2 -bi -g+ -apcs /interwork -D__RUN_IN_SDRAM sdram_init.c
5 SC6600R -D_BL_NF_SC6600R_
6 SC6600H -D_BL_NF_SC6600H_
7 SC6600I -D_BL_NF_SC6600I_
8 SC6800 -gtp -cpu ARM926EJ-S -D_REF_SC6800_ -D_BL_NF_SC6800_
9 ******************************************************************************/
12 #include <asm/arch/sci_types.h>
13 #include <asm/arch/arm_reg.h>
14 #include <asm/arch/sdram_cfg.h>
15 #include <asm/arch/chng_freq.h>
16 #include <asm/arch/sc_reg.h>
17 #include <asm/arch/sdram.h>
18 #include <asm/arch/chip.h>
20 #include <asm/arch/adi_hal_internal.h>
21 #include <asm/arch/regs_ana.h>
22 #include <asm/arch/regs_ahb.h>
23 EMC_PARAM_T s_emc_config = {0};
25 /*lint -e760 -e547 ,because pclint error e63 e26 with REG32()*/
26 #define REG32(x) (*((volatile uint32 *)(x)))
27 #define REG8(x) (*((volatile uint8 *)(x)))
28 /*lint +e760 +e547 ,because pclint error e63 e26 with REG32()*/
32 #define SDRAM_EXT_INVALID 0xffffffff //@David.Jia 2008.1.7
33 #define ROW_MODE_TO_NUM(_m) (_m+11)
35 #if defined(PLATFORM_SC8800G) || defined(CONFIG_SC8810)
38 #endif //defined(PLATFORM_SC8800G) && defined(CHIP_VER_8800G2)
41 SDRAM_TIMING_PARA_T_PTR sdram_parameters;
43 #if defined(PLATFORM_SC8800G) || defined(CONFIG_SC8810)
44 #define SDRAM_AUTODETECT_SUPPORT
48 #ifdef SDRAM_AUTODETECT_SUPPORT
49 #define MEM_REF_DATA0 0x12345678
50 #define MEM_REF_DATA1 0x55AA9889
52 #define ZERO_ADDR 0x00000000UL
55 #define ZERO_ADDR 0x00000000UL
57 #define ZERO_ADDR 0x30000000UL
60 #define STATE_SDRAM_TYPE 0UL
61 #define STATE_BIT_WIDTH 1UL
62 #define STATE_COLUM 2UL
64 #define STATE_REINIT 4UL
67 #define BYTE_OFFSET 3UL // 1BYTE = 8BIT = 2^3
68 #define WIDTH16_OFFSET 4UL // 16BIT = 2^4
69 #define WIDTH32_OFFSET 5UL // 32BIT = 2^5
70 #define BANK_OFFSET 2UL // 4BANK = 2^2
72 #define SDRAM_MIN_COLUM 8UL
73 #define SDRAM_MAX_COLUM 12UL
74 #define SDRAM_MIN_ROW 11UL
75 #define SDRAM_MAX_ROW 14UL
77 SDRAM_CFG_INFO_T s_sdram_raw_cfg;
80 #ifdef PLATFORM_SC8800G
81 #define INTERFACE_CLK_MAX ARM_CLK_200M
82 typedef struct ARM_EMC_AHB_CLK_TAG
90 typedef enum MCU_CLK_TYPE_TAG
92 ARM400_EMC200_AHB100 = 0, //SC8800G2
93 ARM256_EMC200_AHB64, //SC8801G2
94 ARM192_EMC200_AHB96, //SC8802G2
102 LOCAL CONST ARM_EMC_AHB_CLK_T s_arm_emc_ahb_clk[] =
104 // mcu_clk arm_clk emc_clk ahb_clk
105 {ARM_CLK_400M, ARM_CLK_400M, ARM_CLK_200M, ARM_CLK_100M}, //SC8800G2
106 {ARM_CLK_256M, ARM_CLK_256M, ARM_CLK_200M, ARM_CLK_64M}, //SC8801G2
107 {ARM_CLK_192M, ARM_CLK_192M, ARM_CLK_200M, ARM_CLK_96M}, //SC8802G2
108 {ARM_CLK_512M, ARM_CLK_256M, ARM_CLK_192M, ARM_CLK_64M},
109 {ARM_CLK_512M, ARM_CLK_256M, ARM_CLK_128M, ARM_CLK_64M},
110 {ARM_CLK_384M, ARM_CLK_192M, ARM_CLK_192M, ARM_CLK_96M},
113 uint32 __GetMPllClk (void)
116 / ( (REG32(GR_MPLL_MN) & 0x003F0000) >>16)
117 * (REG32(GR_MPLL_MN) & 0x00000FFF) );
120 LOCAL void __SetMPllClk (uint32 clk)
124 M = 13; // M: fix to 13
127 tmp_mn = (REG32(GR_MPLL_MN) & (~0x3FFFFF));
128 tmp_mn |= (M << 16) | N;
130 REG32(GR_GEN1) |= BIT_9; // MPLL Write En
131 REG32(GR_MPLL_MN) = tmp_mn;
132 REG32(GR_GEN1) &= ~BIT_9; // MPLL Write Dis
135 LOCAL void __ClkConfig(uint32 *emcclk, uint32 *ahbclk)
137 uint32 tmp_clk, mcuclk, armclk;
138 uint32 mcu_div, if_div;
139 BOOLEAN is_mpll, is_async;
140 MCU_CLK_TYPE_E clk_type = ARM400_EMC200_AHB100;
143 switch(REG32(GR_GEN3) & 0x3)
146 clk_type = ARM400_EMC200_AHB100; // 8800G2
149 clk_type = ARM256_EMC200_AHB64; // 8801G1
152 clk_type = ARM192_EMC200_AHB96; // 8802G1
155 clk_type = ARM400_EMC200_AHB100;
160 mcuclk = s_arm_emc_ahb_clk[clk_type].mcu_clk;
161 armclk = s_arm_emc_ahb_clk[clk_type].arm_clk;
162 *emcclk = s_arm_emc_ahb_clk[clk_type].emc_clk;
163 *ahbclk = s_arm_emc_ahb_clk[clk_type].ahb_clk;
165 is_mpll = (((0 == (REG32(GR_GEN3) & 0x3)) || (3 == (REG32(GR_GEN3) & 0x3))) ? (SCI_TRUE) : (SCI_FALSE));
166 is_async = ((0 == (armclk%(*emcclk))) ? (SCI_FALSE) : (SCI_TRUE));
171 if(__GetMPllClk() != mcuclk)
173 __SetMPllClk(mcuclk);
182 if(armclk > INTERFACE_CLK_MAX)
187 // step 1: config emc clk in dsp side in async mode
190 REG32(AHB_DSP_BOOT_EN) |= BIT_2;
191 REG32(AHB_CTL1) &= ~BIT_16;
192 REG32(0x10130010) |= BIT_28;
194 REG32(0x1013000C) |= (2<<10); //bit[11:10], DSP SIDE: 1:200M, 2:192M 3:26M
196 REG32(0x10130010) &= ~BIT_28;
197 REG32(AHB_CTL1) |= BIT_16;
198 REG32(AHB_DSP_BOOT_EN) &= ~BIT_2;
201 // step 2: first config divider
202 // ifdiv / mcudiv / ahbdiv
203 // MCU_26M / sync_mode / emc-async-sel
204 tmp_clk = (BIT_23|BIT_24);
205 tmp_clk |= (if_div << 31) | // bit[31], interface-div
206 (mcu_div << 30) | // bit[30], mcu-div
207 // bit[29:25], read only
208 // bit[24:23], mcu-sel, should config at step 2
209 // bit[22:17], reserved
210 (0 << 14) | // bit[16:14], emc-sync-div: 2^n
211 (1 << 12) | // bit[13:12], emc-async-sel: 0:reserved, 1:200M, 2:192M 3:26M
212 (0 << 8) | // bit[11:8], emc-async-div: (n+1)
213 // bit[7], ARM_384M_SEL:0
214 (1 << 4) | // bit[6:4], ahb-div: (n+1)
215 (1 << 3) ; // bit[3], emc sync:1, async:0
216 // bit[2:0], arm-div, only for G1
218 REG32(AHB_ARM_CLK) = tmp_clk;
220 // step 3: config mcu-sel
221 tmp_clk &= ~(BIT_23|BIT_24); // mcu-sel: 26*N/M, this bit must be set after divider
222 REG32(AHB_ARM_CLK) = tmp_clk;
224 //step 4: switch to async mode at last
228 REG32(AHB_ARM_CLK) = tmp_clk;
234 #ifndef CONFIG_SC8810
235 /**---------------------------------------------------------------------------*
237 ** void SDRAM_GenMemCtlCfg(SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr) *
240 ** set emc channel parameters *
252 **---------------------------------------------------------------------------*/
253 LOCAL void SDRAM_GenMemCtlCfg (SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
255 uint32 burst_length = sdram_cfg_ptr->burst_length;
256 uint32 data_width = sdram_cfg_ptr->data_width;
257 uint32 dburst_rlength, dburst_wlength = 0;
260 if (data_width == DATA_WIDTH_16)
262 switch (burst_length)
266 dburst_rlength = BURST_LEN_1;
267 dburst_wlength = BURST_LEN_1;
270 dburst_rlength = BURST_LEN_2;
271 dburst_wlength = BURST_LEN_2;
274 dburst_rlength = BURST_LEN_4;
275 dburst_wlength = BURST_LEN_4;
278 dburst_rlength = BURST_LEN_1;
279 dburst_wlength = BURST_LEN_1;
283 else if (data_width == DATA_WIDTH_32)
285 switch (burst_length)
288 dburst_rlength = BURST_LEN_1;
289 dburst_wlength = BURST_LEN_1;
292 dburst_rlength = BURST_LEN_2;
293 dburst_wlength = BURST_LEN_2;
296 dburst_rlength = BURST_LEN_4;
297 dburst_wlength = BURST_LEN_4;
300 dburst_rlength = BURST_LEN_8;
301 dburst_wlength = BURST_LEN_8;
304 dburst_rlength = BURST_LEN_1;
305 dburst_wlength = BURST_LEN_1;
313 REG32 (EXT_MEM_CFG0) = (BIT_0|BIT_1|BIT_3|BIT_6|BIT_8|BIT_9|BIT_10|BIT_11); //software address mapping
315 #ifdef CHIP_ENDIAN_BIG
316 REG32 (EXT_MEM_CFG0) |= BIT_12; /*lint !e718*/ //big endian
320 /*lint -save -e506 -e774*/
321 if ( (SDR_SDRAM == sdram_cfg_ptr->sdram_type))
323 REG32 (EXT_MEM_CFG1) = 0x00000008; //EMC phy set
325 else if (DDR_SDRAM == sdram_cfg_ptr->sdram_type)
327 REG32 (EXT_MEM_CFG0) |= (BIT_5); // ddr select
328 REG32 (EXT_MEM_CFG1) = 0x01080000; //EMC phy set
335 REG32 (EXT_MEM_CFG0_CS0) = ( (0x1<<12) | (dburst_wlength<<8) | (dburst_rlength<<4) | (0x3));
337 //config channel 0-15
338 REG32 (EXT_MEM_CFG0_CH0) = 0x0003c31c;//0x0001c31c;
339 REG32 (EXT_MEM_CFG0_CH1) = 0x0003c31c;
340 REG32 (EXT_MEM_CFG0_CH2) = 0x0003c31c;
341 REG32 (EXT_MEM_CFG0_CH3) = 0x0003c31c;
342 REG32 (EXT_MEM_CFG0_CH4) = 0x0003c31c;
343 REG32 (EXT_MEM_CFG0_CH5) = 0x0003c31c;
345 #if defined(PLATFORM_SC8800G)
346 REG32 (EXT_MEM_CFG0_CH6) = 0x0001c31c; //for sc8800g emc sleep bug.
347 REG32 (EXT_MEM_CFG0_CH7) = 0x0001c31c;
348 REG32 (EXT_MEM_CFG0_CH8) = 0x0001c31c;
352 /**---------------------------------------------------------------------------*
354 ** void SDRAM_DMemCtlCfg(uint32 sdram_clk,SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr) *
357 ** set emc dmem mode,timing parameters *
360 ** sdram_clk,sdram_cfg_ptr *
369 **---------------------------------------------------------------------------*/
370 LOCAL void SDRAM_DMemCtlCfg (uint32 sdram_clk,SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
372 //initialize dmem mode parameters
373 uint32 row_mode = sdram_cfg_ptr->row_mode;
374 uint32 col_mode = sdram_cfg_ptr->col_mode;
375 uint32 data_width = sdram_cfg_ptr->data_width;
376 uint32 cas_latency = sdram_cfg_ptr->cas_latency;
377 uint32 sdram_cycle_ns = 1000/ (sdram_clk/1000000);
380 uint32 t_ras = (sdram_parameters->ras_min/sdram_cycle_ns+1)>0xF ? 0xF : (sdram_parameters->ras_min/sdram_cycle_ns+1);
381 uint32 t_xsr = (sdram_parameters->xsr_min/sdram_cycle_ns)>0xF ? 0xF : (sdram_parameters->xsr_min/sdram_cycle_ns);
382 uint32 t_rfc = (sdram_parameters->rfc_min/sdram_cycle_ns)>0xF ? 0xF : (sdram_parameters->rfc_min/sdram_cycle_ns);
383 uint32 t_wr = sdram_parameters->wr_min/sdram_cycle_ns+2; //note: twr should add 2 for ddr
384 uint32 t_rcd = (sdram_parameters->rcd_min/sdram_cycle_ns)>3 ? 3:(sdram_parameters->rcd_min/sdram_cycle_ns);
385 uint32 t_rp = (sdram_parameters->row_pre_min/sdram_cycle_ns)>3 ? 3:(sdram_parameters->row_pre_min/sdram_cycle_ns);
386 uint32 t_rrd = (sdram_parameters->rrd_min/sdram_cycle_ns) >3 ? 3:(sdram_parameters->rrd_min/sdram_cycle_ns);
387 uint32 t_mrd = (sdram_parameters->mrd_min) > 3 ? 3:(sdram_parameters->mrd_min);
388 uint32 t_wtr = sdram_parameters->wtr_min;
390 uint32 t_rtw = sdram_cfg_ptr->cas_latency;
392 row_num = ROW_MODE_TO_NUM(row_mode);
393 t_ref = ((sdram_parameters->row_ref_max*6500)>>row_num) - 2; // t_ref*(1/6.5MHz)*2^row <= tREF
395 //set data width mode
396 if (data_width == DATA_WIDTH_32)
398 REG32 (EXT_MEM_DCFG0) = 0x0000BF00;
402 REG32 (EXT_MEM_DCFG0) = 0x0000BE00;
406 REG32 (EXT_MEM_DCFG0) |= row_mode;/*lint !e737*/
409 REG32 (EXT_MEM_DCFG0) |= (col_mode<<4);/*lint !e737*/
412 REG32 (EXT_MEM_DCFG0) &= ~ (BIT_2|BIT_3); //A[10]
414 //set t_rfc and t_ref
415 REG32 (EXT_MEM_DCFG0) |= ( (t_rfc<<16) | (t_ref<<20)); /*lint !e737*/
417 REG32(EXT_MEM_DCFG1) = ( (t_rp <<0) |
427 if (SDR_SDRAM == sdram_cfg_ptr->sdram_type)
429 //read data and write data timing
430 if (cas_latency == 3)
432 REG32 (EXT_MEM_DCFG4) = 0x00600208;
433 REG32 (EXT_MEM_DCFG7) = 0x00400001;
435 else if (cas_latency == 2)
437 REG32 (EXT_MEM_DCFG4) = 0x00400006;
438 REG32 (EXT_MEM_DCFG7) = 0x00100001;
445 //config delay lines.
446 REG32 (EXT_MEM_DL24) = 0x2;
447 REG32 (EXT_MEM_DL25) = 0x2;
448 REG32 (EXT_MEM_DL26) = 0x2;
449 REG32 (EXT_MEM_DL27) = 0x2;
451 else if (DDR_SDRAM == sdram_cfg_ptr->sdram_type)
453 // wtr is only for ddr
454 REG32(EXT_MEM_DCFG1) |= (t_wtr<<24);
456 //read data and write data timing
457 if (cas_latency == 3)
459 REG32 (EXT_MEM_DCFG4) = 0x00622729;
460 REG32 (EXT_MEM_DCFG5) = 0x00200010;
461 REG32 (EXT_MEM_DCFG6) = 0x00F0000E;
462 REG32 (EXT_MEM_DCFG7) = 0x00F0000E;
464 else if (cas_latency == 2)
466 REG32 (EXT_MEM_DCFG4) = 0x00422726;
467 REG32 (EXT_MEM_DCFG5) = 0x00080004;
468 REG32 (EXT_MEM_DCFG6) = 0x003C000E;
469 REG32 (EXT_MEM_DCFG7) = 0x003C000E;
476 //config delay lines.
477 REG32 (EXT_MEM_DL7) = 0x6;
478 REG32 (EXT_MEM_DL16) = 0x3;
479 REG32 (EXT_MEM_DL17) = 0x3;
480 REG32 (EXT_MEM_DL18) = 0x3;
481 REG32 (EXT_MEM_DL19) = 0x3;
482 REG32 (EXT_MEM_DL20) = 0x3;
483 REG32 (EXT_MEM_DL21) = 0x3;
484 REG32 (EXT_MEM_DL22) = 0x3;
485 REG32 (EXT_MEM_DL23) = 0x3;
486 REG32 (EXT_MEM_DL24) = 0x7;
487 REG32 (EXT_MEM_DL25) = 0x7;
488 REG32 (EXT_MEM_DL26) = 0x7;
489 REG32 (EXT_MEM_DL27) = 0x7;
499 /**---------------------------------------------------------------------------*
501 ** void SDRAM_Device_Init(SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr) *
504 ** set emc dmem mode/ext mode register parameters *
516 **---------------------------------------------------------------------------*/
517 LOCAL void SDRAM_Device_Init (SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
519 uint8 mode_reg_bl = 0xFF;
520 uint8 mode_reg_bt = MODE_REG_BT_SEQ;
521 uint8 mode_reg_cl = 0xFF;
522 uint8 mode_reg_opmode = MODE_REG_OPMODE;
523 uint32 ex_mode_reg = 0;
526 //calculate mode reg burst length
527 switch (sdram_cfg_ptr->burst_length)
530 mode_reg_bl = MODE_REG_BL_1;
533 mode_reg_bl = MODE_REG_BL_2;
536 mode_reg_bl = MODE_REG_BL_4;
539 mode_reg_bl = MODE_REG_BL_8;
542 mode_reg_bl = MODE_REG_BL_1;
546 //calculate mode reg cas latency
547 switch (sdram_cfg_ptr->cas_latency)
550 mode_reg_cl = MODE_REG_CL_1;
553 mode_reg_cl = MODE_REG_CL_2;
556 mode_reg_cl = MODE_REG_CL_3;
559 mode_reg_cl = MODE_REG_CL_3;
563 //get mode reg parameter
564 mode_reg = ( (mode_reg_opmode<<9) | (mode_reg_cl<<4) | (mode_reg_bt<<3) | mode_reg_bl);
566 //get ext-mode reg parameter
567 ex_mode_reg = sdram_cfg_ptr->ext_mode_val;
569 // Precharge all banks.
570 REG32 (EXT_MEM_DCFG3) = 0x40010000;
572 while ( (REG32 (EXT_MEM_DCFG3)) & BIT_16){}
575 REG32 (EXT_MEM_DCFG3) = 0x40020000;
577 while ( (REG32 (EXT_MEM_DCFG3)) & BIT_17){}
580 REG32 (EXT_MEM_DCFG3) = 0x40020000;
582 while ( (REG32 (EXT_MEM_DCFG3)) & BIT_17){}
584 //mode register load.
585 REG32 (EXT_MEM_DCFG3) &= ~ (0xFFFF);
586 REG32 (EXT_MEM_DCFG3) |= (mode_reg | 0x40040000);
588 while ( (REG32 (EXT_MEM_DCFG3)) & BIT_18){}
590 //extended mode register load.
591 if (ex_mode_reg != SDRAM_EXT_MODE_INVALID)
593 REG32 (EXT_MEM_DCFG3) &= ~ (0xFFFF);
594 REG32 (EXT_MEM_DCFG3) |= (ex_mode_reg | 0x40040000);/*lint !e737*/
596 while ( (REG32 (EXT_MEM_DCFG3)) & BIT_18){}
601 LOCAL void __sdram_set_param(uint32 clk, SDRAM_CFG_INFO_T_PTR pCfg)
605 //step 1. Disable auto refresh.
606 REG32 (EXT_MEM_DCFG0) &= ~ BIT_14;
608 //step 2. sdram init: config registers, precharege all banks, auto ref for 2 times, load mode register.
609 SDRAM_GenMemCtlCfg (pCfg);
610 SDRAM_DMemCtlCfg (clk,pCfg);
611 SDRAM_Device_Init (pCfg);
613 //step3. enable auto refresh.
614 REG32 (EXT_MEM_DCFG2) |= BIT_15; //clear refresh count.
615 REG32 (EXT_MEM_DCFG0) |= BIT_14; //Enable auto refresh.
617 for (i=0; i<1000; i++){}
620 LOCAL CONST EMC_PHY_L1_TIMING_T EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_MATRIX_MAX] =
622 //dpad_ie, dpad_oe, dqs_gate_pst, dqs_gate_pre, dqs_ie, dqs_oe
623 {0x20, 1, 0, 0, 0, 0}, //sdram cas_latency = 2
624 {0x40, 1, 0, 0, 0, 0}, //sdram cas_latency = 3
625 {0xf, 0xe, 0x10, 8, 0xf, 0xe}, //ddram cas_latency = 2
626 {0xf, 0xe, 0x40, 0x20, 0xf, 0xe}, //ddram cas_latency = 2
629 LOCAL CONST EMC_PHY_L2_TIMING_T EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_MATRIX_MAX] =
631 //dl0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19
632 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //sdram cas_latency = 2
633 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //sdram cas_latency = 3
634 {0, 0, 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6}, //ddram cas_latency = 2
635 {0, 0, 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6}, //ddram cas_latency = 3
639 EMC_PHY_L1_TIMING_T_PTR EMC_GetPHYL1_Timing(SDRAM_CFG_INFO_T_PTR mem_info)
641 if(SDR_SDRAM == mem_info->sdram_type)
643 if(CAS_LATENCY_2 == mem_info->cas_latency)
645 return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_SDRAM_LATENCY2]));
649 return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_SDRAM_LATENCY3]));
654 if(CAS_LATENCY_2 == mem_info->cas_latency)
656 return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_DDRAM_LATENCY2]));
660 return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_DDRAM_LATENCY3]));
665 EMC_PHY_L2_TIMING_T_PTR EMC_GetPHYL2_Timing(SDRAM_CFG_INFO_T_PTR mem_info)
667 if(SDR_SDRAM == mem_info->sdram_type)
669 if(CAS_LATENCY_2 == mem_info->cas_latency)
671 return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_SDRAM_LATENCY2]));
675 return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_SDRAM_LATENCY3]));
680 if(CAS_LATENCY_2 == mem_info->cas_latency)
682 return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_DDRAM_LATENCY2]));
686 return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_DDRAM_LATENCY3]));
690 /*****************************************************************************/
691 // Description: EMC basic mode set function
692 // set the base mode like:
694 // EMC auto gate en for power saving
696 // EMC cmd queue mode
697 // Global resource dependence: NONE
698 // Related register: EMC_CFG0
699 // Author: Johnny.Wang
700 // Note: The default cs map space is 4g, if dram capability is larger than 4g,
701 // emc_cs_map parameter must adjust.
702 /*****************************************************************************/
703 void EMC_Base_Mode_Set(void)
705 REG32(EXT_MEM_CFG0) &= ~0x1fff;//clear bit0~12
706 REG32(EXT_MEM_CFG0) |= (EMC_DVC_ENDIAN_DEFAULT <<12) |
707 (EMC_AUTO_GATE_EN <<11) |
708 (EMC_AUTO_SLEEP_EN <<10) |
710 (EMC_CS_MODE_DEFAULT <<3) |
711 (EMC_CS_MAP_2G <<0) ;
715 /*****************************************************************************/
716 // Description: EMC each cs work mode set function
717 // set each cs work mode parameter like:
718 // memory write burst length
719 // memory read burst length
720 // memory write burst mode:wrap/increase
721 // memory read burst mode:wrap/increase
722 // AHB write busrt divided to single/busrt access
723 // AHB read busrt divided to single/busrt access
724 // Global resource dependence: memory burst length type
725 // Related register: EMC_CFG0_CSx
726 // Author: Johnny.Wang
727 // Note: There are two cs pin in sc8810 emc, we usuall use cs0 to control external memory
729 /*****************************************************************************/
730 void EMC_CSx_Set(EMC_CS_NUM_E emc_cs_num, SDRAM_CFG_INFO_T_PTR mem_info)
732 uint32 emc_cs_cfg = EXT_MEM_CFG0_CS0 + emc_cs_num*4;
734 uint32 burst_len = 0;
736 if(DATA_WIDTH_16 == mem_info ->data_width)
738 burst_len = mem_info->burst_length -1;
742 burst_len = mem_info->burst_length;
745 REG32(emc_cs_cfg) = 0;//clear emc cs cfg
746 REG32(emc_cs_cfg) |=((burst_len <<8) | //write burst length
747 (burst_len <<4) | //read burst length
748 (BURST_WRAP <<3) | //write burst mode
749 (BURST_WRAP <<2) | //write burst mod e
750 (HBURST_TO_BURST <<1) | //write hburst invert to mem burst
751 (HBURST_TO_BURST <<0)); //rrite hburst invert to mem burst
754 /*****************************************************************************/
755 // Description: EMC AXI channel set function
756 // set each axi channel parameter like:
758 // axi channel auto sleep en
759 // channel endian switch
761 // Global resource dependence: NONE
762 // Related register: EMC_CFG0_ACHx
764 // Author: Johnny.Wang
765 // Note: There are two axi channel in sc8810 emc, one for A5,the other for GPU
767 /*****************************************************************************/
768 void EMC_AXI_CHL_Set(EMC_CHL_NUM_E emc_axi_num)
770 uint32 emc_axi_cfg0 = EXT_MEM_CFG0_ACH0 + emc_axi_num*8;
771 uint32 emc_axi_cfg1 = EXT_MEM_CFG1_ACH0 + emc_axi_num*8;
773 REG32(emc_axi_cfg0) &= ~0xf0; //clear bit7~4
774 //REG32(emc_axi_cfg0) |= (TRUE<<7) | //channel auto sleep en
775 // (TRUE<<6) | //channel en
776 // (EMC_ENDIAN_SWITCH_NONE<<4);
778 REG32(emc_axi_cfg0) |= (TRUE<<6) | //channel en
779 (EMC_ENDIAN_SWITCH_NONE<<4);
781 REG32(emc_axi_cfg1) &= ~BIT_4; //clear bit7~4
782 REG32(emc_axi_cfg1) |= (EMC_CLK_ASYNC<<4); //emc clk async with axi clk
783 REG32(emc_axi_cfg1) |= (1<<6); //axi channel response mode 0:at once 1:delay several clk
786 /*****************************************************************************/
787 // Description: EMC AHB channel set function
788 // Global resource dependence: NONE
789 // Author: Johnny.Wang
790 // Note: There are 7 ahb channel in sc8810 emc, but no one is relate with ARM,
791 // so don't used temporarily
793 /*****************************************************************************/
794 void EMC_AHB_CHL_Set(EMC_CHL_NUM_E emc_ahb_num,uint32 addr_offset)
796 uint32 emc_ahb_cfg0 = EXT_MEM_CFG0_ACH0 + emc_ahb_num*8;
797 uint32 emc_ahb_cfg1 = EXT_MEM_CFG1_ACH0 + emc_ahb_num*8;
799 REG32(emc_ahb_cfg1) &= ~0x03ff0000; //clear bit16~25
800 REG32(emc_ahb_cfg1) |= addr_offset<<16;
803 /*****************************************************************************/
804 // Description: EMC Memroy all timing parameter set function
805 // set all timing parameter of EMC when operate external memory like:
817 // Global resource dependence: NONE
818 // Author: Johnny.Wang
819 // Related register: EMC_DCFG1
823 /*****************************************************************************/
824 void EMC_MEM_Timing_Set(uint32 emc_freq,
825 SDRAM_CFG_INFO_T_PTR mem_info,
826 SDRAM_TIMING_PARA_T_PTR mem_timing)
828 uint32 cycle_ns = 2000*1000000/emc_freq;//2000/(clk); //device clock is half of emc clock.
829 //uint32 cycle_t_ref = 1000/EMC_T_REF_CLK;
831 uint32 row_mode = mem_info->row_mode;
832 uint32 t_rtw = mem_info->cas_latency;
834 //round all timing parameter
835 uint32 t_ras = mem_timing->ras_min/cycle_ns;
836 uint32 t_xsr = mem_timing->xsr_min/cycle_ns;
837 uint32 t_rfc = mem_timing->rfc_min/cycle_ns;
838 uint32 t_wr = mem_timing->wr_min/cycle_ns+2; //note: twr should add 2 for ddr
839 uint32 t_rcd = mem_timing->rcd_min/cycle_ns;
840 uint32 t_rp = mem_timing->row_pre_min/cycle_ns;
841 uint32 t_rrd = mem_timing->rrd_min/cycle_ns;
842 //uint32 t_mrd = mem_timing->mrd_min/cycle_ns;
843 uint32 t_mrd = mem_timing->mrd_min;
844 //uint32 t_wtr = mem_timing->wtr_min/cycle_ns+1;
845 uint32 t_wtr = mem_timing->wtr_min+1;
846 uint32 t_ref = ((mem_timing->row_ref_max*EMC_T_REF_CLK)>>(ROW_MODE_TO_NUM(row_mode))) -2;
848 //prevent the maximun overflow of all timing parameter
849 t_ras = (t_ras >= 0xf ) ? 0x7 : t_ras;
850 t_xsr = (t_xsr >= 0xff) ? 0x26 : t_xsr;
851 t_rfc = (t_rfc >= 0x3f) ? 0x1a : t_rfc;
852 t_wr = (t_wr >= 0xf ) ? 0x4 : t_wr;
853 t_rcd = (t_rcd >= 0xf ) ? 0x3 : t_rcd;
854 t_rp = (t_rp >= 0xf ) ? 0x3 : t_rp;
855 t_rrd = (t_rrd >= 0xf ) ? 0x2 : t_rrd;
856 t_mrd = (t_mrd >= 0xf ) ? 0x0 : t_mrd;
857 t_wtr = (t_wtr >= 0xf ) ? 0x3 : t_wtr;
858 t_ref = (t_ref >=0xfff) ? 0x100: t_ref ;
860 //prevent the minmun value of all timing
861 t_ras = (t_ras <= 0) ? 0x7 : t_ras;
862 t_xsr = (t_xsr <= 0) ? 0x26 : t_xsr;
863 t_rfc = (t_rfc <= 0) ? 0x1a : t_rfc;
864 t_wr = (t_wr <= 0) ? 0x4 : t_wr;
865 t_rcd = (t_rcd <= 0) ? 0x3 : t_rcd;
866 t_rp = (t_rp <= 0) ? 0x3 : t_rp;
867 t_rrd = (t_rrd <= 0) ? 0x2 : t_rrd;
868 t_mrd = (t_mrd <= 0) ? 0x2 : t_mrd;
869 t_wtr = (t_wtr <= 0) ? 0x3 : t_wtr;
870 t_ref = (t_ref <=00) ? 0x100: t_ref ;
874 REG32(EXT_MEM_DCFG1) = ((0<<28) |//read to read turn around time between different cs
875 //default:0 2 cs or above:1
884 REG32(EXT_MEM_DCFG2) = ((t_rfc << 24) |
890 /*****************************************************************************/
891 // Description: EMC Memroy mode set function
892 // set external memory work mode parameter like:
895 // row mode and so on
896 // Global resource dependence: NONE
897 // Author: Johnny.Wang
898 // Related register: EMC_DCFG0
902 /*****************************************************************************/
903 void EMC_MEM_Mode_Set(SDRAM_CFG_INFO_T_PTR mem_info)
905 REG32(EXT_MEM_DCFG0) = (EMC_CS_REF_SAME<<15) |
906 (TRUE << 14) |//hardware auto-refresh en
907 (TRUE << 13) |//mode1 en
908 (TRUE << 12) |//mode0 en
909 (TRUE << 11) |//dmem clock output phase
910 (TRUE << 10) |//dmem clock output en
911 (TRUE << 9) |//row hit en
912 (mem_info->data_width<< 8) |
913 (mem_info->col_mode << 4) |
914 (EMC_PRE_BIT_A10<< 2) |
915 (mem_info->row_mode);
919 /*****************************************************************************/
920 // Description: EMC phy latency set function
921 // set parameter relate with cas latency like:
922 // timing adjustment sample clock latency
923 // DQS output latency
926 // write data latency
928 // Global resource dependence: dram type , cas_latency
929 // Author: Johnny.Wang
930 // Related register: EMC_DCFG5
934 /*****************************************************************************/
935 void EMC_PHY_Latency_Set(SDRAM_CFG_INFO_T_PTR mem_info)
937 if(SDR_SDRAM == mem_info->sdram_type)
939 if(CAS_LATENCY_2 == mem_info->cas_latency)
941 REG32(EXT_MEM_DCFG5) = 0x00420006;
945 REG32(EXT_MEM_DCFG5) = 0x00620208;
950 if(CAS_LATENCY_2 == mem_info->cas_latency)
952 REG32(EXT_MEM_DCFG5) = 0x00622726;
956 REG32(EXT_MEM_DCFG5) = 0x00622728;
960 //REG32(EXT_MEM_DCFG5) = 0x00633739;
965 /*****************************************************************************/
966 // Description: EMC phy mode set function
967 // set parameter relate with emc phy work mode like:
968 // cke map to cs0 or cs1
969 // dqs gate delay,delay line or loopback
970 // dqs gate mode,mode0 or mode1
971 // DMEM data output mode,dff or dl
972 // DMEM DDR DQS[3:0] output mode,dff or dl
973 // DMEM DDR DQS PAD IE mode,dff or dl
974 // DMEM sample clock mode,internal or from dqs
975 // DMEM CK/CK# output mode,dff or dl
976 // DMEM READ strobe clock loopback dis/en
977 // Global resource dependence: dll on or off, external memory type
978 // Author: Johnny.Wang
979 // Related register: EMC_CFG1
983 /*****************************************************************************/
984 void EMC_PHY_Mode_Set(SDRAM_CFG_INFO_T_PTR mem_info)
986 REG32(EXT_MEM_CFG1) = 0; //clear phy control register
988 REG32(EXT_MEM_CFG1) |= (EMC_CKE_SEL_DEFAULT << 14) |
989 (EMC_DQS_GATE_DEFAULT<< 8) |
990 (EMC_DQS_GATE_MODE_DEFAULT<< 7) |
991 (mem_info->sdram_type<< 6) |//DMEM data output mode,dff or dl
992 (EMC_DLL_ON_OFF<< 5) |//DMEM DDR DQS[3:0] output mode,dff or dl
993 (EMC_DLL_ON_OFF<< 4) |//DMEM DDR DQS PAD IE mode,dff or dl
994 (mem_info->sdram_type<<3) |//DMEM sample clock mode,internal or from dqs
995 (0<<2) |//DMEM CK/CK# output mode,dff or dl
996 (0<<1) |//DMEM READ strobe clock loopback dis/en
997 mem_info->sdram_type;
999 //REG32(EXT_MEM_CFG1) |= BIT_6;
1004 /*****************************************************************************/
1005 // Description: EMC phy timing set function
1006 // set parameter relate with emc phy work mode like:
1007 // data pad ie delay
1008 // data pad oe delay
1011 // all delay line timing parameter
1012 // Global resource dependence: dll on or off, external memory type
1013 // Author: Johnny.Wang
1014 // Related register: EMC_DCFG6,7,8 and EMC_DMEM_DL0~DL19
1017 /*****************************************************************************/
1018 void EMC_PHY_Timing_Set(uint32 emc_freq,
1019 SDRAM_CFG_INFO_T_PTR mem_info,
1020 EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing,
1021 EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing)
1025 REG32(EXT_MEM_DCFG8) = ((emc_phy_l1_timing->data_pad_ie_delay & 0xffff) <<16) |
1026 (emc_phy_l1_timing->data_pad_oe_delay & 0xff);
1028 if(DDR_SDRAM == mem_info->sdram_type)
1030 REG32(EXT_MEM_DCFG6) = ((emc_phy_l1_timing->dqs_gate_pst_delay& 0xffff) <<16) |
1031 (emc_phy_l1_timing->dqs_gate_pre_delay& 0xffff);
1033 REG32(EXT_MEM_DCFG7) = ((emc_phy_l1_timing->dqs_ie_delay& 0xffff) <<16) |
1034 (emc_phy_l1_timing->dqs_oe_delay& 0xff);
1037 if(EMC_DLL_ON_OFF == TRUE && emc_freq >= ARM_CLK_96M)
1039 for(i = EMC_DMEM_DL0; i < EMC_DMEM_MAX; i++)
1041 REG32(EXT_MEM_DL0 + i*4 ) = REG32(REG32(emc_phy_l2_timing)+i*4);
1046 /*****************************************************************************/
1047 // Description: EMC phy set function
1048 // include these subfunction:
1049 // EMC_PHY_Latency_set(),
1050 // EMC_PHY_Mode_Set(),
1051 // EMC_PHY_Timing_Set()
1052 // Global resource dependence: dll on or off, external memory type
1053 // Author: Johnny.Wang
1054 // Related register:
1057 /*****************************************************************************/
1058 void EMC_PHY_Set(uint32 emc_freq,
1059 SDRAM_CFG_INFO_T_PTR mem_info,
1060 EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing,
1061 EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing)
1063 EMC_PHY_Latency_Set(mem_info);
1064 EMC_PHY_Mode_Set(mem_info);
1065 EMC_PHY_Timing_Set(emc_freq,mem_info,emc_phy_l1_timing,emc_phy_l2_timing);
1068 /*****************************************************************************/
1069 // Description: EMC software command send function
1070 // this function will send software initialization command to external memory
1071 // Global resource dependence: memory type
1072 // Author: Johnny.Wang
1073 // Related register:
1076 /*****************************************************************************/
1077 void EMC_SCMD_Issue(SDRAM_CFG_INFO_T_PTR mem_info)
1081 //shut down auto-refresh
1082 REG32(EXT_MEM_DCFG0) &= ~(DCFG0_AUTOREF_EN);
1084 //precharge all bank
1085 REG32(EXT_MEM_DCFG4) = 0x40010000;
1086 while (REG32(EXT_MEM_DCFG4) & BIT_16);
1087 for(i=0; i<=1000; i++);
1089 //software auto refresh
1090 REG32(EXT_MEM_DCFG4) = 0x40020000;
1091 while (REG32(EXT_MEM_DCFG4) & BIT_17);
1092 for(i=0; i<=1000; i++);
1094 //software auto refresh
1095 REG32(EXT_MEM_DCFG4) = 0x40020000;
1096 while (REG32(EXT_MEM_DCFG4) & BIT_17);
1097 for(i=0; i<=1000; i++);
1099 //load nornal mode register
1100 REG32(EXT_MEM_DCFG4) = 0x40040000 | (mem_info->cas_latency<<4) | (mem_info->burst_length);
1101 while (REG32(EXT_MEM_DCFG4) & BIT_18);
1102 for(i=0; i<=1000; i++);
1104 if(SDRAM_EXT_MODE_INVALID != mem_info->ext_mode_val)
1106 //load external mode register
1107 REG32(EXT_MEM_DCFG4) = 0x40040000 | mem_info->ext_mode_val;
1108 while (REG32(EXT_MEM_DCFG4) & BIT_18);
1109 for(i=0; i<=1000; i++);
1113 REG32(EXT_MEM_DCFG0) |= (DCFG0_AUTOREF_EN);
1117 void EMC_Init(uint32 emc_freq,
1118 EMC_CS_NUM_E emc_cs_num,
1119 EMC_CHL_NUM_E emc_axi_num,
1120 SDRAM_CFG_INFO_T_PTR mem_info,
1121 SDRAM_TIMING_PARA_T_PTR mem_timing,
1122 EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing,
1123 EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing)
1125 EMC_Base_Mode_Set();
1126 EMC_CSx_Set(emc_cs_num,mem_info);
1127 EMC_AXI_CHL_Set(emc_axi_num);
1128 EMC_MEM_Mode_Set(mem_info);
1129 EMC_MEM_Timing_Set(emc_freq,mem_info,mem_timing);
1130 EMC_PHY_Set(emc_freq,mem_info,emc_phy_l1_timing,emc_phy_l2_timing);
1131 EMC_SCMD_Issue(mem_info);
1133 LOCAL void __sdram_set_param(uint32 clk, SDRAM_CFG_INFO_T_PTR pCfg)
1136 EMC_PHY_L1_TIMING_T_PTR *emc_phy_l1_timing;
1137 EMC_PHY_L2_TIMING_T_PTR *emc_phy_l2_timing;
1138 emc_phy_l1_timing = EMC_GetPHYL1_Timing(pCfg);
1139 emc_phy_l2_timing = EMC_GetPHYL2_Timing(pCfg);
1140 EMC_Init(clk, EMC_CS0, EMC_AXI_ARM, pCfg, sdram_parameters, emc_phy_l1_timing, emc_phy_l2_timing);
1141 for (i=0; i<1000; i++){}
1144 #ifdef SDRAM_AUTODETECT_SUPPORT
1145 LOCAL uint32 __colum_to_mode(uint32 colum)
1151 col_mode = COL_MODE_8;
1154 col_mode = COL_MODE_9;
1157 col_mode = COL_MODE_10;
1160 col_mode = COL_MODE_11;
1163 col_mode = COL_MODE_12;
1171 LOCAL uint32 __row_to_mode(uint32 row)
1177 row_mode = ROW_MODE_11;
1180 row_mode = ROW_MODE_12;
1183 row_mode = ROW_MODE_13;
1186 row_mode = ROW_MODE_14;
1195 LOCAL BOOLEAN __is_rw_ok(uint32 addr, uint32 val)
1200 REG32(addr+4) = (~val);
1202 for(i=0;i<0xff;i++) {}
1204 if((REG32(addr) == val) && (REG32(addr+4) == (~val)))
1205 return ((BOOLEAN)SCI_TRUE);
1207 return ((BOOLEAN)SCI_FALSE);
1208 //return ((val == REG32(addr))? ((BOOLEAN)SCI_TRUE) : ((BOOLEAN)SCI_FALSE));
1211 // ADDR: |-BANK -|------------ COLUM 12 ---------------|
1212 // |A13|A12|A11|A10|A9|A8|A7|A6|A5|A4|A3|A2|A1|A0|
1214 // |------------------- ROW 14-------------------|
1215 // |A13|A12|A11|A10|A9|A8|A7|A6|A5|A4|A3|A2|A1|A0|
1216 LOCAL uint32 __col_row_detect(BOOLEAN is_col, SDRAM_CFG_INFO_T_PTR pCfg)
1218 uint32 num, max, min;
1219 uint32 offset, addr;
1220 uint32 width_offset = (DATA_WIDTH_16 == pCfg->data_width)?(WIDTH16_OFFSET):(WIDTH32_OFFSET);
1224 max = SDRAM_MAX_COLUM;
1225 min = SDRAM_MIN_COLUM;
1229 max = SDRAM_MAX_ROW;
1230 min = SDRAM_MIN_ROW;
1232 for(num = max; num >= min; num--)
1235 REG32(ZERO_ADDR) = MEM_REF_DATA0; /*lint !e413*/
1239 offset = num + width_offset - BYTE_OFFSET; // colum+width-byteoff
1243 offset = num + BANK_OFFSET + (uint32)s_colum + width_offset - BYTE_OFFSET; // row+bank+colum+width-byteoff
1245 addr = (1 << (offset - 1)) + ZERO_ADDR;
1246 if(__is_rw_ok(addr, MEM_REF_DATA1))
1248 // if 0addr not changed, row is ok
1249 if(MEM_REF_DATA0 == REG32(ZERO_ADDR)) /*lint !e413*/
1253 // 0addr changed, row is too big
1254 else if(MEM_REF_DATA1 == REG32(ZERO_ADDR)) /*lint !e413*/
1264 LOCAL void set_row_col(SDRAM_CFG_INFO_T_PTR pCfg)
1269 value = REG32(0x20000180);
1271 value |= ((pCfg->col_mode)<<4);
1272 value |= (pCfg->row_mode);
1273 REG32(0x20000180) = value;
1274 for(i =0 ; i < 1000; i++);
1278 LOCAL void __sdram_detect(uint32 clk)
1280 SDRAM_CFG_INFO_T_PTR pCfg = &s_sdram_raw_cfg;
1281 // uint32 state = STATE_SDRAM_TYPE;
1282 uint32 state = STATE_COLUM; //in sc8810 just need to detect the DDR's row and col
1285 //pCfg->bank_mode = BK_MODE_4;
1286 pCfg->row_mode = ROW_MODE_14;
1287 pCfg->col_mode = COL_MODE_12;
1288 pCfg->data_width = DATA_WIDTH_32;
1289 pCfg->burst_length = BURST_LEN_2;
1290 pCfg->cas_latency = CAS_LATENCY_3;
1291 pCfg->ext_mode_val = SDRAM_EXT_MODE_REG;
1292 pCfg->sdram_type = SDR_SDRAM;
1294 while(STATE_END != state)
1296 // __sdram_set_param(clk, pCfg);
1300 case STATE_SDRAM_TYPE:
1301 if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0)) // 16bit sdr/ddr detect ok, try 32bit
1303 pCfg->data_width = DATA_WIDTH_32;
1304 state = STATE_BIT_WIDTH;
1307 else // 16bit sdr failed, try 16bit ddr
1309 if(DDR_SDRAM == pCfg->sdram_type)
1311 for( ; ; ) {} // all failed
1313 pCfg->sdram_type = DDR_SDRAM;
1314 state = STATE_SDRAM_TYPE;
1318 case STATE_BIT_WIDTH:
1319 if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0)) // 32bit sdr/ddr detect ok, try colum
1321 state = STATE_COLUM;
1324 else // 32bit sdr/ddr detect failed, fix 16bit and try colum
1326 pCfg->data_width = DATA_WIDTH_16;
1327 state = STATE_COLUM;
1332 if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0))
1334 colum = __col_row_detect(SCI_TRUE, pCfg);
1335 pCfg->col_mode = __colum_to_mode(colum);
1336 s_colum = colum;//lint !e63
1342 for( ; ; ) {} // should not come here
1346 row = __col_row_detect(SCI_FALSE, pCfg);
1347 pCfg->row_mode = __row_to_mode(row);
1348 state = STATE_REINIT;
1359 /**---------------------------------------------------------------------------*
1361 ** void SDRAM_Init(uint32 sdram_clk) *
1364 ** initialize emc sdram module *
1376 **---------------------------------------------------------------------------*/
1377 LOCAL void SDRAM_Init (uint32 clk)
1379 sdram_parameters = SDRAM_GetTimingPara();
1381 #ifdef SDRAM_AUTODETECT_SUPPORT
1382 __sdram_detect(clk);
1384 __sdram_set_param(clk, SDRAM_GetCfg());
1390 /**---------------------------------------------------------------------------*
1392 ** void SDRAM_PinDrv_Set(void) *
1395 ** initialize emc pins *
1407 **---------------------------------------------------------------------------*/
1408 LOCAL void SDRAM_PinDrv_Set (void)
1410 #if defined(PLATFORM_SC8800G)
1412 uint32 clk_drv = 0x200;
1413 uint32 ctl_drv = 0x100;
1414 uint32 dat_drv = 0x100;
1416 REG32(PIN_CTL_REG) = 0X1FFF00; //set nf_rb keyin[0-7] wpus
1418 REG32(PINMAP_REG_BASE + 0X27c) = clk_drv;
1419 REG32(PINMAP_REG_BASE + 0X280) = clk_drv;
1421 for(i = 0; i<15; i++)
1423 REG32(PINMAP_REG_BASE + 0x019c + i*4) = ctl_drv;
1426 REG32(PINMAP_REG_BASE + 0X1d8) = ctl_drv;
1427 REG32(PINMAP_REG_BASE + 0X2a8) = ctl_drv;
1428 REG32(PINMAP_REG_BASE + 0X1FC) = ctl_drv;
1429 REG32(PINMAP_REG_BASE + 0X200) = ctl_drv;
1430 REG32(PINMAP_REG_BASE + 0X224) = ctl_drv;
1431 REG32(PINMAP_REG_BASE + 0X228) = ctl_drv;
1432 REG32(PINMAP_REG_BASE + 0X24c) = ctl_drv;
1433 REG32(PINMAP_REG_BASE + 0X250) = ctl_drv;
1434 REG32(PINMAP_REG_BASE + 0X274) = ctl_drv;
1435 REG32(PINMAP_REG_BASE + 0X278) = ctl_drv;
1437 for(i = 0; i<9; i++)
1438 REG32(PINMAP_REG_BASE + 0x0284 + i*4) = ctl_drv;
1441 for(i = 0; i<8; i++)
1443 REG32(PINMAP_REG_BASE + 0x1DC + i*4) = dat_drv;
1444 REG32(PINMAP_REG_BASE + 0x204 + i*4) = dat_drv;
1445 REG32(PINMAP_REG_BASE + 0x22c + i*4) = dat_drv;
1446 REG32(PINMAP_REG_BASE + 0x254 + i*4) = dat_drv;
1453 /**---------------------------------------------------------------------------*
1455 ** void Chip_ConfigClk(void) *
1458 ** set pll, arm clock,ahb clock,emc clock *
1461 ** p_system_clk_cfg *
1470 **---------------------------------------------------------------------------*/
1471 LOCAL uint32 Chip_ConfigClk (void)
1474 volatile uint32 arm_ahb_clk =0;
1476 #if defined(PLATFORM_SC6800H)
1479 //support dual pll, mpll 400mhz, bpll 480mhz
1481 volatile uint32 is_pll_done = 0;
1483 //clear the protect control
1484 CHIP_REG_SET(GR_MCU_PORT, PLL_MCU_PROT_VALUE);
1487 CHIP_REG_AND(GR_MISC1, ~ MISC1_MCU_PLL_EN);
1489 //set mpll to 400MHz
1490 CHIP_REG_SET(GR_MPLL_MN, MPLL_MN_400M);
1491 //clk_48M source select to bpll
1492 CHIP_REG_OR(AHB_CLK_CFG1, AHB_CLK_CFG1_SRCSEL48M);
1495 CHIP_REG_AND(GR_MISC1, ~MISC1_MCU_BPLL_FORCE_PD_EN);
1496 //select bpll controlled by hw and release bpll output
1497 CHIP_REG_OR(GR_MISC1, (MISC1_BPLL_SEL|MISC1_BPLL_CONT_DONE));
1500 CHIP_REG_OR (GR_MISC1, MISC1_MCU_PLL_EN);
1502 //wait pll count done
1503 is_pll_done = CHIP_REG_GET(GR_STATUS) & ((uint32) APB_STATUS_PLL_CNT_DONE);
1505 while (0 == is_pll_done)
1507 is_pll_done = CHIP_REG_GET(GR_STATUS) & ((uint32) APB_STATUS_PLL_CNT_DONE);
1510 //set the protect control
1511 CHIP_REG_SET(GR_MCU_PORT, 0);
1515 arm_ahb_clk = ARM_CLK_100M;
1516 //MPLL is open already in RomCode
1517 i = REG32 (AHB_CLK_CFG0);
1518 //set CLK_EMC to 192MHz
1519 i &= ~ (BIT_7 | BIT_6 | BIT_5 | BIT_4);
1520 i |= 0xC << 4; //Src_sel_emc:4'b1100 : MPLL_DIV2:
1521 i &= ~ (BIT_9 | BIT_8); //Div_cfg_emc:0x0
1522 //set CLK_ARM to 192MHz
1523 i &= ~ (BIT_2 | BIT_1); //Div_cfg_arm:0x01
1524 //set CLK_AHB to 96MHz
1526 //set Src_sel_arm to MPLL/2(192Mhz)
1528 REG32 (AHB_CLK_CFG0) = i;
1530 for (i=0; i<100; i++){}
1532 #elif defined(PLATFORM_SC8800G)
1533 #ifdef CONFIG_SC8810
1535 __ClkConfig(&g_emc_clk, (uint32*)&arm_ahb_clk);
1540 for (i=0; i<1000; i++) {}
1545 int timer_init(void);
1546 unsigned long long get_ticks(void);
1549 volatile unsigned int i;
1550 unsigned long long now;
1551 uint32 clkwr_dll = (64*s_emc_config.clk_wr)/(s_emc_config.read_value/2);
1555 do{}while(get_ticks() <= now+2);
1557 REG32(0x20000004) = 0x00000049;
1558 for(i = 0; i < 1000; i++);
1560 REG32(0x20000024) |= BIT_6;
1561 REG32(0x2000002C) |= BIT_6;
1562 for(i = 0; i < 1000; i++);
1564 REG32(0x20000194) = 0x0062272A;
1565 for(i = 0; i < 1000; i++);
1567 REG32(0x20000198) = 0x00200010;
1568 for(i = 0; i < 1000; i++);
1570 REG32(0x2000019c) = 0x00f0000e;
1571 for(i = 0; i < 1000; i++);
1573 REG32(0x200001a0) = 0x00f0000e;
1574 for(i = 0; i < 1000; i++);
1577 REG32(0x20000170) = 0x0011080;
1578 for(i = 0; i < 1000; i++);
1580 #ifndef CONFIG_BOARD_788
1581 REG32(0x2000010C) = (0x8000|clkwr_dll);
1583 REG32(0x2000010C) = 0x804A;
1585 REG32(0x20000110) = 0x8020;
1586 REG32(0x20000114) = 0x8020;
1587 REG32(0x20000118) = 0x8020;
1588 REG32(0x2000011C) = 0x8020;
1589 REG32(0x20000120) = 0x8020;
1590 REG32(0x20000124) = 0x8020;
1591 REG32(0x20000128) = 0x8020;
1592 REG32(0x2000012C) = 0x8020;
1593 REG32(0x20000130) = 0x8040;
1594 REG32(0x20000134) = 0x8040;
1595 REG32(0x20000138) = 0x8040;
1596 REG32(0x2000013C) = 0x8040;
1597 REG32(0x20000140) = 0x8040;
1598 REG32(0x20000144) = 0x8040;
1599 REG32(0x20000148) = 0x8040;
1600 REG32(0x2000014C) = 0x8040;
1602 REG32(0x20000170) = 0x11480;
1604 REG32(0x20000190) = 0x40010000;
1605 for(i =0 ; i < 1000; i++);
1607 REG32(0x20000190) = 0x40020000;
1608 for(i =0 ; i < 1000; i++);
1610 REG32(0x20000190) = 0x40020000;
1611 for(i =0 ; i < 1000; i++);
1613 REG32(0x20000190) = 0x40040031;
1614 for(i =0 ; i < 1000; i++);
1616 REG32(0x20000190) = 0x40048000;
1617 for(i =0 ; i < 1000; i++);
1619 //set cs map to 2G bit
1620 REG32(0x20000000) &= ~(0x7);
1621 // REG32(0x20000000) |= (0x7);
1622 REG32(0x20000000) |= (s_emc_config.cs_pos);
1623 //REG32(0x20000010) = 0x223;
1624 //REG32(0x20000014) = 0x223;
1626 REG32(0x20000184) = 0x233a3566;
1627 REG32(0x20000188) = 0x1a260322;
1628 //REG32(0x20000184) = 0x02371422;
1629 //REG32(0x20000188) = 0x121c0322;
1631 REG32(0x20000180) |= BIT_14;
1632 for(i =0 ; i < 1000; i++);
1634 //detect column mode and row mode
1636 for(i =0 ; i < 1000; i++);
1638 void set_emc_pad(uint32 clk_drv, uint32 ctl_drv, uint32 dat_drv, uint32 dqs_drv)
1641 REG32(PINMAP_REG_BASE + 0x27C) = clk_drv;
1642 REG32(PINMAP_REG_BASE + 0x280) = clk_drv;
1643 for(i = 0; i < 15; i++)
1645 REG32(PINMAP_REG_BASE + 0x19c + i * 4) = ctl_drv;
1647 REG32(PINMAP_REG_BASE + 0x1d8) = ctl_drv;
1649 for(i = 0; i < 10; i++)
1651 REG32(PINMAP_REG_BASE + 0x284 + i * 4) = ctl_drv;
1654 for(i = 0; i < 8; i++)
1656 REG32(PINMAP_REG_BASE + 0x1DC + i * 4) = dat_drv;
1657 REG32(PINMAP_REG_BASE + 0x204 + i * 4) = dat_drv;
1658 REG32(PINMAP_REG_BASE + 0x22C + i * 4) = dat_drv;
1659 REG32(PINMAP_REG_BASE + 0x254 + i * 4) = dat_drv;
1662 REG32(PINMAP_REG_BASE + 0x200) = dqs_drv;
1663 REG32(PINMAP_REG_BASE + 0x228) = dqs_drv;
1664 REG32(PINMAP_REG_BASE + 0x250) = dqs_drv;
1665 REG32(PINMAP_REG_BASE + 0x278) = dqs_drv;
1669 REG32(PINMAP_REG_BASE + 0x1FC) = dat_drv;
1670 REG32(PINMAP_REG_BASE + 0x224) = dat_drv;
1671 REG32(PINMAP_REG_BASE + 0x24C) = dat_drv;
1672 REG32(PINMAP_REG_BASE + 0x274) = dat_drv;
1674 // CKE OUTPUT in sleep
1675 REG32(PINMAP_REG_BASE + 0x1d8) |= 0x1;
1676 REG32(PINMAP_REG_BASE + 0x2a8) |= 0x1;
1680 #ifdef SPL_USB_DOWNLOAD
1681 void uart_trace(uint32 ch)
1684 REG32(0x84000000) = ch;
1685 for(i = 0; i < 0x4000; i++);
1687 typedef void (*JUMPTOHANDLER) (void);
1688 #ifdef CONFIG_SP8810
1689 #define KEY_DOWNLOAD_MODE_MAP 0x10 //keyout0-keyin7
1691 #define KEY_DOWNLOAD_MODE_MAP 0x01 //keyout0-keyin7
1693 PUBLIC void _KeypadEnable()
1696 REG32(0x8b000008) |= BIT_26 | BIT_8; //enable keypad
1697 //REG32(0X8B00004C) |= BIT_1;
1698 //for(i = 0; i < 0x100; i++);
1699 //REG32(0X8B00004C) &= ~BIT_1; //soft reset
1700 //REG32(0x87000010) |= 0xfff; //clear all interrupt
1702 //REG32(0x87000018) = 0xffff;
1703 //REG32(0x87000028) = 0;//debounce
1704 //REG32(0x8700001c) = 0xf;//debounce counter
1706 //REG32(0x87000000) |= 0x000001; //
1707 //REG32(0x87000000) |= 0x000001; //
1708 for(i = 0; i < 0x10000; i++);
1710 PUBLIC void _KeypadClear()
1712 REG32(0x87000010) |= 0xffff; //clear all interrupt
1714 //if download mode return 1, else return 0
1715 PUBLIC uint32 _Check_DownloadMode()
1717 volatile uint32 key_raw_int_sts = 0;
1718 volatile uint32 key_sts = 0;
1721 //for(i = 0; i < 0x100000; i++);
1723 i = REG32(0x87000000);
1725 uart_trace(i & 0xff);
1726 uart_trace((i >> 8) & 0xff);
1727 uart_trace((i >> 16) & 0xff);
1728 uart_trace((i >> 24) & 0xff);
1730 for(time = 0; time < 10; time++)
1735 for(i = 0; i < 0x200000; i++);
1736 key_raw_int_sts = REG32(0x87000008);
1737 key_sts = REG32(0x8700002c);
1740 //for(i = 0; i < 0x200000; i++);
1741 uart_trace(key_raw_int_sts & 0xff);
1742 uart_trace((key_raw_int_sts >> 8) & 0xff);
1743 uart_trace((key_raw_int_sts >> 16) & 0xff);
1744 uart_trace((key_raw_int_sts >> 24) & 0xff);
1747 uart_trace(key_sts & 0xff);
1748 uart_trace((key_sts >> 8)& 0xff);
1749 uart_trace((key_sts >> 16)& 0xff);
1750 uart_trace((key_sts >> 24)& 0xff);
1755 key_raw_int_sts &= BIT_0;
1758 if((key_sts == KEY_DOWNLOAD_MODE_MAP))
1761 return 1; //check ok
1766 PUBLIC void _JumpToDownload()
1770 JUMPTOHANDLER handler = (JUMPTOHANDLER)(0xffff0000);
1773 LOCAL uint32 SystemCountGet()
1777 clock = REG32(0x87003004);
1778 clock_c = REG32(0x87003004);
1779 while(clock != clock_c)
1781 clock = REG32(0x87003004);
1782 clock_c = REG32(0x87003004);
1786 #define SPL_USB_DOWNLOAD_TIMEOUT 3000
1787 PUBLIC void _WaitUsbDownloadKey()
1791 uint32 key_raw_int_sts = 0;
1794 time0 = SystemCountGet();
1797 key_raw_int_sts = REG32(0x87000008);
1798 key_sts = REG32(0x8700002c);
1799 key_raw_int_sts &= BIT_0;
1801 if((key_raw_int_sts != 0) && (key_sts == 0))
1805 time1 = SystemCountGet();
1806 if((time1 - time0) > SPL_USB_DOWNLOAD_TIMEOUT)
1813 PUBLIC void _WaitUsbDownloadKey()
1815 uint32 key_raw_int_sts = 0;
1826 key_raw_int_sts = REG32(0x87000008);
1827 key_raw_int_sts &= BIT_4;
1828 if(key_raw_int_sts != 0)
1838 // for(time = 0; time < 2; time++)
1840 //usb download key press
1844 //for(i = 0; i < 0x200000; i++)
1845 key_raw_int_sts = REG32(0x87000008);
1846 key_sts = REG32(0x8700002c);
1849 uart_trace(key_sts & 0xff);
1850 uart_trace((key_sts >> 8) & 0xff);
1852 uart_trace(key_raw_int_sts & 0xff);
1854 key_raw_int_sts &= BIT_0;
1856 if((key_raw_int_sts != 0) && (key_sts == 0))
1873 #define ARMCLK_CONFIG_EN 1
1874 void sc8810_emc_Init()
1877 volatile unsigned int i;
1879 set_emc_pad(s_emc_config.clk_drv, s_emc_config.ctl_drv, s_emc_config.dat_drv, s_emc_config.dqs_drv);
1882 REG32(0x8b00002c) &= ~(0x3);
1885 REG32(0x20900238) |= (1 << 11);
1886 REG32(0x20900238) &= ~(1 <<12);
1888 REG32(0x8b000018) |= (1 << 9);
1890 //set MPLL to 900MHz
1891 i = REG32(0x8b000024);
1893 #if ARMCLK_CONFIG_EN
1894 i |= s_emc_config.arm_clk;
1896 //i |= 0xFA; //1000M
1900 REG32(0x8b000024) = i;
1902 //set DPLL of EMC to 400MHz
1903 i = REG32(0x8b000040);
1905 i |= s_emc_config.emc_clk;
1909 REG32(0x8b000040) = i;
1910 REG32(0x8b000018) &= ~(1 << 9);
1913 #if 1 // emc from DPLL
1914 REG32(0x20900224) = (3 << 23) | (3 << 12);
1915 REG32(0x20900224) |= (3 << 4) | (0 << 8) | (7 << 14);
1916 REG32(0x20900224) |= (1 << 23) | (3 << 4) | (0 << 8) | (7 << 14);
1917 for(i = 0; i < 1000; i++);
1919 REG32(0x20900224) = (3 << 4) | (0 << 8) | (7 << 14) | (1 << 12/*select dpll*/);
1920 #else // EMC from MPLL
1921 REG32(0x20900224) = (3 << 23) | (3 << 12);
1922 REG32(0x20900224) |= (3 << 4) | (1 << 8) | (7 << 14);
1923 REG32(0x20900224) |= (1 << 23) | (3 << 4) | (1 << 8) | (7 << 14);
1924 for(i = 0; i < 1000; i++);
1926 REG32(0x20900224) = (3 << 4) | (1 << 8) | (7 << 14) | (0 << 12/*select mpll*/);
1928 #ifdef SPL_USB_DOWNLOAD
1930 //if not in download mode
1931 //if(_Check_DownloadMode() == 0)
1935 _WaitUsbDownloadKey();
1941 static const int dcdc_ctl_vol[] = {
1942 650, 700, 800, 900, 1000, 1100, 1200, 1300, 1400,
1945 PUBLIC void dcdc_calibrate(int chan, int to_vol)
1948 uint32 ctl_vol = to_vol;
1950 for (i = 0; i < ARRAY_SIZE(dcdc_ctl_vol) - 1; i++) {
1951 if (ctl_vol < dcdc_ctl_vol[i + 1])
1954 if (i >= ARRAY_SIZE(dcdc_ctl_vol) - 1)
1958 dcdc_ctl = ANA_DCDCARM_CTL;
1960 else if (chan == 11) {
1961 dcdc_ctl = ANA_DCDC_CTL;
1966 ANA_REG_SET(dcdc_ctl, i | (0x07 - i) << 4);
1971 PUBLIC void Chip_Init (void) /*lint !e765 "Chip_Init" is used by init.s entry.s*/
1973 volatile uint32 i = 0;
1974 if (REG32(0x209003fc) == CHIP_ID_8810S) {
1975 dcdc_calibrate(10, 1300);//vddarm 1.30v
1976 dcdc_calibrate(11, 1200);//vddcore 1.20v
1978 EMC_PARAM_T_PTR emc_ptr = EMC_GetPara();
1980 s_emc_config.arm_clk = emc_ptr->arm_clk/1000000/4;
1981 s_emc_config.emc_clk = emc_ptr->emc_clk/1000000/4;
1982 s_emc_config.dqs_drv = (emc_ptr->dqs_drv << 8);
1983 s_emc_config.dat_drv = (emc_ptr->dat_drv << 8);
1984 s_emc_config.ctl_drv = (emc_ptr->ctl_drv << 8);
1985 s_emc_config.clk_drv = (emc_ptr->clk_drv << 8);
1986 s_emc_config.clk_wr = emc_ptr->clk_wr;
1987 s_emc_config.read_value = (emc_ptr->read_value & 0xff);
1988 s_emc_config.cs_pos = emc_ptr->cs_pos;
1990 for (i = 0; i < 0xff1; ++i);
1992 g_ahb_clk = 200000000;
1993 for (i=0; i<0xff1; i++);
1995 // AHB master priority: DSP > lcdc > other > GPU
1996 REG32(0x20000020) = 0x7D;
1997 REG32(0x20000024) = 0x4D;
1998 REG32(0x20000030) = 0x1c31D;
1999 REG32(0x20000050) = 0x1c31D;
2000 REG32(0x20000058) = 0x1c31D;
2001 REG32(0x20000060) = 0x1c31E;
2002 REG32(0x20000038) = 0x1c31F;
2003 REG32(0x20000040) = 0x1c31F;
2004 REG32(0x20000048) = 0x1c31F;