mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] NSC Geode Companion chip workaround
@ 2002-02-06  2:20 Hiroshi MIURA
  2002-02-06 14:06 ` Maciej W. Rozycki
  2002-02-06 14:08 ` Alan Cox
  0 siblings, 2 replies; 5+ messages in thread
From: Hiroshi MIURA @ 2002-02-06  2:20 UTC (permalink / raw)
  To: linux-kernel


Cyrix MediaGX/GXm or NSC Geode have PIT bug not TSC bug. 
but in linux kernel, if CPU is Cyrix, then  TSC flag is disabled.
This is not correct way, I think.

A patch atached below is originally from  NetBSD kernel code.
In FreeBSD bug tracking system, this was discussed.

http://www.freebsd.org/cgi/query-pr.cgi?pr=6630

Here is NetBSD patch.
http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=8654

in this patch, this code is activate only if you defines CONFIG_CS5520.
I've tryed several month with this patch, It seems good for me.
    trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103.
                   MediaGX 200MHz and NSC Geode 300MHz.



diff -ur kernel-source-2.4.7/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- kernel-source-2.4.7/arch/i386/kernel/setup.c	Thu Jul 12 01:31:44 2001
+++ linux/arch/i386/kernel/setup.c	Fri Aug 10 21:12:06 2001
@@ -1425,14 +1425,18 @@
 		/* GXm supports extended cpuid levels 'ala' AMD */
 		if (c->cpuid_level == 2) {
 			get_model_name(c);  /* get CPU marketing name */
+#ifndef CONFIG_CS5520
 			clear_bit(X86_FEATURE_TSC, c->x86_capability);
+#endif
 			return;
 		}
 		else {  /* MediaGX */
 			Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';
 			p = Cx86_cb+2;
 			c->x86_model = (dir1 & 0x20) ? 1 : 2;
+#ifndef CONFIG_CS5520
 			clear_bit(X86_FEATURE_TSC, &c->x86_capability);
+#endif
 		}
 		break;
 
diff -ur kernel-source-2.4.7/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- kernel-source-2.4.7/arch/i386/kernel/time.c	Sat Dec 30 07:07:57 2000
+++ linux/arch/i386/kernel/time.c	Fri Aug 10 21:04:26 2001
@@ -28,6 +28,9 @@
  * 1998-12-24 Copyright (C) 1998  Andrea Arcangeli
  *	Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
  *	serialize accesses to xtime/lost_ticks).
+ * 2001-02-20 Hiroshi Miura <miura@da-cha.org>
+ *      Work around for Cyrix/IBM/NSC MediaGX/GXm, NSC Geode southbridge 
+ *      PIT bug. (NSC Cx5510/5520)
  */
 
 #include <linux/errno.h>
@@ -459,6 +462,10 @@
 static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int count;
+#ifdef CONFIG_CS5520
+	int count1, count2, count3;
+	int n1, n2, n3;
+#endif
 
 	/*
 	 * Here we are in the timer irq handler. We just have irqs locally
@@ -487,6 +494,7 @@
 
 		rdtscl(last_tsc_low);
 
+#ifndef CONFIG_CS5520
 		spin_lock(&i8253_lock);
 		outb_p(0x00, 0x43);     /* latch the count ASAP */
 
@@ -499,6 +507,59 @@
 	}
  
 	do_timer_interrupt(irq, NULL, regs);
+#else
+		spin_lock(&i8253_lock);
+		outb_p(0x00, 0x43);	/* latch the count ASAP */
+/* this codes comes from FreeBSD */
+		count1 = inb_p(0x40);
+		count1 |= inb(0x40) << 8;
+		count2 = inb_p(0x40);
+		count2 = inb(0x40) << 8;
+                count3 = inb_p(0x40);
+                count3 = inb(0x40) << 8;
+		spin_unlock(&i8253_lock);
+		
+		if (count1 >= count2 && count2 >= count3 && count1 - count2 < 0x200)
+			count = count2;
+		else {
+
+#define _swap_val(a, b) do { \
+	int c = a;\
+	a = b; \
+	b = c; \
+} while(0)
+	 	   /* sort values */
+		  if (count1 < count2)
+			_swap_val(count1, count2);
+		  if (count2 < count3)
+                        _swap_val(count2, count3);
+		  if (count1 < count2)
+			_swap_val(count1, count2);
+
+		  /* compare the middle value */
+		  if (count1 - count3 < 0x200)
+			count = count2;
+		  else 
+                       {
+			n1 = count2 - count3;
+			n2 = count3 - count1 + LATCH;
+			n3 = count1 - count2;
+			count = count3;
+			if (n1 >= n2) {
+			   if (n1 >= n3)
+				count = count1;
+			} else {
+			   if (n2 >= n3)
+				count = count2;
+			} 
+		  }
+	      	}
+                count = ((LATCH-1) - count) * TICK_SIZE;
+                delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+	}
+
+      do_timer_interrupt(irq, NULL, regs);
+#endif
 
 	write_unlock(&xtime_lock);
 
