aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/setup.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@analog.com>2007-07-12 04:25:29 -0400
committerBryan Wu <bryan.wu@analog.com>2007-07-12 04:25:29 -0400
commit29440a2b4cd37e32dfe0fa60ef1665775b24dab1 (patch)
tree1b7bd1c1793feba0719f04de2eb68e418498e827 /arch/blackfin/kernel/setup.c
parent474f1a667d4bd40b6dcacc6870b70f4d2ba4e155 (diff)
Blackfin arch: Start untangling the CPLB handling code.
- Move cache initialization to C from assembly. - Move anomaly workaround for writing [ID]MEM_CONTROL to assembly, so that we don't have to mess around with .align directives in C source. - Fix a bug where bfin_write_DMEM_CONTROL would write to IMEM_CONTROL - Break out CPLB related code from kernel/setup.c into their own file. - Don't define variables in header files, only declare them. Signed-off-by: Bernd Schmidt <bernd.schmidt@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/kernel/setup.c')
-rw-r--r--arch/blackfin/kernel/setup.c289
1 files changed, 2 insertions, 287 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 534227f4da30..07c1cfdc958e 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -64,10 +64,6 @@ EXPORT_SYMBOL(mtd_size);
64 64
65char __initdata command_line[COMMAND_LINE_SIZE]; 65char __initdata command_line[COMMAND_LINE_SIZE];
66 66
67#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
68static void generate_cpl_tables(void);
69#endif
70
71void __init bf53x_cache_init(void) 67void __init bf53x_cache_init(void)
72{ 68{
73#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 69#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
@@ -401,8 +397,6 @@ void __init setup_arch(char **cmdline_p)
401 _bfin_swrst = bfin_read_SWRST(); 397 _bfin_swrst = bfin_read_SWRST();
402#endif 398#endif
403 399
404 bf53x_cache_init();
405
406 printk(KERN_INFO "Hardware Trace Enabled\n"); 400 printk(KERN_INFO "Hardware Trace Enabled\n");
407 bfin_write_TBUFCTL(0x03); 401 bfin_write_TBUFCTL(0x03);
408 402
@@ -426,6 +420,8 @@ void __init setup_arch(char **cmdline_p)
426 != ATOMIC_AND32 - FIXED_CODE_START); 420 != ATOMIC_AND32 - FIXED_CODE_START);
427 BUG_ON((char *)&atomic_xor32 - (char *)&fixed_code_start 421 BUG_ON((char *)&atomic_xor32 - (char *)&fixed_code_start
428 != ATOMIC_XOR32 - FIXED_CODE_START); 422 != ATOMIC_XOR32 - FIXED_CODE_START);
423
424 bf53x_cache_init();
429} 425}
430 426
431static int __init topology_init(void) 427static int __init topology_init(void)
@@ -443,287 +439,6 @@ static int __init topology_init(void)
443 439
444subsys_initcall(topology_init); 440subsys_initcall(topology_init);
445 441
446#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
447static u16 __init lock_kernel_check(u32 start, u32 end)
448{
449 if ((start <= (u32) _stext && end >= (u32) _end)
450 || (start >= (u32) _stext && end <= (u32) _end))
451 return IN_KERNEL;
452 return 0;
453}
454
455static unsigned short __init
456fill_cplbtab(struct cplb_tab *table,
457 unsigned long start, unsigned long end,
458 unsigned long block_size, unsigned long cplb_data)
459{
460 int i;
461
462 switch (block_size) {
463 case SIZE_4M:
464 i = 3;
465 break;
466 case SIZE_1M:
467 i = 2;
468 break;
469 case SIZE_4K:
470 i = 1;
471 break;
472 case SIZE_1K:
473 default:
474 i = 0;
475 break;
476 }
477
478 cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
479
480 while ((start < end) && (table->pos < table->size)) {
481
482 table->tab[table->pos++] = start;
483
484 if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
485 table->tab[table->pos++] =
486 cplb_data | CPLB_LOCK | CPLB_DIRTY;
487 else
488 table->tab[table->pos++] = cplb_data;
489
490 start += block_size;
491 }
492 return 0;
493}
494
495static unsigned short __init
496close_cplbtab(struct cplb_tab *table)
497{
498
499 while (table->pos < table->size) {
500
501 table->tab[table->pos++] = 0;
502 table->tab[table->pos++] = 0; /* !CPLB_VALID */
503 }
504 return 0;
505}
506
507/* helper function */
508static void __fill_code_cplbtab(struct cplb_tab *t, int i,
509 u32 a_start, u32 a_end)
510{
511 if (cplb_data[i].psize) {
512 fill_cplbtab(t,
513 cplb_data[i].start,
514 cplb_data[i].end,
515 cplb_data[i].psize,
516 cplb_data[i].i_conf);
517 } else {
518#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
519 if (i == SDRAM_KERN) {
520 fill_cplbtab(t,
521 cplb_data[i].start,
522 cplb_data[i].end,
523 SIZE_4M,
524 cplb_data[i].i_conf);
525 } else
526#endif
527 {
528 fill_cplbtab(t,
529 cplb_data[i].start,
530 a_start,
531 SIZE_1M,
532 cplb_data[i].i_conf);
533 fill_cplbtab(t,
534 a_start,
535 a_end,
536 SIZE_4M,
537 cplb_data[i].i_conf);
538 fill_cplbtab(t, a_end,
539 cplb_data[i].end,
540 SIZE_1M,
541 cplb_data[i].i_conf);
542 }
543 }
544}
545
546static void __fill_data_cplbtab(struct cplb_tab *t, int i,
547 u32 a_start, u32 a_end)
548{
549 if (cplb_data[i].psize) {
550 fill_cplbtab(t,
551 cplb_data[i].start,
552 cplb_data[i].end,
553 cplb_data[i].psize,
554 cplb_data[i].d_conf);
555 } else {
556 fill_cplbtab(t,
557 cplb_data[i].start,
558 a_start, SIZE_1M,
559 cplb_data[i].d_conf);
560 fill_cplbtab(t, a_start,
561 a_end, SIZE_4M,
562 cplb_data[i].d_conf);
563 fill_cplbtab(t, a_end,
564 cplb_data[i].end,
565 SIZE_1M,
566 cplb_data[i].d_conf);
567 }
568}
569static void __init generate_cpl_tables(void)
570{
571
572 u16 i, j, process;
573 u32 a_start, a_end, as, ae, as_1m;
574
575 struct cplb_tab *t_i = NULL;
576 struct cplb_tab *t_d = NULL;
577 struct s_cplb cplb;
578
579 cplb.init_i.size = MAX_CPLBS;
580 cplb.init_d.size = MAX_CPLBS;
581 cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
582 cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
583
584 cplb.init_i.pos = 0;
585 cplb.init_d.pos = 0;
586 cplb.switch_i.pos = 0;
587 cplb.switch_d.pos = 0;
588
589 cplb.init_i.tab = icplb_table;
590 cplb.init_d.tab = dcplb_table;
591 cplb.switch_i.tab = ipdt_table;
592 cplb.switch_d.tab = dpdt_table;
593
594 cplb_data[SDRAM_KERN].end = memory_end;
595
596#ifdef CONFIG_MTD_UCLINUX
597 cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
598 cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
599 cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
600# if defined(CONFIG_ROMFS_FS)
601 cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
602
603 /*
604 * The ROMFS_FS size is often not multiple of 1MB.
605 * This can cause multiple CPLB sets covering the same memory area.
606 * This will then cause multiple CPLB hit exceptions.
607 * Workaround: We ensure a contiguous memory area by extending the kernel
608 * memory section over the mtd section.
609 * For ROMFS_FS memory must be covered with ICPLBs anyways.
610 * So there is no difference between kernel and mtd memory setup.
611 */
612
613 cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
614 cplb_data[SDRAM_RAM_MTD].valid = 0;
615
616# endif
617#else
618 cplb_data[SDRAM_RAM_MTD].valid = 0;
619#endif
620
621 cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
622 cplb_data[SDRAM_DMAZ].end = _ramend;
623
624 cplb_data[RES_MEM].start = _ramend;
625 cplb_data[RES_MEM].end = physical_mem_end;
626
627 if (reserved_mem_dcache_on)
628 cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
629 else
630 cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
631
632 if (reserved_mem_icache_on)
633 cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
634 else
635 cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
636
637 for (i = ZERO_P; i <= L2_MEM; i++) {
638 if (!cplb_data[i].valid)
639 continue;
640
641 as_1m = cplb_data[i].start % SIZE_1M;
642
643 /*
644 * We need to make sure all sections are properly 1M aligned
645 * However between Kernel Memory and the Kernel mtd section,
646 * depending on the rootfs size, there can be overlapping
647 * memory areas.
648 */
649
650 if (as_1m && i != L1I_MEM && i != L1D_MEM) {
651#ifdef CONFIG_MTD_UCLINUX
652 if (i == SDRAM_RAM_MTD) {
653 if ((cplb_data[SDRAM_KERN].end + 1) >
654 cplb_data[SDRAM_RAM_MTD].start)
655 cplb_data[SDRAM_RAM_MTD].start =
656 (cplb_data[i].start &
657 (-2*SIZE_1M)) + SIZE_1M;
658 else
659 cplb_data[SDRAM_RAM_MTD].start =
660 (cplb_data[i].start &
661 (-2*SIZE_1M));
662 } else
663#endif
664 printk(KERN_WARNING
665 "Unaligned Start of %s at 0x%X\n",
666 cplb_data[i].name, cplb_data[i].start);
667 }
668
669 as = cplb_data[i].start % SIZE_4M;
670 ae = cplb_data[i].end % SIZE_4M;
671
672 if (as)
673 a_start = cplb_data[i].start + (SIZE_4M - (as));
674 else
675 a_start = cplb_data[i].start;
676
677 a_end = cplb_data[i].end - ae;
678
679 for (j = INITIAL_T; j <= SWITCH_T; j++) {
680
681 switch (j) {
682 case INITIAL_T:
683 if (cplb_data[i].attr & INITIAL_T) {
684 t_i = &cplb.init_i;
685 t_d = &cplb.init_d;
686 process = 1;
687 } else
688 process = 0;
689 break;
690 case SWITCH_T:
691 if (cplb_data[i].attr & SWITCH_T) {
692 t_i = &cplb.switch_i;
693 t_d = &cplb.switch_d;
694 process = 1;
695 } else
696 process = 0;
697 break;
698 default:
699 process = 0;
700 break;
701 }
702
703 if (!process)
704 continue;
705 if (cplb_data[i].attr & I_CPLB)
706 __fill_code_cplbtab(t_i, i, a_start, a_end);
707
708 if (cplb_data[i].attr & D_CPLB)
709 __fill_data_cplbtab(t_d, i, a_start, a_end);
710 }
711 }
712
713/* close tables */
714
715 close_cplbtab(&cplb.init_i);
716 close_cplbtab(&cplb.init_d);
717
718 cplb.init_i.tab[cplb.init_i.pos] = -1;
719 cplb.init_d.tab[cplb.init_d.pos] = -1;
720 cplb.switch_i.tab[cplb.switch_i.pos] = -1;
721 cplb.switch_d.tab[cplb.switch_d.pos] = -1;
722
723}
724
725#endif
726
727static u_long get_vco(void) 442static u_long get_vco(void)
728{ 443{
729 u_long msel; 444 u_long msel;