summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/dvfs/0014-OMAP3-Introduce-custom-set-rate-and-get-rate-APIs-fo.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/dvfs/0014-OMAP3-Introduce-custom-set-rate-and-get-rate-APIs-fo.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap/dvfs/0014-OMAP3-Introduce-custom-set-rate-and-get-rate-APIs-fo.patch176
1 files changed, 176 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/dvfs/0014-OMAP3-Introduce-custom-set-rate-and-get-rate-APIs-fo.patch b/extras/recipes-kernel/linux/linux-omap/dvfs/0014-OMAP3-Introduce-custom-set-rate-and-get-rate-APIs-fo.patch
new file mode 100644
index 00000000..16335ccb
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap/dvfs/0014-OMAP3-Introduce-custom-set-rate-and-get-rate-APIs-fo.patch
@@ -0,0 +1,176 @@
1From 6fb7bd2b3da02e6e799d3c7661a1acb6572f9add Mon Sep 17 00:00:00 2001
2From: Thara Gopinath <thara@ti.com>
3Date: Wed, 18 Aug 2010 16:22:32 +0530
4Subject: [PATCH 14/20] OMAP3: Introduce custom set rate and get rate APIs for scalable devices
5
6This patch also introduces omap3_mpu_set_rate, omap3_iva_set_rate,
7omap3_l3_set_rate, omap3_mpu_get_rate, omap3_iva_get_rate,
8omap3_l3_get_rate as device specific set rate and get rate
9APIs for OMAP3 mpu, iva and l3_main devices. This patch also
10calls into omap_device_populate_rate_fns during system init to register
11various set_rate and get_rate APIs with the omap device layer
12
13Signed-off-by: Thara Gopinath <thara@ti.com>
14---
15 arch/arm/mach-omap2/pm.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++
16 1 files changed, 110 insertions(+), 0 deletions(-)
17
18diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
19index d5a102c..94ab0dd 100644
20--- a/arch/arm/mach-omap2/pm.c
21+++ b/arch/arm/mach-omap2/pm.c
22@@ -14,6 +14,7 @@
23 #include <linux/io.h>
24 #include <linux/err.h>
25 #include <linux/opp.h>
26+#include <linux/delay.h>
27
28 #include <plat/omap-pm.h>
29 #include <plat/omap_device.h>
30@@ -22,6 +23,8 @@
31
32 #include "powerdomain.h"
33 #include "clockdomain.h"
34+#include "cm-regbits-34xx.h"
35+#include "cm2xxx_3xxx.h"
36 #include "pm.h"
37
38 static struct omap_device_pm_latency *pm_lats;
39@@ -31,6 +34,8 @@ static struct device *iva_dev;
40 static struct device *l3_dev;
41 static struct device *dsp_dev;
42
43+static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
44+
45 struct device *omap2_get_mpuss_device(void)
46 {
47 WARN_ON_ONCE(!mpu_dev);
48@@ -56,6 +61,26 @@ struct device *omap4_get_dsp_device(void)
49 }
50 EXPORT_SYMBOL(omap4_get_dsp_device);
51
52+static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
53+{
54+ unsigned long new_jiffy_l, new_jiffy_h;
55+
56+ /*
57+ * Recalculate loops_per_jiffy. We do it this way to
58+ * avoid math overflow on 32-bit machines. Maybe we
59+ * should make this architecture dependent? If you have
60+ * a better way of doing this, please replace!
61+ *
62+ * new = old * mult / div
63+ */
64+ new_jiffy_h = ref / div;
65+ new_jiffy_l = (ref % div) / 100;
66+ new_jiffy_h *= mult;
67+ new_jiffy_l = new_jiffy_l * mult / div;
68+
69+ return new_jiffy_h + new_jiffy_l * 100;
70+}
71+
72 /* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
73 static int _init_omap_device(char *name, struct device **new_dev)
74 {
75@@ -77,6 +102,74 @@ static int _init_omap_device(char *name, struct device **new_dev)
76 return 0;
77 }
78
79+static unsigned long omap3_mpu_get_rate(struct device *dev)
80+{
81+ return dpll1_clk->rate;
82+}
83+
84+static int omap3_mpu_set_rate(struct device *dev, unsigned long rate)
85+{
86+ unsigned long cur_rate = omap3_mpu_get_rate(dev);
87+ int ret;
88+
89+#ifdef CONFIG_CPU_FREQ
90+ struct cpufreq_freqs freqs_notify;
91+
92+ freqs_notify.old = cur_rate / 1000;
93+ freqs_notify.new = rate / 1000;
94+ freqs_notify.cpu = 0;
95+ /* Send pre notification to CPUFreq */
96+ cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
97+#endif
98+ ret = clk_set_rate(dpll1_clk, rate);
99+ if (ret) {
100+ dev_warn(dev, "%s: Unable to set rate to %ld\n",
101+ __func__, rate);
102+ return ret;
103+ }
104+
105+#ifdef CONFIG_CPU_FREQ
106+ /* Send a post notification to CPUFreq */
107+ cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
108+#endif
109+
110+#ifndef CONFIG_CPU_FREQ
111+ /*Update loops_per_jiffy if processor speed is being changed*/
112+ loops_per_jiffy = compute_lpj(loops_per_jiffy,
113+ cur_rate / 1000, rate / 1000);
114+#endif
115+ return 0;
116+}
117+
118+static int omap3_iva_set_rate(struct device *dev, unsigned long rate)
119+{
120+ return clk_set_rate(dpll2_clk, rate);
121+}
122+
123+static unsigned long omap3_iva_get_rate(struct device *dev)
124+{
125+ return dpll2_clk->rate;
126+}
127+
128+static int omap3_l3_set_rate(struct device *dev, unsigned long rate)
129+{
130+ int l3_div;
131+
132+ l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
133+ OMAP3430_CLKSEL_L3_MASK;
134+
135+ return clk_set_rate(dpll3_clk, rate * l3_div);
136+}
137+
138+static unsigned long omap3_l3_get_rate(struct device *dev)
139+{
140+ int l3_div;
141+
142+ l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
143+ OMAP3430_CLKSEL_L3_MASK;
144+ return dpll3_clk->rate / l3_div;
145+}
146+
147 /*
148 * Build omap_devices for processors and bus.
149 */
150@@ -90,6 +183,23 @@ static void omap2_init_processor_devices(void)
151 } else {
152 _init_omap_device("l3_main", &l3_dev);
153 }
154+
155+ if (cpu_is_omap34xx()) {
156+ dpll1_clk = clk_get(NULL, "dpll1_ck");
157+ dpll2_clk = clk_get(NULL, "dpll2_ck");
158+ dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
159+
160+ if (mpu_dev)
161+ omap_device_populate_rate_fns(mpu_dev,
162+ omap3_mpu_set_rate, omap3_mpu_get_rate);
163+ if (iva_dev)
164+ omap_device_populate_rate_fns(iva_dev,
165+ omap3_iva_set_rate, omap3_iva_get_rate);
166+ if (l3_dev)
167+ omap_device_populate_rate_fns(l3_dev,
168+ omap3_l3_set_rate, omap3_l3_get_rate);
169+
170+ }
171 }
172
173 /* Types of sleep_switch used in omap_set_pwrdm_state */
174--
1751.6.6.1
176