add chaos_calmer branch
[15.05/openwrt.git] / package / boot / uboot-oxnas / files / board / ox820 / ddr.c
1 /*******************************************************************
2  *
3  * File:            ddr_oxsemi.c
4  *
5  * Description:     Declarations for DDR routines and data objects
6  *
7  * Author:          Julien Margetts
8  *
9  * Copyright:       Oxford Semiconductor Ltd, 2009
10  */
11 #include <common.h>
12 #include <asm/arch/clock.h>
13
14 #include "ddr.h"
15
16 typedef unsigned int UINT;
17
18 // DDR TIMING PARAMETERS
19 typedef struct {
20         unsigned int holdoff_cmd_A;
21         unsigned int holdoff_cmd_ARW;
22         unsigned int holdoff_cmd_N;
23         unsigned int holdoff_cmd_LM;
24         unsigned int holdoff_cmd_R;
25         unsigned int holdoff_cmd_W;
26         unsigned int holdoff_cmd_PC;
27         unsigned int holdoff_cmd_RF;
28         unsigned int holdoff_bank_R;
29         unsigned int holdoff_bank_W;
30         unsigned int holdoff_dir_RW;
31         unsigned int holdoff_dir_WR;
32         unsigned int holdoff_FAW;
33         unsigned int latency_CAS;
34         unsigned int latency_WL;
35         unsigned int recovery_WR;
36         unsigned int width_update;
37         unsigned int odt_offset;
38         unsigned int odt_drive_all;
39         unsigned int use_fixed_re;
40         unsigned int delay_wr_to_re;
41         unsigned int wr_slave_ratio;
42         unsigned int rd_slave_ratio0;
43         unsigned int rd_slave_ratio1;
44 } T_DDR_TIMING_PARAMETERS;
45
46 // DDR CONFIG PARAMETERS
47
48 typedef struct {
49         unsigned int ddr_mode;
50         unsigned int width;
51         unsigned int blocs;
52         unsigned int banks8;
53         unsigned int rams;
54         unsigned int asize;
55         unsigned int speed;
56         unsigned int cmd_mode_wr_cl_bl;
57 } T_DDR_CONFIG_PARAMETERS;
58
59 //cmd_mode_wr_cl_bl
60 //when SDR : cmd_mode_wr_cl_bl = 0x80200002 + (latency_CAS_RAM * 16) + (recovery_WR - 1) * 512; -- Sets write rec XX, CL=XX; BL=8
61 //else       cmd_mode_wr_cl_bl = 0x80200003 + (latency_CAS_RAM * 16) + (recovery_WR - 1) * 512; -- Sets write rec XX, CL=XX; BL=8
62
63 //                                                            cmd_                    bank_ dir_     lat_  rec_ width_ odt_   odt_ fix delay     ratio
64 //                                                                A                                F  C         update offset all  re  re_to_we  w  r0  r1
65 //                                                                R     L        P  R        R  W  A  A  W  W
66 //Timing Parameters                                            A  W  N  M  R  W  C  F  R  W  W  R  W  S  L  R
67 static const T_DDR_TIMING_PARAMETERS C_TP_DDR2_25E_CL5_1GB = { 4, 5, 0, 2, 4, 4,
68         5, 51, 23, 24, 9, 11, 18, 5, 4, 6, 3, 2, 0, 1, 2, 75, 56, 56 }; //elida device.
69 static const T_DDR_TIMING_PARAMETERS C_TP_DDR2_25E_CL5_2GB = { 4, 5, 0, 2, 4, 4,
70         5, 79, 22, 24, 9, 11, 20, 5, 4, 6, 3, 2, 0, 1, 2, 75, 56, 56 };
71 static const T_DDR_TIMING_PARAMETERS C_TP_DDR2_25_CL6_1GB = { 4, 5, 0, 2, 4, 4,
72         4, 51, 22, 26, 10, 12, 18, 6, 5, 6, 3, 2, 0, 1, 2, 75, 56, 56 }; // 400MHz, Speedgrade 25 timings (1Gb parts)
73
74 //                                                          D     B  B  R  A   S
75 //                                                          D  W  L  K  A  S   P
76 //Config Parameters                                         R  D  C  8  M  Z   D CMD_MODE
77 //static const T_DDR_CONFIG_PARAMETERS C_CP_DDR2_25E_CL5  = { 2,16, 1, 0, 1, 32,25,0x80200A53}; // 64 MByte
78 static const T_DDR_CONFIG_PARAMETERS C_CP_DDR2_25E_CL5 = { 2, 16, 1, 1, 1, 64,
79         25, 0x80200A53 }; // 128 MByte
80 static const T_DDR_CONFIG_PARAMETERS C_CP_DDR2_25_CL6 = { 2, 16, 1, 1, 1, 128,
81         25, 0x80200A63 }; // 256 MByte
82
83 static void ddr_phy_poll_until_locked(void)
84 {
85         volatile UINT reg_tmp = 0;
86         volatile UINT locked = 0;
87
88         //Extra read to put in delay before starting to poll...
89         reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2;      // read
90
91         //POLL C_DDR_PHY2_REG register until clock and flock
92         //!!! Ideally have a timeout on this.
93         while (locked == 0) {
94                 reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2;      // read
95
96                 //locked when bits 30 and 31 are set
97                 if (reg_tmp & 0xC0000000) {
98                         locked = 1;
99                 }
100         }
101 }
102
103 static void ddr_poll_until_not_busy(void)
104 {
105         volatile UINT reg_tmp = 0;
106         volatile UINT busy = 1;
107
108         //Extra read to put in delay before starting to poll...
109         reg_tmp = *(volatile UINT *) C_DDR_STAT_REG;      // read
110
111         //POLL DDR_STAT register until no longer busy
112         //!!! Ideally have a timeout on this.
113         while (busy == 1) {
114                 reg_tmp = *(volatile UINT *) C_DDR_STAT_REG;      // read
115
116                 //when bit 31 is clear - core is no longer busy
117                 if ((reg_tmp & 0x80000000) == 0x00000000) {
118                         busy = 0;
119                 }
120         }
121 }
122
123 static void ddr_issue_command(int commmand)
124 {
125         *(volatile UINT *) C_DDR_CMD_REG = commmand;
126         ddr_poll_until_not_busy();
127 }
128
129 static void ddr_timing_initialisation(
130         const T_DDR_TIMING_PARAMETERS *ddr_timing_parameters)
131 {
132         volatile UINT reg_tmp = 0;
133         /* update the DDR controller registers for timing parameters */
134         reg_tmp = (ddr_timing_parameters->holdoff_cmd_A << 0);
135         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_ARW << 4);
136         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_N << 8);
137         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_LM << 12);
138         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_R << 16);
139         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_W << 20);
140         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_PC << 24);
141         *(volatile UINT *) C_DDR_REG_TIMING0 = reg_tmp;
142
143         reg_tmp = (ddr_timing_parameters->holdoff_cmd_RF << 0);
144         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_bank_R << 8);
145         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_bank_W << 16);
146         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_dir_RW << 24);
147         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_dir_WR << 28);
148         *(volatile UINT *) C_DDR_REG_TIMING1 = reg_tmp;
149
150         reg_tmp = (ddr_timing_parameters->latency_CAS << 0);
151         reg_tmp = reg_tmp + (ddr_timing_parameters->latency_WL << 4);
152         reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_FAW << 8);
153         reg_tmp = reg_tmp + (ddr_timing_parameters->width_update << 16);
154         reg_tmp = reg_tmp + (ddr_timing_parameters->odt_offset << 21);
155         reg_tmp = reg_tmp + (ddr_timing_parameters->odt_drive_all << 24);
156
157         *(volatile UINT *) C_DDR_REG_TIMING2 = reg_tmp;
158
159         /* Program the timing parameters in the PHY too */
160         reg_tmp = (ddr_timing_parameters->use_fixed_re << 16)
161                         | (ddr_timing_parameters->delay_wr_to_re << 8)
162                         | (ddr_timing_parameters->latency_WL << 4)
163                         | (ddr_timing_parameters->latency_CAS << 0);
164
165         *(volatile UINT *) C_DDR_REG_PHY_TIMING = reg_tmp;
166
167         reg_tmp = ddr_timing_parameters->wr_slave_ratio;
168
169         *(volatile UINT *) C_DDR_REG_PHY_WR_RATIO = reg_tmp;
170
171         reg_tmp = ddr_timing_parameters->rd_slave_ratio0;
172         reg_tmp += ddr_timing_parameters->rd_slave_ratio1 << 8;
173
174         *(volatile UINT *) C_DDR_REG_PHY_RD_RATIO = reg_tmp;
175
176 }
177
178 static void ddr_normal_initialisation(
179         const T_DDR_CONFIG_PARAMETERS *ddr_config_parameters, int mhz)
180 {
181         int i;
182         volatile UINT tmp = 0;
183         volatile UINT reg_tmp = 0;
184         volatile UINT emr_cmd = 0;
185         UINT refresh;
186
187         //Total size of memory in Mbits...
188         tmp = ddr_config_parameters->rams * ddr_config_parameters->asize
189                 * ddr_config_parameters->width;
190         //Deduce value to program into DDR_CFG register...
191         switch (tmp) {
192         case 16:
193                 reg_tmp = 0x00020000 * 1;
194                 break;
195         case 32:
196                 reg_tmp = 0x00020000 * 2;
197                 break;
198         case 64:
199                 reg_tmp = 0x00020000 * 3;
200                 break;
201         case 128:
202                 reg_tmp = 0x00020000 * 4;
203                 break;
204         case 256:
205                 reg_tmp = 0x00020000 * 5;
206                 break;
207         case 512:
208                 reg_tmp = 0x00020000 * 6;
209                 break;
210         case 1024:
211                 reg_tmp = 0x00020000 * 7;
212                 break;
213         case 2048:
214                 reg_tmp = 0x00020000 * 8;
215                 break;
216         default:
217                 reg_tmp = 0; //forces sims not to work if badly configured
218         }
219
220         //Memory width
221         tmp = ddr_config_parameters->rams * ddr_config_parameters->width;
222         switch (tmp) {
223         case 8:
224                 reg_tmp = reg_tmp + 0x00400000;
225                 break;
226         case 16:
227                 reg_tmp = reg_tmp + 0x00200000;
228                 break;
229         case 32:
230                 reg_tmp = reg_tmp + 0x00000000;
231                 break;
232         default:
233                 reg_tmp = 0; //forces sims not to work if badly configured
234         }
235
236         //Setup DDR Mode
237         switch (ddr_config_parameters->ddr_mode) {
238         case 0:
239                 reg_tmp = reg_tmp + 0x00000000;
240                 break;   //SDR
241         case 1:
242                 reg_tmp = reg_tmp + 0x40000000;
243                 break;   //DDR
244         case 2:
245                 reg_tmp = reg_tmp + 0x80000000;
246                 break;   //DDR2
247         default:
248                 reg_tmp = 0; //forces sims not to work if badly configured
249         }
250
251         //Setup Banks
252         if (ddr_config_parameters->banks8 == 1) {
253                 reg_tmp = reg_tmp + 0x00800000;
254         }
255
256         //Program DDR_CFG register...
257         *(volatile UINT *) C_DDR_CFG_REG = reg_tmp;
258
259         //Configure PHY0 reg - se_mode is bit 1,
260         //needs to be 1 for DDR (single_ended drive)
261         switch (ddr_config_parameters->ddr_mode) {
262         case 0:
263                 reg_tmp = 2 + (0 << 4);
264                 break;   //SDR
265         case 1:
266                 reg_tmp = 2 + (4 << 4);
267                 break;   //DDR
268         case 2:
269                 reg_tmp = 0 + (4 << 4);
270                 break;   //DDR2
271         default:
272                 reg_tmp = 0;
273         }
274
275         //Program DDR_PHY0 register...
276         *(volatile UINT *) C_DDR_REG_PHY0 = reg_tmp;
277
278         //Read DDR_PHY* registers to exercise paths for vcd
279         reg_tmp = *(volatile UINT *) C_DDR_REG_PHY3;
280         reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2;
281         reg_tmp = *(volatile UINT *) C_DDR_REG_PHY1;
282         reg_tmp = *(volatile UINT *) C_DDR_REG_PHY0;
283
284         //Start up sequences - Different dependant on DDR mode
285         switch (ddr_config_parameters->ddr_mode) {
286         case 2:   //DDR2
287                 //Start-up sequence: follows procedure described in Micron datasheet.
288                 //start up DDR PHY DLL
289                 reg_tmp = 0x00022828;       // dll on, start point and inc = h28
290                 *(volatile UINT *) C_DDR_REG_PHY2 = reg_tmp;
291
292                 reg_tmp = 0x00032828; // start on, dll on, start point and inc = h28
293                 *(volatile UINT *) C_DDR_REG_PHY2 = reg_tmp;
294
295                 ddr_phy_poll_until_locked();
296
297                 udelay(200);   //200us
298
299                 //Startup SDRAM...
300                 //!!! Software: CK should be running for 200us before wake-up
301                 ddr_issue_command( C_CMD_WAKE_UP);
302                 ddr_issue_command( C_CMD_NOP);
303                 ddr_issue_command( C_CMD_PRECHARGE_ALL);
304                 ddr_issue_command( C_CMD_DDR2_EMR2);
305                 ddr_issue_command( C_CMD_DDR2_EMR3);
306
307                 emr_cmd = C_CMD_DDR2_EMR1 + C_CMD_ODT_75 + C_CMD_REDUCED_DRIVE
308                         + C_CMD_ENABLE_DLL;
309
310                 ddr_issue_command(emr_cmd);
311                 //Sets CL=3; BL=8 but also reset DLL to trigger a DLL initialisation...
312                 udelay(1);   //1us
313                 ddr_issue_command(
314                         ddr_config_parameters->cmd_mode_wr_cl_bl
315                         + C_CMD_RESET_DLL);
316                 udelay(1);   //1us
317
318                 //!!! Software: Wait 200 CK cycles before...
319                 //for(i=1; i<=2; i++) {
320                 ddr_issue_command(C_CMD_PRECHARGE_ALL);
321                 // !!! Software: Wait here at least 8 CK cycles
322                 //}
323                 //need a wait here to ensure PHY DLL lock before the refresh is issued
324                 udelay(1);   //1us
325                 for (i = 1; i <= 2; i++) {
326                         ddr_issue_command( C_CMD_AUTO_REFRESH);
327                         //!!! Software: Wait here at least 8 CK cycles to satify tRFC
328                         udelay(1);   //1us
329                 }
330                 //As before but without 'RESET_DLL' bit set...
331                 ddr_issue_command(ddr_config_parameters->cmd_mode_wr_cl_bl);
332                 udelay(1);   //1us
333                 // OCD commands
334                 ddr_issue_command(emr_cmd + C_CMD_MODE_DDR2_OCD_DFLT);
335                 ddr_issue_command(emr_cmd + C_CMD_MODE_DDR2_OCD_EXIT);
336                 break;
337
338         default:
339                 break;  //Do nothing
340         }
341
342         //Enable auto-refresh
343
344         // 8192 Refreshes required every 64ms, so maximum refresh period is 7.8125 us
345         // We have a 400 MHz DDR clock (2.5ns period) so max period is 3125 cycles
346         // Our core now does 8 refreshes in a go, so we multiply this period by 8
347
348         refresh = (64000 * mhz) / 8192; // Refresh period in clocks
349
350         reg_tmp = *(volatile UINT *) C_DDR_CFG_REG;      // read
351 #ifdef BURST_REFRESH_ENABLE
352         reg_tmp |= C_CFG_REFRESH_ENABLE | (refresh * 8);
353         reg_tmp |= C_CFG_BURST_REFRESH_ENABLE;
354 #else
355         reg_tmp |= C_CFG_REFRESH_ENABLE | (refresh * 1);
356         reg_tmp &= ~C_CFG_BURST_REFRESH_ENABLE;
357 #endif
358         *(volatile UINT *) C_DDR_CFG_REG = reg_tmp;
359
360         //Verify register contents
361         reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2;      // read
362         //printf("Warning XXXXXXXXXXXXXXXXXXXXXX - get bad read data from C_DDR_PHY2_REG, though it looks OK on bus XXXXXXXXXXXXXXXXXX");
363         //TBD   Check_data (read_data,  dll_reg, "Error: bad C_DDR_PHY2_REG read", tb_pass);
364         reg_tmp = *(volatile UINT *) C_DDR_CFG_REG;      // read
365         //TBD   Check_data (read_data,  cfg_reg, "Error: bad DDR_CFG read", tb_pass);
366
367         //disable optimised wrapping
368         if (ddr_config_parameters->ddr_mode == 2) {
369                 reg_tmp = 0xFFFF0000;
370                 *(volatile UINT *) C_DDR_REG_IGNORE = reg_tmp;
371         }
372
373         //enable midbuffer followon
374         reg_tmp = *(volatile UINT *) C_DDR_ARB_REG;      // read
375         reg_tmp = 0xFFFF0000 | reg_tmp;
376         *(volatile UINT *) C_DDR_ARB_REG = reg_tmp;
377
378         // Enable write behind coherency checking for all clients
379
380         reg_tmp = 0xFFFF0000;
381         *(volatile UINT *) C_DDR_AHB4_REG = reg_tmp;
382
383         //Wait for 200 clock cycles for SDRAM DLL to lock...
384         udelay(1);   //1us
385 }
386
387 // Function used to Setup DDR core
388
389 void ddr_setup(int mhz)
390 {
391         static const T_DDR_TIMING_PARAMETERS *ddr_timing_parameters =
392                 &C_TP_DDR2_25_CL6_1GB;
393         static const T_DDR_CONFIG_PARAMETERS *ddr_config_parameters =
394                 &C_CP_DDR2_25_CL6;
395
396         //Bring core out of Reset
397         *(volatile UINT *) C_DDR_BLKEN_REG = C_BLKEN_DDR_ON;
398
399         //DDR TIMING INITIALISTION
400         ddr_timing_initialisation(ddr_timing_parameters);
401
402         //DDR NORMAL INITIALISATION
403         ddr_normal_initialisation(ddr_config_parameters, mhz);
404
405         // route all writes through one client
406         *(volatile UINT *) C_DDR_TRANSACTION_ROUTING = (0
407                 << DDR_ROUTE_CPU0_INSTR_SHIFT)
408                 | (1 << DDR_ROUTE_CPU0_RDDATA_SHIFT)
409                 | (3 << DDR_ROUTE_CPU0_WRDATA_SHIFT)
410                 | (2 << DDR_ROUTE_CPU1_INSTR_SHIFT)
411                 | (3 << DDR_ROUTE_CPU1_RDDATA_SHIFT)
412                 | (3 << DDR_ROUTE_CPU1_WRDATA_SHIFT);
413
414         //Bring all clients out of reset
415         *(volatile UINT *) C_DDR_BLKEN_REG = C_BLKEN_DDR_ON + 0x0000FFFF;
416
417 }
418
419 void set_ddr_timing(unsigned int w, unsigned int i)
420 {
421         unsigned int reg;
422         unsigned int wnow = 16;
423         unsigned int inow = 32;
424
425         /* reset all timing controls to known value (31) */
426         writel(DDR_PHY_TIMING_W_RST | DDR_PHY_TIMING_I_RST, DDR_PHY_TIMING);
427         writel(DDR_PHY_TIMING_W_RST | DDR_PHY_TIMING_I_RST | DDR_PHY_TIMING_CK,
428                DDR_PHY_TIMING);
429         writel(DDR_PHY_TIMING_W_RST | DDR_PHY_TIMING_I_RST, DDR_PHY_TIMING);
430
431         /* step up or down read delay to the requested value */
432         while (wnow != w) {
433                 if (wnow < w) {
434                         reg = DDR_PHY_TIMING_INC;
435                         wnow++;
436                 } else {
437                         reg = 0;
438                         wnow--;
439                 }
440                 writel(DDR_PHY_TIMING_W_CE | reg, DDR_PHY_TIMING);
441                 writel(DDR_PHY_TIMING_CK | DDR_PHY_TIMING_W_CE | reg,
442                        DDR_PHY_TIMING);
443                 writel(DDR_PHY_TIMING_W_CE | reg, DDR_PHY_TIMING);
444         }
445
446         /* now write delay */
447         while (inow != i) {
448                 if (inow < i) {
449                         reg = DDR_PHY_TIMING_INC;
450                         inow++;
451                 } else {
452                         reg = 0;
453                         inow--;
454                 }
455                 writel(DDR_PHY_TIMING_I_CE | reg, DDR_PHY_TIMING);
456                 writel(DDR_PHY_TIMING_CK | DDR_PHY_TIMING_I_CE | reg,
457                        DDR_PHY_TIMING);
458                 writel(DDR_PHY_TIMING_I_CE | reg, DDR_PHY_TIMING);
459         }
460 }
461
462 //Function used to Setup SDRAM in DDR/SDR mode
463 void init_ddr(int mhz)
464 {
465         /* start clocks */
466         enable_clock(SYS_CTRL_CLK_DDRPHY);
467         enable_clock(SYS_CTRL_CLK_DDR);
468         enable_clock(SYS_CTRL_CLK_DDRCK);
469
470         /* bring phy and core out of reset */
471         reset_block(SYS_CTRL_RST_DDR_PHY, 0);
472         reset_block(SYS_CTRL_RST_DDR, 0);
473
474         /* DDR runs at half the speed of the CPU */
475         ddr_setup(mhz >> 1);
476         return;
477 }