1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * IXP4 timer driver 4 * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org> 5 * 6 * Based on arch/arm/mach-ixp4xx/common.c 7 * Copyright 2002 (C) Intel Corporation 8 * Copyright 2003-2004 (C) MontaVista, Software, Inc. 9 * Copyright (C) Deepak Saxena <dsaxena@plexity.net> 10 */ 11 #include <linux/interrupt.h> 12 #include <linux/io.h> 13 #include <linux/clockchips.h> 14 #include <linux/clocksource.h> 15 #include <linux/sched_clock.h> 16 #include <linux/slab.h> 17 #include <linux/bitops.h> 18 #include <linux/delay.h> 19 #include <linux/of_address.h> 20 #include <linux/of_irq.h> 21 /* Goes away with OF conversion */ 22 #include <linux/platform_data/timer-ixp4xx.h> 23 24 /* 25 * Constants to make it easy to access Timer Control/Status registers 26 */ 27 #define IXP4XX_OSTS_OFFSET 0x00 /* Continuous Timestamp */ 28 #define IXP4XX_OST1_OFFSET 0x04 /* Timer 1 Timestamp */ 29 #define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */ 30 #define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */ 31 #define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */ 32 #define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */ 33 #define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */ 34 #define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */ 35 #define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */ 36 37 /* 38 * Timer register values and bit definitions 39 */ 40 #define IXP4XX_OST_ENABLE 0x00000001 41 #define IXP4XX_OST_ONE_SHOT 0x00000002 42 /* Low order bits of reload value ignored */ 43 #define IXP4XX_OST_RELOAD_MASK 0x00000003 44 #define IXP4XX_OST_DISABLED 0x00000000 45 #define IXP4XX_OSST_TIMER_1_PEND 0x00000001 46 #define IXP4XX_OSST_TIMER_2_PEND 0x00000002 47 #define IXP4XX_OSST_TIMER_TS_PEND 0x00000004 48 #define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008 49 #define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010 50 51 #define IXP4XX_WDT_KEY 0x0000482E 52 #define IXP4XX_WDT_RESET_ENABLE 0x00000001 53 #define IXP4XX_WDT_IRQ_ENABLE 0x00000002 54 #define IXP4XX_WDT_COUNT_ENABLE 0x00000004 55 56 struct ixp4xx_timer { 57 void __iomem *base; 58 unsigned int tick_rate; 59 u32 latch; 60 struct clock_event_device clkevt; 61 #ifdef CONFIG_ARM 62 struct delay_timer delay_timer; 63 #endif 64 }; 65 66 /* 67 * A local singleton used by sched_clock and delay timer reads, which are 68 * fast and stateless 69 */ 70 static struct ixp4xx_timer *local_ixp4xx_timer; 71 72 static inline struct ixp4xx_timer * 73 to_ixp4xx_timer(struct clock_event_device *evt) 74 { 75 return container_of(evt, struct ixp4xx_timer, clkevt); 76 } 77 78 static u64 notrace ixp4xx_read_sched_clock(void) 79 { 80 return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET); 81 } 82 83 static u64 ixp4xx_clocksource_read(struct clocksource *c) 84 { 85 return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET); 86 } 87 88 static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) 89 { 90 struct ixp4xx_timer *tmr = dev_id; 91 struct clock_event_device *evt = &tmr->clkevt; 92 93 /* Clear Pending Interrupt */ 94 __raw_writel(IXP4XX_OSST_TIMER_1_PEND, 95 tmr->base + IXP4XX_OSST_OFFSET); 96 97 evt->event_handler(evt); 98 99 return IRQ_HANDLED; 100 } 101 102 static int ixp4xx_set_next_event(unsigned long cycles, 103 struct clock_event_device *evt) 104 { 105 struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 106 u32 val; 107 108 val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET); 109 /* Keep enable/oneshot bits */ 110 val &= IXP4XX_OST_RELOAD_MASK; 111 __raw_writel((cycles & ~IXP4XX_OST_RELOAD_MASK) | val, 112 tmr->base + IXP4XX_OSRT1_OFFSET); 113 114 return 0; 115 } 116 117 static int ixp4xx_shutdown(struct clock_event_device *evt) 118 { 119 struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 120 u32 val; 121 122 val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET); 123 val &= ~IXP4XX_OST_ENABLE; 124 __raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET); 125 126 return 0; 127 } 128 129 static int ixp4xx_set_oneshot(struct clock_event_device *evt) 130 { 131 struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 132 133 __raw_writel(IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT, 134 tmr->base + IXP4XX_OSRT1_OFFSET); 135 136 return 0; 137 } 138 139 static int ixp4xx_set_periodic(struct clock_event_device *evt) 140 { 141 struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 142 u32 val; 143 144 val = tmr->latch & ~IXP4XX_OST_RELOAD_MASK; 145 val |= IXP4XX_OST_ENABLE; 146 __raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET); 147 148 return 0; 149 } 150 151 static int ixp4xx_resume(struct clock_event_device *evt) 152 { 153 struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt); 154 u32 val; 155 156 val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET); 157 val |= IXP4XX_OST_ENABLE; 158 __raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET); 159 160 return 0; 161 } 162 163 /* 164 * IXP4xx timer tick 165 * We use OS timer1 on the CPU for the timer tick and the timestamp 166 * counter as a source of real clock ticks to account for missed jiffies. 167 */ 168 static __init int ixp4xx_timer_register(void __iomem *base, 169 int timer_irq, 170 unsigned int timer_freq) 171 { 172 struct ixp4xx_timer *tmr; 173 int ret; 174 175 tmr = kzalloc(sizeof(*tmr), GFP_KERNEL); 176 if (!tmr) 177 return -ENOMEM; 178 tmr->base = base; 179 tmr->tick_rate = timer_freq; 180 181 /* 182 * The timer register doesn't allow to specify the two least 183 * significant bits of the timeout value and assumes them being zero. 184 * So make sure the latch is the best value with the two least 185 * significant bits unset. 186 */ 187 tmr->latch = DIV_ROUND_CLOSEST(timer_freq, 188 (IXP4XX_OST_RELOAD_MASK + 1) * HZ) 189 * (IXP4XX_OST_RELOAD_MASK + 1); 190 191 local_ixp4xx_timer = tmr; 192 193 /* Reset/disable counter */ 194 __raw_writel(0, tmr->base + IXP4XX_OSRT1_OFFSET); 195 196 /* Clear any pending interrupt on timer 1 */ 197 __raw_writel(IXP4XX_OSST_TIMER_1_PEND, 198 tmr->base + IXP4XX_OSST_OFFSET); 199 200 /* Reset time-stamp counter */ 201 __raw_writel(0, tmr->base + IXP4XX_OSTS_OFFSET); 202 203 clocksource_mmio_init(NULL, "OSTS", timer_freq, 200, 32, 204 ixp4xx_clocksource_read); 205 206 tmr->clkevt.name = "ixp4xx timer1"; 207 tmr->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 208 tmr->clkevt.rating = 200; 209 tmr->clkevt.set_state_shutdown = ixp4xx_shutdown; 210 tmr->clkevt.set_state_periodic = ixp4xx_set_periodic; 211 tmr->clkevt.set_state_oneshot = ixp4xx_set_oneshot; 212 tmr->clkevt.tick_resume = ixp4xx_resume; 213 tmr->clkevt.set_next_event = ixp4xx_set_next_event; 214 tmr->clkevt.cpumask = cpumask_of(0); 215 tmr->clkevt.irq = timer_irq; 216 ret = request_irq(timer_irq, ixp4xx_timer_interrupt, 217 IRQF_TIMER, "IXP4XX-TIMER1", tmr); 218 if (ret) { 219 pr_crit("no timer IRQ\n"); 220 return -ENODEV; 221 } 222 clockevents_config_and_register(&tmr->clkevt, timer_freq, 223 0xf, 0xfffffffe); 224 225 sched_clock_register(ixp4xx_read_sched_clock, 32, timer_freq); 226 227 return 0; 228 } 229 230 /** 231 * ixp4xx_timer_setup() - Timer setup function to be called from boardfiles 232 * @timerbase: physical base of timer block 233 * @timer_irq: Linux IRQ number for the timer 234 * @timer_freq: Fixed frequency of the timer 235 */ 236 void __init ixp4xx_timer_setup(resource_size_t timerbase, 237 int timer_irq, 238 unsigned int timer_freq) 239 { 240 void __iomem *base; 241 242 base = ioremap(timerbase, 0x100); 243 if (!base) { 244 pr_crit("IXP4xx: can't remap timer\n"); 245 return; 246 } 247 ixp4xx_timer_register(base, timer_irq, timer_freq); 248 } 249 EXPORT_SYMBOL_GPL(ixp4xx_timer_setup); 250 251 #ifdef CONFIG_OF 252 static __init int ixp4xx_of_timer_init(struct device_node *np) 253 { 254 void __iomem *base; 255 int irq; 256 int ret; 257 258 base = of_iomap(np, 0); 259 if (!base) { 260 pr_crit("IXP4xx: can't remap timer\n"); 261 return -ENODEV; 262 } 263 264 irq = irq_of_parse_and_map(np, 0); 265 if (irq <= 0) { 266 pr_err("Can't parse IRQ\n"); 267 ret = -EINVAL; 268 goto out_unmap; 269 } 270 271 /* TODO: get some fixed clocks into the device tree */ 272 ret = ixp4xx_timer_register(base, irq, 66666000); 273 if (ret) 274 goto out_unmap; 275 return 0; 276 277 out_unmap: 278 iounmap(base); 279 return ret; 280 } 281 TIMER_OF_DECLARE(ixp4xx, "intel,ixp4xx-timer", ixp4xx_of_timer_init); 282 #endif 283