aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/setup.c')
-rw-r--r--arch/blackfin/kernel/setup.c394
1 files changed, 75 insertions, 319 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index a24fa1ab802b..f59dcee7bae3 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -42,6 +42,7 @@
42#include <asm/cacheflush.h> 42#include <asm/cacheflush.h>
43#include <asm/blackfin.h> 43#include <asm/blackfin.h>
44#include <asm/cplbinit.h> 44#include <asm/cplbinit.h>
45#include <asm/fixed_code.h>
45 46
46u16 _bfin_swrst; 47u16 _bfin_swrst;
47 48
@@ -63,10 +64,6 @@ EXPORT_SYMBOL(mtd_size);
63 64
64char __initdata command_line[COMMAND_LINE_SIZE]; 65char __initdata command_line[COMMAND_LINE_SIZE];
65 66
66#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
67static void generate_cpl_tables(void);
68#endif
69
70void __init bf53x_cache_init(void) 67void __init bf53x_cache_init(void)
71{ 68{
72#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 69#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
@@ -197,6 +194,17 @@ void __init setup_arch(char **cmdline_p)
197 /* this give a chance to get printk() working before crash. */ 194 /* this give a chance to get printk() working before crash. */
198#endif 195#endif
199 196
197 printk(KERN_INFO "Hardware Trace ");
198 if (bfin_read_TBUFCTL() & 0x1 )
199 printk("Active ");
200 else
201 printk("Off ");
202 if (bfin_read_TBUFCTL() & 0x2)
203 printk("and Enabled\n");
204 else
205 printk("and Disabled\n");
206
207
200#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) 208#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
201 /* we need to initialize the Flashrom device here since we might 209 /* we need to initialize the Flashrom device here since we might
202 * do things with flash early on in the boot 210 * do things with flash early on in the boot
@@ -307,10 +315,20 @@ void __init setup_arch(char **cmdline_p)
307 init_leds(); 315 init_leds();
308 316
309 printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n"); 317 printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n");
310 printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); 318 if (bfin_compiled_revid() == 0xffff)
311 if (bfin_revid() != bfin_compiled_revid()) 319 printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU);
312 printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", 320 else if (bfin_compiled_revid() == -1)
313 bfin_compiled_revid(), bfin_revid()); 321 printk(KERN_INFO "Compiled for ADSP-%s Rev none\n", CPU);
322 else
323 printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid());
324 if (bfin_revid() != bfin_compiled_revid()) {
325 if (bfin_compiled_revid() == -1)
326 printk(KERN_ERR "Warning: Compiled for Rev none, but running on Rev %d\n",
327 bfin_revid());
328 else if (bfin_compiled_revid() != 0xffff)
329 printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n",
330 bfin_compiled_revid(), bfin_revid());
331 }
314 if (bfin_revid() < SUPPORTED_REVID) 332 if (bfin_revid() < SUPPORTED_REVID)
315 printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", 333 printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n",
316 CPU, bfin_revid()); 334 CPU, bfin_revid());
@@ -329,9 +347,10 @@ void __init setup_arch(char **cmdline_p)
329 347
330 printk(KERN_INFO "Memory map:\n" 348 printk(KERN_INFO "Memory map:\n"
331 KERN_INFO " text = 0x%p-0x%p\n" 349 KERN_INFO " text = 0x%p-0x%p\n"
332 KERN_INFO " init = 0x%p-0x%p\n" 350 KERN_INFO " rodata = 0x%p-0x%p\n"
333 KERN_INFO " data = 0x%p-0x%p\n" 351 KERN_INFO " data = 0x%p-0x%p\n"
334 KERN_INFO " stack = 0x%p-0x%p\n" 352 KERN_INFO " stack = 0x%p-0x%p\n"
353 KERN_INFO " init = 0x%p-0x%p\n"
335 KERN_INFO " bss = 0x%p-0x%p\n" 354 KERN_INFO " bss = 0x%p-0x%p\n"
336 KERN_INFO " available = 0x%p-0x%p\n" 355 KERN_INFO " available = 0x%p-0x%p\n"
337#ifdef CONFIG_MTD_UCLINUX 356#ifdef CONFIG_MTD_UCLINUX
@@ -341,16 +360,17 @@ void __init setup_arch(char **cmdline_p)
341 KERN_INFO " DMA Zone = 0x%p-0x%p\n" 360 KERN_INFO " DMA Zone = 0x%p-0x%p\n"
342#endif 361#endif
343 , _stext, _etext, 362 , _stext, _etext,
344 __init_begin, __init_end, 363 __start_rodata, __end_rodata,
345 _sdata, _edata, 364 _sdata, _edata,
346 (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000), 365 (void *)&init_thread_union, (void *)((int)(&init_thread_union) + 0x2000),
366 __init_begin, __init_end,
347 __bss_start, __bss_stop, 367 __bss_start, __bss_stop,
348 (void*)_ramstart, (void*)memory_end 368 (void *)_ramstart, (void *)memory_end
349#ifdef CONFIG_MTD_UCLINUX 369#ifdef CONFIG_MTD_UCLINUX
350 , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size) 370 , (void *)memory_mtd_start, (void *)(memory_mtd_start + mtd_size)
351#endif 371#endif
352#if DMA_UNCACHED_REGION > 0 372#if DMA_UNCACHED_REGION > 0
353 , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend) 373 , (void *)(_ramend - DMA_UNCACHED_REGION), (void *)(_ramend)
354#endif 374#endif
355 ); 375 );
356 376
@@ -376,11 +396,11 @@ void __init setup_arch(char **cmdline_p)
376 /* check the size of the l1 area */ 396 /* check the size of the l1 area */
377 l1_length = _etext_l1 - _stext_l1; 397 l1_length = _etext_l1 - _stext_l1;
378 if (l1_length > L1_CODE_LENGTH) 398 if (l1_length > L1_CODE_LENGTH)
379 panic("L1 memory overflow\n"); 399 panic("L1 code memory overflow\n");
380 400
381 l1_length = _ebss_l1 - _sdata_l1; 401 l1_length = _ebss_l1 - _sdata_l1;
382 if (l1_length > L1_DATA_A_LENGTH) 402 if (l1_length > L1_DATA_A_LENGTH)
383 panic("L1 memory overflow\n"); 403 panic("L1 data memory overflow\n");
384 404
385#ifdef BF561_FAMILY 405#ifdef BF561_FAMILY
386 _bfin_swrst = bfin_read_SICA_SWRST(); 406 _bfin_swrst = bfin_read_SICA_SWRST();
@@ -388,10 +408,28 @@ void __init setup_arch(char **cmdline_p)
388 _bfin_swrst = bfin_read_SWRST(); 408 _bfin_swrst = bfin_read_SWRST();
389#endif 409#endif
390 410
391 bf53x_cache_init(); 411 /* Copy atomic sequences to their fixed location, and sanity check that
412 these locations are the ones that we advertise to userspace. */
413 memcpy((void *)FIXED_CODE_START, &fixed_code_start,
414 FIXED_CODE_END - FIXED_CODE_START);
415 BUG_ON((char *)&sigreturn_stub - (char *)&fixed_code_start
416 != SIGRETURN_STUB - FIXED_CODE_START);
417 BUG_ON((char *)&atomic_xchg32 - (char *)&fixed_code_start
418 != ATOMIC_XCHG32 - FIXED_CODE_START);
419 BUG_ON((char *)&atomic_cas32 - (char *)&fixed_code_start
420 != ATOMIC_CAS32 - FIXED_CODE_START);
421 BUG_ON((char *)&atomic_add32 - (char *)&fixed_code_start
422 != ATOMIC_ADD32 - FIXED_CODE_START);
423 BUG_ON((char *)&atomic_sub32 - (char *)&fixed_code_start
424 != ATOMIC_SUB32 - FIXED_CODE_START);
425 BUG_ON((char *)&atomic_ior32 - (char *)&fixed_code_start
426 != ATOMIC_IOR32 - FIXED_CODE_START);
427 BUG_ON((char *)&atomic_and32 - (char *)&fixed_code_start
428 != ATOMIC_AND32 - FIXED_CODE_START);
429 BUG_ON((char *)&atomic_xor32 - (char *)&fixed_code_start
430 != ATOMIC_XOR32 - FIXED_CODE_START);
392 431
393 printk(KERN_INFO "Hardware Trace Enabled\n"); 432 bf53x_cache_init();
394 bfin_write_TBUFCTL(0x03);
395} 433}
396 434
397static int __init topology_init(void) 435static int __init topology_init(void)
@@ -409,286 +447,6 @@ static int __init topology_init(void)
409 447
410subsys_initcall(topology_init); 448subsys_initcall(topology_init);
411 449
412#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
413static u16 __init lock_kernel_check(u32 start, u32 end)
414{
415 if ((start <= (u32) _stext && end >= (u32) _end)
416 || (start >= (u32) _stext && end <= (u32) _end))
417 return IN_KERNEL;
418 return 0;
419}
420
421static unsigned short __init
422fill_cplbtab(struct cplb_tab *table,
423 unsigned long start, unsigned long end,
424 unsigned long block_size, unsigned long cplb_data)
425{
426 int i;
427
428 switch (block_size) {
429 case SIZE_4M:
430 i = 3;
431 break;
432 case SIZE_1M:
433 i = 2;
434 break;
435 case SIZE_4K:
436 i = 1;
437 break;
438 case SIZE_1K:
439 default:
440 i = 0;
441 break;
442 }
443
444 cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
445
446 while ((start < end) && (table->pos < table->size)) {
447
448 table->tab[table->pos++] = start;
449
450 if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
451 table->tab[table->pos++] =
452 cplb_data | CPLB_LOCK | CPLB_DIRTY;
453 else
454 table->tab[table->pos++] = cplb_data;
455
456 start += block_size;
457 }
458 return 0;
459}
460
461static unsigned short __init
462close_cplbtab(struct cplb_tab *table)
463{
464
465 while (table->pos < table->size) {
466
467 table->tab[table->pos++] = 0;
468 table->tab[table->pos++] = 0; /* !CPLB_VALID */
469 }
470 return 0;
471}
472
473/* helper function */
474static void __fill_code_cplbtab(struct cplb_tab *t, int i,
475 u32 a_start, u32 a_end)
476{
477 if (cplb_data[i].psize) {
478 fill_cplbtab(t,
479 cplb_data[i].start,
480 cplb_data[i].end,
481 cplb_data[i].psize,
482 cplb_data[i].i_conf);
483 } else {
484#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
485 if (i == SDRAM_KERN) {
486 fill_cplbtab(t,
487 cplb_data[i].start,
488 cplb_data[i].end,
489 SIZE_4M,
490 cplb_data[i].i_conf);
491 } else {
492#endif
493 fill_cplbtab(t,
494 cplb_data[i].start,
495 a_start,
496 SIZE_1M,
497 cplb_data[i].i_conf);
498 fill_cplbtab(t,
499 a_start,
500 a_end,
501 SIZE_4M,
502 cplb_data[i].i_conf);
503 fill_cplbtab(t, a_end,
504 cplb_data[i].end,
505 SIZE_1M,
506 cplb_data[i].i_conf);
507 }
508 }
509}
510
511static void __fill_data_cplbtab(struct cplb_tab *t, int i,
512 u32 a_start, u32 a_end)
513{
514 if (cplb_data[i].psize) {
515 fill_cplbtab(t,
516 cplb_data[i].start,
517 cplb_data[i].end,
518 cplb_data[i].psize,
519 cplb_data[i].d_conf);
520 } else {
521 fill_cplbtab(t,
522 cplb_data[i].start,
523 a_start, SIZE_1M,
524 cplb_data[i].d_conf);
525 fill_cplbtab(t, a_start,
526 a_end, SIZE_4M,
527 cplb_data[i].d_conf);
528 fill_cplbtab(t, a_end,
529 cplb_data[i].end,
530 SIZE_1M,
531 cplb_data[i].d_conf);
532 }
533}
534static void __init generate_cpl_tables(void)
535{
536
537 u16 i, j, process;
538 u32 a_start, a_end, as, ae, as_1m;
539
540 struct cplb_tab *t_i = NULL;
541 struct cplb_tab *t_d = NULL;
542 struct s_cplb cplb;
543
544 cplb.init_i.size = MAX_CPLBS;
545 cplb.init_d.size = MAX_CPLBS;
546 cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
547 cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
548
549 cplb.init_i.pos = 0;
550 cplb.init_d.pos = 0;
551 cplb.switch_i.pos = 0;
552 cplb.switch_d.pos = 0;
553
554 cplb.init_i.tab = icplb_table;
555 cplb.init_d.tab = dcplb_table;
556 cplb.switch_i.tab = ipdt_table;
557 cplb.switch_d.tab = dpdt_table;
558
559 cplb_data[SDRAM_KERN].end = memory_end;
560
561#ifdef CONFIG_MTD_UCLINUX
562 cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
563 cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
564 cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
565# if defined(CONFIG_ROMFS_FS)
566 cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
567
568 /*
569 * The ROMFS_FS size is often not multiple of 1MB.
570 * This can cause multiple CPLB sets covering the same memory area.
571 * This will then cause multiple CPLB hit exceptions.
572 * Workaround: We ensure a contiguous memory area by extending the kernel
573 * memory section over the mtd section.
574 * For ROMFS_FS memory must be covered with ICPLBs anyways.
575 * So there is no difference between kernel and mtd memory setup.
576 */
577
578 cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
579 cplb_data[SDRAM_RAM_MTD].valid = 0;
580
581# endif
582#else
583 cplb_data[SDRAM_RAM_MTD].valid = 0;
584#endif
585
586 cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
587 cplb_data[SDRAM_DMAZ].end = _ramend;
588
589 cplb_data[RES_MEM].start = _ramend;
590 cplb_data[RES_MEM].end = physical_mem_end;
591
592 if (reserved_mem_dcache_on)
593 cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
594 else
595 cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
596
597 if (reserved_mem_icache_on)
598 cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
599 else
600 cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
601
602 for (i = ZERO_P; i <= L2_MEM; i++) {
603 if (!cplb_data[i].valid)
604 continue;
605
606 as_1m = cplb_data[i].start % SIZE_1M;
607
608 /*
609 * We need to make sure all sections are properly 1M aligned
610 * However between Kernel Memory and the Kernel mtd section,
611 * depending on the rootfs size, there can be overlapping
612 * memory areas.
613 */
614
615 if (as_1m && i != L1I_MEM && i != L1D_MEM) {
616#ifdef CONFIG_MTD_UCLINUX
617 if (i == SDRAM_RAM_MTD) {
618 if ((cplb_data[SDRAM_KERN].end + 1) >
619 cplb_data[SDRAM_RAM_MTD].start)
620 cplb_data[SDRAM_RAM_MTD].start =
621 (cplb_data[i].start &
622 (-2*SIZE_1M)) + SIZE_1M;
623 else
624 cplb_data[SDRAM_RAM_MTD].start =
625 (cplb_data[i].start &
626 (-2*SIZE_1M));
627 } else
628#endif
629 printk(KERN_WARNING
630 "Unaligned Start of %s at 0x%X\n",
631 cplb_data[i].name, cplb_data[i].start);
632 }
633
634 as = cplb_data[i].start % SIZE_4M;
635 ae = cplb_data[i].end % SIZE_4M;
636
637 if (as)
638 a_start = cplb_data[i].start + (SIZE_4M - (as));
639 else
640 a_start = cplb_data[i].start;
641
642 a_end = cplb_data[i].end - ae;
643
644 for (j = INITIAL_T; j <= SWITCH_T; j++) {
645
646 switch (j) {
647 case INITIAL_T:
648 if (cplb_data[i].attr & INITIAL_T) {
649 t_i = &cplb.init_i;
650 t_d = &cplb.init_d;
651 process = 1;
652 } else
653 process = 0;
654 break;
655 case SWITCH_T:
656 if (cplb_data[i].attr & SWITCH_T) {
657 t_i = &cplb.switch_i;
658 t_d = &cplb.switch_d;
659 process = 1;
660 } else
661 process = 0;
662 break;
663 default:
664 process = 0;
665 break;
666 }
667
668 if (!process)
669 continue;
670 if (cplb_data[i].attr & I_CPLB)
671 __fill_code_cplbtab(t_i, i, a_start, a_end);
672
673 if (cplb_data[i].attr & D_CPLB)
674 __fill_data_cplbtab(t_d, i, a_start, a_end);
675 }
676 }
677
678/* close tables */
679
680 close_cplbtab(&cplb.init_i);
681 close_cplbtab(&cplb.init_d);
682
683 cplb.init_i.tab[cplb.init_i.pos] = -1;
684 cplb.init_d.tab[cplb.init_d.pos] = -1;
685 cplb.switch_i.tab[cplb.switch_i.pos] = -1;
686 cplb.switch_d.tab[cplb.switch_d.pos] = -1;
687
688}
689
690#endif
691
692static u_long get_vco(void) 450static u_long get_vco(void)
693{ 451{
694 u_long msel; 452 u_long msel;
@@ -718,7 +476,6 @@ u_long get_cclk(void)
718 return get_vco() / ssel; 476 return get_vco() / ssel;
719 return get_vco() >> csel; 477 return get_vco() >> csel;
720} 478}
721
722EXPORT_SYMBOL(get_cclk); 479EXPORT_SYMBOL(get_cclk);
723 480
724/* Get the System clock */ 481/* Get the System clock */
@@ -737,7 +494,6 @@ u_long get_sclk(void)
737 494
738 return get_vco() / ssel; 495 return get_vco() / ssel;
739} 496}
740
741EXPORT_SYMBOL(get_sclk); 497EXPORT_SYMBOL(get_sclk);
742 498
743/* 499/*
@@ -792,23 +548,23 @@ static int show_cpuinfo(struct seq_file *m, void *v)
792 seq_printf(m, "D-CACHE:\tOFF\n"); 548 seq_printf(m, "D-CACHE:\tOFF\n");
793 549
794 550
795 switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) { 551 switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
796 case ACACHE_BSRAM: 552 case ACACHE_BSRAM:
797 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n"); 553 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
798 dcache_size = 16; 554 dcache_size = 16;
799 dsup_banks = 1; 555 dsup_banks = 1;
800 break; 556 break;
801 case ACACHE_BCACHE: 557 case ACACHE_BCACHE:
802 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n"); 558 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
803 dcache_size = 32; 559 dcache_size = 32;
804 dsup_banks = 2; 560 dsup_banks = 2;
805 break; 561 break;
806 case ASRAM_BSRAM: 562 case ASRAM_BSRAM:
807 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n"); 563 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
808 dcache_size = 0; 564 dcache_size = 0;
809 dsup_banks = 0; 565 dsup_banks = 0;
810 break; 566 break;
811 default: 567 default:
812 break; 568 break;
813 } 569 }
814 570