]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-kernel/linux/linux-3.0/pm-wip/voltdm/0006-omap-Make-a-subset-of-dmtimer-functions-into-inline-.patch
83ee43f02834d949e7da22d97611c0056ac8debb
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-3.0 / pm-wip / voltdm / 0006-omap-Make-a-subset-of-dmtimer-functions-into-inline-.patch
1 From 494286a1785de2342d92c78ba26803cdcfccecfb Mon Sep 17 00:00:00 2001
2 From: Tony Lindgren <tony@atomide.com>
3 Date: Tue, 29 Mar 2011 15:54:48 -0700
4 Subject: [PATCH 006/149] omap: Make a subset of dmtimer functions into inline functions
6 This will allow us to share the code between system timer and
7 dmtimer device driver code without having to initialize all the
8 dmtimers early. This change will also make the timer_set_next_event
9 more efficient as the inline functions will optimize the code
10 better for the timer reprogramming.
12 Signed-off-by: Tony Lindgren <tony@atomide.com>
13 Reviewed-by: Kevin Hilman <khilman@ti.com>
14 ---
15  arch/arm/plat-omap/dmtimer.c              |   78 ++++---------------
16  arch/arm/plat-omap/include/plat/dmtimer.h |  119 +++++++++++++++++++++++++++++
17  2 files changed, 136 insertions(+), 61 deletions(-)
19 diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
20 index dfdc3b2..7c5cb4e 100644
21 --- a/arch/arm/plat-omap/dmtimer.c
22 +++ b/arch/arm/plat-omap/dmtimer.c
23 @@ -170,11 +170,7 @@ static spinlock_t dm_timer_lock;
24   */
25  static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
26  {
27 -       if (timer->posted)
28 -               while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
29 -                               & (reg >> WPSHIFT))
30 -                       cpu_relax();
31 -       return readl(timer->io_base + (reg & 0xff));
32 +       return __omap_dm_timer_read(timer->io_base, reg, timer->posted);
33  }
34  
35  /*
36 @@ -186,11 +182,7 @@ static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
37  static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
38                                                 u32 value)
39  {
40 -       if (timer->posted)
41 -               while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
42 -                               & (reg >> WPSHIFT))
43 -                       cpu_relax();
44 -       writel(value, timer->io_base + (reg & 0xff));
45 +       __omap_dm_timer_write(timer->io_base, reg, value, timer->posted);
46  }
47  
48  static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
49 @@ -209,7 +201,7 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
50  
51  static void omap_dm_timer_reset(struct omap_dm_timer *timer)
52  {
53 -       u32 l;
54 +       int autoidle = 0, wakeup = 0;
55  
56         if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
57                 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
58 @@ -217,28 +209,21 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
59         }
60         omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
61  
62 -       l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
63 -       l |= 0x02 << 3;  /* Set to smart-idle mode */
64 -       l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
65 -
66         /* Enable autoidle on OMAP2 / OMAP3 */
67         if (cpu_is_omap24xx() || cpu_is_omap34xx())
68 -               l |= 0x1 << 0;
69 +               autoidle = 1;
70  
71         /*
72          * Enable wake-up on OMAP2 CPUs.
73          */
74         if (cpu_class_is_omap2())
75 -               l |= 1 << 2;
76 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
77 +               wakeup = 1;
78  
79 -       /* Match hardware reset default of posted mode */
80 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
81 -                       OMAP_TIMER_CTRL_POSTED);
82 +       __omap_dm_timer_reset(timer->io_base, autoidle, wakeup);
83         timer->posted = 1;
84  }
85  
86 -static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
87 +void omap_dm_timer_prepare(struct omap_dm_timer *timer)
88  {
89         omap_dm_timer_enable(timer);
90         omap_dm_timer_reset(timer);
91 @@ -410,25 +395,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start);
92  
93  void omap_dm_timer_stop(struct omap_dm_timer *timer)
94  {
95 -       u32 l;
96 +       unsigned long rate = 0;
97  
98 -       l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
99 -       if (l & OMAP_TIMER_CTRL_ST) {
100 -               l &= ~0x1;
101 -               omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
102  #ifdef CONFIG_ARCH_OMAP2PLUS
103 -               /* Readback to make sure write has completed */
104 -               omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
105 -                /*
106 -                 * Wait for functional clock period x 3.5 to make sure that
107 -                 * timer is stopped
108 -                 */
109 -               udelay(3500000 / clk_get_rate(timer->fclk) + 1);
110 +       rate = clk_get_rate(timer->fclk);
111  #endif
112 -       }
113 -       /* Ack possibly pending interrupt */
114 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
115 -                       OMAP_TIMER_INT_OVERFLOW);
117 +       __omap_dm_timer_stop(timer->io_base, timer->posted, rate);
118  }
119  EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
120  
121 @@ -451,22 +424,11 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
122  
123  int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
124  {
125 -       int ret = -EINVAL;
127         if (source < 0 || source >= 3)
128                 return -EINVAL;
129  
130 -       clk_disable(timer->fclk);
131 -       ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
132 -       clk_enable(timer->fclk);
134 -       /*
135 -        * When the functional clock disappears, too quick writes seem
136 -        * to cause an abort. XXX Is this still necessary?
137 -        */
138 -       __delay(300000);
140 -       return ret;
141 +       return __omap_dm_timer_set_source(timer->fclk,
142 +                                               dm_source_clocks[source]);
143  }
144  EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
145  
146 @@ -504,8 +466,7 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
147         }
148         l |= OMAP_TIMER_CTRL_ST;
149  
150 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
151 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
152 +       __omap_dm_timer_load_start(timer->io_base, l, load, timer->posted);
153  }
154  EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
155  
156 @@ -558,8 +519,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
157  void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
158                                   unsigned int value)
159  {
160 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
161 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
162 +       __omap_dm_timer_int_enable(timer->io_base, value);
163  }
164  EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
165  
166 @@ -575,17 +535,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
167  
168  void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
169  {
170 -       omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
171 +       __omap_dm_timer_write_status(timer->io_base, value);
172  }
173  EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
174  
175  unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
176  {
177 -       unsigned int l;
179 -       l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
181 -       return l;
182 +       return __omap_dm_timer_read_counter(timer->io_base, timer->posted);
183  }
184  EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
185  
186 diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
187 index 3203105..54664a7 100644
188 --- a/arch/arm/plat-omap/include/plat/dmtimer.h
189 +++ b/arch/arm/plat-omap/include/plat/dmtimer.h
190 @@ -32,6 +32,9 @@
191   * 675 Mass Ave, Cambridge, MA 02139, USA.
192   */
193  
194 +#include <linux/clk.h>
195 +#include <linux/delay.h>
197  #ifndef __ASM_ARCH_DMTIMER_H
198  #define __ASM_ARCH_DMTIMER_H
199  
200 @@ -218,4 +221,120 @@ struct omap_dm_timer {
201         unsigned posted:1;
202  };
203  
204 +void omap_dm_timer_prepare(struct omap_dm_timer *timer);
206 +static inline u32 __omap_dm_timer_read(void __iomem *base, u32 reg,
207 +                                               int posted)
208 +{
209 +       if (posted)
210 +               while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
211 +                               & (reg >> WPSHIFT))
212 +                       cpu_relax();
214 +       return __raw_readl(base + (reg & 0xff));
215 +}
217 +static inline void __omap_dm_timer_write(void __iomem *base, u32 reg, u32 val,
218 +                                               int posted)
219 +{
220 +       if (posted)
221 +               while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
222 +                               & (reg >> WPSHIFT))
223 +                       cpu_relax();
225 +       __raw_writel(val, base + (reg & 0xff));
226 +}
228 +/* Assumes the source clock has been set by caller */
229 +static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle,
230 +                                               int wakeup)
231 +{
232 +       u32 l;
234 +       l = __omap_dm_timer_read(base, OMAP_TIMER_OCP_CFG_REG, 0);
235 +       l |= 0x02 << 3;  /* Set to smart-idle mode */
236 +       l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
238 +       if (autoidle)
239 +               l |= 0x1 << 0;
241 +       if (wakeup)
242 +               l |= 1 << 2;
244 +       __omap_dm_timer_write(base, OMAP_TIMER_OCP_CFG_REG, l, 0);
246 +       /* Match hardware reset default of posted mode */
247 +       __omap_dm_timer_write(base, OMAP_TIMER_IF_CTRL_REG,
248 +                                       OMAP_TIMER_CTRL_POSTED, 0);
249 +}
251 +static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
252 +                                               struct clk *parent)
253 +{
254 +       int ret;
256 +       clk_disable(timer_fck);
257 +       ret = clk_set_parent(timer_fck, parent);
258 +       clk_enable(timer_fck);
260 +       /*
261 +        * When the functional clock disappears, too quick writes seem
262 +        * to cause an abort. XXX Is this still necessary?
263 +        */
264 +       __delay(300000);
266 +       return ret;
267 +}
269 +static inline void __omap_dm_timer_stop(void __iomem *base, int posted,
270 +                                               unsigned long rate)
271 +{
272 +       u32 l;
274 +       l = __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
275 +       if (l & OMAP_TIMER_CTRL_ST) {
276 +               l &= ~0x1;
277 +               __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, l, posted);
278 +#ifdef CONFIG_ARCH_OMAP2PLUS
279 +               /* Readback to make sure write has completed */
280 +               __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
281 +               /*
282 +                * Wait for functional clock period x 3.5 to make sure that
283 +                * timer is stopped
284 +                */
285 +               udelay(3500000 / rate + 1);
286 +#endif
287 +       }
289 +       /* Ack possibly pending interrupt */
290 +       __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG,
291 +                                       OMAP_TIMER_INT_OVERFLOW, 0);
292 +}
294 +static inline void __omap_dm_timer_load_start(void __iomem *base, u32 ctrl,
295 +                                               unsigned int load, int posted)
296 +{
297 +       __omap_dm_timer_write(base, OMAP_TIMER_COUNTER_REG, load, posted);
298 +       __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, ctrl, posted);
299 +}
301 +static inline void __omap_dm_timer_int_enable(void __iomem *base,
302 +                                               unsigned int value)
303 +{
304 +       __omap_dm_timer_write(base, OMAP_TIMER_INT_EN_REG, value, 0);
305 +       __omap_dm_timer_write(base, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
306 +}
308 +static inline unsigned int __omap_dm_timer_read_counter(void __iomem *base,
309 +                                                       int posted)
310 +{
311 +       return __omap_dm_timer_read(base, OMAP_TIMER_COUNTER_REG, posted);
312 +}
314 +static inline void __omap_dm_timer_write_status(void __iomem *base,
315 +                                               unsigned int value)
316 +{
317 +       __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG, value, 0);
318 +}
320  #endif /* __ASM_ARCH_DMTIMER_H */
321 -- 
322 1.6.6.1