xref: /linux/drivers/clocksource/timer-ti-dm.c (revision bd628c1bed7902ec1f24ba0fe70758949146abbe)
1 /*
2  * linux/arch/arm/plat-omap/dmtimer.c
3  *
4  * OMAP Dual-Mode Timers
5  *
6  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
7  * Tarun Kanti DebBarma <tarun.kanti@ti.com>
8  * Thara Gopinath <thara@ti.com>
9  *
10  * dmtimer adaptation to platform_driver.
11  *
12  * Copyright (C) 2005 Nokia Corporation
13  * OMAP2 support by Juha Yrjola
14  * API improvements and OMAP2 clock framework support by Timo Teras
15  *
16  * Copyright (C) 2009 Texas Instruments
17  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
18  *
19  * This program is free software; you can redistribute it and/or modify it
20  * under the terms of the GNU General Public License as published by the
21  * Free Software Foundation; either version 2 of the License, or (at your
22  * option) any later version.
23  *
24  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
25  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
27  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * You should have received a copy of the  GNU General Public License along
34  * with this program; if not, write  to the Free Software Foundation, Inc.,
35  * 675 Mass Ave, Cambridge, MA 02139, USA.
36  */
37 
38 #include <linux/clk.h>
39 #include <linux/clk-provider.h>
40 #include <linux/module.h>
41 #include <linux/io.h>
42 #include <linux/device.h>
43 #include <linux/err.h>
44 #include <linux/pm_runtime.h>
45 #include <linux/of.h>
46 #include <linux/of_device.h>
47 #include <linux/platform_device.h>
48 #include <linux/platform_data/dmtimer-omap.h>
49 
50 #include <clocksource/timer-ti-dm.h>
51 
52 static u32 omap_reserved_systimers;
53 static LIST_HEAD(omap_timer_list);
54 static DEFINE_SPINLOCK(dm_timer_lock);
55 
56 enum {
57 	REQUEST_ANY = 0,
58 	REQUEST_BY_ID,
59 	REQUEST_BY_CAP,
60 	REQUEST_BY_NODE,
61 };
62 
63 /**
64  * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
65  * @timer:      timer pointer over which read operation to perform
66  * @reg:        lowest byte holds the register offset
67  *
68  * The posted mode bit is encoded in reg. Note that in posted mode write
69  * pending bit must be checked. Otherwise a read of a non completed write
70  * will produce an error.
71  */
72 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
73 {
74 	WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
75 	return __omap_dm_timer_read(timer, reg, timer->posted);
76 }
77 
78 /**
79  * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
80  * @timer:      timer pointer over which write operation is to perform
81  * @reg:        lowest byte holds the register offset
82  * @value:      data to write into the register
83  *
84  * The posted mode bit is encoded in reg. Note that in posted mode the write
85  * pending bit must be checked. Otherwise a write on a register which has a
86  * pending write will be lost.
87  */
88 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
89 						u32 value)
90 {
91 	WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
92 	__omap_dm_timer_write(timer, reg, value, timer->posted);
93 }
94 
95 static void omap_timer_restore_context(struct omap_dm_timer *timer)
96 {
97 	omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
98 				timer->context.twer);
99 	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
100 				timer->context.tcrr);
101 	omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
102 				timer->context.tldr);
103 	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
104 				timer->context.tmar);
105 	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
106 				timer->context.tsicr);
107 	writel_relaxed(timer->context.tier, timer->irq_ena);
108 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
109 				timer->context.tclr);
110 }
111 
112 static int omap_dm_timer_reset(struct omap_dm_timer *timer)
113 {
114 	u32 l, timeout = 100000;
115 
116 	if (timer->revision != 1)
117 		return -EINVAL;
118 
119 	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
120 
121 	do {
122 		l = __omap_dm_timer_read(timer,
123 					 OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
124 	} while (!l && timeout--);
125 
126 	if (!timeout) {
127 		dev_err(&timer->pdev->dev, "Timer failed to reset\n");
128 		return -ETIMEDOUT;
129 	}
130 
131 	/* Configure timer for smart-idle mode */
132 	l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
133 	l |= 0x2 << 0x3;
134 	__omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
135 
136 	timer->posted = 0;
137 
138 	return 0;
139 }
140 
141 static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
142 {
143 	int ret;
144 	struct clk *parent;
145 
146 	/*
147 	 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
148 	 * do not call clk_get() for these devices.
149 	 */
150 	if (!timer->fclk)
151 		return -ENODEV;
152 
153 	parent = clk_get(&timer->pdev->dev, NULL);
154 	if (IS_ERR(parent))
155 		return -ENODEV;
156 
157 	ret = clk_set_parent(timer->fclk, parent);
158 	if (ret < 0)
159 		pr_err("%s: failed to set parent\n", __func__);
160 
161 	clk_put(parent);
162 
163 	return ret;
164 }
165 
166 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
167 {
168 	int ret;
169 	const char *parent_name;
170 	struct clk *parent;
171 	struct dmtimer_platform_data *pdata;
172 
173 	if (unlikely(!timer) || IS_ERR(timer->fclk))
174 		return -EINVAL;
175 
176 	switch (source) {
177 	case OMAP_TIMER_SRC_SYS_CLK:
178 		parent_name = "timer_sys_ck";
179 		break;
180 	case OMAP_TIMER_SRC_32_KHZ:
181 		parent_name = "timer_32k_ck";
182 		break;
183 	case OMAP_TIMER_SRC_EXT_CLK:
184 		parent_name = "timer_ext_ck";
185 		break;
186 	default:
187 		return -EINVAL;
188 	}
189 
190 	pdata = timer->pdev->dev.platform_data;
191 
192 	/*
193 	 * FIXME: Used for OMAP1 devices only because they do not currently
194 	 * use the clock framework to set the parent clock. To be removed
195 	 * once OMAP1 migrated to using clock framework for dmtimers
196 	 */
197 	if (pdata && pdata->set_timer_src)
198 		return pdata->set_timer_src(timer->pdev, source);
199 
200 #if defined(CONFIG_COMMON_CLK)
201 	/* Check if the clock has configurable parents */
202 	if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
203 		return 0;
204 #endif
205 
206 	parent = clk_get(&timer->pdev->dev, parent_name);
207 	if (IS_ERR(parent)) {
208 		pr_err("%s: %s not found\n", __func__, parent_name);
209 		return -EINVAL;
210 	}
211 
212 	ret = clk_set_parent(timer->fclk, parent);
213 	if (ret < 0)
214 		pr_err("%s: failed to set %s as parent\n", __func__,
215 			parent_name);
216 
217 	clk_put(parent);
218 
219 	return ret;
220 }
221 
222 static void omap_dm_timer_enable(struct omap_dm_timer *timer)
223 {
224 	int c;
225 
226 	pm_runtime_get_sync(&timer->pdev->dev);
227 
228 	if (!(timer->capability & OMAP_TIMER_ALWON)) {
229 		if (timer->get_context_loss_count) {
230 			c = timer->get_context_loss_count(&timer->pdev->dev);
231 			if (c != timer->ctx_loss_count) {
232 				omap_timer_restore_context(timer);
233 				timer->ctx_loss_count = c;
234 			}
235 		} else {
236 			omap_timer_restore_context(timer);
237 		}
238 	}
239 }
240 
241 static void omap_dm_timer_disable(struct omap_dm_timer *timer)
242 {
243 	pm_runtime_put_sync(&timer->pdev->dev);
244 }
245 
246 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
247 {
248 	int rc;
249 
250 	/*
251 	 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
252 	 * do not call clk_get() for these devices.
253 	 */
254 	if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
255 		timer->fclk = clk_get(&timer->pdev->dev, "fck");
256 		if (WARN_ON_ONCE(IS_ERR(timer->fclk))) {
257 			dev_err(&timer->pdev->dev, ": No fclk handle.\n");
258 			return -EINVAL;
259 		}
260 	}
261 
262 	omap_dm_timer_enable(timer);
263 
264 	if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
265 		rc = omap_dm_timer_reset(timer);
266 		if (rc) {
267 			omap_dm_timer_disable(timer);
268 			return rc;
269 		}
270 	}
271 
272 	__omap_dm_timer_enable_posted(timer);
273 	omap_dm_timer_disable(timer);
274 
275 	rc = omap_dm_timer_of_set_source(timer);
276 	if (rc == -ENODEV)
277 		return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
278 
279 	return rc;
280 }
281 
282 static inline u32 omap_dm_timer_reserved_systimer(int id)
283 {
284 	return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
285 }
286 
287 int omap_dm_timer_reserve_systimer(int id)
288 {
289 	if (omap_dm_timer_reserved_systimer(id))
290 		return -ENODEV;
291 
292 	omap_reserved_systimers |= (1 << (id - 1));
293 
294 	return 0;
295 }
296 
297 static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
298 {
299 	struct omap_dm_timer *timer = NULL, *t;
300 	struct device_node *np = NULL;
301 	unsigned long flags;
302 	u32 cap = 0;
303 	int id = 0;
304 
305 	switch (req_type) {
306 	case REQUEST_BY_ID:
307 		id = *(int *)data;
308 		break;
309 	case REQUEST_BY_CAP:
310 		cap = *(u32 *)data;
311 		break;
312 	case REQUEST_BY_NODE:
313 		np = (struct device_node *)data;
314 		break;
315 	default:
316 		/* REQUEST_ANY */
317 		break;
318 	}
319 
320 	spin_lock_irqsave(&dm_timer_lock, flags);
321 	list_for_each_entry(t, &omap_timer_list, node) {
322 		if (t->reserved)
323 			continue;
324 
325 		switch (req_type) {
326 		case REQUEST_BY_ID:
327 			if (id == t->pdev->id) {
328 				timer = t;
329 				timer->reserved = 1;
330 				goto found;
331 			}
332 			break;
333 		case REQUEST_BY_CAP:
334 			if (cap == (t->capability & cap)) {
335 				/*
336 				 * If timer is not NULL, we have already found
337 				 * one timer. But it was not an exact match
338 				 * because it had more capabilities than what
339 				 * was required. Therefore, unreserve the last
340 				 * timer found and see if this one is a better
341 				 * match.
342 				 */
343 				if (timer)
344 					timer->reserved = 0;
345 				timer = t;
346 				timer->reserved = 1;
347 
348 				/* Exit loop early if we find an exact match */
349 				if (t->capability == cap)
350 					goto found;
351 			}
352 			break;
353 		case REQUEST_BY_NODE:
354 			if (np == t->pdev->dev.of_node) {
355 				timer = t;
356 				timer->reserved = 1;
357 				goto found;
358 			}
359 			break;
360 		default:
361 			/* REQUEST_ANY */
362 			timer = t;
363 			timer->reserved = 1;
364 			goto found;
365 		}
366 	}
367 found:
368 	spin_unlock_irqrestore(&dm_timer_lock, flags);
369 
370 	if (timer && omap_dm_timer_prepare(timer)) {
371 		timer->reserved = 0;
372 		timer = NULL;
373 	}
374 
375 	if (!timer)
376 		pr_debug("%s: timer request failed!\n", __func__);
377 
378 	return timer;
379 }
380 
381 static struct omap_dm_timer *omap_dm_timer_request(void)
382 {
383 	return _omap_dm_timer_request(REQUEST_ANY, NULL);
384 }
385 
386 static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
387 {
388 	/* Requesting timer by ID is not supported when device tree is used */
389 	if (of_have_populated_dt()) {
390 		pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
391 			__func__);
392 		return NULL;
393 	}
394 
395 	return _omap_dm_timer_request(REQUEST_BY_ID, &id);
396 }
397 
398 /**
399  * omap_dm_timer_request_by_cap - Request a timer by capability
400  * @cap:	Bit mask of capabilities to match
401  *
402  * Find a timer based upon capabilities bit mask. Callers of this function
403  * should use the definitions found in the plat/dmtimer.h file under the
404  * comment "timer capabilities used in hwmod database". Returns pointer to
405  * timer handle on success and a NULL pointer on failure.
406  */
407 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
408 {
409 	return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
410 }
411 
412 /**
413  * omap_dm_timer_request_by_node - Request a timer by device-tree node
414  * @np:		Pointer to device-tree timer node
415  *
416  * Request a timer based upon a device node pointer. Returns pointer to
417  * timer handle on success and a NULL pointer on failure.
418  */
419 static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
420 {
421 	if (!np)
422 		return NULL;
423 
424 	return _omap_dm_timer_request(REQUEST_BY_NODE, np);
425 }
426 
427 static int omap_dm_timer_free(struct omap_dm_timer *timer)
428 {
429 	if (unlikely(!timer))
430 		return -EINVAL;
431 
432 	clk_put(timer->fclk);
433 
434 	WARN_ON(!timer->reserved);
435 	timer->reserved = 0;
436 	return 0;
437 }
438 
439 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
440 {
441 	if (timer)
442 		return timer->irq;
443 	return -EINVAL;
444 }
445 
446 #if defined(CONFIG_ARCH_OMAP1)
447 #include <mach/hardware.h>
448 
449 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
450 {
451 	return NULL;
452 }
453 
454 /**
455  * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
456  * @inputmask: current value of idlect mask
457  */
458 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
459 {
460 	int i = 0;
461 	struct omap_dm_timer *timer = NULL;
462 	unsigned long flags;
463 
464 	/* If ARMXOR cannot be idled this function call is unnecessary */
465 	if (!(inputmask & (1 << 1)))
466 		return inputmask;
467 
468 	/* If any active timer is using ARMXOR return modified mask */
469 	spin_lock_irqsave(&dm_timer_lock, flags);
470 	list_for_each_entry(timer, &omap_timer_list, node) {
471 		u32 l;
472 
473 		l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
474 		if (l & OMAP_TIMER_CTRL_ST) {
475 			if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
476 				inputmask &= ~(1 << 1);
477 			else
478 				inputmask &= ~(1 << 2);
479 		}
480 		i++;
481 	}
482 	spin_unlock_irqrestore(&dm_timer_lock, flags);
483 
484 	return inputmask;
485 }
486 
487 #else
488 
489 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
490 {
491 	if (timer && !IS_ERR(timer->fclk))
492 		return timer->fclk;
493 	return NULL;
494 }
495 
496 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
497 {
498 	BUG();
499 
500 	return 0;
501 }
502 
503 #endif
504 
505 int omap_dm_timer_trigger(struct omap_dm_timer *timer)
506 {
507 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
508 		pr_err("%s: timer not available or enabled.\n", __func__);
509 		return -EINVAL;
510 	}
511 
512 	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
513 	return 0;
514 }
515 
516 static int omap_dm_timer_start(struct omap_dm_timer *timer)
517 {
518 	u32 l;
519 
520 	if (unlikely(!timer))
521 		return -EINVAL;
522 
523 	omap_dm_timer_enable(timer);
524 
525 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
526 	if (!(l & OMAP_TIMER_CTRL_ST)) {
527 		l |= OMAP_TIMER_CTRL_ST;
528 		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
529 	}
530 
531 	/* Save the context */
532 	timer->context.tclr = l;
533 	return 0;
534 }
535 
536 static int omap_dm_timer_stop(struct omap_dm_timer *timer)
537 {
538 	unsigned long rate = 0;
539 
540 	if (unlikely(!timer))
541 		return -EINVAL;
542 
543 	if (!(timer->capability & OMAP_TIMER_NEEDS_RESET))
544 		rate = clk_get_rate(timer->fclk);
545 
546 	__omap_dm_timer_stop(timer, timer->posted, rate);
547 
548 	/*
549 	 * Since the register values are computed and written within
550 	 * __omap_dm_timer_stop, we need to use read to retrieve the
551 	 * context.
552 	 */
553 	timer->context.tclr =
554 			omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
555 	omap_dm_timer_disable(timer);
556 	return 0;
557 }
558 
559 static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
560 				  unsigned int load)
561 {
562 	u32 l;
563 
564 	if (unlikely(!timer))
565 		return -EINVAL;
566 
567 	omap_dm_timer_enable(timer);
568 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
569 	if (autoreload)
570 		l |= OMAP_TIMER_CTRL_AR;
571 	else
572 		l &= ~OMAP_TIMER_CTRL_AR;
573 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
574 	omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
575 
576 	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
577 	/* Save the context */
578 	timer->context.tclr = l;
579 	timer->context.tldr = load;
580 	omap_dm_timer_disable(timer);
581 	return 0;
582 }
583 
584 /* Optimized set_load which removes costly spin wait in timer_start */
585 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
586                             unsigned int load)
587 {
588 	u32 l;
589 
590 	if (unlikely(!timer))
591 		return -EINVAL;
592 
593 	omap_dm_timer_enable(timer);
594 
595 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
596 	if (autoreload) {
597 		l |= OMAP_TIMER_CTRL_AR;
598 		omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
599 	} else {
600 		l &= ~OMAP_TIMER_CTRL_AR;
601 	}
602 	l |= OMAP_TIMER_CTRL_ST;
603 
604 	__omap_dm_timer_load_start(timer, l, load, timer->posted);
605 
606 	/* Save the context */
607 	timer->context.tclr = l;
608 	timer->context.tldr = load;
609 	timer->context.tcrr = load;
610 	return 0;
611 }
612 static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
613 				   unsigned int match)
614 {
615 	u32 l;
616 
617 	if (unlikely(!timer))
618 		return -EINVAL;
619 
620 	omap_dm_timer_enable(timer);
621 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
622 	if (enable)
623 		l |= OMAP_TIMER_CTRL_CE;
624 	else
625 		l &= ~OMAP_TIMER_CTRL_CE;
626 	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
627 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
628 
629 	/* Save the context */
630 	timer->context.tclr = l;
631 	timer->context.tmar = match;
632 	omap_dm_timer_disable(timer);
633 	return 0;
634 }
635 
636 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
637 				 int toggle, int trigger)
638 {
639 	u32 l;
640 
641 	if (unlikely(!timer))
642 		return -EINVAL;
643 
644 	omap_dm_timer_enable(timer);
645 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
646 	l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
647 	       OMAP_TIMER_CTRL_PT | (0x03 << 10));
648 	if (def_on)
649 		l |= OMAP_TIMER_CTRL_SCPWM;
650 	if (toggle)
651 		l |= OMAP_TIMER_CTRL_PT;
652 	l |= trigger << 10;
653 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
654 
655 	/* Save the context */
656 	timer->context.tclr = l;
657 	omap_dm_timer_disable(timer);
658 	return 0;
659 }
660 
661 static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
662 					int prescaler)
663 {
664 	u32 l;
665 
666 	if (unlikely(!timer) || prescaler < -1 || prescaler > 7)
667 		return -EINVAL;
668 
669 	omap_dm_timer_enable(timer);
670 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
671 	l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
672 	if (prescaler >= 0) {
673 		l |= OMAP_TIMER_CTRL_PRE;
674 		l |= prescaler << 2;
675 	}
676 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
677 
678 	/* Save the context */
679 	timer->context.tclr = l;
680 	omap_dm_timer_disable(timer);
681 	return 0;
682 }
683 
684 static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
685 					unsigned int value)
686 {
687 	if (unlikely(!timer))
688 		return -EINVAL;
689 
690 	omap_dm_timer_enable(timer);
691 	__omap_dm_timer_int_enable(timer, value);
692 
693 	/* Save the context */
694 	timer->context.tier = value;
695 	timer->context.twer = value;
696 	omap_dm_timer_disable(timer);
697 	return 0;
698 }
699 
700 /**
701  * omap_dm_timer_set_int_disable - disable timer interrupts
702  * @timer:	pointer to timer handle
703  * @mask:	bit mask of interrupts to be disabled
704  *
705  * Disables the specified timer interrupts for a timer.
706  */
707 static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
708 {
709 	u32 l = mask;
710 
711 	if (unlikely(!timer))
712 		return -EINVAL;
713 
714 	omap_dm_timer_enable(timer);
715 
716 	if (timer->revision == 1)
717 		l = readl_relaxed(timer->irq_ena) & ~mask;
718 
719 	writel_relaxed(l, timer->irq_dis);
720 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
721 	omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
722 
723 	/* Save the context */
724 	timer->context.tier &= ~mask;
725 	timer->context.twer &= ~mask;
726 	omap_dm_timer_disable(timer);
727 	return 0;
728 }
729 
730 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
731 {
732 	unsigned int l;
733 
734 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
735 		pr_err("%s: timer not available or enabled.\n", __func__);
736 		return 0;
737 	}
738 
739 	l = readl_relaxed(timer->irq_stat);
740 
741 	return l;
742 }
743 
744 static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
745 {
746 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
747 		return -EINVAL;
748 
749 	__omap_dm_timer_write_status(timer, value);
750 
751 	return 0;
752 }
753 
754 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
755 {
756 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
757 		pr_err("%s: timer not iavailable or enabled.\n", __func__);
758 		return 0;
759 	}
760 
761 	return __omap_dm_timer_read_counter(timer, timer->posted);
762 }
763 
764 static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
765 {
766 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
767 		pr_err("%s: timer not available or enabled.\n", __func__);
768 		return -EINVAL;
769 	}
770 
771 	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
772 
773 	/* Save the context */
774 	timer->context.tcrr = value;
775 	return 0;
776 }
777 
778 int omap_dm_timers_active(void)
779 {
780 	struct omap_dm_timer *timer;
781 
782 	list_for_each_entry(timer, &omap_timer_list, node) {
783 		if (!timer->reserved)
784 			continue;
785 
786 		if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
787 		    OMAP_TIMER_CTRL_ST) {
788 			return 1;
789 		}
790 	}
791 	return 0;
792 }
793 
794 static const struct of_device_id omap_timer_match[];
795 
796 /**
797  * omap_dm_timer_probe - probe function called for every registered device
798  * @pdev:	pointer to current timer platform device
799  *
800  * Called by driver framework at the end of device registration for all
801  * timer devices.
802  */
803 static int omap_dm_timer_probe(struct platform_device *pdev)
804 {
805 	unsigned long flags;
806 	struct omap_dm_timer *timer;
807 	struct resource *mem, *irq;
808 	struct device *dev = &pdev->dev;
809 	const struct dmtimer_platform_data *pdata;
810 	int ret;
811 
812 	pdata = of_device_get_match_data(dev);
813 	if (!pdata)
814 		pdata = dev_get_platdata(dev);
815 	else
816 		dev->platform_data = (void *)pdata;
817 
818 	if (!pdata) {
819 		dev_err(dev, "%s: no platform data.\n", __func__);
820 		return -ENODEV;
821 	}
822 
823 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
824 	if (unlikely(!irq)) {
825 		dev_err(dev, "%s: no IRQ resource.\n", __func__);
826 		return -ENODEV;
827 	}
828 
829 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
830 	if (unlikely(!mem)) {
831 		dev_err(dev, "%s: no memory resource.\n", __func__);
832 		return -ENODEV;
833 	}
834 
835 	timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
836 	if (!timer)
837 		return  -ENOMEM;
838 
839 	timer->fclk = ERR_PTR(-ENODEV);
840 	timer->io_base = devm_ioremap_resource(dev, mem);
841 	if (IS_ERR(timer->io_base))
842 		return PTR_ERR(timer->io_base);
843 
844 	if (dev->of_node) {
845 		if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
846 			timer->capability |= OMAP_TIMER_ALWON;
847 		if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
848 			timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
849 		if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
850 			timer->capability |= OMAP_TIMER_HAS_PWM;
851 		if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
852 			timer->capability |= OMAP_TIMER_SECURE;
853 	} else {
854 		timer->id = pdev->id;
855 		timer->capability = pdata->timer_capability;
856 		timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
857 		timer->get_context_loss_count = pdata->get_context_loss_count;
858 	}
859 
860 	if (pdata)
861 		timer->errata = pdata->timer_errata;
862 
863 	timer->irq = irq->start;
864 	timer->pdev = pdev;
865 
866 	pm_runtime_enable(dev);
867 	pm_runtime_irq_safe(dev);
868 
869 	if (!timer->reserved) {
870 		ret = pm_runtime_get_sync(dev);
871 		if (ret < 0) {
872 			dev_err(dev, "%s: pm_runtime_get_sync failed!\n",
873 				__func__);
874 			goto err_get_sync;
875 		}
876 		__omap_dm_timer_init_regs(timer);
877 		pm_runtime_put(dev);
878 	}
879 
880 	/* add the timer element to the list */
881 	spin_lock_irqsave(&dm_timer_lock, flags);
882 	list_add_tail(&timer->node, &omap_timer_list);
883 	spin_unlock_irqrestore(&dm_timer_lock, flags);
884 
885 	dev_dbg(dev, "Device Probed.\n");
886 
887 	return 0;
888 
889 err_get_sync:
890 	pm_runtime_put_noidle(dev);
891 	pm_runtime_disable(dev);
892 	return ret;
893 }
894 
895 /**
896  * omap_dm_timer_remove - cleanup a registered timer device
897  * @pdev:	pointer to current timer platform device
898  *
899  * Called by driver framework whenever a timer device is unregistered.
900  * In addition to freeing platform resources it also deletes the timer
901  * entry from the local list.
902  */
903 static int omap_dm_timer_remove(struct platform_device *pdev)
904 {
905 	struct omap_dm_timer *timer;
906 	unsigned long flags;
907 	int ret = -EINVAL;
908 
909 	spin_lock_irqsave(&dm_timer_lock, flags);
910 	list_for_each_entry(timer, &omap_timer_list, node)
911 		if (!strcmp(dev_name(&timer->pdev->dev),
912 			    dev_name(&pdev->dev))) {
913 			list_del(&timer->node);
914 			ret = 0;
915 			break;
916 		}
917 	spin_unlock_irqrestore(&dm_timer_lock, flags);
918 
919 	pm_runtime_disable(&pdev->dev);
920 
921 	return ret;
922 }
923 
924 const static struct omap_dm_timer_ops dmtimer_ops = {
925 	.request_by_node = omap_dm_timer_request_by_node,
926 	.request_specific = omap_dm_timer_request_specific,
927 	.request = omap_dm_timer_request,
928 	.set_source = omap_dm_timer_set_source,
929 	.get_irq = omap_dm_timer_get_irq,
930 	.set_int_enable = omap_dm_timer_set_int_enable,
931 	.set_int_disable = omap_dm_timer_set_int_disable,
932 	.free = omap_dm_timer_free,
933 	.enable = omap_dm_timer_enable,
934 	.disable = omap_dm_timer_disable,
935 	.get_fclk = omap_dm_timer_get_fclk,
936 	.start = omap_dm_timer_start,
937 	.stop = omap_dm_timer_stop,
938 	.set_load = omap_dm_timer_set_load,
939 	.set_match = omap_dm_timer_set_match,
940 	.set_pwm = omap_dm_timer_set_pwm,
941 	.set_prescaler = omap_dm_timer_set_prescaler,
942 	.read_counter = omap_dm_timer_read_counter,
943 	.write_counter = omap_dm_timer_write_counter,
944 	.read_status = omap_dm_timer_read_status,
945 	.write_status = omap_dm_timer_write_status,
946 };
947 
948 static const struct dmtimer_platform_data omap3plus_pdata = {
949 	.timer_errata = OMAP_TIMER_ERRATA_I103_I767,
950 	.timer_ops = &dmtimer_ops,
951 };
952 
953 static const struct of_device_id omap_timer_match[] = {
954 	{
955 		.compatible = "ti,omap2420-timer",
956 	},
957 	{
958 		.compatible = "ti,omap3430-timer",
959 		.data = &omap3plus_pdata,
960 	},
961 	{
962 		.compatible = "ti,omap4430-timer",
963 		.data = &omap3plus_pdata,
964 	},
965 	{
966 		.compatible = "ti,omap5430-timer",
967 		.data = &omap3plus_pdata,
968 	},
969 	{
970 		.compatible = "ti,am335x-timer",
971 		.data = &omap3plus_pdata,
972 	},
973 	{
974 		.compatible = "ti,am335x-timer-1ms",
975 		.data = &omap3plus_pdata,
976 	},
977 	{
978 		.compatible = "ti,dm816-timer",
979 		.data = &omap3plus_pdata,
980 	},
981 	{},
982 };
983 MODULE_DEVICE_TABLE(of, omap_timer_match);
984 
985 static struct platform_driver omap_dm_timer_driver = {
986 	.probe  = omap_dm_timer_probe,
987 	.remove = omap_dm_timer_remove,
988 	.driver = {
989 		.name   = "omap_timer",
990 		.of_match_table = of_match_ptr(omap_timer_match),
991 	},
992 };
993 
994 module_platform_driver(omap_dm_timer_driver);
995 
996 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
997 MODULE_LICENSE("GPL");
998 MODULE_ALIAS("platform:" DRIVER_NAME);
999 MODULE_AUTHOR("Texas Instruments Inc");
1000