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