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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright © 2010 by Rafaël Carré
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#define CACHE_NONE 0
#define CACHE_ALL 0x0C
#define UNCACHED_ADDR(a) (a + 0x10000000)
#if defined(SANSA_CLIP) || defined(SANSA_M200V4) || defined(SANSA_C200V2)
/* 16 bits external bus, low power SDRAM, 16 Mbits = 2 Mbytes */
#define MEMORY_MODEL 0x21
#elif defined(SANSA_E200V2) || defined(SANSA_FUZE) || defined(SANSA_CLIPV2) \
|| defined(SANSA_CLIPPLUS) || defined(SANSA_FUZEV2)
/* 16 bits external bus, high performance SDRAM, 64 Mbits = 8 Mbytes */
#define MEMORY_MODEL 0x5
#else
#error "The external memory in your player is unknown"
#endif
.global memory_init
.text
memory_init:
#ifdef BOOTLOADER
ldr r2, =0xC80F0014 @ CGU_PERI
ldr r1, [r2]
orr r1, r1, #(CGU_EXTMEM_CLOCK_ENABLE|CGU_EXTMEMIF_CLOCK_ENABLE)
str r1, [r2]
ldr r3, =0xC6030000 @ MPMC_BASE
mov r2, #1 @ enable MPMC
str r2, [r3] @ MPMC_CONTROL
ldr r2, =0x183 @ SDRAM NOP, all clocks high
str r2, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL
ldr r2, =0x103 @ SDRAM PALL, all clocks high
str r2, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL
ldr r1, =0x138 @ 0x138 * 16 HCLK ticks between SDRAM refresh cycles
str r1, [r3, #0x24] @ MPMC_DYNAMIC_REFRESH
mov r2, #0 @ little endian, HCLK:MPMCCLKOUT[3:0] ratio = 1:1
str r2, [r3, #8] @ MPMC_CONFIG
ldr r2, [r3, #0xfe8] @ MPMC_PERIPH_ID2
tst r2, #0xf0
movne r2, #1 @ command delayed, clock out not delayed
strne r2, [r3, #0x28] @ MPMC_DYNAMIC_READ_CONFIG
mov r1, #2
mov r0, #5
mov ip, #4
mov r2, #0
str r1, [r3, #0x30] @ tRP
str ip, [r3, #0x34] @ tRAS
str r0, [r3, #0x38] @ tSREX
str r2, [r3, #0x3c] @ tAPR
str ip, [r3, #0x40] @ tDAL
str r1, [r3, #0x44] @ tWR
str r0, [r3, #0x48] @ tRC
str r0, [r3, #0x4c] @ tRFC
str r0, [r3, #0x50] @ tXSR
str r1, [r3, #0x54] @ tRRD
str r1, [r3, #0x58] @ tMRD
mov ip, #(MEMORY_MODEL << 7)
str ip, [r3, #0x100] @ MPMC_DYNAMIC_CONFIG_CONFIG_0
orr r1, r1, #(2<<8) @ CAS & RAS latency = 2 clock cycle
str r1, [r3, #0x104] @ MPMC_DYNAMIC_CONFIG_RASCAS_0
str r2, [r3, #0x120] @ MPMC_DYNAMIC_CONFIG_CONFIG_1
str r2, [r3, #0x124] @ MPMC_DYNAMIC_CONFIG_RASCAS_1
str r2, [r3, #0x140] @ MPMC_DYNAMIC_CONFIG_CONFIG_2
str r2, [r3, #0x144] @ MPMC_DYNAMIC_CONFIG_RASCAS_2
str r2, [r3, #0x160] @ MPMC_DYNAMIC_CONFIG_CONFIG_3
str r2, [r3, #0x164] @ MPMC_DYNAMIC_CONFIG_RASCAS_3
mov r1, #0x82 @ SDRAM MODE, MPMCCLKOUT runs continuously
str r1, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL
ldr r1, =DRAM_ORIG+(0x2300*MEM)
ldr r1, [r1]
str r2, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL= SDRAM NORMAL,
@ MPMCCLKOUT stopped when SDRAM is idle
ldr r2, [r3, #0x100] @ MPMC_DYNAMIC_CONFIG_0
orr r2, r2, #(1<<19) @ buffer enable
str r2, [r3, #0x100]
#endif /* BOOTLOADER */
@ XXX: to avoid using the stack, we rely on the fact that:
@ - ttb_init
@ - map_section
@ - enable_mmu
@ do not modify ip (r12)
mov ip, lr
/* Setup MMU */
bl ttb_init
mov r0, #0 @ physical address
mov r1, #0 @ virtual address
mov r2, #0x1000 @ size (all memory)
mov r3, #CACHE_NONE
bl map_section
mov r0, #0 @ physical address
ldr r1, =IRAM_ORIG @ virtual address
mov r2, #1 @ size : 1MB
mov r3, #CACHE_ALL
bl map_section
mov r0, #0 @ physical address
ldr r1, =UNCACHED_ADDR(IRAM_ORIG) @ virtual address
mov r2, #1 @ size : 1MB
mov r3, #CACHE_NONE
bl map_section
mov r0, #0x30000000 @ physical address
mov r1, #DRAM_ORIG @ virtual address
mov r2, #MEMORYSIZE @ size
mov r3, #CACHE_ALL
bl map_section
mov r0, #0x30000000 @ physical address
mov r1, #UNCACHED_ADDR(DRAM_ORIG) @ virtual address
mov r2, #MEMORYSIZE @ size
mov r3, #CACHE_NONE
bl map_section
/* map 1st mbyte of RAM at 0x0 to have exception vectors available */
#ifdef BOOTLOADER
mov r0, #0x81000000 @ physical address
#else
mov r0, #0x30000000 @ physical address
#endif
mov r1, #0 @ virtual address
mov r2, #1 @ size
mov r3, #CACHE_ALL
bl map_section
bl enable_mmu
bx ip
|