tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8810 / 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 #include <asm/arch/adi_hal_internal.h>
21 #include <asm/arch/regs_ana.h>
22 #include <asm/arch/regs_ahb.h>
23 EMC_PARAM_T s_emc_config = {0};
24
25 /*lint -e760 -e547 ,because pclint error e63 e26 with REG32()*/
26 #define REG32(x)   (*((volatile uint32 *)(x)))
27 #define REG8(x)   (*((volatile uint8 *)(x)))
28 /*lint +e760 +e547 ,because pclint error e63 e26 with REG32()*/
29
30 /*lint -e765*/
31
32 #define  SDRAM_EXT_INVALID     0xffffffff       //@David.Jia 2008.1.7
33 #define  ROW_MODE_TO_NUM(_m)    (_m+11)
34
35 #if defined(PLATFORM_SC8800G) || defined(CONFIG_SC8810)
36 uint32 g_emc_clk;
37 uint32 s_colum;
38 #endif //defined(PLATFORM_SC8800G) && defined(CHIP_VER_8800G2)
39
40 uint32 g_ahb_clk; 
41 SDRAM_TIMING_PARA_T_PTR sdram_parameters;
42
43 #if defined(PLATFORM_SC8800G) || defined(CONFIG_SC8810)
44 #define SDRAM_AUTODETECT_SUPPORT
45 #endif
46 #define _BL_NF_NBL_
47
48 #ifdef SDRAM_AUTODETECT_SUPPORT
49 #define MEM_REF_DATA0       0x12345678
50 #define MEM_REF_DATA1       0x55AA9889
51 #ifdef CHIP_VER_8810
52 #define ZERO_ADDR           0x00000000UL
53 #else
54 #ifdef _BL_NF_NBL_
55 #define ZERO_ADDR           0x00000000UL
56 #else
57 #define ZERO_ADDR           0x30000000UL
58 #endif
59 #endif
60 #define STATE_SDRAM_TYPE    0UL
61 #define STATE_BIT_WIDTH     1UL
62 #define STATE_COLUM         2UL
63 #define STATE_ROW           3UL
64 #define STATE_REINIT        4UL
65 #define STATE_END           5UL
66
67 #define BYTE_OFFSET         3UL   // 1BYTE = 8BIT = 2^3
68 #define WIDTH16_OFFSET      4UL   // 16BIT = 2^4
69 #define WIDTH32_OFFSET      5UL   // 32BIT = 2^5
70 #define BANK_OFFSET         2UL   // 4BANK = 2^2
71
72 #define SDRAM_MIN_COLUM     8UL
73 #define SDRAM_MAX_COLUM     12UL
74 #define SDRAM_MIN_ROW       11UL
75 #define SDRAM_MAX_ROW       14UL
76
77 SDRAM_CFG_INFO_T s_sdram_raw_cfg;
78 #endif
79
80 #ifdef PLATFORM_SC8800G
81 #define INTERFACE_CLK_MAX   ARM_CLK_200M
82 typedef struct ARM_EMC_AHB_CLK_TAG 
83 {
84     uint32 mcu_clk;
85     uint32 arm_clk;
86     uint32 emc_clk;
87     uint32 ahb_clk;
88 } ARM_EMC_AHB_CLK_T;
89
90 typedef enum MCU_CLK_TYPE_TAG
91 {
92     ARM400_EMC200_AHB100 = 0,   //SC8800G2
93     ARM256_EMC200_AHB64,        //SC8801G2
94     ARM192_EMC200_AHB96,        //SC8802G2
95     ARM256_EMC192_AHB64,
96     ARM256_EMC128_AHB64,
97     ARM192_EMC192_AHB96,
98
99     MCU_CLK_TYPE_MAX   
100 } MCU_CLK_TYPE_E;
101
102 LOCAL CONST ARM_EMC_AHB_CLK_T s_arm_emc_ahb_clk[] = 
103 {
104 //     mcu_clk       arm_clk        emc_clk       ahb_clk
105     {ARM_CLK_400M, ARM_CLK_400M, ARM_CLK_200M, ARM_CLK_100M},   //SC8800G2
106     {ARM_CLK_256M, ARM_CLK_256M, ARM_CLK_200M, ARM_CLK_64M},    //SC8801G2
107     {ARM_CLK_192M, ARM_CLK_192M, ARM_CLK_200M, ARM_CLK_96M},    //SC8802G2
108     {ARM_CLK_512M, ARM_CLK_256M, ARM_CLK_192M, ARM_CLK_64M},
109     {ARM_CLK_512M, ARM_CLK_256M, ARM_CLK_128M, ARM_CLK_64M},
110     {ARM_CLK_384M, ARM_CLK_192M, ARM_CLK_192M, ARM_CLK_96M},
111 };
112
113 uint32 __GetMPllClk (void)
114 {
115     return ( ARM_CLK_26M
116                / ( (REG32(GR_MPLL_MN) & 0x003F0000) >>16)
117                * (REG32(GR_MPLL_MN) & 0x00000FFF) );
118 }
119
120 LOCAL void __SetMPllClk (uint32 clk)
121 {
122     uint32 M, N, tmp_mn;
123
124     M = 13; // M: fix to 13
125     N = clk/2/1000000;
126     
127     tmp_mn  = (REG32(GR_MPLL_MN) & (~0x3FFFFF));
128     tmp_mn |= (M << 16) | N;  
129               
130     REG32(GR_GEN1) |= BIT_9;        // MPLL Write En
131     REG32(GR_MPLL_MN) = tmp_mn;
132     REG32(GR_GEN1) &= ~BIT_9;       // MPLL Write Dis
133 }
134
135 LOCAL void __ClkConfig(uint32 *emcclk, uint32 *ahbclk)
136 {
137     uint32 tmp_clk, mcuclk, armclk;
138     uint32 mcu_div, if_div;
139     BOOLEAN is_mpll, is_async;
140     MCU_CLK_TYPE_E clk_type = ARM400_EMC200_AHB100;
141
142     ///*
143     switch(REG32(GR_GEN3) & 0x3)
144     {
145         case 0:
146                 clk_type = ARM400_EMC200_AHB100; // 8800G2
147                 break;
148         case 1:
149                 clk_type = ARM256_EMC200_AHB64;  // 8801G1
150                 break;
151         case 2:
152                 clk_type = ARM192_EMC200_AHB96;  // 8802G1 
153                 break;
154         default:
155                 clk_type =      ARM400_EMC200_AHB100;
156                 break;
157     }           
158     //*/         
159     
160     mcuclk   = s_arm_emc_ahb_clk[clk_type].mcu_clk;
161     armclk   = s_arm_emc_ahb_clk[clk_type].arm_clk;
162     *emcclk  = s_arm_emc_ahb_clk[clk_type].emc_clk;
163     *ahbclk  = s_arm_emc_ahb_clk[clk_type].ahb_clk;
164     
165     is_mpll  = (((0 == (REG32(GR_GEN3) & 0x3)) || (3 == (REG32(GR_GEN3) & 0x3))) ? (SCI_TRUE) : (SCI_FALSE));
166     is_async = ((0 == (armclk%(*emcclk)))     ? (SCI_FALSE) : (SCI_TRUE));  
167
168     mcu_div = 0;    
169     if(is_mpll)
170     {
171         if(__GetMPllClk() != mcuclk)
172         {
173             __SetMPllClk(mcuclk);
174         }
175         if(armclk != mcuclk)
176         {
177             mcu_div = 1;
178         }
179     }
180
181     if_div = 0;
182     if(armclk > INTERFACE_CLK_MAX)
183     {
184         if_div = 1;
185     }
186     
187     // step 1: config emc clk in dsp side in async mode
188     if(is_async) 
189     {
190         REG32(AHB_DSP_BOOT_EN)  |= BIT_2;
191         REG32(AHB_CTL1)         &= ~BIT_16;
192         REG32(0x10130010)       |= BIT_28;
193
194         REG32(0x1013000C)       |= (2<<10); //bit[11:10], DSP SIDE: 1:200M, 2:192M 3:26M
195         
196         REG32(0x10130010)       &= ~BIT_28;
197         REG32(AHB_CTL1)         |= BIT_16;
198         REG32(AHB_DSP_BOOT_EN)  &= ~BIT_2;
199     }
200     
201     // step 2: first config divider 
202     //         ifdiv / mcudiv /  ahbdiv
203     //         MCU_26M / sync_mode / emc-async-sel
204     tmp_clk = (BIT_23|BIT_24);
205     tmp_clk |= (if_div  << 31)  |   // bit[31],    interface-div
206                (mcu_div << 30)  |   // bit[30],    mcu-div
207                                     // bit[29:25], read only
208                                     // bit[24:23], mcu-sel, should config at step 2
209                                     // bit[22:17], reserved
210                (0 << 14)        |   // bit[16:14], emc-sync-div: 2^n
211                (1 << 12)        |   // bit[13:12], emc-async-sel: 0:reserved, 1:200M, 2:192M 3:26M
212                (0 << 8)         |   // bit[11:8],  emc-async-div: (n+1)
213                                     // bit[7],     ARM_384M_SEL:0
214                (1 << 4)         |   // bit[6:4],   ahb-div: (n+1)
215                (1 << 3)  ;          // bit[3],     emc sync:1, async:0
216                                     // bit[2:0],   arm-div, only for G1
217                
218     REG32(AHB_ARM_CLK) = tmp_clk;
219
220     // step 3: config mcu-sel 
221     tmp_clk &= ~(BIT_23|BIT_24); // mcu-sel: 26*N/M, this bit must be set after divider
222     REG32(AHB_ARM_CLK) = tmp_clk;
223
224     //step 4: switch to async mode at last
225     if(is_async)
226     {
227         tmp_clk &= ~BIT_3;
228         REG32(AHB_ARM_CLK) = tmp_clk;  
229     }
230
231     return;
232 }
233 #endif
234 #ifndef CONFIG_SC8810
235 /**---------------------------------------------------------------------------*
236  ** FUNCTION                                                                  *
237  **     void SDRAM_GenMemCtlCfg(SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)           *
238  **                                                                           *
239  ** DESCRIPTION                                                               *
240  **     set emc channel parameters                                            *
241  **                                                                           *
242  ** INPUT                                                                     *
243  **     sdram_cfg_ptr                                                         *
244  **                                                                           *
245  ** OUTPUT                                                                    *
246  **     None                                                                  *
247  **                                                                           *
248  ** RETURN VALUE                                                              *
249  **                                                                           *
250  ** DEPENDENCIES                                                              *
251  **                                                                           *
252 **---------------------------------------------------------------------------*/
253 LOCAL void SDRAM_GenMemCtlCfg (SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
254 {
255     uint32 burst_length = sdram_cfg_ptr->burst_length;
256     uint32 data_width   = sdram_cfg_ptr->data_width;
257     uint32 dburst_rlength, dburst_wlength = 0;
258
259     //cal burst length
260     if (data_width == DATA_WIDTH_16)
261     {
262         switch (burst_length)
263         {
264             case BURST_LEN_1:
265             case BURST_LEN_2:
266                 dburst_rlength = BURST_LEN_1;
267                 dburst_wlength = BURST_LEN_1;
268                 break;
269             case BURST_LEN_4:
270                 dburst_rlength = BURST_LEN_2;
271                 dburst_wlength = BURST_LEN_2;
272                 break;
273             case BURST_LEN_8:
274                 dburst_rlength = BURST_LEN_4;
275                 dburst_wlength = BURST_LEN_4;
276                 break;
277             default:
278                 dburst_rlength = BURST_LEN_1;
279                 dburst_wlength = BURST_LEN_1;
280                 break;
281         }
282     }
283     else if (data_width == DATA_WIDTH_32)
284     {
285         switch (burst_length)
286         {
287             case BURST_LEN_1:
288                 dburst_rlength = BURST_LEN_1;
289                 dburst_wlength = BURST_LEN_1;
290                 break;
291             case BURST_LEN_2:
292                 dburst_rlength = BURST_LEN_2;
293                 dburst_wlength = BURST_LEN_2;
294                 break;
295             case BURST_LEN_4:
296                 dburst_rlength = BURST_LEN_4;
297                 dburst_wlength = BURST_LEN_4;
298                 break;
299             case BURST_LEN_8:
300                 dburst_rlength = BURST_LEN_8;
301                 dburst_wlength = BURST_LEN_8;
302                 break;
303             default:
304                 dburst_rlength = BURST_LEN_1;
305                 dburst_wlength = BURST_LEN_1;
306                 break;
307         }
308     }
309     else
310     {
311         for (;;){}
312     }
313     REG32 (EXT_MEM_CFG0) = (BIT_0|BIT_1|BIT_3|BIT_6|BIT_8|BIT_9|BIT_10|BIT_11); //software address mapping
314
315 #ifdef CHIP_ENDIAN_BIG
316     REG32 (EXT_MEM_CFG0) |= BIT_12; /*lint !e718*/ //big endian
317 #endif
318
319     //set dmem parameter
320     /*lint -save -e506 -e774*/
321     if ( (SDR_SDRAM == sdram_cfg_ptr->sdram_type))
322     {
323         REG32 (EXT_MEM_CFG1) = 0x00000008; //EMC phy set
324     }
325     else if (DDR_SDRAM == sdram_cfg_ptr->sdram_type)
326     {
327         REG32 (EXT_MEM_CFG0) |= (BIT_5);   // ddr select
328         REG32 (EXT_MEM_CFG1) = 0x01080000; //EMC phy set
329     }
330     else
331     {
332         for (;;){}
333     }
334
335     REG32 (EXT_MEM_CFG0_CS0) = ( (0x1<<12) | (dburst_wlength<<8) | (dburst_rlength<<4) | (0x3)); 
336
337     //config channel 0-15
338     REG32 (EXT_MEM_CFG0_CH0)  = 0x0003c31c;//0x0001c31c;
339     REG32 (EXT_MEM_CFG0_CH1)  = 0x0003c31c;
340     REG32 (EXT_MEM_CFG0_CH2)  = 0x0003c31c;
341     REG32 (EXT_MEM_CFG0_CH3)  = 0x0003c31c;
342     REG32 (EXT_MEM_CFG0_CH4)  = 0x0003c31c;
343     REG32 (EXT_MEM_CFG0_CH5)  = 0x0003c31c;
344
345 #if defined(PLATFORM_SC8800G)
346     REG32 (EXT_MEM_CFG0_CH6)  = 0x0001c31c; //for sc8800g emc sleep bug.
347     REG32 (EXT_MEM_CFG0_CH7)  = 0x0001c31c;
348     REG32 (EXT_MEM_CFG0_CH8)  = 0x0001c31c;
349 #endif
350 }
351
352 /**---------------------------------------------------------------------------*
353  ** FUNCTION                                                                  *
354  **     void SDRAM_DMemCtlCfg(uint32 sdram_clk,SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)  *
355  **                                                                           *
356  ** DESCRIPTION                                                               *
357  **     set emc dmem mode,timing parameters                                   *
358  **                                                                           *
359  ** INPUT                                                                     *
360  **     sdram_clk,sdram_cfg_ptr                                               *
361  **                                                                           *
362  ** OUTPUT                                                                    *
363  **     None                                                                  *
364  **                                                                           *
365  ** RETURN VALUE                                                              *
366  **                                                                           *
367  ** DEPENDENCIES                                                              *
368  **                                                                           *
369 **---------------------------------------------------------------------------*/
370 LOCAL void SDRAM_DMemCtlCfg (uint32 sdram_clk,SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
371 {
372     //initialize dmem mode parameters
373     uint32 row_mode       = sdram_cfg_ptr->row_mode;
374     uint32 col_mode       = sdram_cfg_ptr->col_mode;
375     uint32 data_width     = sdram_cfg_ptr->data_width;
376     uint32 cas_latency    = sdram_cfg_ptr->cas_latency;
377     uint32 sdram_cycle_ns = 1000/ (sdram_clk/1000000);
378     uint32 row_num;
379     
380     uint32 t_ras = (sdram_parameters->ras_min/sdram_cycle_ns+1)>0xF ? 0xF : (sdram_parameters->ras_min/sdram_cycle_ns+1);
381     uint32 t_xsr = (sdram_parameters->xsr_min/sdram_cycle_ns)>0xF ? 0xF : (sdram_parameters->xsr_min/sdram_cycle_ns);
382     uint32 t_rfc = (sdram_parameters->rfc_min/sdram_cycle_ns)>0xF ? 0xF : (sdram_parameters->rfc_min/sdram_cycle_ns);
383     uint32 t_wr  = sdram_parameters->wr_min/sdram_cycle_ns+2; //note: twr should add 2 for ddr
384     uint32 t_rcd = (sdram_parameters->rcd_min/sdram_cycle_ns)>3 ? 3:(sdram_parameters->rcd_min/sdram_cycle_ns);
385     uint32 t_rp  = (sdram_parameters->row_pre_min/sdram_cycle_ns)>3 ? 3:(sdram_parameters->row_pre_min/sdram_cycle_ns);
386     uint32 t_rrd = (sdram_parameters->rrd_min/sdram_cycle_ns) >3 ? 3:(sdram_parameters->rrd_min/sdram_cycle_ns);
387     uint32 t_mrd = (sdram_parameters->mrd_min) > 3 ? 3:(sdram_parameters->mrd_min);
388     uint32 t_wtr = sdram_parameters->wtr_min;
389     uint32 t_ref;
390     uint32 t_rtw = sdram_cfg_ptr->cas_latency;
391
392     row_num = ROW_MODE_TO_NUM(row_mode);
393     t_ref = ((sdram_parameters->row_ref_max*6500)>>row_num) - 2; // t_ref*(1/6.5MHz)*2^row <= tREF
394
395     //set data width mode
396     if (data_width == DATA_WIDTH_32)
397     {
398         REG32 (EXT_MEM_DCFG0) = 0x0000BF00;
399     }
400     else
401     {
402         REG32 (EXT_MEM_DCFG0) = 0x0000BE00;
403     }
404         
405     //set row mode
406     REG32 (EXT_MEM_DCFG0) |= row_mode;/*lint !e737*/
407
408     //set column mode
409     REG32 (EXT_MEM_DCFG0) |= (col_mode<<4);/*lint !e737*/
410
411     //set precharge bit
412     REG32 (EXT_MEM_DCFG0) &= ~ (BIT_2|BIT_3); //A[10]
413
414     //set t_rfc and t_ref
415     REG32 (EXT_MEM_DCFG0) |= ( (t_rfc<<16) | (t_ref<<20)); /*lint !e737*/
416     
417     REG32(EXT_MEM_DCFG1) = (    (t_rp <<0) |       
418                                 (t_rcd<<2) |        
419                                 (t_rrd<<4) |        
420                                 (t_wr <<8) |        
421                                 (t_xsr<<12)|        
422                                 (t_ras<<16)|        
423                                 (t_rtw<<20)|
424                                 (t_mrd<<30)         
425                             );
426     
427     if (SDR_SDRAM == sdram_cfg_ptr->sdram_type)
428     {
429         //read data and write data timing
430         if (cas_latency == 3)
431         {
432             REG32 (EXT_MEM_DCFG4) = 0x00600208;
433             REG32 (EXT_MEM_DCFG7) = 0x00400001;
434         }
435         else if (cas_latency == 2)
436         {
437             REG32 (EXT_MEM_DCFG4) = 0x00400006;
438             REG32 (EXT_MEM_DCFG7) = 0x00100001;
439         }
440         else
441         {
442             for (;;){}
443         }
444         
445         //config delay lines.
446         REG32 (EXT_MEM_DL24) = 0x2;
447         REG32 (EXT_MEM_DL25) = 0x2;
448         REG32 (EXT_MEM_DL26) = 0x2;
449         REG32 (EXT_MEM_DL27) = 0x2;
450     }
451     else if (DDR_SDRAM == sdram_cfg_ptr->sdram_type)
452     {
453         // wtr is only for ddr
454         REG32(EXT_MEM_DCFG1) |= (t_wtr<<24);
455         
456         //read data and write data timing
457         if (cas_latency == 3)
458         {
459             REG32 (EXT_MEM_DCFG4) = 0x00622729;
460             REG32 (EXT_MEM_DCFG5) = 0x00200010;
461             REG32 (EXT_MEM_DCFG6) = 0x00F0000E;
462             REG32 (EXT_MEM_DCFG7) = 0x00F0000E;
463         }
464         else if (cas_latency == 2)
465         {
466             REG32 (EXT_MEM_DCFG4) = 0x00422726;
467             REG32 (EXT_MEM_DCFG5) = 0x00080004;
468             REG32 (EXT_MEM_DCFG6) = 0x003C000E;
469             REG32 (EXT_MEM_DCFG7) = 0x003C000E;
470         }
471         else
472         {
473             for (;;){}
474         }
475
476         //config delay lines.
477         REG32 (EXT_MEM_DL7)  = 0x6;
478         REG32 (EXT_MEM_DL16) = 0x3;
479         REG32 (EXT_MEM_DL17) = 0x3;
480         REG32 (EXT_MEM_DL18) = 0x3;
481         REG32 (EXT_MEM_DL19) = 0x3;
482         REG32 (EXT_MEM_DL20) = 0x3;
483         REG32 (EXT_MEM_DL21) = 0x3;
484         REG32 (EXT_MEM_DL22) = 0x3;
485         REG32 (EXT_MEM_DL23) = 0x3;
486         REG32 (EXT_MEM_DL24) = 0x7;
487         REG32 (EXT_MEM_DL25) = 0x7;
488         REG32 (EXT_MEM_DL26) = 0x7;
489         REG32 (EXT_MEM_DL27) = 0x7;
490     }
491     else
492     {
493         for (;;){}
494     }
495
496     return;
497 }
498
499 /**---------------------------------------------------------------------------*
500  ** FUNCTION                                                                  *
501  **     void SDRAM_Device_Init(SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)            *
502  **                                                                           *
503  ** DESCRIPTION                                                               *
504  **     set emc dmem mode/ext mode register parameters                        *
505  **                                                                           *
506  ** INPUT                                                                     *
507  **     sdram_cfg_ptr                                                         *
508  **                                                                           *
509  ** OUTPUT                                                                    *
510  **     None                                                                  *
511  **                                                                           *
512  ** RETURN VALUE                                                              *
513  **                                                                           *
514  ** DEPENDENCIES                                                              *
515  **                                                                           *
516 **---------------------------------------------------------------------------*/
517 LOCAL void SDRAM_Device_Init (SDRAM_CFG_INFO_T_PTR sdram_cfg_ptr)
518 {
519     uint8 mode_reg_bl = 0xFF;
520     uint8 mode_reg_bt = MODE_REG_BT_SEQ;
521     uint8 mode_reg_cl = 0xFF;
522     uint8 mode_reg_opmode = MODE_REG_OPMODE;
523     uint32 ex_mode_reg = 0;
524     uint16 mode_reg = 0;
525
526     //calculate mode reg burst length
527     switch (sdram_cfg_ptr->burst_length)
528     {
529         case BURST_LEN_1:
530             mode_reg_bl = MODE_REG_BL_1;
531             break;
532         case BURST_LEN_2:
533             mode_reg_bl = MODE_REG_BL_2;
534             break;
535         case BURST_LEN_4:
536             mode_reg_bl = MODE_REG_BL_4;
537             break;
538         case BURST_LEN_8:
539             mode_reg_bl = MODE_REG_BL_8;
540             break;
541         default:
542             mode_reg_bl = MODE_REG_BL_1;
543             break;
544     }
545
546     //calculate mode reg cas latency
547     switch (sdram_cfg_ptr->cas_latency)
548     {
549         case CAS_LATENCY_1:
550             mode_reg_cl = MODE_REG_CL_1;
551             break;
552         case CAS_LATENCY_2:
553             mode_reg_cl = MODE_REG_CL_2;
554             break;
555         case CAS_LATENCY_3:
556             mode_reg_cl = MODE_REG_CL_3;
557             break;
558         default:
559             mode_reg_cl = MODE_REG_CL_3;
560             break;
561     }
562
563     //get mode reg parameter
564     mode_reg = ( (mode_reg_opmode<<9) | (mode_reg_cl<<4) | (mode_reg_bt<<3) | mode_reg_bl);
565
566     //get ext-mode reg parameter
567     ex_mode_reg = sdram_cfg_ptr->ext_mode_val;
568
569     // Precharge all banks.
570     REG32 (EXT_MEM_DCFG3) = 0x40010000;
571
572     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_16){}
573
574     //Auto_ref
575     REG32 (EXT_MEM_DCFG3) = 0x40020000;
576
577     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_17){}
578
579     //Auto_ref
580     REG32 (EXT_MEM_DCFG3) = 0x40020000;
581
582     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_17){}
583
584     //mode register load.
585     REG32 (EXT_MEM_DCFG3) &= ~ (0xFFFF);
586     REG32 (EXT_MEM_DCFG3) |= (mode_reg | 0x40040000);
587
588     while ( (REG32 (EXT_MEM_DCFG3)) & BIT_18){}
589
590     //extended mode register load.
591     if (ex_mode_reg != SDRAM_EXT_MODE_INVALID)
592     {
593         REG32 (EXT_MEM_DCFG3) &= ~ (0xFFFF);
594         REG32 (EXT_MEM_DCFG3) |= (ex_mode_reg | 0x40040000);/*lint !e737*/
595
596         while ( (REG32 (EXT_MEM_DCFG3)) & BIT_18){}
597     }
598     
599 }
600
601 LOCAL void __sdram_set_param(uint32 clk, SDRAM_CFG_INFO_T_PTR pCfg)
602 {
603     volatile uint32 i;
604     
605     //step 1. Disable auto refresh.
606     REG32 (EXT_MEM_DCFG0) &= ~ BIT_14;
607
608     //step 2. sdram init: config registers, precharege all banks, auto ref for 2 times, load mode register.
609     SDRAM_GenMemCtlCfg (pCfg);
610     SDRAM_DMemCtlCfg (clk,pCfg);
611     SDRAM_Device_Init (pCfg);
612
613     //step3. enable auto refresh.
614     REG32 (EXT_MEM_DCFG2) |= BIT_15; //clear refresh count.
615     REG32 (EXT_MEM_DCFG0) |= BIT_14; //Enable auto refresh.
616    
617     for (i=0; i<1000; i++){}
618 }
619 #else
620 LOCAL CONST EMC_PHY_L1_TIMING_T EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_MATRIX_MAX] = 
621 {
622         //dpad_ie, dpad_oe, dqs_gate_pst, dqs_gate_pre, dqs_ie, dqs_oe
623         {0x20,          1,              0,                      0,                      0,              0},     //sdram cas_latency = 2
624         {0x40,          1,              0,                      0,                      0,              0},  //sdram cas_latency = 3
625         {0xf,           0xe,            0x10,           8,                      0xf,            0xe}, //ddram cas_latency = 2   
626         {0xf,           0xe,            0x40,           0x20,           0xf,            0xe},  //ddram cas_latency = 2          
627 };
628
629 LOCAL CONST EMC_PHY_L2_TIMING_T EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_MATRIX_MAX] = 
630 {
631    //dl0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19
632         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0,  0, 0, 0,  0, 0},     //sdram cas_latency = 2
633         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0,  0, 0, 0,  0, 0},     //sdram cas_latency = 3
634         {0, 0, 0, 6, 2, 2, 2, 2, 2, 2,  2,  2,  6,  6, 6,  6, 6, 6,  6, 6},     //ddram cas_latency = 2
635         {0, 0, 0, 6, 2, 2, 2, 2, 2, 2,  2,  2,  6,  6, 6,  6, 6, 6,  6, 6},     //ddram cas_latency = 3
636 };
637
638
639 EMC_PHY_L1_TIMING_T_PTR EMC_GetPHYL1_Timing(SDRAM_CFG_INFO_T_PTR mem_info)
640 {
641         if(SDR_SDRAM == mem_info->sdram_type)
642         {
643                 if(CAS_LATENCY_2 == mem_info->cas_latency)
644                 {
645                         return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_SDRAM_LATENCY2]));
646                 }
647                 else
648                 {
649                         return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_SDRAM_LATENCY3]));
650                 }
651         }
652         else
653         {
654                 if(CAS_LATENCY_2 == mem_info->cas_latency)
655                 {
656                         return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_DDRAM_LATENCY2]));
657                 }
658                 else
659                 {
660                         return (EMC_PHY_L1_TIMING_T_PTR)(&(EMC_PHY_TIMING_L1_INFO[EMC_PHY_TIMING_DDRAM_LATENCY3]));
661                 }
662         }
663 }
664
665 EMC_PHY_L2_TIMING_T_PTR EMC_GetPHYL2_Timing(SDRAM_CFG_INFO_T_PTR mem_info)
666 {
667         if(SDR_SDRAM == mem_info->sdram_type)
668         {
669                 if(CAS_LATENCY_2 == mem_info->cas_latency)
670                 {
671                         return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_SDRAM_LATENCY2]));
672                 }
673                 else
674                 {
675                         return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_SDRAM_LATENCY3]));
676                 }
677         }
678         else
679         {
680                 if(CAS_LATENCY_2 == mem_info->cas_latency)
681                 {
682                         return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_DDRAM_LATENCY2]));
683                 }
684                 else
685                 {
686                         return (EMC_PHY_L2_TIMING_T_PTR)(&(EMC_PHY_TIMING_L2_INFO[EMC_PHY_TIMING_DDRAM_LATENCY3]));
687                 }
688         }
689 }
690 /*****************************************************************************/
691 //  Description:        EMC basic mode set function
692 //                              set the base mode like:
693 //                              EMC device endian
694 //                              EMC auto gate en for power saving
695 //                              EMC auto sleep en
696 //                              EMC cmd queue mode
697 //  Global resource dependence:  NONE
698 //  Related register: EMC_CFG0
699 //  Author:             Johnny.Wang         
700 //  Note:                       The default cs map space is 4g, if dram capability is larger than 4g,
701 //                              emc_cs_map parameter must adjust.
702 /*****************************************************************************/
703 void EMC_Base_Mode_Set(void)
704 {
705         REG32(EXT_MEM_CFG0) &= ~0x1fff;//clear bit0~12
706         REG32(EXT_MEM_CFG0) |= (EMC_DVC_ENDIAN_DEFAULT <<12)    |
707                                                         (EMC_AUTO_GATE_EN               <<11)   |
708                                                         (EMC_AUTO_SLEEP_EN              <<10)   |
709                                                         (EMC_2DB_1CB                    <<6)    |
710                                                         (EMC_CS_MODE_DEFAULT    <<3)    |
711                                                         (EMC_CS_MAP_2G                  <<0)    ;
712         return;                                                 
713 }
714
715 /*****************************************************************************/
716 //  Description:        EMC each cs work mode set function
717 //                              set each cs work mode parameter like:
718 //                              memory write burst length
719 //                              memory read burst length
720 //                              memory write burst mode:wrap/increase
721 //                              memory read burst mode:wrap/increase
722 //                              AHB write busrt divided to single/busrt access
723 //                              AHB read busrt divided to single/busrt access
724 //  Global resource dependence:  memory burst length type
725 //  Related register: EMC_CFG0_CSx
726 //  Author:             Johnny.Wang         
727 //  Note:                       There are two cs pin in sc8810 emc, we usuall use cs0 to control external memory
728 //                              
729 /*****************************************************************************/
730 void EMC_CSx_Set(EMC_CS_NUM_E emc_cs_num, SDRAM_CFG_INFO_T_PTR mem_info)
731 {
732         uint32 emc_cs_cfg = EXT_MEM_CFG0_CS0 + emc_cs_num*4;
733
734         uint32 burst_len = 0;
735
736         if(DATA_WIDTH_16 == mem_info ->data_width)
737         {
738                 burst_len = mem_info->burst_length -1;
739         }
740         else
741         {
742                 burst_len = mem_info->burst_length;
743         }
744         
745         REG32(emc_cs_cfg) = 0;//clear emc cs cfg
746         REG32(emc_cs_cfg) |=((burst_len                 <<8) | //write burst length
747                                                 (burst_len                      <<4) | //read burst length
748                                                 (BURST_WRAP             <<3) | //write burst mode
749                                                 (BURST_WRAP             <<2) | //write burst mod        e
750                                                 (HBURST_TO_BURST        <<1) | //write hburst invert to mem burst
751                                                 (HBURST_TO_BURST        <<0));  //rrite hburst invert to mem burst
752 }
753
754 /*****************************************************************************/
755 //  Description:        EMC AXI channel set function
756 //                              set each axi channel parameter like:
757 //                              axi channel en
758 //                              axi channel auto sleep en
759 //                              channel endian switch
760 //                              channel priority
761 //  Global resource dependence:  NONE
762 //  Related register: EMC_CFG0_ACHx
763 //                                EMC_CFG1_ACHx
764 //  Author:             Johnny.Wang         
765 //  Note:                       There are two axi channel in sc8810 emc, one for A5,the other for GPU
766 //                              
767 /*****************************************************************************/
768 void EMC_AXI_CHL_Set(EMC_CHL_NUM_E emc_axi_num)
769 {
770         uint32 emc_axi_cfg0 = EXT_MEM_CFG0_ACH0 + emc_axi_num*8;
771         uint32 emc_axi_cfg1 = EXT_MEM_CFG1_ACH0 + emc_axi_num*8;
772
773         REG32(emc_axi_cfg0) &= ~0xf0; //clear bit7~4
774         //REG32(emc_axi_cfg0) |= (TRUE<<7) | //channel auto sleep en
775         //                    (TRUE<<6) | //channel en
776         //                    (EMC_ENDIAN_SWITCH_NONE<<4);
777
778         REG32(emc_axi_cfg0) |=      (TRUE<<6) | //channel en
779                               (EMC_ENDIAN_SWITCH_NONE<<4);
780         
781         REG32(emc_axi_cfg1) &= ~BIT_4; //clear bit7~4
782         REG32(emc_axi_cfg1) |= (EMC_CLK_ASYNC<<4); //emc clk async with axi clk
783         REG32(emc_axi_cfg1) |= (1<<6); //axi channel response mode  0:at once  1:delay several clk
784 }
785
786 /*****************************************************************************/
787 //  Description:        EMC AHB channel set function
788 //  Global resource dependence:  NONE
789 //  Author:             Johnny.Wang         
790 //  Note:                       There are 7 ahb channel in sc8810 emc, but no one is relate with ARM,
791 //                              so don't used temporarily
792 //                              
793 /*****************************************************************************/
794 void EMC_AHB_CHL_Set(EMC_CHL_NUM_E emc_ahb_num,uint32 addr_offset)
795 {
796         uint32 emc_ahb_cfg0 = EXT_MEM_CFG0_ACH0 + emc_ahb_num*8;
797         uint32 emc_ahb_cfg1 = EXT_MEM_CFG1_ACH0 + emc_ahb_num*8;
798
799         REG32(emc_ahb_cfg1) &= ~0x03ff0000;     //clear bit16~25
800         REG32(emc_ahb_cfg1) |= addr_offset<<16;
801
802 }
803 /*****************************************************************************/
804 //  Description:        EMC Memroy all timing parameter set function
805 //                              set all timing parameter of EMC when operate external memory like:
806 //                              t_rtw,
807 //                              t_ras,
808 //                              t_xsr,
809 //                              t_rfc,
810 //                              t_wr,
811 //                              t_rcd,
812 //                              t_rp,
813 //                              t_rrd,
814 //                              t_mrd,
815 //                              t_wtr,
816 //                              t_ref,
817 //  Global resource dependence:  NONE
818 //  Author:             Johnny.Wang         
819 //  Related register: EMC_DCFG1
820 //                                EMC_DCFG2
821 //  Note:                       None
822 //                              
823 /*****************************************************************************/
824 void EMC_MEM_Timing_Set(uint32 emc_freq,
825                                                 SDRAM_CFG_INFO_T_PTR     mem_info,
826                                                 SDRAM_TIMING_PARA_T_PTR  mem_timing)
827 {
828         uint32 cycle_ns = 2000*1000000/emc_freq;//2000/(clk); //device clock is half of emc clock.
829         //uint32 cycle_t_ref = 1000/EMC_T_REF_CLK;
830
831         uint32 row_mode    = mem_info->row_mode;        
832         uint32 t_rtw       = mem_info->cas_latency;             
833
834         //round all timing parameter
835         uint32  t_ras   = mem_timing->ras_min/cycle_ns;
836         uint32  t_xsr   = mem_timing->xsr_min/cycle_ns; 
837         uint32  t_rfc   = mem_timing->rfc_min/cycle_ns; 
838         uint32  t_wr    = mem_timing->wr_min/cycle_ns+2; //note: twr should add 2 for ddr       
839         uint32  t_rcd   = mem_timing->rcd_min/cycle_ns;    
840         uint32  t_rp    = mem_timing->row_pre_min/cycle_ns;     
841         uint32  t_rrd   = mem_timing->rrd_min/cycle_ns; 
842         //uint32  t_mrd = mem_timing->mrd_min/cycle_ns; 
843         uint32  t_mrd   = mem_timing->mrd_min;  
844         //uint32  t_wtr         = mem_timing->wtr_min/cycle_ns+1;       
845         uint32  t_wtr   = mem_timing->wtr_min+1;        
846         uint32  t_ref   = ((mem_timing->row_ref_max*EMC_T_REF_CLK)>>(ROW_MODE_TO_NUM(row_mode))) -2;
847
848         //prevent the maximun overflow of all timing parameter
849         t_ras   = (t_ras >= 0xf ) ? 0x7  : t_ras;
850         t_xsr   = (t_xsr >= 0xff) ? 0x26 : t_xsr;   
851         t_rfc   = (t_rfc >= 0x3f) ? 0x1a : t_rfc;
852         t_wr    = (t_wr  >= 0xf ) ? 0x4  : t_wr;
853         t_rcd   = (t_rcd >= 0xf ) ? 0x3  : t_rcd;
854         t_rp    = (t_rp  >= 0xf ) ? 0x3  : t_rp;
855         t_rrd   = (t_rrd >= 0xf ) ? 0x2  : t_rrd;
856         t_mrd   = (t_mrd >= 0xf ) ? 0x0  : t_mrd;
857         t_wtr   = (t_wtr >= 0xf ) ? 0x3  : t_wtr;
858         t_ref   = (t_ref >=0xfff) ? 0x100: t_ref ;  
859
860         //prevent the minmun value of all timing
861         t_ras   = (t_ras <= 0) ? 0x7  : t_ras;   
862         t_xsr   = (t_xsr <= 0) ? 0x26 : t_xsr;   
863         t_rfc   = (t_rfc <= 0) ? 0x1a : t_rfc;   
864         t_wr    = (t_wr  <= 0) ? 0x4  : t_wr;    
865         t_rcd   = (t_rcd <= 0) ? 0x3  : t_rcd;   
866         t_rp    = (t_rp  <= 0) ? 0x3  : t_rp;    
867         t_rrd   = (t_rrd <= 0) ? 0x2  : t_rrd;   
868         t_mrd   = (t_mrd <= 0) ? 0x2  : t_mrd;   
869         t_wtr   = (t_wtr <= 0) ? 0x3  : t_wtr;   
870         t_ref   = (t_ref <=00) ? 0x100: t_ref ;  
871
872
873
874         REG32(EXT_MEM_DCFG1) = ((0<<28)         |//read to read turn around time between different cs
875                                                                                  //default:0     2 cs or above:1
876                                                         (t_wtr << 24) |
877                                                         (t_rtw << 20) |
878                                                         (t_ras << 16) |
879                                                         (t_rrd << 12) |
880                                                         (t_wr  << 8)  |
881                                                         (t_rcd << 4)  |
882                                                         (t_rp  << 0));
883
884         REG32(EXT_MEM_DCFG2) = ((t_rfc << 24) |
885                                                         (t_xsr << 16) |
886                                                         (t_ref << 4)  |
887                                                         (t_mrd << 0));
888 }
889
890 /*****************************************************************************/
891 //  Description:        EMC Memroy mode set function
892 //                              set external memory work mode parameter like:
893 //                              data width
894 //                              column mode
895 //                              row mode and so on
896 //  Global resource dependence:  NONE
897 //  Author:             Johnny.Wang         
898 //  Related register: EMC_DCFG0
899 //                                
900 //  Note:                       None
901 //                              
902 /*****************************************************************************/
903 void EMC_MEM_Mode_Set(SDRAM_CFG_INFO_T_PTR mem_info)
904 {
905         REG32(EXT_MEM_DCFG0) = (EMC_CS_REF_SAME<<15) |
906                                                         (TRUE                   << 14) |//hardware auto-refresh en
907                                                         (TRUE                   << 13) |//mode1 en
908                                                         (TRUE                   << 12) |//mode0 en
909                                                         (TRUE                   << 11) |//dmem clock output phase
910                                                         (TRUE                   << 10) |//dmem clock output en
911                                                         (TRUE                   << 9)   |//row hit en
912                                                         (mem_info->data_width<< 8)   |
913                                                         (mem_info->col_mode << 4)   |
914                                                         (EMC_PRE_BIT_A10<< 2)  |
915                                                         (mem_info->row_mode);
916 }
917
918
919 /*****************************************************************************/
920 //  Description:        EMC phy latency set function
921 //                              set parameter relate with cas latency like:
922 //                              timing adjustment sample clock latency
923 //                              DQS output latency
924 //                              write dm latency
925 //                              read dm latency
926 //                              write data latency
927 //                              read data latency
928 //  Global resource dependence:  dram type , cas_latency
929 //  Author:             Johnny.Wang   
930 //  Related register: EMC_DCFG5
931 //                              
932 //  Note:                       None
933 //                              
934 /*****************************************************************************/
935 void EMC_PHY_Latency_Set(SDRAM_CFG_INFO_T_PTR mem_info) 
936 {
937         if(SDR_SDRAM == mem_info->sdram_type)
938         {
939                 if(CAS_LATENCY_2 == mem_info->cas_latency)
940                 {
941                         REG32(EXT_MEM_DCFG5) = 0x00420006;
942                 }
943                 else
944                 {
945                         REG32(EXT_MEM_DCFG5) = 0x00620208;
946                 }
947         }
948         else
949         {
950                 if(CAS_LATENCY_2 == mem_info->cas_latency)
951                 {
952                         REG32(EXT_MEM_DCFG5) = 0x00622726;
953                 }
954                 else
955                 {
956                         REG32(EXT_MEM_DCFG5) = 0x00622728;
957                 }       
958
959                 #if FPGA_TEST
960                         //REG32(EXT_MEM_DCFG5) = 0x00633739;
961                 #endif
962         }
963 }
964
965 /*****************************************************************************/
966 //  Description:        EMC phy mode set function
967 //                              set parameter relate with emc phy work mode like:
968 //                              cke map to cs0 or cs1
969 //                              dqs gate delay,delay line or loopback
970 //                              dqs gate mode,mode0 or mode1
971 //                              DMEM data output mode,dff or dl
972 //                              DMEM DDR DQS[3:0] output mode,dff or dl
973 //                              DMEM DDR DQS PAD IE mode,dff or dl
974 //                              DMEM sample clock mode,internal or from dqs
975 //                              DMEM CK/CK# output mode,dff or dl
976 //                              DMEM READ strobe clock loopback dis/en
977 //  Global resource dependence:  dll on or off, external memory type
978 //  Author:             Johnny.Wang        
979 //  Related register: EMC_CFG1
980 //                              
981 //  Note:                       None
982 //                              
983 /*****************************************************************************/
984 void EMC_PHY_Mode_Set(SDRAM_CFG_INFO_T_PTR mem_info)
985 {
986         REG32(EXT_MEM_CFG1) = 0; //clear phy control register
987
988         REG32(EXT_MEM_CFG1) |= (EMC_CKE_SEL_DEFAULT << 14) |
989                                                         (EMC_DQS_GATE_DEFAULT<< 8)      |
990                                                         (EMC_DQS_GATE_MODE_DEFAULT<< 7) |
991                                                         (mem_info->sdram_type<< 6) |//DMEM data output mode,dff or dl
992                                                         (EMC_DLL_ON_OFF<< 5) |//DMEM DDR DQS[3:0] output mode,dff or dl
993                                                         (EMC_DLL_ON_OFF<< 4) |//DMEM DDR DQS PAD IE mode,dff or dl
994                                                         (mem_info->sdram_type<<3) |//DMEM sample clock mode,internal or from dqs
995                                                         (0<<2) |//DMEM CK/CK# output mode,dff or dl
996                                                         (0<<1) |//DMEM READ strobe clock loopback dis/en
997                                                         mem_info->sdram_type;
998         #if FPGA_TEST
999         //REG32(EXT_MEM_CFG1) |= BIT_6;
1000         #endif
1001 }
1002
1003
1004 /*****************************************************************************/
1005 //  Description:        EMC phy timing set function
1006 //                              set parameter relate with emc phy work mode like:
1007 //                              data pad ie delay
1008 //                              data pad oe delay
1009 //                              dqs pad ie delay
1010 //                              dqs pad oe delay
1011 //                              all delay line timing parameter
1012 //  Global resource dependence:  dll on or off, external memory type
1013 //  Author:             Johnny.Wang         
1014 //  Related register: EMC_DCFG6,7,8 and EMC_DMEM_DL0~DL19
1015 //  Note:                       None
1016 //                              
1017 /*****************************************************************************/
1018 void EMC_PHY_Timing_Set(uint32 emc_freq,
1019                                         SDRAM_CFG_INFO_T_PTR mem_info,
1020                                         EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing,
1021                                         EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing)
1022 {
1023         uint32 i = 0;
1024         
1025         REG32(EXT_MEM_DCFG8) = ((emc_phy_l1_timing->data_pad_ie_delay & 0xffff) <<16) |
1026                                                         (emc_phy_l1_timing->data_pad_oe_delay & 0xff);
1027         
1028         if(DDR_SDRAM == mem_info->sdram_type)
1029         {
1030                 REG32(EXT_MEM_DCFG6) = ((emc_phy_l1_timing->dqs_gate_pst_delay& 0xffff) <<16) |
1031                                                                 (emc_phy_l1_timing->dqs_gate_pre_delay& 0xffff);
1032
1033                 REG32(EXT_MEM_DCFG7) = ((emc_phy_l1_timing->dqs_ie_delay& 0xffff) <<16) |
1034                                                                 (emc_phy_l1_timing->dqs_oe_delay& 0xff);
1035         }
1036         
1037         if(EMC_DLL_ON_OFF == TRUE && emc_freq >= ARM_CLK_96M)
1038         {
1039                 for(i = EMC_DMEM_DL0; i < EMC_DMEM_MAX; i++)
1040                 {
1041                         REG32(EXT_MEM_DL0 + i*4 ) = REG32(REG32(emc_phy_l2_timing)+i*4);
1042                 }
1043         }
1044 }
1045
1046 /*****************************************************************************/
1047 //  Description:        EMC phy  set function
1048 //                              include these subfunction:
1049 //                              EMC_PHY_Latency_set(),
1050 //                              EMC_PHY_Mode_Set(),
1051 //                              EMC_PHY_Timing_Set()
1052 //  Global resource dependence:  dll on or off, external memory type
1053 //  Author:             Johnny.Wang         
1054 //  Related register: 
1055 //  Note:                       None
1056 //                              
1057 /*****************************************************************************/
1058 void EMC_PHY_Set(uint32 emc_freq,
1059                                         SDRAM_CFG_INFO_T_PTR mem_info,
1060                                         EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing,
1061                                         EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing)
1062 {
1063         EMC_PHY_Latency_Set(mem_info);
1064         EMC_PHY_Mode_Set(mem_info);
1065         EMC_PHY_Timing_Set(emc_freq,mem_info,emc_phy_l1_timing,emc_phy_l2_timing);
1066 }
1067
1068 /*****************************************************************************/
1069 //  Description:        EMC software command send function
1070 //                              this function will send software initialization command to external memory
1071 //  Global resource dependence:  memory type
1072 //  Author:             Johnny.Wang         
1073 //  Related register: 
1074 //  Note:                       None
1075 //                              
1076 /*****************************************************************************/
1077 void EMC_SCMD_Issue(SDRAM_CFG_INFO_T_PTR mem_info)
1078 {
1079         uint32 i = 0;
1080
1081         //shut down auto-refresh
1082         REG32(EXT_MEM_DCFG0) &= ~(DCFG0_AUTOREF_EN);
1083
1084         //precharge all bank
1085         REG32(EXT_MEM_DCFG4) = 0x40010000;
1086         while (REG32(EXT_MEM_DCFG4) & BIT_16);
1087         for(i=0; i<=1000; i++);
1088
1089         //software auto refresh
1090         REG32(EXT_MEM_DCFG4) = 0x40020000;
1091         while (REG32(EXT_MEM_DCFG4) & BIT_17);          
1092         for(i=0; i<=1000; i++);
1093          
1094         //software auto refresh
1095         REG32(EXT_MEM_DCFG4) = 0x40020000;
1096         while (REG32(EXT_MEM_DCFG4) & BIT_17);          
1097         for(i=0; i<=1000; i++);
1098
1099         //load nornal mode register
1100         REG32(EXT_MEM_DCFG4) = 0x40040000 | (mem_info->cas_latency<<4) | (mem_info->burst_length); 
1101         while (REG32(EXT_MEM_DCFG4) & BIT_18);                          
1102         for(i=0; i<=1000; i++);
1103
1104         if(SDRAM_EXT_MODE_INVALID != mem_info->ext_mode_val)
1105         {
1106                 //load external mode register
1107                 REG32(EXT_MEM_DCFG4) = 0x40040000 | mem_info->ext_mode_val;
1108                 while (REG32(EXT_MEM_DCFG4) & BIT_18);                          
1109                 for(i=0; i<=1000; i++);         
1110         }
1111
1112         //open auto-refresh
1113         REG32(EXT_MEM_DCFG0) |= (DCFG0_AUTOREF_EN);
1114 }
1115
1116
1117 void EMC_Init(uint32 emc_freq,
1118                                 EMC_CS_NUM_E emc_cs_num,
1119                                 EMC_CHL_NUM_E emc_axi_num,
1120                                 SDRAM_CFG_INFO_T_PTR mem_info,
1121                                 SDRAM_TIMING_PARA_T_PTR mem_timing,
1122                                 EMC_PHY_L1_TIMING_T_PTR emc_phy_l1_timing,
1123                                 EMC_PHY_L2_TIMING_T_PTR emc_phy_l2_timing)
1124 {
1125         EMC_Base_Mode_Set();
1126         EMC_CSx_Set(emc_cs_num,mem_info);
1127         EMC_AXI_CHL_Set(emc_axi_num);
1128         EMC_MEM_Mode_Set(mem_info);
1129         EMC_MEM_Timing_Set(emc_freq,mem_info,mem_timing);
1130         EMC_PHY_Set(emc_freq,mem_info,emc_phy_l1_timing,emc_phy_l2_timing);
1131         EMC_SCMD_Issue(mem_info);
1132 }
1133 LOCAL void __sdram_set_param(uint32 clk, SDRAM_CFG_INFO_T_PTR pCfg)
1134 {
1135         uint32 i;
1136         EMC_PHY_L1_TIMING_T_PTR *emc_phy_l1_timing;
1137         EMC_PHY_L2_TIMING_T_PTR   *emc_phy_l2_timing;
1138         emc_phy_l1_timing = EMC_GetPHYL1_Timing(pCfg);
1139         emc_phy_l2_timing = EMC_GetPHYL2_Timing(pCfg);
1140         EMC_Init(clk, EMC_CS0, EMC_AXI_ARM, pCfg, sdram_parameters, emc_phy_l1_timing, emc_phy_l2_timing);
1141         for (i=0; i<1000; i++){}
1142 }
1143 #endif
1144 #ifdef SDRAM_AUTODETECT_SUPPORT
1145 LOCAL uint32 __colum_to_mode(uint32 colum)
1146 {
1147     uint32 col_mode;
1148     switch(colum)
1149     {
1150         case 8:
1151             col_mode = COL_MODE_8;
1152             break;
1153         case 9:
1154             col_mode = COL_MODE_9;
1155             break;
1156         case 10:
1157             col_mode = COL_MODE_10;
1158             break;
1159         case 11:
1160             col_mode = COL_MODE_11;
1161             break;
1162         case 12:
1163             col_mode = COL_MODE_12;
1164             break;
1165         default:
1166             for( ; ; ) {}
1167             //break;          
1168     }
1169     return col_mode;
1170 }
1171 LOCAL uint32 __row_to_mode(uint32 row)
1172 {
1173     uint32 row_mode;
1174     switch(row)
1175     {
1176         case 11:
1177             row_mode = ROW_MODE_11;
1178             break;
1179         case 12:
1180             row_mode = ROW_MODE_12;
1181             break;
1182         case 13:
1183             row_mode = ROW_MODE_13;
1184             break;
1185         case 14:
1186             row_mode = ROW_MODE_14;
1187             break;
1188         default:
1189             for( ; ; ) {}
1190             //break;          
1191     }
1192     return row_mode;
1193 }
1194
1195 LOCAL BOOLEAN __is_rw_ok(uint32 addr, uint32 val)
1196 {
1197     volatile uint32 i;
1198     
1199     REG32(addr) = val;
1200     REG32(addr+4) = (~val);
1201     
1202     for(i=0;i<0xff;i++) {}
1203
1204     if((REG32(addr) == val) && (REG32(addr+4) == (~val)))
1205         return ((BOOLEAN)SCI_TRUE);
1206     else
1207         return ((BOOLEAN)SCI_FALSE);
1208     //return ((val == REG32(addr))? ((BOOLEAN)SCI_TRUE) : ((BOOLEAN)SCI_FALSE));
1209 }
1210
1211 // ADDR: |-BANK -|------------ COLUM 12 ---------------|
1212 //       |A13|A12|A11|A10|A9|A8|A7|A6|A5|A4|A3|A2|A1|A0|
1213 //
1214 //       |------------------- ROW 14-------------------|   
1215 //       |A13|A12|A11|A10|A9|A8|A7|A6|A5|A4|A3|A2|A1|A0|
1216 LOCAL uint32 __col_row_detect(BOOLEAN is_col, SDRAM_CFG_INFO_T_PTR pCfg)
1217 {
1218     uint32 num, max, min;
1219     uint32 offset, addr;
1220     uint32 width_offset = (DATA_WIDTH_16 == pCfg->data_width)?(WIDTH16_OFFSET):(WIDTH32_OFFSET);
1221
1222     if(is_col)
1223     {
1224         max = SDRAM_MAX_COLUM;
1225         min = SDRAM_MIN_COLUM;
1226     }
1227     else
1228     {
1229         max = SDRAM_MAX_ROW;
1230         min = SDRAM_MIN_ROW;
1231     }
1232     for(num = max; num >= min; num--)
1233     {
1234         // init 0 address
1235         REG32(ZERO_ADDR) = MEM_REF_DATA0;               /*lint !e413*/
1236
1237         if(is_col)
1238         {
1239             offset = num + width_offset - BYTE_OFFSET;    // colum+width-byteoff
1240         }
1241         else
1242         {
1243             offset = num + BANK_OFFSET + (uint32)s_colum +  width_offset -  BYTE_OFFSET;    // row+bank+colum+width-byteoff
1244         }
1245         addr   = (1 << (offset - 1)) + ZERO_ADDR;
1246         if(__is_rw_ok(addr, MEM_REF_DATA1))
1247         {
1248             // if 0addr not changed, row is ok
1249             if(MEM_REF_DATA0 == REG32(ZERO_ADDR))       /*lint !e413*/
1250             {
1251                 break;
1252             }
1253             // 0addr changed, row is too big
1254             else if(MEM_REF_DATA1 == REG32(ZERO_ADDR))  /*lint !e413*/
1255             {
1256                 continue;
1257             }
1258         }
1259     }
1260
1261     return (num); 
1262 }
1263
1264 LOCAL void set_row_col(SDRAM_CFG_INFO_T_PTR pCfg)
1265 {
1266         uint32 value;
1267         int i;
1268
1269         value = REG32(0x20000180);
1270         value &= ~(0x73);
1271         value |= ((pCfg->col_mode)<<4);
1272         value |= (pCfg->row_mode);
1273         REG32(0x20000180) = value;
1274         for(i =0 ; i < 1000; i++);
1275
1276 }
1277
1278 LOCAL void __sdram_detect(uint32 clk)
1279 {
1280     SDRAM_CFG_INFO_T_PTR pCfg = &s_sdram_raw_cfg;
1281 //    uint32 state = STATE_SDRAM_TYPE;
1282     uint32 state = STATE_COLUM; //in sc8810 just need to detect the DDR's row and col
1283     uint32 colum, row;
1284
1285     //pCfg->bank_mode    = BK_MODE_4;
1286     pCfg->row_mode     = ROW_MODE_14;
1287     pCfg->col_mode     = COL_MODE_12;
1288     pCfg->data_width   = DATA_WIDTH_32;
1289     pCfg->burst_length = BURST_LEN_2;
1290     pCfg->cas_latency  = CAS_LATENCY_3;
1291     pCfg->ext_mode_val = SDRAM_EXT_MODE_REG;
1292     pCfg->sdram_type   = SDR_SDRAM;
1293         
1294     while(STATE_END != state)
1295     {     
1296 //        __sdram_set_param(clk, pCfg);
1297         set_row_col(pCfg);
1298         switch(state)
1299         {
1300         case STATE_SDRAM_TYPE:
1301             if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0))           // 16bit sdr/ddr detect ok, try 32bit
1302             {
1303                 pCfg->data_width = DATA_WIDTH_32;
1304                 state = STATE_BIT_WIDTH;
1305                 //break;
1306             }
1307             else                        // 16bit sdr failed, try 16bit ddr
1308             {
1309                 if(DDR_SDRAM == pCfg->sdram_type)   
1310                 {
1311                     for( ; ; ) {}          // all failed
1312                 }
1313                 pCfg->sdram_type = DDR_SDRAM;
1314                 state = STATE_SDRAM_TYPE;
1315                 //break;
1316             }
1317             break;
1318         case STATE_BIT_WIDTH:
1319             if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0))           // 32bit sdr/ddr detect ok, try colum
1320             {
1321                 state = STATE_COLUM;
1322                 //break;
1323             }
1324             else                        // 32bit sdr/ddr detect failed, fix 16bit and try colum
1325             {
1326                 pCfg->data_width = DATA_WIDTH_16;
1327                 state = STATE_COLUM;
1328                 //break;
1329             }
1330             break;
1331         case STATE_COLUM:
1332             if(__is_rw_ok(ZERO_ADDR, MEM_REF_DATA0))           
1333             {
1334                 colum = __col_row_detect(SCI_TRUE, pCfg);
1335                 pCfg->col_mode = __colum_to_mode(colum);
1336                 s_colum = colum;//lint !e63
1337                 state = STATE_ROW;
1338                 //break;
1339             }
1340             else                        
1341             {
1342                 for( ; ; ) {}           // should not come here
1343             }
1344             break;
1345         case STATE_ROW:
1346             row = __col_row_detect(SCI_FALSE, pCfg);
1347             pCfg->row_mode = __row_to_mode(row);
1348             state = STATE_REINIT;
1349             break;
1350         case STATE_REINIT:
1351             state = STATE_END;  
1352             break;
1353         default:
1354             break;
1355         }
1356     }
1357 }
1358 #endif
1359 /**---------------------------------------------------------------------------*
1360  ** FUNCTION                                                                  *
1361  **     void SDRAM_Init(uint32 sdram_clk)                                     *
1362  **                                                                           *
1363  ** DESCRIPTION                                                               *
1364  **     initialize emc sdram module                                           *
1365  **                                                                           *
1366  ** INPUT                                                                     *
1367  **     sdram_clk                                                             *
1368  **                                                                           *
1369  ** OUTPUT                                                                    *
1370  **     None                                                                  *
1371  **                                                                           *
1372  ** RETURN VALUE                                                              *
1373  **                                                                           *
1374  ** DEPENDENCIES                                                              *
1375  **                                                                           *
1376 **---------------------------------------------------------------------------*/
1377 LOCAL void SDRAM_Init (uint32 clk)
1378 {
1379     sdram_parameters = SDRAM_GetTimingPara();
1380
1381     #ifdef SDRAM_AUTODETECT_SUPPORT
1382     __sdram_detect(clk);
1383     #else
1384     __sdram_set_param(clk, SDRAM_GetCfg());
1385     #endif
1386
1387 }
1388  
1389
1390 /**---------------------------------------------------------------------------*
1391  ** FUNCTION                                                                  *
1392  **     void SDRAM_PinDrv_Set(void)                                           *
1393  **                                                                           *
1394  ** DESCRIPTION                                                               *
1395  **     initialize emc pins                                                   *
1396  **                                                                           *
1397  ** INPUT                                                                     *
1398  **     none                                                                  *
1399  **                                                                           *
1400  ** OUTPUT                                                                    *
1401  **     None                                                                  *
1402  **                                                                           *
1403  ** RETURN VALUE                                                              *
1404  **                                                                           *
1405  ** DEPENDENCIES                                                              *
1406  **                                                                           *
1407 **---------------------------------------------------------------------------*/
1408 LOCAL void SDRAM_PinDrv_Set (void)
1409 {
1410 #if defined(PLATFORM_SC8800G)
1411         uint32 i = 0;
1412         uint32 clk_drv = 0x200;
1413         uint32 ctl_drv = 0x100;
1414         uint32 dat_drv = 0x100;
1415         
1416         REG32(PIN_CTL_REG) = 0X1FFF00; //set nf_rb keyin[0-7] wpus
1417
1418         REG32(PINMAP_REG_BASE + 0X27c) = clk_drv;       
1419         REG32(PINMAP_REG_BASE + 0X280) = clk_drv;               
1420         
1421         for(i = 0; i<15; i++)
1422         {
1423                 REG32(PINMAP_REG_BASE + 0x019c + i*4) = ctl_drv;
1424         }
1425         
1426         REG32(PINMAP_REG_BASE + 0X1d8) = ctl_drv;
1427         REG32(PINMAP_REG_BASE + 0X2a8) = ctl_drv;                               
1428         REG32(PINMAP_REG_BASE + 0X1FC) = ctl_drv;
1429         REG32(PINMAP_REG_BASE + 0X200) = ctl_drv;
1430         REG32(PINMAP_REG_BASE + 0X224) = ctl_drv;
1431         REG32(PINMAP_REG_BASE + 0X228) = ctl_drv;
1432         REG32(PINMAP_REG_BASE + 0X24c) = ctl_drv;       
1433         REG32(PINMAP_REG_BASE + 0X250) = ctl_drv;               
1434         REG32(PINMAP_REG_BASE + 0X274) = ctl_drv;               
1435         REG32(PINMAP_REG_BASE + 0X278) = ctl_drv;               
1436
1437         for(i = 0; i<9; i++)
1438                 REG32(PINMAP_REG_BASE + 0x0284 + i*4) = ctl_drv;
1439         
1440
1441         for(i = 0; i<8; i++)
1442         {       
1443                 REG32(PINMAP_REG_BASE + 0x1DC + i*4) = dat_drv;
1444                 REG32(PINMAP_REG_BASE + 0x204 + i*4) = dat_drv;
1445                 REG32(PINMAP_REG_BASE + 0x22c + i*4) = dat_drv;
1446                 REG32(PINMAP_REG_BASE + 0x254 + i*4) = dat_drv;
1447         }       
1448
1449 #endif
1450 }
1451
1452
1453 /**---------------------------------------------------------------------------*
1454  ** FUNCTION                                                                  *
1455  **     void Chip_ConfigClk(void)                                             *
1456  **                                                                           *
1457  ** DESCRIPTION                                                               *
1458  **     set pll, arm clock,ahb clock,emc clock                                *
1459  **                                                                           *
1460  ** INPUT                                                                     *
1461  **     p_system_clk_cfg                                                      *
1462  **                                                                           *
1463  ** OUTPUT                                                                    *
1464  **     None                                                                  *
1465  **                                                                           *
1466  ** RETURN VALUE                                                              *
1467  **                                                                           *
1468  ** DEPENDENCIES                                                              *
1469  **                                                                           *
1470 **---------------------------------------------------------------------------*/
1471 LOCAL uint32 Chip_ConfigClk (void)
1472 {
1473     volatile uint32 i;
1474     volatile uint32 arm_ahb_clk =0;
1475
1476 #if defined(PLATFORM_SC6800H)
1477 #ifdef _BL_NF_NBL_
1478
1479     //support dual pll, mpll 400mhz, bpll 480mhz
1480     {
1481         volatile uint32 is_pll_done = 0;
1482
1483         //clear the protect control
1484         CHIP_REG_SET(GR_MCU_PORT, PLL_MCU_PROT_VALUE);
1485
1486         //disable pll
1487         CHIP_REG_AND(GR_MISC1, ~ MISC1_MCU_PLL_EN);
1488
1489         //set mpll to 400MHz
1490         CHIP_REG_SET(GR_MPLL_MN, MPLL_MN_400M);
1491         //clk_48M source select to bpll
1492         CHIP_REG_OR(AHB_CLK_CFG1, AHB_CLK_CFG1_SRCSEL48M);
1493
1494         //open bpll
1495         CHIP_REG_AND(GR_MISC1, ~MISC1_MCU_BPLL_FORCE_PD_EN);
1496         //select bpll controlled by hw and release bpll output
1497         CHIP_REG_OR(GR_MISC1, (MISC1_BPLL_SEL|MISC1_BPLL_CONT_DONE));
1498
1499         //enable pll
1500         CHIP_REG_OR (GR_MISC1, MISC1_MCU_PLL_EN);
1501
1502         //wait pll count done
1503         is_pll_done = CHIP_REG_GET(GR_STATUS) & ((uint32) APB_STATUS_PLL_CNT_DONE);
1504
1505         while (0 == is_pll_done)
1506         {
1507             is_pll_done = CHIP_REG_GET(GR_STATUS) & ((uint32) APB_STATUS_PLL_CNT_DONE);
1508         }
1509
1510         //set the protect control
1511         CHIP_REG_SET(GR_MCU_PORT, 0);
1512     }
1513 #endif
1514
1515     arm_ahb_clk = ARM_CLK_100M;
1516     //MPLL is open already in RomCode
1517     i = REG32 (AHB_CLK_CFG0);
1518     //set CLK_EMC to 192MHz
1519     i &= ~ (BIT_7 | BIT_6 | BIT_5 | BIT_4);
1520     i |= 0xC << 4;               //Src_sel_emc:4'b1100 : MPLL_DIV2:
1521     i &= ~ (BIT_9 | BIT_8);      //Div_cfg_emc:0x0
1522     //set CLK_ARM to 192MHz
1523     i &= ~ (BIT_2 | BIT_1);      //Div_cfg_arm:0x01
1524     //set CLK_AHB to 96MHz
1525     i |= BIT_3;
1526     //set Src_sel_arm to  MPLL/2(192Mhz)
1527     i |= BIT_0;
1528     REG32 (AHB_CLK_CFG0) = i;
1529
1530     for (i=0; i<100; i++){}
1531
1532 #elif defined(PLATFORM_SC8800G)
1533 #ifdef CONFIG_SC8810
1534 #else
1535     __ClkConfig(&g_emc_clk, (uint32*)&arm_ahb_clk);
1536 #endif
1537 #endif
1538
1539     //Delay some time
1540     for (i=0; i<1000; i++) {}
1541
1542     return arm_ahb_clk;
1543 }
1544
1545 int timer_init(void);
1546 unsigned long long get_ticks(void);
1547 void ddr_init()
1548 {
1549         volatile unsigned int i;
1550         unsigned long long now;
1551         uint32 clkwr_dll = (64*s_emc_config.clk_wr)/(s_emc_config.read_value/2);
1552
1553         timer_init();
1554         now = get_ticks();
1555         do{}while(get_ticks() <= now+2);
1556
1557         REG32(0x20000004) = 0x00000049;
1558         for(i = 0; i < 1000; i++);
1559
1560         REG32(0x20000024) |= BIT_6;
1561         REG32(0x2000002C) |= BIT_6;
1562         for(i = 0; i < 1000; i++);
1563
1564         REG32(0x20000194) = 0x0062272A;
1565         for(i = 0; i < 1000; i++);
1566
1567         REG32(0x20000198) = 0x00200010;
1568         for(i = 0; i < 1000; i++);
1569
1570         REG32(0x2000019c) = 0x00f0000e;
1571         for(i = 0; i < 1000; i++);
1572
1573         REG32(0x200001a0) = 0x00f0000e;
1574         for(i = 0; i < 1000; i++);      
1575
1576         //set EMC dll
1577         REG32(0x20000170) = 0x0011080;
1578         for(i = 0; i < 1000; i++);      
1579         
1580 #ifndef CONFIG_BOARD_788
1581         REG32(0x2000010C) = (0x8000|clkwr_dll);
1582 #else
1583         REG32(0x2000010C) = 0x804A;     
1584 #endif
1585         REG32(0x20000110) = 0x8020;
1586         REG32(0x20000114) = 0x8020;
1587         REG32(0x20000118) = 0x8020;
1588         REG32(0x2000011C) = 0x8020;
1589         REG32(0x20000120) = 0x8020;
1590         REG32(0x20000124) = 0x8020;
1591         REG32(0x20000128) = 0x8020;
1592         REG32(0x2000012C) = 0x8020;
1593         REG32(0x20000130) = 0x8040;
1594         REG32(0x20000134) = 0x8040;
1595         REG32(0x20000138) = 0x8040;
1596         REG32(0x2000013C) = 0x8040;
1597         REG32(0x20000140) = 0x8040;
1598         REG32(0x20000144) = 0x8040;
1599         REG32(0x20000148) = 0x8040;
1600         REG32(0x2000014C) = 0x8040;
1601
1602         REG32(0x20000170) = 0x11480;
1603
1604         REG32(0x20000190) = 0x40010000;
1605         for(i =0 ; i < 1000; i++);
1606         
1607         REG32(0x20000190) = 0x40020000;
1608         for(i =0 ; i < 1000; i++);
1609
1610         REG32(0x20000190) = 0x40020000;
1611         for(i =0 ; i < 1000; i++);
1612
1613         REG32(0x20000190) = 0x40040031;
1614         for(i =0 ; i < 1000; i++);
1615
1616         REG32(0x20000190) = 0x40048000;
1617         for(i =0 ; i < 1000; i++);
1618
1619         //set cs map to 2G bit
1620         REG32(0x20000000) &= ~(0x7);
1621 //      REG32(0x20000000) |= (0x7);
1622         REG32(0x20000000) |= (s_emc_config.cs_pos);
1623         //REG32(0x20000010) = 0x223;
1624         //REG32(0x20000014) = 0x223;
1625
1626         REG32(0x20000184) = 0x233a3566;
1627         REG32(0x20000188) = 0x1a260322;
1628         //REG32(0x20000184) = 0x02371422;
1629         //REG32(0x20000188) = 0x121c0322;
1630         
1631         REG32(0x20000180) |= BIT_14;
1632         for(i =0 ; i < 1000; i++);
1633       
1634        //detect column mode and row mode
1635         __sdram_detect(0);
1636         for(i =0 ; i < 1000; i++);      
1637 }
1638 void    set_emc_pad(uint32 clk_drv, uint32 ctl_drv, uint32 dat_drv, uint32 dqs_drv)
1639 {
1640         unsigned int i = 0;
1641         REG32(PINMAP_REG_BASE + 0x27C) = clk_drv;
1642         REG32(PINMAP_REG_BASE + 0x280) = clk_drv;
1643         for(i = 0; i < 15; i++)
1644         {
1645                 REG32(PINMAP_REG_BASE + 0x19c + i * 4) = ctl_drv;
1646         }
1647         REG32(PINMAP_REG_BASE + 0x1d8) = ctl_drv;
1648
1649         for(i = 0; i < 10; i++)
1650         {
1651                 REG32(PINMAP_REG_BASE + 0x284 + i * 4) = ctl_drv;
1652         }
1653
1654         for(i = 0; i < 8; i++)
1655         {
1656                 REG32(PINMAP_REG_BASE + 0x1DC + i * 4) = dat_drv;
1657                 REG32(PINMAP_REG_BASE + 0x204 + i * 4) = dat_drv;
1658                 REG32(PINMAP_REG_BASE + 0x22C + i * 4) = dat_drv;
1659                 REG32(PINMAP_REG_BASE + 0x254 + i * 4) = dat_drv;
1660         }
1661         //dqs
1662         REG32(PINMAP_REG_BASE + 0x200) = dqs_drv;
1663         REG32(PINMAP_REG_BASE + 0x228) = dqs_drv;
1664         REG32(PINMAP_REG_BASE + 0x250) = dqs_drv;
1665         REG32(PINMAP_REG_BASE + 0x278) = dqs_drv;
1666
1667
1668         //dqm
1669         REG32(PINMAP_REG_BASE + 0x1FC) = dat_drv;
1670         REG32(PINMAP_REG_BASE + 0x224) = dat_drv;
1671         REG32(PINMAP_REG_BASE + 0x24C) = dat_drv;
1672         REG32(PINMAP_REG_BASE + 0x274) = dat_drv;
1673
1674         // CKE OUTPUT in sleep
1675         REG32(PINMAP_REG_BASE + 0x1d8) |= 0x1;
1676         REG32(PINMAP_REG_BASE + 0x2a8) |= 0x1;
1677
1678 }
1679
1680 #ifdef SPL_USB_DOWNLOAD
1681 void uart_trace(uint32 ch)
1682 {
1683         volatile uint32 i;
1684         REG32(0x84000000) = ch;
1685         for(i = 0; i < 0x4000; i++);
1686 }
1687 typedef void (*JUMPTOHANDLER) (void);
1688 #ifdef CONFIG_SP8810
1689 #define KEY_DOWNLOAD_MODE_MAP 0x10 //keyout0-keyin7
1690 #else
1691 #define KEY_DOWNLOAD_MODE_MAP 0x01 //keyout0-keyin7
1692 #endif
1693 PUBLIC void _KeypadEnable()
1694 {
1695         volatile uint32 i;
1696         REG32(0x8b000008) |= BIT_26 | BIT_8; //enable keypad
1697         //REG32(0X8B00004C) |= BIT_1;
1698         //for(i = 0; i < 0x100; i++);
1699         //REG32(0X8B00004C) &= ~BIT_1; //soft reset
1700         //REG32(0x87000010) |= 0xfff; //clear all interrupt
1701
1702         //REG32(0x87000018) = 0xffff;
1703         //REG32(0x87000028) = 0;//debounce
1704         //REG32(0x8700001c) = 0xf;//debounce counter    
1705
1706         //REG32(0x87000000) |= 0x000001; //
1707         //REG32(0x87000000) |= 0x000001; //
1708         for(i = 0; i < 0x10000; i++);
1709 }
1710 PUBLIC void _KeypadClear()
1711 {
1712         REG32(0x87000010) |= 0xffff; //clear all interrupt
1713 }
1714 //if download mode return 1, else return 0
1715 PUBLIC uint32 _Check_DownloadMode()
1716 {
1717         volatile  uint32 key_raw_int_sts = 0;
1718         volatile  uint32 key_sts = 0;
1719         uint32 time;
1720         volatile uint32 i;
1721         //for(i = 0; i < 0x100000; i++);
1722         uart_trace(0x99);
1723         i = REG32(0x87000000);
1724         
1725         uart_trace(i & 0xff);
1726         uart_trace((i >> 8) & 0xff);
1727         uart_trace((i >> 16) & 0xff);
1728         uart_trace((i >> 24) & 0xff);
1729
1730         for(time = 0; time < 10; time++)
1731         {
1732                 //_KeypadClear();
1733                 //while(1)
1734                 {
1735                 for(i = 0; i < 0x200000; i++);
1736                 key_raw_int_sts = REG32(0x87000008);
1737                 key_sts = REG32(0x8700002c);            
1738                 
1739                 
1740                         //for(i = 0; i < 0x200000; i++);
1741                         uart_trace(key_raw_int_sts & 0xff);
1742                         uart_trace((key_raw_int_sts >> 8) & 0xff);
1743                         uart_trace((key_raw_int_sts >> 16) & 0xff);
1744                         uart_trace((key_raw_int_sts >> 24) & 0xff);
1745
1746
1747                         uart_trace(key_sts & 0xff);
1748                         uart_trace((key_sts >> 8)& 0xff);
1749                         uart_trace((key_sts >> 16)& 0xff);
1750                         uart_trace((key_sts >> 24)& 0xff);
1751
1752                         uart_trace(0x11);                       
1753                 
1754                 }
1755                 key_raw_int_sts &= BIT_0;
1756                 key_sts &= 0x77;
1757
1758                 if((key_sts == KEY_DOWNLOAD_MODE_MAP))
1759                 {
1760                         uart_trace(0x66);
1761                         return 1; //check ok
1762                 }
1763         }
1764         return 0;
1765 }
1766 PUBLIC void _JumpToDownload()
1767 {
1768         uart_trace(0x77);
1769
1770         JUMPTOHANDLER handler = (JUMPTOHANDLER)(0xffff0000);
1771         handler();
1772 }
1773 LOCAL uint32 SystemCountGet()
1774 {
1775         uint32 clock;
1776         uint32 clock_c;
1777         clock = REG32(0x87003004);
1778         clock_c = REG32(0x87003004);
1779         while(clock != clock_c)
1780         {
1781                 clock = REG32(0x87003004);
1782                 clock_c = REG32(0x87003004);
1783         }
1784         return clock;
1785 }
1786 #define SPL_USB_DOWNLOAD_TIMEOUT 3000
1787 PUBLIC void _WaitUsbDownloadKey()
1788 {
1789         uint32 time0;
1790         uint32 time1;
1791         uint32 key_raw_int_sts = 0;
1792         uint32 key_sts = 0;
1793
1794         time0 = SystemCountGet();
1795         while(1)
1796         {
1797                 key_raw_int_sts = REG32(0x87000008);
1798                 key_sts = REG32(0x8700002c);
1799                 key_raw_int_sts &= BIT_0;
1800                 key_sts &= 0x77;
1801                 if((key_raw_int_sts != 0) && (key_sts == 0))
1802                 {
1803                         _JumpToDownload();
1804                 }
1805                 time1 = SystemCountGet();
1806                 if((time1 - time0) > SPL_USB_DOWNLOAD_TIMEOUT)
1807                 {
1808                         break;
1809                 }
1810         }
1811 }
1812 #if 0
1813 PUBLIC void _WaitUsbDownloadKey()
1814 {
1815         uint32 key_raw_int_sts = 0;
1816         uint32 key_sts = 0;
1817         uint32 time;
1818         volatile uint32 i;
1819         uart_trace(0x11);
1820         uart_trace(0x22);
1821         
1822         //wait key1 release
1823 #if 0
1824         while(1)
1825         {
1826                 key_raw_int_sts = REG32(0x87000008);
1827                 key_raw_int_sts &= BIT_4;
1828                 if(key_raw_int_sts != 0)        
1829                 {
1830                         uart_trace(0x77);
1831                         _KeypadClear();
1832                         break;
1833                 }
1834         }
1835 #endif
1836         uart_trace(0x33);
1837         i = 0 ;
1838 //      for(time = 0; time < 2; time++)
1839         {
1840                 //usb download key press
1841                 while(1)
1842                 {       
1843                         //_KeypadClear();
1844                         //for(i = 0; i < 0x200000; i++)
1845                         key_raw_int_sts = REG32(0x87000008);
1846                         key_sts = REG32(0x8700002c);
1847                         
1848                         uart_trace(0x44);
1849                         uart_trace(key_sts & 0xff);
1850                         uart_trace((key_sts >> 8) & 0xff);
1851
1852                         uart_trace(key_raw_int_sts & 0xff);
1853                         //key_sts >>=  8;
1854                         key_raw_int_sts &= BIT_0;
1855                         key_sts &= 0x77;
1856                         if((key_raw_int_sts != 0) && (key_sts == 0))
1857                         {
1858                                 uart_trace(0x88);
1859                                 _JumpToDownload();
1860                                 //break;;
1861                         }
1862                         if(i > 0x3000000)
1863                         {
1864                                 break;
1865                         }
1866                 }
1867         }
1868         return ;        
1869 }
1870 #endif
1871 #endif
1872
1873 #define ARMCLK_CONFIG_EN        1
1874 void sc8810_emc_Init()
1875 {
1876         
1877         volatile unsigned int i;
1878                 
1879         set_emc_pad(s_emc_config.clk_drv, s_emc_config.ctl_drv, s_emc_config.dat_drv, s_emc_config.dqs_drv);
1880
1881         // GPU AXI 256M
1882         REG32(0x8b00002c) &= ~(0x3);
1883         
1884         // A5 AXI DIV           
1885         REG32(0x20900238) |= (1 << 11);
1886         REG32(0x20900238) &= ~(1 <<12);
1887
1888         REG32(0x8b000018) |= (1 << 9);
1889         
1890         //set MPLL to 900MHz
1891         i = REG32(0x8b000024);
1892         i &= ~ 0x7ff;
1893 #if ARMCLK_CONFIG_EN
1894         i |= s_emc_config.arm_clk;
1895 #else
1896         //i |= 0xFA;     //1000M
1897         //i |= 0xe1;     //900M
1898         i |= 0xC8;   //800M
1899 #endif
1900         REG32(0x8b000024) = i;
1901         
1902         //set DPLL of EMC to 400MHz
1903         i = REG32(0x8b000040);
1904         i &= ~ 0x7ff;
1905         i |= s_emc_config.emc_clk;
1906         //i |= 0x80;     //512M
1907         //i |= 0x69;   //420M
1908         //i |= 0x64;   //400M
1909         REG32(0x8b000040) = i;
1910         REG32(0x8b000018) &= ~(1 << 9);
1911         
1912         // AHB_ARM_CLK SET
1913 #if 1   // emc from DPLL
1914         REG32(0x20900224) = (3 << 23) | (3 << 12);
1915         REG32(0x20900224) |= (3 << 4) | (0 << 8) | (7 << 14);
1916         REG32(0x20900224) |= (1 << 23) | (3 << 4) | (0 << 8) | (7 << 14);
1917         for(i = 0; i < 1000; i++);
1918         
1919         REG32(0x20900224) = (3 << 4) | (0 << 8) | (7 << 14) | (1 << 12/*select dpll*/);
1920 #else   // EMC from MPLL
1921         REG32(0x20900224) = (3 << 23) | (3 << 12);
1922         REG32(0x20900224) |= (3 << 4) | (1 << 8) | (7 << 14);
1923         REG32(0x20900224) |= (1 << 23) | (3 << 4) | (1 << 8) | (7 << 14);
1924         for(i = 0; i < 1000; i++);
1925         
1926         REG32(0x20900224) = (3 << 4) | (1 << 8) | (7 << 14) | (0 << 12/*select mpll*/);
1927 #endif
1928 #ifdef SPL_USB_DOWNLOAD
1929         _KeypadEnable();
1930         //if not in download mode
1931         //if(_Check_DownloadMode() == 0)
1932         {
1933         //      return; 
1934         }
1935         _WaitUsbDownloadKey();
1936         
1937 #endif
1938         ddr_init();
1939 }
1940
1941 static const int dcdc_ctl_vol[] = {
1942         650, 700, 800, 900, 1000, 1100, 1200, 1300, 1400,
1943 };
1944
1945 PUBLIC void dcdc_calibrate(int chan, int to_vol)
1946 {
1947         int i;
1948         uint32 ctl_vol = to_vol;
1949         uint32 dcdc_ctl;
1950         for (i = 0; i < ARRAY_SIZE(dcdc_ctl_vol) - 1; i++) {
1951                 if (ctl_vol < dcdc_ctl_vol[i + 1])
1952                         break;
1953         }
1954         if (i >= ARRAY_SIZE(dcdc_ctl_vol) - 1)
1955                 goto exit;
1956
1957         if (chan == 10) {
1958                 dcdc_ctl = ANA_DCDCARM_CTL;
1959         }
1960         else if (chan == 11) {
1961                 dcdc_ctl = ANA_DCDC_CTL;
1962         }
1963         else
1964                 goto exit;
1965
1966         ANA_REG_SET(dcdc_ctl, i | (0x07 - i) << 4);
1967
1968 exit:
1969         return ;
1970 }
1971 PUBLIC void Chip_Init (void) /*lint !e765 "Chip_Init" is used by init.s entry.s*/
1972 {
1973         volatile uint32 i = 0;
1974         if (REG32(0x209003fc) == CHIP_ID_8810S) {
1975                 dcdc_calibrate(10, 1300);//vddarm 1.30v
1976                 dcdc_calibrate(11, 1200);//vddcore 1.20v
1977         }
1978         EMC_PARAM_T_PTR emc_ptr = EMC_GetPara();
1979         
1980         s_emc_config.arm_clk = emc_ptr->arm_clk/1000000/4;
1981         s_emc_config.emc_clk = emc_ptr->emc_clk/1000000/4;
1982         s_emc_config.dqs_drv = (emc_ptr->dqs_drv << 8);
1983         s_emc_config.dat_drv = (emc_ptr->dat_drv << 8);
1984         s_emc_config.ctl_drv = (emc_ptr->ctl_drv << 8);
1985         s_emc_config.clk_drv = (emc_ptr->clk_drv << 8);
1986         s_emc_config.clk_wr  = emc_ptr->clk_wr;
1987         s_emc_config.read_value = (emc_ptr->read_value & 0xff);
1988         s_emc_config.cs_pos = emc_ptr->cs_pos;
1989                 
1990         for (i = 0; i < 0xff1; ++i);    
1991         sc8810_emc_Init();
1992         g_ahb_clk = 200000000;
1993         for (i=0; i<0xff1; i++);
1994
1995         // AHB master priority:  DSP > lcdc > other > GPU
1996         REG32(0x20000020) = 0x7D;
1997         REG32(0x20000024) = 0x4D;
1998         REG32(0x20000030) = 0x1c31D;
1999         REG32(0x20000050) = 0x1c31D;
2000         REG32(0x20000058) = 0x1c31D;
2001         REG32(0x20000060) = 0x1c31E;
2002         REG32(0x20000038) = 0x1c31F;
2003         REG32(0x20000040) = 0x1c31F;
2004         REG32(0x20000048) = 0x1c31F;
2005 }
2006