c04d04ed2db4f63bfea88b3e9f6c0168168a2b5f
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / tiger / 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 #define  ROW_MODE_TO_NUM(_m)    (_m+11)
28
29 uint32 single_chk(uint32 addr, uint32 data)
30 {
31         REG32(addr) = data;
32         
33         if(REG32(addr) == data)
34         {
35                 return 1;
36         }
37         else
38         {
39                 return 0;
40         }
41 }
42
43 uint32 ddr_rw_chk(uint32 addr)
44 {
45         uint32 i    = 0;
46         uint32 data = 0;
47         
48         for(i = 0; i < 8; i++)
49         {
50                 switch(i)
51                 {
52                         case 0: data = 0x00000000; break;
53                         case 1: data = 0xffffffff; break;
54                         case 2: data = 0x55555555; break;
55                         case 3: data = 0xaaaaaaaa; break;
56                         case 4: data = 0x01234567; break;
57                         case 5: data = 0x76543210; break;
58                         case 6: data = 0x89abcdef; break;
59                         case 7: data = 0xfedcba98; break;
60                 }
61                 
62                 if(single_chk(addr,    data) == 0 ||
63                    single_chk(addr+0x4,data) == 0 ||
64                    single_chk(addr+0x8,data) == 0 ||
65                    single_chk(addr+0xc,data) == 0)
66                 {
67                         return 0;
68                 }
69         }
70
71         return 1;
72 }
73
74 uint32 dq_training(uint32 addr)
75 {
76         const uint32 TR_MAX = 16;
77         uint32 i = 0;
78         uint32 tr0,tr1,tr2,tr3;
79
80         for(tr0 = 0; tr0 < TR_MAX; tr0++)
81         {
82                 PUBL_REG(PUBL_CFG_DX0DQSTR) = tr0;
83                 for(tr1 = 0; tr1 < TR_MAX; tr1++)
84                 {
85                         PUBL_REG(PUBL_CFG_DX1DQSTR) = tr1;
86                         for(tr2 = 0; tr2 < TR_MAX; tr2++)
87                         {
88                                 PUBL_REG(PUBL_CFG_DX2DQSTR) = tr2;
89                                 for(tr3 = 0; tr3 < TR_MAX; tr3++)
90                                 {
91                                         PUBL_REG(PUBL_CFG_DX3DQSTR) = tr3;
92                                         if(ddr_rw_chk(addr))
93                                         {
94                                                 REG32(EMC_MEM_BASE_ADDR+i*4)=(0xBA550000|(tr3<<12)|(tr2<<8)|(tr1<<4)|tr0);
95                                                 return 1;
96                                         }
97                                         else
98                                         {
99                                         
100                                                 REG32(EMC_MEM_BASE_ADDR+i*4)=(0xFA110000|(tr3<<12)|(tr2<<8)|(tr1<<4)|tr0);
101                                         }
102                                         i++;
103                                 }
104                         }
105                 }
106         }
107
108         //if not found correct dqs training value, set as default value;
109         PUBL_REG(PUBL_CFG_DX0DQSTR)     = 0xaa;
110         PUBL_REG(PUBL_CFG_DX1DQSTR)     = 0xaa;
111         PUBL_REG(PUBL_CFG_DX2DQSTR)     = 0xaa;
112         PUBL_REG(PUBL_CFG_DX3DQSTR)     = 0xaa;
113     return 0;
114 }
115
116
117
118 void write_upctl_state_cmd(UPCTL_CMD_E cmd)
119 {
120         UMCTL_REG(UMCTL_CFG_SCTL) = cmd;
121 }
122
123 void poll_upctl_state(UPCTL_STATE_E state)
124 {
125         UPCTL_STATE_E state_poll;
126
127         do{state_poll = REG32(UMCTL_REG_BASE + UMCTL_CFG_STAT);}
128         while(state_poll != state);
129 }
130 void move_upctl_state_to_access(void)
131 {
132         UPCTL_STATE_E upctl_state;
133         upctl_state = UMCTL_REG(UMCTL_CFG_STAT);
134
135         while(upctl_state != STATE_ACCESS)
136         {
137                 switch(upctl_state)
138                 {
139                         case STATE_CONFIG:
140                         {
141                                 write_upctl_state_cmd(CMD_GO);
142                                 poll_upctl_state(STATE_ACCESS);
143                                 upctl_state = UMCTL_REG(UMCTL_CFG_STAT);                //hs add
144                                 break;
145                         }
146                         case STATE_INIT_MEM:
147                         {
148                                 write_upctl_state_cmd(CMD_CFG);
149                                 poll_upctl_state(STATE_CONFIG);
150                                 upctl_state = STATE_CONFIG;
151                                 break;
152                         }
153                         case STATE_LOW_POWER:
154                         {
155                                 write_upctl_state_cmd(CMD_WAKEUP);
156                                 poll_upctl_state(STATE_ACCESS);
157                                 upctl_state = UMCTL_REG(UMCTL_CFG_STAT);                //hs add
158                                 break;
159                         }
160                         default:
161                         {                               
162                                 upctl_state = UMCTL_REG(UMCTL_CFG_STAT);
163                                 break;
164                         }
165
166                 }
167         }
168 }
169
170 void DMC_Init(uint32 lpddr_type)
171 {
172         uint32 value_temp,i;
173
174         //memory timing configuration registers
175         UMCTL_REG(UMCTL_CFG_SCFG) = 0x00000420;
176         //UMCTL_REG(UMCTL_CFG_MCFG) = (lpddr_type<<22)|(DRAM_BL<<20)|(DRAM_TYPE<<6);
177         UMCTL_REG(UMCTL_CFG_MCFG) = 0x00A60041;   //hs change
178
179         //memory basic timing configuration     
180         UMCTL_REG(UMCTL_CFG_TOGCNT1U)   = 0x23;
181         UMCTL_REG(UMCTL_CFG_TINIT)              = 0x01;
182         UMCTL_REG(UMCTL_CFG_TRSTH)              = 0x00;
183         UMCTL_REG(UMCTL_CFG_TOGCNT100N) = 0x28;
184         UMCTL_REG(UMCTL_CFG_TREFI)      = 0x4e;
185         UMCTL_REG(UMCTL_CFG_TMRD)       = 0x05;
186         UMCTL_REG(UMCTL_CFG_TRFC)       = 0x34;
187         UMCTL_REG(UMCTL_CFG_TRP)        = (lpddr_type==LPDDR2_SDRAM) ? 0x0001000A:0x00000004;
188         UMCTL_REG(UMCTL_CFG_TRTW)       = 0x03;
189         UMCTL_REG(UMCTL_CFG_TAL)        = 0x00;
190         UMCTL_REG(UMCTL_CFG_TCL)        = (lpddr_type==LPDDR2_SDRAM) ? 0x06:0x03; 
191         UMCTL_REG(UMCTL_CFG_TCWL)       = (lpddr_type==LPDDR2_SDRAM) ? 0x03:0x01;
192         UMCTL_REG(UMCTL_CFG_TRAS)       = (lpddr_type==LPDDR2_SDRAM) ? 0x11:0x08;
193         UMCTL_REG(UMCTL_CFG_TRC)        = (lpddr_type==LPDDR2_SDRAM) ? 0x1b:0x0c;
194         UMCTL_REG(UMCTL_CFG_TRCD)       = (lpddr_type==LPDDR2_SDRAM) ? 0x06:0x04;
195         UMCTL_REG(UMCTL_CFG_TRRD)       = (lpddr_type==LPDDR2_SDRAM) ? 0x04:0x02;
196         UMCTL_REG(UMCTL_CFG_TRTP)       = (lpddr_type==LPDDR2_SDRAM) ? 0x03:0x01;
197         UMCTL_REG(UMCTL_CFG_TWR)        = (lpddr_type==LPDDR2_SDRAM) ? 0x06:0x03;
198
199         //xiaohui change from 3 to 4 due to tWTR=7.5ns whereas clk_emc=2.348ns
200         UMCTL_REG(UMCTL_CFG_TWTR)       = (lpddr_type==LPDDR2_SDRAM) ? 0x04:0x01; 
201         UMCTL_REG(UMCTL_CFG_TEXSR)      = 0x38;
202         UMCTL_REG(UMCTL_CFG_TXP)        = 0x04;
203         UMCTL_REG(UMCTL_CFG_TXPDLL)     = 0x00;
204
205         //xiaohui change from 0x24 to 0x27 due to tZQCS=90ns whereas clk_emc=2.348ns
206         UMCTL_REG(UMCTL_CFG_TZQCS)      = 0x27;
207         UMCTL_REG(UMCTL_CFG_TZQCSI)     = 0x05;
208         UMCTL_REG(UMCTL_CFG_TDQS)       = 0x01;
209         UMCTL_REG(UMCTL_CFG_TCKSRE)     = 0x00;
210         UMCTL_REG(UMCTL_CFG_TCKSRX)     = 0x02;
211         UMCTL_REG(UMCTL_CFG_TCKE)       = 0x03;
212         UMCTL_REG(UMCTL_CFG_TMOD)       = 0x00;
213         UMCTL_REG(UMCTL_CFG_TRSTL)      = 0x02;
214         UMCTL_REG(UMCTL_CFG_TZQCL)      = 0x90;
215         UMCTL_REG(UMCTL_CFG_TCKESR)     = 0x06; 
216         UMCTL_REG(UMCTL_CFG_TDPD)       = 0x01; 
217
218         //default value not compatible with real condition
219         UMCTL_REG(UMCTL_CFG_DCFG)                       =(DRAM_ADDR_MAP<<8)|(DRAM_TYPE<<6)|(DRAM_DENSITY<<2)|DRAM_IO_WIDTH;
220         UMCTL_REG(UMCTL_CFG_DFITPHYWRDATA)      = 0X01;
221         UMCTL_REG(UMCTL_CFG_DFITPHYWRLAT)       = (lpddr_type==LPDDR2_SDRAM) ? 3:0;
222         UMCTL_REG(UMCTL_CFG_DFITRDDATAEN)       = (lpddr_type==LPDDR2_SDRAM) ? 5:1;
223         UMCTL_REG(UMCTL_CFG_DFITPHYRDLAT)       = 0x0f;
224         UMCTL_REG(UMCTL_CFG_DFISTCFG0)          = 0x07;
225         UMCTL_REG(UMCTL_CFG_DFISTCFG1)          = 0x03;
226         UMCTL_REG(UMCTL_CFG_DFISTCFG2)          = 0x03;
227         UMCTL_REG(UMCTL_CFG_DFILPCFG0)          = 0X00070101;
228
229         for(i = 0; i < 8; i++)
230         {
231                 UMCTL_REG(UMCTL_CFG_PCFG0+i*4) |= 0X70; //st_fw_en,bp_rd_en,bp_wr_en
232         }
233
234         //hs add start
235         UMCTL_REG(UMCTL_CFG_PCFG0)              = 0X50;
236         UMCTL_REG(UMCTL_CFG_PCFG1)              = 0X50;
237         UMCTL_REG(UMCTL_CFG_PCFG3)              = 0X50;
238         UMCTL_REG(UMCTL_CFG_PCFG4)              = 0X50;
239         UMCTL_REG(UMCTL_CFG_PCFG5)              = 0X50;
240         UMCTL_REG(UMCTL_CFG_PCFG6)              = 0X50;
241         //hs add end
242
243         //===============================================================================
244         //now,set the PHY registers
245         PUBL_REG(PUBL_CFG_DTAR) = (0<<28)|(0<<12)|0;    
246         PUBL_REG(PUBL_CFG_PTR0) = 0X0020051B;
247
248         value_temp = PUBL_REG(PUBL_CFG_DCR);
249         value_temp &= ~0x30f;
250         value_temp |= (lpddr_type == LPDDR2_SDRAM) ? 0XC:0X0;
251         value_temp |= ((DRAM_TYPE==0)?1:0)<<8;//lpddr2_s4???
252         PUBL_REG(PUBL_CFG_DCR) = value_temp;
253
254         //MR0
255         value_temp = PUBL_REG(PUBL_CFG_MR0);
256         if(lpddr_type == LPDDR1_SDRAM)
257         {
258                 value_temp &= ~0xff;
259                 value_temp |= ((DRAM_CL<<4)|(DRAM_BT<<3)|DRAM_BL);
260         }
261         //PUBL_REG(PUBL_CFG_MR0) = value_temp;
262         PUBL_REG(PUBL_CFG_MR0) = 0x00000A3B;    //hs modify     
263         //MR1
264         value_temp = PUBL_REG(PUBL_CFG_MR1);
265         if(lpddr_type == LPDDR2_SDRAM)
266         {
267                 value_temp &= ~0xff;
268                 value_temp |= ((0X3<<5)|(DRAM_WC<<4)|(DRAM_BT<<3)|DRAM_BL);
269         }
270         PUBL_REG(PUBL_CFG_MR1) = value_temp;
271
272         //MR2
273         if(lpddr_type == LPDDR2_SDRAM)
274         {
275                 PUBL_REG(PUBL_CFG_MR2) = 0X4;
276         }
277
278         //MR3
279         if(lpddr_type == LPDDR2_SDRAM)
280         {
281                 value_temp = PUBL_REG(PUBL_CFG_MR3);
282                 value_temp &= ~0xf;
283                 value_temp |= 0x2;
284                 PUBL_REG(PUBL_CFG_MR3) = value_temp;
285         }
286         
287         //DTPR0
288         if(lpddr_type == LPDDR1_SDRAM)
289         {
290                 //            tCCD   tRC       tRRD    tRAS   tRCD    tRP    tWTR   tRTP  tMRD
291                 value_temp = ((0<<31)|(12<<25)|(2<<21)|(8<<16)|(4<<12)|(4<<8)|(1<<5)|(2<<2)|2);
292         }
293         else if(lpddr_type == LPDDR2_SDRAM)
294         {
295                 value_temp = 0x36916a6d;
296         }
297         PUBL_REG(PUBL_CFG_DTPR0) = value_temp;
298
299         //DTPR1
300         value_temp = PUBL_REG(PUBL_CFG_DTPR1);
301         if(lpddr_type == LPDDR1_SDRAM)
302         {
303                 value_temp &= ~(0x3);
304                 value_temp &= ~(0xff<<16);
305                 value_temp |= 0x1;
306                 value_temp |= 32<<16;
307         }
308         else if(lpddr_type == LPDDR2_SDRAM)
309         {
310                 value_temp = 0x193400a0;
311         }
312         PUBL_REG(PUBL_CFG_DTPR1) = value_temp;
313
314         //DTPR2
315         if(lpddr_type == LPDDR2_SDRAM)
316         {
317                 PUBL_REG(PUBL_CFG_DTPR2) = 0X1001A0C8;
318         }
319
320         //DXCCR
321         value_temp = PUBL_REG(PUBL_CFG_DXCCR);
322         value_temp &= ~0xff0;
323         value_temp |= (lpddr_type == LPDDR2_SDRAM) ? 0XC40:0X0;
324         PUBL_REG(PUBL_CFG_DXCCR) = value_temp;
325
326         //PIR
327         PUBL_REG(PUBL_CFG_PIR) = 0x00020000;
328         
329         //PGCR
330         if(lpddr_type == LPDDR1_SDRAM)
331         {
332                 PUBL_REG(PUBL_CFG_PGCR) = 0X018C2E03;
333         }
334         else
335         {
336                 value_temp = PUBL_REG(PUBL_CFG_PGCR);
337                 value_temp &= ~0xc0006;
338                 value_temp |= 0xc0002;
339                 PUBL_REG(PUBL_CFG_PGCR) = value_temp;
340         }       
341
342         //PTR1
343         PUBL_REG(PUBL_CFG_PTR1) = ((200*1000)/20)&0X7FFFF;
344         //PTR2
345         PUBL_REG(PUBL_CFG_PTR2) = ((200*1000)/20)&0X1FFFF;
346         
347         //waite for PHY initialization done and DLL lock done
348         do{value_temp = PUBL_REG(PUBL_CFG_PGSR);}
349         while((value_temp&0x3) != 0x3);
350
351         //start memory power up sequence
352         UMCTL_REG(UMCTL_CFG_POWCTL) = 0X1;
353         do{value_temp = UMCTL_REG(0X44);}
354         while((value_temp&0x1) != 0x0);
355
356         //excute DRAM initialization sequence
357         PUBL_REG(PUBL_CFG_PIR) = 0X00020041;
358         for(i = 0; i <= 100; i++);
359
360         //waite for initialize done
361         do{value_temp = PUBL_REG(PUBL_CFG_PGSR);}
362         while((value_temp&0x1) != 0x1);
363
364         //waite for dll lock done
365         do{value_temp = PUBL_REG(PUBL_CFG_PGSR);}
366         while((value_temp&0x2) != 0x2);
367
368         move_upctl_state_to_access();
369
370         //manually configure the Q-valid window and phase
371         PUBL_REG(PUBL_CFG_DX0DQSTR) = 0Xaa;
372         PUBL_REG(PUBL_CFG_DX1DQSTR) = 0Xaa;
373         PUBL_REG(PUBL_CFG_DX2DQSTR) = 0Xaa;
374         PUBL_REG(PUBL_CFG_DX3DQSTR) = 0Xaa;
375
376         if(lpddr_type == LPDDR1_SDRAM)
377         {
378                 dq_training(EMC_MEM_BASE_ADDR);
379         }
380         
381         for(i = 0; i < 1000; i++);
382 }
383
384
385 PUBLIC void Chip_Init (void) /*lint !e765 "Chip_Init" is used by init.s entry.s*/
386 {
387     DMC_Init(LPDDR1_SDRAM);
388
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408