Merge tag 'cris-for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jesper...
[cascardo/linux.git] / arch / cris / arch-v10 / lib / dram_init.S
1 /*
2  * DRAM/SDRAM initialization - alter with care
3  * This file is intended to be included from other assembler files
4  *
5  * Note: This file may not modify r9 because r9 is used to carry
6  *       information from the decompressor to the kernel
7  *
8  * Copyright (C) 2000-2012 Axis Communications AB
9  *
10  */
11
12 /* Just to be certain the config file is included, we include it here
13  * explicitly instead of depending on it being included in the file that
14  * uses this code.
15  */
16
17
18         ;; WARNING! The registers r8 and r9 are used as parameters carrying
19         ;; information from the decompressor (if the kernel was compressed).
20         ;; They should not be used in the code below.
21
22         move.d   CONFIG_ETRAX_DEF_R_WAITSTATES, $r0
23         move.d   $r0, [R_WAITSTATES]
24
25         move.d   CONFIG_ETRAX_DEF_R_BUS_CONFIG, $r0
26         move.d   $r0, [R_BUS_CONFIG]
27
28 #ifndef CONFIG_ETRAX_SDRAM
29         move.d   CONFIG_ETRAX_DEF_R_DRAM_CONFIG, $r0
30         move.d   $r0, [R_DRAM_CONFIG]
31
32         move.d   CONFIG_ETRAX_DEF_R_DRAM_TIMING, $r0
33         move.d   $r0, [R_DRAM_TIMING]
34 #else
35         ;; Samsung SDRAMs seem to require to be initialized twice to work properly.
36         moveq    2, $r6 
37 _sdram_init:
38
39         ; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
40
41         ; Bank configuration
42         move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r0
43         move.d   $r0, [R_SDRAM_CONFIG]
44
45         ; Calculate value of mrs_data
46         ; CAS latency = 2 && bus_width = 32 => 0x40
47         ; CAS latency = 3 && bus_width = 32 => 0x60
48         ; CAS latency = 2 && bus_width = 16 => 0x20
49         ; CAS latency = 3 && bus_width = 16 => 0x30
50
51         ; Check if value is already supplied in kernel config
52         move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r2
53         and.d    0x00ff0000, $r2
54         bne      _set_timing
55         lsrq     16, $r2
56
57         move.d   0x40, $r2       ; Assume 32 bits and CAS latency = 2
58         move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
59         move.d   $r1, $r3
60         and.d    0x03, $r1       ; Get CAS latency
61         and.d    0x1000, $r3     ; 50 or 100 MHz?
62         beq      _speed_50
63         nop
64 _speed_100:
65         cmp.d    0x00, $r1      ; CAS latency = 2?
66         beq      _bw_check
67         nop
68         or.d     0x20, $r2      ; CAS latency = 3
69         ba       _bw_check
70         nop
71 _speed_50:
72         cmp.d    0x01, $r1      ; CAS latency = 2?
73         beq      _bw_check
74         nop
75         or.d     0x20, $r2       ; CAS latency = 3
76 _bw_check:
77         move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r1
78         and.d    0x800000, $r1  ; DRAM width is bit 23
79         bne      _set_timing
80         nop
81         lsrq     1, $r2         ;  16 bits. Shift down value.
82
83         ; Set timing parameters. Starts master clock
84 _set_timing:
85         move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
86         and.d    0x8000f9ff, $r1 ; Make sure mrs data and command is 0
87         or.d     0x80000000, $r1        ; Make sure sdram enable bit is set
88         move.d   $r1, $r5
89         or.d     0x0000c000, $r1 ; ref = disable
90         lslq     16, $r2                ; mrs data starts at bit 16
91         or.d     $r2, $r1
92         move.d   $r1, [R_SDRAM_TIMING]
93
94         ; Wait 200us
95         move.d   10000, $r2
96 1:      bne      1b
97         subq     1, $r2
98
99         ; Issue initialization command sequence
100         move.d   _sdram_commands_start, $r2
101         and.d    0x000fffff, $r2 ; Make sure commands are read from flash
102         move.d   _sdram_commands_end,  $r3
103         and.d    0x000fffff, $r3
104 1:      clear.d  $r4
105         move.b   [$r2+], $r4
106         lslq     9, $r4 ; Command starts at bit 9
107         or.d     $r1, $r4
108         move.d   $r4, [R_SDRAM_TIMING]
109         nop             ; Wait five nop cycles between each command
110         nop
111         nop
112         nop
113         nop
114         cmp.d    $r2, $r3
115         bne      1b
116         nop
117         move.d   $r5, [R_SDRAM_TIMING]
118         subq     1, $r6
119         bne      _sdram_init
120         nop
121         ba       _sdram_commands_end
122         nop
123
124 _sdram_commands_start:
125         .byte   3       ; Precharge
126         .byte   0       ; nop
127         .byte   2       ; refresh
128         .byte   0       ; nop
129         .byte   2       ; refresh
130         .byte   0       ; nop
131         .byte   2       ; refresh
132         .byte   0       ; nop
133         .byte   2       ; refresh
134         .byte   0       ; nop
135         .byte   2       ; refresh
136         .byte   0       ; nop
137         .byte   2       ; refresh
138         .byte   0       ; nop
139         .byte   2       ; refresh
140         .byte   0       ; nop
141         .byte   2       ; refresh
142         .byte   0       ; nop
143         .byte   1       ; mrs
144         .byte   0       ; nop
145 _sdram_commands_end:
146 #endif