]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2001-03-12 13:44:58 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Mon, 12 Mar 2001 13:44:58 +0000 (13:44 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Mon, 12 Mar 2001 13:44:58 +0000 (13:44 +0000)
new udelay() using Time Stamp Counters

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@112 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

HD44780.c
TODO
config.h.in
configure
configure.in
lcd4linux.conf.sample
udelay.c
udelay.h

index 8bb44a97c8930ab44e401682e1298f6414ea8c42..f0a3d3ca4eb3af1dd035c58364383b6e0517bec8 100644 (file)
--- 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
  *
  *
  *
  * $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 2c8c7b7ec4edce86b80a0848bdc762dab5caa641..2cf451d2c7f687925af82889894059a9a9689595 100644 (file)
--- a/TODO
+++ b/TODO
@@ -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
index 5e4090fd89e16b202a7cf9020f9a0db6fafa4d69..a52c5c435968b2782d8b049481cccfbc22af4099 100644 (file)
@@ -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
 
index 57d73d99e2bea2a4d789ae1316a78dc10a3e429a..f8e0dbc313a287f2de2e996c0b9e35228d87245e 100755 (executable)
--- 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
+#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
index b7bb573fb63120eadf3bca9150a38034d97699ed..959444b3674e80a0cab9a92fe71caf67b7fa428c 100644 (file)
@@ -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
index c12f7f07195d27b6d9f9b6392b278f0fb5183f39..ec8d8579de068825b94c9204b175c4e44c0bc5b3 100644 (file)
@@ -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
 #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
index e65843690880e2c7a284c863870ceffa2dfefa00..e9a323162696131b09b51de04a293c5d50533803 100644 (file)
--- 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
  *
  *
  *
  * $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
  *  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
index 4a0dabcc283d086132b6afb45c508fa8771d17f9..3cec1378c7a54aeae1b581511a348ce952cfc704 100644 (file)
--- a/udelay.h
+++ b/udelay.h
@@ -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 
  *
  *
  *
  * $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