@@ -659,6 +720,9 @@
  	
 	if (cpu_has_tsc) {
 		unsigned long tsc_quotient = calibrate_tsc();
+#ifdef CONFIG_CS5520
+		if (!tsc_quotient) tsc_quotient = calibrate_tsc();
+#endif
 		if (tsc_quotient) {
 			fast_gettimeoffset_quotient = tsc_quotient;
 			use_tsc = 1;


Hiroshi Miura  --- miura@da-cha.org http://www.da-cha.org/ 
CCNA, Oracle Silver Master, Network Specialist(JITEC)
My interest: http://www.cis.com.tw/Product/WS-U50R.htm











^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] NSC Geode Companion chip workaround
  2002-02-06  2:20 [PATCH] NSC Geode Companion chip workaround Hiroshi MIURA
@ 2002-02-06 14:06 ` Maciej W. Rozycki
  2002-02-09  4:14   ` Hiroshi MIURA
  2002-02-06 14:08 ` Alan Cox
  1 sibling, 1 reply; 5+ messages in thread
From: Maciej W. Rozycki @ 2002-02-06 14:06 UTC (permalink / raw)
  To: Hiroshi MIURA; +Cc: linux-kernel

On Wed, 6 Feb 2002, Hiroshi MIURA wrote:

> I've tryed several month with this patch, It seems good for me.
>     trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103.
>                    MediaGX 200MHz and NSC Geode 300MHz.

 Does the chip fail with the readback 8254 command as well?  If not, it
would be a less intrusive change. 

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] NSC Geode Companion chip workaround
  2002-02-06  2:20 [PATCH] NSC Geode Companion chip workaround Hiroshi MIURA
  2002-02-06 14:06 ` Maciej W. Rozycki
@ 2002-02-06 14:08 ` Alan Cox
  1 sibling, 0 replies; 5+ messages in thread
From: Alan Cox @ 2002-02-06 14:08 UTC (permalink / raw)
  To: Hiroshi MIURA; +Cc: linux-kernel

> in this patch, this code is activate only if you defines CONFIG_CS5520.
> I've tryed several month with this patch, It seems good for me.
>     trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103.
>                    MediaGX 200MHz and NSC Geode 300MHz.

Interesting. That would explain a lot. Unfortunately when I first reported
that problem and disabled the TSC Cyrix actually refused to believe the
problem existed.

With the below it looks fixable

(The CONFIG_CS5520 we can replace I think with a check for the PCI device)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] NSC Geode Companion chip workaround
  2002-02-06 14:06 ` Maciej W. Rozycki
@ 2002-02-09  4:14   ` Hiroshi MIURA
  2002-02-10  4:24     ` Hiroshi MIURA
  0 siblings, 1 reply; 5+ messages in thread
From: Hiroshi MIURA @ 2002-02-09  4:14 UTC (permalink / raw)
  To: macro; +Cc: miura, linux-kernel

In message "Re: [PATCH] NSC Geode Companion chip workaround"
    on 02/02/06, "Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
> On Wed, 6 Feb 2002, Hiroshi MIURA wrote:
> 
> > I've tryed several month with this patch, It seems good for me.
> >     trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103.
> >                    MediaGX 200MHz and NSC Geode 300MHz.
> 
>  Does the chip fail with the readback 8254 command as well?  If not, it
> would be a less intrusive change. 

OK, I want to try  8254 readback command. I will report after weekend.


Hiroshi Miura  --- miura@da-cha.org http://www.da-cha.org/ 
CCNA, Oracle Silver Master, Network Specialist(JITEC)
My interest: http://www.cis.com.tw/Product/WS-U50R.htm




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] NSC Geode Companion chip workaround
  2002-02-09  4:14   ` Hiroshi MIURA
@ 2002-02-10  4:24     ` Hiroshi MIURA
  0 siblings, 0 replies; 5+ messages in thread
From: Hiroshi MIURA @ 2002-02-10  4:24 UTC (permalink / raw)
  To: macro, Alan Cox; +Cc: linux-kernel, Ian S. Nelson


the MediaGX/Geode companion chip CS5520 fails the latch with the read-back
8254 command as well as 8253 latch command.

