0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <linux/kernel.h>
0038 #include <linux/init.h>
0039 #include <linux/delay.h>
0040 #include <linux/interrupt.h>
0041 #include <linux/sched.h>
0042 #include <linux/spinlock.h>
0043 #include <linux/err.h>
0044 #include <linux/clk.h>
0045 #include <linux/clocksource.h>
0046 #include <linux/clockchips.h>
0047 #include <linux/io.h>
0048 #include <linux/sched_clock.h>
0049
0050 #include <asm/irq.h>
0051 #include <asm/mach/irq.h>
0052 #include <asm/mach/time.h>
0053
0054 #include "hardware.h"
0055 #include "common.h"
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 #define OMAP1_32K_TIMER_BASE 0xfffb9000
0071 #define OMAP1_32KSYNC_TIMER_BASE 0xfffbc400
0072 #define OMAP1_32K_TIMER_CR 0x08
0073 #define OMAP1_32K_TIMER_TVR 0x00
0074 #define OMAP1_32K_TIMER_TCR 0x04
0075
0076 #define OMAP_32K_TICKS_PER_SEC (32768)
0077
0078
0079
0080
0081
0082 #define OMAP_32K_TIMER_TICK_PERIOD ((OMAP_32K_TICKS_PER_SEC / HZ) - 1)
0083
0084 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
0085 (((nr_jiffies) * (clock_rate)) / HZ)
0086
0087 static inline void omap_32k_timer_write(int val, int reg)
0088 {
0089 omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
0090 }
0091
0092 static inline void omap_32k_timer_start(unsigned long load_val)
0093 {
0094 if (!load_val)
0095 load_val = 1;
0096 omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
0097 omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
0098 }
0099
0100 static inline void omap_32k_timer_stop(void)
0101 {
0102 omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
0103 }
0104
0105 #define omap_32k_timer_ack_irq()
0106
0107 static int omap_32k_timer_set_next_event(unsigned long delta,
0108 struct clock_event_device *dev)
0109 {
0110 omap_32k_timer_start(delta);
0111
0112 return 0;
0113 }
0114
0115 static int omap_32k_timer_shutdown(struct clock_event_device *evt)
0116 {
0117 omap_32k_timer_stop();
0118 return 0;
0119 }
0120
0121 static int omap_32k_timer_set_periodic(struct clock_event_device *evt)
0122 {
0123 omap_32k_timer_stop();
0124 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
0125 return 0;
0126 }
0127
0128 static struct clock_event_device clockevent_32k_timer = {
0129 .name = "32k-timer",
0130 .features = CLOCK_EVT_FEAT_PERIODIC |
0131 CLOCK_EVT_FEAT_ONESHOT,
0132 .set_next_event = omap_32k_timer_set_next_event,
0133 .set_state_shutdown = omap_32k_timer_shutdown,
0134 .set_state_periodic = omap_32k_timer_set_periodic,
0135 .set_state_oneshot = omap_32k_timer_shutdown,
0136 .tick_resume = omap_32k_timer_shutdown,
0137 };
0138
0139 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
0140 {
0141 struct clock_event_device *evt = &clockevent_32k_timer;
0142 omap_32k_timer_ack_irq();
0143
0144 evt->event_handler(evt);
0145
0146 return IRQ_HANDLED;
0147 }
0148
0149 static __init void omap_init_32k_timer(void)
0150 {
0151 if (request_irq(INT_OS_TIMER, omap_32k_timer_interrupt,
0152 IRQF_TIMER | IRQF_IRQPOLL, "32KHz timer", NULL))
0153 pr_err("Failed to request irq %d(32KHz timer)\n", INT_OS_TIMER);
0154
0155 clockevent_32k_timer.cpumask = cpumask_of(0);
0156 clockevents_config_and_register(&clockevent_32k_timer,
0157 OMAP_32K_TICKS_PER_SEC, 1, 0xfffffffe);
0158 }
0159
0160
0161 #define OMAP2_32KSYNCNT_REV_OFF 0x0
0162 #define OMAP2_32KSYNCNT_REV_SCHEME (0x3 << 30)
0163 #define OMAP2_32KSYNCNT_CR_OFF_LOW 0x10
0164 #define OMAP2_32KSYNCNT_CR_OFF_HIGH 0x30
0165
0166
0167
0168
0169
0170
0171
0172 static void __iomem *sync32k_cnt_reg;
0173
0174 static u64 notrace omap_32k_read_sched_clock(void)
0175 {
0176 return sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0;
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186 static struct timespec64 persistent_ts;
0187 static cycles_t cycles;
0188 static unsigned int persistent_mult, persistent_shift;
0189
0190 static void omap_read_persistent_clock64(struct timespec64 *ts)
0191 {
0192 unsigned long long nsecs;
0193 cycles_t last_cycles;
0194
0195 last_cycles = cycles;
0196 cycles = sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0;
0197
0198 nsecs = clocksource_cyc2ns(cycles - last_cycles,
0199 persistent_mult, persistent_shift);
0200
0201 timespec64_add_ns(&persistent_ts, nsecs);
0202
0203 *ts = persistent_ts;
0204 }
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 static int __init omap_init_clocksource_32k(void __iomem *vbase)
0216 {
0217 int ret;
0218
0219
0220
0221
0222
0223
0224
0225 if (readl_relaxed(vbase + OMAP2_32KSYNCNT_REV_OFF) &
0226 OMAP2_32KSYNCNT_REV_SCHEME)
0227 sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_HIGH;
0228 else
0229 sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_LOW;
0230
0231
0232
0233
0234
0235 clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
0236 32768, NSEC_PER_SEC, 120000);
0237
0238 ret = clocksource_mmio_init(sync32k_cnt_reg, "32k_counter", 32768,
0239 250, 32, clocksource_mmio_readl_up);
0240 if (ret) {
0241 pr_err("32k_counter: can't register clocksource\n");
0242 return ret;
0243 }
0244
0245 sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
0246 register_persistent_clock(omap_read_persistent_clock64);
0247 pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
0248
0249 return 0;
0250 }
0251
0252
0253
0254
0255
0256
0257 int __init omap_32k_timer_init(void)
0258 {
0259 int ret = -ENODEV;
0260
0261 if (cpu_is_omap16xx()) {
0262 void __iomem *base;
0263 struct clk *sync32k_ick;
0264
0265 base = ioremap(OMAP1_32KSYNC_TIMER_BASE, SZ_1K);
0266 if (!base) {
0267 pr_err("32k_counter: failed to map base addr\n");
0268 return -ENODEV;
0269 }
0270
0271 sync32k_ick = clk_get(NULL, "omap_32ksync_ick");
0272 if (!IS_ERR(sync32k_ick))
0273 clk_prepare_enable(sync32k_ick);
0274
0275 ret = omap_init_clocksource_32k(base);
0276 }
0277
0278 if (!ret)
0279 omap_init_32k_timer();
0280
0281 return ret;
0282 }