From fa9a4511b4aef7536ec10128d2b54aff0d117958 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Mon, 12 Mar 2001 13:44:58 +0000 Subject: [lcd4linux @ 2001-03-12 13:44:58 by reinelt] new udelay() using Time Stamp Counters --- HD44780.c | 10 +++- TODO | 3 ++ config.h.in | 3 ++ configure | 100 +++++++++++++++++++++++++----------- configure.in | 1 + lcd4linux.conf.sample | 26 +++++----- udelay.c | 140 +++++++++++++++++++++++++++++++++++++++++++++----- udelay.h | 7 ++- 8 files changed, 232 insertions(+), 58 deletions(-) diff --git a/HD44780.c b/HD44780.c index 8bb44a9..f0a3d3c 100644 --- a/HD44780.c +++ b/HD44780.c @@ -1,4 +1,4 @@ -/* $Id: HD44780.c,v 1.13 2001/03/12 12:39:36 reinelt Exp $ +/* $Id: HD44780.c,v 1.14 2001/03/12 13:44:58 reinelt Exp $ * * driver for display modules based on the HD44780 chip * @@ -20,6 +20,10 @@ * * * $Log: HD44780.c,v $ + * Revision 1.14 2001/03/12 13:44:58 reinelt + * + * new udelay() using Time Stamp Counters + * * Revision 1.13 2001/03/12 12:39:36 reinelt * * reworked autoconf a lot: drivers may be excluded, #define's went to config.h @@ -439,6 +443,10 @@ int HD_init (LCD *Self) Self->gpos=gpos; Lcd=*Self; +#ifndef USE_OLD_UDELAY + udelay_init(); +#endif + if (HD_open()!=0) return -1; diff --git a/TODO b/TODO index 2c8c7b7..2cf451d 100644 --- a/TODO +++ b/TODO @@ -61,3 +61,6 @@ There's a reason for forking that early, but I forgot... 2001-03-12 Michael Reinelt remove USE_OLD_UDELAY after wide testing of new udelay code + +2001-03-12 Michael Reinelt +create a NEWS file with changes/enhancements of every release diff --git a/config.h.in b/config.h.in index 5e4090f..a52c5c4 100644 --- a/config.h.in +++ b/config.h.in @@ -99,6 +99,9 @@ /* Define if you have the header file. */ #undef HAVE_ASM_IO_H +/* Define if you have the header file. */ +#undef HAVE_ASM_MSR_H + /* Define if you have the header file. */ #undef HAVE_DIRENT_H diff --git a/configure b/configure index 57d73d9..f8e0dbc 100755 --- a/configure +++ b/configure @@ -2715,14 +2715,54 @@ else fi done +for ac_hdr in asm/msr.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2723: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2733: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:2721: checking for working const" >&5 +echo "configure:2761: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2815: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -2792,21 +2832,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:2796: checking for inline" >&5 +echo "configure:2836: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -2832,12 +2872,12 @@ EOF esac echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:2836: checking for pid_t" >&5 +echo "configure:2876: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2865,12 +2905,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:2869: checking for size_t" >&5 +echo "configure:2909: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2898,12 +2938,12 @@ EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:2902: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:2942: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2912,7 +2952,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:2916: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2956: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -2933,12 +2973,12 @@ EOF fi echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 -echo "configure:2937: checking whether struct tm is in sys/time.h or time.h" >&5 +echo "configure:2977: checking whether struct tm is in sys/time.h or time.h" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2946,7 +2986,7 @@ int main() { struct tm *tp; tp->tm_sec; ; return 0; } EOF -if { (eval echo configure:2950: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2990: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm=time.h else @@ -2967,12 +3007,12 @@ EOF fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:2971: checking for uid_t in sys/types.h" >&5 +echo "configure:3011: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -3003,13 +3043,13 @@ fi if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 -echo "configure:3007: checking whether ${CC-cc} needs -traditional" >&5 +echo "configure:3047: checking whether ${CC-cc} needs -traditional" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat > conftest.$ac_ext < Autoconf TIOCGETP @@ -3027,7 +3067,7 @@ rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < Autoconf TCGETA @@ -3049,7 +3089,7 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 fi echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 -echo "configure:3053: checking for 8-bit clean memcmp" >&5 +echo "configure:3093: checking for 8-bit clean memcmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3057,7 +3097,7 @@ else ac_cv_func_memcmp_clean=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_memcmp_clean=yes else @@ -3085,12 +3125,12 @@ echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6 test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:3089: checking return type of signal handlers" >&5 +echo "configure:3129: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3107,7 +3147,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:3111: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3151: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -3128,12 +3168,12 @@ EOF for ac_func in gettimeofday putenv select socket strdup strerror strstr strtol uname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3132: checking for $ac_func" >&5 +echo "configure:3172: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3200: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff --git a/configure.in b/configure.in index b7bb573..959444b 100644 --- a/configure.in +++ b/configure.in @@ -186,6 +186,7 @@ AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/ioctl.h sys/time.h syslog.h unis AC_CHECK_HEADERS(sys/io.h asm/io.h) AC_CHECK_HEADERS(gd/gd.h gd.h) AC_CHECK_HEADERS(net/if_ppp.h) +AC_CHECK_HEADERS(asm/msr.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample index c12f7f0..ec8d857 100644 --- a/lcd4linux.conf.sample +++ b/lcd4linux.conf.sample @@ -3,10 +3,10 @@ #Speed 19200 #Contrast 160 -#Display HD44780 -#Port 0x378 -#Size 24x2 -#Delay 503 +Display HD44780 +Port 0x278 +Size 24x2 +Delay 503 #Display BLC100x #Port /dev/ttyS2 @@ -31,15 +31,15 @@ #halfground \#70c000 #background \#80d000 -Display PNG -size 20x4 -font 5x8 -pixel 2+0 -gap -1x-1 -border 5 -foreground \#102000 -halfground \#70c000 -background \#80d000 +#Display PNG +#size 20x4 +#font 5x8 +#pixel 2+0 +#gap -1x-1 +#border 5 +#foreground \#102000 +#halfground \#70c000 +#background \#80d000 #Display X11 #size 20x5 diff --git a/udelay.c b/udelay.c index e658436..e9a3231 100644 --- a/udelay.c +++ b/udelay.c @@ -1,4 +1,4 @@ -/* $Id: udelay.c,v 1.4 2001/03/12 12:39:36 reinelt Exp $ +/* $Id: udelay.c,v 1.5 2001/03/12 13:44:58 reinelt Exp $ * * short delays * @@ -20,6 +20,10 @@ * * * $Log: udelay.c,v $ + * Revision 1.5 2001/03/12 13:44:58 reinelt + * + * new udelay() using Time Stamp Counters + * * Revision 1.4 2001/03/12 12:39:36 reinelt * * reworked autoconf a lot: drivers may be excluded, #define's went to config.h @@ -52,23 +56,42 @@ * This function does busy-waiting! so use only for delays smaller * than 10 msec * - * void udelay_calibrate (void) + * void udelay_calibrate (void) (if USE_OLD_UDELAY is defined) * does a binary approximation for 'loops_per_usec' * should be called several times on an otherwise idle machine * the maximum value should be used * + * void udelay_init (void) + * selects delay method (gettimeofday() ord rdtsc() according + * to processor features + * */ +#include "config.h" #include #include + #ifdef USE_OLD_UDELAY + #include + #else -#include + +#include #include +#include +#include +#include +#include +#ifdef HAVE_ASM_MSR_H +#include +#endif + #endif + +#include "debug.h" #include "udelay.h" #ifdef USE_OLD_UDELAY @@ -119,20 +142,111 @@ void udelay_calibrate (void) #else -void udelay (unsigned long usec) +static unsigned int ticks_per_usec=0; + +static void getCPUinfo (int *hasTSC, double *MHz) { - struct timeval now, end; + int fd; + char buffer[4096], *p; - gettimeofday (&end, NULL); - end.tv_usec+=usec; - while (end.tv_usec>1000000) { - end.tv_usec-=1000000; - end.tv_sec++; + *hasTSC=0; + *MHz=-1; + + fd=open("/proc/cpuinfo", O_RDONLY); + if (fd==-1) { + error ("open(/proc/cpuinfo) failed: %s", strerror(errno)); + return; + } + if (read (fd, &buffer, sizeof(buffer)-1)==-1) { + error ("read(/proc/cpuinfo) failed: %s", strerror(errno)); + close (fd); + return; + } + close (fd); + + p=strstr(buffer, "flags"); + if (p==NULL) { + debug ("/proc/cpuinfo has no 'flags' line"); + } else { + p=strstr(p, "tsc"); + if (p==NULL) { + debug ("CPU does not support Time Stamp Counter"); + } else { + debug ("CPU supports Time Stamp Counter"); + *hasTSC=1; + } } - do { - gettimeofday(&now, NULL); - } while (now.tv_sec==end.tv_sec?now.tv_usec0.0) { + ticks_per_usec=ceil(mhz); + debug ("using TSC delay loop, %u ticks per microsecond", ticks_per_usec); + } else { + ticks_per_usec=0; + debug ("using gettimeofday() delay loop"); + } + +#else + + debug ("lcd4linux has been compiled without asm/msr.h"); + debug ("using gettimeofday() delay loop"); + +#endif + +} + +void udelay (unsigned long usec) +{ + if (ticks_per_usec) { + + unsigned int t1, t2; + + usec*=ticks_per_usec; + + rdtscl(t1); + do { + rdtscl(t2); + } while ((t2-t1)1000000) { + end.tv_usec-=1000000; + end.tv_sec++; + } + + do { + gettimeofday(&now, NULL); + } while (now.tv_sec==end.tv_sec?now.tv_usec