~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/arm/plat-omap/sram.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 * Copyright (C) 2009 Texas Instruments
 
10
 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
 
11
 *
 
12
 * This program is free software; you can redistribute it and/or modify
 
13
 * it under the terms of the GNU General Public License version 2 as
 
14
 * published by the Free Software Foundation.
 
15
 */
 
16
#undef DEBUG
 
17
 
 
18
#include <linux/module.h>
 
19
#include <linux/kernel.h>
 
20
#include <linux/init.h>
 
21
#include <linux/io.h>
 
22
 
 
23
#include <asm/tlb.h>
 
24
#include <asm/cacheflush.h>
 
25
 
 
26
#include <asm/mach/map.h>
 
27
 
 
28
#include <plat/sram.h>
 
29
#include <plat/board.h>
 
30
#include <plat/cpu.h>
 
31
 
 
32
#include "sram.h"
 
33
 
 
34
/* XXX These "sideways" includes are a sign that something is wrong */
 
35
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 
36
# include "../mach-omap2/prm2xxx_3xxx.h"
 
37
# include "../mach-omap2/sdrc.h"
 
38
#endif
 
39
 
 
40
#define OMAP1_SRAM_PA           0x20000000
 
41
#define OMAP2_SRAM_PUB_PA       (OMAP2_SRAM_PA + 0xf800)
 
42
#define OMAP3_SRAM_PUB_PA       (OMAP3_SRAM_PA + 0x8000)
 
43
#define OMAP4_SRAM_PUB_PA       (OMAP4_SRAM_PA + 0x4000)
 
44
 
 
45
#if defined(CONFIG_ARCH_OMAP2PLUS)
 
46
#define SRAM_BOOTLOADER_SZ      0x00
 
47
#else
 
48
#define SRAM_BOOTLOADER_SZ      0x80
 
49
#endif
 
50
 
 
51
#define OMAP24XX_VA_REQINFOPERM0        OMAP2_L3_IO_ADDRESS(0x68005048)
 
52
#define OMAP24XX_VA_READPERM0           OMAP2_L3_IO_ADDRESS(0x68005050)
 
53
#define OMAP24XX_VA_WRITEPERM0          OMAP2_L3_IO_ADDRESS(0x68005058)
 
54
 
 
55
#define OMAP34XX_VA_REQINFOPERM0        OMAP2_L3_IO_ADDRESS(0x68012848)
 
56
#define OMAP34XX_VA_READPERM0           OMAP2_L3_IO_ADDRESS(0x68012850)
 
57
#define OMAP34XX_VA_WRITEPERM0          OMAP2_L3_IO_ADDRESS(0x68012858)
 
58
#define OMAP34XX_VA_ADDR_MATCH2         OMAP2_L3_IO_ADDRESS(0x68012880)
 
59
#define OMAP34XX_VA_SMS_RG_ATT0         OMAP2_L3_IO_ADDRESS(0x6C000048)
 
60
 
 
61
#define GP_DEVICE               0x300
 
62
 
 
63
#define ROUND_DOWN(value,boundary)      ((value) & (~((boundary)-1)))
 
64
 
 
65
static unsigned long omap_sram_start;
 
66
static void __iomem *omap_sram_base;
 
67
static unsigned long omap_sram_size;
 
68
static void __iomem *omap_sram_ceil;
 
69
 
 
70
/*
 
71
 * Depending on the target RAMFS firewall setup, the public usable amount of
 
72
 * SRAM varies.  The default accessible size for all device types is 2k. A GP
 
73
 * device allows ARM11 but not other initiators for full size. This
 
74
 * functionality seems ok until some nice security API happens.
 
75
 */
 
76
static int is_sram_locked(void)
 
77
{
 
78
        if (OMAP2_DEVICE_TYPE_GP == omap_type()) {
 
79
                /* RAMFW: R/W access to all initiators for all qualifier sets */
 
80
                if (cpu_is_omap242x()) {
 
81
                        __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
 
82
                        __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0);  /* all i-read */
 
83
                        __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
 
84
                }
 
85
                if (cpu_is_omap34xx()) {
 
86
                        __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
 
87
                        __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0);  /* all i-read */
 
88
                        __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
 
89
                        __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2);
 
90
                        __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0);
 
91
                }
 
92
                return 0;
 
93
        } else
 
94
                return 1; /* assume locked with no PPA or security driver */
 
95
}
 
96
 
 
97
/*
 
98
 * The amount of SRAM depends on the core type.
 
99
 * Note that we cannot try to test for SRAM here because writes
 
100
 * to secure SRAM will hang the system. Also the SRAM is not
 
101
 * yet mapped at this point.
 
102
 */
 
103
static void __init omap_detect_sram(void)
 
