aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--HD44780.c10
-rw-r--r--TODO3
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure100
-rw-r--r--configure.in1
-rw-r--r--lcd4linux.conf.sample26
-rw-r--r--udelay.c140
-rw-r--r--udelay.h7
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 <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
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
+#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
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 <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
diff --git a/udelay.h b/udelay.h
index 4a0dabc..3cec137 100644
--- 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
*
@@ -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