X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fftape%2Flowlevel%2Fftape-calibr.c;h=956b2586e138a150e385e7fda9fb93c464fb177e;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=34f0e69d354256ee6fc6e5a2608bbec605c3ce2d;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/drivers/char/ftape/lowlevel/ftape-calibr.c b/drivers/char/ftape/lowlevel/ftape-calibr.c index 34f0e69d3..956b2586e 100644 --- a/drivers/char/ftape/lowlevel/ftape-calibr.c +++ b/drivers/char/ftape/lowlevel/ftape-calibr.c @@ -31,7 +31,10 @@ #include #if defined(__alpha__) # include -#elif defined(__i386__) || defined(__x86_64__) +#elif defined(__x86_64__) +# include +# include +#elif defined(__i386__) # include #endif #include @@ -45,7 +48,7 @@ # error Ftape is not implemented for this architecture! #endif -#if defined(__alpha__) +#if defined(__alpha__) || defined(__x86_64__) static unsigned long ps_per_cycle = 0; #endif @@ -72,7 +75,18 @@ unsigned int ftape_timestamp(void) asm volatile ("rpcc %0" : "=r" (r)); return r; -#elif defined(__i386__) || defined(__x86_64__) +#elif defined(__x86_64__) + unsigned long r; + rdtscl(r); + return r; +#elif defined(__i386__) + +/* + * Note that there is some time between counter underflowing and jiffies + * increasing, so the code below won't always give correct output. + * -Vojtech + */ + unsigned long flags; __u16 lo; __u16 hi; @@ -89,9 +103,9 @@ unsigned int ftape_timestamp(void) static unsigned int short_ftape_timestamp(void) { -#if defined(__alpha__) +#if defined(__alpha__) || defined(__x86_64__) return ftape_timestamp(); -#elif defined(__i386__) || defined(__x86_64__) +#elif defined(__i386__) unsigned int count; unsigned long flags; @@ -106,9 +120,9 @@ static unsigned int short_ftape_timestamp(void) static unsigned int diff(unsigned int t0, unsigned int t1) { -#if defined(__alpha__) - return (t1 <= t0) ? t1 + (1UL << 32) - t0 : t1 - t0; -#elif defined(__i386__) || defined(__x86_64__) +#if defined(__alpha__) || defined(__x86_64__) + return (t1 - t0); +#elif defined(__i386__) /* * This is tricky: to work for both short and full ftape_timestamps * we'll have to discriminate between these. @@ -122,9 +136,9 @@ static unsigned int diff(unsigned int t0, unsigned int t1) static unsigned int usecs(unsigned int count) { -#if defined(__alpha__) +#if defined(__alpha__) || defined(__x86_64__) return (ps_per_cycle * count) / 1000000UL; -#elif defined(__i386__) || defined(__x86_64__) +#elif defined(__i386__) return (10000 * count) / ((CLOCK_TICK_RATE + 50) / 100); #endif } @@ -163,38 +177,13 @@ static void time_inb(void) static void init_clock(void) { -#if defined(__i386__) || defined(__x86_64__) - unsigned int t; - int i; TRACE_FUN(ft_t_any); - /* Haven't studied on why, but there sometimes is a problem - * with the tick timer readout. The two bytes get swapped. - * This hack solves that problem by doing one extra input. - */ - for (i = 0; i < 1000; ++i) { - t = short_ftape_timestamp(); - if (t > LATCH) { - inb_p(0x40); /* get in sync again */ - TRACE(ft_t_warn, "clock counter fixed"); - break; - } - } +#if defined(__x86_64__) + ps_per_cycle = 1000000000UL / cpu_khz; #elif defined(__alpha__) -#if CONFIG_FT_ALPHA_CLOCK == 0 -#error You must define and set CONFIG_FT_ALPHA_CLOCK in 'make config' ! -#endif extern struct hwrpb_struct *hwrpb; - TRACE_FUN(ft_t_any); - - if (hwrpb->cycle_freq != 0) { - ps_per_cycle = (1000*1000*1000*1000UL) / hwrpb->cycle_freq; - } else { - /* - * HELP: Linux 2.0.x doesn't set cycle_freq on my noname ! - */ - ps_per_cycle = (1000*1000*1000*1000UL) / CONFIG_FT_ALPHA_CLOCK; - } + ps_per_cycle = (1000*1000*1000*1000UL) / hwrpb->cycle_freq; #endif TRACE_EXIT; } @@ -213,7 +202,7 @@ void ftape_calibrate(char *name, unsigned int tc = 0; unsigned int count; unsigned int time; -#if defined(__i386__) || defined(__x86_64__) +#if defined(__i386__) unsigned int old_tc = 0; unsigned int old_count = 1; unsigned int old_time = 1; @@ -255,7 +244,7 @@ void ftape_calibrate(char *name, tc = (1000 * time) / (count - 1); TRACE(ft_t_any, "once:%3d us,%6d times:%6d us, TC:%5d ns", usecs(once), count - 1, usecs(multiple), tc); -#if defined(__alpha__) +#if defined(__alpha__) || defined(__x86_64__) /* * Increase the calibration count exponentially until the * calibration time exceeds 100 ms. @@ -263,7 +252,7 @@ void ftape_calibrate(char *name, if (time >= 100*1000) { break; } -#elif defined(__i386__) || defined(__x86_64__) +#elif defined(__i386__) /* * increase the count until the resulting time nears 2/HZ, * then the tc will drop sharply because we lose LATCH counts.