diff options
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.patch | 176 |
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 @@ | |||
1 | From 6fb7bd2b3da02e6e799d3c7661a1acb6572f9add Mon Sep 17 00:00:00 2001 | ||
2 | From: Thara Gopinath <thara@ti.com> | ||
3 | Date: Wed, 18 Aug 2010 16:22:32 +0530 | ||
4 | Subject: [PATCH 14/20] OMAP3: Introduce custom set rate and get rate APIs for scalable devices | ||
5 | |||
6 | This patch also introduces omap3_mpu_set_rate, omap3_iva_set_rate, | ||
7 | omap3_l3_set_rate, omap3_mpu_get_rate, omap3_iva_get_rate, | ||
8 | omap3_l3_get_rate as device specific set rate and get rate | ||
9 | APIs for OMAP3 mpu, iva and l3_main devices. This patch also | ||
10 | calls into omap_device_populate_rate_fns during system init to register | ||
11 | various set_rate and get_rate APIs with the omap device layer | ||
12 | |||
13 | Signed-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 | |||
18 | diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c | ||
19 | index 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 | -- | ||
175 | 1.6.6.1 | ||
176 | |||