104
{
 
105
        if (cpu_class_is_omap2()) {
 
106
                if (is_sram_locked()) {
 
107
                        if (cpu_is_omap34xx()) {
 
108
                                omap_sram_start = OMAP3_SRAM_PUB_PA;
 
109
                                if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||
 
110
                                    (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {
 
111
                                        omap_sram_size = 0x7000; /* 28K */
 
112
                                } else {
 
113
                                        omap_sram_size = 0x8000; /* 32K */
 
114
                                }
 
115
                        } else if (cpu_is_omap44xx()) {
 
116
                                omap_sram_start = OMAP4_SRAM_PUB_PA;
 
117
                                omap_sram_size = 0xa000; /* 40K */
 
118
                        } else {
 
119
                                omap_sram_start = OMAP2_SRAM_PUB_PA;
 
120
                                omap_sram_size = 0x800; /* 2K */
 
121
                        }
 
122
                } else {
 
123
                        if (cpu_is_omap34xx()) {
 
124
                                omap_sram_start = OMAP3_SRAM_PA;
 
125
                                omap_sram_size = 0x10000; /* 64K */
 
126
                        } else if (cpu_is_omap44xx()) {
 
127
                                omap_sram_start = OMAP4_SRAM_PA;
 
128
                                omap_sram_size = 0xe000; /* 56K */
 
129
                        } else {
 
130
                                omap_sram_start = OMAP2_SRAM_PA;
 
131
                                if (cpu_is_omap242x())
 
132
                                        omap_sram_size = 0xa0000; /* 640K */
 
133
                                else if (cpu_is_omap243x())
 
134
                                        omap_sram_size = 0x10000; /* 64K */
 
135
                        }
 
136
                }
 
137
        } else {
 
138
                omap_sram_start = OMAP1_SRAM_PA;
 
139
 
 
140
                if (cpu_is_omap7xx())
 
141
                        omap_sram_size = 0x32000;       /* 200K */
 
142
                else if (cpu_is_omap15xx())
 
143
                        omap_sram_size = 0x30000;       /* 192K */
 
144
                else if (cpu_is_omap1610() || cpu_is_omap1621() ||
 
145
                     cpu_is_omap1710())
 
146
                        omap_sram_size = 0x4000;        /* 16K */
 
147
                else if (cpu_is_omap1611())
 
148
                        omap_sram_size = SZ_256K;
 
149
                else {
 
150
                        pr_err("Could not detect SRAM size\n");
 
151
                        omap_sram_size = 0x4000;
 
152
                }
 
153
        }
 
154
}
 
155
 
 
156
/*
 
157
 * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
 
158
 */
 
159
static void __init omap_map_sram(void)
 
160
{
 
161
        int cached = 1;
 
162
 
 
163
        if (omap_sram_size == 0)
 
164
                return;
 
165
 
 
166
        if (cpu_is_omap34xx()) {
 
167
                /*
 
168
                 * SRAM must be marked as non-cached on OMAP3 since the
 
169
                 * CORE DPLL M2 divider change code (in SRAM) runs with the
 
170
                 * SDRAM controller disabled, and if it is marked cached,
 
171
                 * the ARM may attempt to write cache lines back to SDRAM
 
172
                 * which will cause the system to hang.
 
173
                 */
 
174
                cached = 0;
 
175
        }
 
176
 
 
177
        omap_sram_start = ROUND_DOWN(omap_sram_start, PAGE_SIZE);
 
178
        omap_sram_base = __arm_ioremap_exec(omap_sram_start, omap_sram_size,
 
179
                                                cached);
 
180
        if (!omap_sram_base) {
 
181
                pr_err("SRAM: Could not map\n");
 
182
                return;
 
183
        }
 
184
 
 
185
        omap_sram_ceil = omap_sram_base + omap_sram_size;
 
186
 
 
187
        /*
 
188
         * Looks like we need to preserve some bootloader code at the
 
189
         * beginning of SRAM for jumping to flash for reboot to work...
 
190
         */
 
191
        memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0,
 
192
               omap_sram_size - SRAM_BOOTLOADER_SZ);
 
193
}
 
194
 
 
195
/*
 
196
 * Memory allocator for SRAM: calculates the new ceiling address
 
197
 * for pushing a function using the fncpy API.
 
198
 *
 
199
 * Note that fncpy requires the returned address to be aligned
 
200
 * to an 8-byte boundary.
 
201
 */
 
202
void *omap_sram_push_address(unsigned long size)
 
203
{
 
204
        unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
 
205
 
 
206
        available = omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ);
 
207
 
 
208
        if (size > available) {
 
209
                pr_err("Not enough space in SRAM\n");
 
210
                return NULL;
 
211
        }
 
212
 
 
213
        new_ceil -= size;
 
214
        new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN);
 
215
        omap_sram_ceil = IOMEM(new_ceil);
 
216
 
 
217
        return (void *)omap_sram_ceil;
 
218
}
 
219
 
 
220
#ifdef CONFIG_ARCH_OMAP1
 
221
 
 
222
static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
 
223
 
 
224
void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
 
225
{
 
226
        BUG_ON(!_omap_sram_reprogram_clock);
 
227
        _omap_sram_reprogram_clock(dpllctl, ckctl);
 
228
}
 
