1f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer/*
2f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer *  linux/arch/arm/plat-mxc/epit.c
3f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer *
4f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer *  Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
5f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer *
6f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * This program is free software; you can redistribute it and/or
7f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * modify it under the terms of the GNU General Public License
8f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * as published by the Free Software Foundation; either version 2
9f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * of the License, or (at your option) any later version.
10f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * This program is distributed in the hope that it will be useful,
11f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * but WITHOUT ANY WARRANTY; without even the implied warranty of
12f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * GNU General Public License for more details.
14f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer *
15f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * You should have received a copy of the GNU General Public License
16f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * along with this program; if not, write to the Free Software
17f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * MA 02110-1301, USA.
19f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer */
20f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
21f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR		0x00
22f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITSR		0x04
23f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITLR		0x08
24f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCMPR	0x0c
25f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCNR		0x10
26f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
27f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_EN			(1 << 0)
28f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_ENMOD			(1 << 1)
29f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_OCIEN			(1 << 2)
30f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_RLD			(1 << 3)
31f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
32f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_SWR			(1 << 16)
33f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_IOVW			(1 << 17)
34f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_DBGEN			(1 << 18)
35f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_WAITEN			(1 << 19)
36f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_RES			(1 << 20)
37f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_STOPEN			(1 << 21)
38f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_OM_DISCON		(0 << 22)
39f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_OM_TOGGLE		(1 << 22)
40f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_OM_CLEAR			(2 << 22)
41f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_OM_SET			(3 << 22)
42f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_CLKSRC_OFF		(0 << 24)
43f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
44f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_CLKSRC_REF_HIGH		(1 << 24)
45f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITCR_CLKSRC_REF_LOW		(3 << 24)
46f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
47f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#define EPITSR_OCIF			(1 << 0)
48f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
49f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#include <linux/interrupt.h>
50f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#include <linux/irq.h>
51f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#include <linux/clockchips.h>
52f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#include <linux/clk.h>
532cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer#include <linux/err.h>
54f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer#include <asm/mach/time.h>
55e3372474cfa0dc016f10ec47baddbd1ed0abecf3Shawn Guo
56e3372474cfa0dc016f10ec47baddbd1ed0abecf3Shawn Guo#include "common.h"
5750f2de61269bbe2f40bead1969a9594fa8599b93Shawn Guo#include "hardware.h"
58f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
59f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic struct clock_event_device clockevent_epit;
60f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
61f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
62f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic void __iomem *timer_base;
63f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
64f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic inline void epit_irq_disable(void)
65f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
66f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	u32 val;
67f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
68f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	val = __raw_readl(timer_base + EPITCR);
69f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	val &= ~EPITCR_OCIEN;
70f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	__raw_writel(val, timer_base + EPITCR);
71f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
72f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
73f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic inline void epit_irq_enable(void)
74f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
75f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	u32 val;
76f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
77f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	val = __raw_readl(timer_base + EPITCR);
78f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	val |= EPITCR_OCIEN;
79f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	__raw_writel(val, timer_base + EPITCR);
80f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
81f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
82f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic void epit_irq_acknowledge(void)
83f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
84f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	__raw_writel(EPITSR_OCIF, timer_base + EPITSR);
85f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
86f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
87f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic int __init epit_clocksource_init(struct clk *timer_clk)
88f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
89f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	unsigned int c = clk_get_rate(timer_clk);
90f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
91bfe45e0be88d8a2e408226d473bff60da4a97d1fRussell King	return clocksource_mmio_init(timer_base + EPITCNR, "epit", c, 200, 32,
92bfe45e0be88d8a2e408226d473bff60da4a97d1fRussell King			clocksource_mmio_readl_down);
93f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
94f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
95f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer/* clock event */
96f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
97f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic int epit_set_next_event(unsigned long evt,
98f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer			      struct clock_event_device *unused)
99f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
100f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	unsigned long tcmp;
101f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
102f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	tcmp = __raw_readl(timer_base + EPITCNR);
103f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
104f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	__raw_writel(tcmp - evt, timer_base + EPITCMPR);
105f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
106f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	return 0;
107f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
108f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
109f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic void epit_set_mode(enum clock_event_mode mode,
110f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer				struct clock_event_device *evt)
111f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
112f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	unsigned long flags;
113f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
114f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	/*
115f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 * The timer interrupt generation is disabled at least
116f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 * for enough time to call epit_set_next_event()
117f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 */
118f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	local_irq_save(flags);
119f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
120f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	/* Disable interrupt in GPT module */
121f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	epit_irq_disable();
122f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
123f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	if (mode != clockevent_mode) {
124f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		/* Set event time into far-far future */
125f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
126f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		/* Clear pending interrupt */
127f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		epit_irq_acknowledge();
128f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	}
129f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
130f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	/* Remember timer mode */
131f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	clockevent_mode = mode;
132f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	local_irq_restore(flags);
133f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
134f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	switch (mode) {
135f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	case CLOCK_EVT_MODE_PERIODIC:
136f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		printk(KERN_ERR "epit_set_mode: Periodic mode is not "
137f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer				"supported for i.MX EPIT\n");
138f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		break;
139f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	case CLOCK_EVT_MODE_ONESHOT:
140f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	/*
141f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 * Do not put overhead of interrupt enable/disable into
142f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 * epit_set_next_event(), the core has about 4 minutes
143f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 * to call epit_set_next_event() or shutdown clock after
144f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 * mode switching
145f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 */
146f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		local_irq_save(flags);
147f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		epit_irq_enable();
148f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		local_irq_restore(flags);
149f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		break;
150f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	case CLOCK_EVT_MODE_SHUTDOWN:
151f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	case CLOCK_EVT_MODE_UNUSED:
152f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	case CLOCK_EVT_MODE_RESUME:
153f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		/* Left event sources disabled, no more interrupts appear */
154f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer		break;
155f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	}
156f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
157f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
158f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer/*
159f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer * IRQ handler for the timer
160f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer */
161f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
162f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
163f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	struct clock_event_device *evt = &clockevent_epit;
164f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
165f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	epit_irq_acknowledge();
166f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
167f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	evt->event_handler(evt);
168f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
169f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	return IRQ_HANDLED;
170f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
171f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
172f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic struct irqaction epit_timer_irq = {
173f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	.name		= "i.MX EPIT Timer Tick",
1744c1dd3e5edc1619199b4a42618169ac3ac457cb5Michael Opdenacker	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
175f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	.handler	= epit_timer_interrupt,
176f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer};
177f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
178f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic struct clock_event_device clockevent_epit = {
179f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	.name		= "epit",
180f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	.features	= CLOCK_EVT_FEAT_ONESHOT,
181f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	.set_mode	= epit_set_mode,
182f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	.set_next_event	= epit_set_next_event,
183f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	.rating		= 200,
184f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer};
185f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
186f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauerstatic int __init epit_clockevent_init(struct clk *timer_clk)
187f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
188f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	clockevent_epit.cpumask = cpumask_of(0);
189838a2ae80a6ab52139fb1bf0a93ea8c5eff94488Shawn Guo	clockevents_config_and_register(&clockevent_epit,
190838a2ae80a6ab52139fb1bf0a93ea8c5eff94488Shawn Guo					clk_get_rate(timer_clk),
191838a2ae80a6ab52139fb1bf0a93ea8c5eff94488Shawn Guo					0x800, 0xfffffffe);
192f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
193f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	return 0;
194f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
195f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
1962cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauervoid __init epit_timer_init(void __iomem *base, int irq)
197f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer{
1982cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer	struct clk *timer_clk;
1992cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer
2002cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer	timer_clk = clk_get_sys("imx-epit.0", NULL);
2012cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer	if (IS_ERR(timer_clk)) {
2022cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer		pr_err("i.MX epit: unable to get clk\n");
2032cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer		return;
2042cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer	}
2052cfb45188a997ba4c3348e98a999b36663a4646fSascha Hauer
2068f33eed0844d41f2cc3e0d38f866041590c0fbe1Richard Zhao	clk_prepare_enable(timer_clk);
207f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
208f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	timer_base = base;
209f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
210f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	/*
211f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 * Initialise to a known state (all timers off, and timing reset)
212f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	 */
213f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	__raw_writel(0x0, timer_base + EPITCR);
214f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
215f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	__raw_writel(0xffffffff, timer_base + EPITLR);
216f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	__raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
217f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer			timer_base + EPITCR);
218f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
219f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	/* init and register the timer to the framework */
220f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	epit_clocksource_init(timer_clk);
221f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	epit_clockevent_init(timer_clk);
222f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer
223f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	/* Make irqs happen */
224f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer	setup_irq(irq, &epit_timer_irq);
225f2b8901d3efe5e1603c8f6a102b2d5c851c108c6Sascha Hauer}
226