0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/dw_apb_timer.h>
0011 #include <linux/delay.h>
0012 #include <linux/kernel.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/irq.h>
0015 #include <linux/io.h>
0016 #include <linux/slab.h>
0017
0018 #define APBT_MIN_PERIOD 4
0019 #define APBT_MIN_DELTA_USEC 200
0020
0021 #define APBTMR_N_LOAD_COUNT 0x00
0022 #define APBTMR_N_CURRENT_VALUE 0x04
0023 #define APBTMR_N_CONTROL 0x08
0024 #define APBTMR_N_EOI 0x0c
0025 #define APBTMR_N_INT_STATUS 0x10
0026
0027 #define APBTMRS_INT_STATUS 0xa0
0028 #define APBTMRS_EOI 0xa4
0029 #define APBTMRS_RAW_INT_STATUS 0xa8
0030 #define APBTMRS_COMP_VERSION 0xac
0031
0032 #define APBTMR_CONTROL_ENABLE (1 << 0)
0033
0034 #define APBTMR_CONTROL_MODE_PERIODIC (1 << 1)
0035 #define APBTMR_CONTROL_INT (1 << 2)
0036
0037 static inline struct dw_apb_clock_event_device *
0038 ced_to_dw_apb_ced(struct clock_event_device *evt)
0039 {
0040 return container_of(evt, struct dw_apb_clock_event_device, ced);
0041 }
0042
0043 static inline struct dw_apb_clocksource *
0044 clocksource_to_dw_apb_clocksource(struct clocksource *cs)
0045 {
0046 return container_of(cs, struct dw_apb_clocksource, cs);
0047 }
0048
0049 static inline u32 apbt_readl(struct dw_apb_timer *timer, unsigned long offs)
0050 {
0051 return readl(timer->base + offs);
0052 }
0053
0054 static inline void apbt_writel(struct dw_apb_timer *timer, u32 val,
0055 unsigned long offs)
0056 {
0057 writel(val, timer->base + offs);
0058 }
0059
0060 static inline u32 apbt_readl_relaxed(struct dw_apb_timer *timer, unsigned long offs)
0061 {
0062 return readl_relaxed(timer->base + offs);
0063 }
0064
0065 static inline void apbt_writel_relaxed(struct dw_apb_timer *timer, u32 val,
0066 unsigned long offs)
0067 {
0068 writel_relaxed(val, timer->base + offs);
0069 }
0070
0071 static void apbt_disable_int(struct dw_apb_timer *timer)
0072 {
0073 u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL);
0074
0075 ctrl |= APBTMR_CONTROL_INT;
0076 apbt_writel(timer, ctrl, APBTMR_N_CONTROL);
0077 }
0078
0079
0080
0081
0082
0083
0084 void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced)
0085 {
0086 disable_irq(dw_ced->timer.irq);
0087 apbt_disable_int(&dw_ced->timer);
0088 }
0089
0090 static void apbt_eoi(struct dw_apb_timer *timer)
0091 {
0092 apbt_readl_relaxed(timer, APBTMR_N_EOI);
0093 }
0094
0095 static irqreturn_t dw_apb_clockevent_irq(int irq, void *data)
0096 {
0097 struct clock_event_device *evt = data;
0098 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
0099
0100 if (!evt->event_handler) {
0101 pr_info("Spurious APBT timer interrupt %d\n", irq);
0102 return IRQ_NONE;
0103 }
0104
0105 if (dw_ced->eoi)
0106 dw_ced->eoi(&dw_ced->timer);
0107
0108 evt->event_handler(evt);
0109 return IRQ_HANDLED;
0110 }
0111
0112 static void apbt_enable_int(struct dw_apb_timer *timer)
0113 {
0114 u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL);
0115
0116 apbt_readl(timer, APBTMR_N_EOI);
0117 ctrl &= ~APBTMR_CONTROL_INT;
0118 apbt_writel(timer, ctrl, APBTMR_N_CONTROL);
0119 }
0120
0121 static int apbt_shutdown(struct clock_event_device *evt)
0122 {
0123 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
0124 u32 ctrl;
0125
0126 pr_debug("%s CPU %d state=shutdown\n", __func__,
0127 cpumask_first(evt->cpumask));
0128
0129 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
0130 ctrl &= ~APBTMR_CONTROL_ENABLE;
0131 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0132 return 0;
0133 }
0134
0135 static int apbt_set_oneshot(struct clock_event_device *evt)
0136 {
0137 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
0138 u32 ctrl;
0139
0140 pr_debug("%s CPU %d state=oneshot\n", __func__,
0141 cpumask_first(evt->cpumask));
0142
0143 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
0144
0145
0146
0147
0148
0149 ctrl &= ~APBTMR_CONTROL_ENABLE;
0150 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
0151
0152 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0153
0154 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0155
0156
0157
0158
0159
0160 apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT);
0161 ctrl &= ~APBTMR_CONTROL_INT;
0162 ctrl |= APBTMR_CONTROL_ENABLE;
0163 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0164 return 0;
0165 }
0166
0167 static int apbt_set_periodic(struct clock_event_device *evt)
0168 {
0169 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
0170 unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ);
0171 u32 ctrl;
0172
0173 pr_debug("%s CPU %d state=periodic\n", __func__,
0174 cpumask_first(evt->cpumask));
0175
0176 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
0177 ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
0178 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0179
0180
0181
0182
0183 ctrl &= ~APBTMR_CONTROL_ENABLE;
0184 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0185 udelay(1);
0186 pr_debug("Setting clock period %lu for HZ %d\n", period, HZ);
0187 apbt_writel(&dw_ced->timer, period, APBTMR_N_LOAD_COUNT);
0188 ctrl |= APBTMR_CONTROL_ENABLE;
0189 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0190 return 0;
0191 }
0192
0193 static int apbt_resume(struct clock_event_device *evt)
0194 {
0195 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
0196
0197 pr_debug("%s CPU %d state=resume\n", __func__,
0198 cpumask_first(evt->cpumask));
0199
0200 apbt_enable_int(&dw_ced->timer);
0201 return 0;
0202 }
0203
0204 static int apbt_next_event(unsigned long delta,
0205 struct clock_event_device *evt)
0206 {
0207 u32 ctrl;
0208 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
0209
0210
0211 ctrl = apbt_readl_relaxed(&dw_ced->timer, APBTMR_N_CONTROL);
0212 ctrl &= ~APBTMR_CONTROL_ENABLE;
0213 apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0214
0215 apbt_writel_relaxed(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT);
0216 ctrl |= APBTMR_CONTROL_ENABLE;
0217 apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
0218
0219 return 0;
0220 }
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 struct dw_apb_clock_event_device *
0241 dw_apb_clockevent_init(int cpu, const char *name, unsigned rating,
0242 void __iomem *base, int irq, unsigned long freq)
0243 {
0244 struct dw_apb_clock_event_device *dw_ced =
0245 kzalloc(sizeof(*dw_ced), GFP_KERNEL);
0246 int err;
0247
0248 if (!dw_ced)
0249 return NULL;
0250
0251 dw_ced->timer.base = base;
0252 dw_ced->timer.irq = irq;
0253 dw_ced->timer.freq = freq;
0254
0255 clockevents_calc_mult_shift(&dw_ced->ced, freq, APBT_MIN_PERIOD);
0256 dw_ced->ced.max_delta_ns = clockevent_delta2ns(0x7fffffff,
0257 &dw_ced->ced);
0258 dw_ced->ced.max_delta_ticks = 0x7fffffff;
0259 dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced);
0260 dw_ced->ced.min_delta_ticks = 5000;
0261 dw_ced->ced.cpumask = cpu < 0 ? cpu_possible_mask : cpumask_of(cpu);
0262 dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC |
0263 CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
0264 dw_ced->ced.set_state_shutdown = apbt_shutdown;
0265 dw_ced->ced.set_state_periodic = apbt_set_periodic;
0266 dw_ced->ced.set_state_oneshot = apbt_set_oneshot;
0267 dw_ced->ced.set_state_oneshot_stopped = apbt_shutdown;
0268 dw_ced->ced.tick_resume = apbt_resume;
0269 dw_ced->ced.set_next_event = apbt_next_event;
0270 dw_ced->ced.irq = dw_ced->timer.irq;
0271 dw_ced->ced.rating = rating;
0272 dw_ced->ced.name = name;
0273
0274 dw_ced->eoi = apbt_eoi;
0275 err = request_irq(irq, dw_apb_clockevent_irq,
0276 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
0277 dw_ced->ced.name, &dw_ced->ced);
0278 if (err) {
0279 pr_err("failed to request timer irq\n");
0280 kfree(dw_ced);
0281 dw_ced = NULL;
0282 }
0283
0284 return dw_ced;
0285 }
0286
0287
0288
0289
0290
0291
0292 void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced)
0293 {
0294 enable_irq(dw_ced->timer.irq);
0295 }
0296
0297
0298
0299
0300
0301
0302 void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced)
0303 {
0304 free_irq(dw_ced->timer.irq, &dw_ced->ced);
0305 }
0306
0307
0308
0309
0310
0311
0312 void dw_apb_clockevent_register(struct dw_apb_clock_event_device *dw_ced)
0313 {
0314 apbt_writel(&dw_ced->timer, 0, APBTMR_N_CONTROL);
0315 clockevents_register_device(&dw_ced->ced);
0316 apbt_enable_int(&dw_ced->timer);
0317 }
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs)
0328 {
0329
0330
0331
0332
0333 u32 ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL);
0334
0335 ctrl &= ~APBTMR_CONTROL_ENABLE;
0336 apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL);
0337 apbt_writel(&dw_cs->timer, ~0, APBTMR_N_LOAD_COUNT);
0338
0339 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
0340 ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
0341 apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL);
0342
0343 dw_apb_clocksource_read(dw_cs);
0344 }
0345
0346 static u64 __apbt_read_clocksource(struct clocksource *cs)
0347 {
0348 u32 current_count;
0349 struct dw_apb_clocksource *dw_cs =
0350 clocksource_to_dw_apb_clocksource(cs);
0351
0352 current_count = apbt_readl_relaxed(&dw_cs->timer,
0353 APBTMR_N_CURRENT_VALUE);
0354
0355 return (u64)~current_count;
0356 }
0357
0358 static void apbt_restart_clocksource(struct clocksource *cs)
0359 {
0360 struct dw_apb_clocksource *dw_cs =
0361 clocksource_to_dw_apb_clocksource(cs);
0362
0363 dw_apb_clocksource_start(dw_cs);
0364 }
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378 struct dw_apb_clocksource *
0379 dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base,
0380 unsigned long freq)
0381 {
0382 struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL);
0383
0384 if (!dw_cs)
0385 return NULL;
0386
0387 dw_cs->timer.base = base;
0388 dw_cs->timer.freq = freq;
0389 dw_cs->cs.name = name;
0390 dw_cs->cs.rating = rating;
0391 dw_cs->cs.read = __apbt_read_clocksource;
0392 dw_cs->cs.mask = CLOCKSOURCE_MASK(32);
0393 dw_cs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
0394 dw_cs->cs.resume = apbt_restart_clocksource;
0395
0396 return dw_cs;
0397 }
0398
0399
0400
0401
0402
0403
0404 void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs)
0405 {
0406 clocksource_register_hz(&dw_cs->cs, dw_cs->timer.freq);
0407 }
0408
0409
0410
0411
0412
0413
0414 u64 dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs)
0415 {
0416 return (u64)~apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE);
0417 }