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