0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/kernel.h>
0012 #include <linux/bitops.h>
0013 #include <linux/clk.h>
0014 #include <linux/clockchips.h>
0015 #include <linux/delay.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/of_address.h>
0018 #include <linux/of_irq.h>
0019 #include <linux/spinlock.h>
0020 #include <linux/sched_clock.h>
0021
0022 #define TIMER_CTRL 0x00
0023 #define TIMER0_EN BIT(0)
0024 #define TIMER0_RELOAD_EN BIT(1)
0025 #define TIMER1_EN BIT(2)
0026 #define TIMER1_RELOAD_EN BIT(3)
0027 #define TIMER0_RELOAD 0x10
0028 #define TIMER0_VAL 0x14
0029 #define TIMER1_RELOAD 0x18
0030 #define TIMER1_VAL 0x1c
0031
0032 #define ORION_ONESHOT_MIN 1
0033 #define ORION_ONESHOT_MAX 0xfffffffe
0034
0035 static void __iomem *timer_base;
0036
0037 static unsigned long notrace orion_read_timer(void)
0038 {
0039 return ~readl(timer_base + TIMER0_VAL);
0040 }
0041
0042 static struct delay_timer orion_delay_timer = {
0043 .read_current_timer = orion_read_timer,
0044 };
0045
0046 static void orion_delay_timer_init(unsigned long rate)
0047 {
0048 orion_delay_timer.freq = rate;
0049 register_current_timer_delay(&orion_delay_timer);
0050 }
0051
0052
0053
0054
0055 static u64 notrace orion_read_sched_clock(void)
0056 {
0057 return ~readl(timer_base + TIMER0_VAL);
0058 }
0059
0060
0061
0062
0063 static u32 ticks_per_jiffy;
0064
0065 static int orion_clkevt_next_event(unsigned long delta,
0066 struct clock_event_device *dev)
0067 {
0068
0069 writel(delta, timer_base + TIMER1_VAL);
0070 atomic_io_modify(timer_base + TIMER_CTRL,
0071 TIMER1_RELOAD_EN | TIMER1_EN, TIMER1_EN);
0072
0073 return 0;
0074 }
0075
0076 static int orion_clkevt_shutdown(struct clock_event_device *dev)
0077 {
0078
0079 atomic_io_modify(timer_base + TIMER_CTRL,
0080 TIMER1_RELOAD_EN | TIMER1_EN, 0);
0081 return 0;
0082 }
0083
0084 static int orion_clkevt_set_periodic(struct clock_event_device *dev)
0085 {
0086
0087 writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD);
0088 writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL);
0089 atomic_io_modify(timer_base + TIMER_CTRL,
0090 TIMER1_RELOAD_EN | TIMER1_EN,
0091 TIMER1_RELOAD_EN | TIMER1_EN);
0092 return 0;
0093 }
0094
0095 static struct clock_event_device orion_clkevt = {
0096 .name = "orion_event",
0097 .features = CLOCK_EVT_FEAT_ONESHOT |
0098 CLOCK_EVT_FEAT_PERIODIC,
0099 .shift = 32,
0100 .rating = 300,
0101 .set_next_event = orion_clkevt_next_event,
0102 .set_state_shutdown = orion_clkevt_shutdown,
0103 .set_state_periodic = orion_clkevt_set_periodic,
0104 .set_state_oneshot = orion_clkevt_shutdown,
0105 .tick_resume = orion_clkevt_shutdown,
0106 };
0107
0108 static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id)
0109 {
0110 orion_clkevt.event_handler(&orion_clkevt);
0111 return IRQ_HANDLED;
0112 }
0113
0114 static int __init orion_timer_init(struct device_node *np)
0115 {
0116 unsigned long rate;
0117 struct clk *clk;
0118 int irq, ret;
0119
0120
0121 timer_base = of_iomap(np, 0);
0122 if (!timer_base) {
0123 pr_err("%pOFn: unable to map resource\n", np);
0124 return -ENXIO;
0125 }
0126
0127 clk = of_clk_get(np, 0);
0128 if (IS_ERR(clk)) {
0129 pr_err("%pOFn: unable to get clk\n", np);
0130 return PTR_ERR(clk);
0131 }
0132
0133 ret = clk_prepare_enable(clk);
0134 if (ret) {
0135 pr_err("Failed to prepare clock\n");
0136 return ret;
0137 }
0138
0139
0140 irq = irq_of_parse_and_map(np, 1);
0141 if (irq <= 0) {
0142 pr_err("%pOFn: unable to parse timer1 irq\n", np);
0143 ret = -EINVAL;
0144 goto out_unprep_clk;
0145 }
0146
0147 rate = clk_get_rate(clk);
0148
0149
0150 writel(~0, timer_base + TIMER0_VAL);
0151 writel(~0, timer_base + TIMER0_RELOAD);
0152 atomic_io_modify(timer_base + TIMER_CTRL,
0153 TIMER0_RELOAD_EN | TIMER0_EN,
0154 TIMER0_RELOAD_EN | TIMER0_EN);
0155
0156 ret = clocksource_mmio_init(timer_base + TIMER0_VAL,
0157 "orion_clocksource", rate, 300, 32,
0158 clocksource_mmio_readl_down);
0159 if (ret) {
0160 pr_err("Failed to initialize mmio timer\n");
0161 goto out_unprep_clk;
0162 }
0163
0164 sched_clock_register(orion_read_sched_clock, 32, rate);
0165
0166
0167 ret = request_irq(irq, orion_clkevt_irq_handler, IRQF_TIMER,
0168 "orion_event", NULL);
0169 if (ret) {
0170 pr_err("%pOFn: unable to setup irq\n", np);
0171 goto out_unprep_clk;
0172 }
0173
0174 ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ;
0175 orion_clkevt.cpumask = cpumask_of(0);
0176 orion_clkevt.irq = irq;
0177 clockevents_config_and_register(&orion_clkevt, rate,
0178 ORION_ONESHOT_MIN, ORION_ONESHOT_MAX);
0179
0180
0181 orion_delay_timer_init(rate);
0182
0183 return 0;
0184
0185 out_unprep_clk:
0186 clk_disable_unprepare(clk);
0187 return ret;
0188 }
0189 TIMER_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init);