1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2013 Pengutronix 4 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> 5 */ 6 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 9#include <linux/kernel.h> 10#include <linux/clocksource.h> 11#include <linux/clockchips.h> 12#include <linux/irq.h> 13#include <linux/interrupt.h> 14#include <linux/of.h> 15#include <linux/of_address.h> 16#include <linux/of_irq.h> 17#include <linux/clk.h> 18 19#define TIMERn_CTRL 0x00 20#define TIMERn_CTRL_PRESC(val) (((val) & 0xf) << 24) 21#define TIMERn_CTRL_PRESC_1024 TIMERn_CTRL_PRESC(10) 22#define TIMERn_CTRL_CLKSEL(val) (((val) & 0x3) << 16) 23#define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK TIMERn_CTRL_CLKSEL(0) 24#define TIMERn_CTRL_OSMEN 0x00000010 25#define TIMERn_CTRL_MODE(val) (((val) & 0x3) << 0) 26#define TIMERn_CTRL_MODE_UP TIMERn_CTRL_MODE(0) 27#define TIMERn_CTRL_MODE_DOWN TIMERn_CTRL_MODE(1) 28 29#define TIMERn_CMD 0x04 30#define TIMERn_CMD_START 0x00000001 31#define TIMERn_CMD_STOP 0x00000002 32 33#define TIMERn_IEN 0x0c 34#define TIMERn_IF 0x10 35#define TIMERn_IFS 0x14 36#define TIMERn_IFC 0x18 37#define TIMERn_IRQ_UF 0x00000002 38 39#define TIMERn_TOP 0x1c 40#define TIMERn_CNT 0x24 41 42struct efm32_clock_event_ddata { 43 struct clock_event_device evtdev; 44 void __iomem *base; 45 unsigned periodic_top; 46}; 47 48static int efm32_clock_event_shutdown(struct clock_event_device *evtdev) 49{ 50 struct efm32_clock_event_ddata *ddata = 51 container_of(evtdev, struct efm32_clock_event_ddata, evtdev); 52 53 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); 54 return 0; 55} 56 57static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev) 58{ 59 struct efm32_clock_event_ddata *ddata = 60 container_of(evtdev, struct efm32_clock_event_ddata, evtdev); 61 62 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); 63 writel_relaxed(TIMERn_CTRL_PRESC_1024 | 64 TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | 65 TIMERn_CTRL_OSMEN | 66 TIMERn_CTRL_MODE_DOWN, 67 ddata->base + TIMERn_CTRL); 68 return 0; 69} 70 71static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev) 72{ 73 struct efm32_clock_event_ddata *ddata = 74 container_of(evtdev, struct efm32_clock_event_ddata, evtdev); 75 76 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); 77 writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP); 78 writel_relaxed(TIMERn_CTRL_PRESC_1024 | 79 TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | 80 TIMERn_CTRL_MODE_DOWN, 81 ddata->base + TIMERn_CTRL); 82 writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD); 83 return 0; 84} 85 86static int efm32_clock_event_set_next_event(unsigned long evt, 87 struct clock_event_device *evtdev) 88{ 89 struct efm32_clock_event_ddata *ddata = 90 container_of(evtdev, struct efm32_clock_event_ddata, evtdev); 91 92 writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); 93 writel_relaxed(evt, ddata->base + TIMERn_CNT); 94 writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD); 95 96 return 0; 97} 98 99static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id) 100{ 101 struct efm32_clock_event_ddata *ddata = dev_id; 102 103 writel_relaxed(TIMERn_IRQ_UF, ddata->base + TIMERn_IFC); 104 105 ddata->evtdev.event_handler(&ddata->evtdev); 106 107 return IRQ_HANDLED; 108} 109 110static struct efm32_clock_event_ddata clock_event_ddata = { 111 .evtdev = { 112 .name = "efm32 clockevent", 113 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 114 .set_state_shutdown = efm32_clock_event_shutdown, 115 .set_state_periodic = efm32_clock_event_set_periodic, 116 .set_state_oneshot = efm32_clock_event_set_oneshot, 117 .set_next_event = efm32_clock_event_set_next_event, 118 .rating = 200, 119 }, 120}; 121 122static int __init efm32_clocksource_init(struct device_node *np) 123{ 124 struct clk *clk; 125 void __iomem *base; 126 unsigned long rate; 127 int ret; 128 129 clk = of_clk_get(np, 0); 130 if (IS_ERR(clk)) { 131 ret = PTR_ERR(clk); 132 pr_err("failed to get clock for clocksource (%d)\n", ret); 133 goto err_clk_get; 134 } 135 136 ret = clk_prepare_enable(clk); 137 if (ret) { 138 pr_err("failed to enable timer clock for clocksource (%d)\n", 139 ret); 140 goto err_clk_enable; 141 } 142 rate = clk_get_rate(clk); 143 144 base = of_iomap(np, 0); 145 if (!base) { 146 ret = -EADDRNOTAVAIL; 147 pr_err("failed to map registers for clocksource\n"); 148 goto err_iomap; 149 } 150 151 writel_relaxed(TIMERn_CTRL_PRESC_1024 | 152 TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | 153 TIMERn_CTRL_MODE_UP, base + TIMERn_CTRL); 154 writel_relaxed(TIMERn_CMD_START, base + TIMERn_CMD); 155 156 ret = clocksource_mmio_init(base + TIMERn_CNT, "efm32 timer", 157 DIV_ROUND_CLOSEST(rate, 1024), 200, 16, 158 clocksource_mmio_readl_up); 159 if (ret) { 160 pr_err("failed to init clocksource (%d)\n", ret); 161 goto err_clocksource_init; 162 } 163 164 return 0; 165 166err_clocksource_init: 167 168 iounmap(base); 169err_iomap: 170 171 clk_disable_unprepare(clk); 172err_clk_enable: 173 174 clk_put(clk); 175err_clk_get: 176 177 return ret; 178} 179 180static int __init efm32_clockevent_init(struct device_node *np) 181{ 182 struct clk *clk; 183 void __iomem *base; 184 unsigned long rate; 185 int irq; 186 int ret; 187 188 clk = of_clk_get(np, 0); 189 if (IS_ERR(clk)) { 190 ret = PTR_ERR(clk); 191 pr_err("failed to get clock for clockevent (%d)\n", ret); 192 goto err_clk_get; 193 } 194 195 ret = clk_prepare_enable(clk); 196 if (ret) { 197 pr_err("failed to enable timer clock for clockevent (%d)\n", 198 ret); 199 goto err_clk_enable; 200 } 201 rate = clk_get_rate(clk); 202 203 base = of_iomap(np, 0); 204 if (!base) { 205 ret = -EADDRNOTAVAIL; 206 pr_err("failed to map registers for clockevent\n"); 207 goto err_iomap; 208 } 209 210 irq = irq_of_parse_and_map(np, 0); 211 if (!irq) { 212 ret = -ENOENT; 213 pr_err("failed to get irq for clockevent\n"); 214 goto err_get_irq; 215 } 216 217 writel_relaxed(TIMERn_IRQ_UF, base + TIMERn_IEN); 218 219 clock_event_ddata.base = base; 220 clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ); 221 222 clockevents_config_and_register(&clock_event_ddata.evtdev, 223 DIV_ROUND_CLOSEST(rate, 1024), 224 0xf, 0xffff); 225 226 ret = request_irq(irq, efm32_clock_event_handler, IRQF_TIMER, 227 "efm32 clockevent", &clock_event_ddata); 228 if (ret) { 229 pr_err("Failed setup irq\n"); 230 goto err_setup_irq; 231 } 232 233 return 0; 234 235err_setup_irq: 236err_get_irq: 237 238 iounmap(base); 239err_iomap: 240 241 clk_disable_unprepare(clk); 242err_clk_enable: 243 244 clk_put(clk); 245err_clk_get: 246 247 return ret; 248} 249 250/* 251 * This function asserts that we have exactly one clocksource and one 252 * clock_event_device in the end. 253 */ 254static int __init efm32_timer_init(struct device_node *np) 255{ 256 static int has_clocksource, has_clockevent; 257 int ret = 0; 258 259 if (!has_clocksource) { 260 ret = efm32_clocksource_init(np); 261 if (!ret) { 262 has_clocksource = 1; 263 return 0; 264 } 265 } 266 267 if (!has_clockevent) { 268 ret = efm32_clockevent_init(np); 269 if (!ret) { 270 has_clockevent = 1; 271 return 0; 272 } 273 } 274 275 return ret; 276} 277TIMER_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init); 278TIMER_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init); 279