cpufreq: exynos4x12: Parse frequency table from device tree
authorLukasz Majewski <l.majewski@samsung.com>
Thu, 14 Feb 2013 18:43:20 +0000 (19:43 +0100)
committerChanho Park <chanho61.park@samsung.com>
Tue, 18 Nov 2014 02:42:36 +0000 (11:42 +0900)
Proxima PQ (rev1.1) can run stable at frequencies not higher than 1100 MHz.
In the current code (exynos4x12-cpufreq) frequency up to 1400 MHz
can be set (which shall work for REDWOOD).

For the Proxima PQ frequency table has been modified and passed via device
tree.

Tested-on: Proxima PQ rev1.1

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
drivers/cpufreq/exynos-cpufreq.c
drivers/cpufreq/exynos-cpufreq.h
drivers/cpufreq/exynos4x12-cpufreq.c

index ee4b947..3197d88 100644 (file)
@@ -284,6 +284,72 @@ static struct cpufreq_driver exynos_driver = {
 
 /* Device Tree Support for CPU freq */
 
+struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+               struct exynos_dvfs_info *info, const char *property_name)
+{
+       struct device_node *node = info->dev->of_node;
+       struct cpufreq_frequency_table *ft, *ret = NULL;
+       struct property *pp;
+       int len, num, i = 0;
+       u32 *of_f_tab;
+
+       if (!node)
+               return NULL;
+
+       pp = of_find_property(node, property_name, &len);
+       if (!pp) {
+               pr_debug("%s: Property: %s not found\n", __func__,
+                        property_name);
+               goto err;
+       }
+
+       if (len == 0) {
+               pr_debug("%s: Length wrong value!\n", __func__);
+               goto err;
+       }
+
+       of_f_tab = kzalloc(len, GFP_KERNEL);
+       if (!of_f_tab) {
+               pr_err("%s: Allocation failed\n", __func__);
+               goto err;
+       }
+
+       num = len / sizeof(u32);
+
+       if (of_property_read_u32_array(node, pp->name, of_f_tab, num)) {
+               pr_err("%s: Property: %s cannot be read!\n", __func__,
+                      pp->name);
+               goto err_of_f_tab;
+       }
+
+       /* Here + 2 is required for CPUFREQ_ENTRY_INVALID and
+          CPUFREQ_TABLE_END  */
+       ft = kzalloc(sizeof(struct cpufreq_frequency_table) * (num + 2),
+                    GFP_KERNEL);
+       if (!ft) {
+               pr_err("%s: Allocation failed\n", __func__);
+               goto err_of_f_tab;
+       }
+
+       ft[0].index = L0;
+       ft[0].frequency = CPUFREQ_ENTRY_INVALID;
+
+       for (i = 1; i <= num; i++) {
+               ft[i].index = i;
+               ft[i].frequency = of_f_tab[i-1];
+       }
+
+       ft[i].index = 0;
+       ft[i].frequency = CPUFREQ_TABLE_END;
+
+       ret = ft;
+
+ err_of_f_tab:
+       kfree(of_f_tab);
+ err:
+       return ret;
+}
+
 #ifdef CONFIG_OF
 static struct of_device_id exynos_cpufreq_of_match[] __initconst = {
        { .compatible = "samsung,exynos-cpufreq", },
index 1d45a61..4e08ba7 100644 (file)
@@ -47,3 +47,5 @@ struct exynos_dvfs_info {
 extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
 extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
 extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
+extern struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+               struct exynos_dvfs_info *info, const char *property_name);
index 972e949..70999b2 100644 (file)
@@ -247,7 +247,11 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
        info->pll_safe_idx = L7;
        info->cpu_clk = cpu_clk;
        info->volt_table = exynos4x12_volt_table;
-       info->freq_table = exynos4x12_freq_table;
+
+       info->freq_table = exynos_of_parse_freq_table(info, "freq_table");
+       if (!info->freq_table)
+               info->freq_table = exynos4x12_freq_table;
+
        info->set_freq = exynos4x12_set_frequency;
        info->need_apll_change = exynos4x12_pms_change;