Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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));
}