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.c368
1 files changed, 56 insertions, 312 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 83060f98d15d..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
@@ -354,15 +362,15 @@ void __init setup_arch(char **cmdline_p)
354 , _stext, _etext, 362 , _stext, _etext,
355 __start_rodata, __end_rodata, 363 __start_rodata, __end_rodata,
356 _sdata, _edata, 364 _sdata, _edata,
357 (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000), 365 (void *)&init_thread_union, (void *)((int)(&init_thread_union) + 0x2000),
358 __init_begin, __init_end, 366 __init_begin, __init_end,
359 __bss_start, __bss_stop, 367 __bss_start, __bss_stop,
360 (void*)_ramstart, (void*)memory_end 368 (void *)_ramstart, (void *)memory_end
361#ifdef CONFIG_MTD_UCLINUX 369#ifdef CONFIG_MTD_UCLINUX
362 , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size) 370 , (void *)memory_mtd_start, (void *)(memory_mtd_start + mtd_size)
363#endif 371#endif
364#if DMA_UNCACHED_REGION > 0 372#if DMA_UNCACHED_REGION > 0
365 , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend) 373 , (void *)(_ramend - DMA_UNCACHED_REGION), (void *)(_ramend)
366#endif 374#endif
367 ); 375 );
368 376
@@ -388,11 +396,11 @@ void __init setup_arch(char **cmdline_p)
388 /* check the size of the l1 area */ 396 /* check the size of the l1 area */
389 l1_length = _etext_l1 - _stext_l1; 397 l1_length = _etext_l1 - _stext_l1;
390 if (l1_length > L1_CODE_LENGTH) 398 if (l1_length > L1_CODE_LENGTH)
391 panic("L1 memory overflow\n"); 399 panic("L1 code memory overflow\n");
392 400
393 l1_length = _ebss_l1 - _sdata_l1; 401 l1_length = _ebss_l1 - _sdata_l1;
394 if (l1_length > L1_DATA_A_LENGTH) 402 if (l1_length > L1_DATA_A_LENGTH)
395 panic("L1 memory overflow\n"); 403 panic("L1 data memory overflow\n");
396 404
397#ifdef BF561_FAMILY 405#ifdef BF561_FAMILY
398 _bfin_swrst = bfin_read_SICA_SWRST(); 406 _bfin_swrst = bfin_read_SICA_SWRST();
@@ -400,10 +408,28 @@ void __init setup_arch(char **cmdline_p)
400 _bfin_swrst = bfin_read_SWRST(); 408 _bfin_swrst = bfin_read_SWRST();
401#endif 409#endif
402 410
403 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);
404 431
405 printk(KERN_INFO "Hardware Trace Enabled\n"); 432 bf53x_cache_init();
406 bfin_write_TBUFCTL(0x03);
407} 433}
408 434
409static int __init topology_init(void) 435static int __init topology_init(void)
@@ -421,286 +447,6 @@ static int __init topology_init(void)
421 447
422subsys_initcall(topology_init); 448subsys_initcall(topology_init);
423 449
424#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
425static u16 __init lock_kernel_check(u32 start, u32 end)
426{
427 if ((start <= (u32) _stext && end >= (u32) _end)
428 || (start >= (u32) _stext && end <= (u32) _end))
429 return IN_KERNEL;
430 return 0;
431}
432
433static unsigned short __init
434fill_cplbtab(struct cplb_tab *table,
435 unsigned long start, unsigned long end,
436 unsigned long block_size, unsigned long cplb_data)
437{
438 int i;
439
440 switch (block_size) {
441 case SIZE_4M:
442 i = 3;
443 break;
444 case SIZE_1M:
445 i = 2;
446 break;
447 case SIZE_4K:
448 i = 1;
449 break;
450 case SIZE_1K:
451 default:
452 i = 0;
453 break;
454 }
455
456 cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
457
458 while ((start < end) && (table->pos < table->size)) {
459
460 table->tab[table->pos++] = start;
461
462 if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
463 table->tab[table->pos++] =
464 cplb_data | CPLB_LOCK | CPLB_DIRTY;
465 else
466 table->tab[table->pos++] = cplb_data;
467
468 start += block_size;
469 }
470 return 0;
471}
472
473static unsigned short __init
474close_cplbtab(struct cplb_tab *table)
475{
476
477 while (table->pos < table->size) {
478
479 table->tab[table->pos++] = 0;
480 table->tab[table->pos++] = 0; /* !CPLB_VALID */
481 }
482 return 0;
483}
484
485/* helper function */
486static void __fill_code_cplbtab(struct cplb_tab *t, int i,
487 u32 a_start, u32 a_end)
488{
489 if (cplb_data[i].psize) {
490 fill_cplbtab(t,
491 cplb_data[i].start,
492 cplb_data[i].end,
493 cplb_data[i].psize,
494 cplb_data[i].i_conf);
495 } else {
496#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
497 if (i == SDRAM_KERN) {
498 fill_cplbtab(t,
499 cplb_data[i].start,
500 cplb_data[i].end,
501 SIZE_4M,
502 cplb_data[i].i_conf);
503 } else {
504#endif
505 fill_cplbtab(t,
506 cplb_data[i].start,
507 a_start,
508 SIZE_1M,
509 cplb_data[i].i_conf);
510 fill_cplbtab(t,
511 a_start,
512 a_end,
513 SIZE_4M,
514 cplb_data[i].i_conf);
515 fill_cplbtab(t, a_end,
516 cplb_data[i].end,
517 SIZE_1M,
518 cplb_data[i].i_conf);
519 }
520 }
521}
522
523static void __fill_data_cplbtab(struct cplb_tab *t, int i,
524 u32 a_start, u32 a_end)
525{
526 if (cplb_data[i].psize) {
527 fill_cplbtab(t,
528 cplb_data[i].start,
529 cplb_data[i].end,
530 cplb_data[i].psize,
531 cplb_data[i].d_conf);
532 } else {
533 fill_cplbtab(t,
534 cplb_data[i].start,
535 a_start, SIZE_1M,
536 cplb_data[i].d_conf);
537 fill_cplbtab(t, a_start,
538 a_end, SIZE_4M,
539 cplb_data[i].d_conf);
540 fill_cplbtab(t, a_end,
541 cplb_data[i].end,
542 SIZE_1M,
543 cplb_data[i].d_conf);
544 }
545}
546static void __init generate_cpl_tables(void)
547{
548
549 u16 i, j, process;
550 u32 a_start, a_end, as, ae, as_1m;
551
552 struct cplb_tab *t_i = NULL;
553 struct cplb_tab *t_d = NULL;
554 struct s_cplb cplb;
555
556 cplb.init_i.size = MAX_CPLBS;
557 cplb.init_d.size = MAX_CPLBS;
558 cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
559 cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
560
561 cplb.init_i.pos = 0;
562 cplb.init_d.pos = 0;
563 cplb.switch_i.pos = 0;
564 cplb.switch_d.pos = 0;
565
566 cplb.init_i.tab = icplb_table;
567 cplb.init_d.tab = dcplb_table;
568 cplb.switch_i.tab = ipdt_table;
569 cplb.switch_d.tab = dpdt_table;
570
571 cplb_data[SDRAM_KERN].end = memory_end;
572
573#ifdef CONFIG_MTD_UCLINUX
574 cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
575 cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
576 cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
577# if defined(CONFIG_ROMFS_FS)
578 cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
579
580 /*
581 * The ROMFS_FS size is often not multiple of 1MB.
582 * This can cause multiple CPLB sets covering the same memory area.
583 * This will then cause multiple CPLB hit exceptions.
584 * Workaround: We ensure a contiguous memory area by extending the kernel
585 * memory section over the mtd section.
586 * For ROMFS_FS memory must be covered with ICPLBs anyways.
587 * So there is no difference between kernel and mtd memory setup.
588 */
589
590 cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
591 cplb_data[SDRAM_RAM_MTD].valid = 0;
592
593# endif
594#else
595 cplb_data[SDRAM_RAM_MTD].valid = 0;
596#endif
597
598 cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
599 cplb_data[SDRAM_DMAZ].end = _ramend;
600
601 cplb_data[RES_MEM].start = _ramend;
602 cplb_data[RES_MEM].end = physical_mem_end;
603
604 if (reserved_mem_dcache_on)
605 cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
606 else
607 cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
608
609 if (reserved_mem_icache_on)
610 cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
611 else
612 cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
613
614 for (i = ZERO_P; i <= L2_MEM; i++) {
615 if (!cplb_data[i].valid)
616 continue;
617
618 as_1m = cplb_data[i].start % SIZE_1M;
619
620 /*
621 * We need to make sure all sections are properly 1M aligned
622 * However between Kernel Memory and the Kernel mtd section,
623 * depending on the rootfs size, there can be overlapping
624 * memory areas.
625 */
626
627 if (as_1m && i != L1I_MEM && i != L1D_MEM) {
628#ifdef CONFIG_MTD_UCLINUX
629 if (i == SDRAM_RAM_MTD) {
630 if ((cplb_data[SDRAM_KERN].end + 1) >
631 cplb_data[SDRAM_RAM_MTD].start)
632 cplb_data[SDRAM_RAM_MTD].start =
633 (cplb_data[i].start &
634 (-2*SIZE_1M)) + SIZE_1M;
635 else
636 cplb_data[SDRAM_RAM_MTD].start =
637 (cplb_data[i].start &
638 (-2*SIZE_1M));
639 } else
640#endif
641 printk(KERN_WARNING
642 "Unaligned Start of %s at 0x%X\n",
643 cplb_data[i].name, cplb_data[i].start);
644 }
645
646 as = cplb_data[i].start % SIZE_4M;
647 ae = cplb_data[i].end % SIZE_4M;
648
649 if (as)
650 a_start = cplb_data[i].start + (SIZE_4M - (as));
651 else
652 a_start = cplb_data[i].start;
653
654 a_end = cplb_data[i].end - ae;
655
656 for (j = INITIAL_T; j <= SWITCH_T; j++) {
657
658 switch (j) {
659 case INITIAL_T:
660 if (cplb_data[i].attr & INITIAL_T) {
661 t_i = &cplb.init_i;
662 t_d = &cplb.init_d;
663 process = 1;
664 } else
665 process = 0;
666 break;
667 case SWITCH_T:
668 if (cplb_data[i].attr & SWITCH_T) {
669 t_i = &cplb.switch_i;
670 t_d = &cplb.switch_d;
671 process = 1;
672 } else
673 process = 0;
674 break;
675 default:
676 process = 0;
677 break;
678 }
679
680 if (!process)
681 continue;
682 if (cplb_data[i].attr & I_CPLB)
683 __fill_code_cplbtab(t_i, i, a_start, a_end);
684
685 if (cplb_data[i].attr & D_CPLB)
686 __fill_data_cplbtab(t_d, i, a_start, a_end);
687 }
688 }
689
690/* close tables */
691
692 close_cplbtab(&cplb.init_i);
693 close_cplbtab(&cplb.init_d);
694
695 cplb.init_i.tab[cplb.init_i.pos] = -1;
696 cplb.init_d.tab[cplb.init_d.pos] = -1;
697 cplb.switch_i.tab[cplb.switch_i.pos] = -1;
698 cplb.switch_d.tab[cplb.switch_d.pos] = -1;
699
700}
701
702#endif
703
704static u_long get_vco(void) 450static u_long get_vco(void)
705{ 451{
706 u_long msel; 452 u_long msel;
@@ -730,7 +476,6 @@ u_long get_cclk(void)
730 return get_vco() / ssel; 476 return get_vco() / ssel;
731 return get_vco() >> csel; 477 return get_vco() >> csel;
732} 478}
733
734EXPORT_SYMBOL(get_cclk); 479EXPORT_SYMBOL(get_cclk);
735 480
736/* Get the System clock */ 481/* Get the System clock */
@@ -749,7 +494,6 @@ u_long get_sclk(void)
749 494
750 return get_vco() / ssel; 495 return get_vco() / ssel;
751} 496}
752
753EXPORT_SYMBOL(get_sclk); 497EXPORT_SYMBOL(get_sclk);
754 498
755/* 499/*
@@ -804,23 +548,23 @@ static int show_cpuinfo(struct seq_file *m, void *v)
804 seq_printf(m, "D-CACHE:\tOFF\n"); 548 seq_printf(m, "D-CACHE:\tOFF\n");
805 549
806 550
807 switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) { 551 switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
808 case ACACHE_BSRAM: 552 case ACACHE_BSRAM:
809 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n"); 553 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
810 dcache_size = 16; 554 dcache_size = 16;
811 dsup_banks = 1; 555 dsup_banks = 1;
812 break; 556 break;
813 case ACACHE_BCACHE: 557 case ACACHE_BCACHE:
814 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n"); 558 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
815 dcache_size = 32; 559 dcache_size = 32;
816 dsup_banks = 2; 560 dsup_banks = 2;
817 break; 561 break;
818 case ASRAM_BSRAM: 562 case ASRAM_BSRAM:
819 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n"); 563 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
820 dcache_size = 0; 564 dcache_size = 0;
821 dsup_banks = 0; 565 dsup_banks = 0;
822 break; 566 break;
823 default: 567 default:
824 break; 568 break;
825 } 569 }
826 570