ef572809056d334907022d103962a4f9b299ec08
[oweals/u-boot_mod.git] / u-boot / cpu / mips / ar7240 / hornet_ddr_init.S
1 /*
2  *  Startup Code for MIPS32 CPU-core
3  *
4  *  Copyright (c) 2003  Wolfgang Denk <wd@denx.de>
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25
26 #include <config.h>
27 #include <version.h>
28 #include <asm/regdef.h>
29 #include <asm/mipsregs.h>
30 #include <asm/addrspace.h>
31 #include <ar7240_soc.h>
32
33         .globl hornet_ddr_init
34         .text
35         .align 4
36
37 #define set_mem(_mem, _val) \
38         li t9,   _mem;          \
39         sw _val, 0(t9);
40
41 //============================================
42 //   init DDR1 parameter before rel_start
43 //===========================================
44 hornet_ddr_init:
45         // 0x18000000 (DDR_CONFIG, p. 54)
46         // CFG_DDR_CONFIG_VAL = 0x7fbc8cd0 (ap121.h)
47         li t8, CFG_DDR_CONFIG_VAL;
48         set_mem(0xB8000000, t8);
49
50         // 0x18000004 (DDR_CONFIG2, p. 55)
51         // CFG_DDR_CONFIG2_VAL = 0x99d0e6a8 (ap121.h)
52         li t8, CFG_DDR_CONFIG2_VAL;
53         set_mem(0xB8000004, t8);
54
55 /*
56  * WR720N v3 (CH version) has wrong bootstrap configuration,
57  * so the memory type cannot be recognized automatically
58  */
59 #if !defined(CONFIG_FOR_TPLINK_WR720N_V3)
60 mem_type:
61         // TODO: what about SDRAM?
62         // 0x180600AC (BOOT_STRAP, p. 81)
63         li  t8, 0xB80600AC                      // load BOOT_STRAP reg address
64         lw  t9, 0(t8)                           // and its value
65         li  t8, 0x2000                          // 0x2000 -> BIT13 is set
66         and t9, t9, t8
67         beq t9, zero, ddr1_config       // jump if we have DDR1
68
69 ddr2_config:
70         // Enable DDR2
71         // 0x1800008C (DDR_DDR2_CONFIG, p. 58)
72         li t8, 0xA59;
73         set_mem(0xB800008C, t8);
74
75         // Precharge All
76         // 0x18000010 (DDR_CONTROL, p. 56)
77         li t8, 0x8;
78         set_mem(0xB8000010, t8);
79
80         // Disable High Temperature Self-Refresh Rate
81         // 0x18000090 (DDR_EMR2, p. 58)
82         li t8, 0x0;
83         set_mem(0xB8000090, t8);
84
85         // Extended Mode Register 2 Set (EMR2S)
86         // 0x18000010 (DDR_CONTROL, p. 56)
87         li t8, 0x10;
88         set_mem(0xB8000010, t8);
89
90         // 0x18000094 (DDR_EMR3, p. 58)
91         li t8, 0x0;
92         set_mem(0xB8000094, t8);
93
94         // Extended Mode Register 3 Set (EMR3S)
95         // 0x18000010 (DDR_CONTROL, p. 56)
96         li t8, 0x20;
97         set_mem(0xB8000010, t8);
98
99         // Enable DLL
100         // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
101         li t8, 0x0;
102         set_mem(0xB800000C, t8);
103
104         // Extended Mode Register Set (EMRS)
105         // 0x18000010 (DDR_CONTROL, p. 56)
106         li t8, 0x2;
107         set_mem(0xB8000010, t8);
108
109         // Reset DLL
110         // 0x18000008 (DDR_MODE_REGISTER, p. 55)
111         li t8, 0x100;
112         set_mem(0xB8000008, t8);
113
114         // Mode Register Set (MRS)
115         // 0x18000010 (DDR_CONTROL, p. 56)
116         li t8, 0x1;
117         set_mem(0xB8000010, t8);
118
119         // Precharge All
120         // 0x18000010 (DDR_CONTROL, p. 56)
121         li t8, 0x8;
122         set_mem(0xB8000010, t8);
123
124         // Auto Refresh
125         // 0x18000010 (DDR_CONTROL, p. 56)
126         li t8, 0x4;
127         set_mem(0xB8000010, t8);
128
129         // Auto Refresh
130         // 0x18000010 (DDR_CONTROL, p. 56)
131         li t8, 0x4;
132         set_mem(0xB8000010, t8);
133
134         // Write recovery (WR) 6 clock, CAS Latency 3, Burst Length 8
135         // 0x18000008 (DDR_MODE_REGISTER, p. 55)
136         li t8, 0xa33;
137         set_mem(0xB8000008, t8);
138
139         // Mode Register Set (MRS)
140         // 0x18000010 (DDR_CONTROL, p. 56)
141         li t8, 0x1;
142         set_mem(0xB8000010, t8);
143
144         // E7,E8,E9 equal to 1(Enable OCD defaults), Enable DLL, Reduced Drive Strength
145         // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
146         li t8, 0x382;
147         set_mem(0xB800000C, t8);
148
149         // Extended Mode Register Set (EMRS)
150         // 0x18000010 (DDR_CONTROL, p. 56)
151         li t8, 0x2;
152         set_mem(0xB8000010, t8);
153
154         // E7,E8,E9 equal to 0(OCD exit), Enable DLL, Reduced Drive Strength
155         // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
156         li t8, 0x402;
157         set_mem(0xB800000C, t8);
158
159         // Extended Mode Register Set (EMRS)
160         // 0x18000010 (DDR_CONTROL, p. 56)
161         li t8, 0x2;
162         set_mem(0xB8000010, t8);
163
164         // Refresh control. Bit 14 is enable. Bits<13:0> Refresh time
165         // 0x18000014 (DDR_REFRESH, p. 56)
166         li t8, CFG_DDR_REFRESH_VAL;
167         set_mem(0xB8000014, t8);
168
169         // DQS 0 Tap Control (needs tuning)
170         // 0x1800001C (TAP_CONTROL_0, p. 56)
171         li t8, CFG_DDR_TAP0_VAL;
172         set_mem(0xB800001C, t8);
173
174         // DQS 1 Tap Control (needs tuning)
175         // 0x18000020 (TAP_CONTROL_1, p. 57)
176         li t8, CFG_DDR_TAP1_VAL;
177         set_mem(0xB8000020, t8);
178
179         // For 16-bit DDR
180         // 0x18000018 (DDR_RD_DATA_THIS_CYCLE, p. 56)
181         li t8, 0x00ff;
182         set_mem(0xB8000018, t8);
183
184         nop
185         jr ra
186 #endif /* !defined(CONFIG_FOR_TPLINK_WR720N_V3) */
187
188 ddr1_config:
189         // Precharge All
190         // 0x18000010 (DDR_CONTROL, p. 56)
191         li t8, 0x8;
192         set_mem(0xB8000010, t8);
193
194         // 0x18000008 (DDR_MODE_REGISTER, p. 55)
195         li t8, CFG_DDR_MODE_VAL_INIT;
196         set_mem(0xB8000008, t8);
197
198         // Write Mode Word in DDR
199         // 0x18000010 (DDR_CONTROL, p. 56)
200         li t8, 0x1;
201         set_mem(0xB8000010, t8);
202
203         // Enable DLL, High drive strength from DDR
204         // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
205         li t8, 0x2;
206         set_mem(0xB800000C, t8);
207
208         // Write Extended Mode Word of DDR
209         // 0x18000010 (DDR_CONTROL, p. 56)
210         li t8, 0x2;
211         set_mem(0xB8000010, t8);
212
213         // Precharge All
214         // 0x18000010 (DDR_CONTROL, p. 56)
215         li t8, 0x8;
216         set_mem(0xB8000010, t8);
217
218         // DLL out of reset, CAS Latency 3
219         // 0x18000008 (DDR_MODE_REGISTER, p. 55)
220         li t8, CFG_DDR_MODE_VAL;
221         set_mem(0xB8000008, t8);
222
223         // Write mode word
224         // 0x18000010 (DDR_CONTROL, p. 56)
225         li t8, 0x1;
226         set_mem(0xB8000010, t8);
227
228         // Refresh control. Bit 14 is enable. Bits<13:0> Refresh time
229         // 0x18000014 (DDR_REFRESH, p. 56)
230         li t8, CFG_DDR_REFRESH_VAL;
231         set_mem(0xB8000014, t8);
232
233         // DQS 0 Tap Control (needs tuning)
234         // 0x1800001C (TAP_CONTROL_0, p. 56)
235         li t8, CFG_DDR_TAP0_VAL;
236         set_mem(0xB800001C, t8);
237
238         // DQS 1 Tap Control (needs tuning)
239         // 0x18000020 (TAP_CONTROL_1, p. 57)
240         li t8, CFG_DDR_TAP1_VAL;
241         set_mem(0xB8000020, t8);
242
243         // For 16-bit DDR
244         // 0x18000018 (DDR_RD_DATA_THIS_CYCLE, p. 56)
245         li t8, 0x00ff;
246         set_mem(0xB8000018, t8);
247
248         nop
249         jr ra
250     
251 /*
252  * void hornet_ddr_tap_init(void)
253  *
254  * This "function" is used to find the tap settings for the DDR
255  */
256         .globl  hornet_ddr_tap_init
257         .ent    hornet_ddr_tap_init
258 hornet_ddr_tap_init: /* { */
259
260         li      t1,0x80500000 
261         li      t0,0xffffffff 
262          
263         sw      t0,0x0(t1) 
264         sw      t0,0x4(t1) 
265         sw      t0,0x8(t1) 
266         sw      t0,0xc(t1) 
267          
268         nop 
269         nop
270
271 ddr_pat_init:
272         li      t8, 0xa0002000
273         li      t0, 0x00
274         li      t1, 0x100
275
276 write_loop_start:
277         andi    t2, t0, 0x03
278
279 pat_000:
280         li      t3, 0x00
281         bne     t2, t3,pat_001
282         li      t9, 0x00000000
283         sw      t9, 0x0 (t8)
284         b       pat_004
285
286 pat_001:
287         li      t3, 0x01
288         bne     t2, t3,pat_002
289         li      t9, 0x0000ffff
290         sw      t9, 0x0 (t8)
291         b       pat_004
292
293 pat_002:
294         li      t3, 0x02
295         bne     t2, t3,pat_003
296         li      t9, 0xffff0000
297         sw      t9, 0x0 (t8)
298         b       pat_004
299
300 pat_003:
301         li      t3, 0x03
302         bne     t2, t3,pat_004
303         li      t9, 0xffffffff
304         sw      t9, 0x0 (t8)
305
306 pat_004:
307         andi    t2, t0, 0x0c
308         li      t3, 0x00
309         bne     t2, t3,pat_005
310         li      t9, 0x00000000
311         sw      t9, 0x4 (t8)
312         b       pat_008
313
314 pat_005:
315         li      t3, 0x04
316         bne     t2, t3,pat_006
317         li      t9, 0x0000ffff
318         sw      t9, 0x4 (t8)
319         b       pat_008
320
321 pat_006:
322         li      t3, 0x08
323         bne     t2, t3,pat_007
324         li      t9, 0xffff0000
325         sw      t9, 0x4 (t8)
326         b       pat_008
327
328 pat_007:
329         li      t3, 0x0c
330         bne     t2, t3,pat_008
331         li      t9, 0xffffffff
332         sw      t9, 0x4 (t8)
333
334 pat_008:
335         andi    t2, t0, 0x30
336         li      t3, 0x00
337         bne     t2, t3,pat_009
338         li      t9, 0x00000000
339         sw      t9, 0x8 (t8)
340         b       pat_00c
341
342 pat_009:
343         li      t3, 0x10
344         bne     t2, t3,pat_00a
345         li      t9, 0x0000ffff
346         sw      t9, 0x8 (t8)
347         b       pat_00c
348
349 pat_00a:
350         li      t3, 0x20
351         bne     t2, t3,pat_00b
352         li      t9, 0xffff0000
353         sw      t9, 0x8 (t8)
354         b       pat_00c
355
356 pat_00b:
357         li      t3, 0x30
358         bne     t2, t3,pat_00c
359         li      t9, 0xffffffff
360         sw      t9, 0x8 (t8)
361
362 pat_00c:
363         andi    t2, t0, 0xc0
364         li      t3, 0x00
365         bne     t2, t3,pat_00d
366         li      t9, 0x00000000
367         sw      t9, 0xc (t8)
368         b       pat_done
369
370 pat_00d:
371         li      t3, 0x40
372         bne     t2, t3,pat_00e
373         li      t9, 0x0000ffff
374         sw      t9, 0xc (t8)
375         b       pat_done
376
377 pat_00e:
378         li      t3, 0x80
379         bne     t2, t3,pat_00f
380         li      t9, 0xffff0000
381         sw      t9, 0xc (t8)
382         b       pat_done
383
384 pat_00f:
385         li      t3, 0xc0
386         bne     t2, t3,pat_done
387         li      t9, 0xffffffff
388         sw      t9, 0xc (t8)
389
390 pat_done:
391         addiu   t0, t0, 0x1
392         addiu   t8, t8, 0x10
393         bne     t0, t1, write_loop_start
394
395 ###### ddr init over #########
396
397         li      a0, 0xa0002000
398         li      a1, 0x80002000       ### Start address of the pattern   200
399         li      a2, 0x80003000       ### End Address of the pattern     220
400         li      t0, 0xb800001c       ## Tap settings addr
401         lw      a3, 0x0(t0)          ## loading default tap value
402         nop
403         ori     t0, a3, 0x0
404         nop
405         li      t1, 0x1      ## $t1=1 indicates increasing tap value, 0 = decreasing
406
407 load_tap:
408         li      t7, 0x2
409         #li     t7, 0x200       ## No. of times read has to happen for 1 tap setting
410         li      t8, 0xb8000000  #### Loading Tap Setting
411         sw      t0, 0x1c(t8)
412         nop
413         sw      t0, 0x20(t8)
414         nop
415     #if 0 /* Hornet doesn't have DQS2, DQS3*/
416         sw      t0, 0x24(t8)
417         nop
418         sw      t0, 0x28(t8)
419         nop
420     #endif      
421
422 ###### t0 stores current tap setting under test
423 ###### t1 indicates increment or decrement of tap 
424
425 pat_read:
426         ori     t2, a0, 0x0     
427         nop
428         ori     t3, a1, 0x0
429         nop
430         ori     t4, a2, 0x0
431         nop
432
433 tap_addr_loop:
434         lw      t5, 0x0(t2)
435         nop
436         lw      t6, 0x0(t3)
437         nop
438         nop
439         
440         bne     t5, t6, tap_fail  # jump to fail if not equal
441         nop
442         nop
443         nop
444
445         addiu   t2, t2, 0x4  #incrementing addr
446         addiu   t3, t3, 0x4
447         nop
448         nop
449         
450         bne     t3, t4, tap_addr_loop # compare new addr if end addr not reached
451         nop     
452         
453         addiu   t7, t7, -1     # read passed for all locations once hence decrement t7
454         nop
455         bnez    t7, pat_read    # t7 = 0 represents passing of all locations for given tap
456         nop
457         nop
458         
459         bnez    t1, tap_incr     # increment tap if t1 = 1
460         nop
461         nop
462         
463         bnez    t0, tap_decr      ## $t0=0 implies tap=0 works
464         nop                       ## so low limit=0, else decrement tap value
465         nop
466         li      t8, 0x80500000   ## assigning lower limit = 0
467         sw      t0, 0x0(t8)
468         add     t9, t9, t0     ##adding lower limit to upper limit (used to calc mid value)
469         nop
470         nop
471         
472         b tap_calc
473         nop
474         nop
475
476 tap_decr:                       # decrement t0 by 1 and move to loading this new tap
477         addiu   t0, t0 , -1
478         nop
479         b load_tap
480         nop
481         nop
482
483 tap_incr:
484         addiu   t0, t0 , 0x1
485         nop
486         xori    v1, t0, 0x20    # limiting upper limit to 0x20
487         nop
488         bnez    v1, load_tap
489         nop
490         nop
491         b up_limit
492         nop
493         nop
494
495 tap_fail:
496         bnez    t1, up_limit    # t1=0 means lower limit detected @ fail else upper limit
497         nop
498         nop
499         nop
500         addiu   t0, t0, 0x1
501         nop
502         li      t8, 0x80500000  # storing lower limit
503         nop
504         sw      t0, 0x0(t8)
505         add     t9, t9, t0      # storing lower limit# adding lower limit and upper limit
506         nop
507         nop
508         nop
509         
510         b tap_calc
511         nop
512         nop
513
514 up_limit:
515         addiu   t0, t0, -1 
516         li      t1, 0x0  ## changing to decreasing tap mode     
517         li      t8, 0x80500000 ## storing upper limit
518         sw      t0, 0x4(t8)     
519         ori     t9, t0, 0x0     
520         nop
521         nop
522         nop
523         
524         ori     t0, a3, 0x0     # loading default tap value 
525         nop
526         b load_tap
527         nop
528         nop
529
530 tap_calc:  ## calculating mid value of the tap, storing DQS0, DQS1 in 0x80500008, 0x8050000c resp.
531         li      t7, 0x2
532         nop
533         div     t9, t7
534         nop
535         mfhi    t6
536         mflo    t5
537         nop
538         nop
539         add     t6, t6, t5
540         li      t8, 0x80500000
541         nop
542         sw      t5, 0x8(t8)
543         nop
544         sw      t6, 0xc(t8)
545         nop
546         nop
547         li      t8, 0xb8000000  #### Loading Tap Setting
548         nop
549         sw      t5, 0x1c(t8)
550         nop
551         sw      t6, 0x20(t8)
552         nop
553         nop
554         nop
555
556 end:
557         nop
558         nop
559         nop
560         jr      ra
561
562         .end    hornet_ddr_tap_init
563 /* } */