1 \r/******************************************************************************
\r
3 ** Author: Johnny Wang
\r
5 ** Copyright: 2007 Spreatrum, Incoporated. All Rights Reserved.
\r
7 ******************************************************************************/
\r
8 /******************************************************************************
\r
10 **-------------------------------------------------------------------------
\r
11 ** DATE NAME DESCRIPTION
\r
12 ** 2012/12/04 Create.
\r
13 ******************************************************************************/
\r
14 #include <asm/arch/os_api.h>
\r
15 #include <asm/arch/arm_reg.h>
\r
16 #include <asm/arch/sc_reg.h>
\r
17 #include <asm/arch/sc8825_emc_cfg.h>
\r
18 #include <asm/arch/emc_reg_v250a.h>
\r
19 #include <asm/arch/sc8810_reg_ahb.h>
\r
20 #include <asm/arch/sc8810_reg_global.h>
\r
21 #include <asm/arch/adi_hal_internal.h>
\r
22 #include <asm/arch/analog_reg_v3.h>
\r\r
29 /*----------------------------------------------------------------------------*
\r
30 ** Test Cases Prototype *
\r
31 **----------------------------------------------------------------------------*/
\r
34 uint32 LPDDR1_MEM_DS = LPDDR1_DS_39_OHM; //lpddr1 driver strength,refer to multiPHY p155
\r
35 uint32 LPDDR2_MEM_DS = LPDDR2_DS_40_OHM; //lpddr1 driver strength,
\r
36 PUBL_DS_E PUBL_DS = PUBL_DS_40OHM; //publ driver strength,
\ruint32 B0_DQS_STEP_DLY = DQS_STEP_DLY_DEF; //byte0 dqs step delay
\r
37 uint32 B1_DQS_STEP_DLY = DQS_STEP_DLY_DEF; //byte1 dqs step delay
\r
38 uint32 B2_DQS_STEP_DLY = DQS_STEP_DLY_DEF; //byte2 dqs step delay
\r
39 uint32 B3_DQS_STEP_DLY = DQS_STEP_DLY_DEF; //byte3 dqs step delay
\r
40 uint32 B0_SDLL_PHS_DLY = SDLL_PHS_DLY_DEF; //byte0 sll dll phase delay
\r
41 uint32 B1_SDLL_PHS_DLY = SDLL_PHS_DLY_DEF; //byte1 sll dll phase delay
\r
42 uint32 B2_SDLL_PHS_DLY = SDLL_PHS_DLY_DEF; //byte2 sll dll phase delay
\r
43 uint32 B3_SDLL_PHS_DLY = SDLL_PHS_DLY_DEF; //byte3 sll dll phase delay
\r
44 DRAM_INFO_T static_dram_info={0};
\r
46 int mem_name_cmp(char *str1,char *str2)
\r
48 while((*str1==*str2)&& *str1!='\0')
\r
54 if(*str1=='\0'&&*str2=='\0')
\r
64 static BOOLEAN __is_bond_lpddr2()
\r
67 if( ((ADI_Analogdie_reg_read(ANA_STATUS))&BIT_6) == BIT_6 )
\r
78 static void set_reg_fld(uint32 addr, uint32 start_bit, uint32 bit_num, uint32 value) {
\r
80 temp = REG32(addr) ;
\r
81 for(i=0;i<bit_num;i++) {
\r
82 temp &= ~(0x1<<(start_bit+i));
\r
84 temp |= value<<start_bit;
\r
88 DRAM_INFO_T_PTR get_dram_info(char* dram_chip_name)
\r
91 for(i = 0; i < sizeof(DRAM_MODE_INFO_ARRAY)/sizeof(DRAM_MODE_INFO_T);i++)
\r
93 if(mem_name_cmp(DRAM_CHIP_NAME_INFO_ARRAY[i],dram_chip_name)==TRUE)
\r
95 static_dram_info.chip_name = DRAM_CHIP_NAME_INFO_ARRAY[i];
\r
96 static_dram_info.time_info = &DRAM_TIMING_INFO_ARRAY[i];
\r
97 static_dram_info.mode_info = &DRAM_MODE_INFO_ARRAY[i];
\r
104 return &static_dram_info;
\r
107 void set_reg_val_min_max(uint32 reg,uint32 val,uint32 min,uint32 max)
\r
109 if(val>=min && val<=max)
\r
123 uint32 cal_cs_val(DRAM_DENSITY_E density)
\r
127 case DRAM_64MBIT: return 0;
\r
128 case DRAM_128MBIT:return 1;
\r
129 case DRAM_256MBIT:return 2;
\r
130 case DRAM_512MBIT:return 3;
\r
131 case DRAM_1GBIT :return 4;
\r
132 case DRAM_2GBIT :return 5;
\r
133 case DRAM_4GBIT :return 6;
\r
134 case DRAM_8GBIT :return 7;
\r
139 uint32 cal_mem_drv(LPDDR2_MEM_DS_T_E mem_drv)
\r
143 case LPDDR2_DS_34_OHM:return 1;
\r
144 case LPDDR2_DS_40_OHM:return 2;
\r
145 case LPDDR2_DS_48_OHM:return 3;
\r
146 case LPDDR2_DS_60_OHM:return 4;
\r
147 case LPDDR2_DS_80_OHM:return 6;
\r
152 void wait_us(uint32 us)
\r
158 for(j=0;j<300;j++);
\r
162 void wait_pclk(uint32 n)
\r
167 for(i = 0; i < n; i++)
\r
169 value = REG32(PUBL_CFG_PGSR);
\r
173 void modify_dpll_freq (CLK_TYPE_E emc_clk)
\r
177 //step1: enable register write
\r
178 REG32(GR_GEN1_SET) = BIT_9;
\r
180 //step2: modify dpll parameter N
\r
181 temp = (emc_clk/4000000);
\r
182 set_reg_fld(GR_DPLL_MN,0,11,temp);
\r
184 //step3: disable register write
\r
185 REG32(GR_GEN1_CLR) = BIT_9;
\r
188 void set_emc_clk(CLK_TYPE_E emc_clk)
\r
190 uint32 emc_clk_div = 0;
\r
191 emc_clk_div = 400000000/emc_clk -1;
\r
193 REG32(GR_GEN1_SET) = BIT_9;
\r
195 //ensure emc is in idle state
\r
196 //step 1, disable emc clk
\r
197 set_reg_fld(AHB_CTL0,28,1,0);
\r
199 //step 2,assert address,command,data dll
\r
200 set_reg_fld(PUBL_CFG_ACDLLCR,30,1,0);
\r
201 set_reg_fld(PUBL_CFG_DX0DLLCR,30,1,0);
\r
202 set_reg_fld(PUBL_CFG_DX1DLLCR,30,1,0);
\r
203 set_reg_fld(PUBL_CFG_DX2DLLCR,30,1,0);
\r
204 set_reg_fld(PUBL_CFG_DX3DLLCR,30,1,0);
\r
206 //step3,modify dpll
\r
207 modify_dpll_freq(400000000);
\r
208 set_reg_fld(AHB_ARM_CLK,12,2,1);
\r
209 set_reg_fld(AHB_ARM_CLK,8,4,emc_clk_div); //clk_emc_div
\r
210 set_reg_fld(AHB_ARM_CLK,3,1,1); //clk_emc_sync
\r
211 wait_us(150); //PLL lock time. 150us should be enough. please define this function by yourself
\r
213 //step4,enable emc clk
\r
214 set_reg_fld(AHB_CTL0,28,1,1);
\r
216 //step 2,deassert address,command,data dll
\r
217 set_reg_fld(PUBL_CFG_ACDLLCR,30,1,1);
\r
218 set_reg_fld(PUBL_CFG_DX0DLLCR,30,1,1);
\r
219 set_reg_fld(PUBL_CFG_DX1DLLCR,30,1,1);
\r
220 set_reg_fld(PUBL_CFG_DX2DLLCR,30,1,1);
\r
221 set_reg_fld(PUBL_CFG_DX3DLLCR,30,1,1);
\r
222 wait_us(7); //for DLL to lock, spec is 5.12us. we reserve more cycles. please define this function by yourself
\r
224 REG32(GR_GEN1_CLR) = BIT_9;
\r
227 void EMC_CTL_State_Move(EMC_CTL_STATE_E next_state)
\r
232 case CTL_STATE_INIT_MEM :
\r
234 while(CTL_CURRENT_STATE != CTL_STATE_INIT_MEM)
\r
236 switch(CTL_CURRENT_STATE)
\r
238 case CTL_STATE_CONFIG:
\r
240 REG32(UMCTL_CFG_SCTL) = CTL_CMD_INIT;
\r
241 while(CTL_CURRENT_STATE != CTL_STATE_INIT_MEM);
\r
244 case CTL_STATE_ACCESS:
\r
246 REG32(UMCTL_CFG_SCTL) = CTL_CMD_CFG;
\r
247 while(CTL_CURRENT_STATE != CTL_STATE_CONFIG);
\r
250 case CTL_STATE_LOW_POWER:
\r
252 REG32(UMCTL_CFG_SCTL) = CTL_CMD_WAKEUP;
\r
253 while(CTL_CURRENT_STATE != CTL_STATE_ACCESS);
\r
262 case CTL_STATE_CONFIG:
\r
264 while(CTL_CURRENT_STATE != CTL_STATE_CONFIG)
\r
266 switch(CTL_CURRENT_STATE)
\r
268 case CTL_STATE_LOW_POWER:
\r
270 REG32(UMCTL_CFG_SCTL) = CTL_CMD_WAKEUP;
\r
271 while(CTL_CURRENT_STATE != CTL_STATE_ACCESS);
\r
274 case CTL_STATE_INIT_MEM:
\r
276 REG32(UMCTL_CFG_SCTL) = CTL_CMD_CFG;
\r
277 while(CTL_CURRENT_STATE != CTL_STATE_CONFIG);
\r
280 case CTL_STATE_ACCESS:
\r
282 REG32(UMCTL_CFG_SCTL) = CTL_CMD_CFG;
\r
283 while(CTL_CURRENT_STATE != CTL_STATE_CONFIG);
\r
292 case CTL_STATE_LOW_POWER:
\r
294 while(CTL_CURRENT_STATE != CTL_STATE_LOW_POWER)
\r
296 switch(CTL_CURRENT_STATE)
\r
298 case CTL_STATE_ACCESS:
\r
300 REG32(UMCTL_CFG_SCTL) = CTL_CMD_SLEEP;
\r
301 while(CTL_CURRENT_STATE != CTL_STATE_LOW_POWER);
\r
304 case CTL_STATE_CONFIG:
\r
306 REG32(UMCTL_CFG_SCTL) = CTL_CMD_GO;
\r
307 while(CTL_CURRENT_STATE != CTL_STATE_ACCESS);
\r
310 case CTL_STATE_INIT_MEM:
\r
312 REG32(UMCTL_CFG_SCTL) = CTL_CMD_CFG;
\r
313 while(CTL_CURRENT_STATE != CTL_STATE_CONFIG);
\r
322 case CTL_STATE_ACCESS:
\r
324 while(CTL_CURRENT_STATE != CTL_STATE_ACCESS)
\r
326 switch(CTL_CURRENT_STATE)
\r
328 case CTL_STATE_CONFIG:
\r
330 REG32(UMCTL_CFG_SCTL) = CTL_CMD_GO;
\r
331 while(CTL_CURRENT_STATE != CTL_STATE_ACCESS);
\r
334 case CTL_STATE_INIT_MEM:
\r
336 REG32(UMCTL_CFG_SCTL) = CTL_CMD_CFG;
\r
337 while(CTL_CURRENT_STATE != CTL_STATE_CONFIG);
\r
340 case CTL_STATE_LOW_POWER:
\r
342 REG32(UMCTL_CFG_SCTL) = CTL_CMD_WAKEUP;
\r
343 while(CTL_CURRENT_STATE != CTL_STATE_ACCESS);
\r
357 void EMC_MEM_Mode_set(DRAM_INFO_T_PTR dram_info)
\r
360 uint32 mddr_lpddr2_en = 0;
\r
362 if(dram_info->mode_info->mem_type == DRAM_LPDDR1)
\r
364 mddr_lpddr2_en = 2;
\r
366 else if(((dram_info->mode_info->mem_type)&DRAM_LPDDR2) == DRAM_LPDDR2)
\r
368 mddr_lpddr2_en = 3;
\r
373 mddr_lpddr2_en = 0;
\r
376 #ifdef EMC_SMALL_CODE_SIZE
\r
377 REG32(UMCTL_CFG_MCFG) = 0x60010;
\r
378 REG32(UMCTL_CFG_MCFG) |=((mddr_lpddr2_en<<22)|
\r
379 (dram_info->mode_info->bl<<20)|
\r
380 ((dram_info->mode_info->mem_type ==DRAM_LPDDR2_S4)? 0x40:0));
\r
382 REG32(UMCTL_CFG_MCFG1) = 0;
\r
385 REG32(UMCTL_CFG_MCFG) = (
\r
386 (0x0<<24) | //mddr_lpddr2_clk_stop_idle, 0:disable
\r
387 (mddr_lpddr2_en<<22) | // 2'b00 = mDDR/LPDDR2 Disabled, 2'b10 = mDDR Enabled, 2'b11 = LPDDR2 Enabled
\r
388 (dram_info->mode_info->bl<<20) |
\r
389 (1<<18) | //tFAW to be 4,5,or 6 times tRRD when=0,1,2
\r
390 (1<<17) | //power down exit mode,0:slow exit 1:fast exit
\r
391 (0<<16) | //power down type,0:percharge power down,1:active power down
\r
392 (0x0<<8) | //Power-down idle period in n_clk cycles. Memories are placed into power-down modeif the NIF is idle for pd_idle n_clk cycles
\r
393 ((dram_info->mode_info->mem_type ==DRAM_LPDDR2_S4)? 0x40:0) | //lpddr2_s4 enable
\r
394 ((dram_info->mode_info->mem_type ==DRAM_DDR3)? 0x20:0) | //ddr3 enable
\r
395 (1<<4) | // stagger cs_n,0:dis 1:enable
\r
396 (0<<3) | // 2T timing for memory command,0:dis 1:enable
\r
397 (0<<2) | // Setting this bit enables the BL8 interrupt function of DDR2
\r
398 //(1<<1) | // This bit is intended to be set for 4-rank RDIMMs, which have a 2-bit CKE input
\r
399 (dram_info->mode_info->bl==DRAM_BL8?1:0) );// The BL setting in DDR2 / DDR3 must be consistent with the value programmed into the BL field of MR0.
\r
400 // 1'b0 = BL4, Burst length of 4 (MR0.BL=3'b010, DDR2 only)
\r
401 // 1'b1 = BL8, Burst length of 8 (MR0.BL=3'b011 for DDR2, MR0.BL=2'b00 for DDR3)
\r
403 REG32(UMCTL_CFG_MCFG1) = ((0<<31) | //When this bit is programmed to 1¡¯b1 the c_active_in pin can be used to exit from the automatic clock stop , power down or self-refresh modes.
\r
404 (0x0<<16) | //Hardware idle period. The c_active output is driven high if the NIF is idle in Access state for hw_idle * 32 * n_clk cycles
\r
405 (0<<8) | //tfaw_cfg_offset
\r
406 (0x0<<0) ); //Self Refresh idle period. Memories are placed into Self-Refresh mode if the NIF is idle in Access state for sr_idle * 32 * n_clk cycles
\r
409 if(dram_info->mode_info->io_width == IO_WIDTH_16)//x16
\r
411 REG32(UMCTL_CFG_PPCFG) = 0x18;
\r
413 else if(dram_info->mode_info->io_width == IO_WIDTH_8)//x16//x8
\r
415 REG32(UMCTL_CFG_PPCFG) = 0x1c;
\r
418 REG32(UMCTL_CFG_LPDDR2ZQCFG) = 0xAB0A560A;//[31:24]:zqcl_op [23:16]:zqcl_ma [15:8]:zqcs_op [7:0]:zqcs_ma
\r
423 void EMC_MEM_Timing_Set(CLK_TYPE_E emc_clk,DRAM_INFO_T_PTR dram_info)
\r
425 DRAM_TIMING_INFO_T_PTR time_info = dram_info->time_info;
\r
426 DRAM_MODE_INFO_T_PTR mode_info = dram_info->mode_info;
\r
429 uint32 emc_clk_d = 0;
\r
431 emc_clk_d = emc_clk/1000000;
\r
432 mem_t = (1000000000/emc_clk);
\r
434 REG32(UMCTL_CFG_TOGCNT1U) = emc_clk/1000000;
\r
435 REG32(UMCTL_CFG_TINIT) = 200; //200us
\r
436 REG32(UMCTL_CFG_TRSTH) = 0; //500us when ddr3,others 0
\r
437 REG32(UMCTL_CFG_TOGCNT100N) = emc_clk/10000000;
\r
438 REG32(UMCTL_CFG_TREFI) = time_info->tREFI/100; //unit is TOGCNT100N
\r
439 REG32(UMCTL_CFG_TMRD) = (mode_info->mem_type==DRAM_LPDDR1)? 2:5;
\r
440 REG32(UMCTL_CFG_TRTW) = (mode_info->mem_type==DRAM_LPDDR1)? 3: ((emc_clk>CLK_200MHZ)? 2:1);
\r
441 REG32(UMCTL_CFG_TAL) = 0; //no al for lpddr1/lpddr2,ddr3:0, CL-1, CL-2 (depending on AL=0,1,2 in MR1)
\r
442 REG32(UMCTL_CFG_TCL) = mode_info->rl;
\r
443 REG32(UMCTL_CFG_TCWL) = (mode_info->mem_type == DRAM_LPDDR1) ? 1 : mode_info->wl;
\r
444 REG32(UMCTL_CFG_TDPD) = (((mode_info->mem_type)&DRAM_LPDDR2)==DRAM_LPDDR2) ? 500 : 0;
\r
445 REG32(UMCTL_CFG_TXP) = time_info->tXP; //tXPmin=7.5ns,fast exit
\r
446 REG32(UMCTL_CFG_TCKE) = (mode_info->mem_type==DRAM_LPDDR1)? 2:3;
\r
447 //REG32(UMCTL_CFG_TZQCSI)= (mode_info->mem_type==DRAM_LPDDR1)? 0:0;
\r
448 REG32(UMCTL_CFG_TZQCSI) = 0;
\r
449 REG32(UMCTL_CFG_TZQCL) = (mode_info->mem_type==DRAM_LPDDR1)? 0:(time_info->tZQCL*emc_clk_d/1000); //???
\r
450 REG32(UMCTL_CFG_TMOD) = 0; //???
\r
451 REG32(UMCTL_CFG_TRSTL) = 0; //???
\r
452 REG32(UMCTL_CFG_TMRR) = 2; // default value,don't need set
\r
453 REG32(UMCTL_CFG_TRFC) = (time_info->tRFC*emc_clk_d/1000);
\r
454 REG32(UMCTL_CFG_TRC) = (time_info->tRC*emc_clk_d/1000);
\r
455 REG32(UMCTL_CFG_TRCD) = (time_info->tRCD*emc_clk_d/1000);
\r
456 REG32(UMCTL_CFG_TRRD) = (time_info->tRRD*emc_clk_d/1000);
\r
457 REG32(UMCTL_CFG_TWR) = (time_info->tWR*emc_clk_d/1000);
\r
458 REG32(UMCTL_CFG_TWTR) = time_info->tWTR;
\r
459 REG32(UMCTL_CFG_TEXSR) = time_info->tXSR*emc_clk_d/1000;
\r
460 REG32(UMCTL_CFG_TXPDLL) = 0; //slow exit should be 0???
\r
461 REG32(UMCTL_CFG_TDQS) = 2;
\r
463 if(mode_info->mem_type==DRAM_LPDDR1)
\r
465 REG32(UMCTL_CFG_TRP) = (time_info->tRP*emc_clk_d/1000);
\r
466 REG32(UMCTL_CFG_TRAS) = (time_info->tRAS*emc_clk_d/1000);
\r
467 REG32(UMCTL_CFG_TRTP) = 0;
\r
468 REG32(UMCTL_CFG_TZQCS) = 0;
\r
469 REG32(UMCTL_CFG_TCKSRE) = 0;
\r
470 REG32(UMCTL_CFG_TCKSRX) = 0;
\r
471 REG32(UMCTL_CFG_TZQCL) = 0;
\r
472 REG32(UMCTL_CFG_TCKESR) = 0;
\r
474 else if(((mode_info->mem_type)&DRAM_LPDDR2)==DRAM_LPDDR2)
\r
476 REG32(UMCTL_CFG_TRP) = (time_info->tRP*emc_clk_d/1000)+0x20000;
\r
477 REG32(UMCTL_CFG_TRAS) = (time_info->tRAS*emc_clk_d/1000) + 1;
\r
478 REG32(UMCTL_CFG_TRTP) = 3;
\r
479 REG32(UMCTL_CFG_TZQCS) =(time_info->tZQCS*emc_clk_d/1000);
\r
480 REG32(UMCTL_CFG_TCKSRE) = 0;
\r
481 REG32(UMCTL_CFG_TCKSRX) = 0;
\r
482 REG32(UMCTL_CFG_TZQCL) = (time_info->tZQCL*emc_clk_d/1000);
\r
483 REG32(UMCTL_CFG_TCKESR) = (time_info->tCKESR*emc_clk_d/1000);
\r
488 while(1);//don't support ddr3 now
\r
492 void EMC_MEM_Power_Up()
\r
494 volatile uint32 i = 0;
\r
495 REG32(UMCTL_CFG_POWCTL) = 1;
\r
497 //wait unitl power up finished
\r
498 do{i = (REG32(UMCTL_CFG_POWSTAT)&0X1);}
\r
506 void EMC_CTL_Mode_Set(DRAM_INFO_T_PTR dram_info)
\r
508 uint32 dram_type = 1;
\r
509 uint32 dram_dsty_cs0 = cal_cs_val(dram_info->mode_info->cs0_cap);
\r
510 uint32 dram_dsty_cs1 = cal_cs_val(dram_info->mode_info->cs1_cap);
\r
511 uint32 dram_io_width = dram_info->mode_info->io_width;
\r
513 if(dram_info->mode_info->cs1_cap == DRAM_0BIT)
\r
515 dram_dsty_cs1 = dram_dsty_cs0;
\r
517 if(dram_info->mode_info->mem_type==DRAM_LPDDR2_S4)
\r
521 else if(dram_info->mode_info->mem_type==DRAM_LPDDR2_S2)
\r
525 else if(dram_info->mode_info->mem_type==DRAM_LPDDR1)
\r
527 if( (dram_info->mode_info->cs0_cap == DRAM_1GBIT && dram_info->mode_info->io_width==IO_WIDTH_32) ||
\r
528 (dram_info->mode_info->cs0_cap == DRAM_512MBIT && dram_info->mode_info->io_width==IO_WIDTH_16) )
\r
538 REG32(UMCTL_CFG_DCFG_CS0) = RANK_ROW_BANK_COL|(dram_type<<6)|(dram_dsty_cs0<<2)|dram_io_width;
\r
539 REG32(UMCTL_CFG_DCFG_CS1) = RANK_ROW_BANK_COL|(dram_type<<6)|(dram_dsty_cs1<<2)|dram_io_width;
\r
541 REG32(UMCTL_CFG_SCFG) = 0X420;
\r
543 REG32(UMCTL_REG_MRRCFG0) = 1;//set byte1 to store mode register read result
\r
546 void EMC_CTL_CHN_Set(EMC_CHN_INFO_T_PTR emc_chn_info)
\r
548 volatile uint32 i = 0;
\r
549 for(i=EMC_PORT_MIN; i <= EMC_PORT_MAX; i++)
\r
551 REG32(UMCTL_CFG_PCFG_0 +4*i) = ((emc_chn_info+i)->port_data_quantum<<16) |
\r
552 ((emc_chn_info+i)->rdwr_order<<7) |
\r
553 (0x1<<6) | //store_forward enable
\r
554 (0x1<<5) | //back_pressure_read enable
\r
555 (0x1<<4) | //back_pressure_write enable
\r
556 ((emc_chn_info+i)->port_priority);
\r
561 MEM_CMD_RESULT_E EMC_CTL_MDR_Issue(DRAM_INFO_T_PTR dram_info,DRAM_CS_NUM_E cs_num,MEM_CMD_TYPE_E cmd,uint8 mdr)
\r
563 volatile uint32 temp;
\r
570 DRAM_TYPE_E mem_type;
\r
572 bl = dram_info->mode_info->bl+1;
\r
573 wl = dram_info->mode_info->wl;
\r
574 rl = dram_info->mode_info->rl;
\r
575 nwr = REG32(UMCTL_CFG_TWR)-2;
\r
576 mem_ds = cal_mem_drv(LPDDR2_MEM_DS);
\r
577 mem_type = dram_info->mode_info->mem_type&DRAM_LPDDR2;
\r
580 //caluate rl&wr parameter which should be set in lpddr2 MR2
\r
582 if(mem_type ==DRAM_LPDDR2)
\r
584 if((rl == LPDDR2_RL3) && (wl == LPDDR2_WL1))
\r
588 else if(rl == LPDDR2_RL4 && wl == LPDDR2_WL2)
\r
592 else if(rl == LPDDR2_RL5 && wl == LPDDR2_WL2)
\r
596 else if(rl == LPDDR2_RL6 && wl == LPDDR2_WL3)
\r
600 else if(rl == LPDDR2_RL7 && wl == LPDDR2_WL4)
\r
604 else if(rl == LPDDR2_RL8 && wl == LPDDR2_WL4)
\r
610 rl_wl = 4;//default value,rl=6,wl=3
\r
622 case CMD_DPDE: REG32(UMCTL_CFG_MCMD) = 0X89000000+cmd+(cs_num<<20);break;
\r
625 if(mem_type ==DRAM_LPDDR2)
\r
637 case 40: REG32(UMCTL_CFG_MCMD) = 0X89000008+(mdr<<4)+(cs_num<<20);break;
\r
643 case 63: return CMD_MDR_WR_ONLY;break;
\r
644 default: return CMD_MDR_NOT_EXIT;break;
\r
650 return CMD_MDR_NOT_EXIT;//only lpddr2 support mode resiger read
\r
656 if(mem_type ==DRAM_LPDDR2)//lpddr2
\r
660 case 1: REG32(UMCTL_CFG_MCMD) = 0X89000013|(bl<<12)|(DRAM_BURST_TYPE<<15)|(DRAM_BURST_WRAP<<16)|(nwr<<17)|(cs_num<<20);break;
\r
661 case 2: REG32(UMCTL_CFG_MCMD) = 0X89000023|(rl_wl<<12)|(cs_num<<20);break;
\r
662 case 3: REG32(UMCTL_CFG_MCMD) = 0X89000033|(mem_ds<<12)|(cs_num<<20);break;
\r
663 case 9: return CMD_MDR_NOP;break;
\r
664 case 10: REG32(UMCTL_CFG_MCMD) = 0X890ff0a3|(cs_num<<20);break;//0xff:calb after init, 0xab:long calb, 0x56: short calb, 0xc3:zq reset
\r
665 case 63: REG32(UMCTL_CFG_MCMD) = 0x890ee3f3|(cs_num<<20);break;//mdr reset,will reset all mdr to default
\r
674 case 40: return CMD_MDR_RD_ONLY;break;
\r
675 default: return CMD_MDR_NOT_EXIT;break;
\r
682 case 0: REG32(UMCTL_CFG_MCMD) = 0x89000003|(0x0<<17)|((bl|(rl<<4))<<4)|(cs_num<<20);break;//lpddr1 mode resigter
\r
683 case 1: REG32(UMCTL_CFG_MCMD) = 0x89000003|(0x2<<17)|(0<<4)|(cs_num<<20);break; //lpddr1 extern mode resigter
\r
684 default:return CMD_MDR_NOT_EXIT;break;
\r
690 default: return CMD_ERR;
\r
694 //wait memory cmd finished
\r
695 do{temp = (REG32(UMCTL_CFG_MCMD))&0x80000000;}
\r
696 while( temp != 0x00000000);
\r
700 return CMD_MDR_SUCCESS;
\r
703 BOOLEAN EMC_MEM_Init(DRAM_INFO_T_PTR dram_info)
\r
705 volatile uint32 value_temp;
\r
706 volatile uint32 i = 0;
\r
707 DRAM_BL_E bl = dram_info->mode_info->bl;
\r
708 DRAM_TYPE_E mem_type = dram_info->mode_info->mem_type;
\r
712 if(mem_type==DRAM_LPDDR1)//lpddr1
\r
715 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_PREA, NONE_MDR);
\r
718 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_REF, NONE_MDR);
\r
719 //EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_NOP, 0xff);
\r
720 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_REF, NONE_MDR);
\r
721 //EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_NOP, 0xff);
\r
723 //set lpddr1 mode register 0
\r
724 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_MRS, 0);
\r
725 //EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_NOP, 0xff);
\r
728 //set lpddr1 external mode register
\r
729 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_MRS, 1);
\r
730 //EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_NOP, 0xff);
\r
733 else if((mem_type&DRAM_LPDDR2) == DRAM_LPDDR2) //lpddr2
\r
736 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_MRS, 63);
\r
740 EMC_CTL_MDR_Issue(dram_info,FIRST_CS, CMD_MRS, 10);
\r
743 EMC_CTL_MDR_Issue(dram_info,SECOND_CS, CMD_MRS, 10);
\r
745 //Memory burst type sequential is not supported for mDDR and LPDDR2 with BL8
\r
746 if(bl==DRAM_BL8 && DRAM_BURST_TYPE==DRAM_BT_SEQ)
\r
751 //set lpddr2 mode register 1
\r
752 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_MRS, 1);
\r
754 //set lpddr2 mode mode register 2
\r
755 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_MRS, 2);
\r
757 //set lpddr2 mode mode register 3
\r
758 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_MRS, 3);
\r
761 EMC_CTL_MDR_Issue(dram_info,ALL_TWO_CS, CMD_REF, NONE_MDR);
\r
764 else //ddr3 not support in tiger
\r
771 //MR63: reset memory
\r
772 REG32(UMCTL_CFG_MCMD) = 0x89fee3f3;
\r
773 do value_temp = REG32(UMCTL_CFG_MCMD);
\r
774 while((value_temp&0x80000000) != 0x0);
\r
776 #if 1 //must be followed in board test
\r
777 //#(10*1000); //tINIT5+tINIT4, at least 11us
\r
778 for(i=0;i<11000;i++);
\r
781 //$display("%t,lpddr2 initialization: I/O calibration on CS0...",$time);
\r
782 //MR10: I/O calibration
\r
783 REG32(UMCTL_CFG_MCMD) = 0x891ff0a3;
\r
784 do value_temp = REG32(UMCTL_CFG_MCMD);
\r
785 while((value_temp&0x80000000) != 0x0);
\r
786 for(i=0;i<1000;i++);
\r
788 //$display("%t,lpddr2 initialization: I/O calibration on CS1...",$time);
\r
789 //MR10: I/O calibration
\r
790 REG32(UMCTL_CFG_MCMD) = 0x892ff0a3;
\r
791 do value_temp = REG32(UMCTL_CFG_MCMD);
\r
792 while((value_temp&0x80000000) != 0x0);
\r
793 for(i=0;i<1000;i++);
\r
795 //$display("%t,lpddr2 initialization: Device Feature 1...",$time);
\r
796 if(bl==DRAM_BL8 && DRAM_BURST_TYPE==DRAM_BT_SEQ) {
\r
797 //$display("%t,{%m}: Memory burst type sequential is not supported for mDDR and LPDDR2 with BL8",$time);
\r
801 //MR01: Device feature 1
\r
802 value_temp = 0x80f00013;
\r
803 value_temp |= (bl == DRAM_BL4 ? 0x2:
\r
804 bl == DRAM_BL8 ? 0x3:
\r
805 bl == DRAM_BL16 ? 0x4: 0x3)<<12;
\r
806 value_temp |= DRAM_BURST_TYPE<<15;
\r
807 value_temp |= DRAM_BURST_WRAP<<16;
\r
808 value_temp |= 4<<17; //nWR=6 for Auto precharge
\r
809 REG32(UMCTL_CFG_MCMD) = value_temp;
\r
810 do value_temp = REG32(UMCTL_CFG_MCMD);
\r
811 while((value_temp&0x80000000) != 0x0);
\r
813 //$display("%t,lpddr2 initialization: Device Feature 2...",$time);
\r
814 //MR02: Device feature 2
\r
815 REG32(UMCTL_CFG_MCMD) = 0x80f04023;
\r
816 do value_temp = REG32(UMCTL_CFG_MCMD);
\r
817 while((value_temp&0x80000000) != 0x0);
\r
819 //$display("%t,lpddr2 initialization: set I/O DS...",$time);
\r
820 //MR03: I/O config-1. DS: 48 ohm typical (default)
\r
821 //value_temp = 0x80f02030;
\r
822 value_temp = 0x80f00033;
\r
823 //value_temp |= (0x1<<12); //34ohm
\r
824 value_temp |= (0x2<<12); //40ohm
\r
825 //value_temp |= (0x3<<12); //48ohm
\r
826 //value_temp |= (0x4<<12); //60ohm
\r
827 //value_temp |= (0x6<<12); //80
\r
828 REG32(UMCTL_CFG_MCMD) = value_temp;
\r
829 do value_temp = REG32(UMCTL_CFG_MCMD);
\r
830 while((value_temp&0x80000000) != 0x0);
\r
832 //$display("%t,lpddr2 initialization: refresh...",$time);
\r
834 REG32(UMCTL_CFG_MCMD) = 0x80f00002;
\r
835 do value_temp = REG32(UMCTL_CFG_MCMD);
\r
836 while((value_temp&0x80000000) != 0x0);
\r
840 void EMC_DFI_Set(DRAM_INFO_T_PTR dram_info)
\r
842 volatile uint32 temp = 0;
\r
844 if((dram_info->mode_info->mem_type&DRAM_LPDDR2) == DRAM_LPDDR2)
\r
846 REG32(UMCTL_CFG_DFITPHYWRLAT) = dram_info->mode_info->wl;
\r
847 REG32(UMCTL_CFG_DFITRDDATAEN) = dram_info->mode_info->rl-1;
\r
851 REG32(UMCTL_CFG_DFITPHYWRLAT) = (dram_info->mode_info->wl>=1)? (dram_info->mode_info->wl-1):0; //WL-1, see PUBL P143
\r
852 REG32(UMCTL_CFG_DFITRDDATAEN) = (dram_info->mode_info->rl>=2)? (dram_info->mode_info->rl-2):0; //RL-2, see PUBL P143
\r
856 REG32(UMCTL_CFG_DFITPHYRDLAT) = 0xf; //fixed value,see PUBL P143
\r
857 REG32(UMCTL_CFG_DFISTCFG0) = 0x7;
\r
858 REG32(UMCTL_CFG_DFISTCFG1) = 0x3;
\r
859 REG32(UMCTL_CFG_DFISTCFG2) = 0x3;
\r
860 REG32(UMCTL_CFG_DFILPCFG0) = 0x00078101;
\r
863 do temp = REG32(UMCTL_CFG_DFISTSTAT0);
\r
864 while((temp&0x1) == 0);
\r
869 void EMC_PHY_Timing_Set(CLK_TYPE_E emc_clk,DRAM_INFO_T_PTR dram_info)
\r
872 uint32 emc_clk_d = 0;
\r
874 mem_t = (1000000000/emc_clk);
\r
875 emc_clk_d = emc_clk/1000000;
\r
877 //PTR0, to set tDLLSRST, tDLLLOCK, tITMSRST
\r
879 //DLL Soft Reset Time: Number of controller clock cycles that the DLL soft reset pin
\r
880 //must remain asserted when the soft reset is triggered through the PHY Initialization
\r
881 //Register (PIR). This must correspond to a value that is equal to or more than 50ns
\r
882 //or 8 controller clock cycles, whichever is bigger
\r
883 uint32 tDLLSRST = 50; //ns
\r
884 uint32 tDLLSRST_T = ((tDLLSRST*emc_clk_d/1000 < 8)? 8:(tDLLSRST*emc_clk_d/1000));
\r
886 //DLL Lock Time: Number of clock cycles for the DLL to stabilize and lock, i.e. number
\r
887 //of clock cycles from when the DLL reset pin is de-asserted to when the DLL has
\r
888 //locked and is ready for use. Refer to the PHY databook for the DLL lock time.
\r
889 //Default value corresponds to 5.12us at 533MHz.
\r
890 uint32 tDLLLOCK = 5120;//ns
\r
891 //uint32 tDLLLOCK_T = tDLLLOCK*emc_clk_d/1000;
\r
892 uint32 tDLLLOCK_T = ((tDLLLOCK * 26)/ 1000) + 1;//dll lock clk use APB clk(now is 26M)
894 //ITM Soft Reset Time: Number of controller clock cycles that the ITM soft reset pin
\r
895 //must remain asserted when the soft reset is applied to the ITMs. This must
\r
896 //correspond to a value that is equal to or more than 8 controller clock cycles. Default
\r
897 //value corresponds to 8 controller clock cycles
\r
898 uint32 tITMSRST = 8;//CLK
\r
899 REG32(PUBL_CFG_PTR0) = (tITMSRST<<18)|(tDLLLOCK_T<<6)|tDLLSRST_T;
\r
902 //PTR1, to set tINT0, tINT1
\r
905 uint32 tINT0_T = 0;
\r
907 uint32 tINT1_T = 0;
\r
909 tINT0 = 200*1000; //ns, CKE high time to first command,lpddr2
\r
910 tINT0_T = tINT0*emc_clk_d/1000;
\r
912 tINT1 = 100; //ns, CKE low time with power and clock stable
\r
913 tINT0_T = tINT0*emc_clk_d/1000;
\r
915 REG32(PUBL_CFG_PTR1 ) = tINT1_T<<19 | tINT0_T;
\r
919 //PTR2, to set tINT2,tINT3
\r
922 uint32 tINT2_T = 0;
\r
924 uint32 tINT3_T = 0;
\r
926 tINT2 = 11*1000; //ns, time for reset command to end of auto initialization
\r
927 tINT2_T = tINT2*emc_clk_d/1000;
\r
930 tINT3 = 1000; //ns, time for ZQ initialization command to first command
\r
931 tINT3_T = tINT3*emc_clk_d/1000;
\r
933 REG32(PUBL_CFG_PTR2 ) = tINT3_T<<17 | tINT2_T;
\r
936 //DTPR0, to set tMRD,tRTP,tWTR,tRP,tRCD,tRAS,tRRD,tRC,tCCD,
\r
937 //only used in PUBL DCU unite,I suppose
\r
938 if(dram_info->mode_info->mem_type==DRAM_LPDDR1)
\r
940 REG32(PUBL_CFG_DTPR0) = 0x3088444a;
\r
944 REG32(PUBL_CFG_DTPR0) = 0x36916a6d;
\r
948 //DTPR1, to set tRFC,
\r
949 //only used in PUBL DCU unite,I suppose
\r
950 if(dram_info->mode_info->mem_type==DRAM_LPDDR1)
\r
952 REG32(PUBL_CFG_DTPR1) &= ~0xff0003;
\r
953 REG32(PUBL_CFG_DTPR1) |= 0x200001;
\r
957 REG32(PUBL_CFG_DTPR1) = 0x193400a0;
\r
960 //DTPR2, to set tXS,tXP,tCKE,tDLLK
\r
961 //only used in PUBL DCU unite,I suppose
\r
962 //don't need to set,use the default value
\r
966 void EMC_PHY_Mode_Set(DRAM_INFO_T_PTR dram_info)
\r
968 volatile uint32 temp = 0;
\r
969 DRAM_TYPE_E mem_type = dram_info->mode_info->mem_type;
\r
970 DRAM_BL_E bl = dram_info->mode_info->bl;
\r
971 uint32 cs_num = dram_info->mode_info->cs_num;
\r
974 if(mem_type == DRAM_LPDDR1)
\r
976 //when lpddr1,zq power down, override,0xc: 48ohm typical,refer to P155 of multiPHY databook
\r
977 REG32(PUBL_CFG_ZQ0CR0) = (1<<31)|(1<<28)|(LPDDR1_MEM_DS<<5)|(LPDDR1_MEM_DS);
\r
981 REG32(PUBL_CFG_ZQ0CR1) &= ~0xff; //diable On-die termination impedance calibration
\r
982 REG32(PUBL_CFG_ZQ0CR1) |= PUBL_DS;
\r
985 temp = REG32(PUBL_CFG_PGCR);
\r
987 temp |= ((mem_type==DRAM_LPDDR1)? 1:0);
\r
988 temp |= (1<<1); //dqs gating mode, 0:active windows mode 1:passive windows mode
\r
989 temp |= (cs_num ==2)? (0x3<<18):(0x1<<18);
\r
990 REG32(PUBL_CFG_PGCR) = temp;
\r
993 if(B0_SDLL_PHS_DLY != SDLL_PHS_DLY_DEF)
\r
995 set_reg_fld(PUBL_CFG_DX0DLLCR,14,4,B0_SDLL_PHS_DLY);
\r
997 if(B1_SDLL_PHS_DLY != SDLL_PHS_DLY_DEF)
\r
999 set_reg_fld(PUBL_CFG_DX1DLLCR,14,4,B1_SDLL_PHS_DLY);
\r
1001 if(B2_SDLL_PHS_DLY != SDLL_PHS_DLY_DEF)
\r
1003 set_reg_fld(PUBL_CFG_DX2DLLCR,14,4,B2_SDLL_PHS_DLY);
\r
1005 if(B3_SDLL_PHS_DLY != SDLL_PHS_DLY_DEF)
\r
1007 set_reg_fld(PUBL_CFG_DX3DLLCR,14,4,B3_SDLL_PHS_DLY);
\r
1011 if(B0_DQS_STEP_DLY != DQS_STEP_DLY_DEF)
\r
1013 set_reg_fld(PUBL_CFG_DX0DQSTR,20,3,B0_DQS_STEP_DLY);
\r
1014 set_reg_fld(PUBL_CFG_DX0DQSTR,23,3,B0_DQS_STEP_DLY);
\r
1016 if(B1_DQS_STEP_DLY != DQS_STEP_DLY_DEF)
\r
1018 set_reg_fld(PUBL_CFG_DX1DQSTR,20,3,B1_DQS_STEP_DLY);
\r
1019 set_reg_fld(PUBL_CFG_DX1DQSTR,23,3,B1_DQS_STEP_DLY);
\r
1021 if(B2_DQS_STEP_DLY != DQS_STEP_DLY_DEF)
\r
1023 set_reg_fld(PUBL_CFG_DX2DQSTR,20,3,B2_DQS_STEP_DLY);
\r
1024 set_reg_fld(PUBL_CFG_DX2DQSTR,23,3,B2_DQS_STEP_DLY);
\r
1026 if(B3_DQS_STEP_DLY != DQS_STEP_DLY_DEF)
\r
1028 set_reg_fld(PUBL_CFG_DX3DQSTR,20,3,B3_DQS_STEP_DLY);
\r
1029 set_reg_fld(PUBL_CFG_DX3DQSTR,23,3,B3_DQS_STEP_DLY);
\r
1033 //???don't need to set
\r
1036 //???don't need to set
\r
1039 if(mem_type==DRAM_LPDDR1)
\r
1041 REG32(PUBL_CFG_ACIOCR) |= 1; //aciom
\r
1045 REG32(PUBL_CFG_ACIOCR) &= ~1; //aciom
\r
1048 //DXCCR, DATX8 common configuration register,to set data io,qds pin mode and pullup/pulldown resister
\r
1049 REG32(PUBL_CFG_DXCCR) &= ~((1<<14)|(0xff<<4)|(1<<1));
\r
1050 REG32(PUBL_CFG_DXCCR) = ((mem_type==DRAM_LPDDR1 ? 0x1:0x0)<<1) | //iom,0:SSTL mode 1:CMOS mode
\r
1051 ( DQS_PDU_RES<<4) | //dqs resistor,0:open 1:688ohm 2:611ohm 3:550ohm 4:500ohm 5:458ohm 6:393ohm 7:344ohm
\r
1052 ((8|DQS_PDU_RES)<<8) | //dqs# resistor,same as dqs resistor
\r
1053 ((mem_type==DRAM_LPDDR1) ? 1:0<<14); //dqs# reset,see PUBL page61 for detials
\r
1056 temp = REG32(PUBL_CFG_DSGCR);
\r
1057 temp &= ~0xfff; // only applicable for LPDDR
\r
1059 if(mem_type==DRAM_LPDDR1)
\r
1061 temp |= (0xB|(1<<8)|(1<<5));
\r
1065 temp |= (0xB|(2<<8)|(2<<5));
\r
1067 REG32(PUBL_CFG_DSGCR) = temp;
\r
1071 uint32 ddr_mode = 0;
\r
1072 uint32 ddr_8bank = 0;
\r
1073 uint32 ddr_type = 0;
\r
1074 DRAM_TYPE_E mem_type = dram_info->mode_info->mem_type;
\r
1076 if(mem_type==DRAM_LPDDR1)
\r
1080 else if(mem_type&DRAM_LPDDR2 == DRAM_LPDDR2)
\r
1089 ddr_8bank = (dram_info->mode_info->bank_num==8)?1:0;
\r
1090 ddr_type = (mem_type ==DRAM_LPDDR2_S4)? 0:1;
\r
1092 REG32(PUBL_CFG_DCR) &= ~0x3ff;
\r
1093 REG32(PUBL_CFG_DCR) |= (ddr_mode|(ddr_8bank<<1)|(ddr_type<<8));
\r
1096 //DXnGCR,DATX8 General Configuration Register
\r
1097 REG32(PUBL_CFG_DX0GCR) &= ~(0x3<<9);//disable DQ/DQS Dynamic RTT Control
\r
1098 REG32(PUBL_CFG_DX1GCR) &= ~(0x3<<9);//disable DQ/DQS Dynamic RTT Control
\r
1099 REG32(PUBL_CFG_DX2GCR) &= ~(0x3<<9);//disable DQ/DQS Dynamic RTT Control
\r
1100 REG32(PUBL_CFG_DX3GCR) &= ~(0x3<<9);//disable DQ/DQS Dynamic RTT Control
\r
1102 REG32(PUBL_CFG_ODTCR) &= ~0xff00ff;//disable ODT both for read and write
\r
1104 if(mem_type!=DRAM_LPDDR1)
\r
1108 wait_pclk(10); //temp1
\r
1109 REG32(PUBL_CFG_PIR) = 0x9;
\r
1111 wait_pclk(10); //temp1
\r
1112 //wait trigger zqcl done
\r
1113 do temp = REG32(PUBL_CFG_PGSR);
\r
1114 while((temp&0x1) == 0);
\r
1117 //Controller DRAM Initialization
\r
1119 wait_pclk(10); //temp1
\r
1120 REG32(PUBL_CFG_PIR) = 0x40001;
\r
1122 wait_pclk(10); //temp1
\r
1124 do {temp = REG32(PUBL_CFG_PGSR);}
\r
1125 while((temp&0x1) == 0);
\r
1130 void EMC_PHY_MDR_Set(CLK_TYPE_E emc_clk,DRAM_INFO_T_PTR dram_info)
\r
1132 #ifndef CONFIG_MEM_LPDDR1
\r
1135 uint32 emc_clk_d = 0;
\r
1137 emc_clk_d = emc_clk/1000000;
\r
1138 mem_t = (1000000000/emc_clk);
\r
1140 switch(dram_info->mode_info->mem_type)
\r
1145 //lpddr1 mode register
\r
1146 temp = REG32(PUBL_CFG_MR0);
\r
1148 temp |=( (0<<7) | //operation mode, 0:normal_mode 1:test_mode
\r
1149 (dram_info->mode_info->rl<<4) | //cas latency
\r
1150 (0<<3) | //burst type,0:sequential 1:interleaved
\r
1151 (dram_info->mode_info->bl+1));
\r
1152 REG32(PUBL_CFG_MR0) = temp;
\r
1155 //lpddr1 extended mode register
\r
1156 REG32(PUBL_CFG_MR2) = 0;
\r
1159 case DRAM_LPDDR2_S2:
\r
1160 case DRAM_LPDDR2_S4:
\r
1163 //lpddr2 don't use
\r
1164 REG32(PUBL_CFG_MR0) = 0;
\r
1167 //lpddr2 mode register 1
\r
1168 temp = REG32(PUBL_CFG_MR1);
\r
1170 temp |= ((0x4<<5)| //write recovery,1:3 2:4 3:5 4:6 5:7 6:8,???fixed?????have some problem i think
\r
1171 (0x0<<4)| //wrap control, 0:wrap 1:no_wrap
\r
1172 (0x0<<3)| //burst type, 0:sequential 1:interleaved
\r
1173 dram_info->mode_info->bl+1);
\r
1174 REG32(PUBL_CFG_MR1) = temp;
\r
1176 //lpddr2 mode register 2
\r
1177 if(dram_info->mode_info->rl==3 &&dram_info->mode_info->wl==1)
\r
1179 REG32(PUBL_CFG_MR2) = 1;
\r
1181 else if(dram_info->mode_info->rl==4 &&dram_info->mode_info->wl==2)
\r
1183 REG32(PUBL_CFG_MR2) = 2;
\r
1185 else if(dram_info->mode_info->rl==5 &&dram_info->mode_info->wl==2)
\r
1187 REG32(PUBL_CFG_MR2) = 3;
\r
1189 else if(dram_info->mode_info->rl==6 &&dram_info->mode_info->wl==3)
\r
1191 REG32(PUBL_CFG_MR2) = 4;
\r
1193 else if(dram_info->mode_info->rl==7 &&dram_info->mode_info->wl==4)
\r
1195 REG32(PUBL_CFG_MR2) = 5;
\r
1197 else if(dram_info->mode_info->rl==8 &&dram_info->mode_info->wl==4)
\r
1199 REG32(PUBL_CFG_MR2) = 6;
\r
1203 REG32(PUBL_CFG_MR2) = 4;
\r
1207 //lpddr2 mode register 3
\r
1208 REG32(PUBL_CFG_MR3) = 2;// 1=34.3-ohm, 2=40-ohm, 3=48-ohm, 4=60-ohm, 6=80-ohm, 7=120-ohm
\r
1214 //ddr3 mode register 0
\r
1219 bl = (dram_info->mode_info->bl == DRAM_BL4)?2:0;
\r
1220 cl = (dram_info->mode_info->rl <5)?1:(dram_info->mode_info->rl-4);
\r
1221 switch(dram_info->time_info->tWR*emc_clk_d/1000)
\r
1223 case 5: wr=1;break;
\r
1224 case 6: wr=2;break;
\r
1225 case 7: wr=3;break;
\r
1226 case 8: wr=4;break;
\r
1227 case 10: wr=5;break;
\r
1228 case 12: wr=6;break;
\r
1232 REG32(PUBL_CFG_MR0) = bl |
\r
1233 (0<<3) | // Burst Type: 0:sequentia 1:interleaved
\r
1236 (1<<12); // Power-Down Control, 0 = Slow exit (DLL off),1 = Fast exit (DLL on)
\r
1240 //ddr3 mode register 1
\r
1241 REG32(PUBL_CFG_MR1) = 0x81; //bit0:DLL Enable/Disable bit7:Write Leveling Enable
\r
1244 //ddr3 mode register 2
\r
1245 REG32(PUBL_CFG_MR2) = 0x4; //bit6:Auto Self-Refresh 1:eanble 0:disable
\r
1248 //ddr3 mode register 3
\r
1249 REG32(PUBL_CFG_MR3) = 0x0; //bit0~1:Multi-Purpose Register (MPR) Location
\r
1250 //bit2: Multi-Purpose Register Enable
\r
1258 BOOLEAN EMC_PHY_Training()
\r
1262 //while((PHY_CURRENT_STATE&PHY_STATE_INIT_DONE) !=PHY_STATE_INIT_DONE);
\r
1263 //while((PHY_CURRENT_STATE&PHY_STATE_DLL_LOCK_DONE)!=PHY_STATE_DLL_LOCK_DONE);
\r
1264 //for(i = 0; i < 1000; i++);
\r
1266 //set umctl do memory init, phy wouldn't do
\r
1267 //REG32(PUBL_CFG_PIR) |= (PHY_ACT_INIT|PHY_ACT_CTLDINIT);
\r
1268 //while((PHY_CURRENT_STATE&PHY_STATE_INIT_DONE) !=PHY_STATE_INIT_DONE);
\r
1269 //for(i = 0; i < 1000; i++);
\r
1273 wait_pclk(10);//temp1
\r
1274 REG32(PUBL_CFG_PIR) |= (PHY_ACT_INIT|PHY_ACT_DQSTRN);
\r
1275 wait_pclk(10);//temp1
\r
1278 //wait PHY dqs training finished
\r
1279 while((PHY_CURRENT_STATE&PHY_STATE_INIT_DONE) !=PHY_STATE_INIT_DONE);
\r
1280 while((PHY_CURRENT_STATE&PHY_STATE_DTDONE) !=PHY_STATE_DTDONE);
\r
1281 wait_pclk(3);//temp1
\r
1283 if((PHY_CURRENT_STATE&PHY_STATE_DTERR)||
\r
1284 (PHY_CURRENT_STATE&PHY_STATE_DTIERR))
\r
1296 void __emc_low_power_set()
\r
1299 //disable emc hardware low power enable
\r
1300 i = REG32(0x20900308);
\r
1302 REG32(0x20900308) = i;
\r
1303 REG32(UMCTL_CFG_SCFG) = 0x00000421;
\r
1306 void EMC_Common_Reg_Set(CLK_TYPE_E emc_clk,EMC_CHN_INFO_T_PTR emc_chn_info,DRAM_INFO_T_PTR dram_info)
\r
1308 EMC_CTL_Mode_Set(dram_info);
\r
1309 EMC_CTL_CHN_Set(emc_chn_info);
\r
1311 EMC_MEM_Mode_set(dram_info);
\r
1312 EMC_MEM_Timing_Set(emc_clk,dram_info);
\r
1314 EMC_DFI_Set(dram_info);
\r
1316 EMC_PHY_Mode_Set(dram_info);
\r
1317 EMC_PHY_Timing_Set(emc_clk,dram_info);
\r
1318 EMC_PHY_MDR_Set(emc_clk,dram_info);
\r
1321 void __clr_ddr_phy_ret_flg()
\r
1323 REG32(GR_DDR_PHY_RETENTION_SET) = 0x2;
\r
1326 uint32 __reorder_mem_info(uint32 source_data)
\r
1329 uint32 reg_info = 0;
\r
1331 temp = source_data&0xff;
\r
1332 //reorder mdr info which get from lpddr2 by mrr cmd
\r
1333 // bit7(d2) bit6(d1) bit5(d0) bit4(d3) bit3(d5) bit2(d4) bit1(d6) bit0(d7)
\r
1334 reg_info = ((temp&BIT_2)<<5)+((temp&BIT_1)<<5)+((temp&BIT_0)<<5)+((temp&BIT_3)<<1)+((temp&BIT_5)>>2)+((temp&BIT_4)>>2)+((temp&BIT_6)>>5)+((temp&BIT_7)>>7);
\r
1339 DRAM_DENSITY_E __cal_mem_dsy(uint32 dsy_val)
\r
1343 case 0: return DRAM_64MBIT;
\r
1344 case 1: return DRAM_128MBIT;
\r
1345 case 2: return DRAM_256MBIT;
\r
1346 case 3: return DRAM_512MBIT;
\r
1347 case 4: return DRAM_1GBIT;
\r
1348 case 5: return DRAM_2GBIT;
\r
1349 case 6: return DRAM_4GBIT;
\r
1350 case 7: return DRAM_8GBIT;
\r
1351 case 8: return DRAM_16GBIT;
\r
1352 default: DRAM_4GBIT;
\r
1356 customer_timing_t* __get_customer_set(LPDDR2_MANUFACTURE_ID_E lpddr2_id)
\r
1359 for(i = 0; i<sizeof(CUSTOMER_TIMING_INFO)/sizeof(customer_timing_t); i++)
\r
1361 if( CUSTOMER_TIMING_INFO[i].cust_lpddr2_id == lpddr2_id)
\r
1363 return &CUSTOMER_TIMING_INFO[i];
\r
1366 return &CUSTOMER_TIMING_INFO[0];
\r
1368 BOOLEAN __detect_mem_info(DRAM_INFO_T_PTR dram_info)
\r
1370 uint32 cs0_mdr_info = 0;
\r
1371 uint32 cs1_mdr_info = 0;
\r
1372 LPDDR2_MANUFACTURE_ID_E lpddr2_id = LPDDR2_HYNIX;
\r
1373 customer_timing_t* customer_set;
\r
1374 if(__is_bond_lpddr2())
\r
1376 //read lpddr2 mdr8 to get io_width,density and type
\r
1377 EMC_CTL_MDR_Issue(dram_info,SECOND_CS, CMD_MRR, 8);
\r
1378 cs1_mdr_info = __reorder_mem_info(REG32(UMCTL_REG_MRRSTAT0));
\r
1380 EMC_CTL_MDR_Issue(dram_info,FIRST_CS, CMD_MRR, 8);
\r
1381 cs0_mdr_info = __reorder_mem_info(REG32(UMCTL_REG_MRRSTAT0));
\r
1383 if(cs1_mdr_info != 0)
\r
1385 dram_info->mode_info->cs_num = TWO_CS;
\r
1387 dram_info->mode_info->cs1_cap = __cal_mem_dsy((cs1_mdr_info&0x3c)>>2);
\r
1391 dram_info->mode_info->cs_num = ONE_CS;
\r
1393 dram_info->mode_info->cs1_cap = DRAM_0BIT;
\r
1395 dram_info->mode_info->cs0_cap = __cal_mem_dsy((cs0_mdr_info&0x3c)>>2);
\r
1397 //cal memory data io width
\r
1398 if((cs0_mdr_info&0xc0) == 0)
\r
1400 dram_info->mode_info->io_width = IO_WIDTH_32;
\r
1402 else if((cs0_mdr_info&0xc0) == 0x40)
\r
1404 dram_info->mode_info->io_width = IO_WIDTH_16;
\r
1406 else if((cs0_mdr_info&0xc0) == 0x80)
\r
1408 dram_info->mode_info->io_width = IO_WIDTH_8;
\r
1412 dram_info->mode_info->io_width = IO_WIDTH_32;
\r
1415 //cal memmory type
\r
1416 if((cs0_mdr_info&0x3) == 0)
\r
1418 dram_info->mode_info->mem_type == DRAM_LPDDR2_S4;
\r
1420 else if((cs0_mdr_info&0x3) == 1)
\r
1422 dram_info->mode_info->mem_type == DRAM_LPDDR2_S2;
\r
1426 dram_info->mode_info->mem_type == DRAM_LPDDR2_S4;
\r
1429 //read lpddr2 mdr5 to get manufaturer id
1430 EMC_CTL_MDR_Issue(dram_info,FIRST_CS, CMD_MRR, 5);
\r
1431 lpddr2_id = __reorder_mem_info(REG32(UMCTL_REG_MRRSTAT0));
\r
1432 customer_set = __get_customer_set(lpddr2_id);
\r
1433 PUBL_DS = customer_set->cust_publ_ds;
\r
1434 LPDDR2_MEM_DS = customer_set->cust_lpddr2_mem_ds;
\r
1435 B0_SDLL_PHS_DLY = customer_set->cust_b0_sdll_phs;
\r
1436 B1_SDLL_PHS_DLY = customer_set->cust_b1_sdll_phs;
\r
1437 B2_SDLL_PHS_DLY = customer_set->cust_b2_sdll_phs;
\r
1438 B3_SDLL_PHS_DLY = customer_set->cust_b3_sdll_phs;
\r
1439 B0_DQS_STEP_DLY = customer_set->cust_b0_dqs_step;
\r
1440 B1_DQS_STEP_DLY = customer_set->cust_b1_dqs_step;
\r
1441 B2_DQS_STEP_DLY = customer_set->cust_b2_dqs_step;
\r
1442 B3_DQS_STEP_DLY = customer_set->cust_b3_dqs_step;
\r
1446 else//note!!! don't support lpddr1 type detection now
\r
1454 BOOLEAN EMC_Init(CLK_TYPE_E emc_clk,EMC_CHN_INFO_T_PTR emc_chn_info,DRAM_INFO_T_PTR dram_info)
\r
1456 __clr_ddr_phy_ret_flg();
\r
1458 EMC_CTL_State_Move(CTL_STATE_INIT_MEM);
\r
1460 EMC_Common_Reg_Set(emc_clk, emc_chn_info, dram_info);
\r
1462 EMC_MEM_Power_Up();
\r
1464 EMC_MEM_Init(dram_info);
\r
1466 if((dram_info->mode_info->mem_type&DRAM_LPDDR2) == DRAM_LPDDR2)
\r
1468 __detect_mem_info(dram_info);
\r
1470 EMC_Common_Reg_Set(emc_clk, emc_chn_info, dram_info);
\r
1472 EMC_MEM_Init(dram_info);
1475 EMC_CTL_State_Move(CTL_STATE_CONFIG);
\r
1477 if((dram_info->mode_info->mem_type&DRAM_LPDDR2) == DRAM_LPDDR2)
\r
1479 if(!EMC_PHY_Training())
\r
1484 __emc_low_power_set();
\r
1486 EMC_CTL_State_Move(CTL_STATE_ACCESS);
\r
1489 /**---------------------------------------------------------------------------*
\r
1490 ** Static Function Prototypes *
\r
1491 **---------------------------------------------------------------------------*/
\r
1493 PUBLIC void DMC_Dev_Init(CLK_TYPE_E emc_clk)
\r
1495 DRAM_INFO_T_PTR dram_info;
\r
1496 char* dram_chip_name = NULL;
\r
1499 /* set EMC port remapping to protect unsupported area */
\r
1500 #ifdef CONFIG_RAM768M
\r
1501 REG32(0x20900310) = 0xaaaaaa98;
\r
1502 REG32(0x20900314) = 0xaaaaaa98;
\r
1503 REG32(0x20900318) = 0xaaaaaa98;
\r
1504 REG32(0x2090031c) = 0xaaa8aaaa;
\r
1505 REG32(0x20900320) = 0xaaa8aaaa;
\r
1506 REG32(0x20900324) = 0xaaaaaa98;
\r
1507 REG32(0x20900328) = 0xaaaaaa98;
\r
1508 REG32(0x2090032c) = 0xaaaaaa98;
\r
1510 REG32(0x20900310) = 0x99999998;
\r
1511 REG32(0x20900314) = 0x99999998;
\r
1512 REG32(0x20900318) = 0x99999998;
\r
1513 REG32(0x2090031c) = 0x99989999;
\r
1514 REG32(0x20900320) = 0x99989999;
\r
1515 REG32(0x20900324) = 0x99999998;
\r
1516 REG32(0x20900328) = 0x99999998;
\r
1517 REG32(0x2090032c) = 0x99999998;
\r
1520 REG32(0x2090030c) = 0xfff;
\r
1522 if(__is_bond_lpddr2())
\r
1524 dram_chip_name ="NORMAL_LPDDR2_1CS_4G_32BIT";
\r
1525 emc_clk = CLK_400MHZ;
\r
1529 #ifdef CONFIG_MEM_LPDDR1_2CS_4GBIT
\r
1530 dram_chip_name ="NORMAL_LPDDR1_2CS_4G_32BIT";
\r
1532 dram_chip_name ="NORMAL_LPDDR1_1CS_2G_32BIT";
\r
1535 emc_clk = CLK_200MHZ;
\r
1538 dram_info = get_dram_info(dram_chip_name);
\r
1540 if(dram_info->mode_info->mem_type == DRAM_LPDDR1)
\r
1542 //disable EMC module
\r
1543 REG32(AHB_CTL0) &= ~BIT_28;
\r
1545 //set SDLL bias trim accuraty
\r
1546 REG32(PUBL_CFG_DLLGCR) |= BIT_23;
\r
1549 REG32(PUBL_CFG_ACDLLCR) |= BIT_31;
\r
1550 REG32(PUBL_CFG_DX0DLLCR) |= BIT_31;
\r
1551 REG32(PUBL_CFG_DX1DLLCR) |= BIT_31;
\r
1552 REG32(PUBL_CFG_DX2DLLCR) |= BIT_31;
\r
1553 REG32(PUBL_CFG_DX3DLLCR) |= BIT_31;
\r
1556 set_emc_clk(emc_clk);
\r
1558 if(dram_info->mode_info->mem_type == DRAM_LPDDR1)
\r
1560 //disable EMC module
\r
1561 REG32(AHB_CTL0) |= BIT_28;
\r
1564 EMC_Init(emc_clk, EMC_CHN_INFO_ARRAY,dram_info);
\r
1566 #ifdef __cplusplus
\r