linux/drivers/clocksource/i8253.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * i8253 PIT clocksource
   4 */
   5#include <linux/clockchips.h>
   6#include <linux/init.h>
   7#include <linux/io.h>
   8#include <linux/spinlock.h>
   9#include <linux/timex.h>
  10#include <linux/module.h>
  11#include <linux/i8253.h>
  12#include <linux/smp.h>
  13
  14/*
  15 * Protects access to I/O ports
  16 *
  17 * 0040-0043 : timer0, i8253 / i8254
  18 * 0061-0061 : NMI Control Register which contains two speaker control bits.
  19 */
  20DEFINE_RAW_SPINLOCK(i8253_lock);
  21EXPORT_SYMBOL(i8253_lock);
  22
  23/*
  24 * Handle PIT quirk in pit_shutdown() where zeroing the counter register
  25 * restarts the PIT, negating the shutdown. On platforms with the quirk,
  26 * platform specific code can set this to false.
  27 */
  28bool i8253_clear_counter_on_shutdown __ro_after_init = true;
  29
  30#ifdef CONFIG_CLKSRC_I8253
  31/*
  32 * Since the PIT overflows every tick, its not very useful
  33 * to just read by itself. So use jiffies to emulate a free
  34 * running counter:
  35 */
  36static u64 i8253_read(struct clocksource *cs)
  37{
  38        static int old_count;
  39        static u32 old_jifs;
  40        unsigned long flags;
  41        int count;
  42        u32 jifs;
  43
  44        raw_spin_lock_irqsave(&i8253_lock, flags);
  45        /*
  46         * Although our caller may have the read side of jiffies_lock,
  47         * this is now a seqlock, and we are cheating in this routine
  48         * by having side effects on state that we cannot undo if
  49         * there is a collision on the seqlock and our caller has to
  50         * retry.  (Namely, old_jifs and old_count.)  So we must treat
  51         * jiffies as volatile despite the lock.  We read jiffies
  52         * before latching the timer count to guarantee that although
  53         * the jiffies value might be older than the count (that is,
  54         * the counter may underflow between the last point where
  55         * jiffies was incremented and the point where we latch the
  56         * count), it cannot be newer.
  57         */
  58        jifs = jiffies;
  59        outb_p(0x00, PIT_MODE); /* latch the count ASAP */
  60        count = inb_p(PIT_CH0); /* read the latched count */
  61        count |= inb_p(PIT_CH0) << 8;
  62
  63        /* VIA686a test code... reset the latch if count > max + 1 */
  64        if (count > PIT_LATCH) {
  65                outb_p(0x34, PIT_MODE);
  66                outb_p(PIT_LATCH & 0xff, PIT_CH0);
  67                outb_p(PIT_LATCH >> 8, PIT_CH0);
  68                count = PIT_LATCH - 1;
  69        }
  70
  71        /*
  72         * It's possible for count to appear to go the wrong way for a
  73         * couple of reasons:
  74         *
  75         *  1. The timer counter underflows, but we haven't handled the
  76         *     resulting interrupt and incremented jiffies yet.
  77         *  2. Hardware problem with the timer, not giving us continuous time,
  78         *     the counter does small "jumps" upwards on some Pentium systems,
  79         *     (see c't 95/10 page 335 for Neptun bug.)
  80         *
  81         * Previous attempts to handle these cases intelligently were
  82         * buggy, so we just do the simple thing now.
  83         */
  84        if (count > old_count && jifs == old_jifs)
  85                count = old_count;
  86
  87        old_count = count;
  88        old_jifs = jifs;
  89
  90        raw_spin_unlock_irqrestore(&i8253_lock, flags);
  91
  92        count = (PIT_LATCH - 1) - count;
  93
  94        return (u64)(jifs * PIT_LATCH) + count;
  95}
  96
  97static struct clocksource i8253_cs = {
  98        .name           = "pit",
  99        .rating         = 110,
 100        .read           = i8253_read,
 101        .mask           = CLOCKSOURCE_MASK(32),
 102};
 103
 104int __init clocksource_i8253_init(void)
 105{
 106        return clocksource_register_hz(&i8253_cs, PIT_TICK_RATE);
 107}
 108#endif
 109
 110#ifdef CONFIG_CLKEVT_I8253
 111static int pit_shutdown(struct clock_event_device *evt)
 112{
 113        if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt))
 114                return 0;
 115
 116        raw_spin_lock(&i8253_lock);
 117
 118        outb_p(0x30, PIT_MODE);
 119
 120        if (i8253_clear_counter_on_shutdown) {
 121                outb_p(0, PIT_CH0);
 122                outb_p(0, PIT_CH0);
 123        }
 124
 125        raw_spin_unlock(&i8253_lock);
 126        return 0;
 127}
 128
 129static int pit_set_oneshot(struct clock_event_device *evt)
 130{
 131        raw_spin_lock(&i8253_lock);
 132        outb_p(0x38, PIT_MODE);
 133        raw_spin_unlock(&i8253_lock);
 134        return 0;
 135}
 136
 137static int pit_set_periodic(struct clock_event_device *evt)
 138{
 139        raw_spin_lock(&i8253_lock);
 140
 141        /* binary, mode 2, LSB/MSB, ch 0 */
 142        outb_p(0x34, PIT_MODE);
 143        outb_p(PIT_LATCH & 0xff, PIT_CH0);      /* LSB */
 144        outb_p(PIT_LATCH >> 8, PIT_CH0);        /* MSB */
 145
 146        raw_spin_unlock(&i8253_lock);
 147        return 0;
 148}
 149
 150/*
 151 * Program the next event in oneshot mode
 152 *
 153 * Delta is given in PIT ticks
 154 */
 155static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
 156{
 157        raw_spin_lock(&i8253_lock);
 158        outb_p(delta & 0xff , PIT_CH0); /* LSB */
 159        outb_p(delta >> 8 , PIT_CH0);           /* MSB */
 160        raw_spin_unlock(&i8253_lock);
 161
 162        return 0;
 163}
 164
 165/*
 166 * On UP the PIT can serve all of the possible timer functions. On SMP systems
 167 * it can be solely used for the global tick.
 168 */
 169struct clock_event_device i8253_clockevent = {
 170        .name                   = "pit",
 171        .features               = CLOCK_EVT_FEAT_PERIODIC,
 172        .set_state_shutdown     = pit_shutdown,
 173        .set_state_periodic     = pit_set_periodic,
 174        .set_next_event         = pit_next_event,
 175};
 176
 177/*
 178 * Initialize the conversion factor and the min/max deltas of the clock event
 179 * structure and register the clock event source with the framework.
 180 */
 181void __init clockevent_i8253_init(bool oneshot)
 182{
 183        if (oneshot) {
 184                i8253_clockevent.features |= CLOCK_EVT_FEAT_ONESHOT;
 185                i8253_clockevent.set_state_oneshot = pit_set_oneshot;
 186        }
 187        /*
 188         * Start pit with the boot cpu mask. x86 might make it global
 189         * when it is used as broadcast device later.
 190         */
 191        i8253_clockevent.cpumask = cpumask_of(smp_processor_id());
 192
 193        clockevents_config_and_register(&i8253_clockevent, PIT_TICK_RATE,
 194                                        0xF, 0x7FFF);
 195}
 196#endif
 197