test program:  <list1>

kernel configuration: CONFIG_M586

kernel code with read-back command: <list2> 

test results:
  1. kernel 2.4.16 (without any fix, TSC disable)
               fails iteration: 500-1,500
               value of '(now - prev)' when fail:
                               -100 - -200 micro sec
  2. kernel 2.4.16 (with my patch)
               fails iteration: 35,000-70,000 
               error value:  -10 - -20 micro sec
  3. kernel 2.4.16 (with read-back command, TSC enable)
               fails iteration: 5,000-7,000
               error value:  about -20,000 micro sec
  4. kernel 2.4.16 (without any fix but TSC enable)
               fails iteration: 5,000-7,000
               error value: about -20,000 micro sec

these means 'read-back command' fails as well as 'latch command'.
and my patch is better than others.


In message "Re: [PATCH] NSC Geode Companion chip workaround"
    on 02/02/09, Hiroshi MIURA <miura@da-cha.org> writes:
> In message "Re: [PATCH] NSC Geode Companion chip workaround"
>     on 02/02/06, "Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
> > On Wed, 6 Feb 2002, Hiroshi MIURA wrote:
> > 
> > > I've tryed several month with this patch, It seems good for me.
> > >     trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103.
> > >                    MediaGX 200MHz and NSC Geode 300MHz.
> > 
> >  Does the chip fail with the readback 8254 command as well?  If not, it
> > would be a less intrusive change. 
> 
> OK, I want to try  8254 readback command. I will report after weekend.
 
<list1>
----------------
#include <sys/time.h>
#include <time.h>
#include <assert.h>

int main(void) {
  struct timeval tv[2];
  struct timeval *now, *prev;
  int iterations = 0;

  now = &tv[0];
  prev = &tv[1];
  gettimeofday(prev, NULL);

  for (;;) {
    struct timeval *tmp;

    gettimeofday(now, NULL);
    if (!((now->tv_sec > prev->tv_sec) ||
	   (now->tv_sec == prev->tv_sec && now->tv_usec >= prev->tv_usec)))
		printf ("Err: prev: %d,  %d, now: %d, %d, iter: %d\n", prev->tv_sec,
			prev->tv_usec, now->tv_sec, now->tv_usec, iterations);
    tmp = prev;
    prev = now;
    now = tmp;
    iterations++;
  }
  return iterations;
}
----------------
<list2>
----------------
--- /usr/src/linux/arch/i386/kernel/time.c.multiread	Sat Feb  9 22:24:51 2002
+++ /usr/src/linux/arch/i386/kernel/time.c.readback	Sat Feb  9 20:36:41 2002
@@ -474,6 +474,7 @@
 #ifdef CONFIG_CS5520
 	int count1, count2, count3;
 	int n1, n2, n3;
+	int i, cont, status;
 #endif
 
 	/*
@@ -517,6 +518,26 @@
  
 	do_timer_interrupt(irq, NULL, regs);
 #else
+#if 1
+	    for (i = 0, cont = 1; cont && ( i < 3 ); i++) {
+		spin_lock(&i8253_lock);
+		outb_p(0xf2, 0x43);   /* read-back command */
+		status = inb_p(0x40);
+		count = inb_p(0x40);
+		count |= inb_p(0x40) << 8;
+		spin_unlock(&i8253_lock);
+
+		cont = status & (1 << 6);
+            }
+
+		if (cont) 
+			printk("PIT latch fails 3 times.\n");
+
+		count = ((LATCH-1) - count) * TICK_SIZE;
+		delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+	}
+	do_timer_interrupt(irq, NULL, regs);
+#else
 		spin_lock(&i8253_lock);
 		outb_p(0x00, 0x43);	/* latch the count ASAP */
 /* this codes comes from FreeBSD */
@@ -568,6 +589,7 @@
 	}
 
       do_timer_interrupt(irq, NULL, regs);
+#endif
 #endif
 
 	write_unlock(&xtime_lock);


-- 
Hiroshi Miura  --- miura@da-cha.org http://www.da-cha.org/ 
CCNA, Oracle Silver Master, Network Specialist(JITEC)
My interest: http://www.cis.com.tw/Product/WS-U50R.htm



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2002-02-10  3:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-02-06  2:20 [PATCH] NSC Geode Companion chip workaround Hiroshi MIURA
2002-02-06 14:06 ` Maciej W. Rozycki
2002-02-09  4:14   ` Hiroshi MIURA
2002-02-10  4:24     ` Hiroshi MIURA
2002-02-06 14:08 ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®