Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * arch/arm/plat-orion/time.c
0003  *
0004  * Marvell Orion SoC timer handling.
0005  *
0006  * This file is licensed under the terms of the GNU General Public
0007  * License version 2.  This program is licensed "as is" without any
0008  * warranty of any kind, whether express or implied.
0009  *
0010  * Timer 0 is used as free-running clocksource, while timer 1 is
0011  * used as clock_event_device.
0012  */
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/timer.h>
0016 #include <linux/clockchips.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/irq.h>
0019 #include <linux/sched_clock.h>
0020 #include <plat/time.h>
0021 #include <asm/delay.h>
0022 
0023 /*
0024  * MBus bridge block registers.
0025  */
0026 #define BRIDGE_CAUSE_OFF    0x0110
0027 #define BRIDGE_MASK_OFF     0x0114
0028 #define  BRIDGE_INT_TIMER0   0x0002
0029 #define  BRIDGE_INT_TIMER1   0x0004
0030 
0031 
0032 /*
0033  * Timer block registers.
0034  */
0035 #define TIMER_CTRL_OFF      0x0000
0036 #define  TIMER0_EN       0x0001
0037 #define  TIMER0_RELOAD_EN    0x0002
0038 #define  TIMER1_EN       0x0004
0039 #define  TIMER1_RELOAD_EN    0x0008
0040 #define TIMER0_RELOAD_OFF   0x0010
0041 #define TIMER0_VAL_OFF      0x0014
0042 #define TIMER1_RELOAD_OFF   0x0018
0043 #define TIMER1_VAL_OFF      0x001c
0044 
0045 
0046 /*
0047  * SoC-specific data.
0048  */
0049 static void __iomem *bridge_base;
0050 static u32 bridge_timer1_clr_mask;
0051 static void __iomem *timer_base;
0052 
0053 
0054 /*
0055  * Number of timer ticks per jiffy.
0056  */
0057 static u32 ticks_per_jiffy;
0058 
0059 
0060 /*
0061  * Orion's sched_clock implementation. It has a resolution of
0062  * at least 7.5ns (133MHz TCLK).
0063  */
0064 
0065 static u64 notrace orion_read_sched_clock(void)
0066 {
0067     return ~readl(timer_base + TIMER0_VAL_OFF);
0068 }
0069 
0070 /*
0071  * Clockevent handling.
0072  */
0073 static int
0074 orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
0075 {
0076     unsigned long flags;
0077     u32 u;
0078 
0079     if (delta == 0)
0080         return -ETIME;
0081 
0082     local_irq_save(flags);
0083 
0084     /*
0085      * Clear and enable clockevent timer interrupt.
0086      */
0087     writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
0088 
0089     u = readl(bridge_base + BRIDGE_MASK_OFF);
0090     u |= BRIDGE_INT_TIMER1;
0091     writel(u, bridge_base + BRIDGE_MASK_OFF);
0092 
0093     /*
0094      * Setup new clockevent timer value.
0095      */
0096     writel(delta, timer_base + TIMER1_VAL_OFF);
0097 
0098     /*
0099      * Enable the timer.
0100      */
0101     u = readl(timer_base + TIMER_CTRL_OFF);
0102     u = (u & ~TIMER1_RELOAD_EN) | TIMER1_EN;
0103     writel(u, timer_base + TIMER_CTRL_OFF);
0104 
0105     local_irq_restore(flags);
0106 
0107     return 0;
0108 }
0109 
0110 static int orion_clkevt_shutdown(struct clock_event_device *evt)
0111 {
0112     unsigned long flags;
0113     u32 u;
0114 
0115     local_irq_save(flags);
0116 
0117     /* Disable timer */
0118     u = readl(timer_base + TIMER_CTRL_OFF);
0119     writel(u & ~TIMER1_EN, timer_base + TIMER_CTRL_OFF);
0120 
0121     /* Disable timer interrupt */
0122     u = readl(bridge_base + BRIDGE_MASK_OFF);
0123     writel(u & ~BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
0124 
0125     /* ACK pending timer interrupt */
0126     writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
0127 
0128     local_irq_restore(flags);
0129 
0130     return 0;
0131 }
0132 
0133 static int orion_clkevt_set_periodic(struct clock_event_device *evt)
0134 {
0135     unsigned long flags;
0136     u32 u;
0137 
0138     local_irq_save(flags);
0139 
0140     /* Setup timer to fire at 1/HZ intervals */
0141     writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD_OFF);
0142     writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL_OFF);
0143 
0144     /* Enable timer interrupt */
0145     u = readl(bridge_base + BRIDGE_MASK_OFF);
0146     writel(u | BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
0147 
0148     /* Enable timer */
0149     u = readl(timer_base + TIMER_CTRL_OFF);
0150     writel(u | TIMER1_EN | TIMER1_RELOAD_EN, timer_base + TIMER_CTRL_OFF);
0151 
0152     local_irq_restore(flags);
0153 
0154     return 0;
0155 }
0156 
0157 static struct clock_event_device orion_clkevt = {
0158     .name           = "orion_tick",
0159     .features       = CLOCK_EVT_FEAT_ONESHOT |
0160                   CLOCK_EVT_FEAT_PERIODIC,
0161     .rating         = 300,
0162     .set_next_event     = orion_clkevt_next_event,
0163     .set_state_shutdown = orion_clkevt_shutdown,
0164     .set_state_periodic = orion_clkevt_set_periodic,
0165     .set_state_oneshot  = orion_clkevt_shutdown,
0166     .tick_resume        = orion_clkevt_shutdown,
0167 };
0168 
0169 static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
0170 {
0171     /*
0172      * ACK timer interrupt and call event handler.
0173      */
0174     writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
0175     orion_clkevt.event_handler(&orion_clkevt);
0176 
0177     return IRQ_HANDLED;
0178 }
0179 
0180 void __init
0181 orion_time_set_base(void __iomem *_timer_base)
0182 {
0183     timer_base = _timer_base;
0184 }
0185 
0186 static unsigned long orion_delay_timer_read(void)
0187 {
0188     return ~readl(timer_base + TIMER0_VAL_OFF);
0189 }
0190 
0191 static struct delay_timer orion_delay_timer = {
0192     .read_current_timer = orion_delay_timer_read,
0193 };
0194 
0195 void __init
0196 orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
0197         unsigned int irq, unsigned int tclk)
0198 {
0199     u32 u;
0200 
0201     /*
0202      * Set SoC-specific data.
0203      */
0204     bridge_base = _bridge_base;
0205     bridge_timer1_clr_mask = _bridge_timer1_clr_mask;
0206 
0207     ticks_per_jiffy = (tclk + HZ/2) / HZ;
0208 
0209     orion_delay_timer.freq = tclk;
0210     register_current_timer_delay(&orion_delay_timer);
0211 
0212     /*
0213      * Set scale and timer for sched_clock.
0214      */
0215     sched_clock_register(orion_read_sched_clock, 32, tclk);
0216 
0217     /*
0218      * Setup free-running clocksource timer (interrupts
0219      * disabled).
0220      */
0221     writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
0222     writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
0223     u = readl(bridge_base + BRIDGE_MASK_OFF);
0224     writel(u & ~BRIDGE_INT_TIMER0, bridge_base + BRIDGE_MASK_OFF);
0225     u = readl(timer_base + TIMER_CTRL_OFF);
0226     writel(u | TIMER0_EN | TIMER0_RELOAD_EN, timer_base + TIMER_CTRL_OFF);
0227     clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, "orion_clocksource",
0228         tclk, 300, 32, clocksource_mmio_readl_down);
0229 
0230     /*
0231      * Setup clockevent timer (interrupt-driven).
0232      */
0233     if (request_irq(irq, orion_timer_interrupt, IRQF_TIMER, "orion_tick",
0234             NULL))
0235         pr_err("Failed to request irq %u (orion_tick)\n", irq);
0236     orion_clkevt.cpumask = cpumask_of(0);
0237     clockevents_config_and_register(&orion_clkevt, tclk, 1, 0xfffffffe);
0238 }