1 /* 2 * Mediatek SoCs General-Purpose Timer handling. 3 * 4 * Copyright (C) 2014 Matthias Brugger 5 * 6 * Matthias Brugger <[email protected]> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20 21 #include <linux/clk.h> 22 #include <linux/clockchips.h> 23 #include <linux/interrupt.h> 24 #include <linux/irq.h> 25 #include <linux/irqreturn.h> 26 #include <linux/of.h> 27 #include <linux/of_address.h> 28 #include <linux/of_irq.h> 29 #include <linux/sched_clock.h> 30 #include <linux/slab.h> 31 32 #define TIMER_CLK_EVT (1) 33 #define TIMER_CLK_SRC (2) 34 35 #define TIMER_SYNC_TICKS (3) 36 37 /* gpt */ 38 #define GPT_IRQ_EN_REG 0x00 39 #define GPT_IRQ_ENABLE(val) BIT((val) - 1) 40 #define GPT_IRQ_ACK_REG 0x08 41 #define GPT_IRQ_ACK(val) BIT((val) - 1) 42 43 #define GPT_CTRL_REG(val) (0x10 * (val)) 44 #define GPT_CTRL_OP(val) (((val) & 0x3) << 4) 45 #define GPT_CTRL_OP_ONESHOT (0) 46 #define GPT_CTRL_OP_REPEAT (1) 47 #define GPT_CTRL_OP_FREERUN (3) 48 #define GPT_CTRL_CLEAR (2) 49 #define GPT_CTRL_ENABLE (1) 50 #define GPT_CTRL_DISABLE (0) 51 52 #define GPT_CLK_REG(val) (0x04 + (0x10 * (val))) 53 #define GPT_CLK_SRC(val) (((val) & 0x1) << 4) 54 #define GPT_CLK_SRC_SYS13M (0) 55 #define GPT_CLK_SRC_RTC32K (1) 56 #define GPT_CLK_DIV1 (0x0) 57 #define GPT_CLK_DIV2 (0x1) 58 59 #define GPT_CNT_REG(val) (0x08 + (0x10 * (val))) 60 #define GPT_CMP_REG(val) (0x0C + (0x10 * (val))) 61 62 struct mtk_clock_event_device { 63 void __iomem *gpt_base; 64 u32 ticks_per_jiffy; 65 struct clock_event_device dev; 66 }; 67 68 static void __iomem *gpt_sched_reg __read_mostly; 69 70 static u64 notrace mtk_gpt_read_sched_clock(void) 71 { 72 return readl_relaxed(gpt_sched_reg); 73 } 74 75 static inline struct mtk_clock_event_device *to_mtk_clk( 76 struct clock_event_device *c) 77 { 78 return container_of(c, struct mtk_clock_event_device, dev); 79 } 80 81 static void mtk_gpt_clkevt_time_stop(struct mtk_clock_event_device *evt, u8 timer) 82 { 83 u32 val; 84 85 val = readl(evt->gpt_base + GPT_CTRL_REG(timer)); 86 writel(val & ~GPT_CTRL_ENABLE, evt->gpt_base + 87 GPT_CTRL_REG(timer)); 88 } 89 90 static void mtk_gpt_clkevt_time_setup(struct mtk_clock_event_device *evt, 91 unsigned long delay, u8 timer) 92 { 93 writel(delay, evt->gpt_base + GPT_CMP_REG(timer)); 94 } 95 96 static void mtk_gpt_clkevt_time_start(struct mtk_clock_event_device *evt, 97 bool periodic, u8 timer) 98 { 99 u32 val; 100 101 /* Acknowledge interrupt */ 102 writel(GPT_IRQ_ACK(timer), evt->gpt_base + GPT_IRQ_ACK_REG); 103 104 val = readl(evt->gpt_base + GPT_CTRL_REG(timer)); 105 106 /* Clear 2 bit timer operation mode field */ 107 val &= ~GPT_CTRL_OP(0x3); 108 109 if (periodic) 110 val |= GPT_CTRL_OP(GPT_CTRL_OP_REPEAT); 111 else 112 val |= GPT_CTRL_OP(GPT_CTRL_OP_ONESHOT); 113 114 writel(val | GPT_CTRL_ENABLE | GPT_CTRL_CLEAR, 115 evt->gpt_base + GPT_CTRL_REG(timer)); 116 } 117 118 static int mtk_gpt_clkevt_shutdown(struct clock_event_device *clk) 119 { 120 mtk_gpt_clkevt_time_stop(to_mtk_clk(clk), TIMER_CLK_EVT); 121 return 0; 122 } 123 124 static int mtk_gpt_clkevt_set_periodic(struct clock_event_device *clk) 125 { 126 struct mtk_clock_event_device *evt = to_mtk_clk(clk); 127 128 mtk_gpt_clkevt_time_stop(evt, TIMER_CLK_EVT); 129 mtk_gpt_clkevt_time_setup(evt, evt->ticks_per_jiffy, TIMER_CLK_EVT); 130 mtk_gpt_clkevt_time_start(evt, true, TIMER_CLK_EVT); 131 return 0; 132 } 133 134 static int mtk_gpt_clkevt_next_event(unsigned long event, 135 struct clock_event_device *clk) 136 { 137 struct mtk_clock_event_device *evt = to_mtk_clk(clk); 138 139 mtk_gpt_clkevt_time_stop(evt, TIMER_CLK_EVT); 140 mtk_gpt_clkevt_time_setup(evt, event, TIMER_CLK_EVT); 141 mtk_gpt_clkevt_time_start(evt, false, TIMER_CLK_EVT); 142 143 return 0; 144 } 145 146 static irqreturn_t mtk_gpt_interrupt(int irq, void *dev_id) 147 { 148 struct mtk_clock_event_device *evt = dev_id; 149 150 /* Acknowledge timer0 irq */ 151 writel(GPT_IRQ_ACK(TIMER_CLK_EVT), evt->gpt_base + GPT_IRQ_ACK_REG); 152 evt->dev.event_handler(&evt->dev); 153 154 return IRQ_HANDLED; 155 } 156 157 static void 158 __init mtk_gpt_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option) 159 { 160 writel(GPT_CTRL_CLEAR | GPT_CTRL_DISABLE, 161 evt->gpt_base + GPT_CTRL_REG(timer)); 162 163 writel(GPT_CLK_SRC(GPT_CLK_SRC_SYS13M) | GPT_CLK_DIV1, 164 evt->gpt_base + GPT_CLK_REG(timer)); 165 166 writel(0x0, evt->gpt_base + GPT_CMP_REG(timer)); 167 168 writel(GPT_CTRL_OP(option) | GPT_CTRL_ENABLE, 169 evt->gpt_base + GPT_CTRL_REG(timer)); 170 } 171 172 static void mtk_gpt_enable_irq(struct mtk_clock_event_device *evt, u8 timer) 173 { 174 u32 val; 175 176 /* Disable all interrupts */ 177 writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG); 178 179 /* Acknowledge all spurious pending interrupts */ 180 writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG); 181 182 val = readl(evt->gpt_base + GPT_IRQ_EN_REG); 183 writel(val | GPT_IRQ_ENABLE(timer), 184 evt->gpt_base + GPT_IRQ_EN_REG); 185 } 186 187 static int __init mtk_gpt_init(struct device_node *node) 188 { 189 struct mtk_clock_event_device *evt; 190 struct resource res; 191 unsigned long rate = 0; 192 struct clk *clk; 193 194 evt = kzalloc(sizeof(*evt), GFP_KERNEL); 195 if (!evt) 196 return -ENOMEM; 197 198 evt->dev.name = "mtk_tick"; 199 evt->dev.rating = 300; 200 evt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 201 evt->dev.set_state_shutdown = mtk_gpt_clkevt_shutdown; 202 evt->dev.set_state_periodic = mtk_gpt_clkevt_set_periodic; 203 evt->dev.set_state_oneshot = mtk_gpt_clkevt_shutdown; 204 evt->dev.tick_resume = mtk_gpt_clkevt_shutdown; 205 evt->dev.set_next_event = mtk_gpt_clkevt_next_event; 206 evt->dev.cpumask = cpu_possible_mask; 207 208 evt->gpt_base = of_io_request_and_map(node, 0, "mtk-timer-gpt"); 209 if (IS_ERR(evt->gpt_base)) { 210 pr_err("Can't get resource\n"); 211 goto err_kzalloc; 212 } 213 214 evt->dev.irq = irq_of_parse_and_map(node, 0); 215 if (evt->dev.irq <= 0) { 216 pr_err("Can't parse IRQ\n"); 217 goto err_mem; 218 } 219 220 clk = of_clk_get(node, 0); 221 if (IS_ERR(clk)) { 222 pr_err("Can't get timer clock\n"); 223 goto err_irq; 224 } 225 226 if (clk_prepare_enable(clk)) { 227 pr_err("Can't prepare clock\n"); 228 goto err_clk_put; 229 } 230 rate = clk_get_rate(clk); 231 232 if (request_irq(evt->dev.irq, mtk_gpt_interrupt, 233 IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) { 234 pr_err("failed to setup irq %d\n", evt->dev.irq); 235 goto err_clk_disable; 236 } 237 238 evt->ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); 239 240 /* Configure clock source */ 241 mtk_gpt_setup(evt, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN); 242 clocksource_mmio_init(evt->gpt_base + GPT_CNT_REG(TIMER_CLK_SRC), 243 node->name, rate, 300, 32, clocksource_mmio_readl_up); 244 gpt_sched_reg = evt->gpt_base + GPT_CNT_REG(TIMER_CLK_SRC); 245 sched_clock_register(mtk_gpt_read_sched_clock, 32, rate); 246 247 /* Configure clock event */ 248 mtk_gpt_setup(evt, TIMER_CLK_EVT, GPT_CTRL_OP_REPEAT); 249 clockevents_config_and_register(&evt->dev, rate, TIMER_SYNC_TICKS, 250 0xffffffff); 251 252 mtk_gpt_enable_irq(evt, TIMER_CLK_EVT); 253 254 return 0; 255 256 err_clk_disable: 257 clk_disable_unprepare(clk); 258 err_clk_put: 259 clk_put(clk); 260 err_irq: 261 irq_dispose_mapping(evt->dev.irq); 262 err_mem: 263 iounmap(evt->gpt_base); 264 of_address_to_resource(node, 0, &res); 265 release_mem_region(res.start, resource_size(&res)); 266 err_kzalloc: 267 kfree(evt); 268 269 return -EINVAL; 270 } 271 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init); 272