^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/drivers/clocksource/zevio-timer.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clockchips.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/cpumask.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define IO_CURRENT_VAL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define IO_DIVIDER 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define IO_CONTROL 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define IO_TIMER1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define IO_TIMER2 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define IO_MATCH_BEGIN 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define IO_MATCH(x) (IO_MATCH_BEGIN + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define IO_INTR_STS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define IO_INTR_ACK 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define IO_INTR_MSK 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CNTL_STOP_TIMER (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CNTL_RUN_TIMER (0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CNTL_INC (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CNTL_DEC (0 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CNTL_TOZERO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CNTL_MATCH(x) ((x) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define CNTL_FOREVER 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* There are 6 match registers but we only use one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define TIMER_MATCH 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define TIMER_INTR_MSK (1 << (TIMER_MATCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define TIMER_INTR_ALL 0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct zevio_timer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) void __iomem *timer1, *timer2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void __iomem *interrupt_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct clock_event_device clkevt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) char clocksource_name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) char clockevent_name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int zevio_timer_set_event(unsigned long delta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct clock_event_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct zevio_timer *timer = container_of(dev, struct zevio_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) clkevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) writel(delta, timer->timer1 + IO_CURRENT_VAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) writel(CNTL_RUN_TIMER | CNTL_DEC | CNTL_MATCH(TIMER_MATCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) timer->timer1 + IO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int zevio_timer_shutdown(struct clock_event_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct zevio_timer *timer = container_of(dev, struct zevio_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) clkevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Disable timer interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) writel(0, timer->interrupt_regs + IO_INTR_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Stop timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static int zevio_timer_set_oneshot(struct clock_event_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct zevio_timer *timer = container_of(dev, struct zevio_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) clkevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Enable timer interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static irqreturn_t zevio_timer_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct zevio_timer *timer = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u32 intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) intr = readl(timer->interrupt_regs + IO_INTR_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!(intr & TIMER_INTR_MSK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (timer->clkevt.event_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) timer->clkevt.event_handler(&timer->clkevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int __init zevio_timer_add(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct zevio_timer *timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int irqnr, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) timer = kzalloc(sizeof(*timer), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (!timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) timer->base = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!timer->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) timer->timer1 = timer->base + IO_TIMER1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) timer->timer2 = timer->base + IO_TIMER2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) timer->clk = of_clk_get(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (IS_ERR(timer->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = PTR_ERR(timer->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pr_err("Timer clock not found! (error %d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto error_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) timer->interrupt_regs = of_iomap(node, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) irqnr = irq_of_parse_and_map(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) of_address_to_resource(node, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) scnprintf(timer->clocksource_name, sizeof(timer->clocksource_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) "%llx.%pOFn_clocksource",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) (unsigned long long)res.start, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) scnprintf(timer->clockevent_name, sizeof(timer->clockevent_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) "%llx.%pOFn_clockevent",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) (unsigned long long)res.start, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (timer->interrupt_regs && irqnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) timer->clkevt.name = timer->clockevent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) timer->clkevt.set_next_event = zevio_timer_set_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) timer->clkevt.set_state_shutdown = zevio_timer_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) timer->clkevt.set_state_oneshot = zevio_timer_set_oneshot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) timer->clkevt.tick_resume = zevio_timer_set_oneshot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) timer->clkevt.rating = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) timer->clkevt.cpumask = cpu_possible_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) timer->clkevt.features = CLOCK_EVT_FEAT_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) timer->clkevt.irq = irqnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) writel(0, timer->timer1 + IO_DIVIDER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Start with timer interrupts disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) writel(0, timer->interrupt_regs + IO_INTR_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Interrupt to occur when timer value matches 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) writel(0, timer->base + IO_MATCH(TIMER_MATCH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (request_irq(irqnr, zevio_timer_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) IRQF_TIMER | IRQF_IRQPOLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) timer->clockevent_name, timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) pr_err("%s: request_irq() failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) timer->clockevent_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) clockevents_config_and_register(&timer->clkevt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) clk_get_rate(timer->clk), 0x0001, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) pr_info("Added %s as clockevent\n", timer->clockevent_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) writel(CNTL_STOP_TIMER, timer->timer2 + IO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) writel(0, timer->timer2 + IO_CURRENT_VAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) writel(0, timer->timer2 + IO_DIVIDER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) writel(CNTL_RUN_TIMER | CNTL_FOREVER | CNTL_INC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) timer->timer2 + IO_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) clocksource_mmio_init(timer->timer2 + IO_CURRENT_VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) timer->clocksource_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) clk_get_rate(timer->clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 200, 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) clocksource_mmio_readw_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) pr_info("Added %s as clocksource\n", timer->clocksource_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) error_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) iounmap(timer->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) error_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) kfree(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int __init zevio_timer_init(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return zevio_timer_add(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) TIMER_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init);