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, |