0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0025
0026 #include <linux/clk.h>
0027 #include <linux/clockchips.h>
0028 #include <linux/interrupt.h>
0029 #include <linux/irq.h>
0030 #include <linux/irqreturn.h>
0031 #include <linux/sched/clock.h>
0032 #include <linux/sched_clock.h>
0033 #include <linux/of.h>
0034 #include <linux/of_address.h>
0035 #include <linux/of_irq.h>
0036
0037 enum {
0038 TIMER_A,
0039 TIMER_B,
0040 TIMER_C,
0041 TIMER_D,
0042 TIMER_E,
0043 TIMER_F,
0044 TIMER_G,
0045 TIMER_H,
0046 };
0047
0048 #define CONTROL(t) ((t)*8)
0049 #define COUNT(t) ((t)*8 + 4)
0050
0051 #define CONTROL_DISABLE 0
0052 #define CONTROL_ENABLE BIT(0)
0053 #define CONTROL_MODE(m) ((m) << 4)
0054 #define CONTROL_MODE_ONESHOT CONTROL_MODE(1)
0055 #define CONTROL_MODE_PERIODIC CONTROL_MODE(2)
0056
0057 struct digicolor_timer {
0058 struct clock_event_device ce;
0059 void __iomem *base;
0060 u32 ticks_per_jiffy;
0061 int timer_id;
0062 };
0063
0064 static struct digicolor_timer *dc_timer(struct clock_event_device *ce)
0065 {
0066 return container_of(ce, struct digicolor_timer, ce);
0067 }
0068
0069 static inline void dc_timer_disable(struct clock_event_device *ce)
0070 {
0071 struct digicolor_timer *dt = dc_timer(ce);
0072 writeb(CONTROL_DISABLE, dt->base + CONTROL(dt->timer_id));
0073 }
0074
0075 static inline void dc_timer_enable(struct clock_event_device *ce, u32 mode)
0076 {
0077 struct digicolor_timer *dt = dc_timer(ce);
0078 writeb(CONTROL_ENABLE | mode, dt->base + CONTROL(dt->timer_id));
0079 }
0080
0081 static inline void dc_timer_set_count(struct clock_event_device *ce,
0082 unsigned long count)
0083 {
0084 struct digicolor_timer *dt = dc_timer(ce);
0085 writel(count, dt->base + COUNT(dt->timer_id));
0086 }
0087
0088 static int digicolor_clkevt_shutdown(struct clock_event_device *ce)
0089 {
0090 dc_timer_disable(ce);
0091 return 0;
0092 }
0093
0094 static int digicolor_clkevt_set_oneshot(struct clock_event_device *ce)
0095 {
0096 dc_timer_disable(ce);
0097 dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
0098 return 0;
0099 }
0100
0101 static int digicolor_clkevt_set_periodic(struct clock_event_device *ce)
0102 {
0103 struct digicolor_timer *dt = dc_timer(ce);
0104
0105 dc_timer_disable(ce);
0106 dc_timer_set_count(ce, dt->ticks_per_jiffy);
0107 dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
0108 return 0;
0109 }
0110
0111 static int digicolor_clkevt_next_event(unsigned long evt,
0112 struct clock_event_device *ce)
0113 {
0114 dc_timer_disable(ce);
0115 dc_timer_set_count(ce, evt);
0116 dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
0117
0118 return 0;
0119 }
0120
0121 static struct digicolor_timer dc_timer_dev = {
0122 .ce = {
0123 .name = "digicolor_tick",
0124 .rating = 340,
0125 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
0126 .set_state_shutdown = digicolor_clkevt_shutdown,
0127 .set_state_periodic = digicolor_clkevt_set_periodic,
0128 .set_state_oneshot = digicolor_clkevt_set_oneshot,
0129 .tick_resume = digicolor_clkevt_shutdown,
0130 .set_next_event = digicolor_clkevt_next_event,
0131 },
0132 .timer_id = TIMER_C,
0133 };
0134
0135 static irqreturn_t digicolor_timer_interrupt(int irq, void *dev_id)
0136 {
0137 struct clock_event_device *evt = dev_id;
0138
0139 evt->event_handler(evt);
0140
0141 return IRQ_HANDLED;
0142 }
0143
0144 static u64 notrace digicolor_timer_sched_read(void)
0145 {
0146 return ~readl(dc_timer_dev.base + COUNT(TIMER_B));
0147 }
0148
0149 static int __init digicolor_timer_init(struct device_node *node)
0150 {
0151 unsigned long rate;
0152 struct clk *clk;
0153 int ret, irq;
0154
0155
0156
0157
0158
0159 dc_timer_dev.base = of_iomap(node, 0);
0160 if (!dc_timer_dev.base) {
0161 pr_err("Can't map registers\n");
0162 return -ENXIO;
0163 }
0164
0165 irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id);
0166 if (irq <= 0) {
0167 pr_err("Can't parse IRQ\n");
0168 return -EINVAL;
0169 }
0170
0171 clk = of_clk_get(node, 0);
0172 if (IS_ERR(clk)) {
0173 pr_err("Can't get timer clock\n");
0174 return PTR_ERR(clk);
0175 }
0176 clk_prepare_enable(clk);
0177 rate = clk_get_rate(clk);
0178 dc_timer_dev.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
0179
0180 writeb(CONTROL_DISABLE, dc_timer_dev.base + CONTROL(TIMER_B));
0181 writel(UINT_MAX, dc_timer_dev.base + COUNT(TIMER_B));
0182 writeb(CONTROL_ENABLE, dc_timer_dev.base + CONTROL(TIMER_B));
0183
0184 sched_clock_register(digicolor_timer_sched_read, 32, rate);
0185 clocksource_mmio_init(dc_timer_dev.base + COUNT(TIMER_B), node->name,
0186 rate, 340, 32, clocksource_mmio_readl_down);
0187
0188 ret = request_irq(irq, digicolor_timer_interrupt,
0189 IRQF_TIMER | IRQF_IRQPOLL, "digicolor_timerC",
0190 &dc_timer_dev.ce);
0191 if (ret) {
0192 pr_warn("request of timer irq %d failed (%d)\n", irq, ret);
0193 return ret;
0194 }
0195
0196 dc_timer_dev.ce.cpumask = cpu_possible_mask;
0197 dc_timer_dev.ce.irq = irq;
0198
0199 clockevents_config_and_register(&dc_timer_dev.ce, rate, 0, 0xffffffff);
0200
0201 return 0;
0202 }
0203 TIMER_OF_DECLARE(conexant_digicolor, "cnxt,cx92755-timer",
0204 digicolor_timer_init);