tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / arm926ejs / sc8800g / sdram.c
1 /******************************************************************************
2     David.Jia   2007.10.29      share_version_union
3
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 ******************************************************************************/
10
11 #include <common.h>
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>
19
20 /*lint -e760 -e547 ,because pclint error e63 e26 with REG32()*/
21 #define REG32(x)   (*((volatile uint32 *)(x)))
22 /*lint +e760 +e547 ,because pclint error e63 e26 with REG32()*/
23
24 /*lint -e765*/
25
26 #define  SDRAM_EXT_INVALID     0xffffffff       //@David.Jia 2008.1.7
27
28 #if defined(PLATFORM_SC8800G)
29 uint32 g_emc_clk;
30 uint32 s_colum;
31 #endif //defined(PLATFORM_SC8800G) && defined(CHIP_VER_8800G2)
32
33 uint32 g_ahb_clk; 
34 SDRAM_TIMING_PARA_T_PTR sdram_parameters;
35
36 #ifdef PLATFORM_SC8800G
37 #define SDRAM_AUTODETECT_SUPPORT
38 #endif
39 #define _BL_NF_NBL_
40
41 #ifdef SDRAM_AUTODETECT_SUPPORT
42 #define MEM_REF_DATA0       0x12345678
43 #define MEM_REF_DATA1       0x55AA9889
44 #ifdef _BL_NF_NBL_
45 #define ZERO_ADDR           0x00000000UL
46 #else
47 #define ZERO_ADDR           0x30000000UL
48 #endif
49 #define STATE_SDRAM_TYPE    0UL
50 #define STATE_BIT_WIDTH     1UL
51 #define STATE_COLUM         2UL
52 #define STATE_ROW           3UL
53 #define STATE_REINIT        4UL
54 #define STATE_END           5UL
55
56 #define BYTE_OFFSET         3UL   // 1BYTE = 8BIT = 2^3
57 #define WIDTH16_OFFSET      4UL   // 16BIT = 2^4
58 #define WIDTH32_OFFSET      5UL   // 32BIT = 2^5
59 #define BANK_OFFSET         2UL   // 4BANK = 2^2
60
61 #define SDRAM_MIN_COLUM     8UL
62 #define SDRAM_MAX_COLUM     12UL
63 #define SDRAM_MIN_ROW       11UL
64 #define SDRAM_MAX_ROW       14UL
65
66 SDRAM_CFG_INFO_T s_sdram_raw_cfg;
67 #endif
68
69 #ifdef PLATFORM_SC8800G
70 #define INTERFACE_CLK_MAX   ARM_CLK_200M
71 typedef struct ARM_EMC_AHB_CLK_TAG 
72 {
73     uint32 mcu_clk;
74     uint32 arm_clk;
75     uint32 emc_clk;
76     uint32 ahb_clk;
77 } ARM_EMC_AHB_CLK_T;
78
79 typedef enum MCU_CLK_TYPE_TAG
80 {
81     ARM400_EMC200_AHB100 = 0,   //SC8800G2
82     ARM256_EMC200_AHB64,        //SC8801G2
83     ARM192_EMC200_AHB96,        //SC8802G2
84     ARM256_EMC192_AHB64,
85     ARM256_EMC128_AHB64,
86     ARM192_EMC192_AHB96,
87
88     MCU_CLK_TYPE_MAX   
89 } MCU_CLK_TYPE_E;
90
91 LOCAL CONST ARM_EMC_AHB_CLK_T s_arm_emc_ahb_clk[] = 
92 {
93 //     mcu_clk       arm_clk        emc_clk       ahb_clk
94     {ARM_CLK_400M, ARM_CLK_400M, ARM_CLK_200M, ARM_CLK_100M},   //SC8800G2
95     {ARM_CLK_256M, ARM_CLK_256M, ARM_CLK_200M, ARM_CLK_64M},    //SC8801G2
96     {ARM_CLK_192M, ARM_CLK_192M, ARM_CLK_200M, ARM_CLK_96M},    //SC8802G2
97     {ARM_CLK_512M, ARM_CLK_256M, ARM_CLK_192M, ARM_CLK_64M},
98     {ARM_CLK_512M, ARM_CLK_256M, ARM_CLK_128M, ARM_CLK_64M},
99     {ARM_CLK_384M, ARM_CLK_192M, ARM_CLK_192M, ARM_CLK_96M},
100 };
101
102 //unsigned short ADI_Analogdie_reg_read (unsigned int addr);
103
104 //void ADI_Analogdie_reg_write (unsigned int addr, unsigned short data);
105
106 uint32 __GetMPllClk (void)
107 {
108     return ( ARM_CLK_26M
109                / ( (REG32(GR_MPLL_MN) & 0x003F0000) >>16)
110                * (REG32(GR_MPLL_MN) & 0x00000FFF) );
111 }
112
113 LOCAL void __SetMPllClk (uint32 clk)
114 {
115     uint32 M, N, tmp_mn;
116
117     M = 13; // M: fix to 13
118     N = clk/2/1000000;
119     
120     tmp_mn  = (REG32(GR_MPLL_MN) & (~0x3FFFFF));
121     tmp_mn |= (M << 16) | N;  
122               
123     REG32(GR_GEN1) |= BIT_9;        // MPLL Write En
124     REG32(GR_MPLL_MN) = tmp_mn;
125     REG32(GR_GEN1) &= ~BIT_9;       // MPLL Write Dis
126 }
127
128 LOCAL void __ClkConfig(uint32 *emcclk, uint32 *ahbclk)
129 {
130     uint32 tmp_clk, mcuclk, armclk;
131     uint32 mcu_div, if_div;
132     BOOLEAN is_mpll, is_async;
133     MCU_CLK_TYPE_E clk_type = ARM400_EMC200_AHB100;
134
135     ///*
136     switch(REG32(GR_GEN3) & 0x3)
137     {
138         case 0:
139                 clk_type = ARM400_EMC200_AHB100; // 8800G2
140                 break;
141         case 1:
142                 clk_type = ARM256_EMC200_AHB64;  // 8801G1
143                 break;
144         case 2:
145                 clk_type = ARM192_EMC200_AHB96;  // 8802G1 
146                 break;
147         default:
148                 clk_type =      ARM400_EMC200_AHB100;
149                 break;
150     }           
151     //*/         
152     
153     mcuclk   = s_arm_emc_ahb_clk[clk_type].mcu_clk;
154     armclk   = s_arm_emc_ahb_clk[clk_type].arm_clk;
155     *emcclk  = s_arm_emc_ahb_clk[clk_type].emc_clk;
156     *ahbclk  = s_arm_emc_ahb_clk[clk_type].ahb_clk;
157     
158     is_mpll  = (((0 == (REG32(GR_GEN3) & 0x3)) || (3 == (REG32(GR_GEN3) & 0x3))) ? (SCI_TRUE) : (SCI_FALSE));
159     is_async = ((0 == (armclk%(*emcclk)))     ? (SCI_FALSE) : (SCI_TRUE));  
160
161     mcu_div = 0;    
162     if(is_mpll)
163     {
164         if(__GetMPllClk() != mcuclk)
165         {
166             __SetMPllClk(mcuclk);
167         }
168         if(armclk != mcuclk)
169         {
170             mcu_div = 1;
171         }
172     }
173
174     if_div = 0;
175     if(armclk > INTERFACE_CLK_MAX)
176     {
177         if_div = 1;
178     }
179     
180     // step 1: config emc clk in dsp side in async mode
181     if(is_async) 
182     {
183         REG32(AHB_DSP_BOOT_EN)  |= BIT_2;
184         REG32(AHB_CTL1)         &= ~BIT_16;
185         REG32(0x10130010)       |= BIT_28;
186
187         REG32(0x1013000C)       |= (2<<10); //bit[11:10], DSP SIDE: 1:200M, 2:192M 3:26M
188         
189         REG32(0x10130010)       &= ~BIT_28;
190         REG32(AHB_CTL1)         |= BIT_16;
191         REG32(AHB_DSP_BOOT_EN)  &= ~BIT_2;
192     }
193     
194     // step 2: first config divider 
195     //         ifdiv / mcudiv /  ahbdiv
196     //         MCU_26M / sync_mode / emc-async-sel
197     tmp_clk = (BIT_23|BIT_24);
198     tmp_clk |= (if_div  << 31)  |   // bit[31],    interface-div
199                (mcu_div << 30)  |   // bit[30],    mcu-div
200                                     // bit[29:25], read only
201                                     // bit[24:23], mcu-sel, should config at step 2
202                                     // bit[22:17], reserved
203                (0 << 14)        |   // bit[16:14], emc-sync-div: 2^n
204                (1 << 12)        |   // bit[13:12], emc-async-sel: 0:reserved, 1:200M, 2:192M 3:26M
205                (0 << 8)         |   // bit[11:8],  emc-async-div: (n+1)
206                                     // bit[7],     ARM_384M_SEL:0
207                (1 << 4)         |   // bit[6:4],   ahb-div: (n+1)
208                (1 << 3)  ;          // bit[3],     emc sync:1, async:0
209                                     // bit[2:0],   arm-div, only for G1
210                
211     REG32(AHB_ARM_CLK) = tmp_clk;
212
213     // step 3: config mcu-sel 
214     tmp_clk &= ~(BIT_23|BIT_24); // mcu-sel: 26*N/M, this bit must be set after divider
215     REG32(AHB_ARM_CLK) = tmp_clk;
216
217     //step 4: switch to async mode at last
218     if(is_async)
219     {
220         tmp_clk &= ~BIT_3;
221         REG32(AHB_ARM_CLK) = tmp_clk;  
222     }
223
224     return;
225 }
226 #endif
227
228 /**---------------------------------------------------------------------------*
229  ** FUNCTION                                                                  *
230  **     void SDRAM_GenMemCtlCfg(SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)           *
231  **                                                                           *
232  ** DESCRIPTION                                                               *
233  **     set emc channel parameters                                            *
234  **                                                                           *
235  ** INPUT                                                                     *
236  **     sdram_cfg_ptr                                                         *
237  **                                                                           *
238  ** OUTPUT                                                                    *
239  **     None                                                                  *
240  **                                                                           *
241  ** RETURN VALUE                                                              *
242  **                                                                           *
243  ** DEPENDENCIES                                                              *
244  **                                                                           *
245 **---------------------------------------------------------------------------*/
246 LOCAL void SDRAM_GenMemCtlCfg (SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
247 {
248     uint32 burst_length = sdram_cfg_ptr->burst_length;
249     uint32 data_width   = sdram_cfg_ptr->data_width;
250     uint32 dburst_rlength, dburst_wlength = 0;
251
252     //cal burst length
253     if (data_width == DATA_WIDTH_16)
254     {
255         switch (burst_length)
256         {
257             case BURST_LEN_1:
258             case BURST_LEN_2:
259                 dburst_rlength = BURST_LEN_1;
260                 dburst_wlength = BURST_LEN_1;
261                 break;
262             case BURST_LEN_4:
263                 dburst_rlength = BURST_LEN_2;
264                 dburst_wlength = BURST_LEN_2;
265                 break;
266             case BURST_LEN_8:
267                 dburst_rlength = BURST_LEN_4;
268                 dburst_wlength = BURST_LEN_4;
269                 break;
270             default:
271                 dburst_rlength = BURST_LEN_1;
272                 dburst_wlength = BURST_LEN_1;
273                 break;
274         }
275     }
276     else if (data_width == DATA_WIDTH_32)
277     {
278         switch (burst_length)
279         {
280             case BURST_LEN_1:
281                 dburst_rlength = BURST_LEN_1;
282                 dburst_wlength = BURST_LEN_1;
283                 break;
284             case BURST_LEN_2:
285                 dburst_rlength = BURST_LEN_2;
286                 dburst_wlength = BURST_LEN_2;
287                 break;
288             case BURST_LEN_4:
289                 dburst_rlength = BURST_LEN_4;
290                 dburst_wlength = BURST_LEN_4;
291                 break;
292             case BURST_LEN_8:
293                 dburst_rlength = BURST_LEN_8;
294                 dburst_wlength = BURST_LEN_8;
295                 break;
296             default:
297                 dburst_rlength = BURST_LEN_1;
298                 dburst_wlength = BURST_LEN_1;
299                 break;
300         }
301     }
302     else
303     {
304         for (;;){}
305     }
306     REG32 (EXT_MEM_CFG0) = (BIT_0|BIT_1|BIT_3|BIT_6|BIT_8|BIT_9|BIT_10|BIT_11); //software address mapping
307
308 #ifdef CHIP_ENDIAN_BIG
309     REG32 (EXT_MEM_CFG0) |= BIT_12; /*lint !e718*/ //big endian
310 #endif
311
312     //set dmem parameter
313     /*lint -save -e506 -e774*/
314     if ( (SDR_SDRAM == sdram_cfg_ptr->sdram_type))
315     {
316         REG32 (EXT_MEM_CFG1) = 0x00000008; //EMC phy set
317     }
318     else if (DDR_SDRAM == sdram_cfg_ptr->sdram_type)
319     {
320         REG32 (EXT_MEM_CFG0) |= (BIT_5);   // ddr select
321         REG32 (EXT_MEM_CFG1) = 0x01080000; //EMC phy set
322     }
323     else
324     {
325         for (;;){}
326     }
327
328     REG32 (EXT_MEM_CFG0_CS0) = ( (0x1<<12) | (dburst_wlength<<8) | (dburst_rlength<<4) | (0x3)); 
329
330     //config channel 0-15
331     REG32 (EXT_MEM_CFG0_CH0)  = 0x0003c31c;//0x0001c31c;
332     REG32 (EXT_MEM_CFG0_CH1)  = 0x0003c31c;
333     REG32 (EXT_MEM_CFG0_CH2)  = 0x0003c31c;
334     REG32 (EXT_MEM_CFG0_CH3)  = 0x0003c31c;
335     REG32 (EXT_MEM_CFG0_CH4)  = 0x0003c31c;
336     REG32 (EXT_MEM_CFG0_CH5)  = 0x0003c31c;
337
338 #if defined(PLATFORM_SC8800G)
339     REG32 (EXT_MEM_CFG0_CH6)  = 0x0001c31c; //for sc8800g emc sleep bug.
340     REG32 (EXT_MEM_CFG0_CH7)  = 0x0001c31c;
341     REG32 (EXT_MEM_CFG0_CH8)  = 0x0001c31c;
342 #endif
343 }
344
345 /**---------------------------------------------------------------------------*
346  ** FUNCTION                                                                  *
347  **     void SDRAM_DMemCtlCfg(uint32 sdram_clk,SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)  *
348  **                                                                           *
349  ** DESCRIPTION                                                               *
350  **     set emc dmem mode,timing parameters                                   *
351  **                                                                           *
352  ** INPUT                                                                     *
353  **     sdram_clk,sdram_cfg_ptr                                               *
354  **                                                                           *
355  ** OUTPUT                                                                    *
356  **     None                                                                  *
357  **                                                                           *
358  ** RETURN VALUE                                                              *
359  **                                                                           *
360  ** DEPENDENCIES                                                              *
361  **                                                                           *
362 **---------------------------------------------------------------------------*/
363 LOCAL void SDRAM_DMemCtlCfg (uint32 sdram_clk,SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
364 {
365     //initialize dmem mode parameters
366     uint32 row_mode       = sdram_cfg_ptr->row_mode;
367     uint32 col_mode       = sdram_cfg_ptr->col_mode;
368     uint32 data_width     = sdram_cfg_ptr->data_width;
369     uint32 cas_latency    = sdram_cfg_ptr->cas_latency;
370     uint32 sdram_cycle_ns = 1000/ (sdram_clk/1000000);
371     uint32 row_num;
372     
373     uint32 t_ras = (sdram_parameters->ras_min/sdram_cycle_ns+1)>0xF ? 0xF : (sdram_parameters->ras_min/sdram_cycle_ns+1);
374     uint32 t_xsr = (sdram_parameters->xsr_min/sdram_cycle_ns)>0xF ? 0xF : (sdram_parameters->xsr_min/sdram_cycle_ns);
375     uint32 t_rfc = (sdram_parameters->rfc_min/sdram_cycle_ns)>0xF ? 0xF : (sdram_parameters->rfc_min/sdram_cycle_ns);
376     uint32 t_wr  = sdram_parameters->wr_min/sdram_cycle_ns+2; //note: twr should add 2 for ddr
377     uint32 t_rcd = (sdram_parameters->rcd_min/sdram_cycle_ns)>3 ? 3:(sdram_parameters->rcd_min/sdram_cycle_ns);
378     uint32 t_rp  = (sdram_parameters->row_pre_min/sdram_cycle_ns)>3 ? 3:(sdram_parameters->row_pre_min/sdram_cycle_ns);
379     uint32 t_rrd = (sdram_parameters->rrd_min/sdram_cycle_ns) >3 ? 3:(sdram_parameters->rrd_min/sdram_cycle_ns);
380     uint32 t_mrd = (sdram_parameters->mrd_min) > 3 ? 3:(sdram_parameters->mrd_min);
381     uint32 t_wtr = sdram_parameters->wtr_min;
382     uint32 t_ref;
383     uint32 t_rtw = sdram_cfg_ptr->cas_latency;
384
385     switch(row_mode)
386     {
387     case ROW_MODE_14:
388         row_num = 14;
389         break;
390     case ROW_MODE_13:
391         row_num = 13;
392         break;
393     case ROW_MODE_12:
394         row_num = 12;
395         break;
396     case ROW_MODE_11:
397         row_num = 11;
398         break;
399     default:
400         for (;;){}
401     }
402     
403     t_ref = ((sdram_parameters->row_ref_max*6000)>>row_num) - 1; // t_ref*(1/6.5MHz)*2^row <= tREF
404
405     //set data width mode
406     if (data_width == DATA_WIDTH_32)
407     {
408         REG32 (EXT_MEM_DCFG0) = 0x0000BF00;
409     }
410     else
411     {
412         REG32 (EXT_MEM_DCFG0) = 0x0000BE00;
413     }
414         
415     //set row mode
416     REG32 (EXT_MEM_DCFG0) |= row_mode;/*lint !e737*/
417
418     //set column mode
419     REG32 (EXT_MEM_DCFG0) |= (col_mode<<4);/*lint !e737*/
420
421     //set precharge bit
422     REG32 (EXT_MEM_DCFG0) &= ~ (BIT_2|BIT_3); //A[10]
423
424     //set t_rfc and t_ref
425     REG32 (EXT_MEM_DCFG0) |= ( (t_rfc<<16) | (t_ref<<20)); /*lint !e737*/
426     
427     REG32(EXT_MEM_DCFG1) = (    (t_rp <<0) |       
428                                 (t_rcd<<2) |        
429                                 (t_rrd<<4) |        
430                                 (t_wr <<8) |        
431                                 (t_xsr<<12)|        
432                                 (t_ras<<16)|        
433                                 (t_rtw<<20)|
434                                 (t_mrd<<30)         
435                             );
436     
437     if (SDR_SDRAM == sdram_cfg_ptr->sdram_type)
438     {
439         //read data and write data timing
440         if (cas_latency == 3)
441         {
442             REG32 (EXT_MEM_DCFG4) = 0x00600208;
443             REG32 (EXT_MEM_DCFG7) = 0x00400001;
444         }
445         else if (cas_latency == 2)
446         {
447             REG32 (EXT_MEM_DCFG4) = 0x00400006;
448             REG32 (EXT_MEM_DCFG7) = 0x00100001;
449         }
450         else
451         {
452             for (;;){}
453         }
454         
455         //config delay lines.
456         REG32 (EXT_MEM_DL24) = 0x2;
457         REG32 (EXT_MEM_DL25) = 0x2;
458         REG32 (EXT_MEM_DL26) = 0x2;
459         REG32 (EXT_MEM_DL27) = 0x2;
460     }
461     else if (DDR_SDRAM == sdram_cfg_ptr->sdram_type)
462     {
463         // wtr is only for ddr
464         REG32(EXT_MEM_DCFG1) |= (t_wtr<<24);
465         
466         //read data and write data timing
467         if (cas_latency == 3)
468         {
469             REG32 (EXT_MEM_DCFG4) = 0x00622729;
470             REG32 (EXT_MEM_DCFG5) = 0x00200010;
471             REG32 (EXT_MEM_DCFG6) = 0x00F0000E;
472             REG32 (EXT_MEM_DCFG7) = 0x00F0000E;
473         }
474         else if (cas_latency == 2)
475         {
476             REG32 (EXT_MEM_DCFG4) = 0x00422726;
477             REG32 (EXT_MEM_DCFG5) = 0x00080004;
478             REG32 (EXT_MEM_DCFG6) = 0x003C000E;
479             REG32 (EXT_MEM_DCFG7) = 0x003C000E;
480         }
481         else
482         {
483             for (;;){}
484         }
485
486         //config delay lines.
487         REG32 (EXT_MEM_DL7)  = 0x6;
488         REG32 (EXT_MEM_DL16) = 0x3;
489         REG32 (EXT_MEM_DL17) = 0x3;
490         REG32 (EXT_MEM_DL18) = 0x3;
491         REG32 (EXT_MEM_DL19) = 0x3;
492         REG32 (EXT_MEM_DL20) = 0x3;
493         REG32 (EXT_MEM_DL21) = 0x3;
494         REG32 (EXT_MEM_DL22) = 0x3;
495         REG32 (EXT_MEM_DL23) = 0x3;
496         REG32 (EXT_MEM_DL24) = 0x7;
497         REG32 (EXT_MEM_DL25) = 0x7;
498         REG32 (EXT_MEM_DL26) = 0x7;
499         REG32 (EXT_MEM_DL27) = 0x7;
500     }
501     else
502     {
503         for (;;){}
504     }
505
506     return;
507 }
508
509 /**---------------------------------------------------------------------------*
510  ** FUNCTION                                                                  *
511  **     void SDRAM_Device_Init(SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)            *
512  **                                                                           *
513  ** DESCRIPTION                                                               *
514  **     set emc dmem mode/ext mode register parameters                        *
515  **                                                                           *
516  ** INPUT                                                                     *
517  **     sdram_cfg_ptr                                                         *
518  **                                                                           *
519  ** OUTPUT                                                                    *
520  **     None                                                                  *
521  **                                                                           *
522  ** RETURN VALUE                                                              *
523  **                                                                           *
524  ** DEPENDENCIES                                                              *
525  **                                                                           *
526 **---------------------------------------------------------------------------*/
527 LOCAL void SDRAM_Device_Init (SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
528 {
529     uint8 mode_reg_bl = 0xFF;
530     uint8 mode_reg_bt = MODE_REG_BT_SEQ;
531     uint8 mode_reg_cl = 0xFF;
532     uint8 mode_reg_opmode = MODE_REG_OPMODE;
533     uint32 ex_mode_reg = 0;
534     uint16 mode_reg = 0;
535
536     //calculate mode reg burst length
537     switch (sdram_cfg_ptr->burst_length)
538     {
539         case BURST_LEN_1:
540             mode_reg_bl = MODE_REG_BL_1;
541             break;
542         case BURST_LEN_2:
543             mode_reg_bl = MODE_REG_BL_2;
544             break;
545         case BURST_LEN_4:
546             mode_reg_bl = MODE_REG_BL_4;
547             break;
548         case BURST_LEN_8:
549             mode_reg_bl = MODE_REG_BL_8;
550             break;
551         default:
552             mode_reg_bl = MODE_REG_BL_1;
553             break;
554     }
555
556     //calculate mode reg cas latency
557     switch (sdram_cfg_ptr->cas_latency)
558     {
559         case CAS_LATENCY_1:
560             mode_reg_cl = MODE_REG_CL_1;
561             break;
562         case CAS_LATENCY_2:
563             mode_reg_cl = MODE_REG_CL_2;
564             break;
565         case CAS_LATENCY_3:
566             mode_reg_cl = MODE_REG_CL_3;
567             break;
568         default:
569             mode_reg_cl = MODE_REG_CL_3;
570             break;
571     }
572
573     //get mode reg parameter
574     mode_reg = ( (mode_reg_opmode<<9) | (mode_reg_cl<<4) | (mode_reg_bt<<3) | mode_reg_bl);
575
576     //get ext-mode reg parameter
577     ex_mode_reg = sdram_cfg_ptr->ext_mode_val;
578
579     // Precharge all banks.
580     REG32 (EXT_MEM_DCFG3) = 0x40010000;
581
582     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_16){}
583
584     //Auto_ref
585     REG32 (EXT_MEM_DCFG3) = 0x40020000;
586
587     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_17){}
588
589     //Auto_ref
590     REG32 (EXT_MEM_DCFG3) = 0x40020000;
591
592     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_17){}
593
594     //mode register load.
595     REG32 (EXT_MEM_DCFG3) &= ~ (0xFFFF);
596     REG32 (EXT_MEM_DCFG3) |= (mode_reg | 0x40040000);
597
598     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_18){}
599
600     //extended mode register load.
601     if (ex_mode_reg != SDRAM_EXT_MODE_INVALID)
602     {
603         REG32 (EXT_MEM_DCFG3) &= ~ (0xFFFF);
604         REG32 (EXT_MEM_DCFG3) |= (ex_mode_reg | 0x40040000);/*lint !e737*/
605
606         while ( (REG32 (EXT_MEM_DCFG3)) & BIT_18){}
607     }
608     
609 }
610
611 LOCAL void __sdram_set_param(uint32 clk, SDRAM_CFG_INFO_T_PTR pCfg)
612 {
613     volatile uint32 i;
614     
615     //step 1. Disable auto refresh.
616     REG32 (EXT_MEM_DCFG0) &= ~ BIT_14;
617
618     //step 2. sdram init: config registers, precharege all banks, auto ref for 2 times, load mode register.
619     SDRAM_GenMemCtlCfg (pCfg);
620     SDRAM_DMemCtlCfg (clk,pCfg);
621     SDRAM_Device_Init (pCfg);
622
623     //step3. enable auto refresh.
624     REG32 (EXT_MEM_DCFG2) |= BIT_15; //clear refresh count.
625     REG32 (EXT_MEM_DCFG0) |= BIT_14; //Enable auto refresh.
626    
627     for (i=0; i<1000; i++){}
628 }
629 #ifdef SDRAM_AUTODETECT_SUPPORT
630 LOCAL uint32 __colum_to_mode(uint32 colum)
631 {
632     uint32 col_mode;
633     switch(colum)
634     {
635         case 8:
636             col_mode = COL_MODE_8;
637             break;
638         case 9:
639             col_mode = COL_MODE_9;
640             break;
641         case 10:
642             col_mode = COL_MODE_10;
643             break;
644         case 11:
645             col_mode = COL_MODE_11;
646             break;
647         case 12:
648             col_mode = COL_MODE_12;
649             break;
650         default:
651             for( ; ; ) {}
652             //break;          
653     }
654     return col_mode;
655 }
656 LOCAL uint32 __row_to_mode(uint32 row)
657 {
658     uint32 row_mode;
659     switch(row)
660     {
661         case 11:
662             row_mode = ROW_MODE_11;
663             break;
664         case 12:
665             row_mode = ROW_MODE_12;
666             break;
667         case 13:
668             row_mode = ROW_MODE_13;
669             break;
670         case 14:
671             row_mode = ROW_MODE_14;
672             break;
673         default:
674             for( ; ; ) {}
675             //break;          
676     }
677     return row_mode;
678 }
679
680 LOCAL BOOLEAN __is_rw_ok(uint32 addr, uint32 val)
681 {
682     volatile uint32 i;
683     
684     REG32(addr) = val;
685     REG32(addr+4) = (~val);
686     
687     for(i=0;i<0xff;i++) {}
688
689     if((REG32(addr) == val) && (REG32(addr+4) == (~val)))
690         return ((BOOLEAN)SCI_TRUE);
691     else
692         return ((BOOLEAN)SCI_FALSE);
693     //return ((val == REG32(addr))? ((BOOLEAN)SCI_TRUE) : ((BOOLEAN)SCI_FALSE));
694 }
695
696 // ADDR: |-BANK -|------------ COLUM 12 ---------------|
697 //       |A13|A12|A11|A10|A9|A8|A7|A6|A5|A4|A3|A2|A1|A0|
698 //
699 //       |------------------- ROW 14-------------------|   
700 //       |A13|A12|A11|A10|A9|A8|A7|A6|A5|A4|A3|A2|A1|A0|
701 LOCAL uint32 __col_row_detect(BOOLEAN is_col, SDRAM_CFG_INFO_T_PTR pCfg)
702 {
703     uint32 num, max, min;
704     uint32 offset, addr;
705     uint32 width_offset = (DATA_WIDTH_16 == pCfg->data_width)?(WIDTH16_OFFSET):(WIDTH32_OFFSET);
706
707     if(is_col)
708     {
709         max = SDRAM_MAX_COLUM;
710         min = SDRAM_MIN_COLUM;
711     }
712     else
713     {
714         max = SDRAM_MAX_ROW;
715         min = SDRAM_MIN_ROW;
716     }
717     for(num = max; num >= min; num--)
718     {
719         // init 0 address
720         REG32(ZERO_ADDR) = MEM_REF_DATA0;               /*lint !e413*/
721
722         if(is_col)
723         {
724             offset = num + width_offset - BYTE_OFFSET;    // colum+width-byteoff
725         }
726         else
727         {
728             offset = num + BANK_OFFSET + (uint32)s_colum +  width_offset -  BYTE_OFFSET;    // row+bank+colum+width-byteoff
729         }
730         addr   = (1 << (offset - 1)) + ZERO_ADDR;
731         if(__is_rw_ok(addr, MEM_REF_DATA1))
732         {
733             // if 0addr not changed, row is ok
734             if(MEM_REF_DATA0 == REG32(ZERO_ADDR))       /*lint !e413*/
735             {
736                 break;
737             }
738             // 0addr changed, row is too big
739             else if(MEM_REF_DATA1 == REG32(ZERO_ADDR))  /*lint !e413*/
740             {
741                 continue;
742             }
743         }
744     }
745
746     return (num); 
747 }
748
749 LOCAL void __sdram_detect(uint32 clk)
750 {
751     SDRAM_CFG_INFO_T_PTR pCfg = &s_sdram_raw_cfg;
752     uint32 state = STATE_SDRAM_TYPE;
753     uint32 colum, row;
754
755     pCfg->bank_mode    = BK_MODE_4;
756     pCfg->row_mode     = ROW_MODE_14;
757     pCfg->col_mode     = COL_MODE_12;
758     pCfg->data_width   = DATA_WIDTH_16;
759     pCfg->burst_length = BURST_LEN_2;
760     pCfg->cas_latency  = CAS_LATENCY_3;
761     pCfg->ext_mode_val = SDRAM_EXT_MODE_REG;
762     pCfg->sdram_type   = SDR_SDRAM;
763         
764     while(STATE_END != state)
765     {
766         __sdram_set_param(clk, pCfg);
767         switch(state)
768         {
769         case STATE_SDRAM_TYPE:
770             if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0))           // 16bit sdr/ddr detect ok, try 32bit
771             {
772                 pCfg->data_width = DATA_WIDTH_32;
773                 state = STATE_BIT_WIDTH;
774                 //break;
775             }
776             else                        // 16bit sdr failed, try 16bit ddr
777             {
778                 if(DDR_SDRAM == pCfg->sdram_type)   
779                 {
780                     for( ; ; ) {}          // all failed
781                 }
782                 pCfg->sdram_type = DDR_SDRAM;
783                 state = STATE_SDRAM_TYPE;
784                 //break;
785             }
786             break;
787         case STATE_BIT_WIDTH:
788             if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0))           // 32bit sdr/ddr detect ok, try colum
789             {
790                 state = STATE_COLUM;
791                 //break;
792             }
793             else                        // 32bit sdr/ddr detect failed, fix 16bit and try colum
794             {
795                 pCfg->data_width = DATA_WIDTH_16;
796                 state = STATE_COLUM;
797                 //break;
798             }
799             break;
800         case STATE_COLUM:
801             if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0))           
802             {
803                 colum = __col_row_detect(SCI_TRUE, pCfg);
804                 pCfg->col_mode = __colum_to_mode(colum);
805                 s_colum = colum;//lint !e63
806                 state = STATE_ROW;
807                 //break;
808             }
809             else                        
810             {
811                 for( ; ; ) {}           // should not come here
812             }
813             break;
814         case STATE_ROW:
815             row = __col_row_detect(SCI_FALSE, pCfg);
816             pCfg->row_mode = __row_to_mode(row);
817             state = STATE_REINIT;
818             break;
819         case STATE_REINIT:
820             state = STATE_END;  
821             break;
822         default:
823             break;
824         }
825     }
826 }
827 #endif
828 /**---------------------------------------------------------------------------*
829  ** FUNCTION                                                                  *
830  **     void SDRAM_Init(uint32 sdram_clk)                                     *
831  **                                                                           *
832  ** DESCRIPTION                                                               *
833  **     initialize emc sdram module                                           *
834  **                                                                           *
835  ** INPUT                                                                     *
836  **     sdram_clk                                                             *
837  **                                                                           *
838  ** OUTPUT                                                                    *
839  **     None                                                                  *
840  **                                                                           *
841  ** RETURN VALUE                                                              *
842  **                                                                           *
843  ** DEPENDENCIES                                                              *
844  **                                                                           *
845 **---------------------------------------------------------------------------*/
846 LOCAL void SDRAM_Init (uint32 clk)
847 {
848     sdram_parameters = SDRAM_GetTimingPara();
849
850     #ifdef SDRAM_AUTODETECT_SUPPORT
851     __sdram_detect(clk);
852     #else
853     __sdram_set_param(clk, SDRAM_GetCfg());
854     #endif
855
856 #if 1
857     //ANA_REG_MSK_OR(ANA_DCDC_CTL, 4 << 6, 7 << 6);
858     ANA_REG_MSK_OR(ANA_DCDC_CTL, 0x1c << 6, 0x3f << 6);
859     {
860          /* wait until voltage is stable */
861         volatile int32 i;
862          for (i=0; i<3000; ++i)
863          {
864          }
865     }           
866
867     *(volatile uint32 *)(GREG_BASE + 0x18) |= BIT_9;
868     {
869         uint32 tmp = *(volatile uint32 *)(GREG_BASE + 0x24);
870          tmp &= ~0x00000fff;
871          //tmp |= 0xe1; // 450M
872          //tmp |= 0x12c; // 600M
873          tmp |= 0x113; // 550M
874          //tmp |= 0xfa; // 500M
875          //tmp |= 0x104; // 520M
876          //tmp |= 0x145; // 650M
877          *(volatile uint32 *)(GREG_BASE + 0x24) = tmp;
878     }
879     *(volatile uint32 *)(GREG_BASE + 0x18) &= ~BIT_9;   
880 #endif
881
882 }
883
884
885 /**---------------------------------------------------------------------------*
886  ** FUNCTION                                                                  *
887  **     void SDRAM_PinDrv_Set(void)                                           *
888  **                                                                           *
889  ** DESCRIPTION                                                               *
890  **     initialize emc pins                                                   *
891  **                                                                           *
892  ** INPUT                                                                     *
893  **     none                                                                  *
894  **                                                                           *
895  ** OUTPUT                                                                    *
896  **     None                                                                  *
897  **                                                                           *
898  ** RETURN VALUE                                                              *
899  **                                                                           *
900  ** DEPENDENCIES                                                              *
901  **                                                                           *
902 **---------------------------------------------------------------------------*/
903 LOCAL void SDRAM_PinDrv_Set (void)
904 {
905 #if defined(PLATFORM_SC8800G)
906         uint32 i = 0;
907         uint32 clk_drv = 0x200;
908         uint32 ctl_drv = 0x100;
909         uint32 dat_drv = 0x100;
910         
911         REG32(PIN_CTL_REG) = 0X1FFF00; //set nf_rb keyin[0-7] wpus
912
913         REG32(PINMAP_REG_BASE + 0X27c) = clk_drv;       
914         REG32(PINMAP_REG_BASE + 0X280) = clk_drv;               
915         
916         for(i = 0; i<15; i++)
917         {
918                 REG32(PINMAP_REG_BASE + 0x019c + i*4) = ctl_drv;
919         }
920         
921         REG32(PINMAP_REG_BASE + 0X1d8) = ctl_drv;
922         REG32(PINMAP_REG_BASE + 0X2a8) = ctl_drv;                               
923         REG32(PINMAP_REG_BASE + 0X1FC) = ctl_drv;
924         REG32(PINMAP_REG_BASE + 0X200) = ctl_drv;
925         REG32(PINMAP_REG_BASE + 0X224) = ctl_drv;
926         REG32(PINMAP_REG_BASE + 0X228) = ctl_drv;
927         REG32(PINMAP_REG_BASE + 0X24c) = ctl_drv;       
928         REG32(PINMAP_REG_BASE + 0X250) = ctl_drv;               
929         REG32(PINMAP_REG_BASE + 0X274) = ctl_drv;               
930         REG32(PINMAP_REG_BASE + 0X278) = ctl_drv;               
931
932         for(i = 0; i<9; i++)
933                 REG32(PINMAP_REG_BASE + 0x0284 + i*4) = ctl_drv;
934         
935
936         for(i = 0; i<8; i++)
937         {       
938                 REG32(PINMAP_REG_BASE + 0x1DC + i*4) = dat_drv;
939                 REG32(PINMAP_REG_BASE + 0x204 + i*4) = dat_drv;
940                 REG32(PINMAP_REG_BASE + 0x22c + i*4) = dat_drv;
941                 REG32(PINMAP_REG_BASE + 0x254 + i*4) = dat_drv;
942         }       
943
944 #endif
945 }
946
947
948 /**---------------------------------------------------------------------------*
949  ** FUNCTION                                                                  *
950  **     void Chip_ConfigClk(void)                                             *
951  **                                                                           *
952  ** DESCRIPTION                                                               *
953  **     set pll, arm clock,ahb clock,emc clock                                *
954  **                                                                           *
955  ** INPUT                                                                     *
956  **     p_system_clk_cfg                                                      *
957  **                                                                           *
958  ** OUTPUT                                                                    *
959  **     None                                                                  *
960  **                                                                           *
961  ** RETURN VALUE                                                              *
962  **                                                                           *
963  ** DEPENDENCIES                                                              *
964  **                                                                           *
965 **---------------------------------------------------------------------------*/
966 LOCAL uint32 Chip_ConfigClk (void)
967 {
968     volatile uint32 i,arm_ahb_clk;
969
970 #if defined(PLATFORM_SC6800H)
971 #ifdef _BL_NF_NBL_
972
973     //support dual pll, mpll 400mhz, bpll 480mhz
974     {
975         volatile uint32 is_pll_done = 0;
976
977         //clear the protect control
978         CHIP_REG_SET(GR_MCU_PORT, PLL_MCU_PROT_VALUE);
979
980         //disable pll
981         CHIP_REG_AND(GR_MISC1, ~ MISC1_MCU_PLL_EN);
982
983         //set mpll to 400MHz
984         CHIP_REG_SET(GR_MPLL_MN, MPLL_MN_400M);
985         //clk_48M source select to bpll
986         CHIP_REG_OR(AHB_CLK_CFG1, AHB_CLK_CFG1_SRCSEL48M);
987
988         //open bpll
989         CHIP_REG_AND(GR_MISC1, ~MISC1_MCU_BPLL_FORCE_PD_EN);
990         //select bpll controlled by hw and release bpll output
991         CHIP_REG_OR(GR_MISC1, (MISC1_BPLL_SEL|MISC1_BPLL_CONT_DONE));
992
993         //enable pll
994         CHIP_REG_OR (GR_MISC1, MISC1_MCU_PLL_EN);
995
996         //wait pll count done
997         is_pll_done = CHIP_REG_GET(GR_STATUS) & ((uint32) APB_STATUS_PLL_CNT_DONE);
998
999         while (0 == is_pll_done)
1000         {
1001             is_pll_done = CHIP_REG_GET(GR_STATUS) & ((uint32) APB_STATUS_PLL_CNT_DONE);
1002         }
1003
1004         //set the protect control
1005         CHIP_REG_SET(GR_MCU_PORT, 0);
1006     }
1007 #endif
1008
1009     arm_ahb_clk = ARM_CLK_100M;
1010     //MPLL is open already in RomCode
1011     i = REG32 (AHB_CLK_CFG0);
1012     //set CLK_EMC to 192MHz
1013     i &= ~ (BIT_7 | BIT_6 | BIT_5 | BIT_4);
1014     i |= 0xC << 4;               //Src_sel_emc:4'b1100 : MPLL_DIV2:
1015     i &= ~ (BIT_9 | BIT_8);      //Div_cfg_emc:0x0
1016     //set CLK_ARM to 192MHz
1017     i &= ~ (BIT_2 | BIT_1);      //Div_cfg_arm:0x01
1018     //set CLK_AHB to 96MHz
1019     i |= BIT_3;
1020     //set Src_sel_arm to  MPLL/2(192Mhz)
1021     i |= BIT_0;
1022     REG32 (AHB_CLK_CFG0) = i;
1023
1024     for (i=0; i<100; i++){}
1025
1026 #elif defined(PLATFORM_SC8800G)
1027     __ClkConfig(&g_emc_clk, (uint32*)&arm_ahb_clk);
1028 #endif
1029
1030     //Delay some time
1031     for (i=0; i<1000; i++) {}
1032
1033     return arm_ahb_clk;
1034 }
1035
1036
1037 /**---------------------------------------------------------------------------*
1038  ** FUNCTION                                                                  *
1039  **     void Chip_Init(void)                                                  *
1040  **                                                                           *
1041  ** DESCRIPTION                                                               *
1042  **     initialize chip setting                                               *
1043  **                                                                           *
1044  ** INPUT                                                                     *
1045  **     none                                                                  *
1046  **                                                                           *
1047  ** OUTPUT                                                                    *
1048  **     None                                                                  *
1049  **                                                                           *
1050  ** RETURN VALUE                                                              *
1051  **                                                                           *
1052  ** DEPENDENCIES                                                              *
1053  **                                                                           *
1054 **---------------------------------------------------------------------------*/
1055 PUBLIC void Chip_Init (void) /*lint !e765 "Chip_Init" is used by init.s entry.s*/
1056 {
1057     volatile uint32 i = 0;
1058
1059     //step1, SDRAM pin set up
1060     SDRAM_PinDrv_Set();
1061
1062     //step2, config AHB CLK and PLL clk
1063     g_ahb_clk = Chip_ConfigClk();
1064
1065     //step3, initialize SDRAM init
1066     #ifdef PLATFORM_SC8800G
1067     SDRAM_Init (g_emc_clk/2);
1068     #else
1069     SDRAM_Init (g_ahb_clk);
1070     #endif
1071
1072     for (i=0; i<5000; i++) {}
1073 }