AM18x/DA850/OMAP-L138 SoCs have variants that can operate
at a maximum of 456 MHz at 1.3V operating point. Also the
1.2V operating point has a variant that can support a maximum
of 372 MHz.

This patch adds three new OPPs (456 MHz, 408 MHz and 372 MHz)
to the list of DA850 OPPs.

Not all silicon is qualified to run at higher speeds and
unfortunately the maximum speed the chip can support can only
be read from the label on the package (not software readable).
Because of this, kernel configuration options have been
introduced to help users enable higher speeds if they know
that their slicon can support the higher speed.

Signed-off-by: Sekhar Nori <[email protected]>
---
Because of the Kconfig change, this patch should be applied after
"davinci: introduce support for AM1x ARM9 microprocessors"
submitted earlier.

 arch/arm/mach-davinci/Kconfig           |   23 +++++++++
 arch/arm/mach-davinci/board-da850-evm.c |    2 +-
 arch/arm/mach-davinci/da850.c           |   81 ++++++++++++++++++++++++++-----
 3 files changed, 92 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 94f2a2c..f812124 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -41,6 +41,29 @@ config ARCH_DAVINCI_DA850
        select ARCH_DAVINCI_DA8XX
        select ARCH_HAS_CPUFREQ
 
+choice
+       prompt "Select Maximum DA850/OMAP-L138/AM18x SoC speed"
+       depends on ARCH_DAVINCI_DA850 && CPU_FREQ
+       help
+         Select the maximum speed your device can operate at. Note that
+         running the device at a speed more than it is qualified for can
+         cause permanent damage to the device.
+
+         If unsure, leave at the default (300 MHz).
+
+config DA850_MAX_SPEED_300
+       bool "300 MHz"
+
+config DA850_MAX_SPEED_372
+       bool "372 MHz"
+
+config DA850_MAX_SPEED_408
+       bool "408 MHz"
+
+config DA850_MAX_SPEED_456
+       bool "456 MHz"
+endchoice
+
 config ARCH_DAVINCI_DA8XX
        select CPU_ARM926T
        bool
diff --git a/arch/arm/mach-davinci/board-da850-evm.c 
b/arch/arm/mach-davinci/board-da850-evm.c
index a31f37a..b429c2a 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -500,7 +500,7 @@ struct regulator_init_data tps65070_regulator_data[] = {
        {
                .constraints = {
                        .min_uV = 950000,
-                       .max_uV = 1320000,
+                       .max_uV = 1350000,
                        .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
                                REGULATOR_CHANGE_STATUS),
                        .boot_on = 1,
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index a275e8b..45599a7 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -871,6 +871,33 @@ struct da850_opp {
        unsigned int    cvdd_max; /* in uV */
 };
 
+static const struct da850_opp da850_opp_456 = {
+       .freq           = 456000,
+       .prediv         = 1,
+       .mult           = 19,
+       .postdiv        = 1,
+       .cvdd_min       = 1300000,
+       .cvdd_max       = 1350000,
+};
+
+static const struct da850_opp da850_opp_408 = {
+       .freq           = 408000,
+       .prediv         = 1,
+       .mult           = 17,
+       .postdiv        = 1,
+       .cvdd_min       = 1300000,
+       .cvdd_max       = 1350000,
+};
+
+static const struct da850_opp da850_opp_372 = {
+       .freq           = 372000,
+       .prediv         = 1,
+       .mult           = 31,
+       .postdiv        = 2,
+       .cvdd_min       = 1200000,
+       .cvdd_max       = 1320000,
+};
+
 static const struct da850_opp da850_opp_300 = {
        .freq           = 300000,
        .prediv         = 1,
@@ -905,6 +932,9 @@ static const struct da850_opp da850_opp_96 = {
        }
 
 static struct cpufreq_frequency_table da850_freq_table[] = {
+       OPP(456),
+       OPP(408),
+       OPP(372),
        OPP(300),
        OPP(200),
        OPP(96),
@@ -915,6 +945,19 @@ static struct cpufreq_frequency_table da850_freq_table[] = 
{
 };
 
 #ifdef CONFIG_REGULATOR
+static int da850_set_voltage(unsigned int index);
+static int da850_regulator_init(void);
+#endif
+
+static struct davinci_cpufreq_config cpufreq_info = {
+       .freq_table = &da850_freq_table[0],
+#ifdef CONFIG_REGULATOR
+       .init = da850_regulator_init,
+       .set_voltage = da850_set_voltage,
+#endif
+};
+
+#ifdef CONFIG_REGULATOR
 static struct regulator *cvdd;
 
 static int da850_set_voltage(unsigned int index)
@@ -924,7 +967,7 @@ static int da850_set_voltage(unsigned int index)
        if (!cvdd)
                return -ENODEV;
 
-       opp = (struct da850_opp *) da850_freq_table[index].index;
+       opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
 
        return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
 }
@@ -941,14 +984,6 @@ static int da850_regulator_init(void)
 }
 #endif
 
-static struct davinci_cpufreq_config cpufreq_info = {
-       .freq_table = &da850_freq_table[0],
-#ifdef CONFIG_REGULATOR
-       .init = da850_regulator_init,
-       .set_voltage = da850_set_voltage,
-#endif
-};
-
 static struct platform_device da850_cpufreq_device = {
        .name                   = "cpufreq-davinci",
        .dev = {
@@ -956,8 +991,27 @@ static struct platform_device da850_cpufreq_device = {
        },
 };
 
+#if defined CONFIG_DA850_MAX_SPEED_456
+#define DA850_MAX_SPEED        456000
+#elif defined CONFIG_DA850_MAX_SPEED_408
+#define DA850_MAX_SPEED        408000
+#elif defined CONFIG_DA850_MAX_SPEED_372
+#define DA850_MAX_SPEED        372000
+#else
+#define DA850_MAX_SPEED        300000
+#endif
+
 int __init da850_register_cpufreq(void)
 {
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
+               if (da850_freq_table[i].frequency <= DA850_MAX_SPEED) {
+                       cpufreq_info.freq_table = &da850_freq_table[i];
+                       break;
+               }
+       }
+
        return platform_device_register(&da850_cpufreq_device);
 }
 
@@ -965,17 +1019,18 @@ static int da850_round_armrate(struct clk *clk, unsigned 
long rate)
 {
        int i, ret = 0, diff;
        unsigned int best = (unsigned int) -1;
+       struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
 
        rate /= 1000; /* convert to kHz */
 
-       for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-               diff = da850_freq_table[i].frequency - rate;
+       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               diff = table[i].frequency - rate;
                if (diff < 0)
                        diff = -diff;
 
                if (diff < best) {
                        best = diff;
-                       ret = da850_freq_table[i].frequency;
+                       ret = table[i].frequency;
                }
        }
 
@@ -996,7 +1051,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned 
long index)
        struct pll_data *pll = clk->pll_data;
        int ret;
 
-       opp = (struct da850_opp *) da850_freq_table[index].index;
+       opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
        prediv = opp->prediv;
        mult = opp->mult;
        postdiv = opp->postdiv;
-- 
1.6.2.4

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to