]>
Commit | Line | Data |
---|---|---|
92105bb7 TL |
1 | /* |
2 | * linux/arch/arm/plat-omap/sram.c | |
3 | * | |
4 | * OMAP SRAM detection and management | |
5 | * | |
6 | * Copyright (C) 2005 Nokia Corporation | |
7 | * Written by Tony Lindgren <tony@atomide.com> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License version 2 as | |
11 | * published by the Free Software Foundation. | |
12 | */ | |
13 | ||
14 | #include <linux/config.h> | |
15 | #include <linux/module.h> | |
16 | #include <linux/kernel.h> | |
17 | #include <linux/init.h> | |
18 | ||
19 | #include <asm/mach/map.h> | |
20 | #include <asm/io.h> | |
21 | #include <asm/cacheflush.h> | |
22 | ||
1a8bfa1e TL |
23 | #include <asm/arch/sram.h> |
24 | ||
25 | #define OMAP1_SRAM_PA 0x20000000 | |
26 | #define OMAP1_SRAM_VA 0xd0000000 | |
27 | #define OMAP2_SRAM_PA 0x40200000 | |
28 | #define OMAP2_SRAM_VA 0xd0000000 | |
92105bb7 | 29 | |
92105bb7 TL |
30 | #define SRAM_BOOTLOADER_SZ 0x80 |
31 | ||
32 | static unsigned long omap_sram_base; | |
33 | static unsigned long omap_sram_size; | |
34 | static unsigned long omap_sram_ceil; | |
35 | ||
36 | /* | |
1a8bfa1e | 37 | * The amount of SRAM depends on the core type. |
92105bb7 TL |
38 | * Note that we cannot try to test for SRAM here because writes |
39 | * to secure SRAM will hang the system. Also the SRAM is not | |
40 | * yet mapped at this point. | |
41 | */ | |
42 | void __init omap_detect_sram(void) | |
43 | { | |
1a8bfa1e TL |
44 | if (!cpu_is_omap24xx()) |
45 | omap_sram_base = OMAP1_SRAM_VA; | |
46 | else | |
47 | omap_sram_base = OMAP2_SRAM_VA; | |
92105bb7 TL |
48 | |
49 | if (cpu_is_omap730()) | |
1a8bfa1e TL |
50 | omap_sram_size = 0x32000; /* 200K */ |
51 | else if (cpu_is_omap15xx()) | |
52 | omap_sram_size = 0x30000; /* 192K */ | |
92105bb7 | 53 | else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) |
1a8bfa1e | 54 | omap_sram_size = 0x4000; /* 16K */ |
92105bb7 | 55 | else if (cpu_is_omap1611()) |
1a8bfa1e TL |
56 | omap_sram_size = 0x3e800; /* 250K */ |
57 | else if (cpu_is_omap2420()) | |
58 | omap_sram_size = 0xa0014; /* 640K */ | |
92105bb7 TL |
59 | else { |
60 | printk(KERN_ERR "Could not detect SRAM size\n"); | |
61 | omap_sram_size = 0x4000; | |
62 | } | |
63 | ||
92105bb7 TL |
64 | omap_sram_ceil = omap_sram_base + omap_sram_size; |
65 | } | |
66 | ||
67 | static struct map_desc omap_sram_io_desc[] __initdata = { | |
9fe133b1 | 68 | { /* .length gets filled in at runtime */ |
1a8bfa1e TL |
69 | .virtual = OMAP1_SRAM_VA, |
70 | .pfn = __phys_to_pfn(OMAP1_SRAM_PA), | |
9fe133b1 DS |
71 | .type = MT_DEVICE |
72 | } | |
92105bb7 TL |
73 | }; |
74 | ||
75 | /* | |
76 | * In order to use last 2kB of SRAM on 1611b, we must round the size | |
77 | * up to multiple of PAGE_SIZE. We cannot use ioremap for SRAM, as | |
78 | * clock init needs SRAM early. | |
79 | */ | |
80 | void __init omap_map_sram(void) | |
81 | { | |
82 | if (omap_sram_size == 0) | |
83 | return; | |
84 | ||
1a8bfa1e TL |
85 | if (cpu_is_omap24xx()) { |
86 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; | |
87 | omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA); | |
88 | } | |
89 | ||
92105bb7 TL |
90 | omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; |
91 | omap_sram_io_desc[0].length *= PAGE_SIZE; | |
92 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); | |
93 | ||
1a8bfa1e TL |
94 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", |
95 | omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual, | |
96 | omap_sram_io_desc[0].length); | |
97 | ||
92105bb7 TL |
98 | /* |
99 | * Looks like we need to preserve some bootloader code at the | |
100 | * beginning of SRAM for jumping to flash for reboot to work... | |
101 | */ | |
102 | memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0, | |
103 | omap_sram_size - SRAM_BOOTLOADER_SZ); | |
104 | } | |
105 | ||
92105bb7 TL |
106 | void * omap_sram_push(void * start, unsigned long size) |
107 | { | |
108 | if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { | |
109 | printk(KERN_ERR "Not enough space in SRAM\n"); | |
110 | return NULL; | |
111 | } | |
112 | omap_sram_ceil -= size; | |
113 | omap_sram_ceil &= ~0x3; | |
114 | memcpy((void *)omap_sram_ceil, start, size); | |
115 | ||
116 | return (void *)omap_sram_ceil; | |
117 | } | |
118 | ||
1a8bfa1e TL |
119 | static void omap_sram_error(void) |
120 | { | |
121 | panic("Uninitialized SRAM function\n"); | |
122 | } | |
123 | ||
124 | #ifdef CONFIG_ARCH_OMAP1 | |
125 | ||
126 | static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl); | |
127 | ||
128 | void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) | |
129 | { | |
130 | if (!_omap_sram_reprogram_clock) | |
131 | omap_sram_error(); | |
132 | ||
133 | return _omap_sram_reprogram_clock(dpllctl, ckctl); | |
134 | } | |
135 | ||
136 | int __init omap1_sram_init(void) | |
92105bb7 | 137 | { |
92105bb7 TL |
138 | _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock, |
139 | sram_reprogram_clock_sz); | |
1a8bfa1e TL |
140 | |
141 | return 0; | |
142 | } | |
143 | ||
144 | #else | |
145 | #define omap1_sram_init() do {} while (0) | |
146 | #endif | |
147 | ||
148 | #ifdef CONFIG_ARCH_OMAP2 | |
149 | ||
150 | static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | |
151 | u32 base_cs, u32 force_unlock); | |
152 | ||
153 | void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | |
154 | u32 base_cs, u32 force_unlock) | |
155 | { | |
156 | if (!_omap2_sram_ddr_init) | |
157 | omap_sram_error(); | |
158 | ||
159 | return _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, | |
160 | base_cs, force_unlock); | |
161 | } | |
162 | ||
163 | static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val, | |
164 | u32 mem_type); | |
165 | ||
166 | void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type) | |
167 | { | |
168 | if (!_omap2_sram_reprogram_sdrc) | |
169 | omap_sram_error(); | |
170 | ||
171 | return _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); | |
172 | } | |
173 | ||
174 | static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); | |
175 | ||
176 | u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) | |
177 | { | |
178 | if (!_omap2_set_prcm) | |
179 | omap_sram_error(); | |
180 | ||
181 | return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); | |
182 | } | |
183 | ||
184 | int __init omap2_sram_init(void) | |
185 | { | |
186 | _omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz); | |
187 | ||
188 | _omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc, | |
189 | sram_reprogram_sdrc_sz); | |
190 | _omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz); | |
191 | ||
192 | return 0; | |
193 | } | |
194 | #else | |
195 | #define omap2_sram_init() do {} while (0) | |
196 | #endif | |
197 | ||
198 | int __init omap_sram_init(void) | |
199 | { | |
200 | omap_detect_sram(); | |
201 | omap_map_sram(); | |
202 | ||
203 | if (!cpu_is_omap24xx()) | |
204 | omap1_sram_init(); | |
205 | else | |
206 | omap2_sram_init(); | |
207 | ||
208 | return 0; | |
92105bb7 | 209 | } |