diff options
Diffstat (limited to 'arch/blackfin/kernel/setup.c')
| -rw-r--r-- | arch/blackfin/kernel/setup.c | 90 |
1 files changed, 66 insertions, 24 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8efea004aecb..23e637eb78da 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
| @@ -104,6 +104,7 @@ void __init bf53x_relocate_l1_mem(void) | |||
| 104 | unsigned long l1_code_length; | 104 | unsigned long l1_code_length; |
| 105 | unsigned long l1_data_a_length; | 105 | unsigned long l1_data_a_length; |
| 106 | unsigned long l1_data_b_length; | 106 | unsigned long l1_data_b_length; |
| 107 | unsigned long l2_length; | ||
| 107 | 108 | ||
| 108 | l1_code_length = _etext_l1 - _stext_l1; | 109 | l1_code_length = _etext_l1 - _stext_l1; |
| 109 | if (l1_code_length > L1_CODE_LENGTH) | 110 | if (l1_code_length > L1_CODE_LENGTH) |
| @@ -129,6 +130,15 @@ void __init bf53x_relocate_l1_mem(void) | |||
| 129 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ | 130 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ |
| 130 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + | 131 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + |
| 131 | l1_data_a_length, l1_data_b_length); | 132 | l1_data_a_length, l1_data_b_length); |
| 133 | |||
| 134 | #ifdef L2_LENGTH | ||
| 135 | l2_length = _ebss_l2 - _stext_l2; | ||
| 136 | if (l2_length > L2_LENGTH) | ||
| 137 | panic("L2 SRAM Overflow\n"); | ||
| 138 | |||
| 139 | /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ | ||
| 140 | dma_memcpy(_stext_l2, _l2_lma_start, l2_length); | ||
| 141 | #endif | ||
| 132 | } | 142 | } |
| 133 | 143 | ||
| 134 | /* add_memory_region to memmap */ | 144 | /* add_memory_region to memmap */ |
| @@ -664,11 +674,8 @@ static __init void setup_bootmem_allocator(void) | |||
| 664 | }) | 674 | }) |
| 665 | static inline int __init get_mem_size(void) | 675 | static inline int __init get_mem_size(void) |
| 666 | { | 676 | { |
| 667 | #ifdef CONFIG_MEM_SIZE | 677 | #if defined(EBIU_SDBCTL) |
| 668 | return CONFIG_MEM_SIZE; | 678 | # if defined(BF561_FAMILY) |
| 669 | #else | ||
| 670 | # if defined(EBIU_SDBCTL) | ||
| 671 | # if defined(BF561_FAMILY) | ||
| 672 | int ret = 0; | 679 | int ret = 0; |
| 673 | u32 sdbctl = bfin_read_EBIU_SDBCTL(); | 680 | u32 sdbctl = bfin_read_EBIU_SDBCTL(); |
| 674 | ret += EBSZ_TO_MEG(sdbctl >> 0); | 681 | ret += EBSZ_TO_MEG(sdbctl >> 0); |
| @@ -676,10 +683,10 @@ static inline int __init get_mem_size(void) | |||
| 676 | ret += EBSZ_TO_MEG(sdbctl >> 16); | 683 | ret += EBSZ_TO_MEG(sdbctl >> 16); |
| 677 | ret += EBSZ_TO_MEG(sdbctl >> 24); | 684 | ret += EBSZ_TO_MEG(sdbctl >> 24); |
| 678 | return ret; | 685 | return ret; |
| 679 | # else | 686 | # else |
| 680 | return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); | 687 | return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); |
| 681 | # endif | 688 | # endif |
| 682 | # elif defined(EBIU_DDRCTL1) | 689 | #elif defined(EBIU_DDRCTL1) |
| 683 | u32 ddrctl = bfin_read_EBIU_DDRCTL1(); | 690 | u32 ddrctl = bfin_read_EBIU_DDRCTL1(); |
| 684 | int ret = 0; | 691 | int ret = 0; |
| 685 | switch (ddrctl & 0xc0000) { | 692 | switch (ddrctl & 0xc0000) { |
| @@ -693,8 +700,9 @@ static inline int __init get_mem_size(void) | |||
| 693 | case DEVWD_8: ret *= 2; | 700 | case DEVWD_8: ret *= 2; |
| 694 | case DEVWD_16: break; | 701 | case DEVWD_16: break; |
| 695 | } | 702 | } |
| 703 | if ((ddrctl & 0xc000) == 0x4000) | ||
| 704 | ret *= 2; | ||
| 696 | return ret; | 705 | return ret; |
| 697 | # endif | ||
| 698 | #endif | 706 | #endif |
| 699 | BUG(); | 707 | BUG(); |
| 700 | } | 708 | } |
| @@ -763,6 +771,9 @@ void __init setup_arch(char **cmdline_p) | |||
| 763 | 771 | ||
| 764 | _bfin_swrst = bfin_read_SWRST(); | 772 | _bfin_swrst = bfin_read_SWRST(); |
| 765 | 773 | ||
| 774 | /* If we double fault, reset the system - otherwise we hang forever */ | ||
| 775 | bfin_write_SWRST(DOUBLE_FAULT); | ||
| 776 | |||
| 766 | if (_bfin_swrst & RESET_DOUBLE) | 777 | if (_bfin_swrst & RESET_DOUBLE) |
| 767 | printk(KERN_INFO "Recovering from Double Fault event\n"); | 778 | printk(KERN_INFO "Recovering from Double Fault event\n"); |
| 768 | else if (_bfin_swrst & RESET_WDOG) | 779 | else if (_bfin_swrst & RESET_WDOG) |
| @@ -842,38 +853,55 @@ static int __init topology_init(void) | |||
| 842 | 853 | ||
| 843 | subsys_initcall(topology_init); | 854 | subsys_initcall(topology_init); |
| 844 | 855 | ||
| 856 | /* Get the voltage input multiplier */ | ||
| 857 | static u_long cached_vco_pll_ctl, cached_vco; | ||
| 845 | static u_long get_vco(void) | 858 | static u_long get_vco(void) |
| 846 | { | 859 | { |
| 847 | u_long msel; | 860 | u_long msel; |
| 848 | u_long vco; | ||
| 849 | 861 | ||
| 850 | msel = (bfin_read_PLL_CTL() >> 9) & 0x3F; | 862 | u_long pll_ctl = bfin_read_PLL_CTL(); |
| 863 | if (pll_ctl == cached_vco_pll_ctl) | ||
| 864 | return cached_vco; | ||
| 865 | else | ||
| 866 | cached_vco_pll_ctl = pll_ctl; | ||
| 867 | |||
| 868 | msel = (pll_ctl >> 9) & 0x3F; | ||
| 851 | if (0 == msel) | 869 | if (0 == msel) |
| 852 | msel = 64; | 870 | msel = 64; |
| 853 | 871 | ||
| 854 | vco = CONFIG_CLKIN_HZ; | 872 | cached_vco = CONFIG_CLKIN_HZ; |
| 855 | vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */ | 873 | cached_vco >>= (1 & pll_ctl); /* DF bit */ |
| 856 | vco = msel * vco; | 874 | cached_vco *= msel; |
| 857 | return vco; | 875 | return cached_vco; |
| 858 | } | 876 | } |
| 859 | 877 | ||
| 860 | /* Get the Core clock */ | 878 | /* Get the Core clock */ |
| 879 | static u_long cached_cclk_pll_div, cached_cclk; | ||
| 861 | u_long get_cclk(void) | 880 | u_long get_cclk(void) |
| 862 | { | 881 | { |
| 863 | u_long csel, ssel; | 882 | u_long csel, ssel; |
| 883 | |||
| 864 | if (bfin_read_PLL_STAT() & 0x1) | 884 | if (bfin_read_PLL_STAT() & 0x1) |
| 865 | return CONFIG_CLKIN_HZ; | 885 | return CONFIG_CLKIN_HZ; |
| 866 | 886 | ||
| 867 | ssel = bfin_read_PLL_DIV(); | 887 | ssel = bfin_read_PLL_DIV(); |
| 888 | if (ssel == cached_cclk_pll_div) | ||
| 889 | return cached_cclk; | ||
| 890 | else | ||
| 891 | cached_cclk_pll_div = ssel; | ||
| 892 | |||
| 868 | csel = ((ssel >> 4) & 0x03); | 893 | csel = ((ssel >> 4) & 0x03); |
| 869 | ssel &= 0xf; | 894 | ssel &= 0xf; |
| 870 | if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ | 895 | if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ |
| 871 | return get_vco() / ssel; | 896 | cached_cclk = get_vco() / ssel; |
| 872 | return get_vco() >> csel; | 897 | else |
| 898 | cached_cclk = get_vco() >> csel; | ||
| 899 | return cached_cclk; | ||
| 873 | } | 900 | } |
| 874 | EXPORT_SYMBOL(get_cclk); | 901 | EXPORT_SYMBOL(get_cclk); |
| 875 | 902 | ||
| 876 | /* Get the System clock */ | 903 | /* Get the System clock */ |
| 904 | static u_long cached_sclk_pll_div, cached_sclk; | ||
| 877 | u_long get_sclk(void) | 905 | u_long get_sclk(void) |
| 878 | { | 906 | { |
| 879 | u_long ssel; | 907 | u_long ssel; |
| @@ -881,13 +909,20 @@ u_long get_sclk(void) | |||
| 881 | if (bfin_read_PLL_STAT() & 0x1) | 909 | if (bfin_read_PLL_STAT() & 0x1) |
| 882 | return CONFIG_CLKIN_HZ; | 910 | return CONFIG_CLKIN_HZ; |
| 883 | 911 | ||
| 884 | ssel = (bfin_read_PLL_DIV() & 0xf); | 912 | ssel = bfin_read_PLL_DIV(); |
| 913 | if (ssel == cached_sclk_pll_div) | ||
| 914 | return cached_sclk; | ||
| 915 | else | ||
| 916 | cached_sclk_pll_div = ssel; | ||
| 917 | |||
| 918 | ssel &= 0xf; | ||
| 885 | if (0 == ssel) { | 919 | if (0 == ssel) { |
| 886 | printk(KERN_WARNING "Invalid System Clock\n"); | 920 | printk(KERN_WARNING "Invalid System Clock\n"); |
| 887 | ssel = 1; | 921 | ssel = 1; |
| 888 | } | 922 | } |
| 889 | 923 | ||
| 890 | return get_vco() / ssel; | 924 | cached_sclk = get_vco() / ssel; |
| 925 | return cached_sclk; | ||
| 891 | } | 926 | } |
| 892 | EXPORT_SYMBOL(get_sclk); | 927 | EXPORT_SYMBOL(get_sclk); |
| 893 | 928 | ||
| @@ -916,7 +951,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 916 | uint32_t revid; | 951 | uint32_t revid; |
| 917 | 952 | ||
| 918 | u_long cclk = 0, sclk = 0; | 953 | u_long cclk = 0, sclk = 0; |
| 919 | u_int dcache_size = 0, dsup_banks = 0; | 954 | u_int icache_size = BFIN_ICACHESIZE / 1024, dcache_size = 0, dsup_banks = 0; |
| 920 | 955 | ||
| 921 | cpu = CPU; | 956 | cpu = CPU; |
| 922 | mmu = "none"; | 957 | mmu = "none"; |
| @@ -985,12 +1020,15 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 985 | } | 1020 | } |
| 986 | 1021 | ||
| 987 | /* Is it turned on? */ | 1022 | /* Is it turned on? */ |
| 988 | if (!((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))) | 1023 | if ((bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE)) != (ENDCPLB | DMC_ENABLE)) |
| 989 | dcache_size = 0; | 1024 | dcache_size = 0; |
| 990 | 1025 | ||
| 1026 | if ((bfin_read_IMEM_CONTROL() & (IMC | ENICPLB)) == (IMC | ENICPLB)) | ||
| 1027 | icache_size = 0; | ||
| 1028 | |||
| 991 | seq_printf(m, "cache size\t: %d KB(L1 icache) " | 1029 | seq_printf(m, "cache size\t: %d KB(L1 icache) " |
| 992 | "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", | 1030 | "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", |
| 993 | BFIN_ICACHESIZE / 1024, dcache_size, | 1031 | icache_size, dcache_size, |
| 994 | #if defined CONFIG_BFIN_WB | 1032 | #if defined CONFIG_BFIN_WB |
| 995 | "wb" | 1033 | "wb" |
| 996 | #elif defined CONFIG_BFIN_WT | 1034 | #elif defined CONFIG_BFIN_WT |
| @@ -1000,8 +1038,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 1000 | 1038 | ||
| 1001 | seq_printf(m, "%s\n", cache); | 1039 | seq_printf(m, "%s\n", cache); |
| 1002 | 1040 | ||
| 1003 | seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", | 1041 | if (icache_size) |
| 1004 | BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); | 1042 | seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", |
| 1043 | BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); | ||
| 1044 | else | ||
| 1045 | seq_printf(m, "icache setup\t: off\n"); | ||
| 1046 | |||
| 1005 | seq_printf(m, | 1047 | seq_printf(m, |
| 1006 | "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", | 1048 | "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", |
| 1007 | dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, | 1049 | dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, |
