1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2017 Spreadtrum Communications Inc. 4 */ 5 6 #include <linux/init.h> 7 #include <linux/interrupt.h> 8 9 #include "timer-of.h" 10 11 #define TIMER_NAME "sprd_timer" 12 13 #define TIMER_LOAD_LO 0x0 14 #define TIMER_LOAD_HI 0x4 15 #define TIMER_VALUE_LO 0x8 16 #define TIMER_VALUE_HI 0xc 17 18 #define TIMER_CTL 0x10 19 #define TIMER_CTL_PERIOD_MODE BIT(0) 20 #define TIMER_CTL_ENABLE BIT(1) 21 #define TIMER_CTL_64BIT_WIDTH BIT(16) 22 23 #define TIMER_INT 0x14 24 #define TIMER_INT_EN BIT(0) 25 #define TIMER_INT_RAW_STS BIT(1) 26 #define TIMER_INT_MASK_STS BIT(2) 27 #define TIMER_INT_CLR BIT(3) 28 29 #define TIMER_VALUE_SHDW_LO 0x18 30 #define TIMER_VALUE_SHDW_HI 0x1c 31 32 #define TIMER_VALUE_LO_MASK GENMASK(31, 0) 33 #define TIMER_VALUE_HI_MASK GENMASK(31, 0) 34 35 static void sprd_timer_enable(void __iomem *base, u32 flag) 36 { 37 u32 val = readl_relaxed(base + TIMER_CTL); 38 39 val |= TIMER_CTL_ENABLE; 40 if (flag & TIMER_CTL_64BIT_WIDTH) 41 val |= TIMER_CTL_64BIT_WIDTH; 42 else 43 val &= ~TIMER_CTL_64BIT_WIDTH; 44 45 if (flag & TIMER_CTL_PERIOD_MODE) 46 val |= TIMER_CTL_PERIOD_MODE; 47 else 48 val &= ~TIMER_CTL_PERIOD_MODE; 49 50 writel_relaxed(val, base + TIMER_CTL); 51 } 52 53 static void sprd_timer_disable(void __iomem *base) 54 { 55 u32 val = readl_relaxed(base + TIMER_CTL); 56 57 val &= ~TIMER_CTL_ENABLE; 58 writel_relaxed(val, base + TIMER_CTL); 59 } 60 61 static void sprd_timer_update_counter(void __iomem *base, unsigned long cycles) 62 { 63 writel_relaxed(cycles & TIMER_VALUE_LO_MASK, base + TIMER_LOAD_LO); 64 writel_relaxed(0, base + TIMER_LOAD_HI); 65 } 66 67 static void sprd_timer_enable_interrupt(void __iomem *base) 68 { 69 writel_relaxed(TIMER_INT_EN, base + TIMER_INT); 70 } 71 72 static void sprd_timer_clear_interrupt(void __iomem *base) 73 { 74 u32 val = readl_relaxed(base + TIMER_INT); 75 76 val |= TIMER_INT_CLR; 77 writel_relaxed(val, base + TIMER_INT); 78 } 79 80 static int sprd_timer_set_next_event(unsigned long cycles, 81 struct clock_event_device *ce) 82 { 83 struct timer_of *to = to_timer_of(ce); 84 85 sprd_timer_disable(timer_of_base(to)); 86 sprd_timer_update_counter(timer_of_base(to), cycles); 87 sprd_timer_enable(timer_of_base(to), 0); 88 89 return 0; 90 } 91 92 static int sprd_timer_set_periodic(struct clock_event_device *ce) 93 { 94 struct timer_of *to = to_timer_of(ce); 95 96 sprd_timer_disable(timer_of_base(to)); 97 sprd_timer_update_counter(timer_of_base(to), timer_of_period(to)); 98 sprd_timer_enable(timer_of_base(to), TIMER_CTL_PERIOD_MODE); 99 100 return 0; 101 } 102 103 static int sprd_timer_shutdown(struct clock_event_device *ce) 104 { 105 struct timer_of *to = to_timer_of(ce); 106 107 sprd_timer_disable(timer_of_base(to)); 108 return 0; 109 } 110 111 static irqreturn_t sprd_timer_interrupt(int irq, void *dev_id) 112 { 113 struct clock_event_device *ce = (struct clock_event_device *)dev_id; 114 struct timer_of *to = to_timer_of(ce); 115 116 sprd_timer_clear_interrupt(timer_of_base(to)); 117 118 if (clockevent_state_oneshot(ce)) 119 sprd_timer_disable(timer_of_base(to)); 120 121 ce->event_handler(ce); 122 return IRQ_HANDLED; 123 } 124 125 static struct timer_of to = { 126 .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, 127 128 .clkevt = { 129 .name = TIMER_NAME, 130 .rating = 300, 131 .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_PERIODIC | 132 CLOCK_EVT_FEAT_ONESHOT, 133 .set_state_shutdown = sprd_timer_shutdown, 134 .set_state_periodic = sprd_timer_set_periodic, 135 .set_next_event = sprd_timer_set_next_event, 136 .cpumask = cpu_possible_mask, 137 }, 138 139 .of_irq = { 140 .handler = sprd_timer_interrupt, 141 .flags = IRQF_TIMER | IRQF_IRQPOLL, 142 }, 143 }; 144 145 static int __init sprd_timer_init(struct device_node *np) 146 { 147 int ret; 148 149 ret = timer_of_init(np, &to); 150 if (ret) 151 return ret; 152 153 sprd_timer_enable_interrupt(timer_of_base(&to)); 154 clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 155 1, UINT_MAX); 156 157 return 0; 158 } 159 160 static struct timer_of suspend_to = { 161 .flags = TIMER_OF_BASE | TIMER_OF_CLOCK, 162 }; 163 164 static u64 sprd_suspend_timer_read(struct clocksource *cs) 165 { 166 u32 lo, hi; 167 168 do { 169 hi = readl_relaxed(timer_of_base(&suspend_to) + 170 TIMER_VALUE_SHDW_HI); 171 lo = readl_relaxed(timer_of_base(&suspend_to) + 172 TIMER_VALUE_SHDW_LO); 173 } while (hi != readl_relaxed(timer_of_base(&suspend_to) + TIMER_VALUE_SHDW_HI)); 174 175 return ~(((u64)hi << 32) | lo); 176 } 177 178 static int sprd_suspend_timer_enable(struct clocksource *cs) 179 { 180 writel_relaxed(TIMER_VALUE_LO_MASK, 181 timer_of_base(&suspend_to) + TIMER_LOAD_LO); 182 writel_relaxed(TIMER_VALUE_HI_MASK, 183 timer_of_base(&suspend_to) + TIMER_LOAD_HI); 184 sprd_timer_enable(timer_of_base(&suspend_to), 185 TIMER_CTL_PERIOD_MODE|TIMER_CTL_64BIT_WIDTH); 186 187 return 0; 188 } 189 190 static void sprd_suspend_timer_disable(struct clocksource *cs) 191 { 192 sprd_timer_disable(timer_of_base(&suspend_to)); 193 } 194 195 static struct clocksource suspend_clocksource = { 196 .name = "sprd_suspend_timer", 197 .rating = 200, 198 .read = sprd_suspend_timer_read, 199 .enable = sprd_suspend_timer_enable, 200 .disable = sprd_suspend_timer_disable, 201 .mask = CLOCKSOURCE_MASK(64), 202 .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, 203 }; 204 205 static int __init sprd_suspend_timer_init(struct device_node *np) 206 { 207 int ret; 208 209 ret = timer_of_init(np, &suspend_to); 210 if (ret) 211 return ret; 212 213 clocksource_register_hz(&suspend_clocksource, 214 timer_of_rate(&suspend_to)); 215 216 return 0; 217 } 218 219 TIMER_OF_DECLARE(sc9860_timer, "sprd,sc9860-timer", sprd_timer_init); 220 TIMER_OF_DECLARE(sc9860_persistent_timer, "sprd,sc9860-suspend-timer", 221 sprd_suspend_timer_init); 222