// SPDX-License-Identifier: GPL-2.01/*2* i8253 PIT clocksource3*/4#include <linux/clockchips.h>5#include <linux/init.h>6#include <linux/io.h>7#include <linux/spinlock.h>8#include <linux/timex.h>9#include <linux/module.h>10#include <linux/i8253.h>11#include <linux/smp.h>1213/*14* Protects access to I/O ports15*16* 0040-0043 : timer0, i8253 / i825417* 0061-0061 : NMI Control Register which contains two speaker control bits.18*/19DEFINE_RAW_SPINLOCK(i8253_lock);20EXPORT_SYMBOL(i8253_lock);2122#ifdef CONFIG_CLKSRC_I825323/*24* Since the PIT overflows every tick, its not very useful25* to just read by itself. So use jiffies to emulate a free26* running counter:27*/28static u64 i8253_read(struct clocksource *cs)29{30static int old_count;31static u32 old_jifs;32unsigned long flags;33int count;34u32 jifs;3536raw_spin_lock_irqsave(&i8253_lock, flags);37/*38* Although our caller may have the read side of jiffies_lock,39* this is now a seqlock, and we are cheating in this routine40* by having side effects on state that we cannot undo if41* there is a collision on the seqlock and our caller has to42* retry. (Namely, old_jifs and old_count.) So we must treat43* jiffies as volatile despite the lock. We read jiffies44* before latching the timer count to guarantee that although45* the jiffies value might be older than the count (that is,46* the counter may underflow between the last point where47* jiffies was incremented and the point where we latch the48* count), it cannot be newer.49*/50jifs = jiffies;51outb_p(0x00, PIT_MODE); /* latch the count ASAP */52count = inb_p(PIT_CH0); /* read the latched count */53count |= inb_p(PIT_CH0) << 8;5455/* VIA686a test code... reset the latch if count > max + 1 */56if (count > PIT_LATCH) {57outb_p(0x34, PIT_MODE);58outb_p(PIT_LATCH & 0xff, PIT_CH0);59outb_p(PIT_LATCH >> 8, PIT_CH0);60count = PIT_LATCH - 1;61}6263/*64* It's possible for count to appear to go the wrong way for a65* couple of reasons:66*67* 1. The timer counter underflows, but we haven't handled the68* resulting interrupt and incremented jiffies yet.69* 2. Hardware problem with the timer, not giving us continuous time,70* the counter does small "jumps" upwards on some Pentium systems,71* (see c't 95/10 page 335 for Neptun bug.)72*73* Previous attempts to handle these cases intelligently were74* buggy, so we just do the simple thing now.75*/76if (count > old_count && jifs == old_jifs)77count = old_count;7879old_count = count;80old_jifs = jifs;8182raw_spin_unlock_irqrestore(&i8253_lock, flags);8384count = (PIT_LATCH - 1) - count;8586return (u64)(jifs * PIT_LATCH) + count;87}8889static struct clocksource i8253_cs = {90.name = "pit",91.rating = 110,92.read = i8253_read,93.mask = CLOCKSOURCE_MASK(32),94};9596int __init clocksource_i8253_init(void)97{98return clocksource_register_hz(&i8253_cs, PIT_TICK_RATE);99}100#endif101102#ifdef CONFIG_CLKEVT_I8253103void clockevent_i8253_disable(void)104{105guard(raw_spinlock_irqsave)(&i8253_lock);106107/*108* Writing the MODE register should stop the counter, according to109* the datasheet. This appears to work on real hardware (well, on110* modern Intel and AMD boxes; I didn't dig the Pegasos out of the111* shed).112*113* However, some virtual implementations differ, and the MODE change114* doesn't have any effect until either the counter is written (KVM115* in-kernel PIT) or the next interrupt (QEMU). And in those cases,116* it may not stop the *count*, only the interrupts. Although in117* the virt case, that probably doesn't matter, as the value of the118* counter will only be calculated on demand if the guest reads it;119* it's the interrupts which cause steal time.120*121* Hyper-V apparently has a bug where even in mode 0, the IRQ keeps122* firing repeatedly if the counter is running. But it *does* do the123* right thing when the MODE register is written.124*125* So: write the MODE and then load the counter, which ensures that126* the IRQ is stopped on those buggy virt implementations. And then127* write the MODE again, which is the right way to stop it.128*/129outb_p(0x30, PIT_MODE);130outb_p(0, PIT_CH0);131outb_p(0, PIT_CH0);132133outb_p(0x30, PIT_MODE);134}135136static int pit_shutdown(struct clock_event_device *evt)137{138if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt))139return 0;140141clockevent_i8253_disable();142return 0;143}144145static int pit_set_oneshot(struct clock_event_device *evt)146{147raw_spin_lock(&i8253_lock);148outb_p(0x38, PIT_MODE);149raw_spin_unlock(&i8253_lock);150return 0;151}152153static int pit_set_periodic(struct clock_event_device *evt)154{155raw_spin_lock(&i8253_lock);156157/* binary, mode 2, LSB/MSB, ch 0 */158outb_p(0x34, PIT_MODE);159outb_p(PIT_LATCH & 0xff, PIT_CH0); /* LSB */160outb_p(PIT_LATCH >> 8, PIT_CH0); /* MSB */161162raw_spin_unlock(&i8253_lock);163return 0;164}165166/*167* Program the next event in oneshot mode168*169* Delta is given in PIT ticks170*/171static int pit_next_event(unsigned long delta, struct clock_event_device *evt)172{173raw_spin_lock(&i8253_lock);174outb_p(delta & 0xff , PIT_CH0); /* LSB */175outb_p(delta >> 8 , PIT_CH0); /* MSB */176raw_spin_unlock(&i8253_lock);177178return 0;179}180181/*182* On UP the PIT can serve all of the possible timer functions. On SMP systems183* it can be solely used for the global tick.184*/185struct clock_event_device i8253_clockevent = {186.name = "pit",187.features = CLOCK_EVT_FEAT_PERIODIC,188.set_state_shutdown = pit_shutdown,189.set_state_periodic = pit_set_periodic,190.set_next_event = pit_next_event,191};192193/*194* Initialize the conversion factor and the min/max deltas of the clock event195* structure and register the clock event source with the framework.196*/197void __init clockevent_i8253_init(bool oneshot)198{199if (oneshot) {200i8253_clockevent.features |= CLOCK_EVT_FEAT_ONESHOT;201i8253_clockevent.set_state_oneshot = pit_set_oneshot;202}203/*204* Start pit with the boot cpu mask. x86 might make it global205* when it is used as broadcast device later.206*/207i8253_clockevent.cpumask = cpumask_of(smp_processor_id());208209clockevents_config_and_register(&i8253_clockevent, PIT_TICK_RATE,2100xF, 0x7FFF);211}212#endif213214215