Blame view

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