0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/io.h>
0015 #include <linux/irq.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/clocksource.h>
0018 #include <linux/clockchips.h>
0019 #include <linux/delay.h>
0020
0021 #include <linux/of.h>
0022 #include <linux/of_address.h>
0023 #include <linux/of_irq.h>
0024
0025 #define VT8500_TIMER_OFFSET 0x0100
0026 #define VT8500_TIMER_HZ 3000000
0027 #define TIMER_MATCH_VAL 0x0000
0028 #define TIMER_COUNT_VAL 0x0010
0029 #define TIMER_STATUS_VAL 0x0014
0030 #define TIMER_IER_VAL 0x001c
0031 #define TIMER_CTRL_VAL 0x0020
0032 #define TIMER_AS_VAL 0x0024
0033 #define TIMER_COUNT_R_ACTIVE (1 << 5)
0034 #define TIMER_COUNT_W_ACTIVE (1 << 4)
0035 #define TIMER_MATCH_W_ACTIVE (1 << 0)
0036
0037 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
0038
0039 #define MIN_OSCR_DELTA 16
0040
0041 static void __iomem *regbase;
0042
0043 static u64 vt8500_timer_read(struct clocksource *cs)
0044 {
0045 int loops = msecs_to_loops(10);
0046 writel(3, regbase + TIMER_CTRL_VAL);
0047 while ((readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE)
0048 && --loops)
0049 cpu_relax();
0050 return readl(regbase + TIMER_COUNT_VAL);
0051 }
0052
0053 static struct clocksource clocksource = {
0054 .name = "vt8500_timer",
0055 .rating = 200,
0056 .read = vt8500_timer_read,
0057 .mask = CLOCKSOURCE_MASK(32),
0058 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
0059 };
0060
0061 static int vt8500_timer_set_next_event(unsigned long cycles,
0062 struct clock_event_device *evt)
0063 {
0064 int loops = msecs_to_loops(10);
0065 u64 alarm = clocksource.read(&clocksource) + cycles;
0066 while ((readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE)
0067 && --loops)
0068 cpu_relax();
0069 writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL);
0070
0071 if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA)
0072 return -ETIME;
0073
0074 writel(1, regbase + TIMER_IER_VAL);
0075
0076 return 0;
0077 }
0078
0079 static int vt8500_shutdown(struct clock_event_device *evt)
0080 {
0081 writel(readl(regbase + TIMER_CTRL_VAL) | 1, regbase + TIMER_CTRL_VAL);
0082 writel(0, regbase + TIMER_IER_VAL);
0083 return 0;
0084 }
0085
0086 static struct clock_event_device clockevent = {
0087 .name = "vt8500_timer",
0088 .features = CLOCK_EVT_FEAT_ONESHOT,
0089 .rating = 200,
0090 .set_next_event = vt8500_timer_set_next_event,
0091 .set_state_shutdown = vt8500_shutdown,
0092 .set_state_oneshot = vt8500_shutdown,
0093 };
0094
0095 static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
0096 {
0097 struct clock_event_device *evt = dev_id;
0098 writel(0xf, regbase + TIMER_STATUS_VAL);
0099 evt->event_handler(evt);
0100
0101 return IRQ_HANDLED;
0102 }
0103
0104 static int __init vt8500_timer_init(struct device_node *np)
0105 {
0106 int timer_irq, ret;
0107
0108 regbase = of_iomap(np, 0);
0109 if (!regbase) {
0110 pr_err("%s: Missing iobase description in Device Tree\n",
0111 __func__);
0112 return -ENXIO;
0113 }
0114
0115 timer_irq = irq_of_parse_and_map(np, 0);
0116 if (!timer_irq) {
0117 pr_err("%s: Missing irq description in Device Tree\n",
0118 __func__);
0119 return -EINVAL;
0120 }
0121
0122 writel(1, regbase + TIMER_CTRL_VAL);
0123 writel(0xf, regbase + TIMER_STATUS_VAL);
0124 writel(~0, regbase + TIMER_MATCH_VAL);
0125
0126 ret = clocksource_register_hz(&clocksource, VT8500_TIMER_HZ);
0127 if (ret) {
0128 pr_err("%s: clocksource_register failed for %s\n",
0129 __func__, clocksource.name);
0130 return ret;
0131 }
0132
0133 clockevent.cpumask = cpumask_of(0);
0134
0135 ret = request_irq(timer_irq, vt8500_timer_interrupt,
0136 IRQF_TIMER | IRQF_IRQPOLL, "vt8500_timer",
0137 &clockevent);
0138 if (ret) {
0139 pr_err("%s: setup_irq failed for %s\n", __func__,
0140 clockevent.name);
0141 return ret;
0142 }
0143
0144 clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ,
0145 MIN_OSCR_DELTA * 2, 0xf0000000);
0146
0147 return 0;
0148 }
0149
0150 TIMER_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init);