aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/setup.c
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-05-06 17:50:22 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 15:12:58 -0400
commit1394f03221790a988afc3e4b3cb79f2e477246a9 (patch)
tree2c1963c9a4f2d84a5e021307fde240c5d567cf70 /arch/blackfin/kernel/setup.c
parent73243284463a761e04d69d22c7516b2be7de096c (diff)
blackfin architecture
This adds support for the Analog Devices Blackfin processor architecture, and currently supports the BF533, BF532, BF531, BF537, BF536, BF534, and BF561 (Dual Core) devices, with a variety of development platforms including those avaliable from Analog Devices (BF533-EZKit, BF533-STAMP, BF537-STAMP, BF561-EZKIT), and Bluetechnix! Tinyboards. The Blackfin architecture was jointly developed by Intel and Analog Devices Inc. (ADI) as the Micro Signal Architecture (MSA) core and introduced it in December of 2000. Since then ADI has put this core into its Blackfin processor family of devices. The Blackfin core has the advantages of a clean, orthogonal,RISC-like microprocessor instruction set. It combines a dual-MAC (Multiply/Accumulate), state-of-the-art signal processing engine and single-instruction, multiple-data (SIMD) multimedia capabilities into a single instruction-set architecture. The Blackfin architecture, including the instruction set, is described by the ADSP-BF53x/BF56x Blackfin Processor Programming Reference http://blackfin.uclinux.org/gf/download/frsrelease/29/2549/Blackfin_PRM.pdf The Blackfin processor is already supported by major releases of gcc, and there are binary and source rpms/tarballs for many architectures at: http://blackfin.uclinux.org/gf/project/toolchain/frs There is complete documentation, including "getting started" guides available at: http://docs.blackfin.uclinux.org/ which provides links to the sources and patches you will need in order to set up a cross-compiling environment for bfin-linux-uclibc This patch, as well as the other patches (toolchain, distribution, uClibc) are actively supported by Analog Devices Inc, at: http://blackfin.uclinux.org/ We have tested this on LTP, and our test plan (including pass/fails) can be found at: http://docs.blackfin.uclinux.org/doku.php?id=testing_the_linux_kernel [m.kozlowski@tuxland.pl: balance parenthesis in blackfin header files] Signed-off-by: Bryan Wu <bryan.wu@analog.com> Signed-off-by: Mariusz Kozlowski <m.kozlowski@tuxland.pl> Signed-off-by: Aubrey Li <aubrey.li@analog.com> Signed-off-by: Jie Zhang <jie.zhang@analog.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/blackfin/kernel/setup.c')
-rw-r--r--arch/blackfin/kernel/setup.c902
1 files changed, 902 insertions, 0 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
new file mode 100644
index 000000000000..342bb8dd56ac
--- /dev/null
+++ b/arch/blackfin/kernel/setup.c
@@ -0,0 +1,902 @@
1/*
2 * File: arch/blackfin/kernel/setup.c
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/delay.h>
31#include <linux/console.h>
32#include <linux/bootmem.h>
33#include <linux/seq_file.h>
34#include <linux/cpu.h>
35#include <linux/module.h>
36#include <linux/console.h>
37#include <linux/tty.h>
38
39#include <linux/ext2_fs.h>
40#include <linux/cramfs_fs.h>
41#include <linux/romfs_fs.h>
42
43#include <asm/cacheflush.h>
44#include <asm/blackfin.h>
45#include <asm/cplbinit.h>
46
47unsigned long memory_start, memory_end, physical_mem_end;
48unsigned long reserved_mem_dcache_on;
49unsigned long reserved_mem_icache_on;
50EXPORT_SYMBOL(memory_start);
51EXPORT_SYMBOL(memory_end);
52EXPORT_SYMBOL(physical_mem_end);
53EXPORT_SYMBOL(_ramend);
54
55#ifdef CONFIG_MTD_UCLINUX
56unsigned long memory_mtd_end, memory_mtd_start, mtd_size;
57unsigned long _ebss;
58EXPORT_SYMBOL(memory_mtd_end);
59EXPORT_SYMBOL(memory_mtd_start);
60EXPORT_SYMBOL(mtd_size);
61#endif
62
63char command_line[COMMAND_LINE_SIZE];
64
65#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
66static void generate_cpl_tables(void);
67#endif
68
69void __init bf53x_cache_init(void)
70{
71#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
72 generate_cpl_tables();
73#endif
74
75#ifdef CONFIG_BLKFIN_CACHE
76 bfin_icache_init();
77 printk(KERN_INFO "Instruction Cache Enabled\n");
78#endif
79
80#ifdef CONFIG_BLKFIN_DCACHE
81 bfin_dcache_init();
82 printk(KERN_INFO "Data Cache Enabled"
83# if defined CONFIG_BLKFIN_WB
84 " (write-back)"
85# elif defined CONFIG_BLKFIN_WT
86 " (write-through)"
87# endif
88 "\n");
89#endif
90}
91
92void bf53x_relocate_l1_mem(void)
93{
94 unsigned long l1_code_length;
95 unsigned long l1_data_a_length;
96 unsigned long l1_data_b_length;
97
98 l1_code_length = _etext_l1 - _stext_l1;
99 if (l1_code_length > L1_CODE_LENGTH)
100 l1_code_length = L1_CODE_LENGTH;
101 /* cannot complain as printk is not available as yet.
102 * But we can continue booting and complain later!
103 */
104
105 /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */
106 dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length);
107
108 l1_data_a_length = _ebss_l1 - _sdata_l1;
109 if (l1_data_a_length > L1_DATA_A_LENGTH)
110 l1_data_a_length = L1_DATA_A_LENGTH;
111
112 /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */
113 dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);
114
115 l1_data_b_length = _ebss_b_l1 - _sdata_b_l1;
116 if (l1_data_b_length > L1_DATA_B_LENGTH)
117 l1_data_b_length = L1_DATA_B_LENGTH;
118
119 /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */
120 dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
121 l1_data_a_length, l1_data_b_length);
122
123}
124
125/*
126 * Initial parsing of the command line. Currently, we support:
127 * - Controlling the linux memory size: mem=xxx[KMG]
128 * - Controlling the physical memory size: max_mem=xxx[KMG][$][#]
129 * $ -> reserved memory is dcacheable
130 * # -> reserved memory is icacheable
131 */
132static __init void parse_cmdline_early(char *cmdline_p)
133{
134 char c = ' ', *to = cmdline_p;
135 unsigned int memsize;
136 for (;;) {
137 if (c == ' ') {
138
139 if (!memcmp(to, "mem=", 4)) {
140 to += 4;
141 memsize = memparse(to, &to);
142 if (memsize)
143 _ramend = memsize;
144
145 } else if (!memcmp(to, "max_mem=", 8)) {
146 to += 8;
147 memsize = memparse(to, &to);
148 if (memsize) {
149 physical_mem_end = memsize;
150 if (*to != ' ') {
151 if (*to == '$'
152 || *(to + 1) == '$')
153 reserved_mem_dcache_on =
154 1;
155 if (*to == '#'
156 || *(to + 1) == '#')
157 reserved_mem_icache_on =
158 1;
159 }
160 }
161 }
162
163 }
164 c = *(to++);
165 if (!c)
166 break;
167 }
168}
169
170void __init setup_arch(char **cmdline_p)
171{
172 int bootmap_size;
173 unsigned long l1_length, sclk, cclk;
174#ifdef CONFIG_MTD_UCLINUX
175 unsigned long mtd_phys = 0;
176#endif
177
178 cclk = get_cclk();
179 sclk = get_sclk();
180
181#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273)
182 if (cclk == sclk)
183 panic("ANOMALY 05000273, SCLK can not be same as CCLK");
184#endif
185
186#if defined(ANOMALY_05000266)
187 bfin_read_IMDMA_D0_IRQ_STATUS();
188 bfin_read_IMDMA_D1_IRQ_STATUS();
189#endif
190
191#ifdef DEBUG_SERIAL_EARLY_INIT
192 bfin_console_init(); /* early console registration */
193 /* this give a chance to get printk() working before crash. */
194#endif
195
196#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
197 /* we need to initialize the Flashrom device here since we might
198 * do things with flash early on in the boot
199 */
200 flash_probe();
201#endif
202
203#if defined(CONFIG_CMDLINE_BOOL)
204 memset(command_line, 0, sizeof(command_line));
205 strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line));
206 command_line[sizeof(command_line) - 1] = 0;
207#endif
208
209 /* Keep a copy of command line */
210 *cmdline_p = &command_line[0];
211 memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
212 boot_command_line[COMMAND_LINE_SIZE - 1] = 0;
213
214 /* setup memory defaults from the user config */
215 physical_mem_end = 0;
216 _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
217
218 parse_cmdline_early(&command_line[0]);
219
220 if (physical_mem_end == 0)
221 physical_mem_end = _ramend;
222
223 /* by now the stack is part of the init task */
224 memory_end = _ramend - DMA_UNCACHED_REGION;
225
226 _ramstart = (unsigned long)__bss_stop;
227 memory_start = PAGE_ALIGN(_ramstart);
228
229#if defined(CONFIG_MTD_UCLINUX)
230 /* generic memory mapped MTD driver */
231 memory_mtd_end = memory_end;
232
233 mtd_phys = _ramstart;
234 mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8)));
235
236# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS)
237 if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC)
238 mtd_size =
239 PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10);
240# endif
241
242# if defined(CONFIG_CRAMFS)
243 if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC)
244 mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4)));
245# endif
246
247# if defined(CONFIG_ROMFS_FS)
248 if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0
249 && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
250 mtd_size =
251 PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
252# if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
253 /* Due to a Hardware Anomaly we need to limit the size of usable
254 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
255 * 05000263 - Hardware loop corrupted when taking an ICPLB exception
256 */
257# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
258 if (memory_end >= 56 * 1024 * 1024)
259 memory_end = 56 * 1024 * 1024;
260# else
261 if (memory_end >= 60 * 1024 * 1024)
262 memory_end = 60 * 1024 * 1024;
263# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */
264# endif /* ANOMALY_05000263 */
265# endif /* CONFIG_ROMFS_FS */
266
267 memory_end -= mtd_size;
268
269 if (mtd_size == 0) {
270 console_init();
271 panic("Don't boot kernel without rootfs attached.\n");
272 }
273
274 /* Relocate MTD image to the top of memory after the uncached memory area */
275 dma_memcpy((char *)memory_end, __bss_stop, mtd_size);
276
277 memory_mtd_start = memory_end;
278 _ebss = memory_mtd_start; /* define _ebss for compatible */
279#endif /* CONFIG_MTD_UCLINUX */
280
281#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
282 /* Due to a Hardware Anomaly we need to limit the size of usable
283 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
284 * 05000263 - Hardware loop corrupted when taking an ICPLB exception
285 */
286#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
287 if (memory_end >= 56 * 1024 * 1024)
288 memory_end = 56 * 1024 * 1024;
289#else
290 if (memory_end >= 60 * 1024 * 1024)
291 memory_end = 60 * 1024 * 1024;
292#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */
293 printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20);
294#endif /* ANOMALY_05000263 */
295
296#if !defined(CONFIG_MTD_UCLINUX)
297 memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/
298#endif
299 init_mm.start_code = (unsigned long)_stext;
300 init_mm.end_code = (unsigned long)_etext;
301 init_mm.end_data = (unsigned long)_edata;
302 init_mm.brk = (unsigned long)0;
303
304 init_leds();
305
306 printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n");
307 printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid());
308 if (bfin_revid() != bfin_compiled_revid())
309 printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n",
310 bfin_compiled_revid(), bfin_revid());
311 if (bfin_revid() < SUPPORTED_REVID)
312 printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n",
313 CPU, bfin_revid());
314 printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");
315
316 printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n",
317 cclk / 1000000, sclk / 1000000);
318
319#if defined(ANOMALY_05000273)
320 if ((cclk >> 1) <= sclk)
321 printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n");
322#endif
323
324 printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20);
325 printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
326
327 printk(KERN_INFO "Memory map:\n"
328 KERN_INFO " text = 0x%p-0x%p\n"
329 KERN_INFO " init = 0x%p-0x%p\n"
330 KERN_INFO " data = 0x%p-0x%p\n"
331 KERN_INFO " stack = 0x%p-0x%p\n"
332 KERN_INFO " bss = 0x%p-0x%p\n"
333 KERN_INFO " available = 0x%p-0x%p\n"
334#ifdef CONFIG_MTD_UCLINUX
335 KERN_INFO " rootfs = 0x%p-0x%p\n"
336#endif
337#if DMA_UNCACHED_REGION > 0
338 KERN_INFO " DMA Zone = 0x%p-0x%p\n"
339#endif
340 , _stext, _etext,
341 __init_begin, __init_end,
342 _sdata, _edata,
343 (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000),
344 __bss_start, __bss_stop,
345 (void*)_ramstart, (void*)memory_end
346#ifdef CONFIG_MTD_UCLINUX
347 , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size)
348#endif
349#if DMA_UNCACHED_REGION > 0
350 , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend)
351#endif
352 );
353
354 /*
355 * give all the memory to the bootmap allocator, tell it to put the
356 * boot mem_map at the start of memory
357 */
358 bootmap_size = init_bootmem_node(NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */
359 PAGE_OFFSET >> PAGE_SHIFT,
360 memory_end >> PAGE_SHIFT);
361 /*
362 * free the usable memory, we have to make sure we do not free
363 * the bootmem bitmap so we then reserve it after freeing it :-)
364 */
365 free_bootmem(memory_start, memory_end - memory_start);
366
367 reserve_bootmem(memory_start, bootmap_size);
368 /*
369 * get kmalloc into gear
370 */
371 paging_init();
372
373 /* check the size of the l1 area */
374 l1_length = _etext_l1 - _stext_l1;
375 if (l1_length > L1_CODE_LENGTH)
376 panic("L1 memory overflow\n");
377
378 l1_length = _ebss_l1 - _sdata_l1;
379 if (l1_length > L1_DATA_A_LENGTH)
380 panic("L1 memory overflow\n");
381
382 bf53x_cache_init();
383
384#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
385# if defined(CONFIG_BFIN_SHARED_FLASH_ENET) && defined(CONFIG_BFIN533_STAMP)
386 /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */
387 bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN));
388 bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN);
389 SSYNC();
390# endif
391# if defined (CONFIG_BFIN561_EZKIT)
392 bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | (1 << 12));
393 SSYNC();
394# endif /* defined (CONFIG_BFIN561_EZKIT) */
395#endif
396
397 printk(KERN_INFO "Hardware Trace Enabled\n");
398 bfin_write_TBUFCTL(0x03);
399}
400
401#if defined(CONFIG_BF561)
402static struct cpu cpu[2];
403#else
404static struct cpu cpu[1];
405#endif
406static int __init topology_init(void)
407{
408#if defined (CONFIG_BF561)
409 register_cpu(&cpu[0], 0);
410 register_cpu(&cpu[1], 1);
411 return 0;
412#else
413 return register_cpu(cpu, 0);
414#endif
415}
416
417subsys_initcall(topology_init);
418
419#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
420u16 lock_kernel_check(u32 start, u32 end)
421{
422 if ((start <= (u32) _stext && end >= (u32) _end)
423 || (start >= (u32) _stext && end <= (u32) _end))
424 return IN_KERNEL;
425 return 0;
426}
427
428static unsigned short __init
429fill_cplbtab(struct cplb_tab *table,
430 unsigned long start, unsigned long end,
431 unsigned long block_size, unsigned long cplb_data)
432{
433 int i;
434
435 switch (block_size) {
436 case SIZE_4M:
437 i = 3;
438 break;
439 case SIZE_1M:
440 i = 2;
441 break;
442 case SIZE_4K:
443 i = 1;
444 break;
445 case SIZE_1K:
446 default:
447 i = 0;
448 break;
449 }
450
451 cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
452
453 while ((start < end) && (table->pos < table->size)) {
454
455 table->tab[table->pos++] = start;
456
457 if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
458 table->tab[table->pos++] =
459 cplb_data | CPLB_LOCK | CPLB_DIRTY;
460 else
461 table->tab[table->pos++] = cplb_data;
462
463 start += block_size;
464 }
465 return 0;
466}
467
468static unsigned short __init
469close_cplbtab(struct cplb_tab *table)
470{
471
472 while (table->pos < table->size) {
473
474 table->tab[table->pos++] = 0;
475 table->tab[table->pos++] = 0; /* !CPLB_VALID */
476 }
477 return 0;
478}
479
480static void __init generate_cpl_tables(void)
481{
482
483 u16 i, j, process;
484 u32 a_start, a_end, as, ae, as_1m;
485
486 struct cplb_tab *t_i = NULL;
487 struct cplb_tab *t_d = NULL;
488 struct s_cplb cplb;
489
490 cplb.init_i.size = MAX_CPLBS;
491 cplb.init_d.size = MAX_CPLBS;
492 cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
493 cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
494
495 cplb.init_i.pos = 0;
496 cplb.init_d.pos = 0;
497 cplb.switch_i.pos = 0;
498 cplb.switch_d.pos = 0;
499
500 cplb.init_i.tab = icplb_table;
501 cplb.init_d.tab = dcplb_table;
502 cplb.switch_i.tab = ipdt_table;
503 cplb.switch_d.tab = dpdt_table;
504
505 cplb_data[SDRAM_KERN].end = memory_end;
506
507#ifdef CONFIG_MTD_UCLINUX
508 cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
509 cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
510 cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
511# if defined(CONFIG_ROMFS_FS)
512 cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
513
514 /*
515 * The ROMFS_FS size is often not multiple of 1MB.
516 * This can cause multiple CPLB sets covering the same memory area.
517 * This will then cause multiple CPLB hit exceptions.
518 * Workaround: We ensure a contiguous memory area by extending the kernel
519 * memory section over the mtd section.
520 * For ROMFS_FS memory must be covered with ICPLBs anyways.
521 * So there is no difference between kernel and mtd memory setup.
522 */
523
524 cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
525 cplb_data[SDRAM_RAM_MTD].valid = 0;
526
527# endif
528#else
529 cplb_data[SDRAM_RAM_MTD].valid = 0;
530#endif
531
532 cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
533 cplb_data[SDRAM_DMAZ].end = _ramend;
534
535 cplb_data[RES_MEM].start = _ramend;
536 cplb_data[RES_MEM].end = physical_mem_end;
537
538 if (reserved_mem_dcache_on)
539 cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
540 else
541 cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
542
543 if (reserved_mem_icache_on)
544 cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
545 else
546 cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
547
548 for (i = ZERO_P; i <= L2_MEM; i++) {
549
550 if (cplb_data[i].valid) {
551
552 as_1m = cplb_data[i].start % SIZE_1M;
553
554 /* We need to make sure all sections are properly 1M aligned
555 * However between Kernel Memory and the Kernel mtd section, depending on the
556 * rootfs size, there can be overlapping memory areas.
557 */
558
559 if (as_1m && i!=L1I_MEM && i!=L1D_MEM) {
560#ifdef CONFIG_MTD_UCLINUX
561 if (i == SDRAM_RAM_MTD) {
562 if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
563 cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
564 else
565 cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
566 } else
567#endif
568 printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
569 cplb_data[i].name, cplb_data[i].start);
570 }
571
572 as = cplb_data[i].start % SIZE_4M;
573 ae = cplb_data[i].end % SIZE_4M;
574
575 if (as)
576 a_start = cplb_data[i].start + (SIZE_4M - (as));
577 else
578 a_start = cplb_data[i].start;
579
580 a_end = cplb_data[i].end - ae;
581
582 for (j = INITIAL_T; j <= SWITCH_T; j++) {
583
584 switch (j) {
585 case INITIAL_T:
586 if (cplb_data[i].attr & INITIAL_T) {
587 t_i = &cplb.init_i;
588 t_d = &cplb.init_d;
589 process = 1;
590 } else
591 process = 0;
592 break;
593 case SWITCH_T:
594 if (cplb_data[i].attr & SWITCH_T) {
595 t_i = &cplb.switch_i;
596 t_d = &cplb.switch_d;
597 process = 1;
598 } else
599 process = 0;
600 break;
601 default:
602 process = 0;
603 break;
604 }
605
606 if (process) {
607 if (cplb_data[i].attr & I_CPLB) {
608
609 if (cplb_data[i].psize) {
610 fill_cplbtab(t_i,
611 cplb_data[i].start,
612 cplb_data[i].end,
613 cplb_data[i].psize,
614 cplb_data[i].i_conf);
615 } else {
616 /*icplb_table */
617#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
618 if (i == SDRAM_KERN) {
619 fill_cplbtab(t_i,
620 cplb_data[i].start,
621 cplb_data[i].end,
622 SIZE_4M,
623 cplb_data[i].i_conf);
624 } else
625#endif
626 {
627 fill_cplbtab(t_i,
628 cplb_data[i].start,
629 a_start,
630 SIZE_1M,
631 cplb_data[i].i_conf);
632 fill_cplbtab(t_i,
633 a_start,
634 a_end,
635 SIZE_4M,
636 cplb_data[i].i_conf);
637 fill_cplbtab(t_i, a_end,
638 cplb_data[i].end,
639 SIZE_1M,
640 cplb_data[i].i_conf);
641 }
642 }
643
644 }
645 if (cplb_data[i].attr & D_CPLB) {
646
647 if (cplb_data[i].psize) {
648 fill_cplbtab(t_d,
649 cplb_data[i].start,
650 cplb_data[i].end,
651 cplb_data[i].psize,
652 cplb_data[i].d_conf);
653 } else {
654/*dcplb_table*/
655 fill_cplbtab(t_d,
656 cplb_data[i].start,
657 a_start, SIZE_1M,
658 cplb_data[i].d_conf);
659 fill_cplbtab(t_d, a_start,
660 a_end, SIZE_4M,
661 cplb_data[i].d_conf);
662 fill_cplbtab(t_d, a_end,
663 cplb_data[i].end,
664 SIZE_1M,
665 cplb_data[i].d_conf);
666
667 }
668
669 }
670 }
671 }
672
673 }
674 }
675
676/* close tables */
677
678 close_cplbtab(&cplb.init_i);
679 close_cplbtab(&cplb.init_d);
680
681 cplb.init_i.tab[cplb.init_i.pos] = -1;
682 cplb.init_d.tab[cplb.init_d.pos] = -1;
683 cplb.switch_i.tab[cplb.switch_i.pos] = -1;
684 cplb.switch_d.tab[cplb.switch_d.pos] = -1;
685
686}
687
688#endif
689
690static inline u_long get_vco(void)
691{
692 u_long msel;
693 u_long vco;
694
695 msel = (bfin_read_PLL_CTL() >> 9) & 0x3F;
696 if (0 == msel)
697 msel = 64;
698
699 vco = CONFIG_CLKIN_HZ;
700 vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */
701 vco = msel * vco;
702 return vco;
703}
704
705/*Get the Core clock*/
706u_long get_cclk(void)
707{
708 u_long csel, ssel;
709 if (bfin_read_PLL_STAT() & 0x1)
710 return CONFIG_CLKIN_HZ;
711
712 ssel = bfin_read_PLL_DIV();
713 csel = ((ssel >> 4) & 0x03);
714 ssel &= 0xf;
715 if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
716 return get_vco() / ssel;
717 return get_vco() >> csel;
718}
719
720EXPORT_SYMBOL(get_cclk);
721
722/* Get the System clock */
723u_long get_sclk(void)
724{
725 u_long ssel;
726
727 if (bfin_read_PLL_STAT() & 0x1)
728 return CONFIG_CLKIN_HZ;
729
730 ssel = (bfin_read_PLL_DIV() & 0xf);
731 if (0 == ssel) {
732 printk(KERN_WARNING "Invalid System Clock\n");
733 ssel = 1;
734 }
735
736 return get_vco() / ssel;
737}
738
739EXPORT_SYMBOL(get_sclk);
740
741/*
742 * Get CPU information for use by the procfs.
743 */
744static int show_cpuinfo(struct seq_file *m, void *v)
745{
746 char *cpu, *mmu, *fpu, *name;
747 uint32_t revid;
748
749 u_long cclk = 0, sclk = 0;
750 u_int dcache_size = 0, dsup_banks = 0;
751
752 cpu = CPU;
753 mmu = "none";
754 fpu = "none";
755 revid = bfin_revid();
756 name = bfin_board_name;
757
758 cclk = get_cclk();
759 sclk = get_sclk();
760
761 seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n"
762 "MMU:\t\t%s\n"
763 "FPU:\t\t%s\n"
764 "Core Clock:\t%9lu Hz\n"
765 "System Clock:\t%9lu Hz\n"
766 "BogoMips:\t%lu.%02lu\n"
767 "Calibration:\t%lu loops\n",
768 cpu, revid, mmu, fpu,
769 cclk,
770 sclk,
771 (loops_per_jiffy * HZ) / 500000,
772 ((loops_per_jiffy * HZ) / 5000) % 100,
773 (loops_per_jiffy * HZ));
774 seq_printf(m, "Board Name:\t%s\n", name);
775 seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20);
776 seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20);
777 if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC))
778 seq_printf(m, "I-CACHE:\tON\n");
779 else
780 seq_printf(m, "I-CACHE:\tOFF\n");
781 if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
782 seq_printf(m, "D-CACHE:\tON"
783#if defined CONFIG_BLKFIN_WB
784 " (write-back)"
785#elif defined CONFIG_BLKFIN_WT
786 " (write-through)"
787#endif
788 "\n");
789 else
790 seq_printf(m, "D-CACHE:\tOFF\n");
791
792
793 switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
794 case ACACHE_BSRAM:
795 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
796 dcache_size = 16;
797 dsup_banks = 1;
798 break;
799 case ACACHE_BCACHE:
800 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
801 dcache_size = 32;
802 dsup_banks = 2;
803 break;
804 case ASRAM_BSRAM:
805 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
806 dcache_size = 0;
807 dsup_banks = 0;
808 break;
809 default:
810 break;
811 }
812
813
814 seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024);
815 seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
816 seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
817 BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES);
818 seq_printf(m,
819 "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
820 dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS,
821 BLKFIN_DLINES);
822#ifdef CONFIG_BLKFIN_CACHE_LOCK
823 switch (read_iloc()) {
824 case WAY0_L:
825 seq_printf(m, "Way0 Locked-Down\n");
826 break;
827 case WAY1_L:
828 seq_printf(m, "Way1 Locked-Down\n");
829 break;
830 case WAY01_L:
831 seq_printf(m, "Way0,Way1 Locked-Down\n");
832 break;
833 case WAY2_L:
834 seq_printf(m, "Way2 Locked-Down\n");
835 break;
836 case WAY02_L:
837 seq_printf(m, "Way0,Way2 Locked-Down\n");
838 break;
839 case WAY12_L:
840 seq_printf(m, "Way1,Way2 Locked-Down\n");
841 break;
842 case WAY012_L:
843 seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n");
844 break;
845 case WAY3_L:
846 seq_printf(m, "Way3 Locked-Down\n");
847 break;
848 case WAY03_L:
849 seq_printf(m, "Way0,Way3 Locked-Down\n");
850 break;
851 case WAY13_L:
852 seq_printf(m, "Way1,Way3 Locked-Down\n");
853 break;
854 case WAY013_L:
855 seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n");
856 break;
857 case WAY32_L:
858 seq_printf(m, "Way3,Way2 Locked-Down\n");
859 break;
860 case WAY320_L:
861 seq_printf(m, "Way3,Way2,Way0 Locked-Down\n");
862 break;
863 case WAY321_L:
864 seq_printf(m, "Way3,Way2,Way1 Locked-Down\n");
865 break;
866 case WAYALL_L:
867 seq_printf(m, "All Ways are locked\n");
868 break;
869 default:
870 seq_printf(m, "No Ways are locked\n");
871 }
872#endif
873 return 0;
874}
875
876static void *c_start(struct seq_file *m, loff_t *pos)
877{
878 return *pos < NR_CPUS ? ((void *)0x12345678) : NULL;
879}
880
881static void *c_next(struct seq_file *m, void *v, loff_t *pos)
882{
883 ++*pos;
884 return c_start(m, pos);
885}
886
887static void c_stop(struct seq_file *m, void *v)
888{
889}
890
891struct seq_operations cpuinfo_op = {
892 .start = c_start,
893 .next = c_next,
894 .stop = c_stop,
895 .show = show_cpuinfo,
896};
897
898void cmdline_init(unsigned long r0)
899{
900 if (r0)
901 strncpy(command_line, (char *)r0, COMMAND_LINE_SIZE);
902}