1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * 4 * Copyright (C) 2007 Google, Inc. 5 * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved. 6 */ 7 8 #include <linux/clocksource.h> 9 #include <linux/clockchips.h> 10 #include <linux/cpu.h> 11 #include <linux/init.h> 12 #include <linux/interrupt.h> 13 #include <linux/irq.h> 14 #include <linux/io.h> 15 #include <linux/of.h> 16 #include <linux/of_address.h> 17 #include <linux/of_irq.h> 18 #include <linux/sched_clock.h> 19 20 #include <asm/delay.h> 21 22 #define TIMER_MATCH_VAL 0x0000 23 #define TIMER_COUNT_VAL 0x0004 24 #define TIMER_ENABLE 0x0008 25 #define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) 26 #define TIMER_ENABLE_EN BIT(0) 27 #define TIMER_CLEAR 0x000C 28 #define DGT_CLK_CTL 0x10 29 #define DGT_CLK_CTL_DIV_4 0x3 30 #define TIMER_STS_GPT0_CLR_PEND BIT(10) 31 32 #define GPT_HZ 32768 33 34 static void __iomem *event_base; 35 static void __iomem *sts_base; 36 37 static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) 38 { 39 struct clock_event_device *evt = dev_id; 40 /* Stop the timer tick */ 41 if (clockevent_state_oneshot(evt)) { 42 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); 43 ctrl &= ~TIMER_ENABLE_EN; 44 writel_relaxed(ctrl, event_base + TIMER_ENABLE); 45 } 46 evt->event_handler(evt); 47 return IRQ_HANDLED; 48 } 49 50 static int msm_timer_set_next_event(unsigned long cycles, 51 struct clock_event_device *evt) 52 { 53 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); 54 55 ctrl &= ~TIMER_ENABLE_EN; 56 writel_relaxed(ctrl, event_base + TIMER_ENABLE); 57 58 writel_relaxed(ctrl, event_base + TIMER_CLEAR); 59 writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); 60 61 if (sts_base) 62 while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND) 63 cpu_relax(); 64 65 writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); 66 return 0; 67 } 68 69 static int msm_timer_shutdown(struct clock_event_device *evt) 70 { 71 u32 ctrl; 72 73 ctrl = readl_relaxed(event_base + TIMER_ENABLE); 74 ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); 75 writel_relaxed(ctrl, event_base + TIMER_ENABLE); 76 return 0; 77 } 78 79 static struct clock_event_device __percpu *msm_evt; 80 81 static void __iomem *source_base; 82 83 static notrace u64 msm_read_timer_count(struct clocksource *cs) 84 { 85 return readl_relaxed(source_base + TIMER_COUNT_VAL); 86 } 87 88 static struct clocksource msm_clocksource = { 89 .name = "dg_timer", 90 .rating = 300, 91 .read = msm_read_timer_count, 92 .mask = CLOCKSOURCE_MASK(32), 93 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 94 }; 95 96 static int msm_timer_irq; 97 static int msm_timer_has_ppi; 98 99 static int msm_local_timer_starting_cpu(unsigned int cpu) 100 { 101 struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu); 102 int err; 103 104 evt->irq = msm_timer_irq; 105 evt->name = "msm_timer"; 106 evt->features = CLOCK_EVT_FEAT_ONESHOT; 107 evt->rating = 200; 108 evt->set_state_shutdown = msm_timer_shutdown; 109 evt->set_state_oneshot = msm_timer_shutdown; 110 evt->tick_resume = msm_timer_shutdown; 111 evt->set_next_event = msm_timer_set_next_event; 112 evt->cpumask = cpumask_of(cpu); 113 114 clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff); 115 116 if (msm_timer_has_ppi) { 117 enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); 118 } else { 119 err = request_irq(evt->irq, msm_timer_interrupt, 120 IRQF_TIMER | IRQF_NOBALANCING | 121 IRQF_TRIGGER_RISING, "gp_timer", evt); 122 if (err) 123 pr_err("request_irq failed\n"); 124 } 125 126 return 0; 127 } 128 129 static int msm_local_timer_dying_cpu(unsigned int cpu) 130 { 131 struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu); 132 133 disable_percpu_irq(evt->irq); 134 return 0; 135 } 136 137 static u64 notrace msm_sched_clock_read(void) 138 { 139 return msm_clocksource.read(&msm_clocksource); 140 } 141 142 static unsigned long msm_read_current_timer(void) 143 { 144 return msm_clocksource.read(&msm_clocksource); 145 } 146 147 static struct delay_timer msm_delay_timer = { 148 .read_current_timer = msm_read_current_timer, 149 }; 150 151 static int __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, 152 bool percpu) 153 { 154 struct clocksource *cs = &msm_clocksource; 155 int res = 0; 156 157 msm_timer_irq = irq; 158 msm_timer_has_ppi = percpu; 159 160 msm_evt = alloc_percpu(struct clock_event_device); 161 if (!msm_evt) { 162 pr_err("memory allocation failed for clockevents\n"); 163 goto err; 164 } 165 166 if (percpu) 167 res = request_percpu_irq(irq, msm_timer_interrupt, 168 "gp_timer", msm_evt); 169 170 if (res) { 171 pr_err("request_percpu_irq failed\n"); 172 } else { 173 /* Install and invoke hotplug callbacks */ 174 res = cpuhp_setup_state(CPUHP_AP_QCOM_TIMER_STARTING, 175 "clockevents/qcom/timer:starting", 176 msm_local_timer_starting_cpu, 177 msm_local_timer_dying_cpu); 178 if (res) { 179 free_percpu_irq(irq, msm_evt); 180 goto err; 181 } 182 } 183 184 err: 185 writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); 186 res = clocksource_register_hz(cs, dgt_hz); 187 if (res) 188 pr_err("clocksource_register failed\n"); 189 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); 190 msm_delay_timer.freq = dgt_hz; 191 register_current_timer_delay(&msm_delay_timer); 192 193 return res; 194 } 195 196 static int __init msm_dt_timer_init(struct device_node *np) 197 { 198 u32 freq; 199 int irq, ret; 200 struct resource res; 201 u32 percpu_offset; 202 void __iomem *base; 203 void __iomem *cpu0_base; 204 205 base = of_iomap(np, 0); 206 if (!base) { 207 pr_err("Failed to map event base\n"); 208 return -ENXIO; 209 } 210 211 /* We use GPT0 for the clockevent */ 212 irq = irq_of_parse_and_map(np, 1); 213 if (irq <= 0) { 214 pr_err("Can't get irq\n"); 215 return -EINVAL; 216 } 217 218 /* We use CPU0's DGT for the clocksource */ 219 if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) 220 percpu_offset = 0; 221 222 ret = of_address_to_resource(np, 0, &res); 223 if (ret) { 224 pr_err("Failed to parse DGT resource\n"); 225 return ret; 226 } 227 228 cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res)); 229 if (!cpu0_base) { 230 pr_err("Failed to map source base\n"); 231 return -EINVAL; 232 } 233 234 if (of_property_read_u32(np, "clock-frequency", &freq)) { 235 iounmap(cpu0_base); 236 pr_err("Unknown frequency\n"); 237 return -EINVAL; 238 } 239 240 event_base = base + 0x4; 241 sts_base = base + 0x88; 242 source_base = cpu0_base + 0x24; 243 freq /= 4; 244 writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); 245 246 ret = msm_timer_init(freq, 32, irq, !!percpu_offset); 247 if (ret) 248 iounmap(cpu0_base); 249 250 return ret; 251 } 252 TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); 253 TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); 254