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.c90
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})
665static inline int __init get_mem_size(void) 675static 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
843subsys_initcall(topology_init); 854subsys_initcall(topology_init);
844 855
856/* Get the voltage input multiplier */
857static u_long cached_vco_pll_ctl, cached_vco;
845static u_long get_vco(void) 858static 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 */
879static u_long cached_cclk_pll_div, cached_cclk;
861u_long get_cclk(void) 880u_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}
874EXPORT_SYMBOL(get_cclk); 901EXPORT_SYMBOL(get_cclk);
875 902
876/* Get the System clock */ 903/* Get the System clock */
904static u_long cached_sclk_pll_div, cached_sclk;
877u_long get_sclk(void) 905u_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}
892EXPORT_SYMBOL(get_sclk); 927EXPORT_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,