diff options
author | reinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2001-03-12 13:44:58 +0000 |
---|---|---|
committer | reinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2001-03-12 13:44:58 +0000 |
commit | 064f4880a2349039356945b3a9f2081f035c32c1 (patch) | |
tree | c028a9c468ef0c5d0389572fc8363c51e854e9c5 | |
parent | 62fdec1130f15faf0ed0562f79525f64f7f6e9bd (diff) | |
download | lcd4linux-064f4880a2349039356945b3a9f2081f035c32c1.tar.gz |
[lcd4linux @ 2001-03-12 13:44:58 by reinelt]
new udelay() using Time Stamp Counters
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@112 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
Diffstat (limited to '')
-rw-r--r-- | HD44780.c | 10 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rwxr-xr-x | configure | 100 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | lcd4linux.conf.sample | 26 | ||||
-rw-r--r-- | udelay.c | 140 | ||||
-rw-r--r-- | udelay.h | 7 |
8 files changed, 232 insertions, 58 deletions
@@ -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; @@ -61,3 +61,6 @@ There's a reason for forking that early, but I forgot... 2001-03-12 Michael Reinelt <reinelt@eunet.at> remove USE_OLD_UDELAY after wide testing of new udelay code + +2001-03-12 Michael Reinelt <reinelt@eunet.at> +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 <asm/io.h> header file. */ #undef HAVE_ASM_IO_H +/* Define if you have the <asm/msr.h> header file. */ +#undef HAVE_ASM_MSR_H + /* Define if you have the <dirent.h> header file. */ #undef HAVE_DIRENT_H @@ -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 +#line 2728 "configure" +#include "confdefs.h" +#include <$ac_hdr> +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 <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&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 <<EOF -#line 2726 "configure" +#line 2766 "configure" #include "confdefs.h" int main() { @@ -2771,7 +2811,7 @@ ccp = (char const *const *) p; ; return 0; } EOF -if { (eval echo configure:2775: \"$ac_compile\") 1>&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 <<EOF -#line 2803 "configure" +#line 2843 "configure" #include "confdefs.h" int main() { } $ac_kw foo() { ; return 0; } EOF -if { (eval echo configure:2810: \"$ac_compile\") 1>&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 <<EOF -#line 2841 "configure" +#line 2881 "configure" #include "confdefs.h" #include <sys/types.h> #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 <<EOF -#line 2874 "configure" +#line 2914 "configure" #include "confdefs.h" #include <sys/types.h> #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 <<EOF -#line 2907 "configure" +#line 2947 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/time.h> @@ -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 <<EOF -#line 2942 "configure" +#line 2982 "configure" #include "confdefs.h" #include <sys/types.h> #include <time.h> @@ -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 -#line 2976 "configure" +#line 3016 "configure" #include "confdefs.h" #include <sys/types.h> 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 <<EOF -#line 3013 "configure" +#line 3053 "configure" #include "confdefs.h" #include <sgtty.h> Autoconf TIOCGETP @@ -3027,7 +3067,7 @@ rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext <<EOF -#line 3031 "configure" +#line 3071 "configure" #include "confdefs.h" #include <termio.h> 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 <<EOF -#line 3061 "configure" +#line 3101 "configure" #include "confdefs.h" main() @@ -3067,7 +3107,7 @@ main() } EOF -if { (eval echo configure:3071: \"$ac_link\") 1>&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 <<EOF -#line 3094 "configure" +#line 3134 "configure" #include "confdefs.h" #include <sys/types.h> #include <signal.h> @@ -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 <<EOF -#line 3137 "configure" +#line 3177 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -3156,7 +3196,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:3160: \"$ac_link\") 1>&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 @@ -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 <stdlib.h> #include <stdio.h> + #ifdef USE_OLD_UDELAY + #include <time.h> + #else -#include <sys/time.h> + +#include <math.h> #include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/time.h> +#ifdef HAVE_ASM_MSR_H +#include <asm/msr.h> +#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_usec<end.tv_usec:now.tv_sec<end.tv_sec); + p=strstr(buffer, "cpu MHz"); + if (p==NULL) { + debug ("/proc/cpuinfo has no 'cpu MHz' line"); + } else { + if (sscanf(p+7, " : %lf", MHz)!=1) { + error ("parse(/proc/cpuinfo) failed: unknown 'cpu MHz' format"); + *MHz=-1; + } else { + debug ("CPU runs at %f MHz", *MHz); + } + } + +} + + +void udelay_init (void) +{ + +#ifdef HAVE_ASM_MSR_H + + int tsc; + double mhz; + + getCPUinfo (&tsc, &mhz); + + if (tsc && mhz>0.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)<usec); + + } else { + + struct timeval now, end; + + gettimeofday (&end, NULL); + end.tv_usec+=usec; + while (end.tv_usec>1000000) { + end.tv_usec-=1000000; + end.tv_sec++; + } + + do { + gettimeofday(&now, NULL); + } while (now.tv_sec==end.tv_sec?now.tv_usec<end.tv_usec:now.tv_sec<end.tv_sec); + } } #endif @@ -1,4 +1,4 @@ -/* $Id: udelay.h,v 1.2 2001/03/12 12:39:36 reinelt Exp $ +/* $Id: udelay.h,v 1.3 2001/03/12 13:44:58 reinelt Exp $ * * short delays * @@ -20,6 +20,10 @@ * * * $Log: udelay.h,v $ + * Revision 1.3 2001/03/12 13:44:58 reinelt + * + * new udelay() using Time Stamp Counters + * * Revision 1.2 2001/03/12 12:39:36 reinelt * * reworked autoconf a lot: drivers may be excluded, #define's went to config.h @@ -46,6 +50,7 @@ void udelay_calibrate (void); #else +void udelay_init (void); void udelay (unsigned long usec); #endif |