diff options
Diffstat (limited to 'arch/blackfin/kernel/setup.c')
-rw-r--r-- | arch/blackfin/kernel/setup.c | 131 |
1 files changed, 107 insertions, 24 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 2255c289a714..8efea004aecb 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -35,6 +35,7 @@ u16 _bfin_swrst; | |||
35 | EXPORT_SYMBOL(_bfin_swrst); | 35 | EXPORT_SYMBOL(_bfin_swrst); |
36 | 36 | ||
37 | unsigned long memory_start, memory_end, physical_mem_end; | 37 | unsigned long memory_start, memory_end, physical_mem_end; |
38 | unsigned long _rambase, _ramstart, _ramend; | ||
38 | unsigned long reserved_mem_dcache_on; | 39 | unsigned long reserved_mem_dcache_on; |
39 | unsigned long reserved_mem_icache_on; | 40 | unsigned long reserved_mem_icache_on; |
40 | EXPORT_SYMBOL(memory_start); | 41 | EXPORT_SYMBOL(memory_start); |
@@ -106,7 +107,7 @@ void __init bf53x_relocate_l1_mem(void) | |||
106 | 107 | ||
107 | l1_code_length = _etext_l1 - _stext_l1; | 108 | l1_code_length = _etext_l1 - _stext_l1; |
108 | if (l1_code_length > L1_CODE_LENGTH) | 109 | if (l1_code_length > L1_CODE_LENGTH) |
109 | l1_code_length = L1_CODE_LENGTH; | 110 | panic("L1 Instruction SRAM Overflow\n"); |
110 | /* cannot complain as printk is not available as yet. | 111 | /* cannot complain as printk is not available as yet. |
111 | * But we can continue booting and complain later! | 112 | * But we can continue booting and complain later! |
112 | */ | 113 | */ |
@@ -116,19 +117,18 @@ void __init bf53x_relocate_l1_mem(void) | |||
116 | 117 | ||
117 | l1_data_a_length = _ebss_l1 - _sdata_l1; | 118 | l1_data_a_length = _ebss_l1 - _sdata_l1; |
118 | if (l1_data_a_length > L1_DATA_A_LENGTH) | 119 | if (l1_data_a_length > L1_DATA_A_LENGTH) |
119 | l1_data_a_length = L1_DATA_A_LENGTH; | 120 | panic("L1 Data SRAM Bank A Overflow\n"); |
120 | 121 | ||
121 | /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */ | 122 | /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */ |
122 | dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); | 123 | dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); |
123 | 124 | ||
124 | l1_data_b_length = _ebss_b_l1 - _sdata_b_l1; | 125 | l1_data_b_length = _ebss_b_l1 - _sdata_b_l1; |
125 | if (l1_data_b_length > L1_DATA_B_LENGTH) | 126 | if (l1_data_b_length > L1_DATA_B_LENGTH) |
126 | l1_data_b_length = L1_DATA_B_LENGTH; | 127 | panic("L1 Data SRAM Bank B Overflow\n"); |
127 | 128 | ||
128 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ | 129 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ |
129 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + | 130 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + |
130 | l1_data_a_length, l1_data_b_length); | 131 | l1_data_a_length, l1_data_b_length); |
131 | |||
132 | } | 132 | } |
133 | 133 | ||
134 | /* add_memory_region to memmap */ | 134 | /* add_memory_region to memmap */ |
@@ -547,11 +547,38 @@ static __init void memory_setup(void) | |||
547 | ); | 547 | ); |
548 | } | 548 | } |
549 | 549 | ||
550 | /* | ||
551 | * Find the lowest, highest page frame number we have available | ||
552 | */ | ||
553 | void __init find_min_max_pfn(void) | ||
554 | { | ||
555 | int i; | ||
556 | |||
557 | max_pfn = 0; | ||
558 | min_low_pfn = memory_end; | ||
559 | |||
560 | for (i = 0; i < bfin_memmap.nr_map; i++) { | ||
561 | unsigned long start, end; | ||
562 | /* RAM? */ | ||
563 | if (bfin_memmap.map[i].type != BFIN_MEMMAP_RAM) | ||
564 | continue; | ||
565 | start = PFN_UP(bfin_memmap.map[i].addr); | ||
566 | end = PFN_DOWN(bfin_memmap.map[i].addr + | ||
567 | bfin_memmap.map[i].size); | ||
568 | if (start >= end) | ||
569 | continue; | ||
570 | if (end > max_pfn) | ||
571 | max_pfn = end; | ||
572 | if (start < min_low_pfn) | ||
573 | min_low_pfn = start; | ||
574 | } | ||
575 | } | ||
576 | |||
550 | static __init void setup_bootmem_allocator(void) | 577 | static __init void setup_bootmem_allocator(void) |
551 | { | 578 | { |
552 | int bootmap_size; | 579 | int bootmap_size; |
553 | int i; | 580 | int i; |
554 | unsigned long min_pfn, max_pfn; | 581 | unsigned long start_pfn, end_pfn; |
555 | unsigned long curr_pfn, last_pfn, size; | 582 | unsigned long curr_pfn, last_pfn, size; |
556 | 583 | ||
557 | /* mark memory between memory_start and memory_end usable */ | 584 | /* mark memory between memory_start and memory_end usable */ |
@@ -561,8 +588,19 @@ static __init void setup_bootmem_allocator(void) | |||
561 | sanitize_memmap(bfin_memmap.map, &bfin_memmap.nr_map); | 588 | sanitize_memmap(bfin_memmap.map, &bfin_memmap.nr_map); |
562 | print_memory_map("boot memmap"); | 589 | print_memory_map("boot memmap"); |
563 | 590 | ||
564 | min_pfn = PAGE_OFFSET >> PAGE_SHIFT; | 591 | /* intialize globals in linux/bootmem.h */ |
565 | max_pfn = memory_end >> PAGE_SHIFT; | 592 | find_min_max_pfn(); |
593 | /* pfn of the last usable page frame */ | ||
594 | if (max_pfn > memory_end >> PAGE_SHIFT) | ||
595 | max_pfn = memory_end >> PAGE_SHIFT; | ||
596 | /* pfn of last page frame directly mapped by kernel */ | ||
597 | max_low_pfn = max_pfn; | ||
598 | /* pfn of the first usable page frame after kernel image*/ | ||
599 | if (min_low_pfn < memory_start >> PAGE_SHIFT) | ||
600 | min_low_pfn = memory_start >> PAGE_SHIFT; | ||
601 | |||
602 | start_pfn = PAGE_OFFSET >> PAGE_SHIFT; | ||
603 | end_pfn = memory_end >> PAGE_SHIFT; | ||
566 | 604 | ||
567 | /* | 605 | /* |
568 | * give all the memory to the bootmap allocator, tell it to put the | 606 | * give all the memory to the bootmap allocator, tell it to put the |
@@ -570,7 +608,7 @@ static __init void setup_bootmem_allocator(void) | |||
570 | */ | 608 | */ |
571 | bootmap_size = init_bootmem_node(NODE_DATA(0), | 609 | bootmap_size = init_bootmem_node(NODE_DATA(0), |
572 | memory_start >> PAGE_SHIFT, /* map goes here */ | 610 | memory_start >> PAGE_SHIFT, /* map goes here */ |
573 | min_pfn, max_pfn); | 611 | start_pfn, end_pfn); |
574 | 612 | ||
575 | /* register the memmap regions with the bootmem allocator */ | 613 | /* register the memmap regions with the bootmem allocator */ |
576 | for (i = 0; i < bfin_memmap.nr_map; i++) { | 614 | for (i = 0; i < bfin_memmap.nr_map; i++) { |
@@ -583,7 +621,7 @@ static __init void setup_bootmem_allocator(void) | |||
583 | * We are rounding up the start address of usable memory: | 621 | * We are rounding up the start address of usable memory: |
584 | */ | 622 | */ |
585 | curr_pfn = PFN_UP(bfin_memmap.map[i].addr); | 623 | curr_pfn = PFN_UP(bfin_memmap.map[i].addr); |
586 | if (curr_pfn >= max_pfn) | 624 | if (curr_pfn >= end_pfn) |
587 | continue; | 625 | continue; |
588 | /* | 626 | /* |
589 | * ... and at the end of the usable range downwards: | 627 | * ... and at the end of the usable range downwards: |
@@ -591,8 +629,8 @@ static __init void setup_bootmem_allocator(void) | |||
591 | last_pfn = PFN_DOWN(bfin_memmap.map[i].addr + | 629 | last_pfn = PFN_DOWN(bfin_memmap.map[i].addr + |
592 | bfin_memmap.map[i].size); | 630 | bfin_memmap.map[i].size); |
593 | 631 | ||
594 | if (last_pfn > max_pfn) | 632 | if (last_pfn > end_pfn) |
595 | last_pfn = max_pfn; | 633 | last_pfn = end_pfn; |
596 | 634 | ||
597 | /* | 635 | /* |
598 | * .. finally, did all the rounding and playing | 636 | * .. finally, did all the rounding and playing |
@@ -611,9 +649,59 @@ static __init void setup_bootmem_allocator(void) | |||
611 | BOOTMEM_DEFAULT); | 649 | BOOTMEM_DEFAULT); |
612 | } | 650 | } |
613 | 651 | ||
652 | #define EBSZ_TO_MEG(ebsz) \ | ||
653 | ({ \ | ||
654 | int meg = 0; \ | ||
655 | switch (ebsz & 0xf) { \ | ||
656 | case 0x1: meg = 16; break; \ | ||
657 | case 0x3: meg = 32; break; \ | ||
658 | case 0x5: meg = 64; break; \ | ||
659 | case 0x7: meg = 128; break; \ | ||
660 | case 0x9: meg = 256; break; \ | ||
661 | case 0xb: meg = 512; break; \ | ||
662 | } \ | ||
663 | meg; \ | ||
664 | }) | ||
665 | static inline int __init get_mem_size(void) | ||
666 | { | ||
667 | #ifdef CONFIG_MEM_SIZE | ||
668 | return CONFIG_MEM_SIZE; | ||
669 | #else | ||
670 | # if defined(EBIU_SDBCTL) | ||
671 | # if defined(BF561_FAMILY) | ||
672 | int ret = 0; | ||
673 | u32 sdbctl = bfin_read_EBIU_SDBCTL(); | ||
674 | ret += EBSZ_TO_MEG(sdbctl >> 0); | ||
675 | ret += EBSZ_TO_MEG(sdbctl >> 8); | ||
676 | ret += EBSZ_TO_MEG(sdbctl >> 16); | ||
677 | ret += EBSZ_TO_MEG(sdbctl >> 24); | ||
678 | return ret; | ||
679 | # else | ||
680 | return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); | ||
681 | # endif | ||
682 | # elif defined(EBIU_DDRCTL1) | ||
683 | u32 ddrctl = bfin_read_EBIU_DDRCTL1(); | ||
684 | int ret = 0; | ||
685 | switch (ddrctl & 0xc0000) { | ||
686 | case DEVSZ_64: ret = 64 / 8; | ||
687 | case DEVSZ_128: ret = 128 / 8; | ||
688 | case DEVSZ_256: ret = 256 / 8; | ||
689 | case DEVSZ_512: ret = 512 / 8; | ||
690 | } | ||
691 | switch (ddrctl & 0x30000) { | ||
692 | case DEVWD_4: ret *= 2; | ||
693 | case DEVWD_8: ret *= 2; | ||
694 | case DEVWD_16: break; | ||
695 | } | ||
696 | return ret; | ||
697 | # endif | ||
698 | #endif | ||
699 | BUG(); | ||
700 | } | ||
701 | |||
614 | void __init setup_arch(char **cmdline_p) | 702 | void __init setup_arch(char **cmdline_p) |
615 | { | 703 | { |
616 | unsigned long l1_length, sclk, cclk; | 704 | unsigned long sclk, cclk; |
617 | 705 | ||
618 | #ifdef CONFIG_DUMMY_CONSOLE | 706 | #ifdef CONFIG_DUMMY_CONSOLE |
619 | conswitchp = &dummy_con; | 707 | conswitchp = &dummy_con; |
@@ -631,7 +719,7 @@ void __init setup_arch(char **cmdline_p) | |||
631 | 719 | ||
632 | /* setup memory defaults from the user config */ | 720 | /* setup memory defaults from the user config */ |
633 | physical_mem_end = 0; | 721 | physical_mem_end = 0; |
634 | _ramend = CONFIG_MEM_SIZE * 1024 * 1024; | 722 | _ramend = get_mem_size() * 1024 * 1024; |
635 | 723 | ||
636 | memset(&bfin_memmap, 0, sizeof(bfin_memmap)); | 724 | memset(&bfin_memmap, 0, sizeof(bfin_memmap)); |
637 | 725 | ||
@@ -712,15 +800,6 @@ void __init setup_arch(char **cmdline_p) | |||
712 | 800 | ||
713 | paging_init(); | 801 | paging_init(); |
714 | 802 | ||
715 | /* check the size of the l1 area */ | ||
716 | l1_length = _etext_l1 - _stext_l1; | ||
717 | if (l1_length > L1_CODE_LENGTH) | ||
718 | panic("L1 code memory overflow\n"); | ||
719 | |||
720 | l1_length = _ebss_l1 - _sdata_l1; | ||
721 | if (l1_length > L1_DATA_A_LENGTH) | ||
722 | panic("L1 data memory overflow\n"); | ||
723 | |||
724 | /* Copy atomic sequences to their fixed location, and sanity check that | 803 | /* Copy atomic sequences to their fixed location, and sanity check that |
725 | these locations are the ones that we advertise to userspace. */ | 804 | these locations are the ones that we advertise to userspace. */ |
726 | memcpy((void *)FIXED_CODE_START, &fixed_code_start, | 805 | memcpy((void *)FIXED_CODE_START, &fixed_code_start, |
@@ -859,12 +938,17 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
859 | seq_printf(m, "processor\t: %d\n" | 938 | seq_printf(m, "processor\t: %d\n" |
860 | "vendor_id\t: %s\n" | 939 | "vendor_id\t: %s\n" |
861 | "cpu family\t: 0x%x\n" | 940 | "cpu family\t: 0x%x\n" |
862 | "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK)\n" | 941 | "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n" |
863 | "stepping\t: %d\n", | 942 | "stepping\t: %d\n", |
864 | 0, | 943 | 0, |
865 | vendor, | 944 | vendor, |
866 | (bfin_read_CHIPID() & CHIPID_FAMILY), | 945 | (bfin_read_CHIPID() & CHIPID_FAMILY), |
867 | cpu, cclk/1000000, sclk/1000000, | 946 | cpu, cclk/1000000, sclk/1000000, |
947 | #ifdef CONFIG_MPU | ||
948 | "mpu on", | ||
949 | #else | ||
950 | "mpu off", | ||
951 | #endif | ||
868 | revid); | 952 | revid); |
869 | 953 | ||
870 | seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n", | 954 | seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n", |
@@ -973,7 +1057,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
973 | seq_printf(m, "No Ways are locked\n"); | 1057 | seq_printf(m, "No Ways are locked\n"); |
974 | } | 1058 | } |
975 | #endif | 1059 | #endif |
976 | |||
977 | seq_printf(m, "board name\t: %s\n", bfin_board_name); | 1060 | seq_printf(m, "board name\t: %s\n", bfin_board_name); |
978 | seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n", | 1061 | seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n", |
979 | physical_mem_end >> 10, (void *)0, (void *)physical_mem_end); | 1062 | physical_mem_end >> 10, (void *)0, (void *)physical_mem_end); |