1d865bea4SRalf Baechle /* 2d865bea4SRalf Baechle * i8253.c 8253/PIT functions 3d865bea4SRalf Baechle * 4d865bea4SRalf Baechle */ 5d865bea4SRalf Baechle #include <linux/clockchips.h> 6d865bea4SRalf Baechle #include <linux/init.h> 7d865bea4SRalf Baechle #include <linux/interrupt.h> 8d865bea4SRalf Baechle #include <linux/jiffies.h> 9d865bea4SRalf Baechle #include <linux/module.h> 10631330f5SRalf Baechle #include <linux/smp.h> 11d865bea4SRalf Baechle #include <linux/spinlock.h> 12d865bea4SRalf Baechle 13d865bea4SRalf Baechle #include <asm/delay.h> 14d865bea4SRalf Baechle #include <asm/i8253.h> 15d865bea4SRalf Baechle #include <asm/io.h> 16dd3db6ebSRalf Baechle #include <asm/time.h> 17d865bea4SRalf Baechle 1874521c28SRalf Baechle DEFINE_SPINLOCK(i8253_lock); 19a05e623fSRalf Baechle EXPORT_SYMBOL(i8253_lock); 20d865bea4SRalf Baechle 21d865bea4SRalf Baechle /* 22d865bea4SRalf Baechle * Initialize the PIT timer. 23d865bea4SRalf Baechle * 24d865bea4SRalf Baechle * This is also called after resume to bring the PIT into operation again. 25d865bea4SRalf Baechle */ 26d865bea4SRalf Baechle static void init_pit_timer(enum clock_event_mode mode, 27d865bea4SRalf Baechle struct clock_event_device *evt) 28d865bea4SRalf Baechle { 295f627f8eSRalf Baechle spin_lock(&i8253_lock); 30d865bea4SRalf Baechle 31d865bea4SRalf Baechle switch(mode) { 32d865bea4SRalf Baechle case CLOCK_EVT_MODE_PERIODIC: 33d865bea4SRalf Baechle /* binary, mode 2, LSB/MSB, ch 0 */ 34d865bea4SRalf Baechle outb_p(0x34, PIT_MODE); 35d865bea4SRalf Baechle outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ 36d865bea4SRalf Baechle outb(LATCH >> 8 , PIT_CH0); /* MSB */ 37d865bea4SRalf Baechle break; 38d865bea4SRalf Baechle 39d865bea4SRalf Baechle case CLOCK_EVT_MODE_SHUTDOWN: 40d865bea4SRalf Baechle case CLOCK_EVT_MODE_UNUSED: 41d865bea4SRalf Baechle if (evt->mode == CLOCK_EVT_MODE_PERIODIC || 42d865bea4SRalf Baechle evt->mode == CLOCK_EVT_MODE_ONESHOT) { 43d865bea4SRalf Baechle outb_p(0x30, PIT_MODE); 44d865bea4SRalf Baechle outb_p(0, PIT_CH0); 45d865bea4SRalf Baechle outb_p(0, PIT_CH0); 46d865bea4SRalf Baechle } 47d865bea4SRalf Baechle break; 48d865bea4SRalf Baechle 49d865bea4SRalf Baechle case CLOCK_EVT_MODE_ONESHOT: 50d865bea4SRalf Baechle /* One shot setup */ 51d865bea4SRalf Baechle outb_p(0x38, PIT_MODE); 52d865bea4SRalf Baechle break; 53d865bea4SRalf Baechle 54d865bea4SRalf Baechle case CLOCK_EVT_MODE_RESUME: 55d865bea4SRalf Baechle /* Nothing to do here */ 56d865bea4SRalf Baechle break; 57d865bea4SRalf Baechle } 585f627f8eSRalf Baechle spin_unlock(&i8253_lock); 59d865bea4SRalf Baechle } 60d865bea4SRalf Baechle 61d865bea4SRalf Baechle /* 62d865bea4SRalf Baechle * Program the next event in oneshot mode 63d865bea4SRalf Baechle * 64d865bea4SRalf Baechle * Delta is given in PIT ticks 65d865bea4SRalf Baechle */ 66d865bea4SRalf Baechle static int pit_next_event(unsigned long delta, struct clock_event_device *evt) 67d865bea4SRalf Baechle { 685f627f8eSRalf Baechle spin_lock(&i8253_lock); 69d865bea4SRalf Baechle outb_p(delta & 0xff , PIT_CH0); /* LSB */ 70d865bea4SRalf Baechle outb(delta >> 8 , PIT_CH0); /* MSB */ 715f627f8eSRalf Baechle spin_unlock(&i8253_lock); 72d865bea4SRalf Baechle 73d865bea4SRalf Baechle return 0; 74d865bea4SRalf Baechle } 75d865bea4SRalf Baechle 76d865bea4SRalf Baechle /* 77d865bea4SRalf Baechle * On UP the PIT can serve all of the possible timer functions. On SMP systems 78d865bea4SRalf Baechle * it can be solely used for the global tick. 79d865bea4SRalf Baechle * 80d865bea4SRalf Baechle * The profiling and update capabilites are switched off once the local apic is 81d865bea4SRalf Baechle * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - 82d865bea4SRalf Baechle * !using_apic_timer decisions in do_timer_interrupt_hook() 83d865bea4SRalf Baechle */ 841ea6428cSDmitri Vorobiev static struct clock_event_device pit_clockevent = { 85d865bea4SRalf Baechle .name = "pit", 86d865bea4SRalf Baechle .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 87d865bea4SRalf Baechle .set_mode = init_pit_timer, 88d865bea4SRalf Baechle .set_next_event = pit_next_event, 89d865bea4SRalf Baechle .irq = 0, 90d865bea4SRalf Baechle }; 91d865bea4SRalf Baechle 92dd3db6ebSRalf Baechle static irqreturn_t timer_interrupt(int irq, void *dev_id) 93d865bea4SRalf Baechle { 94d865bea4SRalf Baechle pit_clockevent.event_handler(&pit_clockevent); 95d865bea4SRalf Baechle 96d865bea4SRalf Baechle return IRQ_HANDLED; 97d865bea4SRalf Baechle } 98d865bea4SRalf Baechle 99d865bea4SRalf Baechle static struct irqaction irq0 = { 100d865bea4SRalf Baechle .handler = timer_interrupt, 101*f45e5183SWu Zhangjin .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, 102d865bea4SRalf Baechle .name = "timer" 103d865bea4SRalf Baechle }; 104d865bea4SRalf Baechle 105d865bea4SRalf Baechle /* 106d865bea4SRalf Baechle * Initialize the conversion factor and the min/max deltas of the clock event 107d865bea4SRalf Baechle * structure and register the clock event source with the framework. 108d865bea4SRalf Baechle */ 109d865bea4SRalf Baechle void __init setup_pit_timer(void) 110d865bea4SRalf Baechle { 111dd3db6ebSRalf Baechle struct clock_event_device *cd = &pit_clockevent; 112dd3db6ebSRalf Baechle unsigned int cpu = smp_processor_id(); 113dd3db6ebSRalf Baechle 114d865bea4SRalf Baechle /* 115d865bea4SRalf Baechle * Start pit with the boot cpu mask and make it global after the 116d865bea4SRalf Baechle * IO_APIC has been initialized. 117d865bea4SRalf Baechle */ 118320ab2b0SRusty Russell cd->cpumask = cpumask_of(cpu); 119dd3db6ebSRalf Baechle clockevent_set_clock(cd, CLOCK_TICK_RATE); 120dd3db6ebSRalf Baechle cd->max_delta_ns = clockevent_delta2ns(0x7FFF, cd); 121dd3db6ebSRalf Baechle cd->min_delta_ns = clockevent_delta2ns(0xF, cd); 122dd3db6ebSRalf Baechle clockevents_register_device(cd); 123d865bea4SRalf Baechle 124d865bea4SRalf Baechle setup_irq(0, &irq0); 125d865bea4SRalf Baechle } 126d865bea4SRalf Baechle 127d865bea4SRalf Baechle /* 128d865bea4SRalf Baechle * Since the PIT overflows every tick, its not very useful 129d865bea4SRalf Baechle * to just read by itself. So use jiffies to emulate a free 130d865bea4SRalf Baechle * running counter: 131d865bea4SRalf Baechle */ 1328e19608eSMagnus Damm static cycle_t pit_read(struct clocksource *cs) 133d865bea4SRalf Baechle { 134d865bea4SRalf Baechle unsigned long flags; 135d865bea4SRalf Baechle int count; 136d865bea4SRalf Baechle u32 jifs; 137d865bea4SRalf Baechle static int old_count; 138d865bea4SRalf Baechle static u32 old_jifs; 139d865bea4SRalf Baechle 140d865bea4SRalf Baechle spin_lock_irqsave(&i8253_lock, flags); 141d865bea4SRalf Baechle /* 142d865bea4SRalf Baechle * Although our caller may have the read side of xtime_lock, 143d865bea4SRalf Baechle * this is now a seqlock, and we are cheating in this routine 144d865bea4SRalf Baechle * by having side effects on state that we cannot undo if 145d865bea4SRalf Baechle * there is a collision on the seqlock and our caller has to 146d865bea4SRalf Baechle * retry. (Namely, old_jifs and old_count.) So we must treat 147d865bea4SRalf Baechle * jiffies as volatile despite the lock. We read jiffies 148d865bea4SRalf Baechle * before latching the timer count to guarantee that although 149d865bea4SRalf Baechle * the jiffies value might be older than the count (that is, 150d865bea4SRalf Baechle * the counter may underflow between the last point where 151d865bea4SRalf Baechle * jiffies was incremented and the point where we latch the 152d865bea4SRalf Baechle * count), it cannot be newer. 153d865bea4SRalf Baechle */ 154d865bea4SRalf Baechle jifs = jiffies; 155d865bea4SRalf Baechle outb_p(0x00, PIT_MODE); /* latch the count ASAP */ 156d865bea4SRalf Baechle count = inb_p(PIT_CH0); /* read the latched count */ 157d865bea4SRalf Baechle count |= inb_p(PIT_CH0) << 8; 158d865bea4SRalf Baechle 159d865bea4SRalf Baechle /* VIA686a test code... reset the latch if count > max + 1 */ 160d865bea4SRalf Baechle if (count > LATCH) { 161d865bea4SRalf Baechle outb_p(0x34, PIT_MODE); 162d865bea4SRalf Baechle outb_p(LATCH & 0xff, PIT_CH0); 163d865bea4SRalf Baechle outb(LATCH >> 8, PIT_CH0); 164d865bea4SRalf Baechle count = LATCH - 1; 165d865bea4SRalf Baechle } 166d865bea4SRalf Baechle 167d865bea4SRalf Baechle /* 168d865bea4SRalf Baechle * It's possible for count to appear to go the wrong way for a 169d865bea4SRalf Baechle * couple of reasons: 170d865bea4SRalf Baechle * 171d865bea4SRalf Baechle * 1. The timer counter underflows, but we haven't handled the 172d865bea4SRalf Baechle * resulting interrupt and incremented jiffies yet. 173d865bea4SRalf Baechle * 2. Hardware problem with the timer, not giving us continuous time, 174d865bea4SRalf Baechle * the counter does small "jumps" upwards on some Pentium systems, 175d865bea4SRalf Baechle * (see c't 95/10 page 335 for Neptun bug.) 176d865bea4SRalf Baechle * 177d865bea4SRalf Baechle * Previous attempts to handle these cases intelligently were 178d865bea4SRalf Baechle * buggy, so we just do the simple thing now. 179d865bea4SRalf Baechle */ 180d865bea4SRalf Baechle if (count > old_count && jifs == old_jifs) { 181d865bea4SRalf Baechle count = old_count; 182d865bea4SRalf Baechle } 183d865bea4SRalf Baechle old_count = count; 184d865bea4SRalf Baechle old_jifs = jifs; 185d865bea4SRalf Baechle 186d865bea4SRalf Baechle spin_unlock_irqrestore(&i8253_lock, flags); 187d865bea4SRalf Baechle 188d865bea4SRalf Baechle count = (LATCH - 1) - count; 189d865bea4SRalf Baechle 190d865bea4SRalf Baechle return (cycle_t)(jifs * LATCH) + count; 191d865bea4SRalf Baechle } 192d865bea4SRalf Baechle 193d865bea4SRalf Baechle static struct clocksource clocksource_pit = { 194d865bea4SRalf Baechle .name = "pit", 195d865bea4SRalf Baechle .rating = 110, 196d865bea4SRalf Baechle .read = pit_read, 197d865bea4SRalf Baechle .mask = CLOCKSOURCE_MASK(32), 198d865bea4SRalf Baechle .mult = 0, 199d865bea4SRalf Baechle .shift = 20, 200d865bea4SRalf Baechle }; 201d865bea4SRalf Baechle 202d865bea4SRalf Baechle static int __init init_pit_clocksource(void) 203d865bea4SRalf Baechle { 204d865bea4SRalf Baechle if (num_possible_cpus() > 1) /* PIT does not scale! */ 205d865bea4SRalf Baechle return 0; 206d865bea4SRalf Baechle 207d865bea4SRalf Baechle clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); 208d865bea4SRalf Baechle return clocksource_register(&clocksource_pit); 209d865bea4SRalf Baechle } 210d865bea4SRalf Baechle arch_initcall(init_pit_clocksource); 211