229
 
 
230
static int __init omap1_sram_init(void)
 
231
{
 
232
        _omap_sram_reprogram_clock =
 
233
                        omap_sram_push(omap1_sram_reprogram_clock,
 
234
                                        omap1_sram_reprogram_clock_sz);
 
235
 
 
236
        return 0;
 
237
}
 
238
 
 
239
#else
 
240
#define omap1_sram_init()       do {} while (0)
 
241
#endif
 
242
 
 
243
#if defined(CONFIG_ARCH_OMAP2)
 
244
 
 
245
static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
 
246
                              u32 base_cs, u32 force_unlock);
 
247
 
 
248
void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
 
249
                   u32 base_cs, u32 force_unlock)
 
250
{
 
251
        BUG_ON(!_omap2_sram_ddr_init);
 
252
        _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
 
253
                             base_cs, force_unlock);
 
254
}
 
255
 
 
256
static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
 
257
                                          u32 mem_type);
 
258
 
 
259
void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
 
260
{
 
261
        BUG_ON(!_omap2_sram_reprogram_sdrc);
 
262
        _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
 
263
}
 
264
 
 
265
static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 
266
 
 
267
u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
 
268
{
 
269
        BUG_ON(!_omap2_set_prcm);
 
270
        return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
 
271
}
 
272
#endif
 
273
 
 
274
#ifdef CONFIG_SOC_OMAP2420
 
275
static int __init omap242x_sram_init(void)
 
276
{
 
277
        _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init,
 
278
                                        omap242x_sram_ddr_init_sz);
 
279
 
 
280
        _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc,
 
281
                                            omap242x_sram_reprogram_sdrc_sz);
 
282
 
 
283
        _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm,
 
284
                                         omap242x_sram_set_prcm_sz);
 
285
 
 
286
        return 0;
 
287
}
 
288
#else
 
289
static inline int omap242x_sram_init(void)
 
290
{
 
291
        return 0;
 
292
}
 
293
#endif
 
294
 
 
295
#ifdef CONFIG_SOC_OMAP2430
 
296
static int __init omap243x_sram_init(void)
 
297
{
 
298
        _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init,
 
299
                                        omap243x_sram_ddr_init_sz);
 
300
 
 
301
        _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc,
 
302
                                            omap243x_sram_reprogram_sdrc_sz);
 
303
 
 
304
        _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm,
 
305
                                         omap243x_sram_set_prcm_sz);
 
306
 
 
307
        return 0;
 
308
}
 
309
#else
 
310
static inline int omap243x_sram_init(void)
 
311
{
 
312
        return 0;
 
313
}
 
314
#endif
 
315
 
 
316
#ifdef CONFIG_ARCH_OMAP3
 
317
 
 
318
static u32 (*_omap3_sram_configure_core_dpll)(
 
319
                        u32 m2, u32 unlock_dll, u32 f, u32 inc,
 
320
                        u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
 
321
                        u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
 
322
                        u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
 
323
                        u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
 
324
 
 
325
u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,
 
326
                        u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
 
327
                        u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
 
328
                        u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
 
329
                        u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1)
 
330
{
 
331
        BUG_ON(!_omap3_sram_configure_core_dpll);
 
332
        return _omap3_sram_configure_core_dpll(
 
333
                        m2, unlock_dll, f, inc,
 
334
                        sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0,
 
335
                        sdrc_actim_ctrl_b_0, sdrc_mr_0,
 
336
                        sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1,
 
337
                        sdrc_actim_ctrl_b_1, sdrc_mr_1);
 
338
}
 
339
 
 
340
#ifdef CONFIG_PM
 
341
void omap3_sram_restore_context(void)
 
342
{
 
343
        omap_sram_ceil = omap_sram_base + omap_sram_size;
 
344
 
 
345
        _omap3_sram_configure_core_dpll =
 
346
                omap_sram_push(omap3_sram_configure_core_dpll,
 
347
                               omap3_sram_configure_core_dpll_sz);
 
348
        omap_push_sram_idle();
 
349
}
 
350
#endif /* CONFIG_PM */
 
351
 
 
352
#endif /* CONFIG_ARCH_OMAP3 */
 
353
 
 
354
static inline int omap34xx_sram_init(void)
 
355
{
 
356
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
 
357
        omap3_sram_restore_context();
 
358
#endif
 
359
        return 0;
 
360
}
 
361
 
 
362
int __init omap_sram_init(void)
 
363
{
 
364
        omap_detect_sram();
 
365
        omap_map_sram();
 
366
 
 
367
        if (!(cpu_class_is_omap2()))
 
368
                omap1_sram_init();
 
369
        else if (cpu_is_omap242x())
 
370
                omap242x_sram_init();
 
371
        else if (cpu_is_omap2430())
 
372
                omap243x_sram_init();
 
373
        else if (cpu_is_omap34xx())
 
374
                omap34xx_sram_init();
 
375
 
 
376
        return 0;
 
377
}