tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8810 / sdram_sc7710g2.c
1 /******************************************************************************\r
2  ** File Name:        sdram_sc7710g2.c\r
3  ** Author:           henry.he\r
4  ** DATE:             11/03/2013\r
5  ** Copyright:        2013 Spreatrum, Incoporated. All Rights Reserved.\r
6  ** Description:\r
7  ******************************************************************************/\r
8 /******************************************************************************\r
9  **                   Edit    History\r
10  **-------------------------------------------------------------------------\r
11  ** DATE          NAME            DESCRIPTION\r
12  ** 11/03/2013                    Create.\r
13  ******************************************************************************/\r
14 #include <common.h>\r
15 #include <asm/arch/sci_types.h>\r
16 #include <asm/arch/arm_reg.h>\r
17 #include <asm/arch/sc_reg.h>\r
18 #include <asm/arch/sdram_sc7710g2.h>\r
19 #include <asm/arch/emc_config.h>\r
20 #include "asm/arch/chip_plf_export.h"\r
21 #include <asm/arch/adi_hal_internal.h>\r
22 #include <asm/arch/mfp.h>\r
23 \r
24 \r
25 #ifdef   __cplusplus\r
26 extern   "C"\r
27 {\r
28 #endif\r
29 \r
30 /*----------------------------------------------------------------------------*\r
31 **                          Sub Function                                      *\r
32 **----------------------------------------------------------------------------*/\r
33 \r
34 \r
35 \r
36 uint32 DRAM_CAP;\r
37 //uint32  SDRAM_BASE    =       0x00000000;//(128*1024*1024/2)//0x30000000\r
38 \r
39 #define MEM_REF_DATA0       0x12345678\r
40 #define SDRAM_BASE_ADDR     0x00000000UL\r
41 \r
42 #define DMC_SOFT_RST BIT_11\r
43 \r
44 LOCAL BOOLEAN s_emc_dll_open = FALSE;\r
45 LOCAL EMC_PARAM_T s_emc_config = {0};\r
46 \r
47 LOCAL void DMC_Init(void);\r
48 \r
49 /**---------------------------------------------------------------------------*\r
50  **                     Static Function Prototypes                            *\r
51  **---------------------------------------------------------------------------*/\r
52 \r
53 LOCAL void delay(uint32 k)\r
54 {\r
55     volatile uint32 i, j;\r
56 \r
57     for (i=0; i<k; i++)\r
58     {\r
59 //        for (j=0; j<1000; j++);\r
60     }\r
61 \r
62 //    return k;\r
63 }\r
64 \r
65 LOCAL void EMC_AddrMode_Set(SDRAM_CFG_INFO_T_PTR mem_info)\r
66 {\r
67     uint32 reg_val = 0;\r
68 \r
69     reg_val = REG32(EXT_MEM_DCFG0);\r
70     reg_val &= ~((DATA_WIDTH_MASK<<8) | (COL_MODE_MASK<<4) | ROW_MODE_MASK);\r
71     reg_val |= (((mem_info->data_width & DATA_WIDTH_MASK)<< 8)\r
72                 | ((mem_info->col_mode & COL_MODE_MASK) << 4)\r
73                 | (mem_info->row_mode & ROW_MODE_MASK));\r
74 \r
75     REG32(EXT_MEM_DCFG0) = reg_val;\r
76 }\r
77 \r
78 \r
79 LOCAL void EMC_SoftReset(void)\r
80 {\r
81     REG32(AHB_SOFT_RST) |= DMC_SOFT_RST;\r
82     delay(10);\r
83     REG32(AHB_SOFT_RST) &= (~DMC_SOFT_RST);\r
84     delay(10);\r
85 }\r
86 \r
87 #ifndef SDRAM_AUTODETECT_SUPPORT\r
88 \r
89 PUBLIC uint32 SDRAM_GetCap(void)  // capability in bytes\r
90 {\r
91     uint32 SDRAM_Cap;\r
92 \r
93     SDRAM_CHIP_FEATURE_T_PTR mem_feature = SDRAM_GetFeature();\r
94 \r
95     SDRAM_Cap = mem_feature->cap;\r
96 \r
97     return SDRAM_Cap;\r
98 }\r
99 #endif\r
100 \r
101 PUBLIC EMC_PHY_L1_TIMING_T_PTR EMC_GetPHYL1_Timing(DMEM_TYPE_E mem_type, uint32 cas_latency)\r
102 {\r
103 #ifdef SDR_SDRAM_SUPPORT\r
104     if (SDR_SDRAM == mem_type)\r
105     {\r
106         if (CAS_LATENCY_2 == cas_latency)\r
107         {\r
108             return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHYL1_TIMING_SDRAM_LATENCY2]));\r
109         }\r
110         else\r
111         {\r
112             return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHYL1_TIMING_SDRAM_LATENCY3]));\r
113         }\r
114     }\r
115     else\r
116 #endif\r
117     {\r
118         if (CAS_LATENCY_2 == cas_latency)\r
119         {\r
120             return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHYL1_TIMING_DDRAM_LATENCY2]));\r
121         }\r
122         else\r
123         {\r
124             return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHYL1_TIMING_DDRAM_LATENCY3]));\r
125         }\r
126     }\r
127 }\r
128 \r
129 PUBLIC EMC_PHY_L2_TIMING_T_PTR EMC_GetPHYL2_Timing(void)\r
130 {\r
131     if (s_emc_dll_open)\r
132     {\r
133         return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHYL2_TIMING_DLL_ON]));\r
134     }\r
135     else\r
136     {\r
137         return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHYL2_TIMING_DLL_OFF]));\r
138     }\r
139 }\r
140 \r
141 \r
142 /*****************************************************************************/\r
143 //  Description:        EMC basic mode set function\r
144 //                              set the base mode like:\r
145 //                              EMC device endian\r
146 //                              EMC auto gate en for power saving\r
147 //                              EMC auto sleep en\r
148 //                              EMC cmd queue mode\r
149 //  Global resource dependence:  NONE\r
150 //  Related register: EMC_CFG0\r
151 //  Author:             Johnny.Wang\r
152 //  Note:                       The default cs map space is 4g, if dram capability is larger than 4g,\r
153 //                              emc_cs_map parameter must adjust.\r
154 /*****************************************************************************/\r
155 LOCAL void EMC_Base_Mode_Set(SDRAM_CFG_INFO_T_PTR mem_info)\r
156 {\r
157     uint32 i = 0;\r
158     EMC_CS_MAP_E cs_position;\r
159 \r
160     cs_position = mem_info->cs_position;\r
161 \r
162     i = REG32(EXT_MEM_CFG0);\r
163     i &= ~0x1fff;\r
164     i |=(EMC_DVC_ENDIAN_DEFAULT <<12)   |\r
165         (EMC_AUTO_GATE_EN               <<11)   |\r
166         (EMC_AUTO_SLEEP_EN              <<10)   |\r
167         (EMC_2DB_1CB                    <<6)    |\r
168         (EMC_CS_MODE_DEFAULT    <<3)    |\r
169         (cs_position   <<0)     ;\r
170 \r
171     REG32(EXT_MEM_CFG0) = i;\r
172 }\r
173 \r
174 /*****************************************************************************/\r
175 //  Description:        EMC each cs work mode set function\r
176 //                              set each cs work mode parameter like:\r
177 //                              memory write burst length\r
178 //                              memory read burst length\r
179 //                              memory write burst mode:wrap/increase\r
180 //                              memory read burst mode:wrap/increase\r
181 //                              AHB write busrt divided to single/busrt access\r
182 //                              AHB read busrt divided to single/busrt access\r
183 //  Global resource dependence:  memory burst length type\r
184 //  Related register: EMC_CFG0_CSx\r
185 //  Author:             Johnny.Wang\r
186 //  Note:                       There are two cs pin in sc8810 emc, we usuall use cs0 to control external memory\r
187 //\r
188 /*****************************************************************************/\r
189 PUBLIC void EMC_CSx_Burst_Set(EMC_CS_NUM_E emc_cs_num, SDRAM_CFG_INFO_T_PTR mem_info)\r
190 {\r
191     uint32 i = 0;\r
192     uint32 emc_cs_cfg = EXT_MEM_CFG0_CS0 + emc_cs_num*4;\r
193     uint32 burst_len = 0;\r
194 \r
195     if (DDR_SDRAM == mem_info ->sdram_type)\r
196     {\r
197         if (DATA_WIDTH_16 == mem_info ->data_width)\r
198         {\r
199             burst_len = mem_info->burst_length -1;\r
200         }\r
201         else\r
202         {\r
203             burst_len = mem_info->burst_length;\r
204         }\r
205     }\r
206 #ifdef SDR_SDRAM_SUPPORT\r
207     else if (SDR_SDRAM == mem_info ->sdram_type)\r
208     {\r
209         burst_len = 0;\r
210     }\r
211 #endif\r
212 \r
213     i = REG32(emc_cs_cfg);\r
214     i &= ~((0x7<<8)|(0x7<<4)|(1<<1)|1);\r
215     i |=((burst_len                     <<8) | //write burst length\r
216          (burst_len                     <<4) | //read burst length\r
217          (HBURST_TO_BURST       <<1) | //write hburst invert to mem burst\r
218          (HBURST_TO_BURST       <<0));  //rrite hburst invert to mem burst\r
219 \r
220     REG32(emc_cs_cfg) = i;\r
221 }\r
222 \r
223 /*****************************************************************************/\r
224 //  Description:        EMC AXI channel set function\r
225 //                              set each axi channel parameter like:\r
226 //                              axi channel en\r
227 //                              axi channel auto sleep en\r
228 //                              channel endian switch\r
229 //                              channel priority\r
230 //  Global resource dependence:  NONE\r
231 //  Related register: EMC_CFG0_ACHx\r
232 //                                EMC_CFG1_ACHx\r
233 //  Author:             Johnny.Wang\r
234 //  Note:                       There are two axi channel in sc8810 emc, one for A5,the other for GPU\r
235 //\r
236 /*****************************************************************************/\r
237 LOCAL void EMC_AXI_CHL_Set(EMC_CHL_NUM_E emc_axi_num,\r
238                                     EMC_CHL_PRI_E chl_wr_pri,\r
239                                     EMC_CHL_PRI_E chl_rd_pri\r
240                                     )\r
241 {\r
242     uint32 i = 0;\r
243     uint32 emc_axi_cfg0 = EXT_MEM_CFG0_CH0_BASE+ emc_axi_num*8;\r
244     uint32 emc_axi_cfg1 = EXT_MEM_CFG1_CH0_BASE+ emc_axi_num*8;\r
245 \r
246     i = REG32(emc_axi_cfg0);\r
247     i &= (~(ACH_RF_ENDIAN_SWT_CHX | ACH_CHL_PRI_WR_MASK));\r
248 \r
249 //    i |= ACH_RF_AUTO_SLEEP_EN_CHX | ACH_RF_CH_EN_CHX | (EMC_ENDIAN_SWITCH_NONE<<4);\r
250     i |= ACH_RF_CH_EN_CHX | (EMC_ENDIAN_SWITCH_NONE<<4);\r
251 \r
252     i |= (ACH_CHL_PRI_WR(chl_wr_pri));\r
253 \r
254     REG32(emc_axi_cfg0) = i;\r
255 \r
256     i = REG32(emc_axi_cfg1);\r
257     i &= (~(ACH_RF_SYNC_SEL_CHX | ACH_CHL_PRI_RD_MASK)); // async\r
258     i |= (EMC_CLK_ASYNC<<4); //emc clk async with axi clk\r
259     i |= (ACH_RF_BRESP_MODE_CH); //axi channel response mode  0:at once  1:delay several clk\r
260     i |= ACH_CHL_PRI_RD(chl_rd_pri);\r
261     \r
262     REG32(emc_axi_cfg1) = i;\r
263 }\r
264 \r
265 /*****************************************************************************/\r
266 //  Description:        EMC AHB channel set function\r
267 //  Global resource dependence:  NONE\r
268 //  Author:             Johnny.Wang\r
269 //  Note:                       There are 7 ahb channel in sc8810 emc, but no one is relate with ARM,\r
270 //                              so don't used temporarily\r
271 //\r
272 /*****************************************************************************/\r
273 LOCAL void EMC_AHB_CHL_Set(EMC_CHL_NUM_E emc_ahb_num,uint32 addr_offset, EMC_CHL_PRI_E chl_pri)\r
274 {\r
275     uint32 emc_ahb_cfg0 = EXT_MEM_CFG0_CH0_BASE + emc_ahb_num*8;\r
276     uint32 emc_ahb_cfg1 = EXT_MEM_CFG1_CH0_BASE + emc_ahb_num*8;\r
277 \r
278     REG32(emc_ahb_cfg1) &= (~HCH_CHL_PRI_MASK);\r
279 \r
280 //    REG32(emc_ahb_cfg0) |= (HCH_RF_AUTO_SLEEP_EN_CHX | HCH_CHL_PRI(chl_pri));\r
281     REG32(emc_ahb_cfg0) |= HCH_CHL_PRI(chl_pri);\r
282 \r
283     REG32(emc_ahb_cfg1) &= ~0x03ff0000; //clear bit16~25\r
284     REG32(emc_ahb_cfg1) |= (addr_offset & 0x03ff) << 16;\r
285 }\r
286 \r
287 /*****************************************************************************/\r
288 //  Description:        EMC Memroy all timing parameter set function\r
289 //                              set all timing parameter of EMC when operate external memory like:\r
290 //                              t_rtw,\r
291 //                              t_ras,\r
292 //                              t_xsr,\r
293 //                              t_rfc,\r
294 //                              t_wr,\r
295 //                              t_rcd,\r
296 //                              t_rp,\r
297 //                              t_rrd,\r
298 //                              t_mrd,\r
299 //                              t_wtr,\r
300 //                              t_ref,\r
301 //  Global resource dependence:  NONE\r
302 //  Author:             Johnny.Wang\r
303 //  Related register: EMC_DCFG1\r
304 //                                EMC_DCFG2\r
305 //  Note:                       None\r
306 //\r
307 /*****************************************************************************/\r
308 LOCAL void EMC_MEM_Timing_Set(uint32 emc_freq,\r
309                         SDRAM_CFG_INFO_T_PTR     mem_info,\r
310                         SDRAM_TIMING_PARA_T_PTR  mem_timing)\r
311 {\r
312 #if 1 // low code size\r
313     switch (emc_freq)\r
314     {\r
315         case EMC_CLK_26MHZ:\r
316             REG32(EXT_MEM_DCFG1) = 0x13311211;\r
317             REG32(EXT_MEM_DCFG2) = 0x02020322;\r
318             break;\r
319         case EMC_CLK_67MHZ:\r
320             REG32(EXT_MEM_DCFG1) = 0x13321211;\r
321             REG32(EXT_MEM_DCFG2) = 0x04050322;\r
322             break;\r
323         case EMC_CLK_133MHZ:\r
324             REG32(EXT_MEM_DCFG1) = 0x13341322;\r
325             REG32(EXT_MEM_DCFG2) = 0x080A0322;\r
326             break;\r
327         case EMC_CLK_200MHZ:\r
328             REG32(EXT_MEM_DCFG1) = 0x13352333;\r
329             REG32(EXT_MEM_DCFG2) = 0x0B0E0322;\r
330             break;\r
331         case EMC_CLK_266MHZ:\r
332             REG32(EXT_MEM_DCFG1) = 0x13383455;\r
333             REG32(EXT_MEM_DCFG2) = 0x10140322;\r
334             break;\r
335         case EMC_CLK_333MHZ:\r
336             REG32(EXT_MEM_DCFG1) = 0x13393455;\r
337             REG32(EXT_MEM_DCFG2) = 0x13180322;\r
338             break;\r
339         case EMC_CLK_370MHZ:\r
340         case EMC_CLK_400MHZ:\r
341         default:\r
342             REG32(EXT_MEM_DCFG1) = 0x133A3566;\r
343             REG32(EXT_MEM_DCFG2) = 0x161C0322;\r
344             break;\r
345     }\r
346 #else\r
347     uint32 cycle_ns = (uint32)(2000000000/emc_freq);//2000/(clk); //device clock is half of emc clock.\r
348     uint32 cycle_t_ref = 1000000/EMC_T_REF_CLK;\r
349 \r
350 //    uint32 row_mode    = mem_info->row_mode + ROW_LINE_MIN;\r
351     uint32 t_rtr  = 1;\r
352     uint32 t_wtr    = mem_timing->wtr_min+1;\r
353     uint32 t_rtw    = mem_info->cas_latency;\r
354     uint32 t_ras;\r
355     uint32 t_rrd;\r
356 \r
357     uint32 t_wr;\r
358     uint32 t_rcd;\r
359     uint32 t_rp;\r
360     uint32 t_rfc;\r
361     uint32 t_xsr;\r
362     uint32 tREFI = mem_timing->trefi_max;\r
363     uint32 t_ref;\r
364     uint32 t_mrd   = mem_timing->mrd_min;\r
365 \r
366     //round all timing parameter\r
367     t_ras = ((mem_timing->ras_min % cycle_ns) == 0) ? (mem_timing->ras_min/cycle_ns) : (mem_timing->ras_min/cycle_ns + 1);\r
368     t_rrd = ((mem_timing->rrd_min % cycle_ns) == 0) ? (mem_timing->rrd_min/cycle_ns) : (mem_timing->rrd_min/cycle_ns + 1);\r
369     t_rcd = ((mem_timing->rcd_min % cycle_ns) == 0) ? (mem_timing->rcd_min/cycle_ns) : (mem_timing->rcd_min/cycle_ns + 1);\r
370     t_rp = ((mem_timing->row_pre_min % cycle_ns) == 0) ? (mem_timing->row_pre_min/cycle_ns) : (mem_timing->row_pre_min/cycle_ns + 1);\r
371     t_rfc = ((mem_timing->rfc_min % cycle_ns) == 0) ? (mem_timing->rfc_min/cycle_ns) : (mem_timing->rfc_min/cycle_ns + 1);\r
372     t_xsr = ((mem_timing->xsr_min % cycle_ns) == 0) ? (mem_timing->xsr_min/cycle_ns) : (mem_timing->xsr_min/cycle_ns + 1);\r
373 \r
374     \r
375 #ifdef SDR_SDRAM_SUPPORT\r
376     if (SDR_SDRAM == mem_info->sdram_type)\r
377     {\r
378         t_wr = mem_timing->wr_min/cycle_ns; \r
379     }\r
380     else\r
381 #endif\r
382     {\r
383         t_wr = mem_timing->wr_min/cycle_ns+2;//note: twr should add 2 for ddr\r
384     }\r
385 \r
386     t_ref       = tREFI / cycle_t_ref;\r
387 \r
388     //prevent the maximun overflow of all timing parameter\r
389     t_ras       = (t_ras >= 0xf) ? 0xa  : t_ras;\r
390     t_xsr       = (t_xsr >= 0xff) ? 0x26 : t_xsr;\r
391     t_rfc       = (t_rfc >= 0x3f) ? 0x1a : t_rfc;\r
392     t_wr        = (t_wr  >= 0xf) ? 0x4  : t_wr;\r
393     t_rcd       = (t_rcd >= 0xf) ? 0x7  : t_rcd;\r
394     t_rp        = (t_rp  >= 0xf) ? 0x7  : t_rp;\r
395     t_rrd       = (t_rrd >= 0xf) ? 0x4  : t_rrd;\r
396     t_mrd       = (t_mrd >= 0xf) ? 0x3  : t_mrd;\r
397     t_wtr       = (t_wtr >= 0xf) ? 0x3  : t_wtr;\r
398     t_ref       = (t_ref >=0xfff) ? 0x32: t_ref ;\r
399 \r
400     //prevent the minmun value of all timing\r
401     t_ras       = (t_ras == 0) ? 0xa  : t_ras;\r
402     t_xsr       = (t_xsr == 0) ? 0x26 : t_xsr;\r
403     t_rfc       = (t_rfc == 0) ? 0x1a : t_rfc;\r
404     t_wr        = (t_wr  == 0) ? 0x4  : t_wr;\r
405     t_rcd       = (t_rcd == 0) ? 0x7  : t_rcd;\r
406     t_rp        = (t_rp  == 0) ? 0x7  : t_rp;\r
407     t_rrd       = (t_rrd == 0) ? 0x4  : t_rrd;\r
408     t_mrd       = (t_mrd == 0) ? 0x3  : t_mrd;\r
409     t_wtr       = (t_wtr == 0) ? 0x3  : t_wtr;\r
410     t_ref       = (t_ref == 0) ? 0x32: t_ref ;\r
411 \r
412     REG32(EXT_MEM_DCFG1) =\r
413         ((t_rtr << 28)    |//read to read turn around time between different cs,default:0     2 cs or above:1\r
414          (t_wtr << 24) |\r
415          (t_rtw << 20) |\r
416          (t_ras << 16) |\r
417          (t_rrd << 12) |\r
418          (t_wr  << 8)  |\r
419          (t_rcd << 4)  |\r
420          (t_rp  << 0));\r
421 \r
422     REG32(EXT_MEM_DCFG2) =\r
423         ((t_rfc << 24) |\r
424          (t_xsr << 16) |\r
425          (t_ref << 4)  |\r
426          (t_mrd << 0));\r
427 #endif\r
428 }\r
429 \r
430 \r
431 /*****************************************************************************/\r
432 //  Description:        EMC software command send function\r
433 //                              this function will send software initialization command to external memory\r
434 //  Global resource dependence:  memory type\r
435 //  Author:             Johnny.Wang\r
436 //  Related register:\r
437 //  Note:                       None\r
438 //\r
439 /*****************************************************************************/\r
440 LOCAL void EMC_SCMD_Issue(SDRAM_CFG_INFO_T_PTR mem_info)\r
441 {\r
442     uint32 i = 0;\r
443 \r
444     //shut down auto-refresh\r
445     REG32(EXT_MEM_DCFG0) &= ~(DCFG0_AUTOREF_EN);\r
446 \r
447     //precharge all bank\r
448     REG32(EXT_MEM_DCFG4) = 0x40010000;\r
449     while (REG32(EXT_MEM_DCFG4) & BIT_16);\r
450     for (i=0; i<=50; i++);\r
451 \r
452     //software auto refresh\r
453     REG32(EXT_MEM_DCFG4) = 0x40020000;\r
454     while (REG32(EXT_MEM_DCFG4) & BIT_17);\r
455     for (i=0; i<=50; i++);\r
456 \r
457     //software auto refresh\r
458     REG32(EXT_MEM_DCFG4) = 0x40020000;\r
459     while (REG32(EXT_MEM_DCFG4) & BIT_17);\r
460     for (i=0; i<=50; i++);\r
461 \r
462     //load nornal mode register\r
463     REG32(EXT_MEM_DCFG4) = 0x40040000 | (mem_info->cas_latency<<4) | (mem_info->burst_length);\r
464     while (REG32(EXT_MEM_DCFG4) & BIT_18);\r
465     for (i=0; i<=50; i++);\r
466 \r
467     if (SDRAM_EXT_MODE_INVALID != mem_info->ext_mode_val)\r
468     {\r
469         mem_info->ext_mode_val &= (~(0x7 << 5));\r
470         mem_info->ext_mode_val |= (s_emc_config.ddr_drv << 5);\r
471         \r
472         //load external mode register\r
473         REG32(EXT_MEM_DCFG4) = 0x40040000 | mem_info->ext_mode_val;\r
474         while (REG32(EXT_MEM_DCFG4) & BIT_18);\r
475         for (i=0; i<=50; i++);\r
476     }\r
477 \r
478     //open auto-refresh\r
479     REG32(EXT_MEM_DCFG0) |= (DCFG0_AUTOREF_EN);\r
480 \r
481 }\r
482 \r
483 \r
484 /*****************************************************************************/\r
485 //  Description:        EMC phy latency set function\r
486 //                              set parameter relate with cas latency like:\r
487 //                              timing adjustment sample clock latency\r
488 //                              DQS output latency\r
489 //                              write dm latency\r
490 //                              read dm latency\r
491 //                              write data latency\r
492 //                              read data latency\r
493 //  Global resource dependence:  dram type , cas_latency\r
494 //  Author:             Johnny.Wang\r
495 //  Related register: EMC_DCFG5\r
496 //\r
497 //  Note:                       None\r
498 //\r
499 /*****************************************************************************/\r
500 PUBLIC void EMC_PHY_Latency_Set(SDRAM_CFG_INFO_T_PTR mem_info)\r
501 {\r
502 #ifdef SDR_SDRAM_SUPPORT\r
503     if (SDR_SDRAM == mem_info->sdram_type)\r
504     {\r
505         if (CAS_LATENCY_2 == mem_info->cas_latency)\r
506         {\r
507             REG32(EXT_MEM_DCFG5) = 0x00400007;\r
508         }\r
509         else if (CAS_LATENCY_3 == mem_info->cas_latency)\r
510         {\r
511             REG32(EXT_MEM_DCFG5) = 0x00600209;\r
512         }\r
513         \r
514     }\r
515     else\r
516 #endif\r
517     {\r
518         if (CAS_LATENCY_2 == mem_info->cas_latency)\r
519         {\r
520             REG32(EXT_MEM_DCFG5) = 0x00622728;\r
521         }\r
522         else if (CAS_LATENCY_3 == mem_info->cas_latency)\r
523         {\r
524             REG32(EXT_MEM_DCFG5) = 0x0062272A;\r
525         }\r
526     }\r
527 }\r
528 /*****************************************************************************/\r
529 //  Description:        EMC phy mode set function\r
530 //                              set parameter relate with emc phy work mode like:\r
531 //                              cke map to cs0 or cs1\r
532 //                              dqs gate delay,delay line or loopback\r
533 //                              dqs gate mode,mode0 or mode1\r
534 //                              DMEM data output mode,dff or dl\r
535 //                              DMEM DDR DQS[3:0] output mode,dff or dl\r
536 //                              DMEM DDR DQS PAD IE mode,dff or dl\r
537 //                              DMEM sample clock mode,internal or from dqs\r
538 //                              DMEM CK/CK# output mode,dff or dl\r
539 //                              DMEM READ strobe clock loopback dis/en\r
540 //  Global resource dependence:  dll on or off, external memory type\r
541 //  Author:             Johnny.Wang\r
542 //  Related register: EMC_CFG1\r
543 //\r
544 //  Note:                       None\r
545 //\r
546 /*****************************************************************************/\r
547 LOCAL void EMC_PHY_Mode_Set(SDRAM_CFG_INFO_T_PTR mem_info)\r
548 {\r
549     uint32 i = 0;\r
550 \r
551 //    SCI_ASSERT(mem_info != NULL);\r
552 \r
553     i = REG32(EXT_MEM_CFG1);\r
554     i &= ~((3<<14)|0x3ff);\r
555     i |=(EMC_CKE_SEL_DEFAULT << 14) |\r
556         (EMC_DQS_GATE_DEFAULT<< 8)      |\r
557         (EMC_DQS_GATE_MODE_DEFAULT<< 7) |\r
558         (mem_info->sdram_type<< 6) |//DMEM data output mode,0:dff 1:dl\r
559         (0<<5) |//DMEM DDR DQS[3:0] output mode,0:dff 1:dl\r
560         (0<<4) |//DMEM DDR DQS PAD IE mode,0:dff 1:dl\r
561         (mem_info->sdram_type<<3) |//DMEM sample clock mode,0:internal 1:out-of-chip\r
562         (0<<2) |//DMEM CK/CK# output mode,0:dff 1:dl\r
563         ((~mem_info->sdram_type & 0x1) <<1) |//DMEM READ strobe clock loopback 0:dis 1:en\r
564         mem_info->sdram_type;\r
565 \r
566     REG32(EXT_MEM_CFG1) = i;\r
567 \r
568 }\r
569 \r
570 \r
571 \r
572 /*****************************************************************************/\r
573 //  Description:        EMC phy timing set function\r
574 //                              set parameter relate with emc phy work mode like:\r
575 //                              data pad ie delay\r
576 //                              data pad oe delay\r
577 //                              dqs pad ie delay\r
578 //                              dqs pad oe delay\r
579 //                              all delay line timing parameter\r
580 //  Global resource dependence:  dll on or off, external memory type\r
581 //  Author:             Johnny.Wang\r
582 //  Related register: EMC_DCFG6,7,8 and EMC_DMEM_DL0~DL19\r
583 //  Note:                       None\r
584 //\r
585 /*****************************************************************************/\r
586 PUBLIC void EMC_PHY_Timing_Set(SDRAM_CFG_INFO_T_PTR mem_info,\r
587                         EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing,\r
588                         EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing)\r
589 {\r
590     uint32 i = 0;\r
591 \r
592     uint8 emc_dll_rd_val;\r
593 //    uint32 clkwr_dll = (64*s_emc_config.clk_wr)/(s_emc_config.read_value/2);\r
594     uint8 clkwr_dll;\r
595 \r
596 //    SCI_ASSERT((mem_info != NULL) && (emc_phy_l1_timing != NULL) && (emc_phy_l2_timing != NULL));\r
597 \r
598     REG32(EXT_MEM_DCFG8) = ((emc_phy_l1_timing->data_pad_ie_delay & 0xffff) <<16) |\r
599                            (emc_phy_l1_timing->data_pad_oe_delay & 0xff);\r
600 \r
601 \r
602     if (DDR_SDRAM == mem_info->sdram_type)\r
603     {\r
604         REG32(EXT_MEM_DCFG6) = ((emc_phy_l1_timing->dqs_gate_pst_delay& 0xffff) <<16) |\r
605                                (emc_phy_l1_timing->dqs_gate_pre_delay& 0xffff);\r
606 \r
607         REG32(EXT_MEM_DCFG7) = ((emc_phy_l1_timing->dqs_ie_delay& 0xffff) <<16) |\r
608                                (emc_phy_l1_timing->dqs_oe_delay& 0xff);\r
609 \r
610         if (s_emc_dll_open)\r
611         {\r
612             REG32(EXT_MEM_CFG0_DLL) = 0x11080; //DLL and compensation en\r
613 \r
614             WAIT_EMC_DLL_LOCK;\r
615         }\r
616         else\r
617         {\r
618             REG32(EXT_MEM_CFG0_DLL) &= ~BIT_10; //DLL disable\r
619                         for(i=0;i<20;i++);\r
620                         REG32(EXT_MEM_CFG0_DLL) &= ~BIT_7; //DLL disable\r
621                         for(i=0;i<20;i++);\r
622                         REG32(EXT_MEM_CFG0_DLL) = 0; //DLL disable\r
623         }\r
624 \r
625         for (i = 0; i < 20; i++)\r
626         {\r
627             REG32(EXT_MEM_DL0 + i*4) = REG32((unsigned int)emc_phy_l2_timing + i * 4);\r
628         }\r
629 \r
630         if (s_emc_dll_open)\r
631         {\r
632             emc_dll_rd_val = (REG32(EXT_MEM_CFG0_DLL_STS) & 0xFF);\r
633             \r
634             clkwr_dll = (s_emc_config.clk_wr << 6) / ((emc_dll_rd_val & 0xff) >> 1);\r
635             \r
636             for (i = 0; i < 4; i++)\r
637             {\r
638                 REG32(EXT_MEM_DL0 + i*4) = (0x8000 | (clkwr_dll & 0x7F));\r
639             }\r
640 \r
641             REG32(EXT_MEM_CFG0_DLL) |= DCFG0_DLL_COMPENSATION_EN;\r
642         }        \r
643 \r
644     }\r
645     else\r
646     {\r
647         REG32(EXT_MEM_DCFG6) = 0X400020;\r
648         REG32(EXT_MEM_DCFG7) = 0XF0000E;\r
649         REG32(EXT_MEM_DCFG8) = 0X400001;\r
650     }\r
651 }\r
652 \r
653 \r
654 LOCAL void EMC_CHL_Init(EMC_CHL_INFO_PTR emc_chl_info)\r
655 {\r
656     int i = 0;\r
657     EMC_CHL_NUM_E emc_channel_num;\r
658 \r
659     while (emc_chl_info[i].emc_chl_num != EMC_CHL_MAX)\r
660     {\r
661         emc_channel_num = emc_chl_info[i].emc_chl_num;\r
662 \r
663         if ((emc_channel_num >= EMC_AXI_MIN) && (emc_channel_num <= EMC_AXI_MAX))\r
664         {\r
665             EMC_AXI_CHL_Set(emc_channel_num,\r
666                         emc_chl_info[i].axi_chl_wr_pri,\r
667                         emc_chl_info[i].axi_chl_rd_pri\r
668                         );\r
669         }\r
670         else if ((emc_channel_num >= EMC_AHB_MIN) && (emc_channel_num <= EMC_AHB_MAX))\r
671         {\r
672             EMC_AHB_CHL_Set(emc_channel_num, 0, emc_chl_info[i].ahb_chl_pri);\r
673         }\r
674         else\r
675         {\r
676             SCI_ASSERT(0);\r
677         }\r
678 \r
679         i++;\r
680     }\r
681 }\r
682 \r
683 \r
684 LOCAL void set_emc_pad(uint32 dqs_drv,uint32 data_drv,uint32 ctl_drv, uint32 clk_drv)\r
685 {\r
686     unsigned int i = 0;\r
687 \r
688 //    SCI_ASSERT(dqs_drv < 4);\r
689 //    SCI_ASSERT(data_drv < 4);\r
690 //    SCI_ASSERT(ctl_drv < 4);\r
691 //    SCI_ASSERT(clk_drv < 4);\r
692 \r
693     dqs_drv &= 0x3;\r
694     data_drv &= 0x3;\r
695     ctl_drv &= 0x3;\r
696     clk_drv &= 0x3;\r
697 \r
698     for(i = 0; i < 2; i++)\r
699     {// ckdp ckdm\r
700         REG32((CHIPPIN_CTL_BEGIN + PIN_CLKDMMEM_REG_OFFS) + i*4) &= (~0x30F);\r
701         REG32((CHIPPIN_CTL_BEGIN + PIN_CLKDMMEM_REG_OFFS) + i*4) |= ((clk_drv<<8) | 0x4);\r
702     }\r
703 \r
704     //addr\r
705     for(i = 0; i < 14; i++)\r
706     {\r
707         REG32((CHIPPIN_CTL_BEGIN + PIN_EMA0_REG_OFFS) + i*4) &= (~0x30F);\r
708         REG32((CHIPPIN_CTL_BEGIN + PIN_EMA0_REG_OFFS) + i*4) |= ((ctl_drv<<8) | 0x4);\r
709     }\r
710 \r
711     for(i = 0; i < 7; i++)\r
712     {//bank0 bank1 casn cke0 cke1 csn0 csn1\r
713         REG32((CHIPPIN_CTL_BEGIN + PIN_EMBA0_REG_OFFS) + i*4) &= (~0x30F);\r
714         REG32((CHIPPIN_CTL_BEGIN + PIN_EMBA0_REG_OFFS) + i*4) |= ((ctl_drv<<8) | 0x4);\r
715     }\r
716 \r
717     for(i = 0; i < 2; i++)\r
718     {//cke0 cke1\r
719         REG32((CHIPPIN_CTL_BEGIN + PIN_EMCKE0_REG_OFFS) + i*4) |= 0x5;\r
720     }\r
721 \r
722     for(i = 0; i < 4; i++)\r
723     {//dqm\r
724         REG32((CHIPPIN_CTL_BEGIN + PIN_EMDQM0_REG_OFFS) + i*4) &= (~0x30F);\r
725         REG32((CHIPPIN_CTL_BEGIN + PIN_EMDQM0_REG_OFFS) + i*4) |= ((data_drv<<8) | 0x4);\r
726     }\r
727 \r
728     for(i = 0; i < 4; i++)\r
729     {//dqs\r
730         REG32((CHIPPIN_CTL_BEGIN + PIN_EMDQS0_REG_OFFS) + i*4) &= (~0x30F);\r
731         REG32((CHIPPIN_CTL_BEGIN + PIN_EMDQS0_REG_OFFS) + i*4) |= ((dqs_drv<<8) | 0x4);\r
732     }\r
733 \r
734     //data\r
735     for(i = 0; i < 32; i++)\r
736     {\r
737         REG32((CHIPPIN_CTL_BEGIN + PIN_EMD0_REG_OFFS) + i*4) &= (~0x30F);\r
738         REG32((CHIPPIN_CTL_BEGIN + PIN_EMD0_REG_OFFS) + i*4) |= ((data_drv<<8) | 0x4);\r
739     }\r
740 \r
741     for(i = 0; i < 2; i++)\r
742     {//gpre_loop gpst_loop\r
743         REG32((CHIPPIN_CTL_BEGIN + PIN_EMGPRE_LOOP_REG_OFFS) + i*4) &= (~0x300F);\r
744         REG32((CHIPPIN_CTL_BEGIN + PIN_EMGPRE_LOOP_REG_OFFS) + i*4) |= ((ctl_drv<<8) | 0x4);\r
745     }\r
746 \r
747     for(i = 0; i < 2; i++)\r
748     {//rasn wen\r
749         REG32((CHIPPIN_CTL_BEGIN + PIN_EMRAS_N_REG_OFFS) + i*4) &= (~0x30F);\r
750         REG32((CHIPPIN_CTL_BEGIN + PIN_EMRAS_N_REG_OFFS) + i*4) |= ((ctl_drv<<8) | 0x4);\r
751     }\r
752 }\r
753 \r
754 #ifdef SDRAM_AUTODETECT_SUPPORT\r
755 LOCAL BOOLEAN __is_rw_ok(uint32 addr,uint32 val)\r
756 {\r
757     volatile uint32 i;\r
758     BOOLEAN ret = SCI_TRUE;\r
759 \r
760     REG32(addr) = 0;\r
761     REG32(addr)         = val;\r
762 \r
763     REG32(addr + 4) = 0;\r
764     REG32(addr + 4) = (~val);\r
765 \r
766     delay(100);\r
767 \r
768     if ((REG32(addr) == val) && (REG32(addr + 4) == (~val)))\r
769     {\r
770         ret = SCI_TRUE;\r
771     }\r
772     else\r
773     {\r
774         ret = SCI_FALSE;\r
775     }\r
776 \r
777     return ret;\r
778 }\r
779 \r
780 \r
781 LOCAL void dram_detect_write_addr(uint32 start_addr, uint32 detect_size)\r
782 {\r
783     uint32 addr;\r
784     uint32 detect_unit = 0x200;\r
785     uint32 detect_region = (start_addr + detect_size);\r
786 \r
787     for(addr = start_addr; addr < detect_region; addr = start_addr + detect_unit)\r
788     {\r
789         *(volatile uint32 *)addr = addr;\r
790         detect_unit <<= 1;\r
791     }\r
792 }\r
793 \r
794 LOCAL uint32 dram_detect_check_addr(uint32 start_addr, uint32 detect_size)\r
795 {\r
796     uint32 addr;\r
797     uint32 detect_unit = 0x200;\r
798     uint32 detect_region = (start_addr + detect_size);\r
799 \r
800     for(addr = start_addr; addr < detect_region; addr = start_addr + detect_unit)\r
801     {\r
802         if(*(volatile uint32 *)addr != addr)\r
803         {\r
804             break;\r
805         }\r
806         \r
807         detect_unit <<= 1;\r
808     }\r
809 \r
810     if (addr < detect_region)\r
811     {\r
812         return addr;\r
813     } \r
814 \r
815     return detect_region;\r
816 }\r
817 \r
818 \r
819 LOCAL BOOLEAN dram_mode_check(uint32 dram_cap)\r
820 {\r
821     BOOLEAN ret = TRUE;\r
822     uint32 i = 0;\r
823     uint32 detect_block_size = CAP_2G_BIT;\r
824     uint32 start_detect_addr_len = 0;\r
825     uint32 start_detect_addr[] = {\r
826         SDRAM_BASE_ADDR,\r
827         0x10000000,\r
828         0x30000000,\r
829         INVALIDE_VAL\r
830     };\r
831 \r
832 //    SCI_ASSERT(dram_cap >= CAP_1G_BIT);\r
833     \r
834     switch (dram_cap)\r
835     {\r
836         case CAP_6G_BIT:\r
837             break;\r
838         case CAP_4G_BIT:\r
839             start_detect_addr[2] = INVALIDE_VAL;\r
840             break;\r
841         case CAP_2G_BIT:\r
842         default:\r
843             start_detect_addr[1] = INVALIDE_VAL;\r
844             start_detect_addr[2] = INVALIDE_VAL;\r
845             break;\r
846     }\r
847 \r
848     start_detect_addr_len = sizeof(start_detect_addr) / sizeof(start_detect_addr[0]);\r
849 \r
850     for(i = 0; i < start_detect_addr_len; i++)\r
851     {\r
852         if (start_detect_addr[i] != INVALIDE_VAL)\r
853         {\r
854             dram_detect_write_addr(start_detect_addr[i], detect_block_size);\r
855         }\r
856     }\r
857 \r
858     for(i = 0; i < start_detect_addr_len; i++)\r
859     {\r
860         if (start_detect_addr[i] != INVALIDE_VAL)\r
861         {\r
862             if (dram_detect_check_addr(start_detect_addr[i], detect_block_size) != (start_detect_addr[i] + detect_block_size))\r
863             {\r
864                 ret = FALSE;\r
865                 break;\r
866             }\r
867         }  \r
868     }\r
869 \r
870     return ret;\r
871 }\r
872 \r
873 LOCAL BOOLEAN DRAM_Para_SelfAdapt(void)\r
874 {\r
875     int i;\r
876 //    BOOLEAN ret = FALSE;\r
877     SDRAM_CFG_INFO_T_PTR pCfg = SDRAM_GetCfg();\r
878     SDRAM_MODE_PTR modetable_ptr = SDRAM_GetModeTable();\r
879 \r
880     for (;;)\r
881     {\r
882         DMC_Init();\r
883         \r
884         if (__is_rw_ok(SDRAM_BASE_ADDR, MEM_REF_DATA0))\r
885         {\r
886             break;\r
887         }\r
888 \r
889         if((pCfg->data_width == DATA_WIDTH_32)\r
890                 && (pCfg->sdram_type == DDR_SDRAM)\r
891             )\r
892         {\r
893             pCfg->data_width = DATA_WIDTH_16;\r
894         }\r
895         else if((pCfg->data_width == DATA_WIDTH_16)\r
896                 && (pCfg->sdram_type == DDR_SDRAM)\r
897             )\r
898         {\r
899             pCfg->data_width = DATA_WIDTH_32;\r
900             pCfg->sdram_type = SDR_SDRAM;\r
901         }\r
902         else if((pCfg->data_width == DATA_WIDTH_32)\r
903                 && (pCfg->sdram_type == SDR_SDRAM)\r
904             )\r
905         {\r
906             pCfg->data_width = DATA_WIDTH_16;\r
907         }\r
908         else\r
909         {\r
910             return FALSE;\r
911         }\r
912     }\r
913 \r
914     for(i=0; modetable_ptr[i].capacity != CAP_ZERO; i++)\r
915     {\r
916         if(modetable_ptr[i].data_width != pCfg->data_width)\r
917         {\r
918             continue;\r
919         }\r
920 \r
921         pCfg->cs_position = modetable_ptr[i].cs_position;\r
922         pCfg->col_mode = modetable_ptr[i].col_mode;\r
923         pCfg->row_mode = modetable_ptr[i].row_mode;\r
924 \r
925         DMC_Init();\r
926 \r
927         if(dram_mode_check(modetable_ptr[i].capacity))\r
928         {\r
929             DRAM_CAP = modetable_ptr[i].capacity;\r
930             break;\r
931         }\r
932     }\r
933 \r
934     if (modetable_ptr[i].capacity == CAP_ZERO)\r
935     {\r
936         return FALSE;\r
937         //SCI_ASSERT(0);\r
938     }\r
939 \r
940     return TRUE;\r
941 }\r
942 \r
943 #endif\r
944 \r
945 \r
946 LOCAL void DMC_Init(void)\r
947 {\r
948     uint32 emc_freq = s_emc_config.emc_clk;\r
949     SDRAM_CFG_INFO_T_PTR    mem_info = SDRAM_GetCfg();\r
950     SDRAM_TIMING_PARA_T_PTR mem_timing = SDRAM_GetTimingPara();\r
951     EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing = NULL;\r
952     EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing = EMC_GetPHYL2_Timing();\r
953     EMC_CHL_INFO_PTR emc_chl_info = EMC_GetChlInfo();\r
954 \r
955     EMC_SoftReset();\r
956     EMC_CHL_Init(emc_chl_info);\r
957         \r
958     EMC_Base_Mode_Set(mem_info);\r
959     EMC_AddrMode_Set(mem_info);\r
960     EMC_CSx_Burst_Set(EMC_CS0, mem_info);\r
961     EMC_CSx_Burst_Set(EMC_CS1, mem_info);\r
962     EMC_PHY_Mode_Set(mem_info);\r
963     EMC_PHY_Latency_Set(mem_info);\r
964 \r
965     emc_phy_l1_timing = EMC_GetPHYL1_Timing(mem_info->sdram_type, mem_info->cas_latency);\r
966     EMC_PHY_Timing_Set(mem_info, emc_phy_l1_timing, emc_phy_l2_timing);\r
967     EMC_MEM_Timing_Set(emc_freq, mem_info, mem_timing);\r
968     EMC_SCMD_Issue(mem_info);\r
969 \r
970     return;\r
971 }\r
972 \r
973 LOCAL void emc_clock_select(EMC_CLK_SOURCE_E emc_clk_sel)\r
974 {\r
975     uint32 i;\r
976     \r
977 //      SCI_ASSERT(emc_clk_sel < EMC_CLK_NONE);\r
978         \r
979     i = REG32(AHB_ARM_CLK);\r
980     i &= ~(1 << 3); // clk_emc_async\r
981     i &= ~(3 << 12);\r
982     i |= ((emc_clk_sel & 0x3) << 12);\r
983         \r
984         REG32(AHB_ARM_CLK) = i;\r
985 }\r
986 \r
987 LOCAL void set_emc_clock_div(uint32 emc_div)\r
988 {\r
989     uint32 i;\r
990 \r
991     i = REG32(AHB_ARM_CLK);\r
992     i &= ~(0xF << 8);\r
993     i |= ((emc_div & 0xF) << 8); // emc div = n + 1\r
994 \r
995     REG32(AHB_ARM_CLK) = i;\r
996 }\r
997 \r
998 LOCAL void set_dpll_clock_freq(uint32 clk_freq_hz)\r
999 {\r
1000     uint32 i;\r
1001 \r
1002     uint32 dpll_clk;\r
1003 \r
1004     dpll_clk = (clk_freq_hz / 1000000 / 4);\r
1005 \r
1006     //APB_GEN1_PCLK M_PLL_CTRL_WE\r
1007     REG32(GR_GEN1) |= (1 << 9);\r
1008 \r
1009     i = REG32(GR_DPLL_CTL); //0x8b000040\r
1010     i &= ~ 0x7FF;\r
1011     i |= (dpll_clk & 0x7FF);\r
1012 \r
1013     REG32(GR_DPLL_CTL) = i;\r
1014     REG32(GR_GEN1) &= ~(1 << 9);\r
1015 }\r
1016 \r
1017 \r
1018 LOCAL void set_emc_clock_freq(void)\r
1019 {\r
1020     uint32 emc_div = 0;\r
1021     uint32 emc_clk_freq = s_emc_config.emc_clk;\r
1022     EMC_CLK_SOURCE_E emc_clk_sel;\r
1023     \r
1024     switch (emc_clk_freq)\r
1025     {\r
1026         case EMC_CLK_26MHZ:\r
1027             emc_clk_sel = EMC_CLK_XTL_SOURCE;\r
1028             break;\r
1029         case EMC_CLK_67MHZ:\r
1030             emc_clk_sel = EMC_CLK_DPLL_SOURCE;\r
1031             break;\r
1032         case EMC_CLK_133MHZ:\r
1033             emc_clk_sel = EMC_CLK_DPLL_SOURCE;\r
1034             break;\r
1035         case EMC_CLK_266MHZ:\r
1036             emc_clk_sel = EMC_CLK_DPLL_SOURCE;\r
1037             break;\r
1038         case EMC_CLK_333MHZ:\r
1039             emc_clk_sel = EMC_CLK_DPLL_SOURCE;\r
1040             break;\r
1041         case EMC_CLK_370MHZ:\r
1042             emc_clk_sel = EMC_CLK_DPLL_SOURCE;\r
1043             break;\r
1044         case EMC_CLK_200MHZ:\r
1045             emc_clk_sel = EMC_CLK_DPLL_SOURCE;\r
1046             break;\r
1047         case EMC_CLK_400MHZ:\r
1048         default:\r
1049             emc_clk_sel = EMC_CLK_DPLL_SOURCE;\r
1050             emc_clk_freq = EMC_CLK_400MHZ;\r
1051             break;\r
1052     }\r
1053 \r
1054     if (emc_clk_sel == EMC_CLK_DPLL_SOURCE)\r
1055     {\r
1056         set_dpll_clock_freq(emc_clk_freq);\r
1057         set_emc_clock_div(emc_div);\r
1058     }\r
1059 \r
1060         emc_clock_select(emc_clk_sel);\r
1061         \r
1062     if (emc_clk_freq <= EMC_CLK_67MHZ)\r
1063     {\r
1064         s_emc_dll_open = FALSE;\r
1065     }\r
1066     else\r
1067     {\r
1068         s_emc_dll_open = TRUE;\r
1069     }\r
1070 \r
1071 }\r
1072 \r
1073 void sdram_init(void)\r
1074 {\r
1075     uint32 i;\r
1076 \r
1077     EMC_PARAM_PTR emc_ptr = EMC_GetPara();\r
1078 \r
1079 //    s_emc_config.arm_clk = emc_ptr->arm_clk;\r
1080     s_emc_config.emc_clk = emc_ptr->emc_clk;\r
1081     s_emc_config.dqs_drv = emc_ptr->dqs_drv;\r
1082     s_emc_config.dat_drv = emc_ptr->dat_drv;\r
1083     s_emc_config.ctl_drv = emc_ptr->ctl_drv;\r
1084     s_emc_config.clk_drv = emc_ptr->clk_drv;\r
1085     s_emc_config.clk_wr  = emc_ptr->clk_wr;\r
1086     s_emc_config.ddr_drv = emc_ptr->ddr_drv;\r
1087 \r
1088     set_emc_pad(s_emc_config.dqs_drv, s_emc_config.dat_drv, s_emc_config.ctl_drv, s_emc_config.clk_drv);\r
1089 \r
1090     set_emc_clock_freq();\r
1091 \r
1092     delay(200000);\r
1093 \r
1094 #ifdef SDRAM_AUTODETECT_SUPPORT\r
1095     for (i=0; i<3; i++)\r
1096     {\r
1097         if (DRAM_Para_SelfAdapt())\r
1098         {\r
1099             break;\r
1100         }\r
1101     }\r
1102 \r
1103     SCI_ASSERT(i < 3);\r
1104 #else\r
1105     DMC_Init();\r
1106     DRAM_CAP =  SDRAM_GetCap(); // get size\r
1107 #endif\r
1108 \r
1109 }\r
1110 \r
1111 \r
1112 \r
1113 #ifdef   __cplusplus\r
1114 }\r
1115 #endif\r
1116 \r
1117 \r
1118 \r
1119 \r