diff options
Diffstat (limited to 'arch/arm/mach-davinci/da850.c')
-rw-r--r-- | arch/arm/mach-davinci/da850.c | 75 |
1 files changed, 60 insertions, 15 deletions
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b902760..78b5ae29ae40 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c | |||
@@ -830,8 +830,7 @@ static void da850_set_async3_src(int pllnum) | |||
830 | * According to the TRM, minimum PLLM results in maximum power savings. | 830 | * According to the TRM, minimum PLLM results in maximum power savings. |
831 | * The OPP definitions below should keep the PLLM as low as possible. | 831 | * The OPP definitions below should keep the PLLM as low as possible. |
832 | * | 832 | * |
833 | * The output of the PLLM must be between 400 to 600 MHz. | 833 | * The output of the PLLM must be between 300 to 600 MHz. |
834 | * This rules out prediv of anything but divide-by-one for 24Mhz OSC input. | ||
835 | */ | 834 | */ |
836 | struct da850_opp { | 835 | struct da850_opp { |
837 | unsigned int freq; /* in KHz */ | 836 | unsigned int freq; /* in KHz */ |
@@ -842,6 +841,33 @@ struct da850_opp { | |||
842 | unsigned int cvdd_max; /* in uV */ | 841 | unsigned int cvdd_max; /* in uV */ |
843 | }; | 842 | }; |
844 | 843 | ||
844 | static const struct da850_opp da850_opp_456 = { | ||
845 | .freq = 456000, | ||
846 | .prediv = 1, | ||
847 | .mult = 19, | ||
848 | .postdiv = 1, | ||
849 | .cvdd_min = 1300000, | ||
850 | .cvdd_max = 1350000, | ||
851 | }; | ||
852 | |||
853 | static const struct da850_opp da850_opp_408 = { | ||
854 | .freq = 408000, | ||
855 | .prediv = 1, | ||
856 | .mult = 17, | ||
857 | .postdiv = 1, | ||
858 | .cvdd_min = 1300000, | ||
859 | .cvdd_max = 1350000, | ||
860 | }; | ||
861 | |||
862 | static const struct da850_opp da850_opp_372 = { | ||
863 | .freq = 372000, | ||
864 | .prediv = 2, | ||
865 | .mult = 31, | ||
866 | .postdiv = 1, | ||
867 | .cvdd_min = 1200000, | ||
868 | .cvdd_max = 1320000, | ||
869 | }; | ||
870 | |||
845 | static const struct da850_opp da850_opp_300 = { | 871 | static const struct da850_opp da850_opp_300 = { |
846 | .freq = 300000, | 872 | .freq = 300000, |
847 | .prediv = 1, | 873 | .prediv = 1, |
@@ -876,6 +902,9 @@ static const struct da850_opp da850_opp_96 = { | |||
876 | } | 902 | } |
877 | 903 | ||
878 | static struct cpufreq_frequency_table da850_freq_table[] = { | 904 | static struct cpufreq_frequency_table da850_freq_table[] = { |
905 | OPP(456), | ||
906 | OPP(408), | ||
907 | OPP(372), | ||
879 | OPP(300), | 908 | OPP(300), |
880 | OPP(200), | 909 | OPP(200), |
881 | OPP(96), | 910 | OPP(96), |
@@ -886,6 +915,19 @@ static struct cpufreq_frequency_table da850_freq_table[] = { | |||
886 | }; | 915 | }; |
887 | 916 | ||
888 | #ifdef CONFIG_REGULATOR | 917 | #ifdef CONFIG_REGULATOR |
918 | static int da850_set_voltage(unsigned int index); | ||
919 | static int da850_regulator_init(void); | ||
920 | #endif | ||
921 | |||
922 | static struct davinci_cpufreq_config cpufreq_info = { | ||
923 | .freq_table = da850_freq_table, | ||
924 | #ifdef CONFIG_REGULATOR | ||
925 | .init = da850_regulator_init, | ||
926 | .set_voltage = da850_set_voltage, | ||
927 | #endif | ||
928 | }; | ||
929 | |||
930 | #ifdef CONFIG_REGULATOR | ||
889 | static struct regulator *cvdd; | 931 | static struct regulator *cvdd; |
890 | 932 | ||
891 | static int da850_set_voltage(unsigned int index) | 933 | static int da850_set_voltage(unsigned int index) |
@@ -895,7 +937,7 @@ static int da850_set_voltage(unsigned int index) | |||
895 | if (!cvdd) | 937 | if (!cvdd) |
896 | return -ENODEV; | 938 | return -ENODEV; |
897 | 939 | ||
898 | opp = (struct da850_opp *) da850_freq_table[index].index; | 940 | opp = (struct da850_opp *) cpufreq_info.freq_table[index].index; |
899 | 941 | ||
900 | return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max); | 942 | return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max); |
901 | } | 943 | } |
@@ -912,14 +954,6 @@ static int da850_regulator_init(void) | |||
912 | } | 954 | } |
913 | #endif | 955 | #endif |
914 | 956 | ||
915 | static struct davinci_cpufreq_config cpufreq_info = { | ||
916 | .freq_table = &da850_freq_table[0], | ||
917 | #ifdef CONFIG_REGULATOR | ||
918 | .init = da850_regulator_init, | ||
919 | .set_voltage = da850_set_voltage, | ||
920 | #endif | ||
921 | }; | ||
922 | |||
923 | static struct platform_device da850_cpufreq_device = { | 957 | static struct platform_device da850_cpufreq_device = { |
924 | .name = "cpufreq-davinci", | 958 | .name = "cpufreq-davinci", |
925 | .dev = { | 959 | .dev = { |
@@ -928,12 +962,22 @@ static struct platform_device da850_cpufreq_device = { | |||
928 | .id = -1, | 962 | .id = -1, |
929 | }; | 963 | }; |
930 | 964 | ||
965 | unsigned int da850_max_speed = 300000; | ||
966 | |||
931 | int __init da850_register_cpufreq(char *async_clk) | 967 | int __init da850_register_cpufreq(char *async_clk) |
932 | { | 968 | { |
969 | int i; | ||
970 | |||
933 | /* cpufreq driver can help keep an "async" clock constant */ | 971 | /* cpufreq driver can help keep an "async" clock constant */ |
934 | if (async_clk) | 972 | if (async_clk) |
935 | clk_add_alias("async", da850_cpufreq_device.name, | 973 | clk_add_alias("async", da850_cpufreq_device.name, |
936 | async_clk, NULL); | 974 | async_clk, NULL); |
975 | for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) { | ||
976 | if (da850_freq_table[i].frequency <= da850_max_speed) { | ||
977 | cpufreq_info.freq_table = &da850_freq_table[i]; | ||
978 | break; | ||
979 | } | ||
980 | } | ||
937 | 981 | ||
938 | return platform_device_register(&da850_cpufreq_device); | 982 | return platform_device_register(&da850_cpufreq_device); |
939 | } | 983 | } |
@@ -942,17 +986,18 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate) | |||
942 | { | 986 | { |
943 | int i, ret = 0, diff; | 987 | int i, ret = 0, diff; |
944 | unsigned int best = (unsigned int) -1; | 988 | unsigned int best = (unsigned int) -1; |
989 | struct cpufreq_frequency_table *table = cpufreq_info.freq_table; | ||
945 | 990 | ||
946 | rate /= 1000; /* convert to kHz */ | 991 | rate /= 1000; /* convert to kHz */ |
947 | 992 | ||
948 | for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { | 993 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { |
949 | diff = da850_freq_table[i].frequency - rate; | 994 | diff = table[i].frequency - rate; |
950 | if (diff < 0) | 995 | if (diff < 0) |
951 | diff = -diff; | 996 | diff = -diff; |
952 | 997 | ||
953 | if (diff < best) { | 998 | if (diff < best) { |
954 | best = diff; | 999 | best = diff; |
955 | ret = da850_freq_table[i].frequency; | 1000 | ret = table[i].frequency; |
956 | } | 1001 | } |
957 | } | 1002 | } |
958 | 1003 | ||
@@ -973,7 +1018,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index) | |||
973 | struct pll_data *pll = clk->pll_data; | 1018 | struct pll_data *pll = clk->pll_data; |
974 | int ret; | 1019 | int ret; |
975 | 1020 | ||
976 | opp = (struct da850_opp *) da850_freq_table[index].index; | 1021 | opp = (struct da850_opp *) cpufreq_info.freq_table[index].index; |
977 | prediv = opp->prediv; | 1022 | prediv = opp->prediv; |
978 | mult = opp->mult; | 1023 | mult = opp->mult; |
979 | postdiv = opp->postdiv; | 1024 | postdiv = opp->postdiv; |