0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk.h>
0009 #include <linux/clocksource.h>
0010 #include <linux/of_irq.h>
0011 #include <linux/of_address.h>
0012 #include <linux/of_platform.h>
0013 #include <linux/clockchips.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/sched_clock.h>
0016
0017 #include "timer-sp.h"
0018
0019 static void __iomem * sched_clk_base;
0020
0021 static u64 notrace integrator_read_sched_clock(void)
0022 {
0023 return -readl(sched_clk_base + TIMER_VALUE);
0024 }
0025
0026 static int __init integrator_clocksource_init(unsigned long inrate,
0027 void __iomem *base)
0028 {
0029 u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
0030 unsigned long rate = inrate;
0031 int ret;
0032
0033 if (rate >= 1500000) {
0034 rate /= 16;
0035 ctrl |= TIMER_CTRL_DIV16;
0036 }
0037
0038 writel(0xffff, base + TIMER_LOAD);
0039 writel(ctrl, base + TIMER_CTRL);
0040
0041 ret = clocksource_mmio_init(base + TIMER_VALUE, "timer2",
0042 rate, 200, 16, clocksource_mmio_readl_down);
0043 if (ret)
0044 return ret;
0045
0046 sched_clk_base = base;
0047 sched_clock_register(integrator_read_sched_clock, 16, rate);
0048
0049 return 0;
0050 }
0051
0052 static unsigned long timer_reload;
0053 static void __iomem * clkevt_base;
0054
0055
0056
0057
0058 static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
0059 {
0060 struct clock_event_device *evt = dev_id;
0061
0062
0063 writel(1, clkevt_base + TIMER_INTCLR);
0064
0065 evt->event_handler(evt);
0066
0067 return IRQ_HANDLED;
0068 }
0069
0070 static int clkevt_shutdown(struct clock_event_device *evt)
0071 {
0072 u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
0073
0074
0075 writel(ctrl, clkevt_base + TIMER_CTRL);
0076 return 0;
0077 }
0078
0079 static int clkevt_set_oneshot(struct clock_event_device *evt)
0080 {
0081 u32 ctrl = readl(clkevt_base + TIMER_CTRL) &
0082 ~(TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC);
0083
0084
0085 writel(ctrl, clkevt_base + TIMER_CTRL);
0086 return 0;
0087 }
0088
0089 static int clkevt_set_periodic(struct clock_event_device *evt)
0090 {
0091 u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
0092
0093
0094 writel(ctrl, clkevt_base + TIMER_CTRL);
0095
0096
0097 writel(timer_reload, clkevt_base + TIMER_LOAD);
0098 ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
0099 writel(ctrl, clkevt_base + TIMER_CTRL);
0100 return 0;
0101 }
0102
0103 static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
0104 {
0105 unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
0106
0107 writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
0108 writel(next, clkevt_base + TIMER_LOAD);
0109 writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
0110
0111 return 0;
0112 }
0113
0114 static struct clock_event_device integrator_clockevent = {
0115 .name = "timer1",
0116 .features = CLOCK_EVT_FEAT_PERIODIC |
0117 CLOCK_EVT_FEAT_ONESHOT,
0118 .set_state_shutdown = clkevt_shutdown,
0119 .set_state_periodic = clkevt_set_periodic,
0120 .set_state_oneshot = clkevt_set_oneshot,
0121 .tick_resume = clkevt_shutdown,
0122 .set_next_event = clkevt_set_next_event,
0123 .rating = 300,
0124 };
0125
0126 static int integrator_clockevent_init(unsigned long inrate,
0127 void __iomem *base, int irq)
0128 {
0129 unsigned long rate = inrate;
0130 unsigned int ctrl = 0;
0131 int ret;
0132
0133 clkevt_base = base;
0134
0135 if (rate > 0x100000 * HZ) {
0136 rate /= 256;
0137 ctrl |= TIMER_CTRL_DIV256;
0138 } else if (rate > 0x10000 * HZ) {
0139 rate /= 16;
0140 ctrl |= TIMER_CTRL_DIV16;
0141 }
0142 timer_reload = rate / HZ;
0143 writel(ctrl, clkevt_base + TIMER_CTRL);
0144
0145 ret = request_irq(irq, integrator_timer_interrupt,
0146 IRQF_TIMER | IRQF_IRQPOLL, "timer",
0147 &integrator_clockevent);
0148 if (ret)
0149 return ret;
0150
0151 clockevents_config_and_register(&integrator_clockevent,
0152 rate,
0153 1,
0154 0xffffU);
0155 return 0;
0156 }
0157
0158 static int __init integrator_ap_timer_init_of(struct device_node *node)
0159 {
0160 const char *path;
0161 void __iomem *base;
0162 int err;
0163 int irq;
0164 struct clk *clk;
0165 unsigned long rate;
0166 struct device_node *alias_node;
0167
0168 base = of_io_request_and_map(node, 0, "integrator-timer");
0169 if (IS_ERR(base))
0170 return PTR_ERR(base);
0171
0172 clk = of_clk_get(node, 0);
0173 if (IS_ERR(clk)) {
0174 pr_err("No clock for %pOFn\n", node);
0175 return PTR_ERR(clk);
0176 }
0177 clk_prepare_enable(clk);
0178 rate = clk_get_rate(clk);
0179 writel(0, base + TIMER_CTRL);
0180
0181 err = of_property_read_string(of_aliases,
0182 "arm,timer-primary", &path);
0183 if (err) {
0184 pr_warn("Failed to read property\n");
0185 return err;
0186 }
0187
0188 alias_node = of_find_node_by_path(path);
0189
0190
0191
0192
0193
0194
0195 of_node_put(alias_node);
0196
0197 if (node == alias_node)
0198
0199 return integrator_clocksource_init(rate, base);
0200
0201 err = of_property_read_string(of_aliases,
0202 "arm,timer-secondary", &path);
0203 if (err) {
0204 pr_warn("Failed to read property\n");
0205 return err;
0206 }
0207
0208 alias_node = of_find_node_by_path(path);
0209
0210 of_node_put(alias_node);
0211
0212 if (node == alias_node) {
0213
0214 irq = irq_of_parse_and_map(node, 0);
0215 return integrator_clockevent_init(rate, base, irq);
0216 }
0217
0218 pr_info("Timer @%p unused\n", base);
0219 clk_disable_unprepare(clk);
0220
0221 return 0;
0222 }
0223
0224 TIMER_OF_DECLARE(integrator_ap_timer, "arm,integrator-timer",
0225 integrator_ap_timer_init_of);