void rthal_setup_8254_tsc(void) { unsigned long flags; int count; #ifdef CONFIG_IPIPE_CORE if (cpu_has_tsc) printk("Xenomai: your configuration has tsc disabled while " "your cpu has a tsc\nYou would get better performances " "by enabling tsc in kernel configuration.\n"); #endif rthal_local_irq_save_hw(flags); outb_p(0x0, PIT_MODE); count = inb_p(PIT_CH0); count |= inb_p(PIT_CH0) << 8; outb_p(0xb4, PIT_MODE); outb_p(RTHAL_8254_COUNT2LATCH & 0xff, PIT_CH2); outb_p(RTHAL_8254_COUNT2LATCH >> 8, PIT_CH2); rthal_tsc_8254 = count + LATCH * jiffies; rthal_last_8254_counter2 = 0; /* Gate high, disable speaker */ outb_p((inb_p(0x61) & ~0x2) | 1, 0x61); rthal_local_irq_restore_hw(flags); }
static void rthal_timer_set_oneshot(void) { unsigned long flags; int count; rthal_local_irq_save_hw(flags); /* * We should be running in rate generator mode (M2) on entry, * so read the current latch value, in order to roughly * restart the timing where we left it, after the switch to * software strobe mode. */ outb_p(0x00, PIT_MODE); count = inb_p(PIT_CH0); count |= inb_p(PIT_CH0) << 8; if (count > LATCH) /* For broken VIA686a hardware. */ count = LATCH - 1; /* * Force software triggered strobe mode (M4) on PIT channel * #0. We also program an initial shot at a sane value to * restart the timing cycle. */ udelay(10); outb_p(0x38, PIT_MODE); outb(count & 0xff, PIT_CH0); outb(count >> 8, PIT_CH0); rthal_local_irq_restore_hw(flags); }
static void rthal_timer_set_periodic(void) { unsigned long flags; rthal_local_irq_save_hw(flags); outb_p(0x34, PIT_MODE); outb(LATCH & 0xff, PIT_CH0); outb(LATCH >> 8, PIT_CH0); rthal_local_irq_restore_hw(flags); }
rthal_time_t rthal_get_8254_tsc(void) { unsigned long flags; int delta, count; rthal_time_t t; rthal_local_irq_save_hw(flags); outb(0xd8, PIT_MODE); count = inb(PIT_CH2); delta = rthal_last_8254_counter2 - (count |= (inb(PIT_CH2) << 8)); rthal_last_8254_counter2 = count; rthal_tsc_8254 += (delta > 0 ? delta : delta + RTHAL_8254_COUNT2LATCH); t = rthal_tsc_8254; rthal_local_irq_restore_hw(flags); return t; }
unsigned long rthal_timer_calibrate(void) { unsigned long flags; rthal_time_t t, dt; int i, count; rthal_local_irq_save_hw(flags); /* Read the current latch value, whatever the current mode is. */ outb_p(0x00, PIT_MODE); count = inb_p(PIT_CH0); count |= inb_p(PIT_CH0) << 8; if (count > LATCH) /* For broken VIA686a hardware. */ count = LATCH - 1; /* * We only want to measure the average time needed to program * the next shot, so we basically don't care about the current * PIT mode. We just rewrite the original latch value at each * iteration. */ t = rthal_rdtsc(); for (i = 0; i < 20; i++) { outb(count & 0xff, PIT_CH0); outb(count >> 8, PIT_CH0); } dt = rthal_rdtsc() - t; rthal_local_irq_restore_hw(flags); #ifdef CONFIG_IPIPE_TRACE_IRQSOFF /* Reset the max trace, since it contains the calibration time now. */ rthal_trace_max_reset(); #endif /* CONFIG_IPIPE_TRACE_IRQSOFF */ return rthal_ulldiv(dt, i, NULL); }
unsigned long rthal_timer_calibrate(void) { unsigned long flags, freq; u64 t, v; u32 d; int n; rthal_local_irq_save_hw(flags); rthal_read_tsc(t); barrier(); for (n = 1; n < 100; n++) rthal_read_tsc(v); rthal_local_irq_restore_hw(flags); d = (u32)(v - t); freq = rthal_get_clockfreq(); return ((1000000000 / freq) * (d / n)); }