tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / arm926ejs / sc8800x / sdram.c
1 #include <config.h>
2 #include <asm/arch/regs_global.h>
3 #include <asm/arch/regs_emc.h>
4 #include <asm/arch/sdram.h>
5 #include <asm/io.h>
6 #include <linux/types.h>
7 #include <asm/arch/regs_cpc.h>
8 #include <asm/arch/sdram_cfg.h>
9 #include <asm/arch/bits.h>
10 #include <asm/arch/sdram.h>
11
12 /********************************************
13  * SDRAM pin configuration, include direction
14  * driver strength.
15  * ******************************************/
16 static void pin_driver_set(void)
17 {
18         uint32_t i;
19         uint32_t reg_config;
20         for(i = CPC_EMA0_REG; i<= CPC_EMD15_REG; i+=4)
21                 writel(0x31, i); //sdram config, direction:output, driver strength:3
22
23         //use SDRAM/DDR, set the bit on
24         reg_config = readl(CPC_EMBA1_REG);
25         reg_config |= BIT_6;
26         writel(reg_config, CPC_EMBA1_REG);
27 }
28
29 /*
30 static void on_chip_ram_en(void)
31 {
32         REG32(GEN2_ADDR)= ON_CHIP_RAM_EN;
33 }
34 */
35 //file the sdram_config_info structure
36 static void get_config(sdram_cfg_t *sdram_config_info)
37 {
38         sdram_config_info->bank_mode = CONFIG_SYS_SDRAM_BANK_CNT;
39         sdram_config_info->row_mode = CONFIG_SYS_SDRAM_ROW_CNT;
40         sdram_config_info->col_mode = CONFIG_SYS_SDRAM_COL_CNT;
41         sdram_config_info->data_width = CONFIG_SYS_SDRAM_DATA_WIDTH;
42         sdram_config_info->burst_length = CONFIG_SYS_SDRAM_BURST_LENGTH;
43         sdram_config_info->cas_latency = CONFIG_SYS_SDRAM_CAS_LATENCY;
44         sdram_config_info->ext_mode_val = CONFIG_SYS_SDRAM_EXT_MODE;
45         sdram_config_info->sdram_size = CONFIG_SYS_SDRAM_SIZE_M;
46         sdram_config_info->clk_dly = CONFIG_SYS_SDRAM_CLK_DELAY;
47 }
48
49 //fill the sdram_timing_param structure
50 static void get_timing_param(sdram_timing_t *sdram_timing_param)
51 {
52         sdram_timing_param->row_ref_max = CONFIG_SYS_SDRAM_ROW_REFRESH_MAX;
53         sdram_timing_param->row_pre_min = CONFIG_SYS_SDRAM_ROW_PRECHARGE_MIN;
54         sdram_timing_param->row_cyc_min = CONFIG_SYS_SDRAM_ROW_CYCLE_MIN;
55         sdram_timing_param->rcd_min = CONFIG_SYS_SDRAM_TRCD_MIN;
56         sdram_timing_param->wr_min = CONFIG_SYS_SDRAM_TWR_MIN;
57         sdram_timing_param->mrd_min = CONFIG_SYS_SDRAM_TMRD_MIN;
58         sdram_timing_param->rfc_min = CONFIG_SYS_SDRAM_TRFC_MIN;
59         sdram_timing_param->xsr_min = CONFIG_SYS_SDRAM_TXSR_MIN;
60         sdram_timing_param->ras_min = CONFIG_SYS_SDRAM_TRAS_MIN;
61 }
62
63 void general_ctl_cfg(sdram_cfg_t *sdram_cfg)
64 {
65         uint32_t reg_config;
66         uint32_t rburst_length = sdram_cfg->burst_length;
67         uint32_t wburst_length = sdram_cfg->burst_length;
68         uint32_t data_width = sdram_cfg->data_width;
69
70         rburst_length &= 0x3;
71         wburst_length &= 0x3;
72
73         //Config channel2
74         //    //Enable ch2, no switch
75         REG32(EXT_MEM_CFG0) |= (BIT_2|BIT_12|BIT_13);
76
77         //Config channel0 big endian
78         REG32(EXT_MEM_CFG0) |= BIT_4;
79
80         //Disable all channel eburst_hit_en
81         REG32(EXT_MEM_CFG0) &= ~(BIT_20|BIT_21|BIT_22|BIT_23);
82
83         //DMEM enable, (CS0)-->DMEM
84         REG32(EXT_MEM_CFG1) |= (BIT_0|BIT_10);    //DMEM enable
85         REG32(EXT_MEM_CFG1) &=~BIT_4;   //kewang add for 128M sdram
86         REG32(EXT_MEM_CFG1) |=BIT_5;// kewang
87
88         REG32(EXT_MEM_CFG1) &= ~(BIT_12);    //Clear smem_only_en
89
90         REG32(EXT_MEM_CFG1) &= ~(BIT_9);     //SDRAM mode
91
92         if(data_width == DATA_WIDTH_16){
93                 //Config read/write latency for cs0 here...
94                  if(rburst_length == BURST_LEN_8) {
95                         rburst_length = BURST_LEN_4;
96                 }else if(rburst_length == BURST_LEN_4){
97                         rburst_length = BURST_LEN_2;
98                 }
99                 if(wburst_length == BURST_LEN_8){
100                         wburst_length = BURST_LEN_4;
101                 }else if(wburst_length == BURST_LEN_4){
102                         wburst_length = BURST_LEN_2;
103                 }
104                 
105                 reg_config = REG32(EXT_MEM_CFG2);
106                 reg_config &= ~(0x3 | (0x3<<8));
107                 reg_config |= (rburst_length | (wburst_length<<8));
108                 REG32(EXT_MEM_CFG2) = reg_config; 
109         }else if(data_width == DATA_WIDTH_32){
110                 //Config read/write latency for cs0 here...
111                 reg_config = REG32(EXT_MEM_CFG2);
112                 reg_config &= ~(0x3 | (0x3<<8));
113                 reg_config |= (rburst_length | (wburst_length<<8));
114                 REG32(EXT_MEM_CFG2) = reg_config; 
115         }else {
116                 while(1);
117         }
118 }
119
120 void dmem_ctl_cfg(uint32_t ahb_clk, const sdram_cfg_t *sdram_cfg_ptr, const sdram_timing_t * sdram_parameters)
121 {
122         uint32_t t_rtw =0;
123
124         uint32_t row_mode = sdram_cfg_ptr->row_mode;
125         uint32_t col_mode = sdram_cfg_ptr->col_mode;
126         uint32_t data_width = sdram_cfg_ptr->data_width;
127         uint32_t cas_latency = sdram_cfg_ptr->cas_latency;
128         uint32_t write_latency = 0;
129
130         uint32_t sdram_cycle_ns = 1000/(ahb_clk); //1000000000/(clk*1000000),this value can be set a little bigger.
131         uint32_t row_number = 0xFFFFFFFF;
132              
133         uint32_t t_ras = sdram_parameters->ras_min/sdram_cycle_ns;//sdram_parameters[T_RAS_MIN]/sdram_cycle_ns ;
134         uint32_t t_xsr = sdram_parameters->xsr_min/sdram_cycle_ns;
135         uint32_t t_rfc = sdram_parameters->rfc_min/sdram_cycle_ns ;
136         uint32_t t_mrd = sdram_parameters->mrd_min/sdram_cycle_ns ;
137         uint32_t t_wr  = sdram_parameters->wr_min/sdram_cycle_ns ;
138         uint32_t t_rcd = sdram_parameters->rcd_min/sdram_cycle_ns ;
139         uint32_t t_rp  = sdram_parameters->row_pre_min/sdram_cycle_ns ;
140         uint32_t t_ref = sdram_parameters->row_ref_max/sdram_cycle_ns ;    
141         uint32_t t_wtr = 0xf;
142
143         if(cas_latency == 3)
144                 t_rtw = 4;
145         else if(cas_latency == 2)
146                 t_rtw = 2;
147         else 
148                 while(1);
149
150         if (row_mode == ROW_MODE_11)
151         {
152                 row_number = 11;
153         }
154         else if (row_mode == ROW_MODE_12)
155         {
156                 row_number = 12;
157         }
158         else if (row_mode == ROW_MODE_13)
159         {
160                 row_number = 13;
161         }
162         else
163         {
164                 row_number = 13;
165         }
166
167         if(data_width == DATA_WIDTH_16)
168         {
169                 data_width = 0;
170         }else if(data_width == DATA_WIDTH_32)
171         {
172                 data_width = 1;
173         }
174
175         REG32(EXT_MEM_DCFG0) = ( \
176                                  DCFG0_BKPOS_HADDR_24_23 |       \
177                                 (data_width<<3) |               \
178                                 (row_mode<<4) |                 \
179                                 DCFG0_AUTO_PRE_POSITION_A10 |   \
180                                 (col_mode<<8) |                 \
181                                 DCFG0_CLKDMEM_OUT_EN |          \
182                                 DCFG0_ALTERNATIVE_EN |          \
183                                 DCFG0_ROWHIT_EN |               \
184                                 (t_ref<<20)                     \
185                 );
186                 
187                 REG32(EXT_MEM_DCFG1) = (                        \
188                                 (t_rp <<0) |        \
189                                 (t_rcd<<2) |        \
190                                 (t_wr <<4) |        \
191                                 (t_rfc<<8) |        \
192                                 (t_xsr<<12)|        \
193                                 (t_ras<<16)|        \
194                                 (t_rtw<<20)|        \
195                                 (t_wtr<<24)|        \
196                                 (t_mrd<<28)         \
197                         );
198         REG32(EXT_MEM_DCFG2) = ( (1<<row_number)|DCFG2_REF_CNT_RST );
199         //rdm/wdm latency should be cfg relatively...
200          REG32(EXT_MEM_DCFG4) = ( cas_latency | (write_latency<<4) );
201         
202         REG32(EXT_MEM_CFG1)  &= ~BIT_14;
203         REG32(EXT_MEM_DCFG0) |= BIT_14;
204         if(cas_latency == 3)
205         {
206                 REG32(EXT_MEM_DCFG4) = 0x00800209;
207                 REG32(EXT_MEM_DCFG6) = 0x00400100;
208         }
209         else if (cas_latency == 2)
210         {
211                 REG32(EXT_MEM_DCFG4) = 0x00600007;
212                 REG32(EXT_MEM_DCFG6) = 0x00100100;
213         }
214         else 
215         {
216                 while(1);
217         }
218 }
219
220 void sdram_device_init(sdram_cfg_t *sdram_cfg_ptr)
221 {
222         uint8_t mode_reg_bl = 0xFF;
223         uint8_t mode_reg_bt = MODE_REG_BT_SEQ;   //sequencial mode burst.
224         uint8_t mode_reg_cl = 0xFF;
225         uint8_t mode_reg_opmode = MODE_REG_OPMODE;
226         uint8_t mode_reg_wb = MODE_REG_WB_PRORAM;  //Programming burst length for write.
227
228         uint32_t ex_mode_reg = 0;
229         uint16_t mode_reg = 0;
230         uint8_t dsoft_cs = 0; // command for CS0
231
232         // since DMEM suport different r/w burst len, how to cfg sdram deviec burst len?
233         switch (sdram_cfg_ptr->burst_length)
234         {
235         case BURST_LEN_2:
236                 mode_reg_bl = MODE_REG_BL_2;
237                 break;
238         case BURST_LEN_4:
239                 mode_reg_bl = MODE_REG_BL_4;
240                 break;
241         case BURST_LEN_8:
242                 mode_reg_bl = MODE_REG_BL_8;
243                 break;
244         default:
245                 mode_reg_bl = MODE_REG_BL_8;
246                 break;
247         }
248
249         switch (sdram_cfg_ptr->cas_latency)
250         {
251         case CAS_LATENCY_1:
252                 mode_reg_cl = MODE_REG_CL_1;
253                 break;
254         case CAS_LATENCY_2:
255                 mode_reg_cl = MODE_REG_CL_2;
256                 break;
257         case CAS_LATENCY_3:
258                 mode_reg_cl = MODE_REG_CL_3;
259                 break;
260         default:
261                 mode_reg_cl = MODE_REG_CL_3;
262                 break;
263         }
264
265         mode_reg = ((mode_reg_wb<<9) | (mode_reg_opmode<<7) 
266                | (mode_reg_cl<<4) | (mode_reg_bt<<3) | mode_reg_bl); 
267
268         ex_mode_reg = sdram_cfg_ptr->ext_mode_val;
269
270         REG32(EXT_MEM_DCFG3) |= BIT_16 | (dsoft_cs<<28);// Precharge all banks.
271         while ((REG32(EXT_MEM_DCFG3)) & BIT_16);
272
273         REG32(EXT_MEM_DCFG3) |= BIT_17 | (dsoft_cs<<28);//Auto_ref
274         while ((REG32(EXT_MEM_DCFG3)) & BIT_17);
275
276         REG32(EXT_MEM_DCFG3) |= BIT_17 | (dsoft_cs<<28);//Auto_ref
277         while ((REG32(EXT_MEM_DCFG3)) & BIT_17);
278
279         //mode register load.
280         REG32(EXT_MEM_DCFG3) &= ~(0xFFFF);
281         REG32(EXT_MEM_DCFG3) |= (mode_reg | BIT_18 | (dsoft_cs<<28));
282         while ((REG32(EXT_MEM_DCFG3)) & BIT_18);
283
284         //extended mode register load.
285         if (ex_mode_reg != SDRAM_EXT_MODE_INVALID)      
286         {
287                 REG32(EXT_MEM_DCFG3) &= ~(0xFFFF);
288                 REG32(EXT_MEM_DCFG3) |= (ex_mode_reg | BIT_18 | (dsoft_cs<<28));
289                 while ((REG32(EXT_MEM_DCFG3)) & BIT_18);
290         }  
291 }
292
293 void emc_init(uint32_t ahb_clk)
294 {
295         uint32_t reg_config;
296
297         sdram_cfg_t sdram_config_info;
298         sdram_timing_t sdram_timing_param;
299
300         pin_driver_set();
301 //      on_chip_ram_en();
302         get_config(&sdram_config_info);
303         get_timing_param(&sdram_timing_param);
304
305         //disable sdram auto refresh
306         reg_config = readl(EXT_MEM_DCFG0);
307         reg_config &= ~(DCFG0_AUTOREF_EN);
308         writel(reg_config, EXT_MEM_DCFG0);
309
310         general_ctl_cfg(&sdram_config_info);
311         dmem_ctl_cfg(ahb_clk, &sdram_config_info, &sdram_timing_param);
312
313         sdram_device_init(&sdram_config_info);
314
315         reg_config = readl(EXT_MEM_DCFG2);
316         reg_config |= DCFG2_REF_CNT_RST;
317         writel(reg_config, EXT_MEM_DCFG2);
318
319         //enable auto refresh
320         reg_config = readl(EXT_MEM_DCFG0);
321         reg_config |= DCFG0_AUTOREF_EN;
322         writel(reg_config, EXT_MEM_DCFG0);
323
324 }